Boost.Asio SSL 线程安全

2021-12-24 00:00:00 multithreading openssl c++ boost boost-asio

我是创建一个 所有 SSL 套接字共享的链,还是每个 SSL 上下文(由任何关联的套接字共享)创建一个链?

Boost.Asio SSL 文档说明了这一点,但没有提到上下文.我认为这意味着我必须对所有内容只使用一个链,但我认为这是在 OpenSSL 支持多线程之前编写的.

<块引用>

SSL 和线程

SSL 流对象不执行自己的锁定.因此,所有异步 SSL 操作都必须在隐式或显式链中执行.请注意,这意味着在单线程程序中不需要同步(因此不会产生锁定开销).

我很可能只有一个 SSL 上下文,但我想知道将链由 SSL 上下文或全球网络服务拥有是否更合适.

我确实为 CRYPTO_set_locking_callback 提供了一个处理程序,以防万一.

解决方案

UPDATE

David Schwarz 对这个答案的要点提出了质疑,我非常尊重他在这方面的权威.

有理由期??望 ssl 上下文可以在线程之间共享 - 至少对于某些操作,如果只是为了促进 SSL 会话恢复.

我认为 David 有使用 SSL 上下文的经验,因为 OpenSSL 使用它.Boost ASIO 依次使用那个(至少在我知道的所有平台上).所以,要么大卫写了一个答案来分享他的知识,要么你/我必须花一些时间阅读 OpenSSL 文档和 Boost Asio 源代码,以找出适用于 Boost Asio 的 ssl::context用法.

以下是目前记录的限制条件.

[后面是旧答案]

<块引用>

线程安全

<小时><块引用>

一般来说,并发使用不同的对象是安全的,但并发使用单个对象是不安全的.但是,io_service 等类型提供了更强大的保证,即并发使用单个对象是安全的.

从逻辑上讲,因为文档没有特别提到 ssl_context 类的线程安全性,所以您必须得出结论,它不是.

如果您使用某些特定的钩子(就像您提到的),那么您知道底层 SSL 库支持这一点并不重要.这仅告诉您,制作 ssl_context 线程感知可能并不难.

但是在您(与库开发人员合作)提供此补丁之前,它是不可用的.

长话短说,您可以从单个链访问每个 ssl_context.

Do I create one strand that all of my SSL sockets share, or one strand per SSL context (shared by any associated sockets)?

Boost.Asio SSL documentation states this, but it doesn't mention contexts. I assume that this means I must use only one strand for everything, but I think this was written before OpenSSL had multithreading support.

SSL and Threads

SSL stream objects perform no locking of their own. Therefore, it is essential that all asynchronous SSL operations are performed in an implicit or explicit strand. Note that this means that no synchronisation is required (and so no locking overhead is incurred) in single threaded programs.

I'm most likely only going to have only one SSL context, but I'm wondering if it's more proper for the strand to be owned by the SSL context, or by the global network service.

I did provide a handler to CRYPTO_set_locking_callback in case that matters.

解决方案

UPDATE

The gist of this answer is contested by David Schwarz, whose authority in this area I hold in high esteem.

There are reasons to expect that ssl contexts can be shared between threads - at least for some operations, if only to facilitate SSL session resumption.

I think David has experience with SSL context as OpenSSL uses it. Boost ASIO uses that in turn (at least on all platforms I know of). So, either David writes an answer sharing his knowledge, or you/me would have to spend some time with the OpenSSL documentation and Boost Asio source code to figure out the effective constraints that apply to Boost Asio's ssl::context usage.

Below are the constraints as currently documented.

[old answer text follows]

Thread Safety


In general, it is safe to make concurrent use of distinct objects, but unsafe to make concurrent use of a single object. However, types such as io_service provide a stronger guarantee that it is safe to use a single object concurrently.

Logically, because the documentation doesn't mention thread-safety of the ssl_context class in particular, you must conclude that it is not.

It doesn't matter that you know that the underlying SSL library supports this if you use some particular hooks (like you mention). This only tells you that it might not be hard to make ssl_context thread-aware.

But until you (work with the library devs to) provide this patch, it's not available.

Long story short, you access each ssl_context from a single strand.

相关文章