I have a server thread that uses multiple blocking sockets and I need it run when there's data to process. The problem is, how do I let OpenSSL do "its stuff" (like renegotiation) without getting stuck in a blocking operation (awaiting application data)? Note: I have SSL_set_mode - SSL_MODE_AUTO_RETRY
and I suspect that I'll need to not do that and handle the cases myself, but it's not clear from reading documentation how I'd accomplish that. Consider the following pseudo-code:
while(running){
select on readability sockets 1 and 2
if(socket 1 readable) {
SSL_read data(socket 1)
process data, possibly interacting with socket 2
}
if(socket 2 readable) {
SSL_read data(socket 2)
process data, possibly interacting with socket 1
}
}
What happens if the select drops out because there's SSL/TLS-layer "things to do" on either socket but not application-layer data? SSL_read
will handle the "things to do", but then block because there's no application data... that block kills the ability to read from the other socket. There's this nice method SSL_pending
that will tell me about application data, but the stack doesn't get a chance to get any data without a SSL_read
as far as I can tell. Apart from separating the sockets into separate threads or using non-blocking sockets, is there an easy way to say to the OpenSSL layer something like "do renegotiation if you need to, and read data records if there are any but don't block if neither is needed"? Something like a NULL/NULL read or write?
// process records on the socket
SSL_read( ssl, 0, 0 ); // or maybe SSL_write( ssl, 0, 0 ) ?
if ( SSL_pending( ssl ) ) {
// do the application data read
SSL_read( ssl, buf, sizeof(buf) );
}
EDIT: Tried out doing SSL_read( ssl, 0, 0 )
without select-read and it blocks for a record so that won't work. Doing select then read-0/0 or SSL_write( ssl, 0, 0 )
without select seems to not be blocking, although I'm not sure yet that either is doing what I need it to do...