From 4aba687dd3529f47506f40415d0d35da7033d946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A3=8E=E6=89=87=E6=BB=91=E7=BF=94=E7=BF=BC?= Date: Mon, 27 Jul 2026 21:11:25 +0800 Subject: [PATCH] XHTTP & gRPC servers: Get accurate localAddr (#6526) Fixes https://github.com/XTLS/Xray-core/pull/6476 --------- Co-authored-by: echoowall --- transport/internet/grpc/encoding/hunkconn.go | 2 ++ transport/internet/grpc/encoding/multiconn.go | 2 ++ transport/internet/grpc/encoding/remoteaddr.go | 14 ++++++++++++++ transport/internet/splithttp/hub.go | 6 +++++- 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/transport/internet/grpc/encoding/hunkconn.go b/transport/internet/grpc/encoding/hunkconn.go index 92769065e..18262fb95 100644 --- a/transport/internet/grpc/encoding/hunkconn.go +++ b/transport/internet/grpc/encoding/hunkconn.go @@ -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), ) } diff --git a/transport/internet/grpc/encoding/multiconn.go b/transport/internet/grpc/encoding/multiconn.go index f27a1c35e..5a51c929b 100644 --- a/transport/internet/grpc/encoding/multiconn.go +++ b/transport/internet/grpc/encoding/multiconn.go @@ -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), ) } diff --git a/transport/internet/grpc/encoding/remoteaddr.go b/transport/internet/grpc/encoding/remoteaddr.go index a28d91933..5c71f7501 100644 --- a/transport/internet/grpc/encoding/remoteaddr.go +++ b/transport/internet/grpc/encoding/remoteaddr.go @@ -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 +} diff --git a/transport/internet/splithttp/hub.go b/transport/internet/splithttp/hub.go index 557f8a54d..d664c86c4 100644 --- a/transport/internet/splithttp/hub.go +++ b/transport/internet/splithttp/hub.go @@ -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