From 5e0a44e4d58855a52b6e0744df4fab09ded3873c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 31 Dec 2011 10:28:10 +0100 Subject: CURLOPT_RESOLVE: avoid adding already present host names The load host names to DNS cache function was moved to hostip.c and it now makes sure to not add host names that already are present in the cache. It would previously lead to memory leaks when for example using the --resolve and multiple URLs on the command line. --- lib/hostip.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'lib/hostip.c') diff --git a/lib/hostip.c b/lib/hostip.c index 44ed0a424..03c3bc981 100644 --- a/lib/hostip.c +++ b/lib/hostip.c @@ -743,3 +743,69 @@ void Curl_hostcache_destroy(struct SessionHandle *data) data->dns.hostcachetype = HCACHE_NONE; data->dns.hostcache = NULL; } + +CURLcode Curl_loadhostpairs(struct SessionHandle *data) +{ + struct curl_slist *hostp; + char hostname[256]; + char address[256]; + int port; + + for(hostp = data->change.resolve; hostp; hostp = hostp->next ) { + if(!hostp->data) + continue; + if(hostp->data[0] == '-') { + /* TODO: mark an entry for removal */ + } + else if(3 == sscanf(hostp->data, "%255[^:]:%d:%255s", hostname, &port, + address)) { + struct Curl_dns_entry *dns; + Curl_addrinfo *addr; + char *entry_id; + size_t entry_len; + + addr = Curl_str2addr(address, port); + if(!addr) { + infof(data, "Resolve %s found illegal!\n", hostp->data); + continue; + } + + /* Create an entry id, based upon the hostname and port */ + entry_id = create_hostcache_id(hostname, port); + /* If we can't create the entry id, fail */ + if(!entry_id) + return CURLE_OUT_OF_MEMORY; + + entry_len = strlen(entry_id); + + 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->dns.hostcache, entry_id, entry_len+1); + + /* free the allocated entry_id again */ + free(entry_id); + + if(!dns) + /* if not in the cache already, put this host in the cache */ + dns = Curl_cache_addr(data, addr, hostname, port); + else + /* this is a duplicate, free it again */ + Curl_freeaddrinfo(addr); + + if(data->share) + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); + + if(!dns) { + Curl_freeaddrinfo(addr); + return CURLE_OUT_OF_MEMORY; + } + infof(data, "Added %s:%d:%s to DNS cache\n", + hostname, port, address); + } + } + data->change.resolve = NULL; /* dealt with now */ + + return CURLE_OK; +} -- cgit v1.2.3