mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-09-15 22:10:26 +00:00
splithttp: bind sendThrough=origin to the real per-connection local IP
The XHTTP inbound set every accepted connection's LocalAddr to the
listener's address (h.localAddr = l.listener.Addr()). On a wildcard
listener that is the unspecified address ("[::]" / "0.0.0.0").
sendThrough "origin" derives the outbound gateway from inbound.Local,
which comes from conn.LocalAddr(). So with XHTTP every connection's
egress was bound to the wildcard, collapsing all entry IPs onto one
(often IPv6) source address and breaking source-in-source-out on
multi-IP hosts (and failing outright when that address has no route).
Read the concrete per-connection local address from the request context
(http.LocalAddrContextKey), which net/http populates with the address
the client actually connected to. Fall back to the listener address when
the key is absent (e.g. HTTP/3, where net/http does not set it).
This commit is contained in:
@@ -373,11 +373,23 @@ func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Req
|
||||
Reader: request.Body,
|
||||
ResponseWriter: writer,
|
||||
}
|
||||
// Use the concrete local address this request actually arrived on,
|
||||
// not the listener's wildcard address (e.g. "[::]" / "0.0.0.0"). Go's
|
||||
// net/http stores the per-connection local address in the request
|
||||
// context under LocalAddrContextKey. Without this, sendThrough "origin"
|
||||
// (which derives the outbound gateway from inbound.Local) reads the
|
||||
// wildcard and pins every connection's egress to a single address,
|
||||
// breaking source-in-source-out on multi-IP hosts. Fall back to the
|
||||
// listener address when the key is absent (e.g. HTTP/3).
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user