Parimal Das wrote:

> The IMAP(2009) c-client library/API does its own socket I/O for
> non-SSL sessions, but in SSL the socket I/O is delegated to OpenSSL.
> When c-client does its own socket I/O, it sets a timeout (normally
> 15 seconds) on a select() call prior to doing any read() or write()
> calls. Thus, c-client never does a read() or write() that would block.

Actually, they still can block. Suppose 'select' gets a 'write' hit because
X bytes can be written without blocking, but then you call 'write' to send
X+1 bytes. Boom, you block. So unless the library actually uses non-blocking
socket operations, it can always block due to various types of ambush.

> If the select() timeout hits, there is a callback to the application
> to enquire whether the application wants to continue waiting.
> If the application chooses to continue waiting, the select()
> is restarted with an updated timeout.  Otherwise, the socket is
> closed and the application receives a corresponding I/O error.

> The net effect is that a non-SSL I/O can wait forever as long as
> the application consents.  c-client does not unilaterally disconnect.

You can code the same thing with OpenSSL. Use non-blocking sockets and
non-blocking BIOs. Really, the only difference is that with TCP, you can
'select' before or after you try to 'read' or 'write'. (You can call 'read'
and then only call 'select' if the read would block, or you can call
'select' first and only call 'read' if 'select' tells you to; same for
write.) With SSL, you must try to SSL_read or SSL_write *before* you
'select'. Otherwise, you may wind up waiting for something that has already
happened. (And how would you know whether to 'select' for read or write
anyway? You may need to write to the socket to read decrypted data, and you
may need to read from the socket to send encrypted data depending on  what's
going on with the SSL engine.)

> My problem is that this doesn't happen with SSL sessions because
> the socket I/O has been delegated to OpenSSL.  There is no obvious way
> to instruct OpenSSL to timeout its socket I/O, much less do the
> mechanism described above.

Set the sockets and BIOs non-blocking. If SSL_read/SSL_write tells you they
will block, then 'select' in the appropriate direction. If 'select' times
out, then do your callback thing.

> So, the questions are:
> (1) Is there a way to set a timeout for OpenSSL's socket I/O
> (given that it has been delegated to OpenSSL)?  If so, how?

No, but you don't need to.

> (3) If the answer to either (1) or (2) is "no", then how would
> we go about altering the OpenSSL consumer (which, in this case,
> is c-client) so that OpenSSL uses the consumer's socket I/O code
> instead of OpenSSL's socket I/O code?  I'm hoping that you will
> tell me that there's some callback function pointer that can be passed.

You can do that, but it's a lot more work. Just call 'select' when OpenSSL
tells you to and callback the application if the 'select' times out.

DS



______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to