diff --git a/app/dns/nameserver_quic.go b/app/dns/nameserver_quic.go index 9e702564..89bb4aaa 100644 --- a/app/dns/nameserver_quic.go +++ b/app/dns/nameserver_quic.go @@ -1,7 +1,9 @@ package dns import ( + "bytes" "context" + "encoding/binary" "net/url" "sync" "sync/atomic" @@ -24,7 +26,7 @@ import ( // NextProtoDQ - During connection establishment, DNS/QUIC support is indicated // by selecting the ALPN token "dq" in the crypto handshake. -const NextProtoDQ = "doq-i00" +const NextProtoDQ = "doq" const handshakeTimeout = time.Second * 8 @@ -194,13 +196,18 @@ func (s *QUICNameServer) sendQuery(ctx context.Context, domain string, clientIP return } + dnsReqBuf := buf.New() + binary.Write(dnsReqBuf, binary.BigEndian, uint16(b.Len())) + dnsReqBuf.Write(b.Bytes()) + b.Release() + conn, err := s.openStream(dnsCtx) if err != nil { newError("failed to open quic connection").Base(err).AtError().WriteToLog() return } - _, err = conn.Write(b.Bytes()) + _, err = conn.Write(dnsReqBuf.Bytes()) if err != nil { newError("failed to send query").Base(err).AtError().WriteToLog() return @@ -210,9 +217,21 @@ func (s *QUICNameServer) sendQuery(ctx context.Context, domain string, clientIP respBuf := buf.New() defer respBuf.Release() - n, err := respBuf.ReadFrom(conn) + n, err := respBuf.ReadFullFrom(conn, 2) if err != nil && n == 0 { - newError("failed to read response").Base(err).AtError().WriteToLog() + newError("failed to read response length").Base(err).AtError().WriteToLog() + return + } + var length int16 + err = binary.Read(bytes.NewReader(respBuf.Bytes()), binary.BigEndian, &length) + if err != nil { + newError("failed to parse response length").Base(err).AtError().WriteToLog() + return + } + respBuf.Clear() + n, err = respBuf.ReadFullFrom(conn, int32(length)) + if err != nil && n == 0 { + newError("failed to read response length").Base(err).AtError().WriteToLog() return }