[openssl-users] Graceful shutdown of TLS connection for blocking sockets

Wouter Verhelst wouter.verhelst at fedict.be
Wed Oct 11 07:25:56 UTC 2017

On 08-10-17 22:55, Thomas J. Hruska wrote:
> On 10/8/2017 7:28 AM, Michel wrote:
>> While I understand that using non-blocking descriptors is a better
>> practice,
>> I still do not see why select() should NEVER be used for blocking sockets
>> (except when combined/interfered with the internal OpenSSL state
>> machine or
>> equivalent mechanism).
>> Could you please elaborate or give an example ?
>>   Regards,
>> Michel.
> Example:  You call select(), it returns the descriptor as readable, you
> pass it into SSL_read(), and SSL_read() blocks.  You are worse off than
> before you used select() since you made the incorrect assumption that
> you could do something when select() returns and not have a blocking
> socket block.
> Just because select() says that something is readable (or writable) does
> not actually make it so.

Er, yes it does. Perhaps not as much as you wanted, but yes there will
be something there.

> The function only makes sense for non-blocking
> descriptors.  The use of select() with a blocking descriptor is always
> wrong.

Er, no it isn't.

Example: you select() on all your file descriptors in your main thread.
When select() tells you that one of them is ready to read, you fire off
a message to a thread pool and have one of the worker threads in that
thread pool (eventually) handle reading your data in a blocking manner.
Once the thread from the thread pool has finished reading, it will start
work on another file descriptor. This allows you to serve more clients
than you have threads, so allows to avoid overloading your server, but
since you use blocking I/O on your file descriptors you can get away
with not having the extra complexity of the state machine that blocking
I/O requires.

You can't implement that properly without doing select() on blocking
file descriptors, however.

> Non-blocking code is actually easier to implement than you think.

It isn't too hard, to write, that's true. It's more difficult to reason
about and to avoid bugs with, however (and for thread pools, you just
use a library -- e.g., GThreadPool from libglib).

Wouter Verhelst

More information about the openssl-users mailing list