为了账号安全,请及时绑定邮箱和手机立即绑定

使用 UDP 使用 TCP 传输可以解决 DNS 问题

使用 UDP 使用 TCP 传输可以解决 DNS 问题

Go
吃鸡游戏 2022-12-05 11:20:54
我已经尝试了我能想到的一切,但我正在碰壁。我想知道是否有人能够指出我正确的方向或可能发现问题?由于几个原因,我正在尝试编写自己的 DNS 服务器,主要是学习经验。有几件事要提一下:我正在使用围棋使用“gopacket”进行 DNS 数据包反序列化服务器在使用 UDP 协议时按预期工作因此,在通过 UDP 工作获得响应后,我决定是时候实施 TCP 了。下面是侦听 TCP 传入连接的代码片段。// Listen TCP    c, err := t.Accept()    if err != nil {        log.Println(err)    }    go func(c net.Conn) {        tbuff := make([]byte, 4096)        _, err = c.Read(tbuff)        if err != nil {            fmt.Println(err)        }        clientAddr := addrt        packet := gopacket.NewPacket(tbuff, layers.LayerTypeDNS, gopacket.Default)        dnsPacket := packet.Layer(layers.LayerTypeDNS)        tcp, _ := dnsPacket.(*layers.DNS)        if !limiter(clientAddr.String()) {            c.Close()        }        tbuff = DNSHandle(tcp)        c.Write(tbuff)        c.Close()    }(c)当我通过 TCP 发出 dig 命令时,服务器接受连接并将接收到的字节数据传递给 DNSHandle 函数(与 UDP 处理程序相同)。数据似乎与使用 UDP 时的数据有很大不同。
查看完整描述

1 回答

?
qq_笑_17

TA贡献1818条经验 获得超7个赞

但是,如果我将 tbuff 更改为 [2:]:

来自RFC 1035第 4.2.2 节:

4.2.2. TCP 用法

通过 TCP 连接发送的消息使用服务器端口 53(十进制)。消息以一个两字节长度字段为前缀,它 给出了消息长度,不包括两字节长度字段。该长度字段允许低级处理在开始解析之前组装完整的消息。

因此,通过将 DNS over TCP 视为与 DNS over UDP 相同,你做错了 - 在 TCP 中,DNS 消息以包含消息长度的 2 个字节为前缀。

这是必需的,因为 TCP 是一个字节流,而不是像 UDP 这样的数据报协议。这意味着不能简单地假设c.Read(...). 可能尚未收到完整的消息,但也可能收到了不止一条 DNS 消息。为此检查长度前缀。


查看完整回答
反对 回复 2022-12-05
  • 1 回答
  • 0 关注
  • 103 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信