From 52289bea6ca79fa5a8c50bcf1372da3e385bcd0b Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Wed, 13 Aug 2025 21:25:35 +0800 Subject: [PATCH] add network param for sniffing --- handler/http/handler.go | 4 +- handler/redirect/tcp/handler.go | 6 +- handler/relay/connect.go | 4 +- handler/sni/handler.go | 4 +- handler/socks/v4/handler.go | 4 +- handler/socks/v5/connect.go | 4 +- handler/ss/handler.go | 4 +- handler/sshd/handler.go | 4 +- handler/tungo/handler.go | 2 + handler/tungo/metadata.go | 4 ++ handler/tungo/stack.go | 21 ++++-- handler/unix/handler.go | 4 +- internal/util/forwarder/sniffer.go | 105 ++++++++++++++--------------- internal/util/sniffing/sniffer.go | 68 +++++++++---------- 14 files changed, 126 insertions(+), 112 deletions(-) diff --git a/handler/http/handler.go b/handler/http/handler.go index 4e089394..ab37c80e 100644 --- a/handler/http/handler.go +++ b/handler/http/handler.go @@ -405,14 +405,14 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt conn = xnet.NewReadWriteConn(br, conn, conn) switch proto { case sniffing.ProtoHTTP: - return sniffer.HandleHTTP(ctx, conn, + return sniffer.HandleHTTP(ctx, "tcp", conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithRecorderObject(ro), sniffing.WithLog(log), ) case sniffing.ProtoTLS: - return sniffer.HandleTLS(ctx, conn, + return sniffer.HandleTLS(ctx, "tcp", conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithRecorderObject(ro), diff --git a/handler/redirect/tcp/handler.go b/handler/redirect/tcp/handler.go index cc9bb936..9e07b9b9 100644 --- a/handler/redirect/tcp/handler.go +++ b/handler/redirect/tcp/handler.go @@ -206,7 +206,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han conn = xnet.NewReadWriteConn(br, conn, conn) switch proto { case sniffing.ProtoHTTP: - return sniffer.HandleHTTP(ctx, conn, + return sniffer.HandleHTTP(ctx, "tcp", conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithBypass(h.options.Bypass), @@ -214,7 +214,9 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han sniffing.WithLog(log), ) case sniffing.ProtoTLS: - return sniffer.HandleTLS(ctx, conn, + return sniffer.HandleTLS(ctx, + ro.Network, + conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithBypass(h.options.Bypass), diff --git a/handler/relay/connect.go b/handler/relay/connect.go index fd7fb151..630127db 100644 --- a/handler/relay/connect.go +++ b/handler/relay/connect.go @@ -185,14 +185,14 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network conn = xnet.NewReadWriteConn(br, conn, conn) switch proto { case sniffing.ProtoHTTP: - return sniffer.HandleHTTP(ctx, conn, + return sniffer.HandleHTTP(ctx, "tcp", conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithRecorderObject(ro), sniffing.WithLog(log), ) case sniffing.ProtoTLS: - return sniffer.HandleTLS(ctx, conn, + return sniffer.HandleTLS(ctx, "tcp", conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithRecorderObject(ro), diff --git a/handler/sni/handler.go b/handler/sni/handler.go index 4d2aa7f2..870b88b5 100644 --- a/handler/sni/handler.go +++ b/handler/sni/handler.go @@ -159,7 +159,7 @@ func (h *sniHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. conn = xnet.NewReadWriteConn(br, conn, conn) switch proto { case sniffing.ProtoHTTP: - return sniffer.HandleHTTP(ctx, conn, + return sniffer.HandleHTTP(ctx, "tcp", conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithBypass(h.options.Bypass), @@ -167,7 +167,7 @@ func (h *sniHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. sniffing.WithLog(log), ) case sniffing.ProtoTLS: - return sniffer.HandleTLS(ctx, conn, + return sniffer.HandleTLS(ctx, "tcp", conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithBypass(h.options.Bypass), diff --git a/handler/socks/v4/handler.go b/handler/socks/v4/handler.go index cd463292..2f483cd8 100644 --- a/handler/socks/v4/handler.go +++ b/handler/socks/v4/handler.go @@ -304,14 +304,14 @@ func (h *socks4Handler) handleConnect(ctx context.Context, conn net.Conn, req *g conn = xnet.NewReadWriteConn(br, conn, conn) switch proto { case sniffing.ProtoHTTP: - return sniffer.HandleHTTP(ctx, conn, + return sniffer.HandleHTTP(ctx, "tcp", conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithRecorderObject(ro), sniffing.WithLog(log), ) case sniffing.ProtoTLS: - return sniffer.HandleTLS(ctx, conn, + return sniffer.HandleTLS(ctx, "tcp", conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithRecorderObject(ro), diff --git a/handler/socks/v5/connect.go b/handler/socks/v5/connect.go index aa35eca7..93163207 100644 --- a/handler/socks/v5/connect.go +++ b/handler/socks/v5/connect.go @@ -123,14 +123,14 @@ func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, networ conn = xnet.NewReadWriteConn(br, conn, conn) switch proto { case sniffing.ProtoHTTP: - return sniffer.HandleHTTP(ctx, conn, + return sniffer.HandleHTTP(ctx, "tcp", conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithRecorderObject(ro), sniffing.WithLog(log), ) case sniffing.ProtoTLS: - return sniffer.HandleTLS(ctx, conn, + return sniffer.HandleTLS(ctx, "tcp", conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithRecorderObject(ro), diff --git a/handler/ss/handler.go b/handler/ss/handler.go index 523632a7..6c7ae455 100644 --- a/handler/ss/handler.go +++ b/handler/ss/handler.go @@ -210,14 +210,14 @@ func (h *ssHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.H conn = xnet.NewReadWriteConn(br, conn, conn) switch proto { case sniffing.ProtoHTTP: - return sniffer.HandleHTTP(ctx, conn, + return sniffer.HandleHTTP(ctx, "tcp", conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithRecorderObject(ro), sniffing.WithLog(log), ) case sniffing.ProtoTLS: - return sniffer.HandleTLS(ctx, conn, + return sniffer.HandleTLS(ctx, "tcp", conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithRecorderObject(ro), diff --git a/handler/sshd/handler.go b/handler/sshd/handler.go index 09a28704..2b6599ce 100644 --- a/handler/sshd/handler.go +++ b/handler/sshd/handler.go @@ -205,14 +205,14 @@ func (h *forwardHandler) handleDirectForward(ctx context.Context, conn *sshd_uti switch proto { case sniffing.ProtoHTTP: - return sniffer.HandleHTTP(ctx, xnet.NewReadWriteConn(br, conn, conn), + return sniffer.HandleHTTP(ctx, "tcp", xnet.NewReadWriteConn(br, conn, conn), sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithRecorderObject(ro), sniffing.WithLog(log), ) case sniffing.ProtoTLS: - return sniffer.HandleTLS(ctx, xnet.NewReadWriteConn(br, conn, conn), + return sniffer.HandleTLS(ctx, "tcp", xnet.NewReadWriteConn(br, conn, conn), sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithRecorderObject(ro), diff --git a/handler/tungo/handler.go b/handler/tungo/handler.go index 49ae4cd8..d3d1fc74 100644 --- a/handler/tungo/handler.go +++ b/handler/tungo/handler.go @@ -125,6 +125,8 @@ func (h *tungoHandler) Handle(ctx context.Context, conn net.Conn, opts ...handle recorder: h.recorder, stats: h.stats, + ipv6: h.md.ipv6, + opts: &h.options, } diff --git a/handler/tungo/metadata.go b/handler/tungo/metadata.go index aaab9114..88346096 100644 --- a/handler/tungo/metadata.go +++ b/handler/tungo/metadata.go @@ -32,6 +32,8 @@ type metadata struct { multicastGroups []netip.Addr + ipv6 bool + tcpSendBufferSize int tcpReceiveBufferSize int tcpModerateReceiveBuffer bool @@ -73,6 +75,8 @@ func (h *tungoHandler) parseMetadata(md mdata.Metadata) (err error) { h.md.multicastGroups = append(h.md.multicastGroups, addr) } + h.md.ipv6 = mdutil.GetBool(md, "ipv6") + h.md.tcpSendBufferSize = mdutil.GetInt(md, "tcpSendBufferSize", "tungo.tcpSendBufferSize") h.md.tcpReceiveBufferSize = mdutil.GetInt(md, "tcpReceiveBufferSize", "tungo.tcpReceiveBufferSize") h.md.tcpModerateReceiveBuffer = mdutil.GetBool(md, "tcpModerateReceiveBuffer", "tungo.tcpModerateReceiveBuffer") diff --git a/handler/tungo/stack.go b/handler/tungo/stack.go index 7d95d0f8..6cfc1dbf 100644 --- a/handler/tungo/stack.go +++ b/handler/tungo/stack.go @@ -57,6 +57,8 @@ type transportHandler struct { stats *stats_util.HandlerStats recorder recorder.RecorderObject + ipv6 bool + opts *handler.Options } @@ -111,9 +113,14 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) { sid := xid.New().String() ctx := xctx.ContextWithSid(context.Background(), xctx.Sid(sid)) + network := "tcp" + if remoteIP.Unmap().Is6() && h.ipv6 { + network = "tcp6" + } + ro := &xrecorder.HandlerRecorderObject{ Service: h.opts.Service, - Network: "tcp", + Network: network, RemoteAddr: remoteAddr.String(), DstAddr: dstAddr.String(), Host: dstAddr.String(), @@ -191,7 +198,7 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) { ro.Host = address var buf bytes.Buffer - cc, err = h.opts.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", address) + cc, err = h.opts.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), network, address) ro.Route = buf.String() if err != nil && !h.sniffingFallback { return nil, err @@ -200,7 +207,7 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) { if cc == nil { var buf bytes.Buffer - cc, err = h.opts.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", dstAddr.String()) + cc, err = h.opts.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), network, dstAddr.String()) ro.Route = buf.String() ro.Host = dstAddr.String() } @@ -221,7 +228,7 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) { conn = xnet.NewReadWriteConn(br, conn, conn) switch proto { case sniffing.ProtoHTTP: - sniffer.HandleHTTP(ctx, conn, + sniffer.HandleHTTP(ctx, network, conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithBypass(h.opts.Bypass), @@ -230,7 +237,7 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) { ) return case sniffing.ProtoTLS: - sniffer.HandleTLS(ctx, conn, + sniffer.HandleTLS(ctx, network, conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithBypass(h.opts.Bypass), @@ -242,13 +249,13 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) { } if h.opts.Bypass != nil && - h.opts.Bypass.Contains(ctx, "tcp", dstAddr.String()) { + h.opts.Bypass.Contains(ctx, network, dstAddr.String()) { log.Debug("bypass: ", dstAddr) return } var buf bytes.Buffer - cc, err := h.opts.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", dstAddr.String()) + cc, err := h.opts.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), network, dstAddr.String()) ro.Route = buf.String() if err != nil { log.Errorf("dial %s: %v", dstAddr.String(), err) diff --git a/handler/unix/handler.go b/handler/unix/handler.go index af48a36f..59f6a506 100644 --- a/handler/unix/handler.go +++ b/handler/unix/handler.go @@ -176,14 +176,14 @@ func (h *unixHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler conn = xnet.NewReadWriteConn(br, conn, conn) switch proto { case sniffing.ProtoHTTP: - return sniffer.HandleHTTP(ctx, conn, + return sniffer.HandleHTTP(ctx, "tcp", conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithRecorderObject(ro), sniffing.WithLog(log), ) case sniffing.ProtoTLS: - return sniffer.HandleTLS(ctx, conn, + return sniffer.HandleTLS(ctx, "tcp", conn, sniffing.WithDial(dial), sniffing.WithDialTLS(dialTLS), sniffing.WithRecorderObject(ro), diff --git a/internal/util/forwarder/sniffer.go b/internal/util/forwarder/sniffer.go index 94592731..6a0824dc 100644 --- a/internal/util/forwarder/sniffer.go +++ b/internal/util/forwarder/sniffer.go @@ -51,57 +51,56 @@ var ( ) type HandleOptions struct { - Dial func(ctx context.Context, network, address string) (net.Conn, error) - - HTTPKeepalive bool - Node *chain.Node - Hop hop.Hop - Bypass bypass.Bypass - RecorderObject *xrecorder.HandlerRecorderObject - Log logger.Logger + dial func(ctx context.Context, network, address string) (net.Conn, error) + httpKeepalive bool + node *chain.Node + hop hop.Hop + bypass bypass.Bypass + recorderObject *xrecorder.HandlerRecorderObject + log logger.Logger } type HandleOption func(opts *HandleOptions) func WithDial(dial func(ctx context.Context, network, address string) (net.Conn, error)) HandleOption { return func(opts *HandleOptions) { - opts.Dial = dial + opts.dial = dial } } func WithHTTPKeepalive(keepalive bool) HandleOption { return func(opts *HandleOptions) { - opts.HTTPKeepalive = keepalive + opts.httpKeepalive = keepalive } } func WithNode(node *chain.Node) HandleOption { return func(opts *HandleOptions) { - opts.Node = node + opts.node = node } } func WithHop(hop hop.Hop) HandleOption { return func(opts *HandleOptions) { - opts.Hop = hop + opts.hop = hop } } func WithBypass(bypass bypass.Bypass) HandleOption { return func(opts *HandleOptions) { - opts.Bypass = bypass + opts.bypass = bypass } } func WithRecorderObject(ro *xrecorder.HandlerRecorderObject) HandleOption { return func(opts *HandleOptions) { - opts.RecorderObject = ro + opts.recorderObject = ro } } func WithLog(log logger.Logger) HandleOption { return func(opts *HandleOptions) { - opts.Log = log + opts.log = log } } @@ -141,12 +140,12 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO return err } - if ho.Log.IsLevelEnabled(logger.TraceLevel) { + if ho.log.IsLevelEnabled(logger.TraceLevel) { dump, _ := httputil.DumpRequest(req, false) - ho.Log.Trace(string(dump)) + ho.log.Trace(string(dump)) } - ro := ho.RecorderObject + ro := ho.recorderObject ro.HTTP = &xrecorder.HTTPRecorderObject{ Host: req.Host, Proto: req.Proto, @@ -176,8 +175,8 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO } defer cc.Close() - ho.Log = ho.Log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - log := ho.Log + ho.log = ho.log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) + log := ho.log log.Debugf("connected to node %s(%s)", node.Name, node.Addr) ro.SrcAddr = cc.LocalAddr().String() @@ -212,17 +211,17 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO } func (h *Sniffer) dial(ctx context.Context, conn net.Conn, req *http.Request, ho *HandleOptions) (node *chain.Node, cc net.Conn, err error) { - dial := ho.Dial + dial := ho.dial if dial == nil { dial = (&net.Dialer{}).DialContext } - if node = ho.Node; node != nil { + if node = ho.node; node != nil { cc, err = dial(ctx, "tcp", node.Addr) return } - ro := ho.RecorderObject + ro := ho.recorderObject res := &http.Response{ ProtoMajor: req.ProtoMajor, @@ -237,13 +236,13 @@ func (h *Sniffer) dial(ctx context.Context, conn net.Conn, req *http.Request, ho host = net.JoinHostPort(strings.Trim(host, "[]"), "80") } ro.Host = host - ho.Log = ho.Log.WithFields(map[string]any{ + ho.log = ho.log.WithFields(map[string]any{ "host": host, }) - if ho.Bypass != nil && - ho.Bypass.Contains(ctx, "tcp", host, bypass.WithPathOption(req.RequestURI)) { - ho.Log.Debugf("bypass: %s %s", host, req.RequestURI) + if ho.bypass != nil && + ho.bypass.Contains(ctx, "tcp", host, bypass.WithPathOption(req.RequestURI)) { + ho.log.Debugf("bypass: %s %s", host, req.RequestURI) res.StatusCode = http.StatusForbidden ro.HTTP.StatusCode = res.StatusCode res.Write(conn) @@ -252,13 +251,13 @@ func (h *Sniffer) dial(ctx context.Context, conn net.Conn, req *http.Request, ho } node = &chain.Node{} - if ho.Hop != nil { + if ho.hop != nil { var clientIP net.IP if clientAddr, _ := net.ResolveTCPAddr("tcp", ro.ClientAddr); clientAddr != nil { clientIP = clientAddr.IP } - node = ho.Hop.Select(ctx, + node = ho.hop.Select(ctx, hop.ClientIPSelectOption(clientIP), hop.ProtocolSelectOption(sniffing.ProtoHTTP), hop.HostSelectOption(host), @@ -269,7 +268,7 @@ func (h *Sniffer) dial(ctx context.Context, conn net.Conn, req *http.Request, ho ) } if node == nil { - ho.Log.Warnf("node for %s not found", host) + ho.log.Warnf("node for %s not found", host) res.StatusCode = http.StatusBadGateway ro.HTTP.StatusCode = res.StatusCode res.Write(conn) @@ -283,11 +282,11 @@ func (h *Sniffer) dial(ctx context.Context, conn net.Conn, req *http.Request, ho } ro.Host = node.Addr - ho.Log = ho.Log.WithFields(map[string]any{ + ho.log = ho.log.WithFields(map[string]any{ "node": node.Name, "dst": node.Addr, }) - ho.Log.Debugf("find node for host %s -> %s(%s)", host, node.Name, node.Addr) + ho.log.Debugf("find node for host %s -> %s(%s)", host, node.Name, node.Addr) cc, err = dial(ctx, "tcp", node.Addr) if err != nil { @@ -296,7 +295,7 @@ func (h *Sniffer) dial(ctx context.Context, conn net.Conn, req *http.Request, ho if marker := node.Marker(); marker != nil { marker.Mark() } - ho.Log.Warnf("connect to node %s(%s) failed: %v", node.Name, node.Addr, err) + ho.log.Warnf("connect to node %s(%s) failed: %v", node.Name, node.Addr, err) res.Write(conn) return } @@ -332,8 +331,8 @@ func (h *Sniffer) serveH2(ctx context.Context, conn net.Conn, ho *HandleOptions) return errors.New("h2: invalid client preface") } - ro := ho.RecorderObject - log := ho.Log + ro := ho.recorderObject + log := ho.log ro.Time = time.Time{} @@ -370,9 +369,9 @@ func (h *Sniffer) serveH2(ctx context.Context, conn net.Conn, ho *HandleOptions) func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriteCloser, node *chain.Node, req *http.Request, pStats stats.Stats, ho *HandleOptions) (close bool, err error) { close = true - log := ho.Log + log := ho.log ro := &xrecorder.HandlerRecorderObject{} - *ro = *ho.RecorderObject + *ro = *ho.recorderObject ro.Time = time.Now() log.Infof("%s <-> %s", ro.RemoteAddr, req.Host) @@ -540,7 +539,7 @@ func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriteCloser, resp.ProtoMinor = req.ProtoMinor } - if !ho.HTTPKeepalive { + if !ho.httpKeepalive { resp.Header.Set("Connection", "close") } @@ -790,7 +789,7 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp return err } - ro := ho.RecorderObject + ro := ho.recorderObject ro.TLS = &xrecorder.TLSRecorderObject{ ServerName: clientHello.ServerName, ClientHello: hex.EncodeToString(buf.Bytes()), @@ -808,7 +807,7 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp } ro.Host = host - if ho.Bypass != nil && ho.Bypass.Contains(ctx, "tcp", host) { + if ho.bypass != nil && ho.bypass.Contains(ctx, "tcp", host) { return xbypass.ErrBypass } } @@ -818,9 +817,9 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp return err } defer cc.Close() - ho.Node = node + ho.node = node - log := ho.Log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) + log := ho.log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) log.Debugf("connected to node %s(%s)", node.Name, node.Addr) ro.SrcAddr = cc.LocalAddr().String() @@ -874,26 +873,26 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp } func (h *Sniffer) dialTLS(ctx context.Context, host string, ho *HandleOptions) (node *chain.Node, cc net.Conn, err error) { - dial := ho.Dial + dial := ho.dial if dial == nil { dial = (&net.Dialer{}).DialContext } - if node = ho.Node; node != nil { + if node = ho.node; node != nil { cc, err = dial(ctx, "tcp", node.Addr) return } node = &chain.Node{} - ro := ho.RecorderObject - if ho.Hop != nil { + ro := ho.recorderObject + if ho.hop != nil { var clientIP net.IP if clientAddr, _ := net.ResolveTCPAddr("tcp", ro.ClientAddr); clientAddr != nil { clientIP = clientAddr.IP } - node = ho.Hop.Select(ctx, + node = ho.hop.Select(ctx, hop.ClientIPSelectOption(clientIP), hop.HostSelectOption(host), hop.ProtocolSelectOption(sniffing.ProtoTLS), @@ -923,12 +922,12 @@ func (h *Sniffer) dialTLS(ctx context.Context, host string, ho *HandleOptions) ( } ro.Host = addr - ho.Log = ho.Log.WithFields(map[string]any{ + ho.log = ho.log.WithFields(map[string]any{ "host": host, "node": node.Name, "dst": fmt.Sprintf("%s/%s", addr, ro.Network), }) - ho.Log.Debugf("find node for host %s -> %s(%s)", host, node.Name, addr) + ho.log.Debugf("find node for host %s -> %s(%s)", host, node.Name, addr) cc, err = dial(ctx, ro.Network, addr) if err != nil { @@ -937,7 +936,7 @@ func (h *Sniffer) dialTLS(ctx context.Context, host string, ho *HandleOptions) ( if marker := node.Marker(); marker != nil { marker.Mark() } - ho.Log.Warnf("connect to node %s(%s) failed: %v", node.Name, node.Addr, err) + ho.log.Warnf("connect to node %s(%s) failed: %v", node.Name, node.Addr, err) return } @@ -962,8 +961,8 @@ func (h *Sniffer) dialTLS(ctx context.Context, host string, ho *HandleOptions) ( } func (h *Sniffer) terminateTLS(ctx context.Context, conn, cc net.Conn, clientHello *dissector.ClientHelloInfo, ho *HandleOptions) error { - ro := ho.RecorderObject - log := ho.Log + ro := ho.recorderObject + log := ho.log nextProtos := clientHello.SupportedProtos if h.NegotiatedProtocol != "" { @@ -1063,7 +1062,7 @@ func (h *Sniffer) terminateTLS(ctx context.Context, conn, cc net.Conn, clientHel return clientConn, nil }), WithHTTPKeepalive(true), - WithNode(ho.Node), + WithNode(ho.node), WithRecorderObject(ro), WithLog(log), } diff --git a/internal/util/sniffing/sniffer.go b/internal/util/sniffing/sniffer.go index f0566dcb..493fc90e 100644 --- a/internal/util/sniffing/sniffer.go +++ b/internal/util/sniffing/sniffer.go @@ -54,43 +54,43 @@ var ( ) type HandleOptions struct { - Dial func(ctx context.Context, network, address string) (net.Conn, error) - DialTLS func(ctx context.Context, network, address string, cfg *tls.Config) (net.Conn, error) + dial func(ctx context.Context, network, address string) (net.Conn, error) + dialTLS func(ctx context.Context, network, address string, cfg *tls.Config) (net.Conn, error) - Bypass bypass.Bypass - RecorderObject *xrecorder.HandlerRecorderObject - Log logger.Logger + bypass bypass.Bypass + recorderObject *xrecorder.HandlerRecorderObject + log logger.Logger } type HandleOption func(opts *HandleOptions) func WithDial(dial func(ctx context.Context, network, address string) (net.Conn, error)) HandleOption { return func(opts *HandleOptions) { - opts.Dial = dial + opts.dial = dial } } func WithDialTLS(dialTLS func(ctx context.Context, network, address string, cfg *tls.Config) (net.Conn, error)) HandleOption { return func(opts *HandleOptions) { - opts.DialTLS = dialTLS + opts.dialTLS = dialTLS } } func WithBypass(bypass bypass.Bypass) HandleOption { return func(opts *HandleOptions) { - opts.Bypass = bypass + opts.bypass = bypass } } func WithRecorderObject(ro *xrecorder.HandlerRecorderObject) HandleOption { return func(opts *HandleOptions) { - opts.RecorderObject = ro + opts.recorderObject = ro } } func WithLog(log logger.Logger) HandleOption { return func(opts *HandleOptions) { - opts.Log = log + opts.log = log } } @@ -111,7 +111,7 @@ type Sniffer struct { ReadTimeout time.Duration } -func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleOption) error { +func (h *Sniffer) HandleHTTP(ctx context.Context, network string, conn net.Conn, opts ...HandleOption) error { var ho HandleOptions for _, opt := range opts { opt(&ho) @@ -130,13 +130,13 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO return err } - log := ho.Log + log := ho.log if log.IsLevelEnabled(logger.TraceLevel) { dump, _ := httputil.DumpRequest(req, false) log.Trace(string(dump)) } - ro := ho.RecorderObject + ro := ho.recorderObject ro.HTTP = &xrecorder.HTTPRecorderObject{ Host: req.Host, Proto: req.Proto, @@ -156,7 +156,7 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO // http/2 if req.Method == "PRI" && len(req.Header) == 0 && req.URL.Path == "*" && req.Proto == "HTTP/2.0" { - return h.serveH2(ctx, xnet.NewReadWriteConn(br, conn, conn), &ho) + return h.serveH2(ctx, network, xnet.NewReadWriteConn(br, conn, conn), &ho) } host := req.Host @@ -170,16 +170,16 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO "host": host, }) - if ho.Bypass != nil && ho.Bypass.Contains(ctx, "tcp", host) { + if ho.bypass != nil && ho.bypass.Contains(ctx, network, host) { return xbypass.ErrBypass } } - dial := ho.Dial + dial := ho.dial if dial == nil { dial = (&net.Dialer{}).DialContext } - cc, err := dial(ctx, "tcp", host) + cc, err := dial(ctx, network, host) if err != nil { return err } @@ -218,7 +218,7 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO } } -func (h *Sniffer) serveH2(ctx context.Context, conn net.Conn, ho *HandleOptions) error { +func (h *Sniffer) serveH2(ctx context.Context, network string, conn net.Conn, ho *HandleOptions) error { const expectedBody = "SM\r\n\r\n" buf := make([]byte, len(expectedBody)) @@ -230,14 +230,14 @@ func (h *Sniffer) serveH2(ctx context.Context, conn net.Conn, ho *HandleOptions) return errors.New("h2: invalid client preface") } - ro := ho.RecorderObject - log := ho.Log + ro := ho.recorderObject + log := ho.log ro.Time = time.Time{} tr := &http2.Transport{ - DialTLSContext: func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) { - if dial := ho.DialTLS; dial != nil { + DialTLSContext: func(ctx context.Context, nw, addr string, cfg *tls.Config) (net.Conn, error) { + if dial := ho.dialTLS; dial != nil { return dial(ctx, network, addr, cfg) } @@ -564,7 +564,7 @@ func (h *Sniffer) copyWebsocketFrame(w io.Writer, r io.Reader, buf *bytes.Buffer return nil } -func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOption) error { +func (h *Sniffer) HandleTLS(ctx context.Context, network string, conn net.Conn, opts ...HandleOption) error { var ho HandleOptions for _, opt := range opts { opt(&ho) @@ -580,9 +580,9 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp return err } - log := ho.Log + log := ho.log - ro := ho.RecorderObject + ro := ho.recorderObject ro.TLS = &xrecorder.TLSRecorderObject{ ServerName: clientHello.ServerName, ClientHello: hex.EncodeToString(buf.Bytes()), @@ -600,16 +600,16 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp } ro.Host = host - if ho.Bypass != nil && ho.Bypass.Contains(ctx, "tcp", host) { + if ho.bypass != nil && ho.bypass.Contains(ctx, network, host) { return xbypass.ErrBypass } } - dial := ho.Dial + dial := ho.dial if dial == nil { dial = (&net.Dialer{}).DialContext } - cc, err := dial(ctx, "tcp", host) + cc, err := dial(ctx, network, host) if err != nil { return err } @@ -624,8 +624,8 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp if host == "" { host = ro.Host } - if h.MitmBypass == nil || !h.MitmBypass.Contains(ctx, "tcp", host) { - return h.terminateTLS(ctx, xnet.NewReadWriteConn(io.MultiReader(buf, conn), conn, conn), cc, clientHello, &ho) + if h.MitmBypass == nil || !h.MitmBypass.Contains(ctx, network, host) { + return h.terminateTLS(ctx, network, xnet.NewReadWriteConn(io.MultiReader(buf, conn), conn, conn), cc, clientHello, &ho) } } @@ -666,9 +666,9 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp return err } -func (h *Sniffer) terminateTLS(ctx context.Context, conn, cc net.Conn, clientHello *dissector.ClientHelloInfo, ho *HandleOptions) error { - ro := ho.RecorderObject - log := ho.Log +func (h *Sniffer) terminateTLS(ctx context.Context, network string, conn, cc net.Conn, clientHello *dissector.ClientHelloInfo, ho *HandleOptions) error { + ro := ho.recorderObject + log := ho.log nextProtos := clientHello.SupportedProtos if h.NegotiatedProtocol != "" { @@ -773,7 +773,7 @@ func (h *Sniffer) terminateTLS(ctx context.Context, conn, cc net.Conn, clientHel WithRecorderObject(ro), WithLog(log), } - return h.HandleHTTP(ctx, serverConn, opts...) + return h.HandleHTTP(ctx, network, serverConn, opts...) } type h2Handler struct {