| 97 | #endif /* not OPENSSL_VERSION_NUMBER < 0x10100000L */ |
| 98 | |
| 99 | static void init() { |
| 100 | #if OPENSSL_VERSION_NUMBER < 0x10100000L |
| 101 | if (++crypto_refs == 1) { |
| 102 | // according to |
| 103 | // https://wiki.openssl.org/index.php/Library_Initialization#libcrypto_Initialization |
| 104 | OpenSSL_add_all_algorithms(); |
| 105 | ERR_load_crypto_strings(); |
| 106 | |
| 107 | // initialize locking callbacks, needed for thread safety. |
| 108 | // http://www.openssl.org/support/faq.html#PROG1 |
| 109 | CRYPTO_set_locking_callback(&ssl_locking_callback); |
| 110 | CRYPTO_set_id_callback(&ssl_get_thread_id); |
| 111 | |
| 112 | OPENSSL_config(nullptr); |
| 113 | } |
| 114 | |
| 115 | // we need to record IDs of all threads calling the initialization in |
| 116 | // order to *manually* free per-thread memory OpenSSL *automagically* |
| 117 | // allocated in ERR_get_state(). |
| 118 | // XXX: this solution/nasty hack is IMPERFECT. A leak will appear when |
| 119 | // a client init()ializes the crypto subsystem with one thread and then |
| 120 | // uses it from another one in a way that results in ERR_get_state(). |
| 121 | // XXX: for discussion about another approaches please refer to: |
| 122 | // https://www.mail-archive.com/openssl-users@openssl.org/msg59070.html |
| 123 | { |
| 124 | std::lock_guard l(init_records.lock); |
| 125 | CRYPTO_THREADID tmp; |
| 126 | CRYPTO_THREADID_current(&tmp); |
| 127 | init_records.tids.emplace_back(std::move(tmp)); |
| 128 | } |
| 129 | #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ |
| 130 | } |
| 131 | |
| 132 | static void shutdown() { |
| 133 | #if OPENSSL_VERSION_NUMBER < 0x10100000L |
no test coverage detected