commit 2f4ad6437420a56d016b5d1ac5eb61c2a7234254 from: Oliver Lowe date: Sat Nov 20 00:19:50 2021 UTC Use the message length field to only read that much Using io.ReadAll doesn't work properly. The socket has a queue that may be entirely drained by this call, which means we could accidentally read a bit of the next message if there is one in the queue. commit - c245affd0ab63714b15dc1e6bd67307059e8da4f commit + 2f4ad6437420a56d016b5d1ac5eb61c2a7234254 blob - 96f445fbb2f41e17da146512daa63c93863a8556 blob + f44e64273879b3325edd87fc38bac547e6fe57b0 --- dns.go +++ dns.go @@ -87,9 +87,18 @@ func dnsStreamExchange(b []byte, conn net.Conn) ([]byt if _, err := conn.Write(m); err != nil { return nil, err } - buf, err := io.ReadAll(conn) + + b = make([]byte, 1280) + if _, err := io.ReadFull(conn, b[:2]); err != nil { + return nil, fmt.Errorf("read length: %w", err) + } + l := int(b[0])<<8 | int(b[1]) + if l > len(b) { + b = make([]byte, l) + } + n, err := io.ReadFull(conn, b[:l]) if err != nil { - return nil, err + return nil, fmt.Errorf("read after length: %w", err) } - return buf[2:], nil + return b[:n], nil }