fix(doh): use per-connection local address for PROXY protocol (#8005)

This commit is contained in:
Cedric Wang
2026-04-04 11:32:10 -07:00
committed by GitHub
parent 2263340fab
commit 03d0863a45
2 changed files with 119 additions and 1 deletions

View File

@@ -51,6 +51,9 @@ func (l *loggerAdapter) Write(p []byte) (n int, err error) {
// Plugins can access the original HTTP request to retrieve headers, client IP, and metadata.
type HTTPRequestKey struct{}
// connAddrKey is the context key for the per-connection local address set by ConnContext.
type connAddrKey struct{}
// NewServerHTTPS returns a new CoreDNS HTTPS server and compiles all plugins in to it.
func NewServerHTTPS(addr string, group []*Config) (*ServerHTTPS, error) {
s, err := NewServer(addr, group)
@@ -89,6 +92,9 @@ func NewServerHTTPS(addr string, group []*Config) (*ServerHTTPS, error) {
WriteTimeout: s.WriteTimeout,
IdleTimeout: s.IdleTimeout,
ErrorLog: stdlog.New(&loggerAdapter{}, "", 0),
ConnContext: func(ctx context.Context, c net.Conn) context.Context {
return context.WithValue(ctx, connAddrKey{}, c.LocalAddr())
},
}
maxConnections := DefaultHTTPSMaxConnections
if len(group) > 0 && group[0] != nil && group[0].MaxHTTPSConnections != nil {
@@ -169,6 +175,14 @@ func (s *ServerHTTPS) Stop() error {
return nil
}
// localAddr returns the per-connection local address from context, or s.listenAddr as fallback.
func (s *ServerHTTPS) localAddr(r *http.Request) net.Addr {
if addr, ok := r.Context().Value(connAddrKey{}).(net.Addr); ok {
return addr
}
return s.listenAddr
}
// ServeHTTP is the handler that gets the HTTP request and converts to the dns format, calls the plugin
// chain, converts it back and write it to the client.
func (s *ServerHTTPS) ServeHTTP(w http.ResponseWriter, r *http.Request) {
@@ -189,7 +203,7 @@ func (s *ServerHTTPS) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h, p, _ := net.SplitHostPort(r.RemoteAddr)
port, _ := strconv.Atoi(p)
dw := &DoHWriter{
laddr: s.listenAddr,
laddr: s.localAddr(r),
raddr: &net.TCPAddr{IP: net.ParseIP(h), Port: port},
request: r,
}