63b8685833
- Fix openssl thread locking bug under high query load
105 lines
2.6 KiB
Diff
105 lines
2.6 KiB
Diff
Index: daemon/daemon.c
|
|
===================================================================
|
|
--- daemon/daemon.c (revision 2732)
|
|
+++ daemon/daemon.c (revision 2733)
|
|
@@ -209,6 +209,10 @@
|
|
comp_meth = (void*)SSL_COMP_get_compression_methods();
|
|
# endif
|
|
(void)SSL_library_init();
|
|
+# if defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
|
|
+ if(!ub_openssl_lock_init())
|
|
+ fatal_exit("could not init openssl locks");
|
|
+# endif
|
|
#elif defined(HAVE_NSS)
|
|
if(NSS_NoDB_Init(NULL) != SECSuccess)
|
|
fatal_exit("could not init NSS");
|
|
@@ -568,6 +572,9 @@
|
|
ERR_remove_state(0);
|
|
ERR_free_strings();
|
|
RAND_cleanup();
|
|
+# if defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
|
|
+ ub_openssl_lock_delete();
|
|
+# endif
|
|
#elif defined(HAVE_NSS)
|
|
NSS_Shutdown();
|
|
#endif /* HAVE_SSL or HAVE_NSS */
|
|
Index: util/net_help.c
|
|
===================================================================
|
|
--- util/net_help.c (revision 2732)
|
|
+++ util/net_help.c (revision 2733)
|
|
@@ -725,3 +725,54 @@
|
|
return NULL;
|
|
#endif
|
|
}
|
|
+
|
|
+/** global lock list for openssl locks */
|
|
+static lock_basic_t *ub_openssl_locks = NULL;
|
|
+
|
|
+/** callback that gets thread id for openssl */
|
|
+static unsigned long
|
|
+ub_crypto_id_cb(void)
|
|
+{
|
|
+ return (unsigned long)ub_thread_self();
|
|
+}
|
|
+
|
|
+static void
|
|
+ub_crypto_lock_cb(int mode, int type, const char *ATTR_UNUSED(file),
|
|
+ int ATTR_UNUSED(line))
|
|
+{
|
|
+ if((mode&CRYPTO_LOCK)) {
|
|
+ lock_basic_lock(&ub_openssl_locks[type]);
|
|
+ } else {
|
|
+ lock_basic_unlock(&ub_openssl_locks[type]);
|
|
+ }
|
|
+}
|
|
+
|
|
+int ub_openssl_lock_init(void)
|
|
+{
|
|
+#ifdef OPENSSL_THREADS
|
|
+ size_t i;
|
|
+ ub_openssl_locks = (lock_basic_t*)malloc(
|
|
+ sizeof(lock_basic_t)*CRYPTO_num_locks());
|
|
+ if(!ub_openssl_locks)
|
|
+ return 0;
|
|
+ for(i=0; i<CRYPTO_num_locks(); i++) {
|
|
+ lock_basic_init(&ub_openssl_locks[i]);
|
|
+ }
|
|
+ CRYPTO_set_id_callback(&ub_crypto_id_cb);
|
|
+ CRYPTO_set_locking_callback(&ub_crypto_lock_cb);
|
|
+#endif /* OPENSSL_THREADS */
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+void ub_openssl_lock_delete(void)
|
|
+{
|
|
+#ifdef OPENSSL_THREADS
|
|
+ size_t i;
|
|
+ if(!ub_openssl_locks)
|
|
+ return;
|
|
+ for(i=0; i<CRYPTO_num_locks(); i++) {
|
|
+ lock_basic_destroy(&ub_openssl_locks[i]);
|
|
+ }
|
|
+#endif /* OPENSSL_THREADS */
|
|
+}
|
|
+
|
|
Index: util/net_help.h
|
|
===================================================================
|
|
--- util/net_help.h (revision 2732)
|
|
+++ util/net_help.h (revision 2733)
|
|
@@ -369,4 +369,15 @@
|
|
*/
|
|
void* outgoing_ssl_fd(void* sslctx, int fd);
|
|
|
|
+/**
|
|
+ * Initialize openssl locking for thread safety
|
|
+ * @return false on failure (alloc failure).
|
|
+ */
|
|
+int ub_openssl_lock_init(void);
|
|
+
|
|
+/**
|
|
+ * De-init the allocated openssl locks
|
|
+ */
|
|
+void ub_openssl_lock_delete(void);
|
|
+
|
|
#endif /* NET_HELP_H */
|