> 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