You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by rj...@apache.org on 2011/07/10 17:26:58 UTC

svn commit: r1144877 - /tomcat/native/trunk/native/src/ssl.c

Author: rjung
Date: Sun Jul 10 15:26:58 2011
New Revision: 1144877

URL: http://svn.apache.org/viewvc?rev=1144877&view=rev
Log:
Forward port of r1055907 from tcnative trunk:
Fix for bug 48253.

Modified:
    tomcat/native/trunk/native/src/ssl.c

Modified: tomcat/native/trunk/native/src/ssl.c
URL: http://svn.apache.org/viewvc/tomcat/native/trunk/native/src/ssl.c?rev=1144877&r1=1144876&r2=1144877&view=diff
==============================================================================
--- tomcat/native/trunk/native/src/ssl.c (original)
+++ tomcat/native/trunk/native/src/ssl.c Sun Jul 10 15:26:58 2011
@@ -37,6 +37,18 @@ ENGINE *tcn_ssl_engine = NULL;
 void *SSL_temp_keys[SSL_TMP_KEY_MAX];
 tcn_pass_cb_t tcn_password_callback;
 
+/* Global reference to the pool used by the dynamic mutexes */
+static apr_pool_t *dynlockpool = NULL;
+
+/* Dynamic lock structure */
+struct CRYPTO_dynlock_value {
+    apr_pool_t *pool;
+    const char* file;
+    int line;
+    apr_thread_mutex_t *mutex;
+};
+
+
 /*
  * Handle the Temporary RSA Keys and DH Params
  */
@@ -215,11 +227,94 @@ static apr_status_t ssl_thread_cleanup(v
     UNREFERENCED(data);
     CRYPTO_set_locking_callback(NULL);
     CRYPTO_set_id_callback(NULL);
+    CRYPTO_set_dynlock_create_callback(NULL);
+    CRYPTO_set_dynlock_lock_callback(NULL);
+    CRYPTO_set_dynlock_destroy_callback(NULL);
+
+    dynlockpool = NULL;
+
     /* Let the registered mutex cleanups do their own thing
      */
     return APR_SUCCESS;
 }
 
+/*
+ * Dynamic lock creation callback
+ */
+static struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file,
+                                                     int line)
+{
+    struct CRYPTO_dynlock_value *value;
+    apr_pool_t *p;
+    apr_status_t rv;
+
+    /* 
+     * We need a pool to allocate our mutex.  Since we can't clear
+     * allocated memory from a pool, create a subpool that we can blow
+     * away in the destruction callback. 
+     */
+    rv = apr_pool_create(&p, dynlockpool);
+    if (rv != APR_SUCCESS) {
+        /* TODO log that fprintf(stderr, "Failed to create subpool for dynamic lock"); */
+        return NULL;
+    }
+
+    value = (struct CRYPTO_dynlock_value *)apr_palloc(p,
+                                                      sizeof(struct CRYPTO_dynlock_value));
+    if (!value) {
+        /* TODO log that fprintf(stderr, "Failed to allocate dynamic lock structure"); */
+        return NULL;
+    }
+
+    value->pool = p;
+    /* Keep our own copy of the place from which we were created,
+       using our own pool. */
+    value->file = apr_pstrdup(p, file);
+    value->line = line;
+    rv = apr_thread_mutex_create(&(value->mutex), APR_THREAD_MUTEX_DEFAULT,
+                                p);
+    if (rv != APR_SUCCESS) {
+        /* TODO log that fprintf(stderr, "Failed to create thread mutex for dynamic lock"); */
+        apr_pool_destroy(p);
+        return NULL;
+    }
+    return value;
+}
+
+/*
+ * Dynamic locking and unlocking function
+ */
+
+static void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l,
+                           const char *file, int line)
+{
+    apr_status_t rv;
+
+    if (mode & CRYPTO_LOCK) {
+        rv = apr_thread_mutex_lock(l->mutex);
+    }
+    else {
+        rv = apr_thread_mutex_unlock(l->mutex);
+    }
+}
+
+/*
+ * Dynamic lock destruction callback
+ */
+static void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l,
+                          const char *file, int line)
+{
+    apr_status_t rv;
+    rv = apr_thread_mutex_destroy(l->mutex);
+    if (rv != APR_SUCCESS) {
+        /* TODO log that fprintf(stderr, "Failed to destroy mutex for dynamic lock %s:%d", l->file, l->line); */
+    }
+
+    /* Trust that whomever owned the CRYPTO_dynlock_value we were
+     * passed has no future use for it...
+     */
+    apr_pool_destroy(l->pool);
+}
 static void ssl_thread_setup(apr_pool_t *p)
 {
     int i;
@@ -235,6 +330,14 @@ static void ssl_thread_setup(apr_pool_t 
     CRYPTO_set_id_callback(ssl_thread_id);
     CRYPTO_set_locking_callback(ssl_thread_lock);
 
+    /* Set up dynamic locking scaffolding for OpenSSL to use at its
+     * convenience.
+     */
+    dynlockpool = p;
+    CRYPTO_set_dynlock_create_callback(ssl_dyn_create_function);
+    CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock_function);
+    CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy_function);
+
     apr_pool_cleanup_register(p, NULL, ssl_thread_cleanup,
                               apr_pool_cleanup_null);
 }
@@ -404,6 +507,9 @@ TCN_IMPLEMENT_CALL(jint, SSL, initialize
     OPENSSL_load_builtin_modules();
 #endif
 
+    /* Initialize thread support */
+    ssl_thread_setup(tcn_global_pool);
+
 #ifndef OPENSSL_NO_ENGINE
     if (J2S(engine)) {
         ENGINE *ee = NULL;
@@ -457,8 +563,6 @@ TCN_IMPLEMENT_CALL(jint, SSL, initialize
     apr_pool_cleanup_register(tcn_global_pool, NULL,
                               ssl_init_cleanup,
                               apr_pool_cleanup_null);
-    /* Initialize thread support */
-    ssl_thread_setup(tcn_global_pool);
     TCN_FREE_CSTRING(engine);
     return (jint)APR_SUCCESS;
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org