From beb13a1d3e832ae97221ba1d9ad7f9bc262de798 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Barette-LaPierre Date: Tue, 4 Feb 2003 23:48:46 +0000 Subject: added the sharing of DNS cache --- include/curl/curl.h | 13 +++++++++---- lib/Makefile.am | 2 +- lib/connect.c | 2 +- lib/ftp.c | 4 ++-- lib/hostip.c | 25 ++++++++++++++++++++++++- lib/hostip.h | 2 +- lib/share.c | 49 ++++++++++++++++++++++++++++++++++++++++++++----- lib/share.h | 17 +++++++++++++---- lib/url.c | 29 ++++++++++++++++++++++++++--- 9 files changed, 121 insertions(+), 22 deletions(-) diff --git a/include/curl/curl.h b/include/curl/curl.h index 08630b54a..04171ba9a 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -902,10 +902,15 @@ typedef enum { /* Different data locks for a single share */ typedef enum { CURL_LOCK_DATA_NONE = 0, - CURL_LOCK_DATA_COOKIE = 1, - CURL_LOCK_DATA_DNS = 2, - CURL_LOCK_DATA_SSL_SESSION = 3, - CURL_LOCK_DATA_CONNECT = 4, + /* CURL_LOCK_DATA_SHARE is used internaly to say that + * the locking is just made to change the internal state of the share + * itself. + */ + CURL_LOCK_DATA_SHARE, + CURL_LOCK_DATA_COOKIE, + CURL_LOCK_DATA_DNS, + CURL_LOCK_DATA_SSL_SESSION, + CURL_LOCK_DATA_CONNECT, CURL_LOCK_DATA_LAST } curl_lock_data; diff --git a/lib/Makefile.am b/lib/Makefile.am index 7fb166370..342a29c46 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -66,7 +66,7 @@ getpass.c netrc.c telnet.h getinfo.c getinfo.h transfer.c strequal.c \ strequal.h easy.c security.h security.c krb4.c krb4.h memdebug.c \ memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.c strtok.h \ connect.c connect.h llist.c llist.h hash.c hash.h multi.c \ -content_encoding.c content_encoding.h share.h +content_encoding.c content_encoding.h share.c share.h noinst_HEADERS = setup.h transfer.h diff --git a/lib/connect.c b/lib/connect.c index 884425326..da0a5b951 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -248,7 +248,7 @@ static CURLcode bindlocal(struct connectdata *conn, if ( h ) { Curl_addrinfo *addr = h->addr; - Curl_resolv_unlock(h); + Curl_resolv_unlock(data, h); /* we don't need it anymore after this function has returned */ #ifdef ENABLE_IPV6 diff --git a/lib/ftp.c b/lib/ftp.c index 8cff5c66a..c7246446c 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -1233,7 +1233,7 @@ CURLcode ftp_use_port(struct connectdata *conn) if(h) /* when we return from here, we can forget about this */ - Curl_resolv_unlock(h); + Curl_resolv_unlock(data, h); if ( h || sa_filled_in) { if( (portsock = socket(AF_INET, SOCK_STREAM, 0)) >= 0 ) { @@ -1497,7 +1497,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn, &conninfo, connected); - Curl_resolv_unlock(addr); /* we're done using this address */ + Curl_resolv_unlock(data, addr); /* we're done using this address */ /* * When this is used from the multi interface, this might've returned with diff --git a/lib/hostip.c b/lib/hostip.c index d5f32fd49..b5fda2a23 100644 --- a/lib/hostip.c +++ b/lib/hostip.c @@ -64,6 +64,7 @@ #include "sendf.h" #include "hostip.h" #include "hash.h" +#include "share.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -211,6 +212,10 @@ void Curl_scan_cache_used(void *user, void *ptr) #define HOSTCACHE_RETURN(dns) \ { \ free(entry_id); \ + if(data->share) \ + { \ + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); \ + } \ return dns; \ } @@ -245,7 +250,12 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data, /* If we can't create the entry id, fail */ if (!entry_id) return NULL; - + + if(data->share) + { + Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); + } + /* See if its already in our dns cache */ dns = Curl_hash_pick(data->hostcache, entry_id, entry_len+1); @@ -284,6 +294,19 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data, HOSTCACHE_RETURN(dns); } +void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns) +{ + if(data->share) + { + Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); + } + dns->inuse--; + if(data->share) + { + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); + } +} + /* * This is a wrapper function for freeing name information in a protocol * independent way. This takes care of using the appropriate underlaying diff --git a/lib/hostip.h b/lib/hostip.h index 396508e77..fc1474c39 100644 --- a/lib/hostip.h +++ b/lib/hostip.h @@ -59,7 +59,7 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data, int port); /* unlock a previously resolved dns entry */ -#define Curl_resolv_unlock(dns) dns->inuse-- +void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns); /* for debugging purposes only: */ void Curl_scan_cache_used(void *user, void *ptr); diff --git a/lib/share.c b/lib/share.c index dcf7e90bb..8e5ec0ea0 100644 --- a/lib/share.c +++ b/lib/share.c @@ -65,12 +65,53 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...) /* this is a type this share will share */ type = va_arg(param, int); share->specifier |= (1<hostcache) { + share->hostcache = Curl_hash_alloc(7, Curl_freednsinfo); + } + break; + + case CURL_LOCK_DATA_COOKIE: + break; + + case CURL_LOCK_DATA_SSL_SESSION: + break; + + case CURL_LOCK_DATA_CONNECT: + break; + + default: + return CURLSHE_BAD_OPTION; + } break; case CURLSHOPT_UNSHARE: /* this is a type this share will no longer share */ type = va_arg(param, int); share->specifier &= ~(1<hostcache) { + Curl_hash_destroy(share->hostcache); + share->hostcache = NULL; + } + break; + + case CURL_LOCK_DATA_COOKIE: + break; + + case CURL_LOCK_DATA_SSL_SESSION: + break; + + case CURL_LOCK_DATA_CONNECT: + break; + + default: + return CURLSHE_BAD_OPTION; + } break; case CURLSHOPT_LOCKFUNC: @@ -108,7 +149,7 @@ CURLSHcode curl_share_cleanup(CURLSH *sh) CURLSHcode -Curl_share_acquire_lock(struct SessionHandle *data, curl_lock_data type) +Curl_share_lock(struct SessionHandle *data, curl_lock_data type, curl_lock_access access) { struct Curl_share *share = data->share; @@ -116,8 +157,7 @@ Curl_share_acquire_lock(struct SessionHandle *data, curl_lock_data type) return CURLSHE_INVALID; if(share->specifier & (1<lockfunc (data, type, CURL_LOCK_ACCESS_SINGLE, share->clientdata); - share->locked |= (1<lockfunc (data, type, access, share->clientdata); } /* else if we don't share this, pretend successful lock */ @@ -125,7 +165,7 @@ Curl_share_acquire_lock(struct SessionHandle *data, curl_lock_data type) } CURLSHcode -Curl_share_release_lock(struct SessionHandle *data, curl_lock_data type) +Curl_share_unlock(struct SessionHandle *data, curl_lock_data type) { struct Curl_share *share = data->share; @@ -134,7 +174,6 @@ Curl_share_release_lock(struct SessionHandle *data, curl_lock_data type) if(share->specifier & (1<unlockfunc (data, type, share->clientdata); - share->locked &= ~(1<share) + { + Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); + + /* checking the dns cache stuff */ + if(data->share->hostcache == data->hostcache) + { + data->hostcache = NULL; + } + data->share->dirty--; - + + Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); + } + data->share = set; + + Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); + data->share->dirty++; + + if( data->hostcache ) + { + Curl_hash_destroy(data->hostcache); + data->hostcache = data->share->hostcache; + } + + Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); } break; @@ -1518,7 +1541,7 @@ static int handleSock5Proxy( socksreq[6] = ((char*)hp->h_addr_list[0])[2]; socksreq[7] = ((char*)hp->h_addr_list[0])[3]; - Curl_resolv_unlock(dns); /* not used anymore from now on */ + Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */ } else { failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.", @@ -2901,7 +2924,7 @@ CURLcode Curl_done(struct connectdata *conn) } if(conn->connect_addr) - Curl_resolv_unlock(conn->connect_addr); /* done with this */ + Curl_resolv_unlock(conn->data, conn->connect_addr); /* done with this */ #if defined(MALLOCDEBUG) && defined(AGGRESIVE_TEST) /* scan for DNS cache entries still marked as in use */ -- cgit v1.2.3