AcceptEx和OpenSSL

时间:2011-12-14 19:50:09

标签: openssl iocp

我想知道使用AcceptEx和OpenSSL从客户端处理新连接的正确方法。我有一个非常好的工作服务器,它通过常规HTTP使用AcceptEx和IO完成端口。我想为它添加OpenSSL支持。

我在网上看过几篇关于使用OpenSSL和非阻塞套接字的文章:

他们似乎都没有涉及如何做到这一点,因为他们主要关注连接的客户端。 AcceptEx建立套接字连接并返回从客户端发送的第一个数据。我发布的第一个链接讨论了如何使用IOCP处理传入数据。到目前为止,我已经尝试过那里没有运气的东西。基本上我在服务器上看到的是以下内容:

  1. 收到已接受的连接完成。
  2. 我使用SSL_new(ctx)
  3. 创建SSL对象
  4. 我使用BIO_new(BIO_s_mem())创建进出BIO对象。
  5. 我通过调用SSL_set_bio(ssl,bioIn,bioOut)在SSL对象中设置BIO。
  6. 我调用SSL_set_accept_state(ssl)以允许SSL_read和SSL_write进行协商。
  7. 然后我继续尝试处理AcceptEx调用读取的第一个数据缓冲区。

    1. 我调用BIO_Write(bioIn,buf,len)将读取的数据复制到SSL中。
    2. 然后我检查bioOut上的待处理握手数据,看看是否需要将其发送回客户端。当接受新连接时,我从未见过bioOut中有任何数据。
    3. 然后我调用SSL_read(ssl,plainTextBuf,len)来尝试解密我在步骤6中放入bioIn的数据。这总是返回-1,而SSL_get_error返回ERROR_SSL_WANT_READ。据我了解,这意味着bioIn没有完整的SSL记录,因此SSL在解密任何内容之前需要来自客户端的更多数据。
    4. 这是我开始遇到问题的地方,我觉得我需要一些方向。我尝试过很多东西。如果我此时重复调用SSL_read,它将无限返回ERROR_SSL_WANT_READ,可能是因为使用内存BIO实际上并不通过套接字进行通信以接收更多数据。我应该发布一个WSARecv调用来等待来自客户端的更多数据吗?

      此时我还尝试使用BIO_read检查bioOut缓冲区,看看是否有需要发送回客户端的数据。确实有一些,我使用WSASend发送回来,并发布另一个WSARecv调用等待更多数据(响应我的发送)。这导致从客户端接收更多数据(WSARecv在发送完成后完成),因此看起来好像连接正在进行中。但是,当我处理完成的读取时,SSL_read和BIO_read都返回ERROR_SSL_WANT_READ。因此,我没有足够的数据来解密完整记录,而且我没有任何东西可以发送回客户端。发布另一个WSARecv调用以响应这种情况也不会从客户端收到任何更多数据。我不知道SSL在这里想要什么。

      我现在被困住,但我会继续尝试更多的事情。如果我发现任何问题,我会用评论更新这个问题。

1 个答案:

答案 0 :(得分:3)

您在套接字上发出一个新的重叠读取,等待它完成,将数据推送到您的BIO并循环执行您当前正在执行的步骤。

ERROR_SSL_WANT_READ意味着BIO需要更多数据,即它需要另一次读取。

在数据流期间的任何时候,您可能需要允许SSL层发送或接收更多数据,然后才能将更多应用程序级数据推送到BIO中。

我认为我在你引用的文章中清楚地涵盖了所有这些内容;并且该文章中的代码是我在自己的基于IOCP的服务器中使用的代码的基础......