Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenSSL on mutli-core machine

Tags:

c++

c

openssl

I'm doing my first steps into the OpenSSL lib and feel a bit lost. My machine is a multi-threaded (Xeon series, can share more if someone need the info) with Linux OS.

The application build is SSL-Proxy thus I need to handle multiple TCP flows as fast as possible, meaning I want to run the lib as lock-less as possible.

After looking a bit inside crypto/crypto.h mainly on this section:

# 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

I was trying to dig in the code/API and got a bit lost. My questions are:

  • What support does OpenSSL lib have for multi-core/thread applications?
  • What parts of the lib can have only one instance (singleton)?
like image 330
LordTitiKaka Avatar asked Dec 29 '16 20:12

LordTitiKaka


1 Answers

What support does OpenSSL lib have for multi-core/thread applications?

Multithreaded applications are supported, but note that it doesn't "just work" -- in particular, you have to install some special callbacks so that OpenSSL will do the necessary serialization/locking, otherwise your program will suffer from race conditions and not work correctly. (and even with the callbacks installed, you'll want to keep access to any particular OpenSSL socket/connection confined to a single thread, i.e. don't have two threads performing operations on the same connection's OpenSSL handles at the same time without synchronization)

What parts of the lib can have only one instance (singleton)?

Well, the locking callbacks will (of necessity) have only one instance, since they are used by all threads to serialize critical sections.

Furthermore, the SSL library setup functions (SSL_load_error_strings(), SSL_library_init(), etc) should be called only at the beginning of your applications execution (i.e. before you've spawned any threads), and the SSL library teardown functions (if any) should be called only after any spawned threads have been join()'d and discarded; that way you'll avoid any possible race condition where threads try to use OpenSSL resources that have not yet been fully constructed, or have already been partially or fully destroyed.

I want to run the lib as lock-less as possible.

Well, you're probably out of luck there -- OpenSSL wasn't designed to run lockless; its sessions use shared non-read-only data structures and accesses to those data structures have to be synchronized or errors will occur. I think the best you can do is use the lock callbacks as recommended and trust the OpenSSL implementers to not hold the locks longer than is strictly necessary. If that isn't sufficient then you may have to start looking for a different SSL library implementation, or perhaps consider going multiprocess instead of multithreaded.

like image 125
Jeremy Friesner Avatar answered Nov 08 '22 06:11

Jeremy Friesner