From b5974678589ed4d469bb4f7aa407c9c208349e50 Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Mon, 4 Aug 2025 19:29:38 +0800 Subject: [PATCH] add context for conn --- admission/wrapper/conn.go | 42 +++++-------- admission/wrapper/listener.go | 16 ++++- auth/plugin/grpc.go | 4 +- auth/plugin/http.go | 4 +- chain/router.go | 9 +-- connector/http2/connector.go | 18 +++--- connector/router/connector.go | 10 +-- connector/tunnel/connector.go | 10 +-- ctx/value.go | 97 +++++------------------------ dialer/dtls/dialer.go | 6 +- dialer/grpc/dialer.go | 6 +- dialer/http2/conn.go | 10 ++- dialer/http2/dialer.go | 16 +++-- dialer/http2/h2/dialer.go | 13 ++-- dialer/mtcp/dialer.go | 6 +- dialer/mtls/dialer.go | 6 +- dialer/mws/dialer.go | 6 +- dialer/ssh/dialer.go | 6 +- dialer/sshd/dialer.go | 6 +- dialer/tcp/dialer.go | 6 +- dialer/tls/dialer.go | 6 +- dialer/udp/dialer.go | 6 +- dialer/ws/dialer.go | 6 +- handler/dns/handler.go | 20 +++--- handler/file/handler.go | 11 +++- handler/forward/local/handler.go | 43 ++++++------- handler/forward/remote/handler.go | 51 +++++++-------- handler/http/handler.go | 45 ++++++------- handler/http/udp.go | 6 +- handler/http2/handler.go | 46 +++++++------- handler/http3/handler.go | 30 +++++---- handler/redirect/tcp/handler.go | 27 ++++---- handler/redirect/udp/handler.go | 23 ++++--- handler/relay/bind.go | 4 +- handler/relay/connect.go | 13 ++-- handler/relay/forward.go | 7 ++- handler/relay/handler.go | 20 +++--- handler/router/handler.go | 11 ++-- handler/serial/handler.go | 5 +- handler/sni/handler.go | 23 ++++--- handler/socks/v4/handler.go | 31 +++++---- handler/socks/v5/bind.go | 6 +- handler/socks/v5/connect.go | 13 ++-- handler/socks/v5/handler.go | 22 +++---- handler/socks/v5/mbind.go | 6 +- handler/socks/v5/selector.go | 4 +- handler/socks/v5/udp.go | 5 +- handler/socks/v5/udp_tun.go | 11 ++-- handler/ss/handler.go | 27 ++++---- handler/ss/udp/handler.go | 20 +++--- handler/sshd/handler.go | 26 ++++---- handler/tap/handler.go | 14 +++-- handler/tun/handler.go | 9 +-- handler/tungo/handler.go | 9 +-- handler/tungo/stack.go | 49 +++++++-------- handler/tunnel/entrypoint.go | 57 ++++++++--------- handler/tunnel/handler.go | 17 +++-- hop/plugin/grpc.go | 10 ++- hop/plugin/http.go | 11 +++- internal/ctx/value.go | 70 +++++++++++++++++++-- internal/net/net.go | 8 --- internal/net/proxyproto/conn.go | 14 ++--- internal/net/proxyproto/listener.go | 15 ++++- internal/util/forwarder/sniffer.go | 28 +++------ internal/util/mux/mux.go | 32 +++------- internal/util/sniffing/sniffer.go | 25 +++----- internal/util/tls/listener.go | 24 ++----- internal/util/ws/ws.go | 35 ++++++----- limiter/conn/wrapper/conn.go | 17 ++--- limiter/traffic/wrapper/conn.go | 34 +++------- listener/grpc/server.go | 18 ++++-- listener/http2/conn.go | 21 +++---- listener/http2/h2/conn.go | 11 ++-- listener/http2/h2/listener.go | 44 ++++++++----- listener/http2/listener.go | 49 ++++++++++----- listener/http3/conn.go | 21 +++---- listener/http3/listener.go | 22 ++++--- listener/mws/listener.go | 15 +++-- listener/tap/conn.go | 20 +----- listener/tap/listener.go | 9 ++- listener/tun/conn.go | 20 +----- listener/tun/listener.go | 9 ++- listener/tungo/conn.go | 20 +----- listener/tungo/listener.go | 9 ++- listener/ws/listener.go | 13 +++- metrics/wrapper/conn.go | 43 +++++-------- observer/stats/wrapper/conn.go | 43 +++++-------- recorder/recorder.go | 19 +++--- selector/strategy.go | 6 +- service/service.go | 45 ++++++------- 90 files changed, 889 insertions(+), 917 deletions(-) diff --git a/admission/wrapper/conn.go b/admission/wrapper/conn.go index fee7f9f1..716ccc6e 100644 --- a/admission/wrapper/conn.go +++ b/admission/wrapper/conn.go @@ -8,7 +8,7 @@ import ( "syscall" "github.com/go-gost/core/admission" - "github.com/go-gost/core/metadata" + "github.com/go-gost/x/ctx" xio "github.com/go-gost/x/internal/io" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/net/udp" @@ -51,27 +51,6 @@ func (c *serverConn) SyscallConn() (rc syscall.RawConn, err error) { return } -func (c *serverConn) Metadata() metadata.Metadata { - if md, ok := c.Conn.(metadata.Metadatable); ok { - return md.Metadata() - } - return nil -} - -func (c *serverConn) SrcAddr() net.Addr { - if sc, ok := c.Conn.(xnet.SrcAddr); ok { - return sc.SrcAddr() - } - return nil -} - -func (c *serverConn) DstAddr() net.Addr { - if sc, ok := c.Conn.(xnet.DstAddr); ok { - return sc.DstAddr() - } - return nil -} - func (c *serverConn) CloseRead() error { if sc, ok := c.Conn.(xio.CloseRead); ok { return sc.CloseRead() @@ -86,6 +65,13 @@ func (c *serverConn) CloseWrite() error { return xio.ErrUnsupported } +func (c *serverConn) Context() context.Context { + if innerCtx, ok := c.Conn.(ctx.Context); ok { + return innerCtx.Context() + } + return nil +} + type packetConn struct { net.PacketConn admission admission.Admission @@ -117,9 +103,9 @@ func (c *packetConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) { } } -func (c *packetConn) Metadata() metadata.Metadata { - if md, ok := c.PacketConn.(metadata.Metadatable); ok { - return md.Metadata() +func (c *packetConn) Context() context.Context { + if innerCtx, ok := c.PacketConn.(ctx.Context); ok { + return innerCtx.Context() } return nil } @@ -263,9 +249,9 @@ func (c *udpConn) SetDSCP(n int) error { return nil } -func (c *udpConn) Metadata() metadata.Metadata { - if md, ok := c.PacketConn.(metadata.Metadatable); ok { - return md.Metadata() +func (c *udpConn) Context() context.Context { + if innerCtx, ok := c.PacketConn.(ctx.Context); ok { + return innerCtx.Context() } return nil } diff --git a/admission/wrapper/listener.go b/admission/wrapper/listener.go index 55d4e400..bb312d31 100644 --- a/admission/wrapper/listener.go +++ b/admission/wrapper/listener.go @@ -6,6 +6,7 @@ import ( "github.com/go-gost/core/admission" "github.com/go-gost/core/logger" + xctx "github.com/go-gost/x/ctx" ) type listener struct { @@ -30,8 +31,21 @@ func (ln *listener) Accept() (net.Conn, error) { if err != nil { return nil, err } + + ctx := context.Background() + if cc, ok := c.(xctx.Context); ok { + if cv := cc.Context(); cv != nil { + ctx = cv + } + } + + clientAddr := c.RemoteAddr() + if addr := xctx.SrcAddrFromContext(ctx); addr != nil { + clientAddr = addr + } + if ln.admission != nil && - !ln.admission.Admit(context.Background(), c.RemoteAddr().String()) { + !ln.admission.Admit(ctx, clientAddr.String()) { c.Close() continue } diff --git a/auth/plugin/grpc.go b/auth/plugin/grpc.go index bda08717..8e08d53c 100644 --- a/auth/plugin/grpc.go +++ b/auth/plugin/grpc.go @@ -7,7 +7,7 @@ import ( "github.com/go-gost/core/auth" "github.com/go-gost/core/logger" "github.com/go-gost/plugin/auth/proto" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/plugin" "google.golang.org/grpc" ) @@ -52,7 +52,7 @@ func (p *grpcPlugin) Authenticate(ctx context.Context, user, password string, op } var clientAddr string - if v := ctxvalue.SrcAddrFromContext(ctx); v != nil { + if v := xctx.SrcAddrFromContext(ctx); v != nil { clientAddr = v.String() } r, err := p.client.Authenticate(ctx, diff --git a/auth/plugin/http.go b/auth/plugin/http.go index b3e352a0..f2e30149 100644 --- a/auth/plugin/http.go +++ b/auth/plugin/http.go @@ -8,7 +8,7 @@ import ( "github.com/go-gost/core/auth" "github.com/go-gost/core/logger" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/plugin" ) @@ -54,7 +54,7 @@ func (p *httpPlugin) Authenticate(ctx context.Context, user, password string, op } var clientAddr string - if v := ctxvalue.SrcAddrFromContext(ctx); v != nil { + if v := xctx.SrcAddrFromContext(ctx); v != nil { clientAddr = v.String() } diff --git a/chain/router.go b/chain/router.go index cb5907b8..673b0846 100644 --- a/chain/router.go +++ b/chain/router.go @@ -10,7 +10,8 @@ import ( "github.com/go-gost/core/chain" "github.com/go-gost/core/logger" "github.com/go-gost/core/recorder" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" ) @@ -50,7 +51,7 @@ func (r *Router) Dial(ctx context.Context, network, address string) (conn net.Co r.record(ctx, recorder.RecorderServiceRouterDialAddress, []byte(host)) log := r.options.Logger.WithFields(map[string]any{ - "sid": ctxvalue.SidFromContext(ctx), + "sid": xctx.SidFromContext(ctx), }) conn, err = r.dial(ctx, network, address, log) @@ -96,7 +97,7 @@ func (r *Router) dial(ctx context.Context, network, address string, log logger.L defer cancel() } - buf := ctxvalue.BufferFromContext(ctx) + buf := ictx.BufferFromContext(ctx) if buf != nil { buf.Reset() } @@ -151,7 +152,7 @@ func (r *Router) Bind(ctx context.Context, network, address string, opts ...chai } log := r.options.Logger.WithFields(map[string]any{ - "sid": ctxvalue.SidFromContext(ctx), + "sid": xctx.SidFromContext(ctx), }) log.Debugf("bind on %s/%s", address, network) diff --git a/connector/http2/connector.go b/connector/http2/connector.go index 8629c145..efbd2345 100644 --- a/connector/http2/connector.go +++ b/connector/http2/connector.go @@ -15,7 +15,8 @@ import ( "github.com/go-gost/core/connector" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" "github.com/go-gost/x/registry" ) @@ -49,12 +50,17 @@ func (c *http2Connector) Connect(ctx context.Context, conn net.Conn, network, ad "remote": conn.RemoteAddr().String(), "network": network, "address": address, - "sid": string(ctxvalue.SidFromContext(ctx)), + "sid": string(xctx.SidFromContext(ctx)), }) log.Debugf("connect %s/%s", address, network) - v, _ := conn.(md.Metadatable) - if v == nil { + var client *http.Client + if cc, ok := conn.(xctx.Context); ok { + if md := ictx.MetadataFromContext(cc.Context()); md != nil { + client, _ = md.Get("client").(*http.Client) + } + } + if client == nil { err := errors.New("http2: wrong connection type") log.Error(err) return nil, err @@ -69,7 +75,6 @@ func (c *http2Connector) Connect(ctx context.Context, conn net.Conn, network, ad ProtoMinor: 0, Header: c.md.header, Body: pr, - // ContentLength: -1, } if req.Header == nil { req.Header = make(http.Header) @@ -92,8 +97,7 @@ func (c *http2Connector) Connect(ctx context.Context, conn net.Conn, network, ad defer conn.SetDeadline(time.Time{}) } - client := v.Metadata().Get("client").(*http.Client) - resp, err := client.Do(req) + resp, err := client.Do(req.WithContext(ictx.Copy(ctx))) if err != nil { log.Error(err) conn.Close() diff --git a/connector/router/connector.go b/connector/router/connector.go index 65796223..66f40bfa 100644 --- a/connector/router/connector.go +++ b/connector/router/connector.go @@ -9,7 +9,7 @@ import ( "github.com/go-gost/core/connector" md "github.com/go-gost/core/metadata" "github.com/go-gost/relay" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/registry" ) @@ -39,11 +39,11 @@ func (c *routerConnector) Init(md md.Metadata) (err error) { func (c *routerConnector) Connect(ctx context.Context, conn net.Conn, network, address string, opts ...connector.ConnectOption) (net.Conn, error) { log := c.options.Logger.WithFields(map[string]any{ - "remote": conn.RemoteAddr().String(), - "local": conn.LocalAddr().String(), "network": network, "address": address, - "sid": string(ctxvalue.SidFromContext(ctx)), + "remote": conn.RemoteAddr().String(), + "local": conn.LocalAddr().String(), + "sid": xctx.SidFromContext(ctx).String(), }) log.Debugf("connect %s/%s", address, network) @@ -78,7 +78,7 @@ func (c *routerConnector) Connect(ctx context.Context, conn net.Conn, network, a } srcAddr := conn.RemoteAddr().String() - if v := ctxvalue.SrcAddrFromContext(ctx); v != nil { + if v := xctx.SrcAddrFromContext(ctx); v != nil { srcAddr = v.String() } diff --git a/connector/tunnel/connector.go b/connector/tunnel/connector.go index 76f9f6a6..94899335 100644 --- a/connector/tunnel/connector.go +++ b/connector/tunnel/connector.go @@ -9,7 +9,7 @@ import ( "github.com/go-gost/core/connector" md "github.com/go-gost/core/metadata" "github.com/go-gost/relay" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/registry" ) @@ -39,11 +39,11 @@ func (c *tunnelConnector) Init(md md.Metadata) (err error) { func (c *tunnelConnector) Connect(ctx context.Context, conn net.Conn, network, address string, opts ...connector.ConnectOption) (net.Conn, error) { log := c.options.Logger.WithFields(map[string]any{ - "remote": conn.RemoteAddr().String(), - "local": conn.LocalAddr().String(), "network": network, "address": address, - "sid": string(ctxvalue.SidFromContext(ctx)), + "remote": conn.RemoteAddr().String(), + "local": conn.LocalAddr().String(), + "sid": xctx.SidFromContext(ctx).String(), }) log.Debugf("connect %s/%s", address, network) @@ -74,7 +74,7 @@ func (c *tunnelConnector) Connect(ctx context.Context, conn net.Conn, network, a } srcAddr := conn.RemoteAddr().String() - if v := ctxvalue.SrcAddrFromContext(ctx); v != nil { + if v := xctx.SrcAddrFromContext(ctx); v != nil { srcAddr = v.String() } diff --git a/ctx/value.go b/ctx/value.go index 60dda25d..4774bd7d 100644 --- a/ctx/value.go +++ b/ctx/value.go @@ -1,58 +1,37 @@ package ctx import ( - "bytes" "context" "net" - - "github.com/go-gost/core/logger" ) -type ClientAddr string - -func (a ClientAddr) String() string { - return string(a) +type Context interface { + Context() context.Context } -// clientAddrKey saves the client address. -type clientAddrKey struct{} - -var keyClientAddr clientAddrKey - -func ContextWithClientAddr(ctx context.Context, addr ClientAddr) context.Context { - return context.WithValue(ctx, keyClientAddr, addr) +type WithContext interface { + WithContext(ctx context.Context) } -func ClientAddrFromContext(ctx context.Context) ClientAddr { - v, _ := ctx.Value(keyClientAddr).(ClientAddr) - return v -} - -type ( - srcAddrKey struct{} - dstAddrKey struct{} -) - -var ( - keySrcAddr srcAddrKey - keyDstAddr dstAddrKey -) +type srcAddrKey struct{} func ContextWithSrcAddr(ctx context.Context, addr net.Addr) context.Context { - return context.WithValue(ctx, keySrcAddr, addr) + return context.WithValue(ctx, srcAddrKey{}, addr) } func SrcAddrFromContext(ctx context.Context) net.Addr { - v, _ := ctx.Value(keySrcAddr).(net.Addr) + v, _ := ctx.Value(srcAddrKey{}).(net.Addr) return v } +type dstAddrKey struct{} + func ContextWithDstAddr(ctx context.Context, addr net.Addr) context.Context { - return context.WithValue(ctx, keyDstAddr, addr) + return context.WithValue(ctx, dstAddrKey{}, addr) } func DstAddrFromContext(ctx context.Context) net.Addr { - v, _ := ctx.Value(keyDstAddr).(net.Addr) + v, _ := ctx.Value(dstAddrKey{}).(net.Addr) return v } @@ -66,16 +45,12 @@ func (s Sid) String() string { return string(s) } -var ( - keySid sidKey -) - func ContextWithSid(ctx context.Context, sid Sid) context.Context { - return context.WithValue(ctx, keySid, sid) + return context.WithValue(ctx, sidKey{}, sid) } func SidFromContext(ctx context.Context) Sid { - v, _ := ctx.Value(keySid).(Sid) + v, _ := ctx.Value(sidKey{}).(Sid) return v } @@ -87,16 +62,12 @@ type ( } ) -var ( - clientHashKey = &hashKey{} -) - func ContextWithHash(ctx context.Context, hash *Hash) context.Context { - return context.WithValue(ctx, clientHashKey, hash) + return context.WithValue(ctx, hashKey{}, hash) } func HashFromContext(ctx context.Context) *Hash { - if v, _ := ctx.Value(clientHashKey).(*Hash); v != nil { + if v, _ := ctx.Value(hashKey{}).(*Hash); v != nil { return v } return nil @@ -111,45 +82,11 @@ func (s ClientID) String() string { return string(s) } -var ( - keyClientID = &clientIDKey{} -) - func ContextWithClientID(ctx context.Context, clientID ClientID) context.Context { - return context.WithValue(ctx, keyClientID, clientID) + return context.WithValue(ctx, clientIDKey{}, clientID) } func ClientIDFromContext(ctx context.Context) ClientID { - v, _ := ctx.Value(keyClientID).(ClientID) - return v -} - -type bufferKey struct{} - -var ( - keyBuffer = &bufferKey{} -) - -func ContextWithBuffer(ctx context.Context, buffer *bytes.Buffer) context.Context { - return context.WithValue(ctx, keyBuffer, buffer) -} - -func BufferFromContext(ctx context.Context) *bytes.Buffer { - v, _ := ctx.Value(keyBuffer).(*bytes.Buffer) - return v -} - -type loggerKey struct{} - -var ( - keyLogger = &loggerKey{} -) - -func ContextWithLogger(ctx context.Context, log logger.Logger) context.Context { - return context.WithValue(ctx, keyLogger, log) -} - -func LoggerFromContext(ctx context.Context) logger.Logger { - v, _ := ctx.Value(keyLogger).(logger.Logger) + v, _ := ctx.Value(clientIDKey{}).(ClientID) return v } diff --git a/dialer/dtls/dialer.go b/dialer/dtls/dialer.go index 433e7b4b..cff0b876 100644 --- a/dialer/dtls/dialer.go +++ b/dialer/dtls/dialer.go @@ -8,7 +8,7 @@ import ( "github.com/go-gost/core/dialer" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/net/proxyproto" xdtls "github.com/go-gost/x/internal/util/dtls" "github.com/go-gost/x/registry" @@ -54,8 +54,8 @@ func (d *dtlsDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialO conn = proxyproto.WrapClientConn( d.options.ProxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), conn) tlsCfg := d.options.TLSConfig diff --git a/dialer/grpc/dialer.go b/dialer/grpc/dialer.go index c2c284ce..aaa4cb18 100644 --- a/dialer/grpc/dialer.go +++ b/dialer/grpc/dialer.go @@ -7,7 +7,7 @@ import ( "github.com/go-gost/core/dialer" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/net/proxyproto" pb "github.com/go-gost/x/internal/util/grpc/proto" "github.com/go-gost/x/registry" @@ -80,8 +80,8 @@ func (d *grpcDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialO conn = proxyproto.WrapClientConn( d.options.ProxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), conn) return conn, nil diff --git a/dialer/http2/conn.go b/dialer/http2/conn.go index 2d58e106..5bbef009 100644 --- a/dialer/http2/conn.go +++ b/dialer/http2/conn.go @@ -1,11 +1,10 @@ package http2 import ( + "context" "errors" "net" "time" - - mdata "github.com/go-gost/core/metadata" ) // a dummy HTTP2 client conn used by HTTP2 client connector @@ -13,7 +12,7 @@ type conn struct { localAddr net.Addr remoteAddr net.Addr onClose func() - md mdata.Metadata + ctx context.Context } func (c *conn) Close() error { @@ -51,7 +50,6 @@ func (c *conn) SetWriteDeadline(t time.Time) error { return &net.OpError{Op: "set", Net: "nop", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} } -// Metadata implements metadata.Metadatable interface. -func (c *conn) Metadata() mdata.Metadata { - return c.md +func (c *conn) Context() context.Context { + return c.ctx } diff --git a/dialer/http2/dialer.go b/dialer/http2/dialer.go index 5b3f2abb..9f0fff28 100644 --- a/dialer/http2/dialer.go +++ b/dialer/http2/dialer.go @@ -10,7 +10,8 @@ import ( "github.com/go-gost/core/dialer" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" net_dialer "github.com/go-gost/x/internal/net/dialer" "github.com/go-gost/x/internal/net/proxyproto" mdx "github.com/go-gost/x/metadata" @@ -25,7 +26,6 @@ type http2Dialer struct { clients map[string]*http.Client clientMutex sync.Mutex logger logger.Logger - md metadata options dialer.Options } @@ -100,8 +100,8 @@ func (d *http2Dialer) Dial(ctx context.Context, address string, opts ...dialer.D conn = proxyproto.WrapClientConn( d.options.ProxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), conn) return conn, nil @@ -116,7 +116,7 @@ func (d *http2Dialer) Dial(ctx context.Context, address string, opts ...dialer.D d.clients[address] = client } - var c net.Conn = &conn{ + return &conn{ localAddr: &net.TCPAddr{}, remoteAddr: raddr, onClose: func() { @@ -124,8 +124,6 @@ func (d *http2Dialer) Dial(ctx context.Context, address string, opts ...dialer.D defer d.clientMutex.Unlock() delete(d.clients, address) }, - md: mdx.NewMetadata(map[string]any{"client": client}), - } - - return c, nil + ctx: ictx.ContextWithMetadata(ctx, mdx.NewMetadata(map[string]any{"client": client})), + }, nil } diff --git a/dialer/http2/h2/dialer.go b/dialer/http2/h2/dialer.go index 84fb9fa1..ebe50d63 100644 --- a/dialer/http2/h2/dialer.go +++ b/dialer/http2/h2/dialer.go @@ -15,7 +15,8 @@ import ( "github.com/go-gost/core/dialer" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" "github.com/go-gost/x/internal/net/proxyproto" "github.com/go-gost/x/registry" "golang.org/x/net/http2" @@ -103,8 +104,8 @@ func (d *h2Dialer) Dial(ctx context.Context, address string, opts ...dialer.Dial conn = proxyproto.WrapClientConn( d.options.ProxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), conn) return conn, nil @@ -121,8 +122,8 @@ func (d *h2Dialer) Dial(ctx context.Context, address string, opts ...dialer.Dial conn = proxyproto.WrapClientConn( d.options.ProxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), conn) return conn, nil @@ -169,7 +170,7 @@ func (d *h2Dialer) Dial(ctx context.Context, address string, opts ...dialer.Dial d.logger.Trace(string(dump)) } - resp, err := client.Do(req) + resp, err := client.Do(req.WithContext(ictx.Copy(ctx))) if err != nil { return nil, err } diff --git a/dialer/mtcp/dialer.go b/dialer/mtcp/dialer.go index efcbdad5..3c563d56 100644 --- a/dialer/mtcp/dialer.go +++ b/dialer/mtcp/dialer.go @@ -10,7 +10,7 @@ import ( "github.com/go-gost/core/dialer" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/net/proxyproto" "github.com/go-gost/x/internal/util/mux" "github.com/go-gost/x/registry" @@ -76,8 +76,8 @@ func (d *mtcpDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialO conn = proxyproto.WrapClientConn( d.options.ProxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), conn) session = &muxSession{conn: conn} diff --git a/dialer/mtls/dialer.go b/dialer/mtls/dialer.go index ec2f96d8..b19c2f13 100644 --- a/dialer/mtls/dialer.go +++ b/dialer/mtls/dialer.go @@ -11,7 +11,7 @@ import ( "github.com/go-gost/core/dialer" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/net/proxyproto" "github.com/go-gost/x/internal/util/mux" "github.com/go-gost/x/registry" @@ -77,8 +77,8 @@ func (d *mtlsDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialO conn = proxyproto.WrapClientConn( d.options.ProxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), conn) session = &muxSession{conn: conn} diff --git a/dialer/mws/dialer.go b/dialer/mws/dialer.go index a61310d6..b0a75f1b 100644 --- a/dialer/mws/dialer.go +++ b/dialer/mws/dialer.go @@ -11,7 +11,7 @@ import ( "github.com/go-gost/core/dialer" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/net/proxyproto" "github.com/go-gost/x/internal/util/mux" ws_util "github.com/go-gost/x/internal/util/ws" @@ -91,8 +91,8 @@ func (d *mwsDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOp conn = proxyproto.WrapClientConn( d.options.ProxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), conn) session = &muxSession{conn: conn} diff --git a/dialer/ssh/dialer.go b/dialer/ssh/dialer.go index 8e03d570..63a6c1e7 100644 --- a/dialer/ssh/dialer.go +++ b/dialer/ssh/dialer.go @@ -8,7 +8,7 @@ import ( "github.com/go-gost/core/dialer" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/net/proxyproto" ssh_util "github.com/go-gost/x/internal/util/ssh" "github.com/go-gost/x/registry" @@ -77,8 +77,8 @@ func (d *sshDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOp conn = proxyproto.WrapClientConn( d.options.ProxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), conn) session, err = d.initSession(ctx, addr, conn) diff --git a/dialer/sshd/dialer.go b/dialer/sshd/dialer.go index 2c1410ff..124cc20f 100644 --- a/dialer/sshd/dialer.go +++ b/dialer/sshd/dialer.go @@ -9,7 +9,7 @@ import ( "github.com/go-gost/core/dialer" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/net/proxyproto" ssh_util "github.com/go-gost/x/internal/util/ssh" "github.com/go-gost/x/registry" @@ -80,8 +80,8 @@ func (d *sshdDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialO conn = proxyproto.WrapClientConn( d.options.ProxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), conn) session, err = d.initSession(ctx, addr, conn) diff --git a/dialer/tcp/dialer.go b/dialer/tcp/dialer.go index 85ee6d6b..83af2539 100644 --- a/dialer/tcp/dialer.go +++ b/dialer/tcp/dialer.go @@ -7,7 +7,7 @@ import ( "github.com/go-gost/core/dialer" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/net/proxyproto" "github.com/go-gost/x/registry" ) @@ -51,8 +51,8 @@ func (d *tcpDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOp conn = proxyproto.WrapClientConn( d.options.ProxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), conn) return conn, err diff --git a/dialer/tls/dialer.go b/dialer/tls/dialer.go index 49ccaa5f..07e2c247 100644 --- a/dialer/tls/dialer.go +++ b/dialer/tls/dialer.go @@ -9,7 +9,7 @@ import ( "github.com/go-gost/core/dialer" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/net/proxyproto" "github.com/go-gost/x/registry" ) @@ -53,8 +53,8 @@ func (d *tlsDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOp conn = proxyproto.WrapClientConn( d.options.ProxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), conn) return conn, err diff --git a/dialer/udp/dialer.go b/dialer/udp/dialer.go index 242410d4..f6ee976f 100644 --- a/dialer/udp/dialer.go +++ b/dialer/udp/dialer.go @@ -7,7 +7,7 @@ import ( "github.com/go-gost/core/dialer" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/net/proxyproto" "github.com/go-gost/x/registry" ) @@ -55,8 +55,8 @@ func (d *udpDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOp c = proxyproto.WrapClientConn( d.options.ProxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), c) return c, nil diff --git a/dialer/ws/dialer.go b/dialer/ws/dialer.go index 44008bda..a0f1617c 100644 --- a/dialer/ws/dialer.go +++ b/dialer/ws/dialer.go @@ -8,7 +8,7 @@ import ( "github.com/go-gost/core/dialer" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/net/proxyproto" ws_util "github.com/go-gost/x/internal/util/ws" "github.com/go-gost/x/registry" @@ -66,8 +66,8 @@ func (d *wsDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOpt conn = proxyproto.WrapClientConn( d.options.ProxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), conn) return conn, err diff --git a/handler/dns/handler.go b/handler/dns/handler.go index 4df1891d..95fccdd6 100644 --- a/handler/dns/handler.go +++ b/handler/dns/handler.go @@ -18,8 +18,9 @@ import ( md "github.com/go-gost/core/metadata" "github.com/go-gost/core/observer/stats" "github.com/go-gost/core/recorder" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" xhop "github.com/go-gost/x/hop" + ictx "github.com/go-gost/x/internal/ctx" resolver_util "github.com/go-gost/x/internal/util/resolver" rate_limiter "github.com/go-gost/x/limiter/rate" xstats "github.com/go-gost/x/observer/stats" @@ -145,18 +146,19 @@ func (h *dnsHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. Host: conn.LocalAddr().String(), Proto: "dns", Time: start, - SID: string(ctxvalue.SidFromContext(ctx)), + SID: xctx.SidFromContext(ctx).String(), } - if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil { - ro.ClientIP = srcAddr.String() + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { + ro.ClientAddr = srcAddr.String() } log := h.options.Logger.WithFields(map[string]any{ - "remote": conn.RemoteAddr().String(), - "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), - "client": ro.ClientIP, + "network": ro.Network, + "remote": conn.RemoteAddr().String(), + "local": conn.LocalAddr().String(), + "client": ro.ClientAddr, + "sid": ro.SID, }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) @@ -310,7 +312,7 @@ func (h *dnsHandler) request(ctx context.Context, msg []byte, ro *xrecorder.Hand log.Debugf("exchange message %d: %s", mq.Id, mq.Question[0].String()) var buf bytes.Buffer - mr, err := h.exchange(ctxvalue.ContextWithBuffer(ctx, &buf), ex, &mq) + mr, err := h.exchange(ictx.ContextWithBuffer(ctx, &buf), ex, &mq) ro.Route = buf.String() if err != nil { return nil, err diff --git a/handler/file/handler.go b/handler/file/handler.go index 201453f7..52a86a99 100644 --- a/handler/file/handler.go +++ b/handler/file/handler.go @@ -4,13 +4,15 @@ import ( "context" "net" "net/http" + "net/http/httputil" "sync" "time" "github.com/go-gost/core/handler" + "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" "github.com/go-gost/core/recorder" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" xrecorder "github.com/go-gost/x/recorder" "github.com/go-gost/x/registry" ) @@ -67,7 +69,7 @@ func (h *fileHandler) Init(md md.Metadata) (err error) { func (h *fileHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.HandleOption) error { var clientAddr string - if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil { + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { clientAddr = srcAddr.String() } @@ -113,6 +115,11 @@ func (h *fileHandler) handleFunc(w http.ResponseWriter, r *http.Request) { "remote": r.RemoteAddr, }) + if log.IsLevelEnabled(logger.TraceLevel) { + dump, _ := httputil.DumpRequest(r, false) + log.Trace(string(dump)) + } + rw := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK} defer func() { diff --git a/handler/forward/local/handler.go b/handler/forward/local/handler.go index 9c933582..0d2b9b18 100644 --- a/handler/forward/local/handler.go +++ b/handler/forward/local/handler.go @@ -14,7 +14,8 @@ import ( md "github.com/go-gost/core/metadata" "github.com/go-gost/core/observer/stats" "github.com/go-gost/core/recorder" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/net/proxyproto" "github.com/go-gost/x/internal/util/forwarder" @@ -87,28 +88,28 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand LocalAddr: conn.LocalAddr().String(), Network: "tcp", Time: start, - SID: string(ctxvalue.SidFromContext(ctx)), + SID: xctx.SidFromContext(ctx).String(), } - if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil { - ro.ClientIP = srcAddr.String() + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { + ro.ClientAddr = srcAddr.String() } - log := h.options.Logger.WithFields(map[string]any{ - "network": ro.Network, - "remote": conn.RemoteAddr().String(), - "local": conn.LocalAddr().String(), - "sid": ro.SID, - "client": ro.ClientIP, - }) - log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) - network := "tcp" if _, ok := conn.(net.PacketConn); ok { network = "udp" } ro.Network = network + log := h.options.Logger.WithFields(map[string]any{ + "network": ro.Network, + "remote": conn.RemoteAddr().String(), + "local": conn.LocalAddr().String(), + "client": ro.ClientAddr, + "sid": ro.SID, + }) + log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) + pStats := xstats.Stats{} conn = stats_wrapper.WrapConn(conn, &pStats) @@ -150,13 +151,13 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand dial := func(ctx context.Context, network, address string) (net.Conn, error) { var buf bytes.Buffer - cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", address) + cc, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", address) ro.Route = buf.String() cc = proxyproto.WrapClientConn( h.md.proxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), cc) return cc, err @@ -232,7 +233,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand log.Debugf("%s >> %s", conn.RemoteAddr(), addr) var buf bytes.Buffer - cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), network, addr) + cc, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), network, addr) ro.Route = buf.String() if err != nil { log.Error(err) @@ -250,13 +251,13 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand cc = proxyproto.WrapClientConn( h.md.proxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), cc) log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() t := time.Now() log.Infof("%s <-> %s", conn.RemoteAddr(), target.Addr) diff --git a/handler/forward/remote/handler.go b/handler/forward/remote/handler.go index 997d6da4..b39cddeb 100644 --- a/handler/forward/remote/handler.go +++ b/handler/forward/remote/handler.go @@ -14,7 +14,8 @@ import ( mdata "github.com/go-gost/core/metadata" "github.com/go-gost/core/observer/stats" "github.com/go-gost/core/recorder" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/net/proxyproto" "github.com/go-gost/x/internal/util/forwarder" @@ -87,27 +88,28 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand LocalAddr: conn.LocalAddr().String(), Network: "tcp", Time: start, - SID: string(ctxvalue.SidFromContext(ctx)), + SID: xctx.SidFromContext(ctx).String(), } - if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil { - ro.ClientIP = srcAddr.String() + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { + ro.ClientAddr = srcAddr.String() } - log := h.options.Logger.WithFields(map[string]any{ - "remote": conn.RemoteAddr().String(), - "local": conn.LocalAddr().String(), - "sid": ro.SID, - "client": ro.ClientIP, - }) - log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) - network := "tcp" if _, ok := conn.(net.PacketConn); ok { network = "udp" } ro.Network = network + log := h.options.Logger.WithFields(map[string]any{ + "network": ro.Network, + "remote": conn.RemoteAddr().String(), + "local": conn.LocalAddr().String(), + "client": ro.ClientAddr, + "sid": ro.SID, + }) + log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) + pStats := xstats.Stats{} conn = stats_wrapper.WrapConn(conn, &pStats) @@ -133,13 +135,6 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand return rate_limiter.ErrRateLimit } - var host string - if md, ok := conn.(mdata.Metadatable); ok { - if v := mdutil.GetString(md.Metadata(), "host"); v != "" { - host = v - } - } - var proto string if network == "tcp" && h.md.sniffing { if h.md.sniffingTimeout > 0 { @@ -156,13 +151,13 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand dial := func(ctx context.Context, network, address string) (net.Conn, error) { var buf bytes.Buffer - cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", address) + cc, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", address) ro.Route = buf.String() cc = proxyproto.WrapClientConn( h.md.proxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), cc) return cc, err @@ -203,7 +198,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand } var target *chain.Node - if host != "" { + if host := mdutil.GetString(ictx.MetadataFromContext(ctx), "host"); host != "" { target = &chain.Node{ Addr: host, } @@ -239,7 +234,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand log.Debugf("%s >> %s", conn.RemoteAddr(), target.Addr) var buf bytes.Buffer - cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), network, target.Addr) + cc, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), network, target.Addr) ro.Route = buf.String() if err != nil { log.Error(err) @@ -256,13 +251,13 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand } log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() cc = proxyproto.WrapClientConn( h.md.proxyProtocol, - ctxvalue.SrcAddrFromContext(ctx), - ctxvalue.DstAddrFromContext(ctx), + xctx.SrcAddrFromContext(ctx), + xctx.DstAddrFromContext(ctx), cc) t := time.Now() diff --git a/handler/http/handler.go b/handler/http/handler.go index 0f3c5429..4e089394 100644 --- a/handler/http/handler.go +++ b/handler/http/handler.go @@ -30,8 +30,8 @@ import ( "github.com/go-gost/core/observer/stats" "github.com/go-gost/core/recorder" xbypass "github.com/go-gost/x/bypass" - ctxvalue "github.com/go-gost/x/ctx" - ctx_internal "github.com/go-gost/x/internal/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xio "github.com/go-gost/x/internal/io" xnet "github.com/go-gost/x/internal/net" xhttp "github.com/go-gost/x/internal/net/http" @@ -130,18 +130,19 @@ func (h *httpHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler LocalAddr: conn.LocalAddr().String(), Proto: "http", Time: start, - SID: string(ctxvalue.SidFromContext(ctx)), + SID: xctx.SidFromContext(ctx).String(), } - if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil { - ro.ClientIP = srcAddr.String() + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { + ro.ClientAddr = srcAddr.String() } log := h.options.Logger.WithFields(map[string]any{ - "remote": conn.RemoteAddr().String(), - "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), - "client": ro.ClientIP, + "network": ro.Network, + "remote": conn.RemoteAddr().String(), + "local": conn.LocalAddr().String(), + "client": ro.ClientAddr, + "sid": ro.SID, }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) @@ -292,7 +293,7 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt resp.Header.Set("Proxy-Agent", h.md.proxyAgent) } - ctx = ctxvalue.ContextWithClientID(ctx, ctxvalue.ClientID(clientID)) + ctx = xctx.ContextWithClientID(ctx, xctx.ClientID(clientID)) if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, network, addr) { @@ -338,8 +339,8 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt return h.handleProxy(ctx, conn, req, ro, log) } - ctx = ctx_internal.ContextWithRecorderObject(ctx, ro) - ctx = ctxvalue.ContextWithLogger(ctx, log) + ctx = ictx.ContextWithRecorderObject(ctx, ro) + ctx = ictx.ContextWithLogger(ctx, log) cc, err := h.dial(ctx, "tcp", addr) if err != nil { @@ -355,8 +356,8 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt defer cc.Close() log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() b := []byte("HTTP/1.1 200 Connection established\r\n" + "Proxy-Agent: " + h.md.proxyAgent + "\r\n\r\n") @@ -565,8 +566,8 @@ func (h *httpHandler) proxyRoundTrip(ctx context.Context, rw io.ReadWriteCloser, } } - ctx = ctx_internal.ContextWithRecorderObject(ctx, ro) - ctx = ctxvalue.ContextWithLogger(ctx, log) + ctx = ictx.ContextWithRecorderObject(ctx, ro) + ctx = ictx.ContextWithLogger(ctx, log) resp, err := h.transport.RoundTrip(req.WithContext(ctx)) @@ -639,21 +640,21 @@ func (h *httpHandler) proxyRoundTrip(ctx context.Context, rw io.ReadWriteCloser, func (h *httpHandler) dial(ctx context.Context, network, addr string) (conn net.Conn, err error) { switch h.md.hash { case "host": - ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: addr}) + ctx = xctx.ContextWithHash(ctx, &xctx.Hash{Source: addr}) } - if log := ctxvalue.LoggerFromContext(ctx); log != nil { + if log := ictx.LoggerFromContext(ctx); log != nil { log.Debugf("dial: new connection to host %s", addr) } var buf bytes.Buffer - conn, err = h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), network, addr) - if ro := ctx_internal.RecorderObjectFromContext(ctx); ro != nil { + conn, err = h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), network, addr) + if ro := ictx.RecorderObjectFromContext(ctx); ro != nil { ro.Route = buf.String() if conn != nil { - ro.Src = conn.LocalAddr().String() - ro.Dst = conn.RemoteAddr().String() + ro.SrcAddr = conn.LocalAddr().String() + ro.DstAddr = conn.RemoteAddr().String() } } diff --git a/handler/http/udp.go b/handler/http/udp.go index dc8aecfb..4fe52303 100644 --- a/handler/http/udp.go +++ b/handler/http/udp.go @@ -10,7 +10,7 @@ import ( "time" "github.com/go-gost/core/logger" - ctxvalue "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" "github.com/go-gost/x/internal/net/udp" "github.com/go-gost/x/internal/util/socks" xrecorder "github.com/go-gost/x/recorder" @@ -55,7 +55,7 @@ func (h *httpHandler) handleUDP(ctx context.Context, conn net.Conn, ro *xrecorde // obtain a udp connection var buf bytes.Buffer - c, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "udp", "") // UDP association + c, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "udp", "") // UDP association ro.Route = buf.String() if err != nil { log.Error(err) @@ -64,7 +64,7 @@ func (h *httpHandler) handleUDP(ctx context.Context, conn net.Conn, ro *xrecorde defer c.Close() log.WithFields(map[string]any{"src": c.LocalAddr().String()}) - ro.Src = c.LocalAddr().String() + ro.SrcAddr = c.LocalAddr().String() pc, ok := c.(net.PacketConn) if !ok { diff --git a/handler/http2/handler.go b/handler/http2/handler.go index 7d8e8b83..75adbffa 100644 --- a/handler/http2/handler.go +++ b/handler/http2/handler.go @@ -27,7 +27,8 @@ import ( "github.com/go-gost/core/observer/stats" "github.com/go-gost/core/recorder" xbypass "github.com/go-gost/x/bypass" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xio "github.com/go-gost/x/internal/io" xnet "github.com/go-gost/x/internal/net" xhttp "github.com/go-gost/x/internal/net/http" @@ -106,18 +107,18 @@ func (h *http2Handler) Handle(ctx context.Context, conn net.Conn, opts ...handle LocalAddr: conn.LocalAddr().String(), Network: "tcp", Time: start, - SID: string(ctxvalue.SidFromContext(ctx)), + SID: xctx.SidFromContext(ctx).String(), } - if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil { - ro.ClientIP = srcAddr.String() + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { + ro.ClientAddr = srcAddr.String() } log := h.options.Logger.WithFields(map[string]any{ + "network": ro.Network, "remote": conn.RemoteAddr().String(), "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), - "client": ro.ClientIP, - "network": ro.Network, + "client": ro.ClientAddr, + "sid": ro.SID, }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) defer func() { @@ -136,20 +137,17 @@ func (h *http2Handler) Handle(ctx context.Context, conn net.Conn, opts ...handle return rate_limiter.ErrRateLimit } - v, ok := conn.(md.Metadatable) - if !ok || v == nil { - err = errors.New("wrong connection type") + md := ictx.MetadataFromContext(ctx) + if md == nil { + err = errors.New("http2: wrong connection type") log.Error(err) return err } - md := v.Metadata() - return h.roundTrip(ctx, - md.Get("w").(http.ResponseWriter), - md.Get("r").(*http.Request), - ro, - log, - ) + w, _ := md.Get("w").(http.ResponseWriter) + r, _ := md.Get("r").(*http.Request) + + return h.roundTrip(ctx, w, r, ro, log) } func (h *http2Handler) Close() error { @@ -163,6 +161,10 @@ func (h *http2Handler) Close() error { // when server returns an non-200 status code, // May be fixed in go1.18. func (h *http2Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req *http.Request, ro *xrecorder.HandlerRecorderObject, log logger.Logger) error { + if w == nil || req == nil { + return nil + } + // Try to get the actual host. // Compatible with GOST 2.x. if v := req.Header.Get("Gost-Target"); v != "" { @@ -237,7 +239,7 @@ func (h *http2Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req log = log.WithFields(map[string]any{"clientID": clientID}) ro.ClientID = clientID - ctx = ctxvalue.ContextWithClientID(ctx, ctxvalue.ClientID(clientID)) + ctx = xctx.ContextWithClientID(ctx, xctx.ClientID(clientID)) if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, "tcp", host) { resp.StatusCode = http.StatusForbidden @@ -254,11 +256,11 @@ func (h *http2Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req switch h.md.hash { case "host": - ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: host}) + ctx = xctx.ContextWithHash(ctx, &xctx.Hash{Source: host}) } var buf bytes.Buffer - cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", host) + cc, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", host) ro.Route = buf.String() if err != nil { log.Error(err) @@ -269,8 +271,8 @@ func (h *http2Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req defer cc.Close() log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() if req.Method == http.MethodConnect { resp.StatusCode = http.StatusOK diff --git a/handler/http3/handler.go b/handler/http3/handler.go index a56678b1..ed609c29 100644 --- a/handler/http3/handler.go +++ b/handler/http3/handler.go @@ -14,7 +14,8 @@ import ( "github.com/go-gost/core/hop" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" "github.com/go-gost/x/registry" ) @@ -57,10 +58,10 @@ func (h *http3Handler) Handle(ctx context.Context, conn net.Conn, opts ...handle start := time.Now() log := h.options.Logger.WithFields(map[string]any{ + "network": "udp", "remote": conn.RemoteAddr().String(), "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), - "network": "udp", + "sid": xctx.SidFromContext(ctx).String(), }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) defer func() { @@ -73,21 +74,24 @@ func (h *http3Handler) Handle(ctx context.Context, conn net.Conn, opts ...handle return nil } - v, ok := conn.(md.Metadatable) - if !ok || v == nil { - err := errors.New("wrong connection type") + md := ictx.MetadataFromContext(ctx) + if md == nil { + err := errors.New("http3: wrong connection type") log.Error(err) return err } - md := v.Metadata() - return h.roundTrip(ctx, - md.Get("w").(http.ResponseWriter), - md.Get("r").(*http.Request), - log, - ) + + w, _ := md.Get("w").(http.ResponseWriter) + r, _ := md.Get("r").(*http.Request) + + return h.roundTrip(ctx, w, r, log) } func (h *http3Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req *http.Request, log logger.Logger) error { + if w == nil || req == nil { + return nil + } + addr := req.Host if _, port, _ := net.SplitHostPort(addr); port == "" { addr = net.JoinHostPort(strings.Trim(addr, "[]"), "80") @@ -110,7 +114,7 @@ func (h *http3Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req switch h.md.hash { case "host": - ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: addr}) + ctx = xctx.ContextWithHash(ctx, &xctx.Hash{Source: addr}) } var target *chain.Node diff --git a/handler/redirect/tcp/handler.go b/handler/redirect/tcp/handler.go index 633efcf8..cc9bb936 100644 --- a/handler/redirect/tcp/handler.go +++ b/handler/redirect/tcp/handler.go @@ -14,7 +14,8 @@ import ( "github.com/go-gost/core/observer/stats" "github.com/go-gost/core/recorder" xbypass "github.com/go-gost/x/bypass" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/util/sniffing" tls_util "github.com/go-gost/x/internal/util/tls" @@ -74,24 +75,24 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han start := time.Now() ro := &xrecorder.HandlerRecorderObject{ - Service: h.options.Service, Network: "tcp", + Service: h.options.Service, RemoteAddr: conn.RemoteAddr().String(), LocalAddr: conn.LocalAddr().String(), + SID: xctx.SidFromContext(ctx).String(), Time: start, - SID: string(ctxvalue.SidFromContext(ctx)), } - if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil { - ro.ClientIP = srcAddr.String() + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { + ro.ClientAddr = srcAddr.String() } log := h.options.Logger.WithFields(map[string]any{ "network": ro.Network, "remote": conn.RemoteAddr().String(), "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), - "client": ro.ClientIP, + "client": ro.ClientAddr, + "sid": ro.SID, }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) @@ -133,7 +134,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han } ro.Host = dstAddr.String() - ro.Dst = dstAddr.String() + ro.DstAddr = dstAddr.String() log = log.WithFields(map[string]any{ "dst": dstAddr.String(), @@ -166,7 +167,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han ro.Host = address var buf bytes.Buffer - cc, err = h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", address) + cc, err = h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", address) ro.Route = buf.String() if err != nil && !h.md.sniffingFallback { return nil, err @@ -178,7 +179,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han return nil, xbypass.ErrBypass } var buf bytes.Buffer - cc, err = h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", dstAddr.String()) + cc, err = h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", dstAddr.String()) ro.Route = buf.String() ro.Host = dstAddr.String() } @@ -232,7 +233,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han } var buf bytes.Buffer - cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), dstAddr.Network(), dstAddr.String()) + cc, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), dstAddr.Network(), dstAddr.String()) ro.Route = buf.String() if err != nil { log.Error(err) @@ -241,8 +242,8 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han defer cc.Close() log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() t := time.Now() log.Infof("%s <-> %s", conn.RemoteAddr(), dstAddr) diff --git a/handler/redirect/udp/handler.go b/handler/redirect/udp/handler.go index ff45100a..1d6e1294 100644 --- a/handler/redirect/udp/handler.go +++ b/handler/redirect/udp/handler.go @@ -11,7 +11,8 @@ import ( "github.com/go-gost/core/observer/stats" "github.com/go-gost/core/recorder" xbypass "github.com/go-gost/x/bypass" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" rate_limiter "github.com/go-gost/x/limiter/rate" xstats "github.com/go-gost/x/observer/stats" @@ -62,20 +63,24 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han start := time.Now() ro := &xrecorder.HandlerRecorderObject{ + Network: "udp", Service: h.options.Service, RemoteAddr: conn.RemoteAddr().String(), LocalAddr: conn.LocalAddr().String(), - Network: "udp", + SID: xctx.SidFromContext(ctx).String(), Time: start, - SID: string(ctxvalue.SidFromContext(ctx)), } - ro.ClientIP, _, _ = net.SplitHostPort(conn.RemoteAddr().String()) + + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { + ro.ClientAddr = srcAddr.String() + } log := h.options.Logger.WithFields(map[string]any{ + "network": ro.Network, "remote": conn.RemoteAddr().String(), "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), - "network": ro.Network, + "client": ro.ClientAddr, + "sid": ro.SID, }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) @@ -123,7 +128,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han } var buf bytes.Buffer - cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), dstAddr.Network(), dstAddr.String()) + cc, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), dstAddr.Network(), dstAddr.String()) ro.Route = buf.String() if err != nil { log.Error(err) @@ -132,8 +137,8 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han defer cc.Close() log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() t := time.Now() log.Infof("%s <-> %s", conn.RemoteAddr(), dstAddr) diff --git a/handler/relay/bind.go b/handler/relay/bind.go index 3d88edc7..f99cac0b 100644 --- a/handler/relay/bind.go +++ b/handler/relay/bind.go @@ -101,7 +101,7 @@ func (h *relayHandler) bindTCP(ctx context.Context, conn net.Conn, network, addr "bind": fmt.Sprintf("%s/%s", ln.Addr(), ln.Addr().Network()), "src": ln.Addr().String(), }) - ro.Src = ln.Addr().String() + ro.SrcAddr = ln.Addr().String() af := &relay.AddrFeature{} if err := af.ParseFrom(ln.Addr().String()); err != nil { @@ -183,7 +183,7 @@ func (h *relayHandler) bindUDP(ctx context.Context, conn net.Conn, network, addr "bind": pc.LocalAddr().String(), "src": pc.LocalAddr().String(), }) - ro.Src = pc.LocalAddr().String() + ro.SrcAddr = pc.LocalAddr().String() pc = metrics.WrapPacketConn(serviceName, pc) // pc = admission.WrapPacketConn(l.options.Admission, pc) diff --git a/handler/relay/connect.go b/handler/relay/connect.go index c0cfe104..fd7fb151 100644 --- a/handler/relay/connect.go +++ b/handler/relay/connect.go @@ -15,7 +15,8 @@ import ( "github.com/go-gost/core/observer/stats" "github.com/go-gost/relay" xbypass "github.com/go-gost/x/bypass" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" serial "github.com/go-gost/x/internal/util/serial" "github.com/go-gost/x/internal/util/sniffing" @@ -40,7 +41,7 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network log.Debugf("%s >> %s/%s", conn.RemoteAddr(), address, network) { - clientID := ctxvalue.ClientIDFromContext(ctx) + clientID := xctx.ClientIDFromContext(ctx) rw := traffic_wrapper.WrapReadWriter( h.limiter, conn, @@ -85,7 +86,7 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network switch h.md.hash { case "host": - ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: address}) + ctx = xctx.ContextWithHash(ctx, &xctx.Hash{Source: address}) } var cc net.Conn @@ -103,7 +104,7 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network } default: var buf bytes.Buffer - cc, err = h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), network, address) + cc, err = h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), network, address) ro.Route = buf.String() } if err != nil { @@ -114,8 +115,8 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network defer cc.Close() log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() if h.md.noDelay { if _, err := resp.WriteTo(conn); err != nil { diff --git a/handler/relay/forward.go b/handler/relay/forward.go index 12553828..398a00b5 100644 --- a/handler/relay/forward.go +++ b/handler/relay/forward.go @@ -12,6 +12,7 @@ import ( "github.com/go-gost/core/observer/stats" "github.com/go-gost/relay" ctxvalue "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/limiter/traffic/wrapper" stats_wrapper "github.com/go-gost/x/observer/stats/wrapper" @@ -63,7 +64,7 @@ func (h *relayHandler) handleForward(ctx context.Context, conn net.Conn, network } var buf bytes.Buffer - cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), network, target.Addr) + cc, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), network, target.Addr) ro.Route = buf.String() if err != nil { // TODO: the router itself may be failed due to the failed node in the router, @@ -81,8 +82,8 @@ func (h *relayHandler) handleForward(ctx context.Context, conn net.Conn, network defer cc.Close() log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() if marker := target.Marker(); marker != nil { marker.Reset() diff --git a/handler/relay/handler.go b/handler/relay/handler.go index dc6925ab..15076c74 100644 --- a/handler/relay/handler.go +++ b/handler/relay/handler.go @@ -16,7 +16,7 @@ import ( "github.com/go-gost/core/observer/stats" "github.com/go-gost/core/recorder" "github.com/go-gost/relay" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" stats_util "github.com/go-gost/x/internal/util/stats" tls_util "github.com/go-gost/x/internal/util/tls" rate_limiter "github.com/go-gost/x/limiter/rate" @@ -105,22 +105,24 @@ func (h *relayHandler) Handle(ctx context.Context, conn net.Conn, opts ...handle start := time.Now() ro := &xrecorder.HandlerRecorderObject{ + Network: "tcp", Service: h.options.Service, RemoteAddr: conn.RemoteAddr().String(), LocalAddr: conn.LocalAddr().String(), + SID: xctx.SidFromContext(ctx).String(), Time: start, - SID: string(ctxvalue.SidFromContext(ctx)), } - if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil { - ro.ClientIP = srcAddr.String() + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { + ro.ClientAddr = srcAddr.String() } log := h.options.Logger.WithFields(map[string]any{ - "remote": conn.RemoteAddr().String(), - "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), - "client": ro.ClientIP, + "network": ro.Network, + "remote": conn.RemoteAddr().String(), + "local": conn.LocalAddr().String(), + "client": ro.ClientAddr, + "sid": ro.SID, }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) @@ -206,7 +208,7 @@ func (h *relayHandler) Handle(ctx context.Context, conn net.Conn, opts ...handle } log = log.WithFields(map[string]any{"clientID": clientID}) ro.ClientID = clientID - ctx = ctxvalue.ContextWithClientID(ctx, ctxvalue.ClientID(clientID)) + ctx = xctx.ContextWithClientID(ctx, xctx.ClientID(clientID)) } network := networkID.String() diff --git a/handler/router/handler.go b/handler/router/handler.go index f1c70669..4aeb83ed 100644 --- a/handler/router/handler.go +++ b/handler/router/handler.go @@ -15,7 +15,7 @@ import ( md "github.com/go-gost/core/metadata" "github.com/go-gost/core/observer" "github.com/go-gost/relay" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/util/cache" stats_util "github.com/go-gost/x/internal/util/stats" @@ -136,9 +136,10 @@ func (h *routerHandler) Handle(ctx context.Context, conn net.Conn, opts ...handl start := time.Now() log := h.log.WithFields(map[string]any{ - "remote": conn.RemoteAddr().String(), - "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), + "network": conn.LocalAddr().Network(), + "remote": conn.RemoteAddr().String(), + "local": conn.LocalAddr().String(), + "sid": xctx.SidFromContext(ctx).String(), }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) @@ -216,7 +217,7 @@ func (h *routerHandler) Handle(ctx context.Context, conn net.Conn, opts ...handl resp.WriteTo(conn) return ErrUnauthorized } - ctx = ctxvalue.ContextWithClientID(ctx, ctxvalue.ClientID(clientID)) + ctx = xctx.ContextWithClientID(ctx, xctx.ClientID(clientID)) } switch req.Cmd & relay.CmdMask { diff --git a/handler/serial/handler.go b/handler/serial/handler.go index dcd207f0..e38d8ece 100644 --- a/handler/serial/handler.go +++ b/handler/serial/handler.go @@ -13,7 +13,7 @@ import ( "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" "github.com/go-gost/core/recorder" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" xnet "github.com/go-gost/x/internal/net" serial "github.com/go-gost/x/internal/util/serial" xrecorder "github.com/go-gost/x/recorder" @@ -68,9 +68,10 @@ func (h *serialHandler) Handle(ctx context.Context, conn net.Conn, opts ...handl log := h.options.Logger log = log.WithFields(map[string]any{ + "network": "serial", "remote": conn.RemoteAddr().String(), "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), + "sid": xctx.SidFromContext(ctx).String(), }) conn = &recorderConn{ diff --git a/handler/sni/handler.go b/handler/sni/handler.go index 7c673d54..4d2aa7f2 100644 --- a/handler/sni/handler.go +++ b/handler/sni/handler.go @@ -13,7 +13,8 @@ import ( md "github.com/go-gost/core/metadata" "github.com/go-gost/core/observer/stats" "github.com/go-gost/core/recorder" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/util/sniffing" tls_util "github.com/go-gost/x/internal/util/tls" @@ -73,24 +74,24 @@ func (h *sniHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. start := time.Now() ro := &xrecorder.HandlerRecorderObject{ + Network: "tcp", Service: h.options.Service, RemoteAddr: conn.RemoteAddr().String(), LocalAddr: conn.LocalAddr().String(), - Network: "tcp", + SID: xctx.SidFromContext(ctx).String(), Time: start, - SID: string(ctxvalue.SidFromContext(ctx)), } - if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil { - ro.ClientIP = srcAddr.String() + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { + ro.ClientAddr = srcAddr.String() } log := h.options.Logger.WithFields(map[string]any{ + "network": ro.Network, "remote": conn.RemoteAddr().String(), "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), - "client": ro.ClientIP, - "network": ro.Network, + "client": ro.ClientAddr, + "sid": ro.SID, }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) @@ -125,9 +126,13 @@ func (h *sniHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. dial := func(ctx context.Context, network, address string) (net.Conn, error) { var buf bytes.Buffer - cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", address) + cc, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", address) ro.Route = buf.String() + if cc != nil { + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() + } return cc, err } dialTLS := func(ctx context.Context, network, address string, cfg *tls.Config) (net.Conn, error) { diff --git a/handler/socks/v4/handler.go b/handler/socks/v4/handler.go index cb9f61cc..cd463292 100644 --- a/handler/socks/v4/handler.go +++ b/handler/socks/v4/handler.go @@ -18,7 +18,8 @@ import ( "github.com/go-gost/core/observer/stats" "github.com/go-gost/core/recorder" "github.com/go-gost/gosocks4" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/util/sniffing" stats_util "github.com/go-gost/x/internal/util/stats" @@ -104,27 +105,23 @@ func (h *socks4Handler) Handle(ctx context.Context, conn net.Conn, opts ...handl start := time.Now() ro := &xrecorder.HandlerRecorderObject{ - Service: h.options.Service, Network: "tcp", + Service: h.options.Service, RemoteAddr: conn.RemoteAddr().String(), LocalAddr: conn.LocalAddr().String(), + SID: xctx.SidFromContext(ctx).String(), Time: start, - SID: string(ctxvalue.SidFromContext(ctx)), } - ro.ClientIP = conn.RemoteAddr().String() - if clientAddr := ctxvalue.ClientAddrFromContext(ctx); clientAddr != "" { - ro.ClientIP = string(clientAddr) - } - if h, _, _ := net.SplitHostPort(ro.ClientIP); h != "" { - ro.ClientIP = h + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { + ro.ClientAddr = srcAddr.String() } log := h.options.Logger.WithFields(map[string]any{ + "network": ro.Network, "remote": conn.RemoteAddr().String(), "local": conn.LocalAddr().String(), - "client": ro.ClientIP, - "network": ro.Network, + "client": ro.ClientAddr, "sid": ro.SID, }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) @@ -181,7 +178,7 @@ func (h *socks4Handler) Handle(ctx context.Context, conn net.Conn, opts ...handl log.Trace(resp) return resp.Write(conn) } - ctx = ctxvalue.ContextWithClientID(ctx, ctxvalue.ClientID(clientID)) + ctx = xctx.ContextWithClientID(ctx, xctx.ClientID(clientID)) ro.ClientID = clientID log = log.WithFields(map[string]any{"clientID": clientID}) } @@ -215,7 +212,7 @@ func (h *socks4Handler) handleConnect(ctx context.Context, conn net.Conn, req *g log.Debugf("%s >> %s", conn.RemoteAddr(), addr) { - clientID := ctxvalue.ClientIDFromContext(ctx) + clientID := xctx.ClientIDFromContext(ctx) rw := traffic_wrapper.WrapReadWriter( h.limiter, conn, @@ -247,11 +244,11 @@ func (h *socks4Handler) handleConnect(ctx context.Context, conn net.Conn, req *g switch h.md.hash { case "host": - ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: addr}) + ctx = xctx.ContextWithHash(ctx, &xctx.Hash{Source: addr}) } var buf bytes.Buffer - cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", addr) + cc, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", addr) ro.Route = buf.String() if err != nil { resp := gosocks4.NewReply(gosocks4.Failed, nil) @@ -262,8 +259,8 @@ func (h *socks4Handler) handleConnect(ctx context.Context, conn net.Conn, req *g defer cc.Close() log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() resp := gosocks4.NewReply(gosocks4.Granted, nil) log.Trace(resp) diff --git a/handler/socks/v5/bind.go b/handler/socks/v5/bind.go index a0a6a0f9..ec0894f6 100644 --- a/handler/socks/v5/bind.go +++ b/handler/socks/v5/bind.go @@ -9,7 +9,7 @@ import ( "github.com/go-gost/core/logger" "github.com/go-gost/core/observer/stats" "github.com/go-gost/gosocks5" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" xnet "github.com/go-gost/x/internal/net" traffic_wrapper "github.com/go-gost/x/limiter/traffic/wrapper" stats_wrapper "github.com/go-gost/x/observer/stats/wrapper" @@ -32,7 +32,7 @@ func (h *socks5Handler) handleBind(ctx context.Context, conn net.Conn, network, } { - clientID := ctxvalue.ClientIDFromContext(ctx) + clientID := xctx.ClientIDFromContext(ctx) rw := traffic_wrapper.WrapReadWriter( h.limiter, conn, @@ -78,7 +78,7 @@ func (h *socks5Handler) bindLocal(ctx context.Context, conn net.Conn, network, a "src": ln.Addr().String(), "bind": ln.Addr().String(), }) - ro.Src = ln.Addr().String() + ro.SrcAddr = ln.Addr().String() socksAddr := gosocks5.Addr{} if err := socksAddr.ParseFrom(ln.Addr().String()); err != nil { diff --git a/handler/socks/v5/connect.go b/handler/socks/v5/connect.go index f737132a..aa35eca7 100644 --- a/handler/socks/v5/connect.go +++ b/handler/socks/v5/connect.go @@ -13,7 +13,8 @@ import ( "github.com/go-gost/core/logger" "github.com/go-gost/core/observer/stats" "github.com/go-gost/gosocks5" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/util/sniffing" traffic_wrapper "github.com/go-gost/x/limiter/traffic/wrapper" @@ -30,7 +31,7 @@ func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, networ log.Debugf("%s >> %s", conn.RemoteAddr(), address) { - clientID := ctxvalue.ClientIDFromContext(ctx) + clientID := xctx.ClientIDFromContext(ctx) rw := traffic_wrapper.WrapReadWriter( h.limiter, conn, @@ -62,11 +63,11 @@ func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, networ switch h.md.hash { case "host": - ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: address}) + ctx = xctx.ContextWithHash(ctx, &xctx.Hash{Source: address}) } var buf bytes.Buffer - cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), network, address) + cc, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), network, address) ro.Route = buf.String() if err != nil { resp := gosocks5.NewReply(gosocks5.NetUnreachable, nil) @@ -77,8 +78,8 @@ func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, networ defer cc.Close() log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() resp := gosocks5.NewReply(gosocks5.Succeeded, nil) log.Trace(resp) diff --git a/handler/socks/v5/handler.go b/handler/socks/v5/handler.go index 7f13e3d9..4f364a2b 100644 --- a/handler/socks/v5/handler.go +++ b/handler/socks/v5/handler.go @@ -14,7 +14,7 @@ import ( "github.com/go-gost/core/observer/stats" "github.com/go-gost/core/recorder" "github.com/go-gost/gosocks5" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/util/socks" stats_util "github.com/go-gost/x/internal/util/stats" tls_util "github.com/go-gost/x/internal/util/tls" @@ -105,28 +105,24 @@ func (h *socks5Handler) Handle(ctx context.Context, conn net.Conn, opts ...handl start := time.Now() ro := &xrecorder.HandlerRecorderObject{ - Service: h.options.Service, Network: "tcp", + Service: h.options.Service, RemoteAddr: conn.RemoteAddr().String(), LocalAddr: conn.LocalAddr().String(), + SID: xctx.SidFromContext(ctx).String(), Time: start, - SID: string(ctxvalue.SidFromContext(ctx)), } - ro.ClientIP = conn.RemoteAddr().String() - if clientAddr := ctxvalue.ClientAddrFromContext(ctx); clientAddr != "" { - ro.ClientIP = string(clientAddr) - } - if h, _, _ := net.SplitHostPort(ro.ClientIP); h != "" { - ro.ClientIP = h + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { + ro.ClientAddr = srcAddr.String() } log := h.options.Logger.WithFields(map[string]any{ + "network": ro.Network, "remote": conn.RemoteAddr().String(), "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), - "client": ro.ClientIP, - "network": ro.Network, + "client": ro.ClientAddr, + "sid": ro.SID, }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) @@ -167,7 +163,7 @@ func (h *socks5Handler) Handle(ctx context.Context, conn net.Conn, opts ...handl log.Trace(req) if clientID := sc.ID(); clientID != "" { - ctx = ctxvalue.ContextWithClientID(ctx, ctxvalue.ClientID(clientID)) + ctx = xctx.ContextWithClientID(ctx, xctx.ClientID(clientID)) log = log.WithFields(map[string]any{"user": clientID, "clientID": clientID}) ro.ClientID = clientID } diff --git a/handler/socks/v5/mbind.go b/handler/socks/v5/mbind.go index a83bc44b..2dc0f126 100644 --- a/handler/socks/v5/mbind.go +++ b/handler/socks/v5/mbind.go @@ -9,7 +9,7 @@ import ( "github.com/go-gost/core/logger" "github.com/go-gost/core/observer/stats" "github.com/go-gost/gosocks5" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/util/mux" traffic_wrapper "github.com/go-gost/x/limiter/traffic/wrapper" @@ -33,7 +33,7 @@ func (h *socks5Handler) handleMuxBind(ctx context.Context, conn net.Conn, networ } { - clientID := ctxvalue.ClientIDFromContext(ctx) + clientID := xctx.ClientIDFromContext(ctx) rw := traffic_wrapper.WrapReadWriter( h.limiter, conn, @@ -79,7 +79,7 @@ func (h *socks5Handler) muxBindLocal(ctx context.Context, conn net.Conn, network "bind": ln.Addr().String(), }) - ro.Src = ln.Addr().String() + ro.SrcAddr = ln.Addr().String() socksAddr := gosocks5.Addr{} err = socksAddr.ParseFrom(ln.Addr().String()) if err != nil { diff --git a/handler/socks/v5/selector.go b/handler/socks/v5/selector.go index 23f027a9..46a9cc6c 100644 --- a/handler/socks/v5/selector.go +++ b/handler/socks/v5/selector.go @@ -8,7 +8,7 @@ import ( "github.com/go-gost/core/auth" "github.com/go-gost/core/logger" "github.com/go-gost/gosocks5" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/util/socks" ) @@ -70,7 +70,7 @@ func (s *serverSelector) OnSelected(method uint8, conn net.Conn) (string, net.Co var id string if s.Authenticator != nil { var ok bool - ctx := ctxvalue.ContextWithClientAddr(context.Background(), ctxvalue.ClientAddr(conn.RemoteAddr().String())) + ctx := xctx.ContextWithSrcAddr(context.Background(), conn.RemoteAddr()) id, ok = s.Authenticator.Authenticate(ctx, req.Username, req.Password) if !ok { resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Failure) diff --git a/handler/socks/v5/udp.go b/handler/socks/v5/udp.go index ea155a0c..eafaff38 100644 --- a/handler/socks/v5/udp.go +++ b/handler/socks/v5/udp.go @@ -13,6 +13,7 @@ import ( "github.com/go-gost/core/observer/stats" "github.com/go-gost/gosocks5" ctxvalue "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/net/udp" "github.com/go-gost/x/internal/util/socks" @@ -54,7 +55,7 @@ func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, network st "src": cc.LocalAddr().String(), "bind": cc.LocalAddr().String(), }) - ro.Src = cc.LocalAddr().String() + ro.SrcAddr = cc.LocalAddr().String() saddr := gosocks5.Addr{} saddr.ParseFrom(cc.LocalAddr().String()) @@ -75,7 +76,7 @@ func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, network st // obtain a udp connection var buf bytes.Buffer - c, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), network, "") // UDP association + c, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), network, "") // UDP association ro.Route = buf.String() if err != nil { log.Error(err) diff --git a/handler/socks/v5/udp_tun.go b/handler/socks/v5/udp_tun.go index c7b1443c..1d95f8c9 100644 --- a/handler/socks/v5/udp_tun.go +++ b/handler/socks/v5/udp_tun.go @@ -11,7 +11,8 @@ import ( "github.com/go-gost/core/logger" "github.com/go-gost/core/observer/stats" "github.com/go-gost/gosocks5" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/net/udp" "github.com/go-gost/x/internal/util/socks" @@ -27,7 +28,7 @@ func (h *socks5Handler) handleUDPTun(ctx context.Context, conn net.Conn, network }) { - clientID := ctxvalue.ClientIDFromContext(ctx) + clientID := xctx.ClientIDFromContext(ctx) rw := traffic_wrapper.WrapReadWriter( h.limiter, conn, @@ -67,7 +68,7 @@ func (h *socks5Handler) handleUDPTun(ctx context.Context, conn net.Conn, network // obtain a udp connection var buf bytes.Buffer - c, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), network, "") // UDP association + c, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), network, "") // UDP association ro.Route = buf.String() if err != nil { log.Error(err) @@ -111,7 +112,7 @@ func (h *socks5Handler) handleUDPTun(ctx context.Context, conn net.Conn, network "src": pc.LocalAddr().String(), "bind": pc.LocalAddr().String(), }) - ro.Src = pc.LocalAddr().String() + ro.SrcAddr = pc.LocalAddr().String() saddr := gosocks5.Addr{} saddr.ParseFrom(pc.LocalAddr().String()) @@ -123,7 +124,7 @@ func (h *socks5Handler) handleUDPTun(ctx context.Context, conn net.Conn, network } log.Debugf("bind on %s OK", pc.LocalAddr()) - clientID := ctxvalue.ClientIDFromContext(ctx) + clientID := xctx.ClientIDFromContext(ctx) if h.options.Observer != nil { pstats := h.stats.Stats(string(clientID)) pstats.Add(stats.KindTotalConns, 1) diff --git a/handler/ss/handler.go b/handler/ss/handler.go index b540390d..523632a7 100644 --- a/handler/ss/handler.go +++ b/handler/ss/handler.go @@ -14,7 +14,8 @@ import ( "github.com/go-gost/core/observer/stats" "github.com/go-gost/core/recorder" "github.com/go-gost/gosocks5" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/util/sniffing" "github.com/go-gost/x/internal/util/ss" @@ -83,28 +84,24 @@ func (h *ssHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.H start := time.Now() ro := &xrecorder.HandlerRecorderObject{ - Service: h.options.Service, Network: "tcp", + Service: h.options.Service, RemoteAddr: conn.RemoteAddr().String(), LocalAddr: conn.LocalAddr().String(), + SID: xctx.SidFromContext(ctx).String(), Time: start, - SID: string(ctxvalue.SidFromContext(ctx)), } - ro.ClientIP = conn.RemoteAddr().String() - if clientAddr := ctxvalue.ClientAddrFromContext(ctx); clientAddr != "" { - ro.ClientIP = string(clientAddr) - } - if h, _, _ := net.SplitHostPort(ro.ClientIP); h != "" { - ro.ClientIP = h + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { + ro.ClientAddr = srcAddr.String() } log := h.options.Logger.WithFields(map[string]any{ "remote": conn.RemoteAddr().String(), "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), - "client": ro.ClientIP, + "client": ro.ClientAddr, "network": ro.Network, + "sid": ro.SID, }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) @@ -163,11 +160,11 @@ func (h *ssHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.H switch h.md.hash { case "host": - ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: addr.String()}) + ctx = xctx.ContextWithHash(ctx, &xctx.Hash{Source: addr.String()}) } var buf bytes.Buffer - cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", addr.String()) + cc, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", addr.String()) ro.Route = buf.String() if err != nil { return err @@ -175,8 +172,8 @@ func (h *ssHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.H defer cc.Close() log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() if h.md.sniffing { if h.md.sniffingTimeout > 0 { diff --git a/handler/ss/udp/handler.go b/handler/ss/udp/handler.go index f135104f..76504741 100644 --- a/handler/ss/udp/handler.go +++ b/handler/ss/udp/handler.go @@ -12,7 +12,8 @@ import ( "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" "github.com/go-gost/core/recorder" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" "github.com/go-gost/x/internal/util/relay" "github.com/go-gost/x/internal/util/ss" rate_limiter "github.com/go-gost/x/limiter/rate" @@ -73,21 +74,24 @@ func (h *ssuHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. start := time.Now() ro := &xrecorder.HandlerRecorderObject{ - Service: h.options.Service, Network: "udp", + Service: h.options.Service, RemoteAddr: conn.RemoteAddr().String(), LocalAddr: conn.LocalAddr().String(), + SID: xctx.SidFromContext(ctx).String(), Time: start, - SID: string(ctxvalue.SidFromContext(ctx)), } - ro.ClientIP, _, _ = net.SplitHostPort(conn.RemoteAddr().String()) + + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { + ro.ClientAddr = srcAddr.String() + } log := h.options.Logger.WithFields(map[string]any{ + "network": ro.Network, "remote": conn.RemoteAddr().String(), "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), - "client": ro.ClientIP, - "network": ro.Network, + "client": ro.ClientAddr, + "sid": ro.SID, }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) @@ -124,7 +128,7 @@ func (h *ssuHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. // obtain a udp connection var buf bytes.Buffer - c, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "udp", "") // UDP association + c, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "udp", "") // UDP association ro.Route = buf.String() if err != nil { log.Error(err) diff --git a/handler/sshd/handler.go b/handler/sshd/handler.go index 61a5f1e5..09a28704 100644 --- a/handler/sshd/handler.go +++ b/handler/sshd/handler.go @@ -18,7 +18,8 @@ import ( "github.com/go-gost/core/observer/stats" "github.com/go-gost/core/recorder" xbypass "github.com/go-gost/x/bypass" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/util/sniffing" sshd_util "github.com/go-gost/x/internal/util/sshd" @@ -83,21 +84,24 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand start := time.Now() ro := &xrecorder.HandlerRecorderObject{ - Service: h.options.Service, Network: "tcp", + Service: h.options.Service, RemoteAddr: conn.RemoteAddr().String(), LocalAddr: conn.LocalAddr().String(), Time: start, - SID: string(ctxvalue.SidFromContext(ctx)), + SID: xctx.SidFromContext(ctx).String(), + } + + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { + ro.ClientAddr = srcAddr.String() } - ro.ClientIP, _, _ = net.SplitHostPort(conn.RemoteAddr().String()) log := h.options.Logger.WithFields(map[string]any{ + "network": ro.Network, "remote": conn.RemoteAddr().String(), "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), - "client": ro.ClientIP, - "network": ro.Network, + "client": ro.ClientAddr, + "sid": ro.SID, }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) @@ -156,7 +160,7 @@ func (h *forwardHandler) handleDirectForward(ctx context.Context, conn *sshd_uti } var buf bytes.Buffer - cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", targetAddr) + cc, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", targetAddr) ro.Route = buf.String() if err != nil { return err @@ -164,8 +168,8 @@ func (h *forwardHandler) handleDirectForward(ctx context.Context, conn *sshd_uti defer cc.Close() log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() if h.md.sniffing { if h.md.sniffingTimeout > 0 { @@ -261,7 +265,7 @@ func (h *forwardHandler) handleRemoteForward(ctx context.Context, conn *sshd_uti "src": ln.Addr().String(), "bind": ln.Addr().String(), }) - ro.Src = ln.Addr().String() + ro.SrcAddr = ln.Addr().String() log.Debugf("bind on %s OK", ln.Addr()) diff --git a/handler/tap/handler.go b/handler/tap/handler.go index 79785732..b990c56b 100644 --- a/handler/tap/handler.go +++ b/handler/tap/handler.go @@ -15,7 +15,8 @@ import ( "github.com/go-gost/core/hop" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/util/ss" tap_util "github.com/go-gost/x/internal/util/tap" "github.com/go-gost/x/registry" @@ -76,8 +77,12 @@ func (h *tapHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. defer conn.Close() log := h.options.Logger - v, _ := conn.(md.Metadatable) - if v == nil { + + var config *tap_util.Config + if md := ictx.MetadataFromContext(ctx); md != nil { + config, _ = md.Get("config").(*tap_util.Config) + } + if config == nil { err := errors.New("tap: wrong connection type") log.Error(err) return err @@ -87,7 +92,7 @@ func (h *tapHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. log = log.WithFields(map[string]any{ "remote": conn.RemoteAddr().String(), "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), + "sid": xctx.SidFromContext(ctx).String(), }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) @@ -117,7 +122,6 @@ func (h *tapHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. log.Debugf("%s >> %s", conn.RemoteAddr(), target.Addr) } - config := v.Metadata().Get("config").(*tap_util.Config) h.handleLoop(ctx, conn, raddr, config, log) return nil } diff --git a/handler/tun/handler.go b/handler/tun/handler.go index 1c6cbe5c..9c3307e1 100644 --- a/handler/tun/handler.go +++ b/handler/tun/handler.go @@ -12,7 +12,8 @@ import ( "github.com/go-gost/core/handler" "github.com/go-gost/core/hop" md "github.com/go-gost/core/metadata" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" tun_util "github.com/go-gost/x/internal/util/tun" "github.com/go-gost/x/registry" ) @@ -63,8 +64,8 @@ func (h *tunHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. log := h.options.Logger var config *tun_util.Config - if v, _ := conn.(md.Metadatable); v != nil { - config = v.Metadata().Get("config").(*tun_util.Config) + if md := ictx.MetadataFromContext(ctx); md != nil { + config, _ = md.Get("config").(*tun_util.Config) } if config == nil { err := errors.New("tun: wrong connection type") @@ -76,7 +77,7 @@ func (h *tunHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. log = log.WithFields(map[string]any{ "remote": conn.RemoteAddr().String(), "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), + "sid": xctx.SidFromContext(ctx).String(), }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) diff --git a/handler/tungo/handler.go b/handler/tungo/handler.go index 4e7f92d2..49ae4cd8 100644 --- a/handler/tungo/handler.go +++ b/handler/tungo/handler.go @@ -12,7 +12,8 @@ import ( md "github.com/go-gost/core/metadata" "github.com/go-gost/core/observer" "github.com/go-gost/core/recorder" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" stats_util "github.com/go-gost/x/internal/util/stats" tun_util "github.com/go-gost/x/internal/util/tun" cache_limiter "github.com/go-gost/x/limiter/traffic/cache" @@ -86,8 +87,8 @@ func (h *tungoHandler) Handle(ctx context.Context, conn net.Conn, opts ...handle log := h.options.Logger var config *tun_util.Config - if v, _ := conn.(md.Metadatable); v != nil { - config = v.Metadata().Get("config").(*tun_util.Config) + if md := ictx.MetadataFromContext(ctx); md != nil { + config, _ = md.Get("config").(*tun_util.Config) } if config == nil { err := errors.New("tun: wrong connection type") @@ -99,7 +100,7 @@ func (h *tungoHandler) Handle(ctx context.Context, conn net.Conn, opts ...handle log = log.WithFields(map[string]any{ "remote": conn.RemoteAddr().String(), "local": conn.LocalAddr().String(), - "sid": string(ctxvalue.SidFromContext(ctx)), + "sid": xctx.SidFromContext(ctx).String(), }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) diff --git a/handler/tungo/stack.go b/handler/tungo/stack.go index 0943dca6..50329b5e 100644 --- a/handler/tungo/stack.go +++ b/handler/tungo/stack.go @@ -16,7 +16,8 @@ import ( "github.com/go-gost/core/handler" "github.com/go-gost/core/observer/stats" "github.com/go-gost/core/recorder" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/util/sniffing" stats_util "github.com/go-gost/x/internal/util/stats" @@ -108,27 +109,24 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) { start := time.Now() sid := xid.New().String() - ctx := ctxvalue.ContextWithSid(context.Background(), ctxvalue.Sid(sid)) + ctx := xctx.ContextWithSid(context.Background(), xctx.Sid(sid)) ro := &xrecorder.HandlerRecorderObject{ Service: h.opts.Service, Network: "tcp", RemoteAddr: remoteAddr.String(), - Dst: dstAddr.String(), + DstAddr: dstAddr.String(), Host: dstAddr.String(), - ClientIP: remoteAddr.String(), + ClientAddr: remoteAddr.String(), Time: start, SID: sid, } - if h, _, _ := net.SplitHostPort(ro.ClientIP); h != "" { - ro.ClientIP = h - } log := h.opts.Logger.WithFields(map[string]any{ "network": ro.Network, "remote": ro.RemoteAddr, - "dst": ro.Dst, - "client": ro.ClientIP, + "dst": ro.DstAddr, + "client": ro.ClientAddr, "sid": ro.SID, }) @@ -152,7 +150,7 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) { } log.WithFields(map[string]any{ - "src": ro.Src, + "src": ro.SrcAddr, "duration": time.Since(start), "inputBytes": ro.InputBytes, "outputBytes": ro.OutputBytes, @@ -193,7 +191,7 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) { ro.Host = address var buf bytes.Buffer - cc, err = h.opts.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", address) + cc, err = h.opts.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", address) ro.Route = buf.String() if err != nil && !h.sniffingFallback { return nil, err @@ -202,7 +200,7 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) { if cc == nil { var buf bytes.Buffer - cc, err = h.opts.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", dstAddr.String()) + cc, err = h.opts.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", dstAddr.String()) ro.Route = buf.String() ro.Host = dstAddr.String() } @@ -250,7 +248,7 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) { } var buf bytes.Buffer - cc, err := h.opts.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", dstAddr.String()) + cc, err := h.opts.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", dstAddr.String()) ro.Route = buf.String() if err != nil { log.Errorf("dial %s: %v", dstAddr.String(), err) @@ -258,8 +256,8 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) { } defer cc.Close() - ro.Src = cc.LocalAddr().String() - log = log.WithFields(map[string]any{"src": ro.Src}) + ro.SrcAddr = cc.LocalAddr().String() + log = log.WithFields(map[string]any{"src": ro.SrcAddr}) t := time.Now() log.Infof("%s <-> %s", remoteAddr, dstAddr) @@ -283,26 +281,23 @@ func (h *transportHandler) handleUDPConn(uc adapter.UDPConn) { start := time.Now() sid := xid.New().String() - ctx := ctxvalue.ContextWithSid(context.Background(), ctxvalue.Sid(sid)) + ctx := xctx.ContextWithSid(context.Background(), xctx.Sid(sid)) ro := &xrecorder.HandlerRecorderObject{ - Service: h.opts.Service, Network: "udp", + Service: h.opts.Service, RemoteAddr: remoteAddr.String(), - Dst: dstAddr.String(), + DstAddr: dstAddr.String(), + ClientAddr: remoteAddr.String(), Host: dstAddr.String(), - ClientIP: remoteAddr.String(), - Time: start, SID: sid, - } - if h, _, _ := net.SplitHostPort(ro.ClientIP); h != "" { - ro.ClientIP = h + Time: start, } log := h.opts.Logger.WithFields(map[string]any{ "network": ro.Network, "remote": ro.RemoteAddr, - "dst": ro.Dst, + "dst": ro.DstAddr, "sid": ro.SID, }) @@ -326,7 +321,7 @@ func (h *transportHandler) handleUDPConn(uc adapter.UDPConn) { } log.WithFields(map[string]any{ - "src": ro.Src, + "src": ro.SrcAddr, "duration": time.Since(start), "inputBytes": ro.InputBytes, "outputBytes": ro.OutputBytes, @@ -340,8 +335,8 @@ func (h *transportHandler) handleUDPConn(uc adapter.UDPConn) { } defer cc.Close() - ro.Src = cc.LocalAddr().String() - log = log.WithFields(map[string]any{"src": ro.Src}) + ro.SrcAddr = cc.LocalAddr().String() + log = log.WithFields(map[string]any{"src": ro.SrcAddr}) t := time.Now() log.Infof("%s <-> %s", remoteAddr, dstAddr) diff --git a/handler/tunnel/entrypoint.go b/handler/tunnel/entrypoint.go index 7a2564fd..c09221ce 100644 --- a/handler/tunnel/entrypoint.go +++ b/handler/tunnel/entrypoint.go @@ -27,8 +27,8 @@ import ( "github.com/go-gost/relay" dissector "github.com/go-gost/tls-dissector" admission "github.com/go-gost/x/admission/wrapper" - ctxvalue "github.com/go-gost/x/ctx" - ctx_internal "github.com/go-gost/x/internal/ctx" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xio "github.com/go-gost/x/internal/io" xnet "github.com/go-gost/x/internal/net" xhttp "github.com/go-gost/x/internal/net/http" @@ -70,20 +70,25 @@ func (ep *entrypoint) Handle(ctx context.Context, conn net.Conn) (err error) { defer conn.Close() ro := &xrecorder.HandlerRecorderObject{ + Network: "tcp", Node: ep.node, Service: ep.service, RemoteAddr: conn.RemoteAddr().String(), LocalAddr: conn.LocalAddr().String(), - Network: "tcp", + SID: xctx.SidFromContext(ctx).String(), Time: time.Now(), - SID: string(ctxvalue.SidFromContext(ctx)), } - ro.ClientIP, _, _ = net.SplitHostPort(conn.RemoteAddr().String()) + + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { + ro.ClientAddr = srcAddr.String() + } log := ep.log.WithFields(map[string]any{ - "remote": conn.RemoteAddr().String(), - "local": conn.LocalAddr().String(), - "sid": ro.SID, + "network": ro.Network, + "remote": conn.RemoteAddr().String(), + "local": conn.LocalAddr().String(), + "client": ro.ClientAddr, + "sid": ro.SID, }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) @@ -132,7 +137,7 @@ func (ep *entrypoint) dial(ctx context.Context, network, addr string) (conn net. } } - log := ctxvalue.LoggerFromContext(ctx) + log := ictx.LoggerFromContext(ctx) if log == nil { log = ep.log } @@ -142,7 +147,7 @@ func (ep *entrypoint) dial(ctx context.Context, network, addr string) (conn net. return nil, fmt.Errorf("%w %s", ErrTunnelRoute, addr) } - ro := ctx_internal.RecorderObjectFromContext(ctx) + ro := ictx.RecorderObjectFromContext(ctx) ro.ClientID = tunnelID.String() if tunnelID.IsPrivate() { @@ -170,7 +175,10 @@ func (ep *entrypoint) dial(ctx context.Context, network, addr string) (conn net. if node == ep.node { ro.Redirect = "" - clientAddr := ctxvalue.ClientAddrFromContext(ctx) + var clientAddr string + if addr := xctx.SrcAddrFromContext(ctx); addr != nil { + clientAddr = addr.String() + } var features []relay.Feature af := &relay.AddrFeature{} af.ParseFrom(string(clientAddr)) @@ -311,17 +319,6 @@ func (ep *entrypoint) httpRoundTrip(ctx context.Context, rw io.ReadWriteCloser, }, } - if clientIP := xhttp.GetClientIP(req); clientIP != nil { - ro.ClientIP = clientIP.String() - } - - clientAddr := ro.RemoteAddr - if ro.ClientIP != "" { - if _, port, _ := net.SplitHostPort(ro.RemoteAddr); port != "" { - clientAddr = net.JoinHostPort(ro.ClientIP, port) - } - } - res := &http.Response{ ProtoMajor: req.ProtoMajor, ProtoMinor: req.ProtoMinor, @@ -345,9 +342,13 @@ func (ep *entrypoint) httpRoundTrip(ctx context.Context, rw io.ReadWriteCloser, } } - ctx = ctxvalue.ContextWithClientAddr(ctx, ctxvalue.ClientAddr(clientAddr)) - ctx = ctx_internal.ContextWithRecorderObject(ctx, ro) - ctx = ctxvalue.ContextWithLogger(ctx, log) + if clientIP := xhttp.GetClientIP(req); clientIP != nil { + ro.ClientIP = clientIP.String() + ctx = xctx.ContextWithSrcAddr(ctx, (&net.TCPAddr{IP: clientIP})) + } + + ctx = ictx.ContextWithRecorderObject(ctx, ro) + ctx = ictx.ContextWithLogger(ctx, log) resp, err := ep.transport.RoundTrip(req.WithContext(ctx)) @@ -580,9 +581,9 @@ func (ep *entrypoint) HandleTLS(ctx context.Context, conn net.Conn, ro *xrecorde ro.Host = host } - ctx = ctxvalue.ContextWithClientAddr(ctx, ctxvalue.ClientAddr(ro.RemoteAddr)) - ctx = ctx_internal.ContextWithRecorderObject(ctx, ro) - ctx = ctxvalue.ContextWithLogger(ctx, log) + // ctx = xctx.ContextWithClientAddr(ctx, xctx.ClientAddr(ro.RemoteAddr)) + ctx = ictx.ContextWithRecorderObject(ctx, ro) + ctx = ictx.ContextWithLogger(ctx, log) cc, err := ep.dial(ctx, "tcp", host) if err != nil { diff --git a/handler/tunnel/handler.go b/handler/tunnel/handler.go index 53a98c4d..dd06584b 100644 --- a/handler/tunnel/handler.go +++ b/handler/tunnel/handler.go @@ -18,7 +18,7 @@ import ( "github.com/go-gost/core/observer" "github.com/go-gost/core/service" "github.com/go-gost/relay" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" xnet "github.com/go-gost/x/internal/net" stats_util "github.com/go-gost/x/internal/util/stats" rate_limiter "github.com/go-gost/x/limiter/rate" @@ -187,19 +187,16 @@ func (h *tunnelHandler) initEntrypoint() (err error) { func (h *tunnelHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.HandleOption) (err error) { start := time.Now() - clientIP := conn.RemoteAddr().String() - if clientAddr := ctxvalue.ClientAddrFromContext(ctx); clientAddr != "" { - clientIP = string(clientAddr) - } - if h, _, _ := net.SplitHostPort(clientIP); h != "" { - clientIP = h + var clientAddr string + if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil { + clientAddr = srcAddr.String() } log := h.log.WithFields(map[string]any{ "remote": conn.RemoteAddr().String(), "local": conn.LocalAddr().String(), - "sid": ctxvalue.SidFromContext(ctx), - "client": clientIP, + "client": clientAddr, + "sid": xctx.SidFromContext(ctx).String(), }) log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr()) @@ -286,7 +283,7 @@ func (h *tunnelHandler) Handle(ctx context.Context, conn net.Conn, opts ...handl resp.WriteTo(conn) return ErrUnauthorized } - ctx = ctxvalue.ContextWithClientID(ctx, ctxvalue.ClientID(clientID)) + ctx = xctx.ContextWithClientID(ctx, xctx.ClientID(clientID)) } switch req.Cmd & relay.CmdMask { diff --git a/hop/plugin/grpc.go b/hop/plugin/grpc.go index ed5671b0..c3653339 100644 --- a/hop/plugin/grpc.go +++ b/hop/plugin/grpc.go @@ -12,7 +12,7 @@ import ( "github.com/go-gost/plugin/hop/proto" "github.com/go-gost/x/config" node_parser "github.com/go-gost/x/config/parsing/node" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/plugin" "google.golang.org/grpc" ) @@ -61,14 +61,18 @@ func (p *grpcPlugin) Select(ctx context.Context, opts ...hop.SelectOption) *chai opt(&options) } + var srcAddr string + if addr := xctx.SrcAddrFromContext(ctx); addr != nil { + srcAddr = addr.String() + } r, err := p.client.Select(ctx, &proto.SelectRequest{ Network: options.Network, Addr: options.Addr, Host: options.Host, Path: options.Path, - Client: string(ctxvalue.ClientIDFromContext(ctx)), - Src: string(ctxvalue.ClientAddrFromContext(ctx)), + Client: xctx.ClientIDFromContext(ctx).String(), + Src: srcAddr, }) if err != nil { p.log.Error(err) diff --git a/hop/plugin/http.go b/hop/plugin/http.go index b08280d3..e676542d 100644 --- a/hop/plugin/http.go +++ b/hop/plugin/http.go @@ -11,7 +11,7 @@ import ( "github.com/go-gost/core/logger" "github.com/go-gost/x/config" node_parser "github.com/go-gost/x/config/parsing/node" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" "github.com/go-gost/x/internal/plugin" ) @@ -61,13 +61,18 @@ func (p *httpPlugin) Select(ctx context.Context, opts ...hop.SelectOption) *chai opt(&options) } + var srcAddr string + if addr := xctx.SrcAddrFromContext(ctx); addr != nil { + srcAddr = addr.String() + } + rb := httpPluginRequest{ Network: options.Network, Addr: options.Addr, Host: options.Host, Path: options.Path, - Client: string(ctxvalue.ClientIDFromContext(ctx)), - Src: string(ctxvalue.ClientAddrFromContext(ctx)), + Client: xctx.ClientIDFromContext(ctx).String(), + Src: srcAddr, } v, err := json.Marshal(&rb) if err != nil { diff --git a/internal/ctx/value.go b/internal/ctx/value.go index 1c4556c6..271645b3 100644 --- a/internal/ctx/value.go +++ b/internal/ctx/value.go @@ -1,22 +1,80 @@ package ctx import ( + "bytes" "context" + "github.com/go-gost/core/logger" + "github.com/go-gost/core/metadata" + xctx "github.com/go-gost/x/ctx" xrecorder "github.com/go-gost/x/recorder" ) +type bufferKey struct{} + +func ContextWithBuffer(ctx context.Context, buffer *bytes.Buffer) context.Context { + return context.WithValue(ctx, bufferKey{}, buffer) +} + +func BufferFromContext(ctx context.Context) *bytes.Buffer { + v, _ := ctx.Value(bufferKey{}).(*bytes.Buffer) + return v +} + +type loggerKey struct{} + +func ContextWithLogger(ctx context.Context, log logger.Logger) context.Context { + return context.WithValue(ctx, loggerKey{}, log) +} + +func LoggerFromContext(ctx context.Context) logger.Logger { + v, _ := ctx.Value(loggerKey{}).(logger.Logger) + return v +} + +type mdKey struct{} + +func ContextWithMetadata(ctx context.Context, md metadata.Metadata) context.Context { + return context.WithValue(ctx, mdKey{}, md) +} + +func MetadataFromContext(ctx context.Context) metadata.Metadata { + v, _ := ctx.Value(mdKey{}).(metadata.Metadata) + return v +} + type recorderObjectCtxKey struct{} -var ( - ctxKeyRecorderObject = &recorderObjectCtxKey{} -) - func ContextWithRecorderObject(ctx context.Context, ro *xrecorder.HandlerRecorderObject) context.Context { - return context.WithValue(ctx, ctxKeyRecorderObject, ro) + return context.WithValue(ctx, recorderObjectCtxKey{}, ro) } func RecorderObjectFromContext(ctx context.Context) *xrecorder.HandlerRecorderObject { - v, _ := ctx.Value(ctxKeyRecorderObject).(*xrecorder.HandlerRecorderObject) + v, _ := ctx.Value(recorderObjectCtxKey{}).(*xrecorder.HandlerRecorderObject) return v } + +func Copy(ctx context.Context) context.Context { + if ctx == nil { + return nil + } + + ctx2 := context.Background() + if v := xctx.SrcAddrFromContext(ctx); v != nil { + ctx2 = xctx.ContextWithSrcAddr(ctx2, v) + } + if v := xctx.DstAddrFromContext(ctx); v != nil { + ctx2 = xctx.ContextWithDstAddr(ctx2, v) + } + if v := xctx.SidFromContext(ctx); v != "" { + ctx2 = xctx.ContextWithSid(ctx2, v) + } + if v := xctx.ClientIDFromContext(ctx); v != "" { + ctx2 = xctx.ContextWithClientID(ctx2, v) + } + if v := MetadataFromContext(ctx); v != nil { + ctx2 = ContextWithMetadata(ctx2, v) + } + + return ctx2 +} diff --git a/internal/net/net.go b/internal/net/net.go index 3be6eb45..22483ce6 100644 --- a/internal/net/net.go +++ b/internal/net/net.go @@ -26,14 +26,6 @@ type RemoteAddr interface { RemoteAddr() net.Addr } -type SrcAddr interface { - SrcAddr() net.Addr -} - -type DstAddr interface { - DstAddr() net.Addr -} - // tcpraw.TCPConn type SetDSCP interface { SetDSCP(int) error diff --git a/internal/net/proxyproto/conn.go b/internal/net/proxyproto/conn.go index 40fa17dc..c7caa4e0 100644 --- a/internal/net/proxyproto/conn.go +++ b/internal/net/proxyproto/conn.go @@ -1,6 +1,7 @@ package proxyproto import ( + "context" "net" "strconv" @@ -10,6 +11,11 @@ import ( type serverConn struct { net.Conn + ctx context.Context +} + +func (c *serverConn) Context() context.Context { + return c.ctx } func (c *serverConn) RemoteAddr() net.Addr { @@ -26,14 +32,6 @@ func (c *serverConn) LocalAddr() net.Addr { return c.Conn.LocalAddr() } -func (c *serverConn) SrcAddr() net.Addr { - return c.Conn.RemoteAddr() -} - -func (c *serverConn) DstAddr() net.Addr { - return c.Conn.LocalAddr() -} - func (c *serverConn) CloseRead() error { if sc, ok := c.Conn.(xio.CloseRead); ok { return sc.CloseRead() diff --git a/internal/net/proxyproto/listener.go b/internal/net/proxyproto/listener.go index cd043175..497b3b80 100644 --- a/internal/net/proxyproto/listener.go +++ b/internal/net/proxyproto/listener.go @@ -1,9 +1,11 @@ package proxyproto import ( + "context" "net" "time" + "github.com/go-gost/x/ctx" proxyproto "github.com/pires/go-proxyproto" ) @@ -16,7 +18,18 @@ func (ln *listener) Accept() (net.Conn, error) { if err != nil { return nil, err } - return &serverConn{Conn: conn}, nil + + innerCtx := context.Background() + if c, ok := conn.(ctx.Context); ok { + if v := c.Context(); v != nil { + innerCtx = v + } + } + + innerCtx = ctx.ContextWithSrcAddr(innerCtx, conn.RemoteAddr()) + innerCtx = ctx.ContextWithDstAddr(innerCtx, conn.LocalAddr()) + + return &serverConn{Conn: conn, ctx: innerCtx}, nil } func WrapListener(ppv int, ln net.Listener, readHeaderTimeout time.Duration) net.Listener { diff --git a/internal/util/forwarder/sniffer.go b/internal/util/forwarder/sniffer.go index 86f529d3..ef06265f 100644 --- a/internal/util/forwarder/sniffer.go +++ b/internal/util/forwarder/sniffer.go @@ -27,7 +27,7 @@ import ( dissector "github.com/go-gost/tls-dissector" xbypass "github.com/go-gost/x/bypass" "github.com/go-gost/x/config" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" xio "github.com/go-gost/x/internal/io" xnet "github.com/go-gost/x/internal/net" xhttp "github.com/go-gost/x/internal/net/http" @@ -161,15 +161,7 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO if clientIP := xhttp.GetClientIP(req); clientIP != nil { ro.ClientIP = clientIP.String() - } - { - clientAddr := ro.RemoteAddr - if ro.ClientIP != "" { - if _, port, _ := net.SplitHostPort(ro.RemoteAddr); port != "" { - clientAddr = net.JoinHostPort(ro.ClientIP, port) - } - } - ctx = ctxvalue.ContextWithClientAddr(ctx, ctxvalue.ClientAddr(clientAddr)) + ctx = xctx.ContextWithSrcAddr(ctx, &net.TCPAddr{IP: clientIP}) } // http/2 @@ -187,8 +179,8 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO log := ho.Log log.Debugf("connected to node %s(%s)", node.Name, node.Addr) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() ro.Time = time.Time{} shouldClose, err := h.httpRoundTrip(ctx, xio.NewReadWriteCloser(br, conn, conn), cc, node, req, &pStats, &ho) @@ -343,8 +335,8 @@ func (h *Sniffer) serveH2(ctx context.Context, conn net.Conn, ho *HandleOptions) } log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() log.Debugf("connected to node %s(%s)", node.Name, node.Addr) return cc, nil }, @@ -435,7 +427,7 @@ func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriteCloser, err = errors.New("unauthorized") return } - ctx = ctxvalue.ContextWithClientID(ctx, ctxvalue.ClientID(id)) + ctx = xctx.ContextWithClientID(ctx, xctx.ClientID(id)) } if httpSettings.Host != "" { @@ -797,7 +789,7 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp ro.TLS.Proto = clientHello.SupportedProtos[0] } - ctx = ctxvalue.ContextWithClientAddr(ctx, ctxvalue.ClientAddr(ro.RemoteAddr)) + // ctx = xctx.ContextWithClientAddr(ctx, xctx.ClientAddr(ro.RemoteAddr)) host := clientHello.ServerName if host != "" { @@ -821,8 +813,8 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp 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.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() if h.Certificate != nil && h.PrivateKey != nil && len(clientHello.SupportedProtos) > 0 && (clientHello.SupportedProtos[0] == "h2" || clientHello.SupportedProtos[0] == "http/1.1") { diff --git a/internal/util/mux/mux.go b/internal/util/mux/mux.go index e17a42d0..a462b4db 100644 --- a/internal/util/mux/mux.go +++ b/internal/util/mux/mux.go @@ -1,11 +1,11 @@ package mux import ( + "context" "net" "time" - "github.com/go-gost/core/metadata" - xnet "github.com/go-gost/x/internal/net" + "github.com/go-gost/x/ctx" smux "github.com/xtaci/smux" ) @@ -145,27 +145,13 @@ func (c *streamConn) Write(b []byte) (n int, err error) { return c.stream.Write(b) } -func (c *streamConn) Metadata() metadata.Metadata { - if md, ok := c.Conn.(metadata.Metadatable); ok { - return md.Metadata() - } - return nil -} - -func (c *streamConn) SrcAddr() net.Addr { - if sc, ok := c.Conn.(xnet.SrcAddr); ok { - return sc.SrcAddr() - } - return nil -} - -func (c *streamConn) DstAddr() net.Addr { - if sc, ok := c.Conn.(xnet.DstAddr); ok { - return sc.DstAddr() - } - return nil -} - func (c *streamConn) Close() error { return c.stream.Close() } + +func (c *streamConn) Context() context.Context { + if sc, ok := c.Conn.(ctx.Context); ok { + return sc.Context() + } + return nil +} diff --git a/internal/util/sniffing/sniffer.go b/internal/util/sniffing/sniffer.go index b769127d..f0566dcb 100644 --- a/internal/util/sniffing/sniffer.go +++ b/internal/util/sniffing/sniffer.go @@ -24,7 +24,7 @@ import ( "github.com/go-gost/core/recorder" dissector "github.com/go-gost/tls-dissector" xbypass "github.com/go-gost/x/bypass" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" xio "github.com/go-gost/x/internal/io" xnet "github.com/go-gost/x/internal/net" xhttp "github.com/go-gost/x/internal/net/http" @@ -151,16 +151,9 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO if clientIP := xhttp.GetClientIP(req); clientIP != nil { ro.ClientIP = clientIP.String() + ctx = xctx.ContextWithSrcAddr(ctx, &net.TCPAddr{IP: clientIP}) } - clientAddr := ro.RemoteAddr - if ro.ClientIP != "" { - if _, port, _ := net.SplitHostPort(ro.RemoteAddr); port != "" { - clientAddr = net.JoinHostPort(ro.ClientIP, port) - } - } - ctx = ctxvalue.ContextWithClientAddr(ctx, ctxvalue.ClientAddr(clientAddr)) - // 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) @@ -194,8 +187,8 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() ro.Time = time.Time{} shouldClose, err := h.httpRoundTrip(ctx, xio.NewReadWriteCloser(br, conn, conn), cc, req, ro, &pStats, log) @@ -254,8 +247,8 @@ func (h *Sniffer) serveH2(ctx context.Context, conn net.Conn, ho *HandleOptions) } log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() cc = tls.Client(cc, cfg) return cc, nil @@ -598,7 +591,7 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp ro.TLS.Proto = clientHello.SupportedProtos[0] } - ctx = ctxvalue.ContextWithClientAddr(ctx, ctxvalue.ClientAddr(ro.RemoteAddr)) + // ctx = xctx.ContextWithClientAddr(ctx, xctx.ClientAddr(ro.RemoteAddr)) host := clientHello.ServerName if host != "" { @@ -623,8 +616,8 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp defer cc.Close() log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()}) - ro.Src = cc.LocalAddr().String() - ro.Dst = cc.RemoteAddr().String() + ro.SrcAddr = cc.LocalAddr().String() + ro.DstAddr = cc.RemoteAddr().String() if h.Certificate != nil && h.PrivateKey != nil && len(clientHello.SupportedProtos) > 0 && (clientHello.SupportedProtos[0] == "h2" || clientHello.SupportedProtos[0] == "http/1.1") { diff --git a/internal/util/tls/listener.go b/internal/util/tls/listener.go index c227b496..95aa6af1 100644 --- a/internal/util/tls/listener.go +++ b/internal/util/tls/listener.go @@ -1,11 +1,11 @@ package tls import ( + "context" "crypto/tls" "net" - "github.com/go-gost/core/metadata" - xnet "github.com/go-gost/x/internal/net" + "github.com/go-gost/x/ctx" ) type listener struct { @@ -34,23 +34,9 @@ type tlsConn struct { *tls.Conn } -func (c *tlsConn) Metadata() metadata.Metadata { - if md, ok := c.NetConn().(metadata.Metadatable); ok { - return md.Metadata() - } - return nil -} - -func (c *tlsConn) SrcAddr() net.Addr { - if sc, ok := c.NetConn().(xnet.SrcAddr); ok { - return sc.SrcAddr() - } - return nil -} - -func (c *tlsConn) DstAddr() net.Addr { - if sc, ok := c.NetConn().(xnet.DstAddr); ok { - return sc.DstAddr() +func (c *tlsConn) Context() context.Context { + if sc, ok := c.NetConn().(ctx.Context); ok { + return sc.Context() } return nil } diff --git a/internal/util/ws/ws.go b/internal/util/ws/ws.go index 02138a4b..eb7b32a0 100644 --- a/internal/util/ws/ws.go +++ b/internal/util/ws/ws.go @@ -1,12 +1,13 @@ package ws import ( + "context" "net" "sync" "time" + ctx_pkg "github.com/go-gost/x/ctx" xio "github.com/go-gost/x/internal/io" - xnet "github.com/go-gost/x/internal/net" "github.com/gorilla/websocket" ) @@ -14,28 +15,31 @@ type WebsocketConn interface { net.Conn WriteMessage(int, []byte) error ReadMessage() (int, []byte, error) - xnet.SrcAddr xio.CloseRead xio.CloseWrite } type websocketConn struct { *websocket.Conn - rb []byte - srcAddr net.Addr - mux sync.Mutex + rb []byte + ctx context.Context + mux sync.Mutex } func Conn(conn *websocket.Conn) WebsocketConn { - return &websocketConn{ - Conn: conn, + ctx := context.Background() + if cc, ok := conn.NetConn().(ctx_pkg.Context); ok { + if cv := cc.Context(); cv != nil { + ctx = cv + } } + return ContextConn(ctx, conn) } -func ConnWithSrcAddr(conn *websocket.Conn, srcAddr net.Addr) WebsocketConn { +func ContextConn(ctx context.Context, conn *websocket.Conn) WebsocketConn { return &websocketConn{ - Conn: conn, - srcAddr: srcAddr, + Conn: conn, + ctx: ctx, } } @@ -80,13 +84,6 @@ func (c *websocketConn) SetWriteDeadline(t time.Time) error { return c.Conn.SetWriteDeadline(t) } -func (c *websocketConn) SrcAddr() net.Addr { - if sa, ok := c.Conn.NetConn().(xnet.SrcAddr); ok { - return sa.SrcAddr() - } - return c.srcAddr -} - func (c *websocketConn) CloseRead() error { if sc, ok := c.Conn.NetConn().(xio.CloseRead); ok { return sc.CloseRead() @@ -100,3 +97,7 @@ func (c *websocketConn) CloseWrite() error { } return xio.ErrUnsupported } + +func (c *websocketConn) Context() context.Context { + return c.ctx +} diff --git a/limiter/conn/wrapper/conn.go b/limiter/conn/wrapper/conn.go index 5f6ed359..61b4718c 100644 --- a/limiter/conn/wrapper/conn.go +++ b/limiter/conn/wrapper/conn.go @@ -1,12 +1,13 @@ package wrapper import ( + "context" "errors" "net" "syscall" limiter "github.com/go-gost/core/limiter/conn" - "github.com/go-gost/core/metadata" + "github.com/go-gost/x/ctx" xio "github.com/go-gost/x/internal/io" ) @@ -44,13 +45,6 @@ func (c *serverConn) Close() error { return c.Conn.Close() } -func (c *serverConn) Metadata() metadata.Metadata { - if md, ok := c.Conn.(metadata.Metadatable); ok { - return md.Metadata() - } - return nil -} - func (c *serverConn) CloseRead() error { if sc, ok := c.Conn.(xio.CloseRead); ok { return sc.CloseRead() @@ -64,3 +58,10 @@ func (c *serverConn) CloseWrite() error { } return xio.ErrUnsupported } + +func (c *serverConn) Context() context.Context { + if innerCtx, ok := c.Conn.(ctx.Context); ok { + return innerCtx.Context() + } + return nil +} diff --git a/limiter/traffic/wrapper/conn.go b/limiter/traffic/wrapper/conn.go index 5c71df89..c41f8119 100644 --- a/limiter/traffic/wrapper/conn.go +++ b/limiter/traffic/wrapper/conn.go @@ -10,7 +10,7 @@ import ( "github.com/go-gost/core/limiter" "github.com/go-gost/core/limiter/traffic" - "github.com/go-gost/core/metadata" + "github.com/go-gost/x/ctx" xio "github.com/go-gost/x/internal/io" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/net/udp" @@ -100,23 +100,9 @@ func (c *limitConn) SyscallConn() (rc syscall.RawConn, err error) { return } -func (c *limitConn) Metadata() metadata.Metadata { - if md, ok := c.Conn.(metadata.Metadatable); ok { - return md.Metadata() - } - return nil -} - -func (c *limitConn) SrcAddr() net.Addr { - if sc, ok := c.Conn.(xnet.SrcAddr); ok { - return sc.SrcAddr() - } - return nil -} - -func (c *limitConn) DstAddr() net.Addr { - if sc, ok := c.Conn.(xnet.DstAddr); ok { - return sc.DstAddr() +func (c *limitConn) Context() context.Context { + if innerCtx, ok := c.Conn.(ctx.Context); ok { + return innerCtx.Context() } return nil } @@ -187,9 +173,9 @@ func (c *packetConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { return c.PacketConn.WriteTo(p, addr) } -func (c *packetConn) Metadata() metadata.Metadata { - if md, ok := c.PacketConn.(metadata.Metadatable); ok { - return md.Metadata() +func (c *packetConn) Context() context.Context { + if innerCtx, ok := c.PacketConn.(ctx.Context); ok { + return innerCtx.Context() } return nil } @@ -441,9 +427,9 @@ func (c *udpConn) SetDSCP(n int) error { return nil } -func (c *udpConn) Metadata() metadata.Metadata { - if md, ok := c.PacketConn.(metadata.Metadatable); ok { - return md.Metadata() +func (c *udpConn) Context() context.Context { + if innerCtx, ok := c.PacketConn.(ctx.Context); ok { + return innerCtx.Context() } return nil } diff --git a/listener/grpc/server.go b/listener/grpc/server.go index 112b9fa4..24568722 100644 --- a/listener/grpc/server.go +++ b/listener/grpc/server.go @@ -1,6 +1,7 @@ package grpc import ( + "context" "errors" "io" "net" @@ -8,6 +9,7 @@ import ( "time" "github.com/go-gost/core/logger" + xctx "github.com/go-gost/x/ctx" pb "github.com/go-gost/x/internal/util/grpc/proto" mdata "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" @@ -30,12 +32,16 @@ func (s *server) Tunnel(srv pb.GostTunel_TunnelServer) error { if p, ok := peer.FromContext(srv.Context()); ok { c.remoteAddr = p.Addr } + + ctx := srv.Context() if md, ok := mdata.FromIncomingContext(srv.Context()); ok { if cip := getClientIP(md); cip != nil { - c.clientAddr = &net.IPAddr{IP: cip} + ctx = xctx.ContextWithSrcAddr(ctx, &net.TCPAddr{IP: cip}) } } + c.ctx = ctx + select { case s.cqueue <- c: default: @@ -80,8 +86,8 @@ type conn struct { rb []byte localAddr net.Addr remoteAddr net.Addr - clientAddr net.Addr closed chan struct{} + ctx context.Context } func (c *conn) Read(b []byte) (n int, err error) { @@ -146,10 +152,6 @@ func (c *conn) RemoteAddr() net.Addr { return c.remoteAddr } -func (c *conn) ClientAddr() net.Addr { - return c.clientAddr -} - func (c *conn) SetDeadline(t time.Time) error { return &net.OpError{Op: "set", Net: "grpc", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} } @@ -161,3 +163,7 @@ func (c *conn) SetReadDeadline(t time.Time) error { func (c *conn) SetWriteDeadline(t time.Time) error { return &net.OpError{Op: "set", Net: "grpc", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} } + +func (c *conn) Context() context.Context { + return c.ctx +} diff --git a/listener/http2/conn.go b/listener/http2/conn.go index 86549983..45199624 100644 --- a/listener/http2/conn.go +++ b/listener/http2/conn.go @@ -1,20 +1,18 @@ package http2 import ( + "context" "errors" "net" "time" - - mdata "github.com/go-gost/core/metadata" ) // a dummy HTTP2 server conn used by HTTP2 handler type conn struct { - md mdata.Metadata - laddr net.Addr - raddr net.Addr - srcAddr net.Addr - closed chan struct{} + laddr net.Addr + raddr net.Addr + closed chan struct{} + ctx context.Context } func (c *conn) Read(b []byte) (n int, err error) { @@ -42,10 +40,6 @@ func (c *conn) RemoteAddr() net.Addr { return c.raddr } -func (c *conn) SrcAddr() net.Addr { - return c.srcAddr -} - func (c *conn) SetDeadline(t time.Time) error { return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} } @@ -62,7 +56,6 @@ func (c *conn) Done() <-chan struct{} { return c.closed } -// Metadata implements metadata.Metadatable interface. -func (c *conn) Metadata() mdata.Metadata { - return c.md +func (c *conn) Context() context.Context { + return c.ctx } diff --git a/listener/http2/h2/conn.go b/listener/http2/h2/conn.go index 30fdeb2e..956cc1d1 100644 --- a/listener/http2/h2/conn.go +++ b/listener/http2/h2/conn.go @@ -1,6 +1,7 @@ package h2 import ( + "context" "errors" "io" "net" @@ -14,8 +15,8 @@ type conn struct { w io.Writer remoteAddr net.Addr localAddr net.Addr - srcAddr net.Addr closed chan struct{} + ctx context.Context } func (c *conn) Read(b []byte) (n int, err error) { @@ -50,10 +51,6 @@ func (c *conn) RemoteAddr() net.Addr { return c.remoteAddr } -func (c *conn) SrcAddr() net.Addr { - return c.srcAddr -} - func (c *conn) SetDeadline(t time.Time) error { return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} } @@ -66,6 +63,10 @@ func (c *conn) SetWriteDeadline(t time.Time) error { return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} } +func (c *conn) Context() context.Context { + return c.ctx +} + type flushWriter struct { w io.Writer } diff --git a/listener/http2/h2/listener.go b/listener/http2/h2/listener.go index 29d25604..650c5392 100644 --- a/listener/http2/h2/listener.go +++ b/listener/http2/h2/listener.go @@ -14,6 +14,7 @@ import ( "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" admission "github.com/go-gost/x/admission/wrapper" + xctx "github.com/go-gost/x/ctx" xnet "github.com/go-gost/x/internal/net" xhttp "github.com/go-gost/x/internal/net/http" "github.com/go-gost/x/internal/net/proxyproto" @@ -36,7 +37,7 @@ type h2Listener struct { addr net.Addr cqueue chan net.Conn errChan chan error - logger logger.Logger + log logger.Logger md metadata h2c bool options listener.Options @@ -49,7 +50,7 @@ func NewListener(opts ...listener.Option) listener.Listener { } return &h2Listener{ h2c: true, - logger: options.Logger, + log: options.Logger, options: options, } } @@ -60,7 +61,7 @@ func NewTLSListener(opts ...listener.Option) listener.Listener { opt(&options) } return &h2Listener{ - logger: options.Logger, + log: options.Logger, options: options, } } @@ -72,6 +73,21 @@ func (l *h2Listener) Init(md md.Metadata) (err error) { l.server = &http.Server{ Addr: l.options.Addr, + ConnContext: func(ctx context.Context, c net.Conn) context.Context { + if tlsConn, ok := c.(*tls.Conn); ok { + if cc, ok := tlsConn.NetConn().(xctx.Context); ok { + if cv := cc.Context(); cv != nil { + return cv + } + } + } + if cc, ok := c.(xctx.Context); ok { + if cv := cc.Context(); cv != nil { + return cv + } + } + return ctx + }, } network := "tcp" @@ -81,7 +97,7 @@ func (l *h2Listener) Init(md md.Metadata) (err error) { lc := net.ListenConfig{} if l.md.mptcp { lc.SetMultipathTCP(true) - l.logger.Debugf("mptcp enabled: %v", lc.MultipathTCP()) + l.log.Debugf("mptcp enabled: %v", lc.MultipathTCP()) } ln, err := lc.Listen(context.Background(), network, l.options.Addr) if err != nil { @@ -113,7 +129,7 @@ func (l *h2Listener) Init(md md.Metadata) (err error) { go func() { if err := l.server.Serve(ln); err != nil { - l.logger.Error(err) + l.log.Error(err) } }() @@ -150,10 +166,10 @@ func (l *h2Listener) Close() (err error) { case <-l.errChan: default: err = l.server.Close() - l.errChan <- err + l.errChan <- http.ErrServerClosed close(l.errChan) } - return nil + return } func (l *h2Listener) handleFunc(w http.ResponseWriter, r *http.Request) { @@ -162,25 +178,25 @@ func (l *h2Listener) handleFunc(w http.ResponseWriter, r *http.Request) { if clientIP != nil { cip = clientIP.String() } - log := l.logger.WithFields(map[string]any{ + log := l.log.WithFields(map[string]any{ "local": l.addr.String(), "remote": r.RemoteAddr, "client": cip, }) if log.IsLevelEnabled(logger.TraceLevel) { dump, _ := httputil.DumpRequest(r, false) - l.logger.Trace(string(dump)) + log.Trace(string(dump)) } conn, err := l.upgrade(w, r) if err != nil { - l.logger.Error(err) + l.log.Error(err) return } select { case l.cqueue <- conn: default: conn.Close() - l.logger.Warnf("connection queue is full, client %s discarded", r.RemoteAddr) + l.log.Warnf("connection queue is full, client %s discarded", r.RemoteAddr) } <-conn.closed // NOTE: we need to wait for streaming end, or the connection will be closed @@ -209,9 +225,9 @@ func (l *h2Listener) upgrade(w http.ResponseWriter, r *http.Request) (*conn, err } } - var srcAddr net.Addr + ctx := r.Context() if clientIP := xhttp.GetClientIP(r); clientIP != nil { - srcAddr = &net.TCPAddr{IP: clientIP} + ctx = xctx.ContextWithSrcAddr(ctx, &net.TCPAddr{IP: clientIP}) } return &conn{ @@ -219,7 +235,7 @@ func (l *h2Listener) upgrade(w http.ResponseWriter, r *http.Request) (*conn, err w: flushWriter{w}, localAddr: l.addr, remoteAddr: remoteAddr, - srcAddr: srcAddr, closed: make(chan struct{}), + ctx: ctx, }, nil } diff --git a/listener/http2/listener.go b/listener/http2/listener.go index 1f7af845..db13430e 100644 --- a/listener/http2/listener.go +++ b/listener/http2/listener.go @@ -12,6 +12,8 @@ import ( "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" admission "github.com/go-gost/x/admission/wrapper" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" xhttp "github.com/go-gost/x/internal/net/http" "github.com/go-gost/x/internal/net/proxyproto" @@ -33,7 +35,7 @@ type http2Listener struct { addr net.Addr cqueue chan net.Conn errChan chan error - logger logger.Logger + log logger.Logger md metadata options listener.Options } @@ -44,7 +46,7 @@ func NewListener(opts ...listener.Option) listener.Listener { opt(&options) } return &http2Listener{ - logger: options.Logger, + log: options.Logger, options: options, } } @@ -58,6 +60,21 @@ func (l *http2Listener) Init(md md.Metadata) (err error) { Addr: l.options.Addr, Handler: http.HandlerFunc(l.handleFunc), TLSConfig: l.options.TLSConfig, + ConnContext: func(ctx context.Context, c net.Conn) context.Context { + if tlsConn, ok := c.(*tls.Conn); ok { + if cc, ok := tlsConn.NetConn().(xctx.Context); ok { + if cv := cc.Context(); cv != nil { + return cv + } + } + } + if cc, ok := c.(xctx.Context); ok { + if cv := cc.Context(); cv != nil { + return cv + } + } + return ctx + }, } if err := http2.ConfigureServer(l.server, nil); err != nil { return err @@ -70,7 +87,7 @@ func (l *http2Listener) Init(md md.Metadata) (err error) { lc := net.ListenConfig{} if l.md.mptcp { lc.SetMultipathTCP(true) - l.logger.Debugf("mptcp enabled: %v", lc.MultipathTCP()) + l.log.Debugf("mptcp enabled: %v", lc.MultipathTCP()) } ln, err := lc.Listen(context.Background(), network, l.options.Addr) if err != nil { @@ -83,7 +100,6 @@ func (l *http2Listener) Init(md md.Metadata) (err error) { ln = admission.WrapListener(l.options.Admission, ln) ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter) ln = climiter.WrapListener(l.options.ConnLimiter, ln) - ln = tls.NewListener( ln, l.options.TLSConfig, @@ -94,7 +110,7 @@ func (l *http2Listener) Init(md md.Metadata) (err error) { go func() { if err := l.server.Serve(ln); err != nil { - l.logger.Error(err) + l.log.Error(err) } }() @@ -146,26 +162,27 @@ func (l *http2Listener) handleFunc(w http.ResponseWriter, r *http.Request) { } } - var srcAddr net.Addr + ctx := r.Context() if clientIP := xhttp.GetClientIP(r); clientIP != nil { - srcAddr = &net.TCPAddr{IP: clientIP} + ctx = xctx.ContextWithSrcAddr(ctx, &net.TCPAddr{IP: clientIP}) } + ctx = ictx.ContextWithMetadata(ctx, mdx.NewMetadata(map[string]any{ + "r": r, + "w": w, + })) + conn := &conn{ - laddr: l.addr, - raddr: remoteAddr, - srcAddr: srcAddr, - closed: make(chan struct{}), - md: mdx.NewMetadata(map[string]any{ - "r": r, - "w": w, - }), + laddr: l.addr, + raddr: remoteAddr, + closed: make(chan struct{}), + ctx: ctx, } select { case l.cqueue <- conn: default: - l.logger.Warnf("connection queue is full, client %s discarded", r.RemoteAddr) + l.log.Warnf("connection queue is full, client %s discarded", r.RemoteAddr) return } diff --git a/listener/http3/conn.go b/listener/http3/conn.go index 040e11e9..0adcc02d 100644 --- a/listener/http3/conn.go +++ b/listener/http3/conn.go @@ -1,20 +1,18 @@ package http3 import ( + "context" "errors" "net" "time" - - mdata "github.com/go-gost/core/metadata" ) // a dummy HTTP3 server conn used by HTTP3 handler type conn struct { - md mdata.Metadata - laddr net.Addr - raddr net.Addr - srcAddr net.Addr - closed chan struct{} + laddr net.Addr + raddr net.Addr + closed chan struct{} + ctx context.Context } func (c *conn) Read(b []byte) (n int, err error) { @@ -42,10 +40,6 @@ func (c *conn) RemoteAddr() net.Addr { return c.raddr } -func (c *conn) SrcAddr() net.Addr { - return c.srcAddr -} - func (c *conn) SetDeadline(t time.Time) error { return &net.OpError{Op: "set", Net: "http3", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} } @@ -62,7 +56,6 @@ func (c *conn) Done() <-chan struct{} { return c.closed } -// Metadata implements metadata.Metadatable interface. -func (c *conn) Metadata() mdata.Metadata { - return c.md +func (c *conn) Context() context.Context { + return c.ctx } diff --git a/listener/http3/listener.go b/listener/http3/listener.go index d237d773..963d1da7 100644 --- a/listener/http3/listener.go +++ b/listener/http3/listener.go @@ -8,6 +8,8 @@ import ( "github.com/go-gost/core/listener" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" + xctx "github.com/go-gost/x/ctx" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" xhttp "github.com/go-gost/x/internal/net/http" mdx "github.com/go-gost/x/metadata" @@ -131,18 +133,22 @@ func (l *http3Listener) handleFunc(w http.ResponseWriter, r *http.Request) { IP: net.IPv4zero, } } + + ctx := r.Context() + if clientIP := xhttp.GetClientIP(r); clientIP != nil { + ctx = xctx.ContextWithSrcAddr(ctx, &net.UDPAddr{IP: clientIP}) + } + + ctx = ictx.ContextWithMetadata(ctx, mdx.NewMetadata(map[string]any{ + "r": r, + "w": w, + })) + conn := &conn{ laddr: l.addr, raddr: remoteAddr, closed: make(chan struct{}), - md: mdx.NewMetadata(map[string]any{ - "r": r, - "w": w, - }), - } - - if clientIP := xhttp.GetClientIP(r); clientIP != nil { - conn.srcAddr = &net.UDPAddr{IP: clientIP} + ctx: ctx, } select { diff --git a/listener/mws/listener.go b/listener/mws/listener.go index 50091582..7155c642 100644 --- a/listener/mws/listener.go +++ b/listener/mws/listener.go @@ -12,6 +12,7 @@ import ( "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" admission "github.com/go-gost/x/admission/wrapper" + xctx "github.com/go-gost/x/ctx" xnet "github.com/go-gost/x/internal/net" xhttp "github.com/go-gost/x/internal/net/http" "github.com/go-gost/x/internal/net/proxyproto" @@ -184,12 +185,18 @@ func (l *mwsListener) upgrade(w http.ResponseWriter, r *http.Request) { return } - var srcAddr net.Addr - if clientIP != nil { - srcAddr = &net.TCPAddr{IP: clientIP} + ctx := r.Context() + if cc, ok := conn.NetConn().(xctx.Context); ok { + if cv := cc.Context(); cv != nil { + ctx = cv + } } - l.mux(ws_util.ConnWithSrcAddr(conn, srcAddr), log) + if clientIP != nil { + ctx = xctx.ContextWithSrcAddr(ctx, &net.TCPAddr{IP: clientIP}) + } + + l.mux(ws_util.ContextConn(ctx, conn), log) } func (l *mwsListener) mux(conn net.Conn, log logger.Logger) { diff --git a/listener/tap/conn.go b/listener/tap/conn.go index 0874d65d..72dbfa12 100644 --- a/listener/tap/conn.go +++ b/listener/tap/conn.go @@ -6,14 +6,13 @@ import ( "io" "net" "time" - - mdata "github.com/go-gost/core/metadata" ) type conn struct { ifce io.ReadWriteCloser laddr net.Addr raddr net.Addr + ctx context.Context cancel context.CancelFunc } @@ -52,19 +51,6 @@ func (c *conn) Close() (err error) { return c.ifce.Close() } -type metadataConn struct { - net.Conn - md mdata.Metadata -} - -// Metadata implements metadata.Metadatable interface. -func (c *metadataConn) Metadata() mdata.Metadata { - return c.md -} - -func withMetadata(md mdata.Metadata, c net.Conn) net.Conn { - return &metadataConn{ - Conn: c, - md: md, - } +func (c *conn) Context() context.Context { + return c.ctx } diff --git a/listener/tap/listener.go b/listener/tap/listener.go index 157560cc..e86ff31f 100644 --- a/listener/tap/listener.go +++ b/listener/tap/listener.go @@ -9,6 +9,7 @@ import ( "github.com/go-gost/core/listener" "github.com/go-gost/core/logger" mdata "github.com/go-gost/core/metadata" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" traffic_limiter "github.com/go-gost/x/limiter/traffic" limiter_wrapper "github.com/go-gost/x/limiter/traffic/wrapper" @@ -85,11 +86,16 @@ func (l *tapListener) listenLoop() { l.logger.Infof("name: %s, net: %s, mtu: %d, addrs: %s", itf.Name, ip, itf.MTU, addrs) + ctx = ictx.ContextWithMetadata(ctx, mdx.NewMetadata(map[string]any{ + "config": l.md.config, + })) + var c net.Conn c = &conn{ ifce: ifce, laddr: l.addr, raddr: &net.IPAddr{IP: ip}, + ctx: ctx, cancel: cancel, } c = metrics.WrapConn(l.options.Service, c) @@ -102,9 +108,6 @@ func (l *tapListener) listenLoop() { limiter.ServiceOption(l.options.Service), limiter.NetworkOption(c.LocalAddr().Network()), ) - c = withMetadata(mdx.NewMetadata(map[string]any{ - "config": l.md.config, - }), c) l.cqueue <- c diff --git a/listener/tun/conn.go b/listener/tun/conn.go index 20c01857..9fe68b7c 100644 --- a/listener/tun/conn.go +++ b/listener/tun/conn.go @@ -6,14 +6,13 @@ import ( "io" "net" "time" - - mdata "github.com/go-gost/core/metadata" ) type conn struct { ifce io.ReadWriteCloser laddr net.Addr raddr net.Addr + ctx context.Context cancel context.CancelFunc } @@ -52,19 +51,6 @@ func (c *conn) Close() (err error) { return c.ifce.Close() } -type metadataConn struct { - net.Conn - md mdata.Metadata -} - -// Metadata implements metadata.Metadatable interface. -func (c *metadataConn) Metadata() mdata.Metadata { - return c.md -} - -func withMetadata(md mdata.Metadata, c net.Conn) net.Conn { - return &metadataConn{ - Conn: c, - md: md, - } +func (c *conn) Context() context.Context { + return c.ctx } diff --git a/listener/tun/listener.go b/listener/tun/listener.go index 20d4460e..551a339e 100644 --- a/listener/tun/listener.go +++ b/listener/tun/listener.go @@ -10,6 +10,7 @@ import ( "github.com/go-gost/core/logger" mdata "github.com/go-gost/core/metadata" "github.com/go-gost/core/router" + ictx "github.com/go-gost/x/internal/ctx" xnet "github.com/go-gost/x/internal/net" traffic_limiter "github.com/go-gost/x/limiter/traffic" limiter_wrapper "github.com/go-gost/x/limiter/traffic/wrapper" @@ -92,11 +93,16 @@ func (l *tunListener) listenLoop(ready context.CancelCauseFunc) { l.log.Infof("name: %s, net: %s, mtu: %d, addrs: %s", itf.Name, ip, l.md.config.MTU, addrs) + ctx = ictx.ContextWithMetadata(ctx, mdx.NewMetadata(map[string]any{ + "config": l.md.config, + })) + var c net.Conn c = &conn{ ifce: ifce, laddr: l.addr, raddr: &net.IPAddr{IP: ip}, + ctx: ctx, cancel: cancel, } c = metrics.WrapConn(l.options.Service, c) @@ -109,9 +115,6 @@ func (l *tunListener) listenLoop(ready context.CancelCauseFunc) { limiter.ServiceOption(l.options.Service), limiter.NetworkOption(c.LocalAddr().Network()), ) - c = withMetadata(mdx.NewMetadata(map[string]any{ - "config": l.md.config, - }), c) l.cqueue <- c diff --git a/listener/tungo/conn.go b/listener/tungo/conn.go index af9f8e78..2cd2ad88 100644 --- a/listener/tungo/conn.go +++ b/listener/tungo/conn.go @@ -6,14 +6,13 @@ import ( "io" "net" "time" - - mdata "github.com/go-gost/core/metadata" ) type conn struct { ifce io.ReadWriteCloser laddr net.Addr raddr net.Addr + ctx context.Context cancel context.CancelFunc } @@ -52,19 +51,6 @@ func (c *conn) Close() (err error) { return c.ifce.Close() } -type metadataConn struct { - net.Conn - md mdata.Metadata -} - -// Metadata implements metadata.Metadatable interface. -func (c *metadataConn) Metadata() mdata.Metadata { - return c.md -} - -func withMetadata(md mdata.Metadata, c net.Conn) net.Conn { - return &metadataConn{ - Conn: c, - md: md, - } +func (c *conn) Context() context.Context { + return c.ctx } diff --git a/listener/tungo/listener.go b/listener/tungo/listener.go index fbca8490..548e8ff6 100644 --- a/listener/tungo/listener.go +++ b/listener/tungo/listener.go @@ -10,6 +10,7 @@ import ( "github.com/go-gost/core/logger" mdata "github.com/go-gost/core/metadata" "github.com/go-gost/core/router" + ictx "github.com/go-gost/x/internal/ctx" traffic_limiter "github.com/go-gost/x/limiter/traffic" limiter_wrapper "github.com/go-gost/x/limiter/traffic/wrapper" mdx "github.com/go-gost/x/metadata" @@ -85,11 +86,16 @@ func (l *tunListener) listenLoop(ready context.CancelCauseFunc) { l.log.Infof("name: %s, net: %s, mtu: %d, addrs: %s", itf.Name, ip, l.md.config.MTU, addrs) + ctx = ictx.ContextWithMetadata(ctx, mdx.NewMetadata(map[string]any{ + "config": l.md.config, + })) + var c net.Conn c = &conn{ ifce: ifce, laddr: l.addr, raddr: &net.IPAddr{IP: ip}, + ctx: ctx, cancel: cancel, } c = metrics.WrapConn(l.options.Service, c) @@ -102,9 +108,6 @@ func (l *tunListener) listenLoop(ready context.CancelCauseFunc) { limiter.ServiceOption(l.options.Service), limiter.NetworkOption(c.LocalAddr().Network()), ) - c = withMetadata(mdx.NewMetadata(map[string]any{ - "config": l.md.config, - }), c) l.cqueue <- c return nil diff --git a/listener/ws/listener.go b/listener/ws/listener.go index 58b294a5..18ac856d 100644 --- a/listener/ws/listener.go +++ b/listener/ws/listener.go @@ -12,6 +12,7 @@ import ( "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" admission "github.com/go-gost/x/admission/wrapper" + xctx "github.com/go-gost/x/ctx" xnet "github.com/go-gost/x/internal/net" xhttp "github.com/go-gost/x/internal/net/http" "github.com/go-gost/x/internal/net/proxyproto" @@ -179,13 +180,19 @@ func (l *wsListener) upgrade(w http.ResponseWriter, r *http.Request) { return } - var srcAddr net.Addr + ctx := r.Context() + if cc, ok := conn.NetConn().(xctx.Context); ok { + if cv := cc.Context(); cv != nil { + ctx = cv + } + } + if clientIP != nil { - srcAddr = &net.TCPAddr{IP: clientIP} + ctx = xctx.ContextWithSrcAddr(ctx, &net.TCPAddr{IP: clientIP}) } select { - case l.cqueue <- ws_util.ConnWithSrcAddr(conn, srcAddr): + case l.cqueue <- ws_util.ContextConn(ctx, conn): default: conn.Close() log.Warnf("connection queue is full, client %s discarded", conn.RemoteAddr()) diff --git a/metrics/wrapper/conn.go b/metrics/wrapper/conn.go index 547b6b14..1c000902 100644 --- a/metrics/wrapper/conn.go +++ b/metrics/wrapper/conn.go @@ -1,13 +1,14 @@ package wrapper import ( + "context" "errors" "io" "net" "syscall" - "github.com/go-gost/core/metadata" "github.com/go-gost/core/metrics" + "github.com/go-gost/x/ctx" xio "github.com/go-gost/x/internal/io" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/net/udp" @@ -74,27 +75,6 @@ func (c *serverConn) SyscallConn() (rc syscall.RawConn, err error) { return } -func (c *serverConn) Metadata() metadata.Metadata { - if md, ok := c.Conn.(metadata.Metadatable); ok { - return md.Metadata() - } - return nil -} - -func (c *serverConn) SrcAddr() net.Addr { - if sc, ok := c.Conn.(xnet.SrcAddr); ok { - return sc.SrcAddr() - } - return nil -} - -func (c *serverConn) DstAddr() net.Addr { - if sc, ok := c.Conn.(xnet.DstAddr); ok { - return sc.DstAddr() - } - return nil -} - func (c *serverConn) CloseRead() error { if sc, ok := c.Conn.(xio.CloseRead); ok { return sc.CloseRead() @@ -109,6 +89,13 @@ func (c *serverConn) CloseWrite() error { return xio.ErrUnsupported } +func (c *serverConn) Context() context.Context { + if innerCtx, ok := c.Conn.(ctx.Context); ok { + return innerCtx.Context() + } + return nil +} + type packetConn struct { net.PacketConn service string @@ -162,9 +149,9 @@ func (c *packetConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { return } -func (c *packetConn) Metadata() metadata.Metadata { - if md, ok := c.PacketConn.(metadata.Metadatable); ok { - return md.Metadata() +func (c *packetConn) Context() context.Context { + if innerCtx, ok := c.PacketConn.(ctx.Context); ok { + return innerCtx.Context() } return nil } @@ -393,9 +380,9 @@ func (c *udpConn) SetDSCP(n int) error { return nil } -func (c *udpConn) Metadata() metadata.Metadata { - if md, ok := c.PacketConn.(metadata.Metadatable); ok { - return md.Metadata() +func (c *udpConn) Context() context.Context { + if innerCtx, ok := c.PacketConn.(ctx.Context); ok { + return innerCtx.Context() } return nil } diff --git a/observer/stats/wrapper/conn.go b/observer/stats/wrapper/conn.go index 4df0ba2a..196be4eb 100644 --- a/observer/stats/wrapper/conn.go +++ b/observer/stats/wrapper/conn.go @@ -1,14 +1,15 @@ package wrapper import ( + "context" "errors" "io" "net" "sync" "syscall" - "github.com/go-gost/core/metadata" "github.com/go-gost/core/observer/stats" + "github.com/go-gost/x/ctx" xio "github.com/go-gost/x/internal/io" xnet "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/net/udp" @@ -76,27 +77,6 @@ func (c *conn) SyscallConn() (rc syscall.RawConn, err error) { return } -func (c *conn) Metadata() metadata.Metadata { - if md, ok := c.Conn.(metadata.Metadatable); ok { - return md.Metadata() - } - return nil -} - -func (c *conn) SrcAddr() net.Addr { - if sc, ok := c.Conn.(xnet.SrcAddr); ok { - return sc.SrcAddr() - } - return nil -} - -func (c *conn) DstAddr() net.Addr { - if sc, ok := c.Conn.(xnet.DstAddr); ok { - return sc.DstAddr() - } - return nil -} - func (c *conn) CloseRead() error { if sc, ok := c.Conn.(xio.CloseRead); ok { return sc.CloseRead() @@ -111,6 +91,13 @@ func (c *conn) CloseWrite() error { return xio.ErrUnsupported } +func (c *conn) Context() context.Context { + if innerCtx, ok := c.Conn.(ctx.Context); ok { + return innerCtx.Context() + } + return nil +} + type packetConn struct { net.PacketConn stats stats.Stats @@ -138,9 +125,9 @@ func (c *packetConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { return } -func (c *packetConn) Metadata() metadata.Metadata { - if md, ok := c.PacketConn.(metadata.Metadatable); ok { - return md.Metadata() +func (c *packetConn) Context() context.Context { + if innerCtx, ok := c.PacketConn.(ctx.Context); ok { + return innerCtx.Context() } return nil } @@ -281,9 +268,9 @@ func (c *udpConn) SetDSCP(n int) error { return nil } -func (c *udpConn) Metadata() metadata.Metadata { - if md, ok := c.PacketConn.(metadata.Metadatable); ok { - return md.Metadata() +func (c *udpConn) Context() context.Context { + if innerCtx, ok := c.PacketConn.(ctx.Context); ok { + return innerCtx.Context() } return nil } diff --git a/recorder/recorder.go b/recorder/recorder.go index f0f8a9cf..24869628 100644 --- a/recorder/recorder.go +++ b/recorder/recorder.go @@ -72,15 +72,16 @@ type DNSRecorderObject struct { } type HandlerRecorderObject struct { - Node string `json:"node,omitempty"` - Service string `json:"service"` - Network string `json:"network"` - RemoteAddr string `json:"remote"` - LocalAddr string `json:"local"` - Host string `json:"host"` - Src string `json:"src"` - Dst string `json:"dst"` - Proto string `json:"proto,omitempty"` + Node string `json:"node,omitempty"` + Service string `json:"service"` + Network string `json:"network"` + RemoteAddr string `json:"remote"` + LocalAddr string `json:"local"` + ClientAddr string `json:"client"` + SrcAddr string `json:"src"` + DstAddr string `json:"dst"` + Host string `json:"host"` + Proto string `json:"proto,omitempty"` ClientIP string `json:"clientIP"` ClientID string `json:"clientID,omitempty"` HTTP *HTTPRecorderObject `json:"http,omitempty"` diff --git a/selector/strategy.go b/selector/strategy.go index 6c4a0b67..47e8c822 100644 --- a/selector/strategy.go +++ b/selector/strategy.go @@ -10,9 +10,9 @@ import ( "github.com/go-gost/core/logger" "github.com/go-gost/core/metadata" - mdutil "github.com/go-gost/x/metadata/util" "github.com/go-gost/core/selector" - ctxvalue "github.com/go-gost/x/ctx" + xctx "github.com/go-gost/x/ctx" + mdutil "github.com/go-gost/x/metadata/util" ) type roundRobinStrategy[T any] struct { @@ -102,7 +102,7 @@ func (s *hashStrategy[T]) Apply(ctx context.Context, vs ...T) (v T) { if len(vs) == 0 { return } - if h := ctxvalue.HashFromContext(ctx); h != nil { + if h := xctx.HashFromContext(ctx); h != nil { value := uint64(crc32.ChecksumIEEE([]byte(h.Source))) logger.Default().Tracef("hash %s %d", h.Source, value) return vs[value%uint64(len(vs))] diff --git a/service/service.go b/service/service.go index 4ee7d35a..8f3e4206 100644 --- a/service/service.go +++ b/service/service.go @@ -20,8 +20,7 @@ import ( "github.com/go-gost/core/observer/stats" "github.com/go-gost/core/recorder" "github.com/go-gost/core/service" - ctxvalue "github.com/go-gost/x/ctx" - xnet "github.com/go-gost/x/internal/net" + xctx "github.com/go-gost/x/ctx" xmetrics "github.com/go-gost/x/metrics" xstats "github.com/go-gost/x/observer/stats" "github.com/google/shlex" @@ -146,11 +145,11 @@ func (s *defaultService) Serve() error { Message: fmt.Sprintf("service %s is listening on %s", s.name, s.listener.Addr()), }) - ctx, cancel := context.WithCancel(context.Background()) + gctx, cancel := context.WithCancel(context.Background()) defer cancel() if s.status.Stats() != nil { - go s.observeStats(ctx) + go s.observeStats(gctx) } if v := xmetrics.GetGauge( @@ -206,37 +205,39 @@ func (s *defaultService) Serve() error { s.setState(StateReady) } + ctx := gctx + if cv, ok := conn.(xctx.Context); ok { + if v := cv.Context(); v != nil { + ctx = v + } + } + sid := xid.New().String() - ctx := ctxvalue.ContextWithSid(ctx, ctxvalue.Sid(sid)) + ctx = xctx.ContextWithSid(ctx, xctx.Sid(sid)) log := s.options.logger.WithFields(map[string]any{ "sid": sid, }) - srcAddr := conn.RemoteAddr() - if a, ok := conn.(xnet.SrcAddr); ok { - if addr := a.SrcAddr(); addr != nil { - srcAddr = addr - } + srcAddr := xctx.SrcAddrFromContext(ctx) + if srcAddr == nil { + srcAddr = conn.RemoteAddr() + ctx = xctx.ContextWithSrcAddr(ctx, srcAddr) } - ctx = ctxvalue.ContextWithSrcAddr(ctx, srcAddr) - clientAddr := srcAddr.String() - ctx = ctxvalue.ContextWithClientAddr(ctx, ctxvalue.ClientAddr(clientAddr)) - - dstAddr := conn.LocalAddr() - if a, ok := conn.(xnet.DstAddr); ok { - if addr := a.DstAddr(); addr != nil { - dstAddr = addr - } + if dstAddr := xctx.DstAddrFromContext(ctx); dstAddr == nil { + dstAddr = conn.LocalAddr() + ctx = xctx.ContextWithDstAddr(ctx, dstAddr) } - ctx = ctxvalue.ContextWithDstAddr(ctx, dstAddr) - clientIP := clientAddr + // clientAddr := srcAddr.String() + // ctx = xctx.ContextWithClientAddr(ctx, xctx.ClientAddr(clientAddr)) + + clientIP := srcAddr.String() if h, _, _ := net.SplitHostPort(clientIP); h != "" { clientIP = h } - ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: clientIP}) + // ctx = xctx.ContextWithHash(ctx, &xctx.Hash{Source: clientIP}) for _, rec := range s.options.recorders { if rec.Record == recorder.RecorderServiceClientAddress {