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

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

问题描述

我正在 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 0c 0 0 c

我看不出有什么问题.

解决方案

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

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

已经有很多建议可以解决您所谈论的问题(例如 this 提议引入结合 A 和 AAAA 的 QTYPE,以及 Paul Vixie 的 重复 尝试引入 EDNS 形式的多个问题),但目前支持 IPv4 和 6 的程序倾向于执行两个单独的查询,AAAA 后跟(超时后)A,或两者兼而有之同时.

我想还有所有"QTYPE,但它可以返回比您需要的更多的数据.

来自 BIND 源中的 query.c:

 dns_message_currentname(message, DNS_SECTION_QUESTION,&client->query.qname);客户端->query.origqname = 客户端->query.qname;结果 = dns_message_nextname(message, DNS_SECTION_QUESTION);如果(结果!= ISC_R_NOMORE){如果(结果 == ISC_R_SUCCESS){/** 问题中有不止一个 QNAME* 部分.*/查询错误(客户端,DNS_R_FORMERR,__LINE__);} 别的查询错误(客户端,结果,__LINE__);返回;}

同样来自 BIND 源中的 resolver.c:

/** XXXRTH 目前我们只支持一个问题.*/if (message->counts[DNS_SECTION_QUESTION] != 1) {log_formerr(fctx, 问题太多");返回(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天全站免登陆