aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/hash.c20
-rw-r--r--lib/hash.h1
-rw-r--r--lib/hostip.c51
3 files changed, 61 insertions, 11 deletions
diff --git a/lib/hash.c b/lib/hash.c
index dd2f00b6a..a262b2a44 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -249,6 +249,26 @@ curl_hash_clean(curl_hash *h)
}
/* }}} */
+/* {{{ void curl_hash_clean_with_criterium (curl_hash *, void *, int (*)(void *, void *))
+ */
+void
+curl_hash_clean_with_criterium(curl_hash *h, void *user, int (*comp)(void *, void *))
+{
+ curl_llist_element *le;
+ int i;
+
+ for (i = 0; i < h->slots; ++i) {
+ for (le = CURL_LLIST_HEAD(h->table[i]);
+ le != NULL;
+ le = CURL_LLIST_NEXT(le)) {
+ if (comp(user, ((curl_hash_element *) CURL_LLIST_VALP(le))->ptr)) {
+ curl_llist_remove(h->table[i], le, (void *) h);
+ --h->size;
+ }
+ }
+ }
+}
+
/* {{{ int curl_hash_count (curl_hash *)
*/
int
diff --git a/lib/hash.h b/lib/hash.h
index 6c74ed2d3..9f4557639 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -53,6 +53,7 @@ int curl_hash_find(curl_hash *, char *, size_t, void **p);
void curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *));
int curl_hash_count(curl_hash *h);
void curl_hash_clean(curl_hash *h);
+void curl_hash_clean_with_criterium(curl_hash *h, void *user, int (*comp)(void *, void *));
void curl_hash_destroy(curl_hash *h);
#define curl_hash_update curl_hash_add
diff --git a/lib/hostip.c b/lib/hostip.c
index 356b93015..e3daab1ff 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -152,6 +152,38 @@ _create_hostcache_id(char *server, int port, ssize_t *entry_len)
return id;
}
+struct _curl_hostcache_prune_data {
+ int cache_timeout;
+ int now;
+};
+
+static int
+_curl_hostcache_timestamp_remove(void *datap, void *hc)
+{
+ struct _curl_hostcache_prune_data *data =
+ (struct _curl_hostcache_prune_data *) datap;
+ struct curl_dns_cache_entry *c = (struct curl_dns_cache_entry *) hc;
+
+ if (data->now - c->timestamp < data->cache_timeout) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static void
+_curl_hostcache_prune(curl_hash *hostcache, int cache_timeout, int now)
+{
+ struct _curl_hostcache_prune_data user;
+
+ user.cache_timeout = cache_timeout;
+ user.now = now;
+
+ curl_hash_clean_with_criterium(hostcache,
+ (void *) &user,
+ _curl_hostcache_timestamp_remove);
+}
+
/* Macro to save redundant free'ing of entry_id */
#define _hostcache_return(__v) \
{ \
@@ -175,6 +207,13 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
return Curl_getaddrinfo(data, hostname, port, bufp);
}
+ time(&now);
+
+ /* Remove outdated entries from the hostcache */
+ _curl_hostcache_prune(data->hostcache,
+ data->set.dns_cache_timeout,
+ now);
+
/* Create an entry id, based upon the hostname and port */
entry_len = strlen(hostname);
entry_id = _create_hostcache_id(hostname, port, &entry_len);
@@ -184,19 +223,9 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
return Curl_getaddrinfo(data, hostname, port, bufp);
}
- time(&now);
/* See if its already in our dns cache */
if (entry_id && curl_hash_find(data->hostcache, entry_id, entry_len+1, (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) {
- _hostcache_return(p->addr);
- }
- }
- else {
- _hostcache_return(p->addr);
- }
+ _hostcache_return(p->addr);
}
/* Create a new cache entry */