From 4c18ac2b180395665a186e2c9076d25944239fcb Mon Sep 17 00:00:00 2001 From: yhirose Date: Fri, 19 Jul 2019 17:03:47 -0400 Subject: [PATCH] Added locking_callback for OpenSSL versions prior to 1.1.0 --- httplib.h | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/httplib.h b/httplib.h index 5adfc2a..8b17b69 100644 --- a/httplib.h +++ b/httplib.h @@ -78,6 +78,7 @@ typedef int socket_t; #include #if OPENSSL_VERSION_NUMBER < 0x10100000L +#include inline const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *asn1) { return M_ASN1_STRING_data(asn1); } @@ -2397,8 +2398,6 @@ namespace detail { template inline bool read_and_close_socket_ssl(socket_t sock, size_t keep_alive_max_count, - // TODO: OpenSSL 1.0.2 occasionally crashes... - // The upcoming 1.1.0 is going to be thread safe. SSL_CTX *ctx, std::mutex &ctx_mutex, U SSL_connect_or_accept, V setup, T callback) { SSL *ssl = nullptr; @@ -2461,6 +2460,32 @@ read_and_close_socket_ssl(socket_t sock, size_t keep_alive_max_count, return ret; } +#if OPENSSL_VERSION_NUMBER < 0x10100000L +class SSLThreadLocks { +public: + SSLThreadLocks() { + CRYPTO_set_locking_callback(locking_callback); + } + + ~SSLThreadLocks() { + CRYPTO_set_locking_callback(nullptr); + } + +private: + static void locking_callback(int mode, int type, const char * /*file*/, int /*line*/) { + if (mode & CRYPTO_LOCK) { + locks_[type].lock(); + } else { + locks_[type].unlock(); + } + } + + static std::vector locks_; +}; + +std::vector SSLThreadLocks::locks_(CRYPTO_num_locks()); +#endif + class SSLInit { public: SSLInit() { @@ -2469,6 +2494,11 @@ public: } ~SSLInit() { ERR_free_strings(); } + +private: +#if OPENSSL_VERSION_NUMBER < 0x10100000L + SSLThreadLocks thread_init_; +#endif }; static SSLInit sslinit_;