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 aacba92698
commit e4e655414c
3 changed files with 286 additions and 31 deletions
+25
View File
@@ -92,6 +92,27 @@ func (uc *UpstreamConfig) doh3Transport(ctx context.Context, dnsType uint16) htt
return uc.http3RoundTripper
}
func (uc *UpstreamConfig) doqTransport(ctx context.Context, dnsType uint16) *doqConnPool {
uc.transportOnce.Do(func() {
uc.SetupTransport(ctx)
})
if uc.rebootstrap.CompareAndSwap(true, false) {
uc.SetupTransport(ctx)
}
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
@@ -159,3 +180,7 @@ func (d *quicParallelDialer) Dial(ctx context.Context, addrs []string, tlsCfg *t
return nil, errors.Join(errs...)
}
func (uc *UpstreamConfig) newDOQConnPool(ctx context.Context, addrs []string) *doqConnPool {
return newDOQConnPool(ctx, uc, addrs)
}