diff --git a/lib/easy.c b/lib/easy.c index ead4da73a..2c0520a65 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -73,16 +73,30 @@ #include "urldata.h" #include #include "transfer.h" -#include +#include "ssluse.h" #define _MPRINTF_REPLACE /* use our functions only */ #include +CURLcode curl_global_init(void) +{ + Curl_SSL_init(); + return CURLE_OK; +} + +void curl_global_cleanup(void) +{ + Curl_SSL_cleanup(); +} + CURL *curl_easy_init(void) { CURLcode res; struct UrlData *data; + /* Make sure we inited the global SSL stuff */ + Curl_SSL_init(); + /* We use curl_open() with undefined URL so far */ res = Curl_open((CURL **)&data, NULL); if(res != CURLE_OK) diff --git a/lib/ssluse.c b/lib/ssluse.c index e8e3a4cf5..3707a4965 100644 --- a/lib/ssluse.c +++ b/lib/ssluse.c @@ -235,6 +235,40 @@ int cert_verify_callback(int ok, X509_STORE_CTX *ctx) #endif +/* Global init */ +void Curl_SSL_init(void) +{ +#ifdef USE_SSLEAY + static int only_once=0; + + /* make sure this is only done once */ + if(0 != only_once) + return; + + only_once++; /* never again */ + + /* Lets get nice error messages */ + SSL_load_error_strings(); + + /* Setup all the global SSL stuff */ + SSLeay_add_ssl_algorithms(); +#endif +} + +/* Global cleanup */ +void Curl_SSL_cleanup(void) +{ +#ifdef USE_SSLEAY + /* Free the SSL error strings */ + ERR_free_strings(); + + /* EVP_cleanup() removes all ciphers and digests from the + table. */ + EVP_cleanup(); +#endif +} + + /* ====================================================== */ CURLcode Curl_SSLConnect(struct connectdata *conn) @@ -250,15 +284,9 @@ Curl_SSLConnect(struct connectdata *conn) /* mark this is being ssl enabled from here on out. */ conn->ssl.use = TRUE; - /* Lets get nice error messages */ - SSL_load_error_strings(); - /* Make funny stuff to get random input */ random_the_seed(conn); - /* Setup all the global SSL stuff */ - SSLeay_add_ssl_algorithms(); - switch(data->ssl.version) { default: req_method = SSLv23_client_method(); diff --git a/lib/ssluse.h b/lib/ssluse.h index d211c1cb4..645970f4b 100644 --- a/lib/ssluse.h +++ b/lib/ssluse.h @@ -24,4 +24,8 @@ *****************************************************************************/ #include "urldata.h" CURLcode Curl_SSLConnect(struct connectdata *conn); +/* Global SSL init */ +void Curl_SSL_init(void); +/* Global SSL cleanup */ +void Curl_SSL_cleanup(void); #endif diff --git a/lib/url.c b/lib/url.c index 364e10881..726e259ca 100644 --- a/lib/url.c +++ b/lib/url.c @@ -833,6 +833,17 @@ CURLcode Curl_disconnect(struct connectdata *conn) #ifdef USE_SSLEAY if (conn->ssl.use) { + /* + ERR_remove_state() frees the error queue associated with + thread pid. If pid == 0, the current thread will have its + error queue removed. + + Since error queue data structures are allocated + automatically for new threads, they must be freed when + threads are terminated in oder to avoid memory leaks. + */ + ERR_remove_state(0); + if(conn->ssl.handle) { (void)SSL_shutdown(conn->ssl.handle); SSL_set_connect_state(conn->ssl.handle);