0
votes

I am currently writing a client using OpenSSL. Ideally the client has e.g. 4 threads that waits to read from server, when one thread reads, it may perform some work, then write to the server and return in line to read from the server.

The OpenSSL documentation states that I can not use SSL_read() and SSL_write() from different threads. However SSL_read()is a blocking call, and I can not SSL_write() until it returns? I know I could use select to and do a non-blocking SSL_read() but I find this solution less optimal.

OpenSSL further complicates the issue by stating that SSL_write() can return SSL_ERROR_WANT_READ. If all threads wants to write, then this would cause a dead-lock.

My question is: if I was to use a separate input and output BIO on the SSL-connection instead, would it be possible to do a blocking read from the input BIO while another thread was writing to the output BIO?

Any other suggestions are welcome, I have also looked at the gnutls, which supports writing and reading to the same session from multiple threads.

1
The connection isn't multi-threaded. If you need four threads you need four connections, unless you can arbitrate and sequentialize among them yourself. SSL_read() being a blocking call means that it blocks, not that you can't call other functions concurrenctly. Your statement about a deadlock is therefore also a non sequitur. Unclear what you're asking. - user207421
If I want to SSL_write() while waiting for a blocking SSL_read() to complete, it could take forever. - sigvardsen
Where did you get that from? If a handshake is in progress both the receive and the send write will unblock and return with appropriate status codes, and if it isn't the send can proceed concurrently with the receive. - user207421
As the documentation states, SSL_read and SSL_write can no be called simultaneously. Therefore if I need to SSL_read() from one thread, I am not allowed to call SSL_write() from another, causing the application to hang. - sigvardsen
So you need four connections, as I stated originally. - user207421

1 Answers

2
votes

It is unclear as to why you say using select with non-blocking sockets is a sub-optimal solution for you.

OpenSSL doesn't allow SSL_read and SSL_write to happen simultaneously because Handshake can be triggered due to renegotiation request and Handshake state cannot be shared across threads. Similarly the Non-Blocking or other error information is stored in a single variable per session and when you use the same session/connection in multiple threads a race condition can occur. In my suggestion, better do all operations related to one SSL connection / session in a Single Thread. If you have more than one connection, you can spawn threads to handle different connections on different threads.