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 { func NewHunkConn(hc HunkConn, cancel context.CancelFunc, trustedXForwardedFor []string) net.Conn {
rAddr := remoteAddrFromContext(hc.Context(), trustedXForwardedFor) rAddr := remoteAddrFromContext(hc.Context(), trustedXForwardedFor)
lAddr := localAddrFromContext(hc.Context())
wrc := NewHunkReadWriter(hc, cancel) wrc := NewHunkReadWriter(hc, cancel)
return cnc.NewConnection( return cnc.NewConnection(
cnc.ConnectionInput(wrc), cnc.ConnectionInput(wrc),
cnc.ConnectionOutput(wrc), cnc.ConnectionOutput(wrc),
cnc.ConnectionOnClose(wrc), cnc.ConnectionOnClose(wrc),
cnc.ConnectionRemoteAddr(rAddr), 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 { func NewMultiHunkConn(hc MultiHunkConn, cancel context.CancelFunc, trustedXForwardedFor []string) net.Conn {
rAddr := remoteAddrFromContext(hc.Context(), trustedXForwardedFor) rAddr := remoteAddrFromContext(hc.Context(), trustedXForwardedFor)
lAddr := localAddrFromContext(hc.Context())
wrc := NewMultiHunkReadWriter(hc, cancel) wrc := NewMultiHunkReadWriter(hc, cancel)
return cnc.NewConnection( return cnc.NewConnection(
cnc.ConnectionInputMulti(wrc), cnc.ConnectionInputMulti(wrc),
cnc.ConnectionOutputMulti(wrc), cnc.ConnectionOutputMulti(wrc),
cnc.ConnectionOnClose(wrc), cnc.ConnectionOnClose(wrc),
cnc.ConnectionRemoteAddr(rAddr), cnc.ConnectionRemoteAddr(rAddr),
cnc.ConnectionLocalAddr(lAddr),
) )
} }
@@ -56,3 +56,17 @@ func parseTrustedXForwardedFor(md metadata.MD, trusted []string, remoteAddr net.
} }
return nil 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, Reader: request.Body,
ResponseWriter: writer, ResponseWriter: writer,
} }
localAddr := h.localAddr
if la, ok := request.Context().Value(http.LocalAddrContextKey).(net.Addr); ok && la != nil {
localAddr = la
}
conn := splitConn{ conn := splitConn{
writer: httpSC, writer: httpSC,
reader: httpSC, reader: httpSC,
remoteAddr: remoteAddr, remoteAddr: remoteAddr,
localAddr: h.localAddr, localAddr: localAddr,
} }
if sessionId != "" { // if not stream-one if sessionId != "" { // if not stream-one
conn.reader = currentSession.uploadQueue conn.reader = currentSession.uploadQueue