summaryrefslogtreecommitdiff
path: root/lib/hostip.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hostip.c')
-rw-r--r--lib/hostip.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/lib/hostip.c b/lib/hostip.c
index ab1f6df05..50fb42f21 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -444,7 +444,7 @@ Curl_cache_addr(struct Curl_easy *data,
dns->addr = addr; /* this is the address(es) */
time(&dns->timestamp);
if(dns->timestamp == 0)
- dns->timestamp = 1; /* zero indicates CURLOPT_RESOLVE entry */
+ dns->timestamp = 1; /* zero indicates permanent CURLOPT_RESOLVE entry */
/* Store the resolved data in our DNS cache. */
dns2 = Curl_hash_add(data->dns.hostcache, entry_id, entry_len + 1,
@@ -916,17 +916,24 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
char *addr_end;
char *port_ptr;
char *end_ptr;
+ bool permanent = TRUE;
+ char *host_begin;
char *host_end;
unsigned long tmp_port;
bool error = true;
- host_end = strchr(hostp->data, ':');
+ host_begin = hostp->data;
+ if(host_begin[0] == '+') {
+ host_begin++;
+ permanent = FALSE;
+ }
+ host_end = strchr(host_begin, ':');
if(!host_end ||
- ((host_end - hostp->data) >= (ptrdiff_t)sizeof(hostname)))
+ ((host_end - host_begin) >= (ptrdiff_t)sizeof(hostname)))
goto err;
- memcpy(hostname, hostp->data, host_end - hostp->data);
- hostname[host_end - hostp->data] = '\0';
+ memcpy(hostname, host_begin, host_end - host_begin);
+ hostname[host_end - host_begin] = '\0';
port_ptr = host_end + 1;
tmp_port = strtoul(port_ptr, &end_ptr, 10);
@@ -1008,18 +1015,22 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
if(data->share)
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
- /* See if its already in our dns cache */
+ /* See if it's already in our dns cache */
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1);
if(dns) {
infof(data, "RESOLVE %s:%d is - old addresses discarded!\n",
hostname, port);
- /* delete old entry entry, there are two reasons for this
+ /* delete old entry, there are two reasons for this
1. old entry may have different addresses.
2. even if entry with correct addresses is already in the cache,
but if it is close to expire, then by the time next http
request is made, it can get expired and pruned because old
- entry is not necessarily marked as added by CURLOPT_RESOLVE. */
+ entry is not necessarily marked as permanent.
+ 3. when adding a non-permanent entry, we want it to remove and
+ replace an existing permanent entry.
+ 4. when adding a non-permanent entry, we want it to get a "fresh"
+ timeout that starts _now_. */
Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1);
}
@@ -1027,10 +1038,11 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
/* put this new host in the cache */
dns = Curl_cache_addr(data, head, hostname, port);
if(dns) {
- dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */
+ if(permanent)
+ dns->timestamp = 0; /* mark as permanent */
/* release the returned reference; the cache itself will keep the
* entry alive: */
- dns->inuse--;
+ dns->inuse--;
}
if(data->share)
@@ -1040,8 +1052,8 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
Curl_freeaddrinfo(head);
return CURLE_OUT_OF_MEMORY;
}
- infof(data, "Added %s:%d:%s to DNS cache\n",
- hostname, port, addresses);
+ infof(data, "Added %s:%d:%s to DNS cache%s\n",
+ hostname, port, addresses, permanent ? "" : " (non-permanent)");
/* Wildcard hostname */
if(hostname[0] == '*' && hostname[1] == '\0') {