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.
This commit is contained in:
Baptiste Assmann 2015-09-02 22:20:56 +02:00 committed by Willy Tarreau
parent 3440f0da2a
commit 90447582d7

View File

@ -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);