From c9b4a492cfe93fc9563d9b2b30bcdceefee1d4bb Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Fri, 20 Dec 2013 18:38:48 +0100 Subject: Detect POSIX threads at configure time and use them for OpenSSL. --- lib/tls.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) (limited to 'lib/tls.c') diff --git a/lib/tls.c b/lib/tls.c index e5e7440..ba3cab5 100644 --- a/lib/tls.c +++ b/lib/tls.c @@ -10,11 +10,15 @@ #include #include #include +#if defined HAVE_PTHREAD_H +#include +#endif #include #include #include #include #include +#include #include #include @@ -182,11 +186,62 @@ init_openssl_rand_ (void) return 0; } +#if defined HAVE_PTHREADS +/** Array of pthread_mutex_t for OpenSSL. Allocated and initialised in + \a init_locking_ and never freed. */ +static pthread_mutex_t *s_openssl_mutexes = NULL; +/** Number of pthread_mutex_t's allocated at s_openssl_mutexes. */ +static int s_openssl_mutexes_count = 0; + +/** Callback for OpenSSL when a lock is to be held or released. */ +static void +openssl_locking_cb_ (int mode, int i, const char *file, int line) +{ + if (s_openssl_mutexes == NULL || i >= s_openssl_mutexes_count) + return; + if (mode & CRYPTO_LOCK) + pthread_mutex_lock (&s_openssl_mutexes[i]); + else + pthread_mutex_unlock (&s_openssl_mutexes[i]); +} + +/** Initialise any locking needed for being thread safe. Libradsec has + all its own state in one or more struct rs_context and doesn't + need locks but libraries used by libradsec may need protection. */ +static int +init_locking_ () +{ + int i, n; + n = CRYPTO_num_locks (); + + s_openssl_mutexes = calloc (n, sizeof(pthread_mutex_t)); + if (s_openssl_mutexes == NULL) + return -RSE_NOMEM; + for (i = 0; i < n; i++) + pthread_mutex_init (&s_openssl_mutexes[i], NULL); + s_openssl_mutexes_count = n; + + return 0; +} +#endif /* HAVE_PTHREADS */ + /** Initialise the TLS library. Return 0 on success, -1 on failure. */ int -tls_init (void) +tls_init () { SSL_load_error_strings (); +#if defined HAVE_PTHREADS + if (CRYPTO_get_locking_callback () == NULL) + { + assert (s_openssl_mutexes_count == 0); + /* Allocate and initialise mutexes. We will never free + these. FIXME: Is there a portable way of having a function + invoked when a solib is unloaded? -ln */ + if (init_locking_ ()) + return -1; + CRYPTO_set_locking_callback (openssl_locking_cb_); + } +#endif /* HAVE_PTHREADS */ SSL_library_init (); return init_openssl_rand_ (); } -- cgit v1.1