X-Git-Url: http://www.project-moonshot.org/gitweb/?p=radsecproxy.git;a=blobdiff_plain;f=lib%2Ftls.c;fp=lib%2Ftls.c;h=ba3cab5e89f612f6fd6d2fb4dfa64abf39570088;hp=e5e74406790bf81dcfc2b490ef3f162c9aeb2052;hb=c9b4a492cfe93fc9563d9b2b30bcdceefee1d4bb;hpb=5871418432e1b127c760cd42a50f781d95d245fd 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_ (); }