我们有一个使用套接字 10 年的多线程网络应用程序,现在我们正尝试使用 OpenSSL 0.9.8L 保护该应用程序。多年来,应用程序的网络协议被设计为利用单套接字连接的双工特性;应用程序同时在同一个套接字上读取和写入。应用程序自己管理底层套接字,并通过 SSL_set_fd 将套接字描述符传递给 OpenSSL。
我们为多线程支持配置了 OpenSSL,同时设置了静态和动态锁定回调,例如 CRYPTO_set_id_callback()、CRYPTO_set_locking_callback() 等。在大多数情况下,应用程序运行良好,但我们看到了一些异常情况。为了帮助我们确定原因,对几个问题的明确回答会有所帮助。
OpenSSL 常见问题页面声明 OpenSSL 是线程安全的,但坚持单个“SSL 连接可能不会被多个线程同时使用”。
http://www.openssl.org/support/faq.html#PROG1
- 对或错。OpenSSL 连接 API 调用(SSL_Read、SSL_Write 等)可能在同一个 SSL 实例上同时执行(SSL_new 调用返回的指向 SSL 的指针)?
- 对或错。对于启用 SSL_MODE_AUTO_RETRY 的阻塞套接字,线程 A 可以在 SSL 实例 X 上调用 SSL_Read() 而线程 B 在 SSL 实例 X 上同时调用 SSL_Write()?
- 对或错。当应用程序使用非阻塞套接字并防止在同一 SSL 实例上同时执行 SSL_Read 和 SSL_Write(以及其他连接 API 调用)时,OpenSSL 可以正常工作吗?
- 对或错。SSL_new 返回的 OpenSSL SSL 实例绑定到名为 SSL_new 的单个线程;绑定意味着 SSL 实例不能与任何其他线程共享,SSL 实例仅对调用 SSL_new 的线程有效?
- 对或错。如果线程A i) 调用SSL_new,获得一个SSL 实例X 并且ii) 使用SSL 实例X 调用SSL_Read。如果线程B 非并发地使用同一个SSL 实例X 调用SSL_Read/SSL_Write,最终会失败?