41

I'm working on a DNS query implementation in C and interested in requesting both A and AAAA (IPv4 and IPv6) records in a single query packet, but I'm not getting any responses from the nameserver when I put the two queries together in one packet like this. I've tried sending the query to several different nameservers (both local and 8.8.8.8) with no luck. Is this something that does not work, or is it likely that my query packet is malformed?

My basic algorithm for appending the AAAA query (to an existing A request packet) is to increase the QDCOUNT field in the packet header, then append an RR query with TYPE set to AAAA and NAME as a pointer to the hostname in the existing A query (bytes 0xC0 0x0C for an offset of 12 bytes from the beginning of the packet). Does this sound correct?

FYI, everything works fine with just the A query in the packet.

Edit: Apparently my queries were all slightly malformed (I was not aware that queries unlike answers do not have TTL and RDLENGTH/RDATA fields). Upon fixing this, I'm getting back RCODE=1 format error replies which acknowledge the presence of the 2 queries. Does this mean multiple queries per packet are just not supported?

Edit 2: Here's a hexdump of a lookup for www.google.com:

d8 32 01 00 00 02 00 00 00 00 00 00 03 77 77 77 06 67 6f 6f 67 6c 65 03 63 6f 6d 00 00 01 00 01 c0 0c 00 1c 00 01

I don't see anything wrong with it.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711

4 Answers4

49

I'm not aware of any nameservers that support multiple questions in a single query.

There's potential for ambiguity in such a query, since there are per-packet flags (such as AA) which could apply to only one of the questions. If you ask two questions and the server is authoritative for only one of the domains, should the server set the flag or not? I suspect issues such as these have deterred implementors.

There have been a number of proposals to solve the problem you're talking about (such as this proposal to introduce a QTYPE that combines A and AAAA, and Paul Vixie's repeated attempts to introduce an EDNS form of multiple questions), but at present programs supporting both IPv4 and 6 tend to perform two separate queries, either AAAA followed (after a timeout) by A, or both simultaneously.

I suppose there's also the "all" QTYPE, but it can return a lot more data than you need.

Edit: from query.c in the BIND source:

   dns_message_currentname(message, DNS_SECTION_QUESTION,
         &client->query.qname);
   client->query.origqname = client->query.qname;
   result = dns_message_nextname(message, DNS_SECTION_QUESTION);
   if (result != ISC_R_NOMORE) {
     if (result == ISC_R_SUCCESS) {
       /*
        * There's more than one QNAME in the question
        * section.
        */
       query_error(client, DNS_R_FORMERR, __LINE__);
     } else
       query_error(client, result, __LINE__);
     return;
   }

Edit: also, from resolver.c in the BIND source:

    /*
     * XXXRTH  Currently we support only one question.
     */
    if (message->counts[DNS_SECTION_QUESTION] != 1) {
            log_formerr(fctx, "too many questions");
            return (DNS_R_FORMERR);
    }
Community
  • 1
  • 1
SimonJ
  • 21,076
  • 1
  • 35
  • 50
  • I don't think the "all" QTYPE is useful because it won't resolve CNAMEs like A or AAAA queries would. – R.. GitHub STOP HELPING ICE Nov 03 '10 at 06:51
  • Also true - mentioned it more for completeness rather than to suggest you actually *use* it :) – SimonJ Nov 03 '10 at 08:00
  • Updated with source of your FORMERR. – SimonJ Nov 03 '10 at 08:24
  • with all, he probably means any. however many servers, most notably cloudflare regect this one. – Nick Nov 01 '16 at 06:06
  • 5
    @Nick the other issue with `ANY` is that when a stub resolvers sends an `ANY` query to a recursive server, the server only has to respond with what's in its cache at that time (although it will send the query upstream if there's nothing in the cache). If the `A` is in the cache, but the `AAAA` isn't, you only get the `A`. – Alnitak Oct 13 '17 at 22:01
22

Whilst the packet format technically supports having more than one record in the question section (see §4.1.2 of RFC 1035), in practise it just doesn't work, as you've found.

In particular no-one has ever managed to define correct semantics for what to do if the two questions were to result in two different RCODEs.

I've tried to define those semantics at the IETF but as yet that hasn't got very far.

In my own DNS packet parsing code I always reject any such packet.

Community
  • 1
  • 1
Alnitak
  • 334,560
  • 70
  • 407
  • 495
0

I tried the same, with slightly different results. When sending two queries in one telegram (A and AAAA) I don't get any response from my local DNS (dnsmasq), but when testing the same with Google's 8.8.8.8 server I get a response. The Google NS sends back a response with just one query and one response, it simply ignores the second entry.

Request:

Frame 5: 78 bytes on wire (624 bits), 78 bytes captured (624 bits) on interface any, id 0
Linux cooked capture v1
Internet Protocol Version 4, Src: 192.168.0.94, Dst: 8.8.8.8
User Datagram Protocol, Src Port: 48440, Dst Port: 53
Domain Name System (query)
    Transaction ID: 0x6f23
    Flags: 0x0100 Standard query
    Questions: 2
    Answer RRs: 0
    Authority RRs: 0
    Additional RRs: 0
    Queries
        google.com: type A, class IN
            Name: google.com
            [Name Length: 10]
            [Label Count: 2]
            Type: A (Host Address) (1)
            Class: IN (0x0001)
        google.com: type AAAA, class IN
            Name: google.com
            [Name Length: 10]
            [Label Count: 2]
            Type: AAAA (IPv6 Address) (28)
            Class: IN (0x0001)
    [Response In: 11]

Response:

Frame 11: 88 bytes on wire (704 bits), 88 bytes captured (704 bits) on interface any, id 0
Linux cooked capture v1
Internet Protocol Version 4, Src: 8.8.8.8, Dst: 192.168.0.94
User Datagram Protocol, Src Port: 53, Dst Port: 48440
Domain Name System (response)
    Transaction ID: 0x6f23
    Flags: 0x8180 Standard query response, No error
    Questions: 1
    Answer RRs: 1
    Authority RRs: 0
    Additional RRs: 0
    Queries
        google.com: type A, class IN
            Name: google.com
            [Name Length: 10]
            [Label Count: 2]
            Type: A (Host Address) (1)
            Class: IN (0x0001)
    Answers
        google.com: type A, class IN, addr 142.250.186.142
            Name: google.com
            Type: A (Host Address) (1)
            Class: IN (0x0001)
            Time to live: 300 (5 minutes)
            Data length: 4
            Address: 142.250.186.142
    [Request In: 5]
    [Time: 0.023670110 seconds]
Hans Dampf
  • 356
  • 2
  • 3
-4

A and AAAA queries can be compined in a single packet, so my guess is that your packet is still malformed in some way, especially considering that queries do not use offsets into each others data. I would really help if you could show your actual code, or at least the raw bytes that you are sending.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 2 questions (QDCOUNT=2) in the same query packet should be able share data, right? Certainly 2 answers can. I'll post a dump of the bytes I'm sending. – R.. GitHub STOP HELPING ICE Nov 03 '10 at 05:17
  • I was not aware of this capability before, but the use of pointers and offsets is defined in RFC 1035 Section 4.1.4 generically for all message types. – Remy Lebeau Nov 04 '10 at 00:36
  • 1
    Indeed the answers can, and typically do, use offsets within the question. – caf Nov 08 '10 at 13:37
  • @R.. the problem is not the question - it's that the semantics of how to put multiple results _if the rcode differs_ are not defined. See http://tools.ietf.org/html/draft-bellis-dnsext-multi-qtypes-01 – Alnitak Jun 14 '12 at 11:58