在多核机器上的OpenSSL

Lor*_*aka 5 c c++ openssl

我正在进入OpenSSL lib的第一步,感觉有点迷失.我的机器是一个多线程(Xeon系列,如果有人需要信息,可以分享更多)与Linux操作系统.

应用程序构建是SSL代理,因此我需要尽可能快地处理多个TCP流,这意味着我想尽可能地将lib作为无锁运行.

在看了一下这里crypto/crypto.h主要是关于这一节:

# ifndef OPENSSL_NO_LOCKING
#  ifndef CRYPTO_w_lock
#   define CRYPTO_w_lock(type)     \
        CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
#   define CRYPTO_w_unlock(type)   \
        CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
#   define CRYPTO_r_lock(type)     \
        CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__)
#   define CRYPTO_r_unlock(type)   \
        CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__)
#   define CRYPTO_add(addr,amount,type)    \
        CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__)
#  endif
Run Code Online (Sandbox Code Playgroud)

我试图挖掘代码/ API并且有点迷失.我的问题是:

  • OpenSSL lib对多核/线程应用程序有什么支持?
  • lib的哪些部分只能有一个实例(单例)?

Jer*_*ner 5

OpenSSL lib对多核/线程应用程序有什么支持?

支持多线程应用程序,但请注意它不"正常工作" - 特别是,您必须安装一些特殊的回调,以便OpenSSL执行必要的序列化/锁定,否则您的程序将受到竞争条件的影响而无法正常工作正确.(即使安装了回调函数,您也希望能够访问限制在单个线程中的任何特定OpenSSL套接字/连接,即没有两个线程同时在同一连接的OpenSSL句柄上执行操作而不进行同步)

lib的哪些部分只能有一个实例(单例)?

好吧,锁定回调将(必然)只有一个实例,因为所有线程都使用它们来序列化关键部分.

此外,SSL库设置函数(SSL_load_error_strings(),SSL_library_init()等)应仅在应用程序执行开始时(即在您生成任何线程之前)调用,并且SSL库拆卸函数(如果有)只有在任何生成的线程连接()并丢弃后才应调用; 这样你就可以避免任何可能的竞争条件,其中线程试图使用尚未完全构建的OpenSSL资源,或者已经部分或完全销毁.

我想尽可能地将lib作为无锁运行.

好吧,你可能在那里运气不好 - OpenSSL不是为了无锁而设计的; 其会话使用共享的非只读数据结构,并且必须同步对这些数据结构的访问或发生错误.我认为你能做的最好的事情就是按照建议使用锁定回调,并相信OpenSSL实现者不会持有超过严格必要的锁定.如果这还不够,那么您可能必须开始寻找不同的SSL库实现,或者考虑使用多进程而不是多线程.