diff --git a/src/Makefile.am b/src/Makefile.am index 19710652..765673b1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -70,6 +70,7 @@ nghttpd_SOURCES = ${HELPER_OBJECTS} ${HELPER_HFILES} nghttpd.cc \ HttpServer.cc HttpServer.h h2load_SOURCES = util.cc util.h http2.cc http2.h h2load.cc h2load.h \ + ssl.cc ssl.h \ h2load_session.h \ h2load_http2_session.cc h2load_http2_session.h diff --git a/src/h2load.cc b/src/h2load.cc index 2e930501..8f0413af 100644 --- a/src/h2load.cc +++ b/src/h2load.cc @@ -50,6 +50,7 @@ #ifdef HAVE_SPDYLAY #include "h2load_spdy_session.h" #endif // HAVE_SPDYLAY +#include "ssl.h" #include "http2.h" #include "util.h" @@ -684,6 +685,8 @@ int main(int argc, char **argv) SSL_load_error_strings(); SSL_library_init(); + ssl::LibsslGlobalLock(); + http_parser_url u; memset(&u, 0, sizeof(u)); auto uri = argv[optind]; diff --git a/src/ssl.cc b/src/ssl.cc new file mode 100644 index 00000000..5dcc179c --- /dev/null +++ b/src/ssl.cc @@ -0,0 +1,74 @@ +/* + * nghttp2 - HTTP/2.0 C Library + * + * Copyright (c) 2014 Tatsuhiro Tsujikawa + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "ssl.h" + +#include +#include +#include +#include + +#include + +namespace nghttp2 { + +namespace ssl { + +namespace { +std::vector ssl_global_locks; +} // namespace + +namespace { +void ssl_locking_cb(int mode, int type, const char *file, int line) +{ + if(mode & CRYPTO_LOCK) { + ssl_global_locks[type].lock(); + } else { + ssl_global_locks[type].unlock(); + } +} +} // namespace + +LibsslGlobalLock::LibsslGlobalLock() +{ + if(!ssl_global_locks.empty()) { + std::cerr << "OpenSSL global lock has been already set" << std::endl; + assert(0); + } + ssl_global_locks = std::vector(CRYPTO_num_locks()); + // CRYPTO_set_id_callback(ssl_thread_id); OpenSSL manual says that + // if threadid_func is not specified using + // CRYPTO_THREADID_set_callback(), then default implementation is + // used. We use this default one. + CRYPTO_set_locking_callback(ssl_locking_cb); +} + +LibsslGlobalLock::~LibsslGlobalLock() +{ + ssl_global_locks.clear(); +} + +} // namespace ssl + +} // namespace nghttp2 diff --git a/src/ssl.h b/src/ssl.h new file mode 100644 index 00000000..fb3ae5aa --- /dev/null +++ b/src/ssl.h @@ -0,0 +1,43 @@ +/* + * nghttp2 - HTTP/2.0 C Library + * + * Copyright (c) 2012 Tatsuhiro Tsujikawa + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "nghttp2_config.h" + +namespace nghttp2 { + +namespace ssl { + +// Acquire OpenSSL global lock to share SSL_CTX across multiple +// threads. The constructor acquires lock and destructor unlocks. +class LibsslGlobalLock { +public: + LibsslGlobalLock(); + ~LibsslGlobalLock(); + LibsslGlobalLock(const LibsslGlobalLock&) = delete; + LibsslGlobalLock& operator=(const LibsslGlobalLock&) = delete; +}; + +} // namespace ssl + +} // namespace nghttp2