|
|
|
@ -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 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").Base(err).AtError().WriteToLog() |
|
|
|
|
newError("failed to read response length").Base(err).AtError().WriteToLog() |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|