plugin/forward: support DNS-over-QUIC upstreams (#8474)

Signed-off-by: houyuwushang <liuluoqianqiu@outlook.com>
This commit is contained in:
houyuwushang
2026-09-08 12:51:18 +08:00
committed by GitHub
parent 71a60e140b
commit e1d3fe6bc6
13 changed files with 1679 additions and 40 deletions

View File

@@ -1,7 +1,6 @@
// Package forward implements a forwarding proxy. It caches an upstream net.Conn for some time, so if the same
// client returns the upstream's Conn will be precached. Depending on how you benchmark this looks to be
// 50% faster than just opening a new connection for every client. It works with UDP and TCP and uses
// inband healthchecking.
// Package forward implements a DNS forwarding proxy. It reuses upstream
// connections across DNS, DoT, DoH, and DoQ transports and uses in-band
// health checking.
package forward
import (
@@ -190,7 +189,7 @@ func (f *Forward) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg
for {
ret, localAddr, upstreamProto, err = proxy.Connect(ctx, state, opts)
if err == proxyPkg.ErrCachedClosed { // Remote side closed conn, can only happen with TCP.
if err == proxyPkg.ErrCachedClosed { // The peer closed a cached TCP or QUIC connection before the query was sent.
continue
}
// Retry with TCP if truncated and prefer_udp configured.
@@ -215,6 +214,9 @@ func (f *Forward) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg
if errors.Is(err, proxyPkg.ErrInvalidRequest) {
return dns.RcodeFormatError, err
}
if errors.Is(err, proxyPkg.ErrUnsupportedRequest) {
return dns.RcodeNotImplemented, err
}
// Kick off health check to see if *our* upstream is broken.
if f.maxfails != 0 {