> Mark Williams wrote:
>
> > > 2) Let the two threads read and write to your own two
> > > independent queues and
> > > service the application side of the SSL connection with your
> > > own code to and from the read and write queues.
>
> > Won't I still need to combine the reading and writing to
> the SSL object
> > into a
> > single thread for this? This is the bit I am having difficulty
> > visualising.
>
> The data pump thread is more or less like this:
>
> While (connection_is_alive)
> {
> If (connection_is_not_corked_in)
> {
> SSL_read into temporary buffer.
> If we got data:
> {
> If a read thread is blocked, unblock it.
> If the receive queue is too full, set the 'corked_in' flag.
> }
> If we got a fatal error, mark the connection dead.
> }
> If(send queue not empty)
> {
> Try to send some data using SSL_write
> Put back what we didn't send
> }
> If we made no forward progress, block (see notes)
> }
> Tear down the connection
>
> The read thread acquires the queue mutex, blocks on the
> condvar for data if
> desired, pulls data off the queue, and clears the corked_in
> flag if it was
> set (assuming the queue is still not full), and signals the
> data pump thread if it uncorked.
>
> The write thread acquires the mutex, checks if the send queue is full,
> blocks on the condvar if it is, and signals the data pump
> thread if the queu was empty.
>
> The only trick left is the blocking logic in the data pump
> thread. This is the hard part:
>
> 1) If you have no outbound data pending, and the connection
> is corked, block
> only on an internal signal. (Since you don't want to do I/O either way
> anyway.)
>
> 2) If you have outbound data pending and the connection is
> corked, block as
> directed by SSL_write. If it said WANT_READ, block on read. If it said
> WANT_WRITE, block on write.
>
> 3) If you have no outbound data pending (and hence, did not
> call SSL_write),
> and the connection is uncorked, block as directed in SSL_read.
>
> 4) If you have outbound data pending, and the connection is
> uncorked, block
> on the logical OR of the SSL_read result and the SSL_write
> result (block for
> read on the socket if either one returned WANT_READ, block
> for write if either returned WANT_WRITE).
>
> Note that your data pump threads needs to block on a 'select'
> or 'poll' type
> function but be unblocked when signaled. If necessary, add
> one end of a pipe
> to the select/poll set and have you read/write threads write
> a byte to that pipe to unblock the data pump thread.
>
> This is from memory, but it should be basically correct.
>
> By the way, I think only the logic in 4 is not obviously
> correct. Here's the proof it's safe:
> 1) If nothing changed, and we block on the OR of both
> operations, we will
> only unblock if one of those operations can make forward
> progress. (We only
> unblock on X if one operation Xould make forward progress on
> X, and nothing has changed since then.)
> 2) If something changed, then we already made some forward progress.
> So either way, we make forward progress in each pass of the
> loop, which is the best you can hope for.
Thanks. This will take me some time to digest.
There is one added complication in that the protocol is a datagram
protocol at a
higher level (although it uses TCP). I am concerned that the whole
protocol could
block if there is not enough data to encrypt a whole outgoing message
but the peer cannot
continue until it gets the message.
Mark.
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List [email protected]
Automated List Manager [email protected]