Oh wonderful - something's come up that would have blocked me from
working on this until next week, so thank you very much for updating
it for me!

On Tue, Oct 20, 2015 at 3:07 PM, Baptiste <[email protected]> wrote:
> Hi Andrew,
>
> I've updated your patch quickly so Willy can integrate it.
> I've also updated the commit message to follow Lukas recommendations.
>
> Baptiste
>
> On Tue, Oct 20, 2015 at 2:26 PM, Baptiste <[email protected]> wrote:
>> Hi Andrew,
>>
>> There is a bug repeated twice in your code.
>> In both dns_reset_resolution() and trigger_resolution(), you use
>> "resolution->resolver_family_priority" before it is positioned. This
>> may lead to using the last resolution->resolver_family_priority, which
>> may be different than the server one.
>> Please move the line "resolution->resolver_family_priority =
>> s->resolver_family_priority;" before using the value stored in it.
>>
>> Appart this, it looks good.
>>
>> Baptiste
>>
>>
>> On Tue, Oct 20, 2015 at 12:39 AM, Andrew Hayworth
>> <[email protected]> wrote:
>>> The ANY query type is weird, and some resolvers don't 'do the legwork'
>>> of resolving useful things like CNAMEs. Given that upstream resolver
>>> behavior is not always under the control of the HAProxy administrator,
>>> we should not use the ANY query type. Rather, we should use A or AAAA
>>> according to either the explicit preferences of the operator, or the
>>> implicit default (AAAA/IPv6).
>>>
>>> - Andrew Hayworth
>>>
>>> From 8ed172424cbd79197aacacd1fd89ddcfa46e213d Mon Sep 17 00:00:00 2001
>>> From: Andrew Hayworth <[email protected]>
>>> Date: Mon, 19 Oct 2015 22:29:51 +0000
>>> Subject: [PATCH] MEDIUM: dns: Don't use the ANY query type
>>>
>>> Basically, it's ill-defined and shouldn't really be used going forward.
>>> We can't guarantee that resolvers will do the 'legwork' for us and
>>> actually resolve CNAMES when we request the ANY query-type. Case in point
>>> (obfuscated, clearly):
>>>
>>>   PRODUCTION! [email protected]:~$
>>>   dig @10.11.12.53 ANY api.somestartup.io
>>>
>>>   ; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> @10.11.12.53 ANY api.somestartup.io
>>>   ; (1 server found)
>>>   ;; global options: +cmd
>>>   ;; Got answer:
>>>   ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62454
>>>   ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 0
>>>
>>>   ;; QUESTION SECTION:
>>>   ;api.somestartup.io.                        IN      ANY
>>>
>>>   ;; ANSWER SECTION:
>>>   api.somestartup.io.         20      IN      CNAME
>>> api-somestartup-production.ap-southeast-2.elb.amazonaws.com.
>>>
>>>   ;; AUTHORITY SECTION:
>>>   somestartup.io.               166687  IN      NS      
>>> ns-1254.awsdns-28.org.
>>>   somestartup.io.               166687  IN      NS      
>>> ns-1884.awsdns-43.co.uk.
>>>   somestartup.io.               166687  IN      NS      
>>> ns-440.awsdns-55.com.
>>>   somestartup.io.               166687  IN      NS      
>>> ns-577.awsdns-08.net.
>>>
>>>   ;; Query time: 1 msec
>>>   ;; SERVER: 10.11.12.53#53(10.11.12.53)
>>>   ;; WHEN: Mon Oct 19 22:02:29 2015
>>>   ;; MSG SIZE  rcvd: 242
>>>
>>> HAProxy can't handle that response correctly.
>>>
>>> Rather than try to build in support for resolving CNAMEs presented
>>> without an A record in an answer section (which may be a valid
>>> improvement further on), this change just skips ANY record types
>>> altogether. A and AAAA are much more well-defined and predictable.
>>>
>>> Notably, this commit preserves the implicit "Prefer IPV6 behavior."
>>> ---
>>>  include/types/dns.h |  3 ++-
>>>  src/checks.c        |  6 +++++-
>>>  src/dns.c           |  6 +++++-
>>>  src/server.c        | 18 +++++++-----------
>>>  4 files changed, 19 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/include/types/dns.h b/include/types/dns.h
>>> index f8edb73..ea1a9f9 100644
>>> --- a/include/types/dns.h
>>> +++ b/include/types/dns.h
>>> @@ -161,7 +161,8 @@ struct dns_resolution {
>>>   unsigned int last_status_change; /* time of the latest DNS
>>> resolution status change */
>>>   int query_id; /* DNS query ID dedicated for this resolution */
>>>   struct eb32_node qid; /* ebtree query id */
>>> - int query_type; /* query type to send. By default DNS_RTYPE_ANY */
>>> + int query_type;
>>> + /* query type to send. By default DNS_RTYPE_A or DNS_RTYPE_AAAA
>>> depending on resolver_family_priority */
>>>   int status; /* status of the resolution being processed RSLV_STATUS_* */
>>>   int step; /* */
>>>   int try; /* current resolution try */
>>> diff --git a/src/checks.c b/src/checks.c
>>> index ade2428..d3cd567 100644
>>> --- a/src/checks.c
>>> +++ b/src/checks.c
>>> @@ -2214,7 +2214,11 @@ int trigger_resolution(struct server *s)
>>>   resolution->query_id = query_id;
>>>   resolution->qid.key = query_id;
>>>   resolution->step = RSLV_STEP_RUNNING;
>>> - resolution->query_type = DNS_RTYPE_ANY;
>>> + if (resolution->resolver_family_priority == AF_INET) {
>>> + resolution->query_type = DNS_RTYPE_A;
>>> + } else {
>>> + resolution->query_type = DNS_RTYPE_AAAA;
>>> + }
>>>   resolution->try = resolvers->resolve_retries;
>>>   resolution->try_cname = 0;
>>>   resolution->nb_responses = 0;
>>> diff --git a/src/dns.c b/src/dns.c
>>> index 7f71ac7..53b65ab 100644
>>> --- a/src/dns.c
>>> +++ b/src/dns.c
>>> @@ -102,7 +102,11 @@ void dns_reset_resolution(struct dns_resolution
>>> *resolution)
>>>   resolution->qid.key = 0;
>>>
>>>   /* default values */
>>> - resolution->query_type = DNS_RTYPE_ANY;
>>> + if (resolution->resolver_family_priority == AF_INET) {
>>> + resolution->query_type = DNS_RTYPE_A;
>>> + } else {
>>> + resolution->query_type = DNS_RTYPE_AAAA;
>>> + }
>>>
>>>   /* the second resolution in the queue becomes the first one */
>>>   LIST_DEL(&resolution->list);
>>> diff --git a/src/server.c b/src/server.c
>>> index 8ddff00..33d6922 100644
>>> --- a/src/server.c
>>> +++ b/src/server.c
>>> @@ -2692,21 +2692,13 @@ int snr_resolution_error_cb(struct
>>> dns_resolution *resolution, int error_code)
>>>   case DNS_RESP_TRUNCATED:
>>>   case DNS_RESP_ERROR:
>>>   case DNS_RESP_NO_EXPECTED_RECORD:
>>> - 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)
>>> + if ((res_preferred_afinet || res_preferred_afinet6)
>>>         || (resolution->try > 0)) {
>>>   /* let's change the query type */
>>> - 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) {
>>> + if (res_preferred_afinet6) {
>>>   /* fallback from AAAA to A */
>>>   resolution->query_type = DNS_RTYPE_A;
>>>   }
>>> @@ -2716,7 +2708,11 @@ int snr_resolution_error_cb(struct
>>> dns_resolution *resolution, int error_code)
>>>   }
>>>   else {
>>>   resolution->try -= 1;
>>> - resolution->query_type = DNS_RTYPE_ANY;
>>> + if (resolution->resolver_family_priority == AF_INET) {
>>> + resolution->query_type = DNS_RTYPE_A;
>>> + } else {
>>> + resolution->query_type = DNS_RTYPE_AAAA;
>>> + }
>>>   }
>>>
>>>   dns_send_query(resolution);
>>> --
>>> 2.1.3



-- 
- Andrew Hayworth

Reply via email to