```
feat(core): 改进 DNS 响应构造逻辑以支持扩展错误码和诊断信息 在 writeReply 函数中,增强对上游 EDNS 选项的处理: - 继承上游的扩展 RCODE 与 EDNS 版本号 - 可选透传 EDE(Extended DNS Errors)记录,保留更多诊断信息 - 明确设置 UDPSize、DO 位及 EDNS 版本转换逻辑 这有助于提升调试能力与协议兼容性,同时保持客户端请求的一致性。 ```
This commit is contained in:
31
main.go
31
main.go
@@ -392,20 +392,22 @@ func getDOFlag(m *dns.Msg) bool {
|
||||
* 响应构造:使用客户端请求头构造 reply,复制上游内容
|
||||
******************************************************************/
|
||||
|
||||
// writeReply 根据客户端请求构造响应骨架:复制上游的 Answer/Ns/(非伪)Extra,
|
||||
// 并按照**客户端请求**重建 OPT(UDPSize/DO),避免直接采纳上游的 OPT/TSIG。
|
||||
// writeReply 根据客户端请求构造响应:复制上游 Answer/Ns/非伪 Extra,
|
||||
// 并按客户端请求重建 OPT(UDPSize/DO),同时继承上游的扩展 RCODE 与 EDNS 版本;
|
||||
// 可选透传上游的 EDE(Extended DNS Errors)以保留诊断信息。
|
||||
func writeReply(w dns.ResponseWriter, req, upstream *dns.Msg) {
|
||||
if upstream == nil {
|
||||
dns.HandleFailed(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
out := new(dns.Msg)
|
||||
out.SetReply(req)
|
||||
out.Authoritative = false
|
||||
out.RecursionAvailable = upstream.RecursionAvailable
|
||||
out.AuthenticatedData = upstream.AuthenticatedData
|
||||
out.CheckingDisabled = req.CheckingDisabled // 反映客户端 CD 位
|
||||
out.Rcode = upstream.Rcode
|
||||
out.Rcode = upstream.Rcode // 主 RCODE(低 4 位)
|
||||
out.Answer = upstream.Answer
|
||||
out.Ns = upstream.Ns
|
||||
|
||||
@@ -417,20 +419,39 @@ func writeReply(w dns.ResponseWriter, req, upstream *dns.Msg) {
|
||||
}
|
||||
extras = append(extras, rr)
|
||||
}
|
||||
// 基于客户端请求镜像 EDNS(UDPSize + DO),保持传输一致性
|
||||
|
||||
// 基于客户端请求镜像 EDNS(UDPSize + DO)
|
||||
if ro := req.IsEdns0(); ro != nil {
|
||||
o := new(dns.OPT)
|
||||
o.Hdr.Name = "."
|
||||
o.Hdr.Rrtype = dns.TypeOPT
|
||||
|
||||
// 与客户端保持一致的 UDPSize / DO 位
|
||||
o.SetUDPSize(ro.UDPSize())
|
||||
if ro.Do() {
|
||||
o.SetDo()
|
||||
}
|
||||
// 如需转发 NSID/COOKIE 等可在此附加;为减少复杂性与缓存污染,建议保守最小集合
|
||||
|
||||
// 继承上游的扩展 RCODE 与 EDNS 版本(注意不同版本签名差异,这里显式转换)
|
||||
if uo := upstream.IsEdns0(); uo != nil {
|
||||
// 你当前库期望 uint16,这里强转;若你的库期望 uint8,也可改成 uint8(...)
|
||||
o.SetExtendedRcode(uint16(uo.ExtendedRcode()))
|
||||
o.SetVersion(uint8(uo.Version()))
|
||||
|
||||
// 可选:透传只读的 EDE 诊断信息
|
||||
for _, opt := range uo.Option {
|
||||
if ede, ok := opt.(*dns.EDNS0_EDE); ok {
|
||||
o.Option = append(o.Option, ede)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extras = append(extras, o)
|
||||
}
|
||||
|
||||
out.Extra = extras
|
||||
out.Compress = true
|
||||
|
||||
if err := w.WriteMsg(out); err != nil {
|
||||
log.Printf("[write] WriteMsg error: %v", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user