c++ - boost ASIO,SSL : How do strands help the implementation?

标签 c++ multithreading ssl boost

TLDR:Strands 序列化跨完成处理程序共享的资源:这如何防止 ssl::stream 实现并发访问 SSL 上下文(内部使用)以用于并发读/写请求(stream::ssl 不是全双工的) ?请记住,strands 仅序列化完成处理程序调用或读/写请求的原始队列。 [感谢 sehe 帮助我更好地表达这一点]


我花了一天的大部分时间阅读有关 ASIO、SSL 和 strands 的内容;主要是关于 stackoverflow(其中有一些非常详细且表达明确的解释,例如 Why do I need strand per connection when using boost::asio? )和 Boost 文档;但有一点仍不清楚。

显然,strands 可以序列化同一 strand 中的回调调用,因此也可以序列化对这些 strands 共享的资源的访问。

但在我看来,boost::asio::ssl::stream 的问题不在完成处理程序回调中,因为它不是在 SSL 上下文上同时运行的回调,而是 ssl::stream即实现。

我不能确信在调用 async_read_some 和 async_write_some 时使用链,或者在完成处理程序中使用链,会阻止 io 引擎在不同线程中同时对 SSL 上下文进行操作。

调用 async_read_some 或 async_write_some 时显然使用 strand 意味着读取和写入不能同时排队,但我看不出这如何阻止内部实现同时执行读取和写入操作如果封装的 tcp::socket 同时准备好读取和写入,则不同线程上的时间。

这个问题的最后一个答案末尾的评论boost asio - SSL async_read and async_write from one thread声称对 ssl::stream 的并发写入可能会出现段错误,而不仅仅是交错,这表明该实现没有采用必要的锁来防止并发访问。

除非实际延迟的套接字写入绑定(bind)到排队它的线程/链(我看不出这是真的,否则它会破坏工作线程的有用性),我怎么能相信它是可能的在同一个 ssl::stream 上排队读取和写入,或者那种方式可能是什么?

也许 async_write_some 会立即使用 SSL 上下文处理所有数据,以生成加密数据,然后变成普通套接字写入,因此不会与同一链上的读取完成处理程序发生冲突,但它不会这并不意味着在完成处理程序在 strand 上排队之前,它不能与内部实现 socket-read-and-decrypt 冲突。不要介意可能发生的透明 SSL session 重新协商......

我注意到:Why do I need strand per connection when using boost::asio? “组合操作的独特之处在于对流的中间调用是在处理程序的链中调用的,如果存在的话,而不是在启动组合操作的链中调用。”但我不确定我指的是不是“对流的中间调用”。这是否意味着:“该流实现中的任何后续处理”?我怀疑不是

最后,为什么-哦-为什么,为什么 ssl::stream 实现不使用 futex 或其他在没有冲突时便宜的锁?如果遵循链规则(隐式或显式),则成本几乎不存在,但它会提供安全性。我问是因为我刚刚将 Sutter、Stroustrup 和其他人的宣传,即 C++ 让一切变得更好、更安全,转移到了 ssl::stream,在 ssl::stream 中似乎很容易遵循某些咒语,但几乎不可能知道你的代码是否真的安全.

最佳答案

答案是 boost ssl::stream 实现在内部使用 strands 进行 SSL 操作。

例如,async_read_some() 函数创建一个 openssl_operation 实例,然后调用 strand_.post(boost::bind(&openssl_operation::start, op))。 [ http://www.boost.org/doc/libs/1_57_0/boost/asio/ssl/old/detail/openssl_stream_service.hpp]

假设所有必要的内部 ssl 操作都在此内部链上执行似乎是合理的,从而序列化对 SSL 上下文的访问。

关于c++ - boost ASIO,SSL : How do strands help the implementation?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33041635/

相关文章:

c++ - 依赖项、命名空间和 header

c++ - 我们可以在 Windows 上使用 .so 文件吗?

c++ - 如何构造包含 union 的结构的 unique_ptr?

java - 跨线程共享一个 jdbc "Connection"

java - 如何使异步任务在 Java 8 中具有较低的优先级?

node.js - NodeJS 子进程无法发送 net.socket fd :3

windows - 只允许用户运行指定证书的程序(Windows)

c++ - 在 C++ 中使用 union 时是否可以跳过字节?

.net - 带有 ssl : Certificate not recognized when run under IIS 的 HttpRequest

ssl - 为 strpi 项目运行 npm i 时证书链中的自签名证书