From: Mark Wooding Date: Mon, 12 May 2014 09:34:02 +0000 (+0100) Subject: Start work on handling inconsistent CNAMEs in addr queries. X-Git-Tag: wip.base.getaddrinfo~22 X-Git-Url: https://git.distorted.org.uk/~mdw/adns/commitdiff_plain/0aa4a35785ac722734fcd8d461ac14a5e791a08c Start work on handling inconsistent CNAMEs in addr queries. --- diff --git a/src/internal.h b/src/internal.h index 66e55dc..1a9c61b 100644 --- a/src/internal.h +++ b/src/internal.h @@ -94,7 +94,10 @@ typedef enum { enum { adns__qf_senddirect = 0x00100000,/* don't call the `query_send' type hook */ - adns__qf_nosend = 0x00200000 /* don't send the query when submitting */ + adns__qf_nosend = 0x00200000,/* don't send the query when submitting */ + adns__qf_addr_answer= 0x01000000,/* addr query received an answer */ + adns__qf_addr_cnhack= 0x02000000,/* addr query found cname inconsistency */ + adns__qf_addr_cname = 0x04000000 /* addr subquery performed on cname */ }; /* Shared data structures */ diff --git a/src/types.c b/src/types.c index 0f672bf..b87039d 100644 --- a/src/types.c +++ b/src/types.c @@ -339,6 +339,27 @@ static adns_status cs_in6addr(vbuf *vb, const void *datap) { * addr_rrtypes, addr_rrsz) */ +/* About CNAME handling in addr queries. + * + * A user-level addr query is translated into a number of protocol-level + * queries, and its job is to reassemble the results. This gets tricky if + * the answers aren't consistent. In particular, if the answers report + * inconsistent indirection via CNAME records (e.g., different CNAMEs, or + * some indirect via a CNAME, and some don't) then we have trouble. + * + * Once we've received an answer, even if it was NODATA, we set + * adns__qf_addr_answer on the parent query. This will let us detect a + * conflict between a no-CNAME-with-NODATA reply and a subsequent CNAME. + * + * If we detect a conflict of any kind, then at least one answer came back + * with a CNAME record, so we pick the first such answer (somewhat + * arbitrarily) as being the `right' canonical name, and set this in the + * parent query's answer->cname slot. We discard address records from the + * wrong name. And finally we cancel the outstanding child queries, and + * resubmit address queries for the address families we don't yet have, with + * adns__qf_addr_cname set so that we know that we're in the fixup state. + */ + static adns_status pap_addr(const parseinfo *pai, int rrty, size_t rrsz, int *cbyte_io, int max, adns_rr_addr *storeto) { @@ -508,9 +529,8 @@ static void icb_addr(adns_query parent, adns_query child) adns_status err; const struct timeval *now = 0; - /* Must handle CNAMEs correctly. This gets very hairy if the answers we - * get are inconsistent. - */ + if (child->cname || parent->cname) { + } if ((parent->flags & adns_qf_search) && cans->status == adns_s_nxdomain) {