在单个DNS查询中请求A和AAAA记录 [英] Requesting A and AAAA records in single DNS query

查看:2632
本文介绍了在单个DNS查询中请求A和AAAA记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用C进行DNS查询实现,并且有兴趣在单个查询数据包中同时请求A和AAAA(IPv4和IPv6)记录,但是当我将两者放置时,我没有从名称服务器得到任何响应像这样在一个数据包中一起查询.我尝试将查询发送到几个不同的域名服务器(本地和8.8.8.8),但没有运气.这是行不通的,还是我的查询数据包格式错误?

我将AAAA查询(附加到现有A请求数据包)的基本算法是增加数据包头中的QDCOUNT字段,然后将RR查询的TYPE设置为AAAA,并将NAME设置为指向主机名的指针.现有的查询(字节0xC0 0x0C,距数据包开头的偏移量为12个字节).这听起来正确吗?

仅供参考,仅使用数据包中的A查询,一切正常.

编辑:显然,我的查询都略有不正确(我不知道与答案不同的查询没有TTL和RDLENGTH/RDATA字段).解决此问题后,我得到了RCODE = 1格式错误答复,该答复确认了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

我没有发现任何问题.

解决方案

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

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

有很多建议可以解决您正在讨论的问题(例如建议,以引入结合了A和AAAA的QTYPE,以及Paul Vixie的尝试引入一个包含多个问题的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);
    }

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.

解决方案

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

这篇关于在单个DNS查询中请求A和AAAA记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆