From 20bf57c117f3b5317474e2d3e6dcb22b4a029997 Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Tue, 10 Feb 2026 12:41:35 +0800 Subject: [PATCH] feat: add `disable-reuse` params for DoT --- dns/dot.go | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/dns/dot.go b/dns/dot.go index a4ffe461..fa37d86a 100644 --- a/dns/dot.go +++ b/dns/dot.go @@ -23,6 +23,7 @@ type dnsOverTLS struct { host string dialer *dnsDialer skipCertVerify bool + disableReuse bool access sync.Mutex connections deque.Deque[net.Conn] // LIFO @@ -57,11 +58,13 @@ func (t *dnsOverTLS) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, err var conn net.Conn isOldConn := true - t.access.Lock() - if t.connections.Len() > 0 { - conn = t.connections.PopBack() + if !t.disableReuse { + t.access.Lock() + if t.connections.Len() > 0 { + conn = t.connections.PopBack() + } + t.access.Unlock() } - t.access.Unlock() if conn == nil { conn, err = t.dialContext(ctx) @@ -90,13 +93,17 @@ func (t *dnsOverTLS) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, err return } - t.access.Lock() - if t.connections.Len() >= maxOldDotConns { - oldConn := t.connections.PopFront() - go oldConn.Close() // close in a new goroutine, not blocking the current task + if !t.disableReuse { + t.access.Lock() + if t.connections.Len() >= maxOldDotConns { + oldConn := t.connections.PopFront() + go oldConn.Close() // close in a new goroutine, not blocking the current task + } + t.connections.PushBack(conn) + t.access.Unlock() + } else { + _ = conn.Close() } - t.connections.PushBack(conn) - t.access.Unlock() return } }() @@ -134,12 +141,14 @@ func (t *dnsOverTLS) dialContext(ctx context.Context) (net.Conn, error) { } func (t *dnsOverTLS) ResetConnection() { - t.access.Lock() - for t.connections.Len() > 0 { - oldConn := t.connections.PopFront() - go oldConn.Close() // close in a new goroutine, not blocking the current task + if !t.disableReuse { + t.access.Lock() + for t.connections.Len() > 0 { + oldConn := t.connections.PopFront() + go oldConn.Close() // close in a new goroutine, not blocking the current task + } + t.access.Unlock() } - t.access.Unlock() } func (t *dnsOverTLS) Close() error { @@ -159,6 +168,9 @@ func newDoTClient(addr string, resolver *Resolver, params map[string]string, pro if params["skip-cert-verify"] == "true" { c.skipCertVerify = true } + if params["disable-reuse"] == "true" { + c.disableReuse = true + } runtime.SetFinalizer(c, (*dnsOverTLS).Close) return c }