XHTTP & gRPC servers: Get accurate localAddr (#6526)

Fixes https://github.com/XTLS/Xray-core/pull/6476

---------

Co-authored-by: echoowall <echoowall@gmail.com>
This commit is contained in:
风扇滑翔翼
2026-07-27 13:11:25 +00:00
committed by GitHub
co-authored by echoowall
parent 5b1b41058e
commit 4aba687dd3
4 changed files with 23 additions and 1 deletions
@@ -38,12 +38,14 @@ func NewHunkReadWriter(hc HunkConn, cancel context.CancelFunc) *HunkReaderWriter
func NewHunkConn(hc HunkConn, cancel context.CancelFunc, trustedXForwardedFor []string) net.Conn {
rAddr := remoteAddrFromContext(hc.Context(), trustedXForwardedFor)
lAddr := localAddrFromContext(hc.Context())
wrc := NewHunkReadWriter(hc, cancel)
return cnc.NewConnection(
cnc.ConnectionInput(wrc),
cnc.ConnectionOutput(wrc),
cnc.ConnectionOnClose(wrc),
cnc.ConnectionRemoteAddr(rAddr),
cnc.ConnectionLocalAddr(lAddr),
)
}
@@ -33,12 +33,14 @@ func NewMultiHunkReadWriter(hc MultiHunkConn, cancel context.CancelFunc) *MultiH
func NewMultiHunkConn(hc MultiHunkConn, cancel context.CancelFunc, trustedXForwardedFor []string) net.Conn {
rAddr := remoteAddrFromContext(hc.Context(), trustedXForwardedFor)
lAddr := localAddrFromContext(hc.Context())
wrc := NewMultiHunkReadWriter(hc, cancel)
return cnc.NewConnection(
cnc.ConnectionInputMulti(wrc),
cnc.ConnectionOutputMulti(wrc),
cnc.ConnectionOnClose(wrc),
cnc.ConnectionRemoteAddr(rAddr),
cnc.ConnectionLocalAddr(lAddr),
)
}
@@ -56,3 +56,17 @@ func parseTrustedXForwardedFor(md metadata.MD, trusted []string, remoteAddr net.
}
return nil
}
func localAddrFromContext(ctx context.Context) net.Addr {
var localAddr net.Addr
if pr, ok := peer.FromContext(ctx); ok {
localAddr = pr.LocalAddr
}
if localAddr == nil {
localAddr = &net.TCPAddr{
IP: []byte{0, 0, 0, 0},
Port: 0,
}
}
return localAddr
}
+5 -1
View File
@@ -373,11 +373,15 @@ func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Req
Reader: request.Body,
ResponseWriter: writer,
}
localAddr := h.localAddr
if la, ok := request.Context().Value(http.LocalAddrContextKey).(net.Addr); ok && la != nil {
localAddr = la
}
conn := splitConn{
writer: httpSC,
reader: httpSC,
remoteAddr: remoteAddr,
localAddr: h.localAddr,
localAddr: localAddr,
}
if sessionId != "" { // if not stream-one
conn.reader = currentSession.uploadQueue