【问题标题】:Requesting A and AAAA records in single DNS query在单个 DNS 查询中请求 A 和 AAAA 记录
【发布时间】:2011-05-04 04:23:41
【问题描述】:

我正在使用 C 语言实现 DNS 查询,并且有兴趣在单个查询数据包中同时请求 A 和 AAAA(IPv4 和 IPv6)记录,但是当我将这两个数据包放入时,我没有收到来自名称服务器的任何响应像这样在一个数据包中一起查询。我尝试将查询发送到几个不同的名称服务器(本地和 8.8.8.8),但没有成功。这是不起作用的东西,还是我的查询数据包格式错误?

我附加 AAAA 查询(到现有的 A 请求数据包)的基本算法是增加数据包头中的 QDCOUNT 字段,然后附加一个 RR 查询,其中 TYPE 设置为 AAAA 和 NAME 作为指向主机名的指针现有 A 查询(字节 0xC0 0x0C 表示距数据包开头 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

我看不出有什么问题。

【问题讨论】:

  • Wireshark 也没有,这通常是您正确阅读规范的好兆头。

标签: c sockets networking dns network-protocols


【解决方案1】:

我不知道有任何名称服务器支持单个查询中的多个问题。

此类查询可能存在歧义,因为每个数据包的标志(例如 AA)仅适用于其中一个问题。如果您问两个问题并且服务器仅对其中一个域具有权威性,那么服务器是否应该设置标志?我怀疑诸如此类的问题让实施者望而却步。

已经有很多建议可以解决你所说的问题(比如this建议引入结合A和AAAA的QTYPE,以及Paul Vixie的repeatedattempts引入EDNS表单多个问题),但目前同时支持 IPv4 和 6 的程序倾向于执行两个单独的查询,要么 AAAA 后跟(超时后)A,要么同时进行。

我想还有“全部”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);
    }

【讨论】:

  • 我认为“全部”QTYPE 没有用,因为它不会像 A 或 AAAA 查询那样解析 CNAME。
  • 也是正确的 - 更多地提到它是为了完整性而不是建议你实际使用它:)
  • 已更新您的 FORMERR 的来源。
  • 总之,他可能意味着任何。不管有多少服务器,尤其是 cloudflare 都支持这个。
  • @Nick ANY 的另一个问题是,当存根解析器向递归服务器发送 ANY 查询时,服务器只需要响应当时缓存中的内容(尽管如果缓存中没有任何内容,它将向上游发送查询)。如果A 在缓存中,但AAAA 不在,你只会得到A
【解决方案2】:

虽然数据包格式技术上支持在问题部分包含多个记录(请参阅RFC 1035 的第 4.1.2 节),但实际上它只是行不通,因为您已经找到了。

尤其是没有人能够为如果这两个问题导致两个不同的 RCODE 时该怎么做定义正确的语义。

我有tried to define those semantics at the IETF,但到目前为止还没有很远。

在我自己的 DNS 数据包解析代码中,我总是拒绝任何此类数据包。

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 同一个查询包中的2个问题(QDCOUNT=2)应该可以共享数据吧?当然2个答案可以。我将发布我正在发送的字节的转储。
    • 我以前不知道这个功能,但是指针和偏移量的使用在 RFC 1035 第 4.1.4 节中定义了一般适用于所有消息类型。
    • 确实,答案可以而且通常会在问题中使用偏移量。
    • @R.. 问题不是问题——而是如何放置多个结果的语义如果 rcode 不同 没有定义。见tools.ietf.org/html/draft-bellis-dnsext-multi-qtypes-01
    猜你喜欢
    • 2013-03-14
    • 1970-01-01
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-20
    • 2018-09-05
    • 1970-01-01
    相关资源
    最近更新 更多