mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-21 05:00:42 +00:00
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.
This commit is contained in:
parent
8d11236234
commit
f5f71304b0
11
src/dns.c
11
src/dns.c
@ -183,7 +183,7 @@ int dns_trigger_resolution(struct dns_resolution *resolution)
|
||||
{
|
||||
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 @@ int dns_trigger_resolution(struct dns_resolution *resolution)
|
||||
|
||||
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 @@ int dns_trigger_resolution(struct dns_resolution *resolution)
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user