mirror of
https://github.com/curl/curl.git
synced 2026-08-25 04:13:32 +03:00
dns: extend CURLOPT_RESOLVE syntax for adding non-permanent entries
Extend the syntax of CURLOPT_RESOLVE strings: allow using a '+' prefix (similar to the existing '-' prefix for removing entries) to add DNS cache entries that will time out just like entries that are added by libcurl itself. Append " (non-permanent)" to info log message in case a non-permanent entry is added. Adjust relevant comments to reflect the new behavior. Adjust documentation. Extend unit1607 to test the new functionality. Closes #6294
This commit is contained in:
parent
68dde8e330
commit
8324dc8b1a
6 changed files with 82 additions and 40 deletions
36
lib/hostip.c
36
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') {
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ struct Curl_hash *Curl_global_host_cache_init(void);
|
|||
|
||||
struct Curl_dns_entry {
|
||||
struct Curl_addrinfo *addr;
|
||||
/* timestamp == 0 -- CURLOPT_RESOLVE entry, doesn't timeout */
|
||||
/* timestamp == 0 -- permanent CURLOPT_RESOLVE entry (doesn't time out) */
|
||||
time_t timestamp;
|
||||
/* use-counter, use Curl_resolv_unlock to release reference */
|
||||
long inuse;
|
||||
|
|
|
|||
13
lib/setopt.c
13
lib/setopt.c
|
|
@ -1460,13 +1460,16 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
|||
break;
|
||||
case CURLOPT_RESOLVE:
|
||||
/*
|
||||
* List of NAME:[address] names to populate the DNS cache with
|
||||
* Prefix the NAME with dash (-) to _remove_ the name from the cache.
|
||||
*
|
||||
* Names added with this API will remain in the cache until explicitly
|
||||
* List of HOST:PORT:[addresses] strings to populate the DNS cache with
|
||||
* Entries added this way will remain in the cache until explicitly
|
||||
* removed or the handle is cleaned up.
|
||||
*
|
||||
* This API can remove any name from the DNS cache, but only entries
|
||||
* Prefix the HOST with plus sign (+) to have the entry expire just like
|
||||
* automatically added entries.
|
||||
*
|
||||
* Prefix the HOST with dash (-) to _remove_ the entry from the cache.
|
||||
*
|
||||
* This API can remove any entry from the DNS cache, but only entries
|
||||
* that aren't actually in use right now will be pruned immediately.
|
||||
*/
|
||||
data->set.resolve = va_arg(param, struct curl_slist *);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue