0

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...

mark
  • 5,269
  • 2
  • 21
  • 34
  • SSL_Pending is for read ahead not for the purpose you are using. Blocking read will automatically renegotiate when ever the next read is done. If you are using the ssl_set_fd you can set the recieve timeout on the descriptor and it might help you in this case. http://stackoverflow.com/questions/4181784/how-to-set-socket-timeout-in-c-when-making-multiple-connections .Otherwise non blocking io can be used. – Adnan Akbar Aug 16 '13 at 15:53

1 Answers1

0

SSL_Pending is for read ahead not for the purpose you are using. Blocking read will automatically renegotiate when ever the next read is done. If you are using the ssl_set_fd you can set the recieve timeout on the descriptor and it might help you in this case. How to set socket timeout in C when making multiple connections?

Otherwise non blocking io can be used.

Community
  • 1
  • 1
Adnan Akbar
  • 718
  • 6
  • 16
  • Thanks... I am using `SSL_set_fd` on both sockets, and I am using a `select` with timeout on them. My problem is, when the select indicates a socket needs reading, how do I know if the data is a renegotiate (non-application data) or not? If it's not application data, then a `SSL_read` will do the renegotiate just fine, but then it will block on application data, which is the problem. – mark Aug 16 '13 at 16:01
  • You will need to set SO_RCVTIMEO and SO_SNDTIMEO on the fd and when the SSL_read is done with negotiation it will return after the timeout set in the above calls so you dont need to worry about the always waiting on read part. Please not i am not reffering to timeout on select but on fd. – Adnan Akbar Aug 16 '13 at 16:05
  • Ah, I think you're suggesting go ahead an let it block, just use something near-zero... – mark Aug 16 '13 at 16:07
  • yup there is a select which will tell you there is something to read and in case if it application data all is fine. If it is renogotiation it will do that and then possibly go on to read which will return at the timeout specified initially with set_sock_opt. You can set it to something near zero. – Adnan Akbar Aug 16 '13 at 16:11
  • This sounds ominous from Windows documentation: *if a send or receive operation times out on a socket, the socket state is indeterminate, and should not be used*. Note that I need to be able to continue to use the connection, I'm not aborting it. I'll need to research this further... – mark Aug 16 '13 at 16:26
  • In that case this might help. SSL_state(). http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/V51B_HTML/MAN/MAN3/1080____.HTM – Adnan Akbar Aug 16 '13 at 16:43