I have read in this SO question that OpenSSL socket communication can be only ha
ID: 658577 • Letter: I
Question
I have read in this SO question that OpenSSL socket communication can be only half duplex in a single thread.
Assuming what I have read is true, I am wondering if I can apply philosopher's dining problem to send SSL_write() and receive SSL_read() on a non-blocking socket in a single thread that communicates with a OpenSSL TCP Server. Both server and client are non-blocking.
Would that be a good model? Or should I always set priority to read SSL_read()? What would be the best approach to code?
I am using C++ to code this single threaded non-blocking socket model (without BOOST or other libraries).
Explanation / Answer
From the comments I see that your "half-duplex" refers to the fact, that you should not operate on the same SSL object from different threads at the same time (or use explicit locking) and thus cannot use SSL_read and SSL_write at the same time from different threads.
While most protocols are request/response and thus don't need parallel read and write the usual way to reach what you want is with non-blocking I/O and select. This works similar to non-blocking I/O with normal sockets. There are two major differences:
There might be SSL handshakes inside SSL_read and SSL_write, so a SSL_read might need to write data and SSL_write might need to read data. So you need to check for the ERROR_SSL_WANT_READ and ERROR_SSL_WANT_WRITE conditions. Same with SSL_connect and SSL_accept.
SSL_read returns only the amount of data you ask for, but there might be more data in the SSL frame. In this case the data are buffered internally inside the SSL object and you will not get from a call to select that there are more data (because they've already read from the socket). You need to check for this case with SSL_pending, or make sure that you always try to read the maximum amount of data which fits into an SSL frame (16k).
And for your dining philosophers: You have this kind of problem only with threads. With single-threaded you don't need locking and thus have no locking problems (which often makes the code faster too because of no lock contention).