Loading docs/libcurl/curl_share_setopt.3 +5 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,11 @@ Cached DNS hosts will be shared across the easy handles using this shared object. Note that when you use the multi interface, all easy handles added to the same multi handle will share DNS cache by default without this having to be used! .IP CURL_LOCK_DATA_SSL_SESSION SSL session IDs will be shared accross the easy handles using this shared object. This will reduce the time spent in the SSL handshake when reconnecting to the same server. Note SSL session IDs are reused within the same easy handle by default. .RE .IP CURLSHOPT_UNSHARE This option does the opposite of \fICURLSHOPT_SHARE\fP. It specifies that Loading lib/share.c +23 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <curl/curl.h> #include "urldata.h" #include "share.h" #include "sslgen.h" #include "curl_memory.h" /* The last #include file should be: */ Loading Loading @@ -82,7 +83,16 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...) break; #endif /* CURL_DISABLE_HTTP */ case CURL_LOCK_DATA_SSL_SESSION: /* not supported (yet) */ case CURL_LOCK_DATA_SSL_SESSION: if(!share->sslsession) { share->nsslsession = 8; share->sslsession = calloc(share->nsslsession, sizeof(struct curl_ssl_session)); if(!share->sslsession) return CURLSHE_NOMEM; } break; case CURL_LOCK_DATA_CONNECT: /* not supported (yet) */ default: Loading Loading @@ -112,6 +122,11 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...) #endif /* CURL_DISABLE_HTTP */ case CURL_LOCK_DATA_SSL_SESSION: if(share->sslsession) { free(share->sslsession); share->sslsession = NULL; share->nsslsession = 0; } break; case CURL_LOCK_DATA_CONNECT: Loading Loading @@ -148,6 +163,7 @@ CURLSHcode curl_share_cleanup(CURLSH *sh) { struct Curl_share *share = (struct Curl_share *)sh; unsigned int i; if(share == NULL) return CURLSHE_INVALID; Loading @@ -170,6 +186,12 @@ curl_share_cleanup(CURLSH *sh) if(share->cookies) Curl_cookie_cleanup(share->cookies); if(share->sslsession) { for(i = 0; i < share->nsslsession; ++i) Curl_ssl_kill_session(&(share->sslsession[i])); free(share->sslsession); } if(share->unlockfunc) share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata); free(share); Loading lib/share.h +4 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include "setup.h" #include <curl/curl.h> #include "cookie.h" #include "urldata.h" /* SalfordC says "A structure member may not be volatile". Hence: */ Loading @@ -46,6 +47,9 @@ struct Curl_share { struct curl_hash *hostcache; struct CookieInfo *cookies; struct curl_ssl_session *sslsession; unsigned int nsslsession; }; CURLSHcode Curl_share_lock (struct SessionHandle *, curl_lock_data, Loading lib/sslgen.c +42 −7 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ #include "url.h" #include "curl_memory.h" #include "progress.h" #include "share.h" /* The last #include file should be: */ #include "memdebug.h" Loading Loading @@ -236,6 +237,10 @@ int Curl_ssl_getsessionid(struct connectdata *conn, /* session ID re-use is disabled */ return TRUE; /* Lock for reading if shared */ if(data->share && data->share->sslsession == data->state.session) Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SHARED); for(i=0; i< data->set.ssl.numsessions; i++) { check = &data->state.session[i]; if(!check->sessionid) Loading @@ -254,13 +259,19 @@ int Curl_ssl_getsessionid(struct connectdata *conn, } } *ssl_sessionid = NULL; /* Unlock for reading */ if(data->share && data->share->sslsession == data->state.session) Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION); return TRUE; } /* * Kill a single session ID entry in the cache. */ static int kill_session(struct curl_ssl_session *session) int Curl_ssl_kill_session(struct curl_ssl_session *session) { if(session->sessionid) { /* defensive check */ Loading Loading @@ -288,14 +299,23 @@ static int kill_session(struct curl_ssl_session *session) void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid) { int i; for(i=0; i< conn->data->set.ssl.numsessions; i++) { struct curl_ssl_session *check = &conn->data->state.session[i]; struct SessionHandle *data=conn->data; if(data->share && data->share->sslsession == data->state.session) Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE); for(i=0; i< data->set.ssl.numsessions; i++) { struct curl_ssl_session *check = &data->state.session[i]; if(check->sessionid == ssl_sessionid) { kill_session(check); Curl_ssl_kill_session(check); break; } } if(data->share && data->share->sslsession == data->state.session) Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION); } /* Loading Loading @@ -325,6 +345,10 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn, /* Now we should add the session ID and the host name to the cache, (remove the oldest if necessary) */ /* If using shared SSL session, lock! */ if(data->share && data->share->sslsession == data->state.session) Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE); /* find an empty slot for us, or find the oldest */ for(i=1; (i<data->set.ssl.numsessions) && data->state.session[i].sessionid; i++) { Loading @@ -335,7 +359,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn, } if(i == data->set.ssl.numsessions) /* cache is full, we must "kill" the oldest entry! */ kill_session(store); Curl_ssl_kill_session(store); else store = &data->state.session[i]; /* use this slot */ Loading @@ -349,6 +373,11 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn, store->name = clone_host; /* clone host name */ store->remote_port = conn->remote_port; /* port number */ /* Unlock */ if(data->share && data->share->sslsession == data->state.session) Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION); if(!Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config)) { store->sessionid = NULL; /* let caller free sessionid */ free(clone_host); Loading @@ -363,14 +392,20 @@ void Curl_ssl_close_all(struct SessionHandle *data) { long i; /* kill the session ID cache */ if(data->state.session) { if(data->state.session && !(data->share && data->share->sslsession == data->state.session)) { Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE); for(i=0; i< data->set.ssl.numsessions; i++) /* the single-killer function handles empty table slots */ kill_session(&data->state.session[i]); Curl_ssl_kill_session(&data->state.session[i]); /* free the cache data */ free(data->state.session); data->state.session = NULL; Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION); } curlssl_close_all(data); Loading lib/sslgen.h +2 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,8 @@ int Curl_ssl_getsessionid(struct connectdata *conn, CURLcode Curl_ssl_addsessionid(struct connectdata *conn, void *ssl_sessionid, size_t idsize); /* Kill a single session ID entry in the cache */ int Curl_ssl_kill_session(struct curl_ssl_session *session); /* delete a session from the cache */ void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid); Loading Loading
docs/libcurl/curl_share_setopt.3 +5 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,11 @@ Cached DNS hosts will be shared across the easy handles using this shared object. Note that when you use the multi interface, all easy handles added to the same multi handle will share DNS cache by default without this having to be used! .IP CURL_LOCK_DATA_SSL_SESSION SSL session IDs will be shared accross the easy handles using this shared object. This will reduce the time spent in the SSL handshake when reconnecting to the same server. Note SSL session IDs are reused within the same easy handle by default. .RE .IP CURLSHOPT_UNSHARE This option does the opposite of \fICURLSHOPT_SHARE\fP. It specifies that Loading
lib/share.c +23 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <curl/curl.h> #include "urldata.h" #include "share.h" #include "sslgen.h" #include "curl_memory.h" /* The last #include file should be: */ Loading Loading @@ -82,7 +83,16 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...) break; #endif /* CURL_DISABLE_HTTP */ case CURL_LOCK_DATA_SSL_SESSION: /* not supported (yet) */ case CURL_LOCK_DATA_SSL_SESSION: if(!share->sslsession) { share->nsslsession = 8; share->sslsession = calloc(share->nsslsession, sizeof(struct curl_ssl_session)); if(!share->sslsession) return CURLSHE_NOMEM; } break; case CURL_LOCK_DATA_CONNECT: /* not supported (yet) */ default: Loading Loading @@ -112,6 +122,11 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...) #endif /* CURL_DISABLE_HTTP */ case CURL_LOCK_DATA_SSL_SESSION: if(share->sslsession) { free(share->sslsession); share->sslsession = NULL; share->nsslsession = 0; } break; case CURL_LOCK_DATA_CONNECT: Loading Loading @@ -148,6 +163,7 @@ CURLSHcode curl_share_cleanup(CURLSH *sh) { struct Curl_share *share = (struct Curl_share *)sh; unsigned int i; if(share == NULL) return CURLSHE_INVALID; Loading @@ -170,6 +186,12 @@ curl_share_cleanup(CURLSH *sh) if(share->cookies) Curl_cookie_cleanup(share->cookies); if(share->sslsession) { for(i = 0; i < share->nsslsession; ++i) Curl_ssl_kill_session(&(share->sslsession[i])); free(share->sslsession); } if(share->unlockfunc) share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata); free(share); Loading
lib/share.h +4 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include "setup.h" #include <curl/curl.h> #include "cookie.h" #include "urldata.h" /* SalfordC says "A structure member may not be volatile". Hence: */ Loading @@ -46,6 +47,9 @@ struct Curl_share { struct curl_hash *hostcache; struct CookieInfo *cookies; struct curl_ssl_session *sslsession; unsigned int nsslsession; }; CURLSHcode Curl_share_lock (struct SessionHandle *, curl_lock_data, Loading
lib/sslgen.c +42 −7 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ #include "url.h" #include "curl_memory.h" #include "progress.h" #include "share.h" /* The last #include file should be: */ #include "memdebug.h" Loading Loading @@ -236,6 +237,10 @@ int Curl_ssl_getsessionid(struct connectdata *conn, /* session ID re-use is disabled */ return TRUE; /* Lock for reading if shared */ if(data->share && data->share->sslsession == data->state.session) Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SHARED); for(i=0; i< data->set.ssl.numsessions; i++) { check = &data->state.session[i]; if(!check->sessionid) Loading @@ -254,13 +259,19 @@ int Curl_ssl_getsessionid(struct connectdata *conn, } } *ssl_sessionid = NULL; /* Unlock for reading */ if(data->share && data->share->sslsession == data->state.session) Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION); return TRUE; } /* * Kill a single session ID entry in the cache. */ static int kill_session(struct curl_ssl_session *session) int Curl_ssl_kill_session(struct curl_ssl_session *session) { if(session->sessionid) { /* defensive check */ Loading Loading @@ -288,14 +299,23 @@ static int kill_session(struct curl_ssl_session *session) void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid) { int i; for(i=0; i< conn->data->set.ssl.numsessions; i++) { struct curl_ssl_session *check = &conn->data->state.session[i]; struct SessionHandle *data=conn->data; if(data->share && data->share->sslsession == data->state.session) Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE); for(i=0; i< data->set.ssl.numsessions; i++) { struct curl_ssl_session *check = &data->state.session[i]; if(check->sessionid == ssl_sessionid) { kill_session(check); Curl_ssl_kill_session(check); break; } } if(data->share && data->share->sslsession == data->state.session) Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION); } /* Loading Loading @@ -325,6 +345,10 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn, /* Now we should add the session ID and the host name to the cache, (remove the oldest if necessary) */ /* If using shared SSL session, lock! */ if(data->share && data->share->sslsession == data->state.session) Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE); /* find an empty slot for us, or find the oldest */ for(i=1; (i<data->set.ssl.numsessions) && data->state.session[i].sessionid; i++) { Loading @@ -335,7 +359,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn, } if(i == data->set.ssl.numsessions) /* cache is full, we must "kill" the oldest entry! */ kill_session(store); Curl_ssl_kill_session(store); else store = &data->state.session[i]; /* use this slot */ Loading @@ -349,6 +373,11 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn, store->name = clone_host; /* clone host name */ store->remote_port = conn->remote_port; /* port number */ /* Unlock */ if(data->share && data->share->sslsession == data->state.session) Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION); if(!Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config)) { store->sessionid = NULL; /* let caller free sessionid */ free(clone_host); Loading @@ -363,14 +392,20 @@ void Curl_ssl_close_all(struct SessionHandle *data) { long i; /* kill the session ID cache */ if(data->state.session) { if(data->state.session && !(data->share && data->share->sslsession == data->state.session)) { Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE); for(i=0; i< data->set.ssl.numsessions; i++) /* the single-killer function handles empty table slots */ kill_session(&data->state.session[i]); Curl_ssl_kill_session(&data->state.session[i]); /* free the cache data */ free(data->state.session); data->state.session = NULL; Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION); } curlssl_close_all(data); Loading
lib/sslgen.h +2 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,8 @@ int Curl_ssl_getsessionid(struct connectdata *conn, CURLcode Curl_ssl_addsessionid(struct connectdata *conn, void *ssl_sessionid, size_t idsize); /* Kill a single session ID entry in the cache */ int Curl_ssl_kill_session(struct curl_ssl_session *session); /* delete a session from the cache */ void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid); Loading