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

我已经尝试了我能想到的一切,但我正在碰壁。我想知道是否有人能够指出我正确的方向或可能发现问题?

由于几个原因,我正在尝试编写自己的 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 时的数据有很大不同。


吃鸡游戏
浏览 104回答 1
1回答

qq_笑_17

但是,如果我将 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 消息。为此检查长度前缀。
打开App,查看更多内容
随时随地看视频慕课网APP