RE: Problem handling unexpected SSL shutdown
Thanks for the response. You'll have to bear with me, as I'm not really a low-level sockets programmer. But maybe you misunderstood the nature of my problem. The problem is that, on Windows at least, my server doesn't appear to get the SSL shutdown notify packet, for some reason. So, if that is to be expected, I'm looking for an alternative way of detecting the closure. I've now tested it on Linux, and the existing code works fine. In other words, when trying the SSL_Get: 1. It fails 2. SSL_get_error() returns SSL_ERROR_ZERO_RETURN 3. (SSL_get_shutdown() SSL_RECEIVED_SHUTDOWN) is true On Windows this is not the case. But I guess if this problem is restricted to Windows, then I can: 1. Add the call to WSAGetLastError() just for that platform 2. Use it to detect the socket closure and ... 3. Softly close the server socket that way Unless somebody has any better ideas ... G. -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Darryl Miles Sent: 15 August 2007 15:40 To: openssl-users@openssl.org Subject: Re: Problem handling unexpected SSL shutdown Shaw Graham George wrote: The sequence of events goes like this: 1. The SSL handshake proceeds as normal. 2. The client puts an HTTP request 3. The server gets the HTTP request 4. The client then executes an (unexpected) SSL shutdown 5. The server puts the HTTP response Here I might expect the put to fail, but all appears normal. 6. As an HTTP Keep-Alive request has been made, the server enters a wait for the next read event. 7. The read event occurs (presumably due to the SSL shutdown), and now the get fails. SSL_get_error() returns SSL_ERROR_SYSCALL (I would expect SSL_ERROR_ZERO_RETURN for an SSL shutdown). ERR_get_error() returns 0. (SSL_get_shutdown() SSL_RECEIVED_SHUTDOWN) returns 0. Is this the expected behaviour? What I am looking for is a way of identifying the shutdown at the server, so that I can close the connection softly. I.e. you dont want your Keep-Alive's hanging around when the other end has gone. The client will take one of these actions: * It will simply close the socket. This can be picked up by your normal read() / write() failure scenarios. * It will write out a SSL shutdown notify packet, and then close the connection anyway. The server may or may not get the SSL shutdown notify packet due to send buffering, socket linger options, retransmission timeouts etc... But at server end will either receive the SSL shutdown notify before the socket close or it will just see a socket close. So again there is no special trickey here. * It will write out a SSL shutdown notify packet and wait for the acknowledgment from the server. This is 100% graceful and conceptually correct way to finish things off. To handle this your SSL_read() will signal a shutdown has been received (and from this point on no further SSL data will be received on that session that just closed). From seeing this you have a number of options at the server: * ACK the shutdown and issue your own shutdown (but only after you have finished writing all your application data with SSL_write()). A HTTP client can often send the request and then shut the socket down, the server can observe this right after it pulled the request off to process it in another thread, this does not mean you want to shut the socket down at your end until you have processed that request and finished writing the Content body back the other way, only then should you take action in response to seeing the client's SSL shutdown notify. * Once your SSL shutdown notify has hit the kernel write socket buffer, issue a TCP level shutdown(fd, SHUTDOWN_SEND). * Then wait to receive your shutdown ack or for the socket to close/timeout. This wait does not have to be forever, I have an implementation that will allow the client socket a configurable amount of time to provide the SSL shutdown notify ACK back to me, if it does not happen within that time I close the socket. * Ultimately all this work leads to closing the socket. If you implement everything above then your server is at least complying with all the available mechanisms within SSL during the shutdown sequence. I'm sure many implementations skip all the more complex points and jump right to the close the socket. I don't fully see the problem with your code, nor the concern of having a solution that works on Unix and Win32 because most people in the situation you are in would put the socket into idle state but listening for more data (an active Keep-Alive idle list). You will always get an event from listening for more data that will indicate the socket has been closed, or the socket has received a SSL shutdown notify request. You won't miss it. Here is a random fragment of my read code from Unix, it interests me if the there is a difference for Win32 but I would expect SSL_read() to return
Re: Problem handling unexpected SSL shutdown
Shaw Graham George wrote: The problem is that, on Windows at least, my server doesn't appear to get the SSL shutdown notify packet, for some reason. So, if that is to be expected, I'm looking for an alternative way of detecting the closure. I've now tested it on Linux, and the existing code works fine. In other words, when trying the SSL_Get: SSL_read() ? 1. It fails 2. SSL_get_error() returns SSL_ERROR_ZERO_RETURN 3. (SSL_get_shutdown() SSL_RECEIVED_SHUTDOWN) is true On Windows this is not the case. But I guess if this problem is restricted to Windows, then I can: 1. Add the call to WSAGetLastError() just for that platform 2. Use it to detect the socket closure and ... 3. Softly close the server socket that way Unless somebody has any better ideas ... Can you log the OpenSSL API calls you make and the return values you see. When seeing any errors from OpenSSL don't forget the idiom's: int err = SSL_get_error(client-ssl, n); int wsa_errno = WSAGetLastError(); and log the values you see. Please also include the OpenSSL API calls made just before the other end disappears. This would clear up in my mind what you are observing : * You don't get the read-ready wakeup event from Win32 API ? So you never get a chance to call SSL_read(). * You don't see an error from SSL_read() ? But what did it return instead ? * You never see '(SSL_get_shutdown() SSL_RECEIVED_SHUTDOWN) is true' condition, even though you have written you own client and can confirm it does/will send a SSL shutdown notify packet, will ensure the data is flushed to the socket and will keep the socket open waiting to receive a SSL shutdown notify packet from the other end ? If you get the read-ready wakeup event from Win32 API, then your code will end up calling SSL_read() and that call should attempt to process another packet and pull data from the socket as necessary until no more progress can be made at this time. This will implicitly process the SSL shutdown notify packet. Darryl __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
RE: Problem handling unexpected SSL shutdown
Sure. 1. The server receives the HTTP request, using SSL_read() and SSL_pending(). The request contains a Keep-Alive request. 2. The server writes the data out to another process. 3. The server then it sits on an event handler that multiplexes a select() (or Windows equivalent) on sockets it has an interest in, and other events such as receiving data from other processes. At this time it actually has no interest in any events at the socket, as it is waiting for the processing to complete. 4. The SSL client lose patience with a lack of response, and does an SSL shutdown and socket close. 5. An event is detected, and the server receives the result from the background processing. 6. It adds write interest to the socket and goes back to sitting on the event handler. 7. An event is detected and the server then performs an SSL_write() to the (non-existent) client, which is successful. 8. It then adds read interest in the socket, as it is a Keep-Alive socket, so it is waiting for the next HTTP request. It goes back to sitting on the event handler. 9. An event is detected and the server then performs: 9a. SSL_read() which fails (return code is -1). 9b. SSL_get_error() which returns SSL_ERROR_SYSCALL. 9c. ERR_get_error() which returns 0. In the original code SSL_get_shutdown() would not be called unless SSL_get_error() returns SSL_ERROR_ZERO_RETURN, but I added an extra debug call after the call to SSL_get_error(), and it did not show SSL_RECEIVED_SHUTDOWN. And I have now added a call to WSAGetLastError() after the call to ERR_get_error(), and it returns WSAECONNABORTED. So I do get a read event on the socket. I do call SSL_read. It fails. But the shutdown is apparently not received, as: a. SSL_get_error() does not return SSL_ERROR_ZERO_RETURN b. SSL_get_shutdown() does not show SSL_RECEIVED_SHUTDOWN I hope that's clear. As I say, the code works fine on Linux. G. -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Darryl Miles Sent: 16 August 2007 17:44 To: openssl-users@openssl.org Subject: Re: Problem handling unexpected SSL shutdown Shaw Graham George wrote: The problem is that, on Windows at least, my server doesn't appear to get the SSL shutdown notify packet, for some reason. So, if that is to be expected, I'm looking for an alternative way of detecting the closure. I've now tested it on Linux, and the existing code works fine. In other words, when trying the SSL_Get: SSL_read() ? 1. It fails 2. SSL_get_error() returns SSL_ERROR_ZERO_RETURN 3. (SSL_get_shutdown() SSL_RECEIVED_SHUTDOWN) is true On Windows this is not the case. But I guess if this problem is restricted to Windows, then I can: 1. Add the call to WSAGetLastError() just for that platform 2. Use it to detect the socket closure and ... 3. Softly close the server socket that way Unless somebody has any better ideas ... Can you log the OpenSSL API calls you make and the return values you see. When seeing any errors from OpenSSL don't forget the idiom's: int err = SSL_get_error(client-ssl, n); int wsa_errno = WSAGetLastError(); and log the values you see. Please also include the OpenSSL API calls made just before the other end disappears. This would clear up in my mind what you are observing : * You don't get the read-ready wakeup event from Win32 API ? So you never get a chance to call SSL_read(). * You don't see an error from SSL_read() ? But what did it return instead ? * You never see '(SSL_get_shutdown() SSL_RECEIVED_SHUTDOWN) is true' condition, even though you have written you own client and can confirm it does/will send a SSL shutdown notify packet, will ensure the data is flushed to the socket and will keep the socket open waiting to receive a SSL shutdown notify packet from the other end ? If you get the read-ready wakeup event from Win32 API, then your code will end up calling SSL_read() and that call should attempt to process another packet and pull data from the socket as necessary until no more progress can be made at this time. This will implicitly process the SSL shutdown notify packet. Darryl __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED] __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
Re: Problem handling unexpected SSL shutdown
Shaw Graham George wrote: Sure. 1. The server receives the HTTP request, using SSL_read() and SSL_pending(). The request contains a Keep-Alive request. 2. The server writes the data out to another process. 3. The server then it sits on an event handler that multiplexes a select() (or Windows equivalent) on sockets it has an interest in, and other events such as receiving data from other processes. What is the sleep/wakeup IO mechanism you are employing on windows ? WaitForMultipleObjects() ? Side track: Is it possible to make the window platform listen on 31 sockets at once per thread ? (or whatever is small limit was) At this time it actually has no interest in any events at the socket, as it is waiting for the processing to complete. I take this to mean you revoke all interest in the socket readability/writability. So the server is no oblivious to what the client is doing. 4. The SSL client lose patience with a lack of response, and does an SSL shutdown and socket close. Okay you closed your ears to the read event ? On Unix the select() has an exceptfds which can be used to pickup a socket error/close (but may not be reliable if there is readable data first, since by convention of TCPs orderly shutdown that has to be eaten before the socket close can be seen). 5. An event is detected, and the server receives the result from the background processing. I take this event to mean a read wakeup on channel facing the request processing process ? 6. It adds write interest to the socket and goes back to sitting on the event handler. 7. An event is detected and the server then performs an SSL_write() to the (non-existent) client, which is successful. This write may succeed due to kernel buffering and the unread data still in the read buffer of the kernel until that is read the normal TCP shutdown/close condition may not be seen. Or it may fail SSL_write() == -1 SSL_get_error() == SSL_ERROR_SYSCALL. But the problem here is that your application is being single minded, in that it has shut its ears to processing more TCP level data (even tho the SSL protocol handling layer might require some read processing to take place, even during writes, but you cut of the SSL protocol layer's source of data). I can understand why you do it, since you don't want the application to be holding onto data relating to the next pipelined request just yet as you have no intention on servicing it. What you really wanted in this scenario is continue to observe read interest in the client TCP socket but use an SSL_peek() call. I have called for this API call before, that is an OpenSSL API function that allows WANT_READ processing to take place but does not destructively return application data. Since OpenSSL doesn't have a SSL_peek() call and your application could hold onto a small buffer of extraneous application data then it would be possible to over-read by one (before you drop read interest). This would not detect the situation where the client wrote multiple requests to the server, waited a short time, then reverted to sending a SSL shutdown notify and closing the socket. What you really wanted to know was out-of-band indication from the kernel that the client reset the connection. Knowing that client had TCP send shutdown is not useful, only if a connection reset was known about before, which requires the client to have actually sent a TCP reset packet (which I think occurs in the situation you are in, due to the WSAGetLastError() == WSAECONNABORTED. 8. It then adds read interest in the socket, as it is a Keep-Alive socket, so it is waiting for the next HTTP request. It goes back to sitting on the event handler. 9. An event is detected and the server then performs: 9a. SSL_read() which fails (return code is -1). 9b. SSL_get_error() which returns SSL_ERROR_SYSCALL. 9c. ERR_get_error() which returns 0. In the original code SSL_get_shutdown() would not be called unless SSL_get_error() returns SSL_ERROR_ZERO_RETURN, but I added an extra debug call after the call to SSL_get_error(), and it did not show SSL_RECEIVED_SHUTDOWN. And I have now added a call to WSAGetLastError() after the call to ERR_get_error(), and it returns WSAECONNABORTED. So I do get a read event on the socket. I do call SSL_read. It fails. But the shutdown is apparently not received, as: a. SSL_get_error() does not return SSL_ERROR_ZERO_RETURN b. SSL_get_shutdown() does not show SSL_RECEIVED_SHUTDOWN I hope that's clear. Okay knowing that WSAGetLastError() == WSAECONNABORTED as this time is irrelevant, since any SSL_read() == -1 SSL_get_error() == SSL_ERROR_SYSCALL would always be a sitution to cleanup and close the socket. Since OpenSSL already processes the Winsock API error returns for WANT_READ and WANT_WRITE on non-blocking sockets itself. Getting a SSL_ERROR_SYSCALL is not a recoverable situation. Work through my code snippet to see exactly this
RE: Problem handling unexpected SSL shutdown
Side track: Is it possible to make the window platform listen on 31 sockets at once per thread ? (or whatever is small limit was) IOCP. Okay you closed your ears to the read event ? On Unix the select() has an exceptfds which can be used to pickup a socket error/close (but may not be reliable if there is readable data first, since by convention of TCPs orderly shutdown that has to be eaten before the socket close can be seen). Neither errors nor closes are 'select' exceptions. Perhaps you are thinking of 'poll' and 'POLLERR'/'POLLHUP'? DS __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
Problem handling unexpected SSL shutdown
Hi, We have an application that provides HTTPS, either as client or server, for our customers. At the moment I am doing some testing between our client and our server, as a result of a problem with one of our customers, and there is a particular sequence of events, that involves an unexpected SSL shutdown, that is giving an unexpected behaviour (at least to me). The sequence of events goes like this: 1. The SSL handshake proceeds as normal. 2. The client puts an HTTP request 3. The server gets the HTTP request 4. The client then executes an (unexpected) SSL shutdown 5. The server puts the HTTP response Here I might expect the put to fail, but all appears normal. 6. As an HTTP Keep-Alive request has been made, the server enters a wait for the next read event. 7. The read event occurs (presumably due to the SSL shutdown), and now the get fails. SSL_get_error() returns SSL_ERROR_SYSCALL (I would expect SSL_ERROR_ZERO_RETURN for an SSL shutdown). ERR_get_error() returns 0. (SSL_get_shutdown() SSL_RECEIVED_SHUTDOWN) returns 0. Is this the expected behaviour? What I am looking for is a way of identifying the shutdown at the server, so that I can close the connection softly. The version is 0.9.8e. All sockets are non-blocking. The test platform is Windows - but our application runs on many platforms, I can test on those as well if required. Thanks in advance, G. __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
RE: Problem handling unexpected SSL shutdown
Some more information and thoughts. I can replicate the server behaviour using openssl s_client, sending the HTTP request, and then shutting down the client with a Q. I'm wondering if the problem is that, once the HTTP request is received by my server, then it has no read interest in the socket (as it now wants to write the HTTP response). So it will put the response whatever the state of the socket. Then maybe the put affects the state of the socket, so that the shutdown state is no longer present. So should I always have a read interest in the socket, in case of shutdown? Or should I check for a shutdown before actually doing the put? But I would still have thought that the put should return an error if the socket has been shutdown. Thanks again, G. -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Shaw Graham George Sent: 15 August 2007 11:38 To: openssl-users@openssl.org Subject: Problem handling unexpected SSL shutdown Hi, We have an application that provides HTTPS, either as client or server, for our customers. At the moment I am doing some testing between our client and our server, as a result of a problem with one of our customers, and there is a particular sequence of events, that involves an unexpected SSL shutdown, that is giving an unexpected behaviour (at least to me). The sequence of events goes like this: 1. The SSL handshake proceeds as normal. 2. The client puts an HTTP request 3. The server gets the HTTP request 4. The client then executes an (unexpected) SSL shutdown 5. The server puts the HTTP response Here I might expect the put to fail, but all appears normal. 6. As an HTTP Keep-Alive request has been made, the server enters a wait for the next read event. 7. The read event occurs (presumably due to the SSL shutdown), and now the get fails. SSL_get_error() returns SSL_ERROR_SYSCALL (I would expect SSL_ERROR_ZERO_RETURN for an SSL shutdown). ERR_get_error() returns 0. (SSL_get_shutdown() SSL_RECEIVED_SHUTDOWN) returns 0. Is this the expected behaviour? What I am looking for is a way of identifying the shutdown at the server, so that I can close the connection softly. The version is 0.9.8e. All sockets are non-blocking. The test platform is Windows - but our application runs on many platforms, I can test on those as well if required. Thanks in advance, G. __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED] __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
Re: Problem handling unexpected SSL shutdown
Shaw Graham George wrote: Hi, We have an application that provides HTTPS, either as client or server, for our customers. At the moment I am doing some testing between our client and our server, as a result of a problem with one of our customers, and there is a particular sequence of events, that involves an unexpected SSL shutdown, that is giving an unexpected behaviour (at least to me). The sequence of events goes like this: 1. The SSL handshake proceeds as normal. 2. The client puts an HTTP request 3. The server gets the HTTP request 4. The client then executes an (unexpected) SSL shutdown Is this only a SSL_shutdown() or is SSL_shutdown() followed by a socket close by the client? Well if you had been listening for a read, both the SSL_shutdown and the socket close are capable of generating read events in select() If it was only a SSL_shutdown, i suppose you should be getting SSL_ERROR_ZERO_RETURN. In the other case SSL_ERROR_SYSCALL with errno=EPIPE seems possible. 5. The server puts the HTTP response Here I might expect the put to fail, but all appears normal. 6. As an HTTP Keep-Alive request has been made, the server enters a wait for the next read event. 7. The read event occurs (presumably due to the SSL shutdown), and now the get fails. SSL_get_error() returns SSL_ERROR_SYSCALL (I would expect Did you check errno here? SSL_ERROR_ZERO_RETURN for an SSL shutdown). ERR_get_error() returns 0. (SSL_get_shutdown() SSL_RECEIVED_SHUTDOWN) returns 0. Is this the expected behaviour? What I am looking for is a way of identifying the shutdown at the server, so that I can close the connection softly. The version is 0.9.8e. All sockets are non-blocking. The test platform is Windows - but our application runs on many platforms, I can test on those as well if required. Thanks in advance, G. -jb -- Tact is the art of making a point without making an enemy. __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
Re: Problem handling unexpected SSL shutdown
jimmy bahuleyan wrote: Shaw Graham George wrote: Hi, We have an application that provides HTTPS, either as client or server, for our customers. At the moment I am doing some testing between our client and our server, as a result of a problem with one of our customers, and there is a particular sequence of events, that involves an unexpected SSL shutdown, that is giving an unexpected behaviour (at least to me). The sequence of events goes like this: 1. The SSL handshake proceeds as normal. 2. The client puts an HTTP request 3. The server gets the HTTP request 4. The client then executes an (unexpected) SSL shutdown Is this only a SSL_shutdown() or is SSL_shutdown() followed by a socket close by the client? Well if you had been listening for a read, both the SSL_shutdown and the socket close are capable of generating read events in select() If it was only a SSL_shutdown, i suppose you should be getting SSL_ERROR_ZERO_RETURN. In the other case SSL_ERROR_SYSCALL with errno=EPIPE seems possible. 5. The server puts the HTTP response Here I might expect the put to fail, but all appears normal. 6. As an HTTP Keep-Alive request has been made, the server enters a wait for the next read event. 7. The read event occurs (presumably due to the SSL shutdown), and now the get fails. SSL_get_error() returns SSL_ERROR_SYSCALL (I would expect Did you check errno here? i mean WSAGetLastError() or whatever. -jb -- Tact is the art of making a point without making an enemy. __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
RE: Problem handling unexpected SSL shutdown
Hi, More information. Before the server put: (SSL_get_shutdown() SSL_RECEIVED_SHUTDOWN) returns 0. ... so that's of no use. After the server get: errno returns 0. WSAGetLastError() returns WSAECONNABORTED. That's one step forward, maybe. But my code must work for all supported platforms, so I need to find a solution that will work on UNIX as well. I guess I should make a test on UNIX to see if the same problem occurs, or if this is a Windows-specific problem. G. -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of jimmy bahuleyan Sent: 15 August 2007 14:01 To: openssl-users@openssl.org Subject: Re: Problem handling unexpected SSL shutdown jimmy bahuleyan wrote: Shaw Graham George wrote: Hi, We have an application that provides HTTPS, either as client or server, for our customers. At the moment I am doing some testing between our client and our server, as a result of a problem with one of our customers, and there is a particular sequence of events, that involves an unexpected SSL shutdown, that is giving an unexpected behaviour (at least to me). The sequence of events goes like this: 1. The SSL handshake proceeds as normal. 2. The client puts an HTTP request 3. The server gets the HTTP request 4. The client then executes an (unexpected) SSL shutdown Is this only a SSL_shutdown() or is SSL_shutdown() followed by a socket close by the client? Well if you had been listening for a read, both the SSL_shutdown and the socket close are capable of generating read events in select() If it was only a SSL_shutdown, i suppose you should be getting SSL_ERROR_ZERO_RETURN. In the other case SSL_ERROR_SYSCALL with errno=EPIPE seems possible. 5. The server puts the HTTP response Here I might expect the put to fail, but all appears normal. 6. As an HTTP Keep-Alive request has been made, the server enters a wait for the next read event. 7. The read event occurs (presumably due to the SSL shutdown), and now the get fails. SSL_get_error() returns SSL_ERROR_SYSCALL (I would expect Did you check errno here? i mean WSAGetLastError() or whatever. -jb -- Tact is the art of making a point without making an enemy. __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED] __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
Re: Problem handling unexpected SSL shutdown
Shaw Graham George wrote: The sequence of events goes like this: 1. The SSL handshake proceeds as normal. 2. The client puts an HTTP request 3. The server gets the HTTP request 4. The client then executes an (unexpected) SSL shutdown 5. The server puts the HTTP response Here I might expect the put to fail, but all appears normal. 6. As an HTTP Keep-Alive request has been made, the server enters a wait for the next read event. 7. The read event occurs (presumably due to the SSL shutdown), and now the get fails. SSL_get_error() returns SSL_ERROR_SYSCALL (I would expect SSL_ERROR_ZERO_RETURN for an SSL shutdown). ERR_get_error() returns 0. (SSL_get_shutdown() SSL_RECEIVED_SHUTDOWN) returns 0. Is this the expected behaviour? What I am looking for is a way of identifying the shutdown at the server, so that I can close the connection softly. I.e. you dont want your Keep-Alive's hanging around when the other end has gone. The client will take one of these actions: * It will simply close the socket. This can be picked up by your normal read() / write() failure scenarios. * It will write out a SSL shutdown notify packet, and then close the connection anyway. The server may or may not get the SSL shutdown notify packet due to send buffering, socket linger options, retransmission timeouts etc... But at server end will either receive the SSL shutdown notify before the socket close or it will just see a socket close. So again there is no special trickey here. * It will write out a SSL shutdown notify packet and wait for the acknowledgment from the server. This is 100% graceful and conceptually correct way to finish things off. To handle this your SSL_read() will signal a shutdown has been received (and from this point on no further SSL data will be received on that session that just closed). From seeing this you have a number of options at the server: * ACK the shutdown and issue your own shutdown (but only after you have finished writing all your application data with SSL_write()). A HTTP client can often send the request and then shut the socket down, the server can observe this right after it pulled the request off to process it in another thread, this does not mean you want to shut the socket down at your end until you have processed that request and finished writing the Content body back the other way, only then should you take action in response to seeing the client's SSL shutdown notify. * Once your SSL shutdown notify has hit the kernel write socket buffer, issue a TCP level shutdown(fd, SHUTDOWN_SEND). * Then wait to receive your shutdown ack or for the socket to close/timeout. This wait does not have to be forever, I have an implementation that will allow the client socket a configurable amount of time to provide the SSL shutdown notify ACK back to me, if it does not happen within that time I close the socket. * Ultimately all this work leads to closing the socket. If you implement everything above then your server is at least complying with all the available mechanisms within SSL during the shutdown sequence. I'm sure many implementations skip all the more complex points and jump right to the close the socket. I don't fully see the problem with your code, nor the concern of having a solution that works on Unix and Win32 because most people in the situation you are in would put the socket into idle state but listening for more data (an active Keep-Alive idle list). You will always get an event from listening for more data that will indicate the socket has been closed, or the socket has received a SSL shutdown notify request. You won't miss it. Here is a random fragment of my read code from Unix, it interests me if the there is a difference for Win32 but I would expect SSL_read() to return 0, when you can do your WSAGetLastError() returns WSAECONNABORTED to see why. int n = SSL_read(client-ssl, buffer, sizeof(buffer)); if(n 0) { int err = SSL_get_error(client-ssl, n); switch(err) { case SSL_ERROR_WANT_READ: ... // put the 'fd' on the read interested list break; case SSL_ERROR_WANT_WRITE: ... // put the 'fd' on the write interested list break; case SSL_ERROR_ZERO_RETURN: ... // peer change their mind on connecting to us // unrecoverable error so cleanup break; case SSL_ERROR__WHATEVER: ... // unrecoverable error so cleanup break; default: ... // unrecoverable error so cleanup // This is where I'd expect you to put your: // int wsa_errno = WSAGetLastError() // if you really want to know the exact cause of the error, // but the corrective action by the application at this // point is all the same (no matter what WSAGetLastError() // actually is. break; } } else if(n == 0) { if((SSL_get_shutdown(client-ssl) SSL_RECEIVED_SHUTDOWN) != 0) { /* recv_shutdown_notify */ // Peer signalled he is not going to send