我们有一个使用套接字的多线程网络应用程序已有10年了,现在我们正尝试使用OpenSSL 0.9.8L保护该应用程序。多年来,应用程序的网络协议(protocol)已被设计为利用单个套接字连接的双工特性。应用程序同时在同一套接字上读写。应用程序自行管理基础套接字,并通过SSL_set_fd将套接字描述符传递给OpenSSL。
我们将OpenSSL配置为支持多线程,同时设置了静态和动态锁定回调,例如CRYPTO_set_id_callback(),CRYPTO_set_locking_callback()等。在大多数情况下,应用程序运行良好,但我们看到了一些异常情况。为了帮助我们确定原因,对一些问题的明确答案将有所帮助。
“OpenSSL常见问题”页面指出OpenSSL是线程安全的,但坚持认为单个“SSL连接可能无法同时由多个线程使用”。
http://www.openssl.org/support/faq.html#PROG1
最佳答案
1,正确还是错误OpenSSL连接API调用(SSL_Read,SSL_Write等)是否可以在同一SSL实例上同时执行(由SSL_new调用返回的指向SSL的指针)?
* 错误。不,您不能在同一SSL实例上同时使用SSL_read/SSL_write。*
2.是非题。对于阻塞启用了SSL_MODE_AUTO_RETRY的套接字,线程A可以在SSL实例X上调用SSL_Read(),而线程B可以同时在SSL实例X上调用SSL_Write()?
* 与上述相同。使用或不使用SSL_MODE_AUTO_RETRY,您不能同时使用同一SSL实例X并行执行SSL_read和SSL_write *
3.是非题。当应用程序使用非阻塞套接字并阻止在同一SSL实例上同时执行SSL_Read和SSL_Write(以及其他连接API调用)时,OpenSSL可以无错误地工作?
是的。如果没有并发执行,则OpenSSL可以很好地适用于阻塞套接字和非阻塞套接字。
4,是非题SSL_new返回的OpenSSL SSL实例绑定(bind)到名为SSL_new的单个线程。 bound表示SSL实例不得与任何其他线程共享,因此该SSL实例仅可在名为SSL_new?的线程上使用。
错误。 OpenSSL本身未将SSL实例绑定(bind)到任何线程。您可以在另一个线程中的一个线程中使用创建的SSL实例,只要在任何一个时间点只有一个线程正在使用一个SSL实例即可。
5,真假如果线程A i)调用SSL_new,获得SSL实例X,并且ii)使用SSL实例X调用SSL_Read。如果线程B非同时使用同一SSL实例X调用SSL_Read/SSL_Write,最终将发生故障。
错误。线程A和线程B都可以使用相同的SSL实例X,只要它们都不在SSL实例X上执行并发操作即可。