C语言 在单个DNS查询中请求A和AAAA记录

rdlzhqv9  于 2022-12-02  发布在  其他
关注(0)|答案(4)|浏览(412)

我正在用C语言编写一个DNS查询实现,并对在一个查询包中同时请求A和AAAA(IPv4和IPv6)记录感兴趣,但是当我把这两个查询放在一个包中时,我没有从名称服务器得到任何响应,就像这样。我试着把查询发送到几个不同的名称服务器(本地和8.8.8.8),都没有成功。这是不是不起作用?还是我的查询数据包可能格式不正确?
我附加AAAA查询(到一个现有的A请求包)的基本算法是增加包头中的QDCOUNT字段,然后附加一个RR查询,TYPE设置为AAAA,NAME作为一个指针指向现有A查询中的主机名(字节0xC 0 0x 0 C,从包的开头偏移12个字节)。
仅供参考,数据包中只有A查询时一切都正常。

**编辑:**显然我的查询都有轻微的格式错误(我不知道查询不像回答没有TTL和RDLENGTH/RDATA字段)。在修复这个问题后,我得到了RCODE=1格式错误的回复,它确认了2个查询的存在。这是否意味着每个数据包不支持多个查询?
**编辑2:**以下是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
我看不出有什么问题。

fdbelqdn

fdbelqdn1#

我不知道任何名称服务器支持在一个查询中的多个问题。
在这样的查询中存在潜在的歧义,因为每个数据包的标志(如AA)可能只适用于其中一个问题。如果你问了两个问题,而服务器只对其中一个域具有权威性,那么服务器是否应该设置标志?我怀疑诸如此类的问题已经阻止了实现者。
已经有很多建议来解决你所说的问题(例如this提议引入组合A和AAAA的QTYPE,以及Paul Vixie的repeatedattempts提议引入多个问题的EDNS形式),但是目前支持IPv4和6两者的程序倾向于执行两个单独的查询,或者AAAA跟随(超时后)由A执行,或同时执行两者。
我想还有“all”QTYPE,但是它可以返回比您需要的更多的数据。

**编辑:**来自BIND源代码中的query.c:

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;
   }

**编辑:**另外,从BIND源代码中得resolver. c:

/*
     * XXXRTH  Currently we support only one question.
     */
    if (message->counts[DNS_SECTION_QUESTION] != 1) {
            log_formerr(fctx, "too many questions");
            return (DNS_R_FORMERR);
    }
klsxnrf1

klsxnrf12#

虽然数据包格式 * 技术上 * 支持在问题部分有多个记录(参见RFC 1035的§4.1.2),但实际上它并不起作用,正如你所发现的。
特别是,如果两个问题导致两个不同的RCODE,没有人能够定义正确的语义。
我有tried to define those semantics at the IETF,但到目前为止还没有走得很远。
在我自己的DNS数据包解析代码中,我总是拒绝任何这样的数据包。

ldioqlga

ldioqlga3#

我也尝试了同样的方法,但结果略有不同。当我在一封电报中发送两个查询(A和AAAA)时,我没有从本地DNS(dnsmasq)得到任何响应,但当我在谷歌的www.example.com服务器上测试同样的方法时8.8.8.8,我得到了响应。谷歌NS返回的响应只有一个查询和一个响应,它只是忽略了第二个条目。
请求:

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]

回应:

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]
bkkx9g8r

bkkx9g8r4#

AAAAA查询可以组合在一个数据包中,所以我猜测您的数据包在某些方面仍然存在格式错误,特别是考虑到查询不使用彼此数据的偏移量。如果您能显示实际代码,或者至少显示您发送的原始字节,我将非常有帮助。

相关问题