如何将SSL_read和电子投票结合起来?

How to combine SSL_read and epoll?

本文关键字:结合 起来 SSL read      更新时间:2023-10-16

我正在编写一个带有基于事件的网络库的HTTP代理服务器(使用epoll(。

假设上游有一个快速的HTTPS和一个缓慢的HTTP(S(下游。所以我必须将上游数据存储到缓冲区,并在缓冲区已满时将上游读取事件从网络库中分离出来。

但正如我们所知,SSL_read可能会部分返回数据。因此,请考虑以下情况:

  1. 缓冲区大小32,并在网络库上附加读取事件
  2. 上游发送32字节,整个HTTP消息为32字节
  3. 网络库调用读取事件回调
  4. 拨打SSL_read(ssl, buf, 32)SSL_read返回16
  5. 16字节发送到下游并在网络库上附加读取事件
  6. 读取回调永远不会被调用,因为剩余的 16 个字节在 openSSL 缓冲区中,并且没有更多来自上游的字节

那么有没有好的解决方案呢?

OpenSSL 的基于 SSL 的旧版 API 不遵循您尝试使用的传统套接字 I/O 事件模型。

使用非阻塞套接字时,不应在调用SSL_read()之前等待套接字读取事件。您应该无条件地调用SSL_read(),并通过返回SSL_ERROR_WANT_READ错误来让它告诉您何时需要套接字中的更多数据。只有这样,您才应该等待套接字读取事件(如果它返回SSL_ERROR_WANT_WRITE,请等待套接字写入事件(,然后再调用SSL_read()

如果您想使用传统的套接字事件来驱动读取/写入,请改用OpenSSL较新的基于BIO的API。使用 BIO 对将收到的加密字节推送到 OpenSSL 引擎中,让它在读取时将解密的字节推送给您,反之亦然。然后,您可以根据需要处理套接字 I/O。