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

@@ -17,7 +17,7 @@ import (
type hostEntry struct {
hostname string // the hostname to resolve (e.g., "rbldnsd.rbldnsd.svc.cluster.local")
port string // port (e.g., "53", "443", "853")
transport string // "dns", "tls", or "https"
transport string // "dns", "tls", "quic", or "https"
zone string // TLS server name zone (from %zone syntax)
}
@@ -67,8 +67,8 @@ func parseAsHostEntry(h string) (hostEntry, bool) {
cleanH, zone := splitZone(h)
trans, host := parse.Transport(cleanH)
// Only dns, tls, and https transports are supported for hostname resolution
if trans != transport.DNS && trans != transport.TLS && trans != transport.HTTPS {
// Only forward-supported transports are accepted for hostname resolution.
if trans != transport.DNS && trans != transport.TLS && trans != transport.QUIC && trans != transport.HTTPS {
return hostEntry{}, false
}
@@ -77,6 +77,8 @@ func parseAsHostEntry(h string) (hostEntry, bool) {
switch trans {
case transport.TLS:
port = transport.TLSPort
case transport.QUIC:
port = transport.QUICPort
case transport.HTTPS:
port = transport.HTTPSPort
}
@@ -126,8 +128,7 @@ func expandAndDedup(entries []toEntry, resolvers []string) ([]string, error) {
}
for _, addr := range addrs {
// Normalize the address for dedup comparison
key := normalizeAddr(addr)
key := dedupKey(addr)
if !seen[key] {
seen[key] = true
result = append(result, addr)
@@ -137,8 +138,16 @@ func expandAndDedup(entries []toEntry, resolvers []string) ([]string, error) {
return result, nil
}
// normalizeAddr extracts the canonical IP:port from an address string
// (stripping transport prefix and zone) for deduplication.
// dedupKey identifies an upstream endpoint without collapsing distinct
// transports or TLS server names that happen to use the same IP and port.
func dedupKey(addr string) string {
host, zone := splitZone(addr)
trans, endpoint := parse.Transport(host)
return trans + "\x00" + endpoint + "\x00" + strings.ToLower(zone)
}
// normalizeAddr extracts the IP:port from an address string, stripping its
// transport prefix and TLS server name.
func normalizeAddr(addr string) string {
host, _ := splitZone(addr)
_, h := parse.Transport(host)
@@ -164,7 +173,7 @@ func formatResolvedAddr(ip, port, trans, zone string) string {
isIPv6 := strings.Contains(ip, ":")
switch trans {
case transport.TLS, transport.HTTPS:
case transport.TLS, transport.QUIC, transport.HTTPS:
if zone != "" {
if isIPv6 {
return trans + "://[" + ip + "%" + zone + "]:" + port