summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorArjan van de Ven <arjan@linux.intel.com>2012-01-09 16:08:29 -0800
committerDaniel Wagner <daniel.wagner@bmw-carit.de>2012-01-10 13:43:57 +0100
commit007cf88321db75c5f86649b73d0376d7c0ae01a6 (patch)
treeff1c1a3f197139cc901fa1d0506006bb5b794303 /src
parent3d849d116f85c656a97d07937f73307399babc07 (diff)
downloadconnman-007cf88321db75c5f86649b73d0376d7c0ae01a6.tar.gz
connman-007cf88321db75c5f86649b73d0376d7c0ae01a6.tar.bz2
connman-007cf88321db75c5f86649b73d0376d7c0ae01a6.zip
dnsproxy: Start tracking the end time of the TTL
In order to be able to report an accurate TTL to our client (see next patch to actually do that), we are going to need to track the end point in time for this TTL. This also allows us to track separately how long an entry is valid versus how long we want to cache the entry. This patch also adds some logic to group end times of the various cache entries to logical boundaries (10 and 30 seconds); this will cause cache entries to expire together, which is more efficient in power/performance, and also later when we add refreshing logic.
Diffstat (limited to 'src')
-rw-r--r--src/dnsproxy.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/src/dnsproxy.c b/src/dnsproxy.c
index 4810c6eb..93a1db57 100644
--- a/src/dnsproxy.c
+++ b/src/dnsproxy.c
@@ -127,6 +127,8 @@ struct listener_data {
struct cache_data {
time_t inserted;
+ time_t valid_until;
+ time_t cache_until;
int timeout;
uint16_t type;
uint16_t answers;
@@ -192,6 +194,27 @@ static int protocol_offset(int protocol)
}
+/*
+ * There is a power and efficiency benefit to have entries
+ * in our cache expire at the same time. To this extend,
+ * we round down the cache valid time to common boundaries.
+ */
+static time_t round_down_ttl(time_t end_time, int ttl)
+{
+ if (ttl < 15)
+ return end_time;
+
+ /* Less than 5 minutes, round to 10 second boundary */
+ if (ttl < 300) {
+ end_time = end_time / 10;
+ end_time = end_time * 10;
+ } else { /* 5 or more minutes, round to 30 seconds */
+ end_time = end_time / 30;
+ end_time = end_time * 30;
+ }
+ return end_time;
+}
+
static struct request_data *find_request(guint16 id)
{
GSList *list;
@@ -416,7 +439,7 @@ static gboolean cache_check_is_valid(struct cache_data *data,
if (data == NULL)
return FALSE;
- if (data->inserted + data->timeout < current_time)
+ if (data->cache_until < current_time)
return FALSE;
return TRUE;
@@ -862,22 +885,20 @@ static gboolean cache_check_entry(gpointer key, gpointer value,
*/
if (entry->ipv4 != NULL && entry->ipv4->timeout > 0) {
- max_timeout = entry->ipv4->inserted + entry->ipv4->timeout;
+ max_timeout = entry->ipv4->cache_until;
if (max_timeout > data->max_timeout)
data->max_timeout = max_timeout;
- if (entry->ipv4->inserted + entry->ipv4->timeout
- < data->current_time)
+ if (entry->ipv4->cache_until < data->current_time)
return TRUE;
}
if (entry->ipv6 != NULL && entry->ipv6->timeout > 0) {
- max_timeout = entry->ipv6->inserted + entry->ipv6->timeout;
+ max_timeout = entry->ipv6->cache_until;
if (max_timeout > data->max_timeout)
data->max_timeout = max_timeout;
- if (entry->ipv6->inserted + entry->ipv6->timeout
- < data->current_time)
+ if (entry->ipv6->cache_until < data->current_time)
return TRUE;
}
@@ -1002,6 +1023,14 @@ static int cache_update(struct server_data *srv, unsigned char *msg,
new_entry = FALSE;
}
+ data->inserted = current_time;
+ data->type = type;
+ data->answers = answers;
+ data->timeout = ttl;
+ data->data_len = 12 + qlen + 1 + 2 + 2 + rsplen;
+ data->data = ptr = g_malloc(data->data_len);
+ data->valid_until = current_time + ttl;
+
/*
* Restrict the cached DNS record TTL to some sane value
* in order to prevent data staying in the cache too long.
@@ -1009,12 +1038,8 @@ static int cache_update(struct server_data *srv, unsigned char *msg,
if (ttl > MAX_CACHE_TTL)
ttl = MAX_CACHE_TTL;
- data->inserted = current_time;
- data->type = type;
- data->answers = answers;
- data->timeout = ttl;
- data->data_len = 12 + qlen + 1 + 2 + 2 + rsplen;
- data->data = ptr = g_malloc(data->data_len);
+ data->cache_until = round_down_ttl(current_time + ttl, ttl);
+
if (data->data == NULL) {
g_free(entry->key);
g_free(data);