fix: nil HTTP recorder ref in WebSocket goroutines, add tunnel loop detection
- handler/http/websocket, forwarder/sniffer_ws, sniffing/sniffer_ws: nil ro2.HTTP in WebSocket copy goroutines to avoid data races on the shared HTTP recorder object - handler/tunnel/bind: remove ingress rule check that incorrectly overrode the endpoint host for non-matching ingress rules - handler/tunnel/entrypoint: add forwarding loop detection by checking Gost-Forwarded-Node header for the entrypoint's own node ID
This commit is contained in:
@@ -51,6 +51,7 @@ func (h *httpHandler) copyWebsocketDirection(ctx context.Context, r io.Reader, w
|
||||
}
|
||||
ro2 := &xrecorder.HandlerRecorderObject{}
|
||||
*ro2 = *ro
|
||||
ro2.HTTP = nil
|
||||
r2 := ro2
|
||||
|
||||
limiter := rate.NewLimiter(rate.Limit(sampleRate), int(sampleRate))
|
||||
|
||||
@@ -41,9 +41,7 @@ func (h *tunnelHandler) handleBind(ctx context.Context, conn net.Conn, network,
|
||||
if host == "" || h.md.ingress == nil {
|
||||
host = endpoint
|
||||
} else if host != endpoint {
|
||||
if rule := h.md.ingress.GetRule(ctx, host, ingress.WithService(h.options.Service)); rule != nil && rule.Endpoint != tunnelID.String() {
|
||||
host = endpoint
|
||||
}
|
||||
host = endpoint
|
||||
}
|
||||
addr := net.JoinHostPort(host, port)
|
||||
|
||||
|
||||
@@ -278,6 +278,24 @@ func (ep *entrypoint) httpRoundTrip(ctx context.Context, rw io.ReadWriteCloser,
|
||||
} else {
|
||||
req.Header.Set(httpHeaderSID, ro.SID)
|
||||
}
|
||||
|
||||
// Loop detection: if Gost-Forwarded-Node contains our own node ID,
|
||||
// the request has already passed through this entrypoint and is looping.
|
||||
for _, node := range strings.Split(req.Header.Get(httpHeaderForwardedNode), ",") {
|
||||
if strings.TrimSpace(node) == ep.node {
|
||||
log.Warn("forwarding loop detected, rejecting request")
|
||||
res := &http.Response{
|
||||
ProtoMajor: req.ProtoMajor,
|
||||
ProtoMinor: req.ProtoMinor,
|
||||
Header: http.Header{},
|
||||
StatusCode: http.StatusServiceUnavailable,
|
||||
}
|
||||
ro.HTTP.StatusCode = res.StatusCode
|
||||
res.Write(rw)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
req.Header.Set(httpHeaderForwardedNode, ro.Node)
|
||||
|
||||
host := req.Host
|
||||
|
||||
Reference in New Issue
Block a user