]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: DNS request retry counter used for retry only
authorBaptiste Assmann <bedis9@gmail.com>
Tue, 8 Sep 2015 22:54:38 +0000 (00:54 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 10 Sep 2015 13:46:03 +0000 (15:46 +0200)
There are two types of retries when performing a DNS resolution:
1. retry because of a timeout
2. retry of the full sequence of requests (query types failover)

Before this patch, the 'resolution->try' counter was incremented
after each send of a DNS request, which does not cover the 2 cases
above.
This patch fix this behavior.

src/checks.c
src/dns.c
src/server.c

index 3fb166bfd92b3487f5314dca3454241722a27b10..eeff4eaacc80e78bc855037a927d88f315485b6e 100644 (file)
@@ -2215,13 +2215,14 @@ int trigger_resolution(struct server *s)
        resolution->qid.key = query_id;
        resolution->step = RSLV_STEP_RUNNING;
        resolution->query_type = DNS_RTYPE_ANY;
-       resolution->try = 0;
+       resolution->try = resolvers->resolve_retries;
        resolution->try_cname = 0;
        resolution->nb_responses = 0;
        resolution->resolver_family_priority = s->resolver_family_priority;
        eb32_insert(&resolvers->query_ids, &resolution->qid);
 
        dns_send_query(resolution);
+       resolution->try -= 1;
 
        /* update wakeup date if this resolution is the only one in the FIFO list */
        if (dns_check_resolution_queue(resolvers) == 1) {
index d002f1b93919b6f27d2bb809e2c5528074287555..3439f7ee90e17415daf3812c90a94f8492bc7d4b 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
@@ -305,7 +305,6 @@ int dns_send_query(struct dns_resolution *resolution)
        }
 
        /* update resolution */
-       resolution->try += 1;
        resolution->nb_responses = 0;
        resolution->last_sent_packet = now_ms;
 
@@ -1103,7 +1102,7 @@ struct task *dns_process_resolve(struct task *t)
                 * if current resolution has been tried too many times and finishes in timeout
                 * we update its status and remove it from the list
                 */
-               if (resolution->try >= resolvers->resolve_retries) {
+               if (resolution->try <= 0) {
                        /* clean up resolution information and remove from the list */
                        dns_reset_resolution(resolution);
 
@@ -1111,6 +1110,8 @@ struct task *dns_process_resolve(struct task *t)
                        resolution->requester_error_cb(resolution, DNS_RESP_TIMEOUT);
                }
 
+               resolution->try -= 1;
+
                /* check current resolution status */
                if (resolution->step == RSLV_STEP_RUNNING) {
                        /* resend the DNS query */
index 8bc3165c786dcb9aa8bf07a42c1297a3c27cf3ed..49ab68b0cf7c13a0c67c2588e61c24346bcc6a68 100644 (file)
@@ -2132,7 +2132,8 @@ int snr_resolution_error_cb(struct dns_resolution *resolution, int error_code)
                        res_preferred_afinet = resolution->resolver_family_priority == AF_INET && resolution->query_type == DNS_RTYPE_A;
                        res_preferred_afinet6 = resolution->resolver_family_priority == AF_INET6 && resolution->query_type == DNS_RTYPE_AAAA;
 
-                       if (qtype_any || res_preferred_afinet || res_preferred_afinet6) {
+                       if ((qtype_any || res_preferred_afinet || res_preferred_afinet6)
+                                      || (resolution->try > 0)) {
                                /* let's change the query type */
                                if (qtype_any) {
                                        /* fallback from ANY to resolution preference */
@@ -2149,6 +2150,10 @@ int snr_resolution_error_cb(struct dns_resolution *resolution, int error_code)
                                        /* fallback from A to AAAA */
                                        resolution->query_type = DNS_RTYPE_AAAA;
                                }
+                               else {
+                                       resolution->try -= 1;
+                                       resolution->query_type = DNS_RTYPE_ANY;
+                               }
 
                                dns_send_query(resolution);