* feat: change ALPN of DNS over QUIC

* Fix: length of DNS over QUIC (#1888)

---------

Co-authored-by: 秋のかえで <autmaple@protonmail.com>
This commit is contained in:
yuhan6665 2024-02-28 21:35:35 -05:00 committed by GitHub
parent c83c0bb21d
commit aa101d9dc2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

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