All; Hello. I have been using Tomcat and TCNative for quite a while now, but have just now subscribed to this list so I may contribute a proposed patch. Since I am new, please be patient if I'm doing things wrong - I've RTFM, but that only goes so far. The attached patch adds dynamic locking callbacks needed by certain engines in OpenSSL (chil, specifically). Most of this code was poached from HTTPD 2.2.x mod_ssl (ssl_util.c). The notable differences to TCNative after applying the patch are that the call to ssl_thread_setup had to be moved before the engine is initialized since the callbacks must be set before engine init, and the dynamic callback functions were added to ssl_thread_setup. I am attaching the proposed patch to this email, but please let me know what it would take to have it properly committed and offer any suggestions that may relate to the patch itself. I'm also used to patches including information in the CHANGELOG file, but it seems TCNative doesn't do things that way? Thanks for your time --
-- ![]() |
diff -Nru tomcat-native-1.1.16-src/jni/native/include/ssl_private.h tomcat-native-1.1.16-src-dynamic_callbacks/jni/native/include/ssl_private.h --- tomcat-native-1.1.16-src/jni/native/include/ssl_private.h 2006-10-21 17:16:34.000000000 -0500 +++ tomcat-native-1.1.16-src-dynamic_callbacks/jni/native/include/ssl_private.h 2009-11-19 09:10:58.630479400 -0600 @@ -292,3 +292,13 @@ int SSL_callback_SSL_verify(int, X509_STORE_CTX *); int SSL_rand_seed(const char *file); #endif /* SSL_PRIVATE_H */ + +/* Global reference to the pool used by the dynamic mutexes */ +apr_pool_t *dynlockpool; + +/** + * Dynamic lock callback functions + */ +static struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file, int line); +static void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line); +static void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char *file, int line); diff -Nru tomcat-native-1.1.16-src/jni/native/src/ssl.c tomcat-native-1.1.16-src-dynamic_callbacks/jni/native/src/ssl.c --- tomcat-native-1.1.16-src/jni/native/src/ssl.c 2007-04-03 09:16:23.000000000 -0500 +++ tomcat-native-1.1.16-src-dynamic_callbacks/jni/native/src/ssl.c 2009-11-19 09:10:40.567979400 -0600 @@ -213,6 +213,12 @@ 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; @@ -233,6 +239,14 @@ 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); } @@ -402,6 +416,9 @@ OPENSSL_load_builtin_modules(); #endif + /* Initialize thread support */ + ssl_thread_setup(tcn_global_pool); + #ifndef OPENSSL_NO_ENGINE if (J2S(engine)) { ENGINE *ee = NULL; @@ -455,8 +472,6 @@ 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; } @@ -911,3 +926,109 @@ } #endif + +/* Dynamic lock structure */ +struct CRYPTO_dynlock_value { + apr_pool_t *pool; + const char* file; + int line; + apr_thread_mutex_t *mutex; +}; + +/* + * 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) { + fprintf(stderr, "Failed to create subpool for dynamic lock"); + return NULL; + } + + /* + fprintf(stderr, "Creating dynamic lock"); + */ + + value = (struct CRYPTO_dynlock_value *)apr_palloc(p, + sizeof(struct CRYPTO_dynlock_value)); + if (!value) { + 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) { + 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) { + /* + fprintf(stderr, "Acquiring mutex %s:%d", l->file, l->line); + */ + rv = apr_thread_mutex_lock(l->mutex); + /* + fprintf(stderr, "Mutex %s:%d acquired!", l->file, l->line); + */ + } + else { + /* + fprintf(stderr, "Releasing mutex %s:%d", l->file, l->line); + */ + rv = apr_thread_mutex_unlock(l->mutex); + /* + fprintf(stderr, "Mutex %s:%d released!", l->file, l->line); + */ + } +} + +/* + * Dynamic lock destruction callback + */ +static void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l, + const char *file, int line) +{ + apr_status_t rv; + + /* + fprintf(stderr, "Destroying dynamic lock %s:%d", l->file, l->line); + */ + rv = apr_thread_mutex_destroy(l->mutex); + if (rv != APR_SUCCESS) { + 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); +}
--------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org