6

我已经使用 OpenSSL API 编写了一个 SSL 客户端来与一个 SSL 服务器进行交互。在 OpenSSL 站点中,我了解到写入一些数据后需要刷新写入缓冲区。我在我的客户端程序中使用 SSL_Write 和 SSL_Read。正如 OpenSSL 网站建议的那样,我尝试使用 BIO_flush(BIO*) 刷新数据,我在这里崩溃了。

我正在使用从这个站点获得的 SSL 库

在这里,我不清楚 BIO_flush 是刷新读取缓冲区还是写入缓冲区..:-( 所以我只想知道是否有其他方法可以刷新 SSL 写入缓冲区...?

这是有关我的客户程序的详细信息。

  1. 使用 SSL_new 创建 SSL 对象(mSsl)
  2. 创建 TCP 套接字并与服务器建立连接
  3. 使用 BIO_new_socket(socket_id,BIO_NOCLOSE) 创建 BIO 对象(mBio)
  4. 使用 SSL_set_bio(mSsl,mBio,mBio) 将 BIO 对象设置为 SSL 对象;
  5. 使用 SSL_set_fd(mSsl,socket_id) 将套接字设置为 SSL 对象;
  6. 使用 SSL_Connect(mSsl) 与服务器建立 SSL 连接;

在上述步骤之后,我启动了两个单独的线程进行写入和读取。写入线程使用 SSL_write 将数据写入服务器,读取线程使用 SSL_Read 从服务器读取数据。

在使用 SSL_Write 写入每个数据包后的写入线程中,我调用 BIO_flush(mBio)。

在整个程序中,我只在这个地方直接使用 mBio 对象来进行生物缓冲区刷新。

当我开始发送一些数据包时,程序在 BIO_flush 中崩溃......根据转储说它在 BIO_ctrl 函数中。我没有得到更多的东西。

有没有人使用我上面提供的链接并面临同样的问题..?如果是,请让我知道您是否知道解决方案。

是否有任何线程同步规则可以使用 BIO_flush()...?我的意思是调用 BIO_flush SSL_Read 不应该像那样同时发生......?

4

2 回答 2

9

您从哪里得知写入后需要刷新写入缓冲区?

我也在寻找一个刷新功能,但找不到。

我认为它的工作原理是这样的:对 SSL_write 的每次调用都会产生至少一个 SSL 记录并将其发送到套接字,在那里 nagle 算法可能会在内核中将其缓冲片刻并快速将其提交到外部。

所以 SSL_write 中没有缓冲,因此没有刷新!

我宁愿有一个刷新功能并将所有 SSL 记录填充到边缘,但据我所知,这不可用。我现在计划进行自己的缓冲并尽可能多地调用 SSL_write。

BTW: I just wrote a little test program: It sends a buffer with one write and then I ran it again, calling SSL_write for each character. Both times I run tcpdump and in Wireshark I could see that the first run had few large application data records and the second run had many small records. So I think it's confirmed.

于 2014-01-03T10:33:17.970 回答
2

BIO_flush 用于刷新写入数据。

您的 BIO_flush 和 SSL_read/write 的混合和匹配是有问题的,因为 BIO 结构不知道您的 SSL_read/write 调用。

使用 BIO_read/write 会获得更好的结果。

如果您绝对需要使用 SSL_read/write,则应避免使用 BIO。

我想你会在这个 OpenSSL 文档末尾的例子中走得更远。

简单的 OpenSSL 客户端示例

如果您在尝试该示例时仍然遇到崩溃,则您正在使用的特定库构建可能存在问题。

于 2013-06-18T14:20:45.663 回答