diff --git a/handler/http/handler.go b/handler/http/handler.go index 5012082f..b944abbe 100644 --- a/handler/http/handler.go +++ b/handler/http/handler.go @@ -303,30 +303,34 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt } defer cc.Close() - rw := traffic_wrapper.WrapReadWriter( - h.limiter, - conn, - clientID, - limiter.ScopeOption(limiter.ScopeClient), - limiter.ServiceOption(h.options.Service), - limiter.NetworkOption(network), - limiter.AddrOption(addr), - limiter.ClientOption(clientID), - limiter.SrcOption(conn.RemoteAddr().String()), - ) - if h.options.Observer != nil { - pstats := h.stats.Stats(clientID) - pstats.Add(stats.KindTotalConns, 1) - pstats.Add(stats.KindCurrentConns, 1) - defer pstats.Add(stats.KindCurrentConns, -1) - rw = stats_wrapper.WrapReadWriter(rw, pstats) + { + rw := traffic_wrapper.WrapReadWriter( + h.limiter, + conn, + clientID, + limiter.ScopeOption(limiter.ScopeClient), + limiter.ServiceOption(h.options.Service), + limiter.NetworkOption(network), + limiter.AddrOption(addr), + limiter.ClientOption(clientID), + limiter.SrcOption(conn.RemoteAddr().String()), + ) + if h.options.Observer != nil { + pstats := h.stats.Stats(clientID) + pstats.Add(stats.KindTotalConns, 1) + pstats.Add(stats.KindCurrentConns, 1) + defer pstats.Add(stats.KindCurrentConns, -1) + rw = stats_wrapper.WrapReadWriter(rw, pstats) + } + + conn = xnet.NewReadWriteConn(rw, rw, conn) } if req.Method != http.MethodConnect { ro2 := &xrecorder.HandlerRecorderObject{} *ro2 = *ro ro.Time = time.Time{} - return h.handleProxy(ctx, rw, cc, req, ro2, log) + return h.handleProxy(ctx, conn, cc, req, ro2, log) } resp.StatusCode = http.StatusOK @@ -336,7 +340,7 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt dump, _ := httputil.DumpResponse(resp, false) log.Trace(string(dump)) } - if err = resp.Write(rw); err != nil { + if err = resp.Write(conn); err != nil { log.Error(err) return err } @@ -346,7 +350,7 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt conn.SetReadDeadline(time.Now().Add(h.md.sniffingTimeout)) } - br := bufio.NewReader(rw) + br := bufio.NewReader(conn) proto, _ := sniffing.Sniff(ctx, br) ro.Proto = proto @@ -371,7 +375,7 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt ReadTimeout: h.md.readTimeout, } - conn = xnet.NewReadWriteConn(br, rw, conn) + conn = xnet.NewReadWriteConn(br, conn, conn) switch proto { case sniffing.ProtoHTTP: return sniffer.HandleHTTP(ctx, conn, @@ -392,7 +396,7 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt start := time.Now() log.Infof("%s <-> %s", conn.RemoteAddr(), addr) - xnet.Transport(rw, cc) + xnet.Transport(conn, cc) log.WithFields(map[string]any{ "duration": time.Since(start), }).Infof("%s >-< %s", conn.RemoteAddr(), addr) diff --git a/handler/relay/connect.go b/handler/relay/connect.go index 3597290e..ce0f12d1 100644 --- a/handler/relay/connect.go +++ b/handler/relay/connect.go @@ -121,24 +121,28 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network } } - clientID := ctxvalue.ClientIDFromContext(ctx) - rw := traffic_wrapper.WrapReadWriter( - h.limiter, - conn, - string(clientID), - limiter.ScopeOption(limiter.ScopeClient), - limiter.ServiceOption(h.options.Service), - limiter.NetworkOption(network), - limiter.AddrOption(address), - limiter.ClientOption(string(clientID)), - limiter.SrcOption(conn.RemoteAddr().String()), - ) - if h.options.Observer != nil { - pstats := h.stats.Stats(string(clientID)) - pstats.Add(stats.KindTotalConns, 1) - pstats.Add(stats.KindCurrentConns, 1) - defer pstats.Add(stats.KindCurrentConns, -1) - rw = stats_wrapper.WrapReadWriter(rw, pstats) + { + clientID := ctxvalue.ClientIDFromContext(ctx) + rw := traffic_wrapper.WrapReadWriter( + h.limiter, + conn, + string(clientID), + limiter.ScopeOption(limiter.ScopeClient), + limiter.ServiceOption(h.options.Service), + limiter.NetworkOption(network), + limiter.AddrOption(address), + limiter.ClientOption(string(clientID)), + limiter.SrcOption(conn.RemoteAddr().String()), + ) + if h.options.Observer != nil { + pstats := h.stats.Stats(string(clientID)) + pstats.Add(stats.KindTotalConns, 1) + pstats.Add(stats.KindCurrentConns, 1) + defer pstats.Add(stats.KindCurrentConns, -1) + rw = stats_wrapper.WrapReadWriter(rw, pstats) + } + + conn = xnet.NewReadWriteConn(rw, rw, conn) } if h.md.sniffing { @@ -146,7 +150,7 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network conn.SetReadDeadline(time.Now().Add(h.md.sniffingTimeout)) } - br := bufio.NewReader(rw) + br := bufio.NewReader(conn) proto, _ := sniffing.Sniff(ctx, br) ro.Proto = proto @@ -171,7 +175,7 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network ReadTimeout: h.md.readTimeout, } - conn = xnet.NewReadWriteConn(br, rw, conn) + conn = xnet.NewReadWriteConn(br, conn, conn) switch proto { case sniffing.ProtoHTTP: return sniffer.HandleHTTP(ctx, conn, @@ -192,7 +196,7 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network t := time.Now() log.Infof("%s <-> %s", conn.RemoteAddr(), address) - xnet.Transport(rw, cc) + xnet.Transport(conn, cc) log.WithFields(map[string]any{ "duration": time.Since(t), }).Infof("%s >-< %s", conn.RemoteAddr(), address) diff --git a/handler/socks/v4/handler.go b/handler/socks/v4/handler.go index 68bf80a9..f6021d7f 100644 --- a/handler/socks/v4/handler.go +++ b/handler/socks/v4/handler.go @@ -230,24 +230,28 @@ func (h *socks4Handler) handleConnect(ctx context.Context, conn net.Conn, req *g return err } - clientID := ctxvalue.ClientIDFromContext(ctx) - rw := traffic_wrapper.WrapReadWriter( - h.limiter, - conn, - string(clientID), - limiter.ScopeOption(limiter.ScopeClient), - limiter.ServiceOption(h.options.Service), - limiter.NetworkOption("tcp"), - limiter.AddrOption(addr), - limiter.ClientOption(string(clientID)), - limiter.SrcOption(conn.RemoteAddr().String()), - ) - if h.options.Observer != nil { - pstats := h.stats.Stats(string(clientID)) - pstats.Add(stats.KindTotalConns, 1) - pstats.Add(stats.KindCurrentConns, 1) - defer pstats.Add(stats.KindCurrentConns, -1) - rw = stats_wrapper.WrapReadWriter(rw, pstats) + { + clientID := ctxvalue.ClientIDFromContext(ctx) + rw := traffic_wrapper.WrapReadWriter( + h.limiter, + conn, + string(clientID), + limiter.ScopeOption(limiter.ScopeClient), + limiter.ServiceOption(h.options.Service), + limiter.NetworkOption("tcp"), + limiter.AddrOption(addr), + limiter.ClientOption(string(clientID)), + limiter.SrcOption(conn.RemoteAddr().String()), + ) + if h.options.Observer != nil { + pstats := h.stats.Stats(string(clientID)) + pstats.Add(stats.KindTotalConns, 1) + pstats.Add(stats.KindCurrentConns, 1) + defer pstats.Add(stats.KindCurrentConns, -1) + rw = stats_wrapper.WrapReadWriter(rw, pstats) + } + + conn = xnet.NewReadWriteConn(rw, rw, conn) } if h.md.sniffing { @@ -255,7 +259,7 @@ func (h *socks4Handler) handleConnect(ctx context.Context, conn net.Conn, req *g conn.SetReadDeadline(time.Now().Add(h.md.sniffingTimeout)) } - br := bufio.NewReader(rw) + br := bufio.NewReader(conn) proto, _ := sniffing.Sniff(ctx, br) ro.Proto = proto @@ -280,7 +284,7 @@ func (h *socks4Handler) handleConnect(ctx context.Context, conn net.Conn, req *g ReadTimeout: h.md.readTimeout, } - conn = xnet.NewReadWriteConn(br, rw, conn) + conn = xnet.NewReadWriteConn(br, conn, conn) switch proto { case sniffing.ProtoHTTP: return sniffer.HandleHTTP(ctx, conn, @@ -301,7 +305,7 @@ func (h *socks4Handler) handleConnect(ctx context.Context, conn net.Conn, req *g t := time.Now() log.Infof("%s <-> %s", conn.RemoteAddr(), ro.Host) - xnet.Transport(rw, cc) + xnet.Transport(conn, cc) log.WithFields(map[string]any{ "duration": time.Since(t), }).Infof("%s >-< %s", conn.RemoteAddr(), ro.Host) diff --git a/handler/socks/v5/connect.go b/handler/socks/v5/connect.go index a8e6bb71..9389ff05 100644 --- a/handler/socks/v5/connect.go +++ b/handler/socks/v5/connect.go @@ -58,24 +58,28 @@ func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, networ return err } - clientID := ctxvalue.ClientIDFromContext(ctx) - rw := traffic_wrapper.WrapReadWriter( - h.limiter, - conn, - string(clientID), - limiter.ServiceOption(h.options.Service), - limiter.ScopeOption(limiter.ScopeClient), - limiter.NetworkOption(network), - limiter.AddrOption(address), - limiter.ClientOption(string(clientID)), - limiter.SrcOption(conn.RemoteAddr().String()), - ) - if h.options.Observer != nil { - pstats := h.stats.Stats(string(clientID)) - pstats.Add(stats.KindTotalConns, 1) - pstats.Add(stats.KindCurrentConns, 1) - defer pstats.Add(stats.KindCurrentConns, -1) - rw = stats_wrapper.WrapReadWriter(rw, pstats) + { + clientID := ctxvalue.ClientIDFromContext(ctx) + rw := traffic_wrapper.WrapReadWriter( + h.limiter, + conn, + string(clientID), + limiter.ServiceOption(h.options.Service), + limiter.ScopeOption(limiter.ScopeClient), + limiter.NetworkOption(network), + limiter.AddrOption(address), + limiter.ClientOption(string(clientID)), + limiter.SrcOption(conn.RemoteAddr().String()), + ) + if h.options.Observer != nil { + pstats := h.stats.Stats(string(clientID)) + pstats.Add(stats.KindTotalConns, 1) + pstats.Add(stats.KindCurrentConns, 1) + defer pstats.Add(stats.KindCurrentConns, -1) + rw = stats_wrapper.WrapReadWriter(rw, pstats) + } + + conn = xnet.NewReadWriteConn(rw, rw, conn) } if h.md.sniffing { @@ -83,7 +87,7 @@ func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, networ conn.SetReadDeadline(time.Now().Add(h.md.sniffingTimeout)) } - br := bufio.NewReader(rw) + br := bufio.NewReader(conn) proto, _ := sniffing.Sniff(ctx, br) ro.Proto = proto @@ -108,7 +112,7 @@ func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, networ ReadTimeout: h.md.readTimeout, } - conn = xnet.NewReadWriteConn(br, rw, conn) + conn = xnet.NewReadWriteConn(br, conn, conn) switch proto { case sniffing.ProtoHTTP: return sniffer.HandleHTTP(ctx, conn, @@ -129,7 +133,7 @@ func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, networ t := time.Now() log.Infof("%s <-> %s", conn.RemoteAddr(), address) - xnet.Transport(rw, cc) + xnet.Transport(conn, cc) log.WithFields(map[string]any{ "duration": time.Since(t), }).Infof("%s >-< %s", conn.RemoteAddr(), address) diff --git a/handler/tunnel/entrypoint.go b/handler/tunnel/entrypoint.go index 911da0e5..72c3966d 100644 --- a/handler/tunnel/entrypoint.go +++ b/handler/tunnel/entrypoint.go @@ -100,7 +100,9 @@ func (ep *entrypoint) Handle(ctx context.Context, conn net.Conn) (err error) { } log.WithFields(map[string]any{ - "duration": time.Since(ro.Time), + "duration": time.Since(ro.Time), + "inputBytes": ro.InputBytes, + "outputBytes": ro.OutputBytes, }).Infof("%s >< %s", conn.RemoteAddr(), conn.LocalAddr()) }() @@ -192,7 +194,9 @@ func (ep *entrypoint) httpRoundTrip(ctx context.Context, rw io.ReadWriter, req * } log.WithFields(map[string]any{ - "duration": time.Since(ro.Time), + "duration": time.Since(ro.Time), + "inputBytes": ro.InputBytes, + "outputBytes": ro.OutputBytes, }).Infof("%s >-< %s", ro.RemoteAddr, req.Host) }() diff --git a/internal/util/forwarder/sniffer.go b/internal/util/forwarder/sniffer.go index ccdd5f23..774b834e 100644 --- a/internal/util/forwarder/sniffer.go +++ b/internal/util/forwarder/sniffer.go @@ -364,7 +364,9 @@ func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriter, node } log.WithFields(map[string]any{ - "duration": time.Since(ro.Time), + "duration": time.Since(ro.Time), + "inputBytes": ro.InputBytes, + "outputBytes": ro.OutputBytes, }).Infof("%s >-< %s", ro.RemoteAddr, req.Host) }() diff --git a/internal/util/sniffing/sniffer.go b/internal/util/sniffing/sniffer.go index c4369154..47f498d6 100644 --- a/internal/util/sniffing/sniffer.go +++ b/internal/util/sniffing/sniffer.go @@ -272,7 +272,9 @@ func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriter, req * } log.WithFields(map[string]any{ - "duration": time.Since(ro.Time), + "duration": time.Since(ro.Time), + "inputBytes": ro.InputBytes, + "outputBytes": ro.OutputBytes, }).Infof("%s >-< %s", ro.RemoteAddr, req.Host) }()