From: Baptiste Assmann Date: Wed, 2 Sep 2015 20:20:56 +0000 (+0200) Subject: MINOR: DNS client query type failover management X-Git-Tag: v1.6-dev5~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=90447582d79a773f66dc3ef1ea2c0cbbc8da5ad3;p=thirdparty%2Fhaproxy.git MINOR: DNS client query type failover management In the first version of the DNS resolver, HAProxy sends an ANY query type and in case of issue fails over to the type pointed by the directive in 'resolve-prefer'. This patch allows the following new failover management: 1. default query type is still ANY 2. if response is truncated or in error because ANY is not supported by the server, then a fail over to a new query type is performed. The new query type is the one pointed by the directive 'resolve-prefer'. 3. if no response or still some errors occurs, then a query type fail over is performed to the remaining IP address family. --- diff --git a/src/server.c b/src/server.c index ca8c4f88da..340a310501 100644 --- a/src/server.c +++ b/src/server.c @@ -2112,6 +2112,7 @@ int snr_resolution_error_cb(struct dns_resolution *resolution, int error_code) { struct server *s; struct dns_resolvers *resolvers; + int qtype_any, res_preferred_afinet, res_preferred_afinet6; /* shortcut to the server whose name is being resolved */ s = (struct server *)resolution->requester; @@ -2134,12 +2135,27 @@ int snr_resolution_error_cb(struct dns_resolution *resolution, int error_code) case DNS_RESP_ANCOUNT_ZERO: case DNS_RESP_TRUNCATED: case DNS_RESP_ERROR: - if (resolution->query_type == DNS_RTYPE_ANY) { + qtype_any = resolution->query_type == DNS_RTYPE_ANY; + 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) { /* let's change the query type */ - if (resolution->resolver_family_priority == AF_INET6) - resolution->query_type = DNS_RTYPE_AAAA; - else + if (qtype_any) { + /* fallback from ANY to resolution preference */ + if (resolution->resolver_family_priority == AF_INET6) + resolution->query_type = DNS_RTYPE_AAAA; + else + resolution->query_type = DNS_RTYPE_A; + } + else if (res_preferred_afinet6) { + /* fallback from AAAA to A */ resolution->query_type = DNS_RTYPE_A; + } + else if (res_preferred_afinet) { + /* fallback from A to AAAA */ + resolution->query_type = DNS_RTYPE_AAAA; + } dns_send_query(resolution);