fix(redirect): check bypass on dstAddr before sniffing

IP/CIDR bypass rules were silently ignored when sniffing was enabled because the sniffer's internal bypass only matches sniffed hostnames. The post-sniffing dstAddr check was unreachable since HandleHTTP/HandleTLS return early.
This commit is contained in:
Denis Galeev
2026-07-11 21:01:37 +08:00
committed by GitHub
parent d12663dfe3
commit fe394a8420
+8 -6
View File
@@ -142,6 +142,14 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
"host": dstAddr.String(),
})
// Check bypass on dstAddr before sniffing — the sniffer only matches the
// sniffed req.Host, so IP/CIDR rules miss connections carrying a hostname.
if h.options.Bypass != nil &&
h.options.Bypass.Contains(ctx, dstAddr.Network(), dstAddr.String(), bypass.WithService(h.options.Service)) {
log.Debug("bypass: ", dstAddr)
return xbypass.ErrBypass
}
if h.md.sniffing {
if h.md.sniffingTimeout > 0 {
conn.SetReadDeadline(time.Now().Add(h.md.sniffingTimeout))
@@ -229,12 +237,6 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
log.Debugf("%s >> %s", conn.RemoteAddr(), dstAddr)
if h.options.Bypass != nil &&
h.options.Bypass.Contains(ctx, dstAddr.Network(), dstAddr.String(), bypass.WithService(h.options.Service)) {
log.Debug("bypass: ", dstAddr)
return xbypass.ErrBypass
}
var buf bytes.Buffer
cc, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), dstAddr.Network(), dstAddr.String())
ro.Route = buf.String()