perf(doq): implement connection pooling for improved performance

Implement QUIC connection pooling for DoQ resolver to match DoH3
performance. Previously, DoQ created a new QUIC connection for every
DNS query, incurring significant handshake overhead. Now connections are
reused across queries, eliminating this overhead for subsequent requests.

The implementation follows the same pattern as DoH3, using parallel dialing
and connection pooling to achieve comparable performance characteristics.
This commit is contained in:
Cuong Manh Le
2026-01-06 14:46:00 +07:00
committed by Cuong Manh Le
parent 8d63a755ba
commit e8d1a4604e
3 changed files with 286 additions and 30 deletions
+25
View File
@@ -91,6 +91,27 @@ func (uc *UpstreamConfig) doh3Transport(dnsType uint16) http.RoundTripper {
return uc.http3RoundTripper
}
func (uc *UpstreamConfig) doqTransport(dnsType uint16) *doqConnPool {
uc.transportOnce.Do(func() {
uc.SetupTransport()
})
if uc.rebootstrap.CompareAndSwap(true, false) {
uc.SetupTransport()
}
switch uc.IPStack {
case IpStackBoth, IpStackV4, IpStackV6:
return uc.doqConnPool
case IpStackSplit:
switch dnsType {
case dns.TypeA:
return uc.doqConnPool4
default:
return uc.doqConnPool6
}
}
return uc.doqConnPool
}
// Putting the code for quic parallel dialer here:
//
// - quic dialer is different with net.Dialer
@@ -158,3 +179,7 @@ func (d *quicParallelDialer) Dial(ctx context.Context, addrs []string, tlsCfg *t
return nil, errors.Join(errs...)
}
func (uc *UpstreamConfig) newDOQConnPool(addrs []string) *doqConnPool {
return newDOQConnPool(uc, addrs)
}