> 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                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to