SSL read and SSL write simultaneously

2019-05-11 14:55发布

I have two threads, mainThread and recvThread.

On recvThread, I call SSL_read(ssl, readBuffer, sizeof(readBuffer)). This blocks the thread until data is received.

Then, on mainThread I get told that some data needs to be sent. So, I call SSL_write(ssl, someData, sizeof(someData)).

Sometimes, this works fine. Other times, this fails with wierd internal error messages. My guess is that I can't call SSL_write whilst an SSL_read is occurring on the same ssl context. This makes total sense to me, but how do I fix it?

Do I make recvThread do something like:

SSL * ssl;
std::string data;
boost::mutex dataMutex;

while (recvThreadShouldBeRunning) {
    char readBuffer[100];
    auto nRead = SSL_read(ssl, readBuffer, sizeof(readBuffer)); //Non-blocking call to SSL_read.

    // Do something with nRead (handle errors, use data)

    {
        auto dataLock = boost::unique_lock<boost::mutex>(dataMutex);
        if (data.length() > 0)
        {
            SSL_write(ssl, data.c_str(), data.length());
        }
    }
    sleep(50);
}

and then when I need to send something...

{
    auto dataLock = boost::unique_lock<boost::mutex>(dataMutex);
    data = "some data";
}

This seems like it will work, but I think it is a rather ugly solution to my problem. Is there a way to somehow SSL_lock() SSL_wait_on_data() SSL_unlock()? Or is this the best way to go about it?

What is the standard way to go about this sort of problem?

Thanks for your time.

1条回答
我想做一个坏孩纸
2楼-- · 2019-05-11 15:30

The quote from the documentation seems to contain the answer:

OpenSSL can safely be used in multi-threaded applications provided that at least two callback functions are set, locking_function and threadid_func.

locking_function(int mode, int n, const char *file, int line) is needed to perform locking on shared data structures. (Note that OpenSSL uses a number of global data structures that will be implicitly shared whenever multiple threads use OpenSSL.) Multi-threaded applications will crash at random if it is not set.

locking_function() must be able to handle up to CRYPTO_num_locks() different mutex locks. It sets the n-th lock if mode & CRYPTO_LOCK, and releases it otherwise.

file and line are the file number of the function setting the lock. They can be useful for debugging.

-- threads - OpenSSL.

The example of using the locking-related functions (github):

crypto/threads/mttest.c shows examples of the callback functions on Solaris, Irix and Win32.

-- threads - OpenSSL.

查看更多
登录 后发表回答