我正在尝试使用 Openssl 在 C++ 中通过 TCP 套接字创建通用 TLS。该套接字将用于运行选择循环并利用非阻塞 I/O 的程序。
我担心在先前的 SSL_get_error
调用返回 SSL_ERROR_WANT_WRITE
后底层 TCP 套接字变得可读的情况。我可以想到可能发生这种情况的两种情况:
- 本地应用程序和远程应用程序同时决定发送大量数据。两个应用程序同时调用
SSL_write
,随后对两个应用程序的SSL_get_error
调用返回SSL_ERROR_WANT_WRITE
。从两个应用程序发送的 TCP 数据包在线路上交叉。在先前的SSL_get_error
调用返回SSL_ERROR_WANT_WRITE
后,本地应用程序的 TCP 套接字现在可读。 - 如上,除了远程 Openssl 库决定在写入任何应用程序数据之前在
SSL_write
调用中执行 SSL 重新协商。这只是将本地应用程序的 TCP 套接字上接收到的数据的含义从加密的应用程序数据更改为 session 重新协商数据。
本地应用程序应该如何处理这些数据?应该:
- 调用
SSL_write
,因为它当前正在写入? - 调用
SSL_read
,就像套接字空闲时会发生的那样?
最佳答案
SSL_ERROR_WANT_READ 和 SSL_ERROR_WANT_WRITE 可能由(重新)协商或完整的套接字缓冲区引起,并且不仅会发生在 SSL_read 和 SSL_write 中,还会发生在非阻塞套接字上的 SSL_connect 和 SSL_accept 中。您所要做的就是等待所需的套接字状态(例如可读或可写),然后重复相同的操作。例如。如果你从 SSL_write 得到一个 SSL_ERROR_WANT_READ 你等到套接字变得可读(使用选择,轮询或类似的)然后再次调用 SSL_write。与 SSL_read 相同。
将 SSL_CTX_set_mode 与 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|SSL_MODE_ENABLE_PARTIAL_WRITE 结合使用可能也很有用。
关于ssl - 在 Openssl 调用返回 WANT_WRITE 后,TLS Openssl 连接中使用的 TCP 套接字变得可读,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20815854/