我正在尝试从头开始实现自己的 DNS 服务器。但是,我很难理解如何RFC 1035建议执行截断。
第 6.2 节说:
当响应太长而需要截断时,截断应从响应末尾开始,并在数据报中向前进行。因此,如果授权部分有任何数据,则保证答案部分是唯一的。
我真的不明白这是什么意思。我猜“转发”是指远离标题。但这与授权部分有什么关系?它说的是“响应结束”,我猜是指答案部分的结束?如果整个答案部分不适合消息怎么办?
有人可以更好地解释这个算法吗?
仅当 RRSet 是响应的一部分,但无法全部包含时,才应在响应中设置 TC 位。不应仅仅因为可以包含一些额外信息,但空间不足而设置 TC 位。这包括额外部分处理的结果。在这种情况下,应省略响应中放不下的整个 RRSet,并按原样发送答复,同时清除 TC 位。如果答复的接收者需要省略的数据,它可以构造对该数据的查询并单独发送。
如果设置了 TC,则响应中可能会留下无法完全容纳的部分 RRSet。当 DNS 客户端收到设置了 TC 的回复时,它应该忽略该响应,然后使用允许更大回复的机制(例如 TCP 连接)再次查询。
答案1
总结
如果TC
设置了,答案中的记录选择(如果有)实际上并不重要,因为客户端无论如何都应该丢弃消息并通过 TCP 重试。
首先,我只想说,如果这个实现是为了学习目的,那么这当然是深入了解的好方法。我建议你好 DNS作为补充阅读。
如果用于生产用途,我强烈建议考虑使用一些现有的 DNS 实现作为解决方案的框架,以帮助提供正确的行为;有很多事情要做当您开始研究现代 DNS 服务器的期望时。
关于您对 RFC1035 中关于截断的非常简短的说明的问题(请注意这份文件的年代,它在语言清晰度方面确实站不住脚),我还发现他们对 TC 的解释措辞相当奇怪。
但是,我确实相信那里所暗示的本质上是 DNS 消息中各部分的顺序与数据的“重要性”相一致。
常规查询/响应消息包含以下部分(来自第4.1节):
+---------------------+
| Header |
+---------------------+
| Question | the question for the name server
+---------------------+
| Answer | RRs answering the question
+---------------------+
| Authority | RRs pointing toward an authority
+---------------------+
| Additional | RRs holding additional information
+---------------------+
我认为他们所说的本质上只是你应该从末尾开始删除内容(最好从附加部分删除内容,然后是权威部分……)。这种方法会让他们注意到我认为应该说的是,如果权威部分等中有内容,你就知道答案部分是完整的。
尽管如此,我确实认为 RFC2181 中的相关部分更有帮助(并且更清晰,这正是 RFC2181 的目的)。
如那里所述(释义):
如果您考虑将任何可选数据(除了严格要求回答问题的最低限度数据之外的数据,即通常与问题匹配的完整 RRSet)添加到响应中,那么可以简单地删除该可选数据而无需设置TC
。
如果您必须删除对答案至关重要的内容TC
,则必须设置,如果TC
设置了,客户端必须丢弃响应并通过 TCP 重试(这在很大程度上使 RFC1035 中有些复杂的推理与行为良好的客户端无关,他们不会将截断的答案用于任何事情)。