BUG/MINOR: dns: wrong resolution interval lead to 100% CPU
Since the DNS layer split and the use of obj_type structure, we did not
updated propoerly the code used to compute the interval between 2
resolutions.
A nasty loop was then created when:
- resolver's hold.valid is shorter than servers' check.inter
- a valid response is available in the DNS cache
A task was woken up for a server's resolution. The servers pick up the IP
in the cache and returns without updating the 'last update' timestamp of
the resolution (which is normal...). Then the task is woken up again for
the same server.
The fix simply computes now properly the interval between 2 resolutions
and the cache is used properly while a new resolution is triggered if
the data is not fresh enough.
diff --git a/src/dns.c b/src/dns.c
index 421beab..2cf1ec9 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -183,7 +183,7 @@
{
struct dns_requester *requester = NULL, *tmprequester;
struct dns_resolvers *resolvers = NULL;
- int inter;
+ int inter, valid_period;
/* process the element of the wait queue */
list_for_each_entry_safe(requester, tmprequester, &resolution->requester.wait, list) {
@@ -191,11 +191,11 @@
switch (obj_type(requester->requester)) {
case OBJ_TYPE_SERVER:
- inter = objt_server(requester->requester)->check.inter;
+ valid_period = objt_server(requester->requester)->check.inter;
resolvers = objt_server(requester->requester)->resolvers;
break;
case OBJ_TYPE_SRVRQ:
- inter = objt_dns_srvrq(requester->requester)->inter;
+ valid_period = objt_dns_srvrq(requester->requester)->inter;
resolvers = objt_dns_srvrq(requester->requester)->resolvers;
break;
case OBJ_TYPE_NONE:
@@ -203,6 +203,11 @@
return -1;
}
+ if (resolvers->hold.valid < valid_period)
+ inter = resolvers->hold.valid;
+ else
+ inter = valid_period;
+
/* if data is fresh enough, let's use it */
if (!tick_is_expired(tick_add(resolution->last_resolution, inter), now_ms)) {
/* we only use cache if the response there is valid.