我正在使用C语言进行DNS查询实现,并且有兴趣在单个查询数据包中请求A和AAAA(IPv4和IPv6)记录,但是当我放入两个时,我没有从名称服务器获得任何响应像这样在一个数据包中一起查询。我已经尝试将查询发送到几个不同的名称服务器(本地和8.8.8.8)没有运气。这是不起作用的,还是我的查询包可能格式错误?
我将AAAA查询附加到现有A请求数据包的基本算法是增加数据包标头中的QDCOUNT字段,然后将TYPE设置为AAAA和NAME的RR查询附加为指向主机名的指针。现有的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
我认为没有任何问题。
答案 0 :(得分:31)
我不知道在单个查询中支持多个问题的任何名称服务器。
在这样的查询中可能存在歧义,因为每个数据包标志(例如AA)只能应用于其中一个问题。如果您提出两个问题并且服务器仅对其中一个域具有权威性,那么服务器是否应该设置标志?我怀疑这些问题阻碍了实施者。
有很多建议可以解决您所讨论的问题(例如this提议引入结合A和AAAA的QTYPE,以及Paul Vixie的repeated {{3}引入EDNS形式的多个问题),但目前支持IPv4和6的程序倾向于执行两个单独的查询,AAAA跟随(超时后)或同时执行。
我认为还有“全部”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);
}
答案 1 :(得分:14)
虽然数据包格式技术上支持在问题部分中有多个记录(参见RFC 1035的§4.1.2),但在实践中它只是不起作用,因为你已经找到了。
特别是没有人设法定义正确的语义,如果这两个问题导致两个不同的RCODE,该怎么做。
我tried to define those semantics at the IETF但到目前为止还没有走得太远。
在我自己的DNS数据包解析代码中,我总是拒绝任何此类数据包。
答案 2 :(得分:-3)
A
和AAAA
查询可以在一个数据包中进行编译,因此我的猜测是您的数据包在某种程度上仍然存在格式错误,特别是考虑到查询不会对其他数据使用偏移量。如果您能显示实际代码,或者至少显示您要发送的原始字节,我会非常有帮助。