aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSterling Hughes <sterling@bumblebury.com>2002-01-08 04:26:47 +0000
committerSterling Hughes <sterling@bumblebury.com>2002-01-08 04:26:47 +0000
commit22ac08e06db32cb2a7872316a669eb81ec3ea204 (patch)
tree1afa025886527ee24580723104e03357931cc786
parent87037136efd4d5eeefb7456c2ad14740a956e47d (diff)
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 :)
-rw-r--r--include/curl/curl.h3
-rw-r--r--lib/hostip.c61
-rw-r--r--lib/url.c10
-rw-r--r--lib/urldata.h1
4 files changed, 62 insertions, 13 deletions
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 3d91c85ff..9059d1492 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -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;
diff --git a/lib/hostip.c b/lib/hostip.c
index 9d0013ffe..fc76242f7 100644
--- a/lib/hostip.c
+++ b/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 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);
+ }
+
+ 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;
+ }
+ }
- if (curl_hash_find(data->hostcache, hostname, hostname_len, (void **) &addr)) {
- return addr;
+ /* Create a new cache entry */
+ p = (struct curl_dns_cache_entry *) malloc(sizeof(struct curl_dns_cache_entry));
+ if (!p) {
+ return NULL;
}
-
- addr = Curl_getaddrinfo(data, hostname, port, bufp);
- if (!addr)
+
+ p->addr = Curl_getaddrinfo(data, hostname, port, bufp);
+ if (!p->addr) {
return NULL;
+ }
+ p->timestamp = now;
- curl_hash_add(data->hostcache, hostname, hostname_len, (const void *) addr);
- return addr;
+ /* 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 --- */
diff --git a/lib/url.c b/lib/url.c
index 56e7fa73f..63d9ae56a 100644
--- a/lib/url.c
+++ b/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();
diff --git a/lib/urldata.h b/lib/urldata.h
index 36358d60f..64ee821ca 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -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;
};
/*