diff --git a/connector/http2/connector.go b/connector/http2/connector.go index 807869d..737c31e 100644 --- a/connector/http2/connector.go +++ b/connector/http2/connector.go @@ -16,7 +16,6 @@ import ( "github.com/go-gost/gost/v3/pkg/logger" md "github.com/go-gost/gost/v3/pkg/metadata" "github.com/go-gost/gost/v3/pkg/registry" - http2_util "github.com/go-gost/x/internal/util/http2" ) func init() { @@ -52,9 +51,9 @@ func (c *http2Connector) Connect(ctx context.Context, conn net.Conn, network, ad }) log.Infof("connect %s/%s", address, network) - cc, ok := conn.(*http2_util.ClientConn) - if !ok { - err := errors.New("wrong connection type") + v, _ := conn.(md.Metadatable) + if v == nil { + err := errors.New("http2: wrong connection type") log.Error(err) return nil, err } @@ -91,10 +90,11 @@ func (c *http2Connector) Connect(ctx context.Context, conn net.Conn, network, ad defer conn.SetDeadline(time.Time{}) } - resp, err := cc.Client().Do(req.WithContext(ctx)) + client := v.GetMetadata().Get("client").(*http.Client) + resp, err := client.Do(req.WithContext(ctx)) if err != nil { log.Error(err) - cc.Close() + conn.Close() return nil, err } diff --git a/dialer/http2/conn.go b/dialer/http2/conn.go new file mode 100644 index 0000000..12a6f45 --- /dev/null +++ b/dialer/http2/conn.go @@ -0,0 +1,63 @@ +package http2 + +import ( + "errors" + "net" + "time" + + mdata "github.com/go-gost/gost/v3/pkg/metadata" +) + +// a dummy HTTP2 client conn used by HTTP2 client connector +type conn struct { + localAddr net.Addr + remoteAddr net.Addr + onClose func() +} + +func (c *conn) Close() error { + if c.onClose != nil { + c.onClose() + } + return nil +} + +func (c *conn) Read(b []byte) (n int, err error) { + return 0, &net.OpError{Op: "read", Net: "nop", Source: nil, Addr: nil, Err: errors.New("read not supported")} +} + +func (c *conn) Write(b []byte) (n int, err error) { + return 0, &net.OpError{Op: "write", Net: "nop", Source: nil, Addr: nil, Err: errors.New("write not supported")} +} + +func (c *conn) LocalAddr() net.Addr { + return c.localAddr +} + +func (c *conn) RemoteAddr() net.Addr { + return c.remoteAddr +} + +func (c *conn) SetDeadline(t time.Time) error { + return &net.OpError{Op: "set", Net: "nop", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} +} + +func (c *conn) SetReadDeadline(t time.Time) error { + return &net.OpError{Op: "set", Net: "nop", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} +} + +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")} +} + +type metadataConn struct { + net.Conn + md mdata.Metadata +} + +func withMetadata(md mdata.Metadata, c net.Conn) net.Conn { + return &metadataConn{ + Conn: c, + md: md, + } +} diff --git a/dialer/http2/dialer.go b/dialer/http2/dialer.go index 61ac5bd..46bc0ec 100644 --- a/dialer/http2/dialer.go +++ b/dialer/http2/dialer.go @@ -12,7 +12,6 @@ import ( "github.com/go-gost/gost/v3/pkg/logger" md "github.com/go-gost/gost/v3/pkg/metadata" "github.com/go-gost/gost/v3/pkg/registry" - http2_util "github.com/go-gost/x/internal/util/http2" ) func init() { @@ -90,12 +89,19 @@ func (d *http2Dialer) Dial(ctx context.Context, address string, opts ...dialer.D d.clients[address] = client } - return http2_util.NewClientConn( - &net.TCPAddr{}, raddr, - client, - func() { + var c net.Conn + c = &conn{ + localAddr: &net.TCPAddr{}, + remoteAddr: raddr, + onClose: func() { d.clientMutex.Lock() defer d.clientMutex.Unlock() delete(d.clients, address) - }), nil + }, + } + c = withMetadata(md.MapMetadata{ + "client": client, + }, c) + + return c, nil } diff --git a/go.mod b/go.mod index d302089..6dd94c3 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/docker/libcontainer v2.2.1+incompatible github.com/go-gost/gosocks5 v0.3.1-0.20211109033403-d894d75b7f09 github.com/go-gost/gost v0.0.0-20220312160816-bfc1f8472cc2 - github.com/go-gost/gost/v3 v3.0.0-alpha.3.0.20220314141206-42f72adde0ee + github.com/go-gost/gost/v3 v3.0.0-alpha.3.0.20220315024338-20e7528b2588 github.com/go-gost/metrics v0.0.0-20220314135054-2263ae431a5f github.com/go-gost/relay v0.1.1-0.20211123134818-8ef7fd81ffd7 github.com/go-gost/tls-dissector v0.0.2-0.20211125135007-2b5d5bd9c07e diff --git a/go.sum b/go.sum index 13c8a6c..c4dd5d6 100644 --- a/go.sum +++ b/go.sum @@ -112,6 +112,10 @@ github.com/go-gost/gost/v3 v3.0.0-alpha.3.0.20220314122048-c282e69ffdc6 h1:epQ9S github.com/go-gost/gost/v3 v3.0.0-alpha.3.0.20220314122048-c282e69ffdc6/go.mod h1:Hv/IAKyc+9uEGQT5DPWsnqgAFEp4Or7uOxFawr6ghjM= github.com/go-gost/gost/v3 v3.0.0-alpha.3.0.20220314141206-42f72adde0ee h1:p+KM6ZUggiPnxa9l9lP+bsGjO52smX73wPeHlf5xR+E= github.com/go-gost/gost/v3 v3.0.0-alpha.3.0.20220314141206-42f72adde0ee/go.mod h1:hq4/YM+Vki2ODyhMCk59IwvFJks1sAYhHGnivz+6Ono= +github.com/go-gost/gost/v3 v3.0.0-alpha.3.0.20220315022357-2e40afe53584 h1:TfVYWYW0Oyg5ojvWFVO/Vux6Ht9wt7x1HDOv09nsS1Q= +github.com/go-gost/gost/v3 v3.0.0-alpha.3.0.20220315022357-2e40afe53584/go.mod h1:S4iyROMDN6+OvvrALvHyoV/lBswp7ExC1DS5go7woLM= +github.com/go-gost/gost/v3 v3.0.0-alpha.3.0.20220315024338-20e7528b2588 h1:2RxUmbtz1Rz0qfzxmmfGqo61EhnY4L908LFW4nTQT1I= +github.com/go-gost/gost/v3 v3.0.0-alpha.3.0.20220315024338-20e7528b2588/go.mod h1:S4iyROMDN6+OvvrALvHyoV/lBswp7ExC1DS5go7woLM= github.com/go-gost/metrics v0.0.0-20220314135054-2263ae431a5f h1:gNquUvOvPXUpq4Xk7ed7motbVN5t0HMqImf96k+pzlU= github.com/go-gost/metrics v0.0.0-20220314135054-2263ae431a5f/go.mod h1:Ac2Pigx5GMJEznkP9wLdBJ36+rYwWiJPqWk7lrg3FKg= github.com/go-gost/relay v0.1.1-0.20211123134818-8ef7fd81ffd7 h1:itaaJhQJ19kUXEB4Igb0EbY8m+1Py2AaNNSBds/9gk4= diff --git a/handler/http2/handler.go b/handler/http2/handler.go index f5cf9cb..bb426cc 100644 --- a/handler/http2/handler.go +++ b/handler/http2/handler.go @@ -24,7 +24,6 @@ import ( "github.com/go-gost/gost/v3/pkg/logger" md "github.com/go-gost/gost/v3/pkg/metadata" "github.com/go-gost/gost/v3/pkg/registry" - http2_util "github.com/go-gost/x/internal/util/http2" ) func init() { @@ -76,13 +75,18 @@ func (h *http2Handler) Handle(ctx context.Context, conn net.Conn, opts ...handle }).Infof("%s >< %s", conn.RemoteAddr(), conn.LocalAddr()) }() - cc, ok := conn.(*http2_util.ServerConn) - if !ok { + v, ok := conn.(md.Metadatable) + if !ok || v == nil { err := errors.New("wrong connection type") log.Error(err) return err } - return h.roundTrip(ctx, cc.Writer(), cc.Request(), log) + md := v.GetMetadata() + return h.roundTrip(ctx, + md.Get("w").(http.ResponseWriter), + md.Get("r").(*http.Request), + log, + ) } // NOTE: there is an issue (golang/go#43989) will cause the client hangs diff --git a/handler/tap/handler.go b/handler/tap/handler.go index d492e36..3eb9d51 100644 --- a/handler/tap/handler.go +++ b/handler/tap/handler.go @@ -81,8 +81,8 @@ func (h *tapHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. defer conn.Close() log := h.options.Logger - cc, ok := conn.(*tap_util.Conn) - if !ok || cc.Config() == nil { + v, _ := conn.(md.Metadatable) + if v == nil { err := errors.New("tap: wrong connection type") log.Error(err) return err @@ -118,7 +118,8 @@ func (h *tapHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. log.Infof("%s >> %s", conn.RemoteAddr(), target.Addr) } - h.handleLoop(ctx, conn, raddr, cc.Config(), log) + config := v.GetMetadata().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 aade1b1..4515400 100644 --- a/handler/tun/handler.go +++ b/handler/tun/handler.go @@ -84,8 +84,8 @@ func (h *tunHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. log := h.options.Logger - cc, ok := conn.(*tun_util.Conn) - if !ok || cc.Config() == nil { + v, _ := conn.(md.Metadatable) + if v == nil { err := errors.New("tun: wrong connection type") log.Error(err) return err @@ -121,7 +121,8 @@ func (h *tunHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. log.Infof("%s >> %s", conn.RemoteAddr(), target.Addr) } - h.handleLoop(ctx, conn, raddr, cc.Config(), log) + config := v.GetMetadata().Get("config").(*tun_util.Config) + h.handleLoop(ctx, conn, raddr, config, log) return nil } diff --git a/internal/util/http2/conn.go b/internal/util/http2/conn.go deleted file mode 100644 index eb2f43c..0000000 --- a/internal/util/http2/conn.go +++ /dev/null @@ -1,132 +0,0 @@ -package http2 - -import ( - "errors" - "net" - "net/http" - "time" -) - -// a dummy HTTP2 client conn used by HTTP2 client connector -type ClientConn struct { - localAddr net.Addr - remoteAddr net.Addr - client *http.Client - onClose func() -} - -func NewClientConn(localAddr, remoteAddr net.Addr, client *http.Client, onClose func()) net.Conn { - return &ClientConn{ - localAddr: localAddr, - remoteAddr: remoteAddr, - client: client, - onClose: onClose, - } -} - -func (c *ClientConn) Client() *http.Client { - return c.client -} - -func (c *ClientConn) Close() error { - if c.onClose != nil { - c.onClose() - } - return nil -} - -func (c *ClientConn) Read(b []byte) (n int, err error) { - return 0, &net.OpError{Op: "read", Net: "nop", Source: nil, Addr: nil, Err: errors.New("read not supported")} -} - -func (c *ClientConn) Write(b []byte) (n int, err error) { - return 0, &net.OpError{Op: "write", Net: "nop", Source: nil, Addr: nil, Err: errors.New("write not supported")} -} - -func (c *ClientConn) LocalAddr() net.Addr { - return c.localAddr -} - -func (c *ClientConn) RemoteAddr() net.Addr { - return c.remoteAddr -} - -func (c *ClientConn) SetDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "nop", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} - -func (c *ClientConn) SetReadDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "nop", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} - -func (c *ClientConn) SetWriteDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "nop", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} - -// a dummy HTTP2 server conn used by HTTP2 handler -type ServerConn struct { - r *http.Request - w http.ResponseWriter - localAddr net.Addr - remoteAddr net.Addr - closed chan struct{} -} - -func NewServerConn(w http.ResponseWriter, r *http.Request, localAddr, remoteAddr net.Addr) *ServerConn { - return &ServerConn{ - r: r, - w: w, - localAddr: localAddr, - remoteAddr: remoteAddr, - closed: make(chan struct{}), - } -} - -func (c *ServerConn) Done() <-chan struct{} { - return c.closed -} - -func (c *ServerConn) Request() *http.Request { - return c.r -} - -func (c *ServerConn) Writer() http.ResponseWriter { - return c.w -} - -func (c *ServerConn) Read(b []byte) (n int, err error) { - return 0, &net.OpError{Op: "read", Net: "http2", Source: nil, Addr: nil, Err: errors.New("read not supported")} -} - -func (c *ServerConn) Write(b []byte) (n int, err error) { - return 0, &net.OpError{Op: "write", Net: "http2", Source: nil, Addr: nil, Err: errors.New("write not supported")} -} - -func (c *ServerConn) Close() error { - select { - case <-c.closed: - default: - close(c.closed) - } - return nil -} - -func (c *ServerConn) LocalAddr() net.Addr { - return c.localAddr -} - -func (c *ServerConn) RemoteAddr() net.Addr { - return c.remoteAddr -} - -func (c *ServerConn) SetDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} - -func (c *ServerConn) SetReadDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} - -func (c *ServerConn) SetWriteDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} diff --git a/internal/util/tap/conn.go b/internal/util/tap/conn.go deleted file mode 100644 index 453444f..0000000 --- a/internal/util/tap/conn.go +++ /dev/null @@ -1,61 +0,0 @@ -package tap - -import ( - "errors" - "net" - "time" - - "github.com/songgao/water" -) - -type Conn struct { - config *Config - ifce *water.Interface - laddr net.Addr - raddr net.Addr -} - -func NewConn(config *Config, ifce *water.Interface, laddr, raddr net.Addr) *Conn { - return &Conn{ - config: config, - ifce: ifce, - laddr: laddr, - raddr: raddr, - } -} - -func (c *Conn) Config() *Config { - return c.config -} - -func (c *Conn) Read(b []byte) (n int, err error) { - return c.ifce.Read(b) -} - -func (c *Conn) Write(b []byte) (n int, err error) { - return c.ifce.Write(b) -} - -func (c *Conn) Close() (err error) { - return c.ifce.Close() -} - -func (c *Conn) LocalAddr() net.Addr { - return c.laddr -} - -func (c *Conn) RemoteAddr() net.Addr { - return c.raddr -} - -func (c *Conn) SetDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "tuntap", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} - -func (c *Conn) SetReadDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "tuntap", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} - -func (c *Conn) SetWriteDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "tuntap", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} diff --git a/internal/util/tun/conn.go b/internal/util/tun/conn.go deleted file mode 100644 index 05477f9..0000000 --- a/internal/util/tun/conn.go +++ /dev/null @@ -1,61 +0,0 @@ -package tun - -import ( - "errors" - "net" - "time" - - "github.com/songgao/water" -) - -type Conn struct { - config *Config - ifce *water.Interface - laddr net.Addr - raddr net.Addr -} - -func NewConn(config *Config, ifce *water.Interface, laddr, raddr net.Addr) *Conn { - return &Conn{ - config: config, - ifce: ifce, - laddr: laddr, - raddr: raddr, - } -} - -func (c *Conn) Config() *Config { - return c.config -} - -func (c *Conn) Read(b []byte) (n int, err error) { - return c.ifce.Read(b) -} - -func (c *Conn) Write(b []byte) (n int, err error) { - return c.ifce.Write(b) -} - -func (c *Conn) Close() (err error) { - return c.ifce.Close() -} - -func (c *Conn) LocalAddr() net.Addr { - return c.laddr -} - -func (c *Conn) RemoteAddr() net.Addr { - return c.raddr -} - -func (c *Conn) SetDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "tuntap", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} - -func (c *Conn) SetReadDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "tuntap", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} - -func (c *Conn) SetWriteDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "tuntap", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} diff --git a/listener/http2/conn.go b/listener/http2/conn.go index c145860..d1ab68d 100644 --- a/listener/http2/conn.go +++ b/listener/http2/conn.go @@ -5,12 +5,17 @@ import ( "net" "net/http" "time" + + mdata "github.com/go-gost/gost/v3/pkg/metadata" ) // a dummy HTTP2 server conn used by HTTP2 handler type conn struct { + md mdata.Metadata r *http.Request w http.ResponseWriter + laddr net.Addr + raddr net.Addr closed chan struct{} } @@ -32,13 +37,11 @@ func (c *conn) Close() error { } func (c *conn) LocalAddr() net.Addr { - addr, _ := net.ResolveTCPAddr("tcp", c.r.Host) - return addr + return c.raddr } func (c *conn) RemoteAddr() net.Addr { - addr, _ := net.ResolveTCPAddr("tcp", c.r.RemoteAddr) - return addr + return c.raddr } func (c *conn) SetDeadline(t time.Time) error { @@ -52,3 +55,12 @@ func (c *conn) SetReadDeadline(t time.Time) error { 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) Done() <-chan struct{} { + return c.closed +} + +// GetMetadata implements metadata.Metadatable interface. +func (c *conn) GetMetadata() mdata.Metadata { + return c.md +} diff --git a/listener/http2/listener.go b/listener/http2/listener.go index 508c060..1ea3614 100644 --- a/listener/http2/listener.go +++ b/listener/http2/listener.go @@ -11,7 +11,6 @@ import ( md "github.com/go-gost/gost/v3/pkg/metadata" "github.com/go-gost/gost/v3/pkg/registry" metrics "github.com/go-gost/metrics/wrapper" - http2_util "github.com/go-gost/x/internal/util/http2" "golang.org/x/net/http2" ) @@ -108,7 +107,15 @@ func (l *http2Listener) Close() (err error) { func (l *http2Listener) handleFunc(w http.ResponseWriter, r *http.Request) { raddr, _ := net.ResolveTCPAddr("tcp", r.RemoteAddr) - conn := http2_util.NewServerConn(w, r, l.addr, raddr) + conn := &conn{ + laddr: l.addr, + raddr: raddr, + closed: make(chan struct{}), + md: md.MapMetadata{ + "r": r, + "w": w, + }, + } select { case l.cqueue <- conn: default: diff --git a/listener/tap/conn.go b/listener/tap/conn.go new file mode 100644 index 0000000..ec9a28a --- /dev/null +++ b/listener/tap/conn.go @@ -0,0 +1,60 @@ +package tap + +import ( + "errors" + "net" + "time" + + mdata "github.com/go-gost/gost/v3/pkg/metadata" + "github.com/songgao/water" +) + +type conn struct { + ifce *water.Interface + laddr net.Addr + raddr net.Addr +} + +func (c *conn) Read(b []byte) (n int, err error) { + return c.ifce.Read(b) +} + +func (c *conn) Write(b []byte) (n int, err error) { + return c.ifce.Write(b) +} + +func (c *conn) LocalAddr() net.Addr { + return c.laddr +} + +func (c *conn) RemoteAddr() net.Addr { + return c.raddr +} + +func (c *conn) SetDeadline(t time.Time) error { + return &net.OpError{Op: "set", Net: "tap", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} +} + +func (c *conn) SetReadDeadline(t time.Time) error { + return &net.OpError{Op: "set", Net: "tap", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} +} + +func (c *conn) SetWriteDeadline(t time.Time) error { + return &net.OpError{Op: "set", Net: "tap", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} +} + +func (c *conn) Close() (err error) { + return c.ifce.Close() +} + +type metadataConn struct { + net.Conn + md mdata.Metadata +} + +func withMetadata(md mdata.Metadata, c net.Conn) net.Conn { + return &metadataConn{ + Conn: c, + md: md, + } +} diff --git a/listener/tap/listener.go b/listener/tap/listener.go index ae04bbc..6024649 100644 --- a/listener/tap/listener.go +++ b/listener/tap/listener.go @@ -5,9 +5,9 @@ import ( "github.com/go-gost/gost/v3/pkg/listener" "github.com/go-gost/gost/v3/pkg/logger" - md "github.com/go-gost/gost/v3/pkg/metadata" + mdata "github.com/go-gost/gost/v3/pkg/metadata" "github.com/go-gost/gost/v3/pkg/registry" - tap_util "github.com/go-gost/x/internal/util/tap" + metrics "github.com/go-gost/metrics/wrapper" ) func init() { @@ -15,26 +15,28 @@ func init() { } type tapListener struct { - saddr string - addr net.Addr - cqueue chan net.Conn - closed chan struct{} - logger logger.Logger - md metadata + saddr string + addr net.Addr + cqueue chan net.Conn + closed chan struct{} + logger logger.Logger + md metadata + options listener.Options } func NewListener(opts ...listener.Option) listener.Listener { - options := &listener.Options{} + options := listener.Options{} for _, opt := range opts { - opt(options) + opt(&options) } return &tapListener{ - saddr: options.Addr, - logger: options.Logger, + saddr: options.Addr, + logger: options.Logger, + options: options, } } -func (l *tapListener) Init(md md.Metadata) (err error) { +func (l *tapListener) Init(md mdata.Metadata) (err error) { if err = l.parseMetadata(md); err != nil { return } @@ -64,9 +66,18 @@ func (l *tapListener) Init(md md.Metadata) (err error) { l.cqueue = make(chan net.Conn, 1) l.closed = make(chan struct{}) - conn := tap_util.NewConn(l.md.config, ifce, l.addr, &net.IPAddr{IP: ip}) + var c net.Conn + c = &conn{ + ifce: ifce, + laddr: l.addr, + raddr: &net.IPAddr{IP: ip}, + } + c = metrics.WrapConn(l.options.Service, c) + c = withMetadata(mdata.MapMetadata{ + "config": l.md.config, + }, c) - l.cqueue <- conn + l.cqueue <- c return } diff --git a/listener/tun/conn.go b/listener/tun/conn.go new file mode 100644 index 0000000..0292dc8 --- /dev/null +++ b/listener/tun/conn.go @@ -0,0 +1,60 @@ +package tun + +import ( + "errors" + "net" + "time" + + mdata "github.com/go-gost/gost/v3/pkg/metadata" + "github.com/songgao/water" +) + +type conn struct { + ifce *water.Interface + laddr net.Addr + raddr net.Addr +} + +func (c *conn) Read(b []byte) (n int, err error) { + return c.ifce.Read(b) +} + +func (c *conn) Write(b []byte) (n int, err error) { + return c.ifce.Write(b) +} + +func (c *conn) LocalAddr() net.Addr { + return c.laddr +} + +func (c *conn) RemoteAddr() net.Addr { + return c.raddr +} + +func (c *conn) SetDeadline(t time.Time) error { + return &net.OpError{Op: "set", Net: "tun", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} +} + +func (c *conn) SetReadDeadline(t time.Time) error { + return &net.OpError{Op: "set", Net: "tun", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} +} + +func (c *conn) SetWriteDeadline(t time.Time) error { + return &net.OpError{Op: "set", Net: "tun", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} +} + +func (c *conn) Close() (err error) { + return c.ifce.Close() +} + +type metadataConn struct { + net.Conn + md mdata.Metadata +} + +func withMetadata(md mdata.Metadata, c net.Conn) net.Conn { + return &metadataConn{ + Conn: c, + md: md, + } +} diff --git a/listener/tun/listener.go b/listener/tun/listener.go index 08a4540..64ba4d6 100644 --- a/listener/tun/listener.go +++ b/listener/tun/listener.go @@ -3,11 +3,11 @@ package tun import ( "net" + "github.com/go-gost/gost/pkg/common/metrics" "github.com/go-gost/gost/v3/pkg/listener" "github.com/go-gost/gost/v3/pkg/logger" - md "github.com/go-gost/gost/v3/pkg/metadata" + mdata "github.com/go-gost/gost/v3/pkg/metadata" "github.com/go-gost/gost/v3/pkg/registry" - tun_util "github.com/go-gost/x/internal/util/tun" ) func init() { @@ -34,7 +34,7 @@ func NewListener(opts ...listener.Option) listener.Listener { } } -func (l *tunListener) Init(md md.Metadata) (err error) { +func (l *tunListener) Init(md mdata.Metadata) (err error) { if err = l.parseMetadata(md); err != nil { return } @@ -64,9 +64,18 @@ func (l *tunListener) Init(md md.Metadata) (err error) { l.cqueue = make(chan net.Conn, 1) l.closed = make(chan struct{}) - conn := tun_util.NewConn(l.md.config, ifce, l.addr, &net.IPAddr{IP: ip}) + var c net.Conn + c = &conn{ + ifce: ifce, + laddr: l.addr, + raddr: &net.IPAddr{IP: ip}, + } + c = metrics.WrapConn(l.options.Service, c) + c = withMetadata(mdata.MapMetadata{ + "config": l.md.config, + }, c) - l.cqueue <- conn + l.cqueue <- c return }