Add support for DNS cache timeouts via the CURLOPT_DNS_CACHE_TIMEOUT option.
The default cache timeout for this is 60 seconds, which is arbitrary and completely subject to change :)
This commit is contained in:
parent
87037136ef
commit
22ac08e06d
@ -491,6 +491,9 @@ typedef enum {
|
||||
/* Non-zero value means to use the global dns cache */
|
||||
CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91),
|
||||
|
||||
/* DNS cache timeout */
|
||||
CINIT(DNS_CACHE_TIMEOUT, LONG, 92),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unusued */
|
||||
} CURLoption;
|
||||
|
||||
|
63
lib/hostip.c
63
lib/hostip.c
@ -93,24 +93,59 @@ void Curl_global_host_cache_dtor(void)
|
||||
}
|
||||
}
|
||||
|
||||
struct curl_dns_cache_entry {
|
||||
Curl_addrinfo *addr;
|
||||
int timestamp;
|
||||
};
|
||||
|
||||
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
||||
char *hostname,
|
||||
int port,
|
||||
char **bufp)
|
||||
{
|
||||
Curl_addrinfo *addr = NULL;
|
||||
size_t hostname_len = strlen(hostname)+1;
|
||||
struct curl_dns_cache_entry *p = NULL;
|
||||
size_t hostname_len;
|
||||
time_t now;
|
||||
|
||||
if (curl_hash_find(data->hostcache, hostname, hostname_len, (void **) &addr)) {
|
||||
return addr;
|
||||
/* If the host cache timeout is 0, we don't do DNS cach'ing
|
||||
so fall through */
|
||||
if (data->set.dns_cache_timeout == 0) {
|
||||
return Curl_getaddrinfo(data, hostname, port, bufp);
|
||||
}
|
||||
|
||||
addr = Curl_getaddrinfo(data, hostname, port, bufp);
|
||||
if (!addr)
|
||||
return NULL;
|
||||
|
||||
curl_hash_add(data->hostcache, hostname, hostname_len, (const void *) addr);
|
||||
return addr;
|
||||
hostname_len = strlen(hostname)+1;
|
||||
|
||||
time(&now);
|
||||
/* See if its already in our dns cache */
|
||||
if (curl_hash_find(data->hostcache, hostname, hostname_len, (void **) &p)) {
|
||||
/* Do we need to check for a cache timeout? */
|
||||
if (data->set.dns_cache_timeout != -1) {
|
||||
/* Return if the entry has not timed out */
|
||||
if ((now - p->timestamp) < data->set.dns_cache_timeout) {
|
||||
return p->addr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return p->addr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a new cache entry */
|
||||
p = (struct curl_dns_cache_entry *) malloc(sizeof(struct curl_dns_cache_entry));
|
||||
if (!p) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p->addr = Curl_getaddrinfo(data, hostname, port, bufp);
|
||||
if (!p->addr) {
|
||||
return NULL;
|
||||
}
|
||||
p->timestamp = now;
|
||||
|
||||
/* Save it in our host cache */
|
||||
curl_hash_update(data->hostcache, hostname, hostname_len, (const void *) p);
|
||||
|
||||
return p->addr;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -120,11 +155,15 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
||||
*/
|
||||
void Curl_freeaddrinfo(void *freethis)
|
||||
{
|
||||
struct curl_dns_cache_entry *p = (struct curl_dns_cache_entry *) freethis;
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
freeaddrinfo(freethis);
|
||||
freeaddrinfo(p->addr);
|
||||
#else
|
||||
free(freethis);
|
||||
free(p->addr);
|
||||
#endif
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
/* --- resolve name or IP-number --- */
|
||||
|
10
lib/url.c
10
lib/url.c
@ -251,13 +251,15 @@ CURLcode Curl_open(struct SessionHandle **curl)
|
||||
data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
|
||||
data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
|
||||
|
||||
data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
|
||||
|
||||
/* make libcurl quiet by default: */
|
||||
data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
|
||||
data->progress.flags |= PGRS_HIDE;
|
||||
|
||||
/* Set the default size of the SSL session ID cache */
|
||||
data->set.ssl.numsessions = 5;
|
||||
|
||||
|
||||
/* create an array with connection data struct pointers */
|
||||
data->state.numconnects = 5; /* hard-coded right now */
|
||||
data->state.connects = (struct connectdata **)
|
||||
@ -284,7 +286,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
||||
va_start(param, option);
|
||||
|
||||
switch(option) {
|
||||
case CURLOPT_DNS_USE_GLOBAL_CACHE: {
|
||||
case CURLOPT_DNS_CACHE_TIMEOUT:
|
||||
data->set.dns_cache_timeout = va_arg(param, int);
|
||||
break;
|
||||
case CURLOPT_DNS_USE_GLOBAL_CACHE:
|
||||
{
|
||||
int use_cache = va_arg(param, int);
|
||||
if (use_cache) {
|
||||
Curl_global_host_cache_init();
|
||||
|
@ -647,6 +647,7 @@ struct UserDefined {
|
||||
bool ftp_use_epsv; /* if EPSV is to be attempted or not */
|
||||
|
||||
bool global_dns_cache;
|
||||
bool dns_cache_timeout;
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user