ietf
[Top] [All Lists]

Re: DNS: Order of CNAME and A in Authoritative Reply.

2015-08-11 15:59:20

In message 
<20150811140909(_dot_)6F61221AAC(_at_)orac(_dot_)inputplus(_dot_)co(_dot_)uk>, 
Ralph Corderoy writes:
Hi,

If a non-recursive DNS query for an A RR is sent to the authoritative
server for both the queried CNAME and the A RR that's its value, it does
not seem to be clearly stated in the RFCs that the CNAME answer shall
precede the A answer in the reply.

BIND/named seems to have done the obvious from early on, appending the
CNAME to the reply, and then appending the A.  Clients have come to
depend on this behaviour, assuming on seeing the CNAME that they can
switch horses to the CNAME's value and continue processing the packet
from that point.  DNS servers that don't follow this unwritten
convention thus break some of the many and varied clients that already
exist.

How do we get the desired behaviour clarified so implementers of servers
and clients have a reference when trying to resolve their disagreement?
IMO, the CNAME should precede the A, but that still isn't precise
enough.  Some are asking if it's sufficient that all CNAME precede all
A.

Here's some background.

http://tools.ietf.org/html/rfc1034#section-4.3.1 says

    If recursive service is requested and available, the recursive
    response to a query will be one of the following:

       - The answer to the query, possibly preface by one or more CNAME
         RRs that specify aliases encountered on the way to an answer.

but this is a non-recursive query.

http://tools.ietf.org/html/rfc1034#section-4.3.2 says

                If the data at the node is a CNAME, and QTYPE doesn't
                match CNAME, copy the CNAME RR into the answer section
                of the response, change QNAME to the canonical name in
                the CNAME RR, and go back to step 1.

but copying doesn't state an order,

Actually the order of the RRsets in the answer section is defined
by that.  The order of the RRsets in the other sections isn't.

strictly, and 4.3.2 starts by saying

    The actual algorithm used by the name server will depend on the
    local OS and data structures used to store RRs.

Which allows you to use a hash table instead of a tree.  Or a hash
table and a tree.  Or to store the CNAME + pointer to the target
data so there is one lookup into the data store.  You can also use
a flat database.  The answers that are generated need to match those
that would be generate by processing the data in the tree structure
defined following the defined algorithm.

so someone arguing otherwise can say other algorithms are valid.

I've been talking with Robert Elz, co-author of RFC 2181, Clarifications
to the DNS Specification, July 1997.  He briefly shared a room with
Kevin Dunlap when the latter was working on an early BIND at UCB.  His
opinion is the order isn't stated, and that no one considered it
relevant.  Then client implementations came to depend on BIND's
ordering, as it led to simpler code.  I agree.

An ad hoc survey of clients...

    4.3BSD's named built the reply in the obvious (CNAME, A) order, and
    its client expected the same.

    glibc and dietlibc both expect (CNAME, A).

    uclibc stops on seeing the CNAME, sending another request!  But it
    means it happens to `work' with (A, CNAME).

    Finally Go came along in 2008, probably influenced by Plan 9's
    implementation, though I haven't checked that.  It alters what it
    wants on seeing the CNAME, and restarts parsing the whole packet.

So an (A foo?) query greeted with an (A bar=1, CNAME foo=bar, A bar=2)
reply would have 4.3BSD, glibc, and dietlibc think foo was 2, uclibc
would see 1 and 2 in the next reply, and Go sees 1 and 2 now.

This issue arose with a server that was replying (CNAME foo=bar, A
bar=1), but randomising the order for `round robin'.  This meant `ping
foo' failed to look up the host 50% of the time.

It seems clear to me that the decades of DNS clients, many of which are
still in service, but will never be altered, depend on (CNAME, A).
Better rules to new DNS-server writers are needed, unless someone can
point out what I've missed.  There are still unanswered questions, e.g.
is all CNAME before A sufficient.  I'd expect the answer should be
whatever that early BIND generated is now what's demanded, i.e. no, it
must be (CNAME foo=bar1, A bar=1, CNAME xyzzy=bar2, A bar2=2).

I'm new to this list, and how these things work.  What's next?

-- 
Cheers, Ralph.
https://plus.google.com/+RalphCorderoy    LinkedIn: http://goo.gl/tBVpUF

-- 
Mark Andrews, ISC
1 Seymour St., Dundas Valley, NSW 2117, Australia
PHONE: +61 2 9871 4742                 INTERNET: marka(_at_)isc(_dot_)org