From f09a7a69b3b829cbdf84c3f59fcb3945934be443 Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Fri, 5 Jun 2026 20:27:27 +0800 Subject: [PATCH] fix(sniffing): return early on empty SNI to avoid 'missing port in address' errors (#645) When TLS ClientHello has no SNI extension (ServerName is empty), normalizeHost returns empty string. Both sniffer_tls.go paths (sniffing and forwarder packages) previously still called dial with an empty host, cascading 'missing port in address' errors through connector, router, and service layers. Now returns early with a debug-level log, silently closing the connection instead of attempting to dial upstream. --- internal/util/forwarder/sniffer_tls.go | 14 +++++++++----- internal/util/sniffing/sniffer_tls.go | 14 +++++++++----- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/internal/util/forwarder/sniffer_tls.go b/internal/util/forwarder/sniffer_tls.go index d1dfd96f..b0bb72fa 100644 --- a/internal/util/forwarder/sniffer_tls.go +++ b/internal/util/forwarder/sniffer_tls.go @@ -50,12 +50,16 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp } host := normalizeHost(clientHello.ServerName, "443") - if host != "" { - ro.Host = host - - if ho.bypass != nil && ho.bypass.Contains(ctx, "tcp", host, bypass.WithService(ho.service)) { - return xbypass.ErrBypass + if host == "" { + if ho.log != nil { + ho.log.Debugf("no sni in clienthello from %s", conn.RemoteAddr()) } + return nil + } + ro.Host = host + + if ho.bypass != nil && ho.bypass.Contains(ctx, "tcp", host, bypass.WithService(ho.service)) { + return xbypass.ErrBypass } node, cc, err := h.dialTLS(ctx, host, &ho) diff --git a/internal/util/sniffing/sniffer_tls.go b/internal/util/sniffing/sniffer_tls.go index 7924e9ca..69c8b31e 100644 --- a/internal/util/sniffing/sniffer_tls.go +++ b/internal/util/sniffing/sniffer_tls.go @@ -48,12 +48,16 @@ func (h *Sniffer) HandleTLS(ctx context.Context, network string, conn net.Conn, } host := normalizeHost(clientHello.ServerName, "443") - if host != "" { - ro.Host = host - - if ho.bypass != nil && ho.bypass.Contains(ctx, network, host, bypass.WithService(ho.service)) { - return xbypass.ErrBypass + if host == "" { + if log != nil { + log.Debugf("no sni in clienthello from %s", conn.RemoteAddr()) } + return nil + } + ro.Host = host + + if ho.bypass != nil && ho.bypass.Contains(ctx, network, host, bypass.WithService(ho.service)) { + return xbypass.ErrBypass } dial := ho.dial