问题
用 Net::DNS 测试 nameserver,客户端发 EDNS 查询,服务端的响应包一直不带 EDNS OPT。
rt上的bug单 #115558: Net::DNS::Nameserver does not allow EDNS replies
补丁
bug分析
Nameserver.pm
服务端 tcp_connection / udp_connection 函数先调用 make_reply 生成应答包,再调用 $reply->data 发送给客户端服务端
$self->make_reply 制作应答包
$query->reply() 初始化应答包
Packet.pm : sub reply() 如果收到的是edns查询,则初始化应答包时预设edns size
Packet.pm : sub edns() 取出edns opt对象,bug发生地
如果收到带edns的查询,make_reply初始化时,依次调用
由于 $self->{xedns} 为空,$link指向 $self->{xedns} 的地址
且由于$self->{additional} 为空,$$link 将被置为一个新的空OPT
也就是说,$self->{xedns} 被置为该空OPT
后续如果再次调用 $reply->edns,
$link = $self->{xedns} 一直指向该空OPT的地址,$$link一直为true,后面两行操作不会生效:
$self->edns 总是返回空OPT
$reply->data 发送给客户端
由于 $self->edns 为空OPT,$edns->_specified将一直为0,导致edns OPT不会被unshift到@addl
响应包丢失edns OPT