From 16f34d3e945739076b85012400c2e1217b954248 Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Sun, 7 Nov 2021 23:39:35 +0800 Subject: [PATCH] add socks5 udp relay --- cmd/gost/gost.yml | 18 ++- cmd/gost/register.go | 1 + go.mod | 2 +- go.sum | 8 ++ pkg/chain/transport.go | 3 + pkg/connector/connector.go | 4 + pkg/connector/http/connector.go | 7 ++ pkg/connector/http/metadata.go | 15 ++- pkg/connector/socks/v4/connector.go | 2 +- pkg/connector/socks/v5/connector.go | 128 ++++++++++++-------- pkg/connector/socks/v5/metadata.go | 6 +- pkg/connector/socks/v5/selector.go | 81 +++++++++++++ pkg/connector/ss/connector.go | 8 +- pkg/handler/http/handler.go | 7 +- pkg/handler/socks/v4/handler.go | 7 +- pkg/handler/socks/v5/bind.go | 15 ++- pkg/handler/socks/v5/connect.go | 8 +- pkg/handler/socks/v5/handler.go | 28 ++--- pkg/handler/socks/v5/mbind.go | 155 ++++++++++++++++++++++++ pkg/handler/socks/v5/metadata.go | 4 +- pkg/handler/socks/v5/selector.go | 13 +- pkg/handler/socks/v5/udp.go | 168 ++++++++++++++++++++++++++ pkg/handler/ss/handler.go | 13 +- pkg/internal/bufpool/pool.go | 24 ++-- pkg/internal/utils/{ => kcp}/kcp.go | 2 +- pkg/internal/utils/mux/mux.go | 75 ++++++++++++ pkg/internal/utils/{ => quic}/quic.go | 2 +- pkg/internal/utils/socks/socks.go | 18 +++ pkg/internal/utils/{ => ss}/ss.go | 2 +- pkg/internal/utils/{ => tls}/tls.go | 2 +- pkg/internal/utils/{ => ws}/ws.go | 2 +- pkg/listener/http2/h2/listener.go | 3 +- pkg/listener/http2/listener.go | 3 +- pkg/listener/kcp/listener.go | 2 +- pkg/listener/quic/listener.go | 2 +- pkg/listener/tls/listener.go | 3 +- pkg/listener/tls/mux/listener.go | 4 +- pkg/listener/ws/listener.go | 7 +- pkg/listener/ws/mux/listener.go | 7 +- 39 files changed, 728 insertions(+), 131 deletions(-) create mode 100644 pkg/connector/socks/v5/selector.go create mode 100644 pkg/handler/socks/v5/mbind.go create mode 100644 pkg/handler/socks/v5/udp.go rename pkg/internal/utils/{ => kcp}/kcp.go (97%) create mode 100644 pkg/internal/utils/mux/mux.go rename pkg/internal/utils/{ => quic}/quic.go (99%) create mode 100644 pkg/internal/utils/socks/socks.go rename pkg/internal/utils/{ => ss}/ss.go (98%) rename pkg/internal/utils/{ => tls}/tls.go (98%) rename pkg/internal/utils/{ => ws}/ws.go (97%) diff --git a/cmd/gost/gost.yml b/cmd/gost/gost.yml index e2adadd..bd1ce31 100644 --- a/cmd/gost/gost.yml +++ b/cmd/gost/gost.yml @@ -54,7 +54,7 @@ services: type: tcp metadata: keepAlive: 15s - chain: chain-socks4 + # chain: chain-socks5 # bypass: bypass01 chains: @@ -129,6 +129,22 @@ chains: dialer: type: tcp metadata: {} +- name: chain-socks5 + hops: + - name: hop01 + nodes: + - name: node01 + addr: ":1081" + url: "http://gost:gost@:8081" + # bypass: bypass01 + connector: + type: socks5 + metadata: + # notls: true + auth: gost:gost + dialer: + type: tcp + metadata: {} bypasses: - name: bypass01 diff --git a/cmd/gost/register.go b/cmd/gost/register.go index f779d44..d9074c6 100644 --- a/cmd/gost/register.go +++ b/cmd/gost/register.go @@ -4,6 +4,7 @@ import ( // Register connectors _ "github.com/go-gost/gost/pkg/connector/http" _ "github.com/go-gost/gost/pkg/connector/socks/v4" + _ "github.com/go-gost/gost/pkg/connector/socks/v5" _ "github.com/go-gost/gost/pkg/connector/ss" // Register dialers diff --git a/go.mod b/go.mod index 8dcd962..3e9e2d6 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/coreos/go-iptables v0.5.0 // indirect github.com/ginuerzh/tls-dissector v0.0.2-0.20201202075250-98fa925912da github.com/go-gost/gosocks4 v0.0.1 - github.com/go-gost/gosocks5 v0.3.0 + github.com/go-gost/gosocks5 v0.3.1-0.20211107153135-23b5baedc2aa github.com/gobwas/glob v0.2.3 github.com/golang/snappy v0.0.3 github.com/google/gopacket v1.1.19 // indirect diff --git a/go.sum b/go.sum index 1825123..6d7cf50 100644 --- a/go.sum +++ b/go.sum @@ -113,6 +113,14 @@ github.com/go-gost/gosocks4 v0.0.1 h1:+k1sec8HlELuQV7rWftIkmy8UijzUt2I6t+iMPlGB2 github.com/go-gost/gosocks4 v0.0.1/go.mod h1:3B6L47HbU/qugDg4JnoFPHgJXE43Inz8Bah1QaN9qCc= github.com/go-gost/gosocks5 v0.3.0 h1:Hkmp9YDRBSCJd7xywW6dBPT6B9aQTkuWd+3WCheJiJA= github.com/go-gost/gosocks5 v0.3.0/go.mod h1:1G6I7HP7VFVxveGkoK8mnprnJqSqJjdcASKsdUn4Pp4= +github.com/go-gost/gosocks5 v0.3.1-0.20211107101454-adcd9c8808ae h1:IPcN2DQQxPiKE/hYudFYYeeN3036tQOjnWpsQBLo4Bw= +github.com/go-gost/gosocks5 v0.3.1-0.20211107101454-adcd9c8808ae/go.mod h1:1G6I7HP7VFVxveGkoK8mnprnJqSqJjdcASKsdUn4Pp4= +github.com/go-gost/gosocks5 v0.3.1-0.20211107103216-55ee58d8201a h1:H35F3INQHliXXipi3aU6F0PJ4OzE5EZVeOZohUd/sKc= +github.com/go-gost/gosocks5 v0.3.1-0.20211107103216-55ee58d8201a/go.mod h1:1G6I7HP7VFVxveGkoK8mnprnJqSqJjdcASKsdUn4Pp4= +github.com/go-gost/gosocks5 v0.3.1-0.20211107150557-ff084b955b6a h1:LQ189f7tRprIJwx3znV+V2KMw1Yjo+up38Tujo5vGFo= +github.com/go-gost/gosocks5 v0.3.1-0.20211107150557-ff084b955b6a/go.mod h1:1G6I7HP7VFVxveGkoK8mnprnJqSqJjdcASKsdUn4Pp4= +github.com/go-gost/gosocks5 v0.3.1-0.20211107153135-23b5baedc2aa h1:4yBKO6CPj5LokDeVJy3jbvQTcclG6lMk7zQMQ1/MAYo= +github.com/go-gost/gosocks5 v0.3.1-0.20211107153135-23b5baedc2aa/go.mod h1:1G6I7HP7VFVxveGkoK8mnprnJqSqJjdcASKsdUn4Pp4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= diff --git a/pkg/chain/transport.go b/pkg/chain/transport.go index 60d0a0f..3397bdf 100644 --- a/pkg/chain/transport.go +++ b/pkg/chain/transport.go @@ -52,6 +52,9 @@ func (tr *Transport) Handshake(ctx context.Context, conn net.Conn) (net.Conn, er if hs, ok := tr.dialer.(dialer.Handshaker); ok { return hs.Handshake(ctx, conn) } + if hs, ok := tr.connector.(connector.Handshaker); ok { + return hs.Handshake(ctx, conn) + } return conn, nil } diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 7a5c7cb..b5e361d 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -12,3 +12,7 @@ type Connector interface { Init(metadata.Metadata) error Connect(ctx context.Context, conn net.Conn, network, address string, opts ...ConnectOption) (net.Conn, error) } + +type Handshaker interface { + Handshake(ctx context.Context, conn net.Conn) (net.Conn, error) +} diff --git a/pkg/connector/http/connector.go b/pkg/connector/http/connector.go index c399d9f..ed36280 100644 --- a/pkg/connector/http/connector.go +++ b/pkg/connector/http/connector.go @@ -10,6 +10,7 @@ import ( "net/http/httputil" "net/url" "strings" + "time" "github.com/go-gost/gost/pkg/connector" "github.com/go-gost/gost/pkg/logger" @@ -74,6 +75,11 @@ func (c *httpConnector) Connect(ctx context.Context, conn net.Conn, network, add c.logger.Debug(string(dump)) } + if c.md.connectTimeout > 0 { + conn.SetDeadline(time.Now().Add(c.md.connectTimeout)) + defer conn.SetDeadline(time.Time{}) + } + req = req.WithContext(ctx) if err := req.Write(conn); err != nil { return nil, err @@ -98,6 +104,7 @@ func (c *httpConnector) Connect(ctx context.Context, conn net.Conn, network, add } func (c *httpConnector) parseMetadata(md md.Metadata) (err error) { + c.md.connectTimeout = md.GetDuration(connectTimeout) c.md.UserAgent, _ = md.Get(userAgent).(string) if c.md.UserAgent == "" { c.md.UserAgent = defaultUserAgent diff --git a/pkg/connector/http/metadata.go b/pkg/connector/http/metadata.go index ab4a782..b3b6741 100644 --- a/pkg/connector/http/metadata.go +++ b/pkg/connector/http/metadata.go @@ -1,10 +1,14 @@ package http -import "net/url" +import ( + "net/url" + "time" +) const ( - userAgent = "userAgent" - auth = "auth" + connectTimeout = "timeout" + userAgent = "userAgent" + auth = "auth" ) const ( @@ -12,6 +16,7 @@ const ( ) type metadata struct { - UserAgent string - User *url.Userinfo + connectTimeout time.Duration + UserAgent string + User *url.Userinfo } diff --git a/pkg/connector/socks/v4/connector.go b/pkg/connector/socks/v4/connector.go index 97eb862..cd2d578 100644 --- a/pkg/connector/socks/v4/connector.go +++ b/pkg/connector/socks/v4/connector.go @@ -79,8 +79,8 @@ func (c *socks4Connector) Connect(ctx context.Context, conn net.Conn, network, a if c.md.connectTimeout > 0 { conn.SetDeadline(time.Now().Add(c.md.connectTimeout)) + defer conn.SetDeadline(time.Time{}) } - defer conn.SetDeadline(time.Time{}) req := gosocks4.NewRequest(gosocks4.CmdConnect, addr, nil) if err := req.Write(conn); err != nil { diff --git a/pkg/connector/socks/v5/connector.go b/pkg/connector/socks/v5/connector.go index 7b87378..492df20 100644 --- a/pkg/connector/socks/v5/connector.go +++ b/pkg/connector/socks/v5/connector.go @@ -2,27 +2,30 @@ package v5 import ( "context" - "fmt" + "crypto/tls" + "errors" "net" "net/url" - "strconv" + "strings" "time" - "github.com/go-gost/gosocks4" + "github.com/go-gost/gosocks5" "github.com/go-gost/gost/pkg/connector" + "github.com/go-gost/gost/pkg/internal/utils/socks" "github.com/go-gost/gost/pkg/logger" md "github.com/go-gost/gost/pkg/metadata" "github.com/go-gost/gost/pkg/registry" ) func init() { - registry.RegiserConnector("socks4", NewConnector) - registry.RegiserConnector("socks4a", NewConnector) + registry.RegiserConnector("socks5", NewConnector) + registry.RegiserConnector("socks", NewConnector) } -type socks4Connector struct { - md metadata - logger logger.Logger +type socks5Connector struct { + selector gosocks5.Selector + logger logger.Logger + md metadata } func NewConnector(opts ...connector.Option) connector.Connector { @@ -31,64 +34,85 @@ func NewConnector(opts ...connector.Option) connector.Connector { opt(options) } - return &socks4Connector{ + return &socks5Connector{ logger: options.Logger, } } -func (c *socks4Connector) Init(md md.Metadata) (err error) { - return c.parseMetadata(md) +func (c *socks5Connector) Init(md md.Metadata) (err error) { + if err = c.parseMetadata(md); err != nil { + return + } + + selector := &clientSelector{ + methods: []uint8{ + gosocks5.MethodNoAuth, + gosocks5.MethodUserPass, + }, + logger: c.logger, + User: c.md.User, + TLSConfig: c.md.tlsConfig, + } + if !c.md.noTLS { + selector.methods = append(selector.methods, socks.MethodTLS) + if selector.TLSConfig == nil { + selector.TLSConfig = &tls.Config{ + InsecureSkipVerify: true, + } + } + } + c.selector = selector + + return } -func (c *socks4Connector) Connect(ctx context.Context, conn net.Conn, network, address string, opts ...connector.ConnectOption) (net.Conn, error) { +func (c *socks5Connector) Handshake(ctx context.Context, conn net.Conn) (net.Conn, error) { c.logger = c.logger.WithFields(map[string]interface{}{ "remote": conn.RemoteAddr().String(), "local": conn.LocalAddr().String(), + }) + + if c.md.connectTimeout > 0 { + conn.SetDeadline(time.Now().Add(c.md.connectTimeout)) + defer conn.SetDeadline(time.Time{}) + } + + cc := gosocks5.ClientConn(conn, c.selector) + if err := cc.Handleshake(); err != nil { + return nil, err + } + + return cc, nil +} + +func (c *socks5Connector) Connect(ctx context.Context, conn net.Conn, network, address string, opts ...connector.ConnectOption) (net.Conn, error) { + c.logger = c.logger.WithFields(map[string]interface{}{ "target": address, }) - c.logger.Infof("connect: ", address) + c.logger.Info("connect: ", address) - var addr *gosocks4.Addr - - if c.md.disable4a { - taddr, err := net.ResolveTCPAddr("tcp4", address) - if err != nil { - c.logger.Error("resolve: ", err) - return nil, err - } - if len(taddr.IP) == 0 { - taddr.IP = net.IPv4zero - } - addr = &gosocks4.Addr{ - Type: gosocks4.AddrIPv4, - Host: taddr.IP.String(), - Port: uint16(taddr.Port), - } - } else { - host, port, err := net.SplitHostPort(address) - if err != nil { - return nil, err - } - p, _ := strconv.Atoi(port) - addr = &gosocks4.Addr{ - Type: gosocks4.AddrDomain, - Host: host, - Port: uint16(p), - } + addr, err := gosocks5.NewAddr(address) + if err != nil { + c.logger.Error(err) + return nil, err } - conn.SetDeadline(time.Now().Add(c.md.connectTimeout)) - defer conn.SetDeadline(time.Time{}) - req := gosocks4.NewRequest(gosocks4.CmdConnect, addr, nil) + if c.md.connectTimeout > 0 { + conn.SetDeadline(time.Now().Add(c.md.connectTimeout)) + defer conn.SetDeadline(time.Time{}) + } + + req := gosocks5.NewRequest(gosocks5.CmdConnect, addr) if err := req.Write(conn); err != nil { c.logger.Error(err) return nil, err } + if c.logger.IsLevelEnabled(logger.DebugLevel) { c.logger.Debug(req) } - reply, err := gosocks4.ReadReply(conn) + reply, err := gosocks5.ReadReply(conn) if err != nil { c.logger.Error(err) return nil, err @@ -98,19 +122,25 @@ func (c *socks4Connector) Connect(ctx context.Context, conn net.Conn, network, a c.logger.Debug(reply) } - if reply.Code != gosocks4.Granted { - return nil, fmt.Errorf("error: %d", reply.Code) + if reply.Rep != gosocks5.Succeeded { + return nil, errors.New("service unavailable") } return conn, nil } -func (c *socks4Connector) parseMetadata(md md.Metadata) (err error) { +func (c *socks5Connector) parseMetadata(md md.Metadata) (err error) { if v := md.GetString(auth); v != "" { - c.md.User = url.User(v) + ss := strings.SplitN(v, ":", 2) + if len(ss) == 1 { + c.md.User = url.User(ss[0]) + } else { + c.md.User = url.UserPassword(ss[0], ss[1]) + } } + c.md.connectTimeout = md.GetDuration(connectTimeout) - c.md.disable4a = md.GetBool(disable4a) + c.md.noTLS = md.GetBool(noTLS) return } diff --git a/pkg/connector/socks/v5/metadata.go b/pkg/connector/socks/v5/metadata.go index ffb0bbc..362c9af 100644 --- a/pkg/connector/socks/v5/metadata.go +++ b/pkg/connector/socks/v5/metadata.go @@ -1,6 +1,7 @@ package v5 import ( + "crypto/tls" "net/url" "time" ) @@ -8,11 +9,12 @@ import ( const ( connectTimeout = "timeout" auth = "auth" - disable4a = "disable4a" + noTLS = "notls" ) type metadata struct { connectTimeout time.Duration User *url.Userinfo - disable4a bool + tlsConfig *tls.Config + noTLS bool } diff --git a/pkg/connector/socks/v5/selector.go b/pkg/connector/socks/v5/selector.go new file mode 100644 index 0000000..2b9e29e --- /dev/null +++ b/pkg/connector/socks/v5/selector.go @@ -0,0 +1,81 @@ +package v5 + +import ( + "crypto/tls" + "net" + "net/url" + + "github.com/go-gost/gosocks5" + "github.com/go-gost/gost/pkg/internal/utils/socks" + "github.com/go-gost/gost/pkg/logger" +) + +type clientSelector struct { + methods []uint8 + User *url.Userinfo + TLSConfig *tls.Config + logger logger.Logger +} + +func (s *clientSelector) Methods() []uint8 { + if s.logger.IsLevelEnabled(logger.DebugLevel) { + s.logger.Debug("methods: ", s.methods) + } + return s.methods +} + +func (s *clientSelector) AddMethod(methods ...uint8) { + s.methods = append(s.methods, methods...) +} + +func (s *clientSelector) Select(methods ...uint8) (method uint8) { + return +} + +func (s *clientSelector) OnSelected(method uint8, conn net.Conn) (net.Conn, error) { + if s.logger.IsLevelEnabled(logger.DebugLevel) { + s.logger.Debug("method selected: ", method) + } + + switch method { + case socks.MethodTLS: + conn = tls.Client(conn, s.TLSConfig) + + case gosocks5.MethodUserPass, socks.MethodTLSAuth: + if method == socks.MethodTLSAuth { + conn = tls.Client(conn, s.TLSConfig) + } + + var username, password string + if s.User != nil { + username = s.User.Username() + password, _ = s.User.Password() + } + + req := gosocks5.NewUserPassRequest(gosocks5.UserPassVer, username, password) + if err := req.Write(conn); err != nil { + s.logger.Error(err) + return nil, err + } + if s.logger.IsLevelEnabled(logger.DebugLevel) { + s.logger.Debug(req) + } + + resp, err := gosocks5.ReadUserPassResponse(conn) + if err != nil { + s.logger.Error(err) + return nil, err + } + if s.logger.IsLevelEnabled(logger.DebugLevel) { + s.logger.Debug(resp) + } + + if resp.Status != gosocks5.Succeeded { + return nil, gosocks5.ErrAuthFailure + } + case gosocks5.MethodNoAcceptable: + return nil, gosocks5.ErrBadMethod + } + + return conn, nil +} diff --git a/pkg/connector/ss/connector.go b/pkg/connector/ss/connector.go index 1b51ddf..e5464d9 100644 --- a/pkg/connector/ss/connector.go +++ b/pkg/connector/ss/connector.go @@ -8,7 +8,7 @@ import ( "github.com/go-gost/gosocks5" "github.com/go-gost/gost/pkg/connector" "github.com/go-gost/gost/pkg/internal/bufpool" - "github.com/go-gost/gost/pkg/internal/utils" + "github.com/go-gost/gost/pkg/internal/utils/ss" "github.com/go-gost/gost/pkg/logger" md "github.com/go-gost/gost/pkg/metadata" "github.com/go-gost/gost/pkg/registry" @@ -71,21 +71,21 @@ func (c *ssConnector) Connect(ctx context.Context, conn net.Conn, network, addre var sc net.Conn if c.md.noDelay { - sc = utils.ShadowConn(conn, nil) + sc = ss.ShadowConn(conn, nil) // write the addr at once. if _, err := sc.Write(rawaddr[:n]); err != nil { return nil, err } } else { // cache the header - sc = utils.ShadowConn(conn, rawaddr[:n]) + sc = ss.ShadowConn(conn, rawaddr[:n]) } return sc, nil } func (c *ssConnector) parseMetadata(md md.Metadata) (err error) { - c.md.cipher, err = utils.ShadowCipher( + c.md.cipher, err = ss.ShadowCipher( md.GetString(method), md.GetString(password), md.GetString(key), diff --git a/pkg/handler/http/handler.go b/pkg/handler/http/handler.go index 5816382..1900be3 100644 --- a/pkg/handler/http/handler.go +++ b/pkg/handler/http/handler.go @@ -246,9 +246,14 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt } } + start := time.Now() h.logger.Infof("%s <-> %s", conn.RemoteAddr(), addr) handler.Transport(conn, cc) - h.logger.Infof("%s >-< %s", conn.RemoteAddr(), addr) + h.logger. + WithFields(map[string]interface{}{ + "duration": time.Since(start), + }). + Infof("%s >-< %s", conn.RemoteAddr(), addr) } func (h *httpHandler) decodeServerName(s string) (string, error) { diff --git a/pkg/handler/socks/v4/handler.go b/pkg/handler/socks/v4/handler.go index 6588d32..dc92d4c 100644 --- a/pkg/handler/socks/v4/handler.go +++ b/pkg/handler/socks/v4/handler.go @@ -139,9 +139,14 @@ func (h *socks4Handler) handleConnect(ctx context.Context, conn net.Conn, req *g h.logger.Debug(resp) } + t := time.Now() h.logger.Infof("%s <-> %s", conn.RemoteAddr(), addr) handler.Transport(conn, cc) - h.logger.Infof("%s >-< %s", conn.RemoteAddr(), addr) + h.logger. + WithFields(map[string]interface{}{ + "duration": time.Since(t), + }). + Infof("%s >-< %s", conn.RemoteAddr(), addr) } func (h *socks4Handler) handleBind(ctx context.Context, conn net.Conn, req *gosocks4.Request) { diff --git a/pkg/handler/socks/v5/bind.go b/pkg/handler/socks/v5/bind.go index f5088cf..fc54765 100644 --- a/pkg/handler/socks/v5/bind.go +++ b/pkg/handler/socks/v5/bind.go @@ -3,6 +3,7 @@ package v5 import ( "context" "net" + "time" "github.com/go-gost/gosocks5" "github.com/go-gost/gost/pkg/handler" @@ -39,6 +40,7 @@ func (h *socks5Handler) handleBind(ctx context.Context, conn net.Conn, req *goso } defer cc.Close() + // forward request if err := req.Write(cc); err != nil { h.logger.Error(err) resp := gosocks5.NewReply(gosocks5.NetUnreachable, nil) @@ -88,7 +90,11 @@ func (h *socks5Handler) bindLocal(ctx context.Context, conn net.Conn, addr strin if h.logger.IsLevelEnabled(logger.DebugLevel) { h.logger.Debug(reply.String()) } - h.logger.Infof("bind on: %s OK", socksAddr.String()) + + h.logger = h.logger.WithFields(map[string]interface{}{ + "bind": socksAddr.String(), + }) + h.logger.Infof("bind on %s OK", socksAddr.String()) h.serveBind(ctx, conn, ln) } @@ -144,11 +150,14 @@ func (h *socks5Handler) serveBind(ctx context.Context, conn net.Conn, ln net.Lis if h.logger.IsLevelEnabled(logger.DebugLevel) { h.logger.Debug(reply.String()) } - h.logger.Infof("PEER %s ACCEPTED", raddr.String()) + h.logger.Infof("peer accepted: %s", raddr.String()) + start := time.Now() h.logger.Infof("%s <-> %s", conn.RemoteAddr(), raddr.String()) handler.Transport(pc2, rc) - h.logger.Infof("%s >-< %s", conn.RemoteAddr(), raddr.String()) + h.logger. + WithFields(map[string]interface{}{"duration": time.Since(start)}). + Infof("%s >-< %s", conn.RemoteAddr(), raddr.String()) case err := <-pipe(): if err != nil { diff --git a/pkg/handler/socks/v5/connect.go b/pkg/handler/socks/v5/connect.go index 86f4542..a335afc 100644 --- a/pkg/handler/socks/v5/connect.go +++ b/pkg/handler/socks/v5/connect.go @@ -3,6 +3,7 @@ package v5 import ( "context" "net" + "time" "github.com/go-gost/gosocks5" "github.com/go-gost/gost/pkg/handler" @@ -51,7 +52,12 @@ func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, addr s h.logger.Debug(resp) } + t := time.Now() h.logger.Infof("%s <-> %s", conn.RemoteAddr(), addr) handler.Transport(conn, cc) - h.logger.Infof("%s >-< %s", conn.RemoteAddr(), addr) + h.logger. + WithFields(map[string]interface{}{ + "duration": time.Since(t), + }). + Infof("%s >-< %s", conn.RemoteAddr(), addr) } diff --git a/pkg/handler/socks/v5/handler.go b/pkg/handler/socks/v5/handler.go index 5a65269..30992e9 100644 --- a/pkg/handler/socks/v5/handler.go +++ b/pkg/handler/socks/v5/handler.go @@ -9,28 +9,12 @@ import ( "github.com/go-gost/gost/pkg/bypass" "github.com/go-gost/gost/pkg/chain" "github.com/go-gost/gost/pkg/handler" + "github.com/go-gost/gost/pkg/internal/utils/socks" "github.com/go-gost/gost/pkg/logger" md "github.com/go-gost/gost/pkg/metadata" "github.com/go-gost/gost/pkg/registry" ) -const ( - // MethodTLS is an extended SOCKS5 method with tls encryption support. - MethodTLS uint8 = 0x80 - // MethodTLSAuth is an extended SOCKS5 method with tls encryption and authentication support. - MethodTLSAuth uint8 = 0x82 - // MethodMux is an extended SOCKS5 method for stream multiplexing. - MethodMux = 0x88 -) - -const ( - // CmdMuxBind is an extended SOCKS5 request CMD for - // multiplexing transport with the binding server. - CmdMuxBind uint8 = 0xF2 - // CmdUDPTun is an extended SOCKS5 request CMD for UDP over TCP. - CmdUDPTun uint8 = 0xF3 -) - func init() { registry.RegisterHandler("socks5", NewHandler) registry.RegisterHandler("socks", NewHandler) @@ -58,8 +42,8 @@ func NewHandler(opts ...handler.Option) handler.Handler { } func (h *socks5Handler) Init(md md.Metadata) (err error) { - if err := h.parseMetadata(md); err != nil { - return err + if err = h.parseMetadata(md); err != nil { + return } h.selector = &serverSelector{ @@ -110,9 +94,11 @@ func (h *socks5Handler) Handle(ctx context.Context, conn net.Conn) { h.handleConnect(ctx, conn, req.Addr.String()) case gosocks5.CmdBind: h.handleBind(ctx, conn, req) - case CmdMuxBind: + case socks.CmdMuxBind: + h.handleMuxBind(ctx, conn, req) case gosocks5.CmdUdp: - case CmdUDPTun: + h.handleUDP(ctx, conn, req) + case socks.CmdUDPTun: default: h.logger.Errorf("unknown cmd: %d", req.Cmd) resp := gosocks5.NewReply(gosocks5.CmdUnsupported, nil) diff --git a/pkg/handler/socks/v5/mbind.go b/pkg/handler/socks/v5/mbind.go new file mode 100644 index 0000000..8b42bf6 --- /dev/null +++ b/pkg/handler/socks/v5/mbind.go @@ -0,0 +1,155 @@ +package v5 + +import ( + "context" + "net" + "time" + + "github.com/go-gost/gosocks5" + "github.com/go-gost/gost/pkg/handler" + "github.com/go-gost/gost/pkg/internal/utils/mux" + "github.com/go-gost/gost/pkg/logger" +) + +func (h *socks5Handler) handleMuxBind(ctx context.Context, conn net.Conn, req *gosocks5.Request) { + addr := req.Addr.String() + + h.logger = h.logger.WithFields(map[string]interface{}{ + "dst": addr, + "cmd": "mbind", + }) + + h.logger.Infof("%s >> %s", conn.RemoteAddr(), addr) + + if h.chain.IsEmpty() { + h.muxBindLocal(ctx, conn, addr) + return + } + + r := (&handler.Router{}). + WithChain(h.chain). + WithRetry(h.md.retryCount). + WithLogger(h.logger) + cc, err := r.Connect(ctx) + if err != nil { + resp := gosocks5.NewReply(gosocks5.Failure, nil) + resp.Write(conn) + if h.logger.IsLevelEnabled(logger.DebugLevel) { + h.logger.Debug(resp) + } + return + } + defer cc.Close() + + // forward request + if err := req.Write(cc); err != nil { + h.logger.Error(err) + resp := gosocks5.NewReply(gosocks5.NetUnreachable, nil) + resp.Write(conn) + if h.logger.IsLevelEnabled(logger.DebugLevel) { + h.logger.Debug(resp) + } + return + } + + t := time.Now() + h.logger.Infof("%s <-> %s", conn.RemoteAddr(), addr) + handler.Transport(conn, cc) + h.logger. + WithFields(map[string]interface{}{ + "duration": time.Since(t), + }). + Infof("%s >-< %s", conn.RemoteAddr(), addr) +} + +func (h *socks5Handler) muxBindLocal(ctx context.Context, conn net.Conn, addr string) { + bindAddr, _ := net.ResolveTCPAddr("tcp", addr) + ln, err := net.ListenTCP("tcp", bindAddr) // strict mode: if the port already in use, it will return error + if err != nil { + h.logger.Error(err) + reply := gosocks5.NewReply(gosocks5.Failure, nil) + if err := reply.Write(conn); err != nil { + h.logger.Error(err) + } + if h.logger.IsLevelEnabled(logger.DebugLevel) { + h.logger.Debug(reply.String()) + } + return + } + + socksAddr, err := gosocks5.NewAddr(ln.Addr().String()) + if err != nil { + h.logger.Warn(err) + socksAddr = &gosocks5.Addr{ + Type: gosocks5.AddrIPv4, + } + } + + // Issue: may not reachable when host has multi-interface + socksAddr.Host, _, _ = net.SplitHostPort(conn.LocalAddr().String()) + reply := gosocks5.NewReply(gosocks5.Succeeded, socksAddr) + if err := reply.Write(conn); err != nil { + h.logger.Error(err) + ln.Close() + return + } + if h.logger.IsLevelEnabled(logger.DebugLevel) { + h.logger.Debug(reply.String()) + } + + h.logger = h.logger.WithFields(map[string]interface{}{ + "bind": socksAddr.String(), + }) + h.logger.Infof("bind on: %s OK", socksAddr.String()) + + h.serveMuxBind(ctx, conn, ln) +} + +func (h *socks5Handler) serveMuxBind(ctx context.Context, conn net.Conn, ln net.Listener) { + // Upgrade connection to multiplex stream. + session, err := mux.NewMuxSession(conn) + if err != nil { + h.logger.Error(err) + return + } + defer session.Close() + + go func() { + defer ln.Close() + for { + conn, err := session.Accept() + if err != nil { + h.logger.Error(err) + return + } + conn.Close() // we do not handle incoming connections. + } + }() + + for { + rc, err := ln.Accept() + if err != nil { + h.logger.Error(err) + return + } + h.logger.Infof("peer accepted: %s", rc.RemoteAddr().String()) + + go func(c net.Conn) { + defer c.Close() + + sc, err := session.GetConn() + if err != nil { + h.logger.Error(err) + return + } + defer sc.Close() + + t := time.Now() + h.logger.Infof("%s <-> %s", conn.RemoteAddr(), c.RemoteAddr().String()) + handler.Transport(sc, c) + h.logger. + WithFields(map[string]interface{}{"duration": time.Since(t)}). + Infof("%s >-< %s", conn.RemoteAddr(), c.RemoteAddr().String()) + }(rc) + } +} diff --git a/pkg/handler/socks/v5/metadata.go b/pkg/handler/socks/v5/metadata.go index f3425ed..ff7615e 100644 --- a/pkg/handler/socks/v5/metadata.go +++ b/pkg/handler/socks/v5/metadata.go @@ -6,7 +6,7 @@ import ( "time" "github.com/go-gost/gost/pkg/auth" - "github.com/go-gost/gost/pkg/internal/utils" + util_tls "github.com/go-gost/gost/pkg/internal/utils/tls" md "github.com/go-gost/gost/pkg/metadata" ) @@ -30,7 +30,7 @@ type metadata struct { func (h *socks5Handler) parseMetadata(md md.Metadata) error { var err error - h.md.tlsConfig, err = utils.LoadTLSConfig( + h.md.tlsConfig, err = util_tls.LoadTLSConfig( md.GetString(certFile), md.GetString(keyFile), md.GetString(caFile), diff --git a/pkg/handler/socks/v5/selector.go b/pkg/handler/socks/v5/selector.go index cc8feb5..3472539 100644 --- a/pkg/handler/socks/v5/selector.go +++ b/pkg/handler/socks/v5/selector.go @@ -6,6 +6,7 @@ import ( "github.com/go-gost/gosocks5" "github.com/go-gost/gost/pkg/auth" + "github.com/go-gost/gost/pkg/internal/utils/socks" "github.com/go-gost/gost/pkg/logger" ) @@ -27,7 +28,7 @@ func (s *serverSelector) Select(methods ...uint8) (method uint8) { } method = gosocks5.MethodNoAuth for _, m := range methods { - if m == MethodTLS && !s.noTLS { + if m == socks.MethodTLS && !s.noTLS { method = m break } @@ -38,8 +39,8 @@ func (s *serverSelector) Select(methods ...uint8) (method uint8) { if method == gosocks5.MethodNoAuth { method = gosocks5.MethodUserPass } - if method == MethodTLS && !s.noTLS { - method = MethodTLSAuth + if method == socks.MethodTLS && !s.noTLS { + method = socks.MethodTLSAuth } } @@ -51,11 +52,11 @@ func (s *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Conn, erro s.logger.Debugf("%d %d", gosocks5.Ver5, method) } switch method { - case MethodTLS: + case socks.MethodTLS: conn = tls.Server(conn, s.TLSConfig) - case gosocks5.MethodUserPass, MethodTLSAuth: - if method == MethodTLSAuth { + case gosocks5.MethodUserPass, socks.MethodTLSAuth: + if method == socks.MethodTLSAuth { conn = tls.Server(conn, s.TLSConfig) } diff --git a/pkg/handler/socks/v5/udp.go b/pkg/handler/socks/v5/udp.go new file mode 100644 index 0000000..4b489cf --- /dev/null +++ b/pkg/handler/socks/v5/udp.go @@ -0,0 +1,168 @@ +package v5 + +import ( + "bytes" + "context" + "io" + "io/ioutil" + "net" + "time" + + "github.com/go-gost/gosocks5" + "github.com/go-gost/gost/pkg/internal/bufpool" + "github.com/go-gost/gost/pkg/logger" +) + +func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, req *gosocks5.Request) { + h.logger = h.logger.WithFields(map[string]interface{}{ + "cmd": "udp", + }) + + relay, err := net.ListenUDP("udp", nil) + if err != nil { + h.logger.Error(err) + reply := gosocks5.NewReply(gosocks5.Failure, nil) + reply.Write(conn) + if h.logger.IsLevelEnabled(logger.DebugLevel) { + h.logger.Debug(reply) + } + return + } + defer relay.Close() + + saddr, _ := gosocks5.NewAddr(relay.LocalAddr().String()) + if saddr == nil { + saddr = &gosocks5.Addr{} + } + saddr.Type = 0 + saddr.Host, _, _ = net.SplitHostPort(conn.LocalAddr().String()) // replace the IP to the out-going interface's + reply := gosocks5.NewReply(gosocks5.Succeeded, saddr) + if err := reply.Write(conn); err != nil { + h.logger.Error(err) + return + } + if h.logger.IsLevelEnabled(logger.DebugLevel) { + h.logger.Debug(reply) + } + + h.logger = h.logger.WithFields(map[string]interface{}{ + "bind": saddr.String(), + }) + h.logger.Infof("bind on %s OK", saddr.String()) + + if !h.chain.IsEmpty() { + + } + + peer, err := net.ListenUDP("udp", nil) + if err != nil { + h.logger.Error(err) + return + } + defer peer.Close() + + go h.transportUDP(relay, peer) + + t := time.Now() + h.logger.Infof("%s <-> %s", conn.RemoteAddr(), saddr) + io.Copy(ioutil.Discard, conn) + h.logger. + WithFields(map[string]interface{}{"duration": time.Since(t)}). + Infof("%s >-< %s", conn.RemoteAddr(), saddr) +} + +func (h *socks5Handler) transportUDP(relay, peer net.PacketConn) (err error) { + const bufSize = 65 * 1024 + errc := make(chan error, 2) + + var clientAddr net.Addr + + go func() { + b := bufpool.Get(bufSize) + defer bufpool.Put(b) + + for { + n, laddr, err := relay.ReadFrom(b) + if err != nil { + errc <- err + return + } + if clientAddr == nil { + clientAddr = laddr + } + + var addr gosocks5.Addr + header := gosocks5.UDPHeader{ + Addr: &addr, + } + hlen, err := header.ReadFrom(bytes.NewReader(b[:n])) + if err != nil { + errc <- err + return + } + + raddr, err := net.ResolveUDPAddr("udp", addr.String()) + if err != nil { + continue // drop silently + } + + if h.bypass != nil && h.bypass.Contains(raddr.String()) { + h.logger.Warn("bypass: ", raddr) + continue // bypass + } + + data := b[hlen:n] + if _, err := peer.WriteTo(data, raddr); err != nil { + errc <- err + return + } + if h.logger.IsLevelEnabled(logger.DebugLevel) { + h.logger.Debugf("%s >>> %s: %v data: %d", + clientAddr, raddr, b[:hlen], len(data)) + } + } + }() + + go func() { + b := bufpool.Get(bufSize) + defer bufpool.Put(b) + + const dataPos = 1024 + + for { + n, raddr, err := peer.ReadFrom(b[dataPos:]) + if err != nil { + errc <- err + return + } + if clientAddr == nil { + continue + } + if h.bypass != nil && h.bypass.Contains(raddr.String()) { + h.logger.Warn("bypass: ", raddr) + continue // bypass + } + + socksAddr, _ := gosocks5.NewAddr(raddr.String()) + if socksAddr == nil { + socksAddr = &gosocks5.Addr{} + } + socksAddr.Type = 0 + addrLen := socksAddr.Length() + socksAddr.Encode(b[dataPos-addrLen : dataPos]) + + hlen := addrLen + 3 + if _, err := relay.WriteTo(b[dataPos-hlen:dataPos+n], clientAddr); err != nil { + errc <- err + return + } + + if h.logger.IsLevelEnabled(logger.DebugLevel) { + h.logger.Debugf("%s <<< %s: %v data: %d", + clientAddr, raddr, b[dataPos-hlen:dataPos], n) + } + } + }() + + return <-errc +} diff --git a/pkg/handler/ss/handler.go b/pkg/handler/ss/handler.go index af0ff95..a92e4d0 100644 --- a/pkg/handler/ss/handler.go +++ b/pkg/handler/ss/handler.go @@ -11,7 +11,7 @@ import ( "github.com/go-gost/gost/pkg/bypass" "github.com/go-gost/gost/pkg/chain" "github.com/go-gost/gost/pkg/handler" - "github.com/go-gost/gost/pkg/internal/utils" + "github.com/go-gost/gost/pkg/internal/utils/ss" "github.com/go-gost/gost/pkg/logger" md "github.com/go-gost/gost/pkg/metadata" "github.com/go-gost/gost/pkg/registry" @@ -64,7 +64,7 @@ func (h *ssHandler) Handle(ctx context.Context, conn net.Conn) { sc := conn if h.md.cipher != nil { - sc = utils.ShadowConn(h.md.cipher.StreamConn(conn), nil) + sc = ss.ShadowConn(h.md.cipher.StreamConn(conn), nil) } if h.md.readTimeout > 0 { @@ -102,9 +102,14 @@ func (h *ssHandler) Handle(ctx context.Context, conn net.Conn) { } defer cc.Close() + t := time.Now() h.logger.Infof("%s <-> %s", conn.RemoteAddr(), addr) handler.Transport(sc, cc) - h.logger.Infof("%s >-< %s", conn.RemoteAddr(), addr) + h.logger. + WithFields(map[string]interface{}{ + "duration": time.Since(t), + }). + Infof("%s >-< %s", conn.RemoteAddr(), addr) } func (h *ssHandler) discard(conn net.Conn) { @@ -112,7 +117,7 @@ func (h *ssHandler) discard(conn net.Conn) { } func (h *ssHandler) parseMetadata(md md.Metadata) (err error) { - h.md.cipher, err = utils.ShadowCipher( + h.md.cipher, err = ss.ShadowCipher( md.GetString(method), md.GetString(password), md.GetString(key), diff --git a/pkg/internal/bufpool/pool.go b/pkg/internal/bufpool/pool.go index 23f1504..8550941 100644 --- a/pkg/internal/bufpool/pool.go +++ b/pkg/internal/bufpool/pool.go @@ -2,12 +2,6 @@ package bufpool import "sync" -var ( - smallBufferSize = 1 * 1024 // 1KB buffer - mediumBufferSize = 8 * 1024 // 8KB buffer - largeBufferSize = 64 * 1024 // 64KB buffer -) - var ( pools = []struct { size int @@ -77,24 +71,32 @@ var ( }, }, }, + { + size: 65 * 1024, + pool: sync.Pool{ + New: func() interface{} { + return make([]byte, 65*1024) + }, + }, + }, } ) -// Get returns a buffer size range from (0, 64]KB, -// panic if size > 64KB. +// Get returns a buffer size range from (0, 65]KB, +// panic if size > 65KB. func Get(size int) []byte { for i := range pools { if size <= pools[i].size { return pools[i].pool.Get().([]byte) } } - panic("size too large (max=64KB)") + panic("size too large (max=65KB)") } func Put(b []byte) { for i := range pools { - if len(b) == pools[i].size { - pools[i].pool.Put(b) + if cap(b) == pools[i].size { + pools[i].pool.Put(b[:cap(b)]) } } } diff --git a/pkg/internal/utils/kcp.go b/pkg/internal/utils/kcp/kcp.go similarity index 97% rename from pkg/internal/utils/kcp.go rename to pkg/internal/utils/kcp/kcp.go index 93a73d2..93250aa 100644 --- a/pkg/internal/utils/kcp.go +++ b/pkg/internal/utils/kcp/kcp.go @@ -1,4 +1,4 @@ -package utils +package kcp import ( "net" diff --git a/pkg/internal/utils/mux/mux.go b/pkg/internal/utils/mux/mux.go new file mode 100644 index 0000000..cd70aae --- /dev/null +++ b/pkg/internal/utils/mux/mux.go @@ -0,0 +1,75 @@ +package mux + +import ( + "net" + + smux "github.com/xtaci/smux" +) + +type MuxSession struct { + conn net.Conn + session *smux.Session +} + +func NewMuxSession(conn net.Conn) (*MuxSession, error) { + // Upgrade connection to multiplex stream. + s, err := smux.Client(conn, smux.DefaultConfig()) + if err != nil { + return nil, err + } + return &MuxSession{ + conn: conn, + session: s, + }, nil +} + +func (session *MuxSession) GetConn() (net.Conn, error) { + stream, err := session.session.OpenStream() + if err != nil { + return nil, err + } + return &muxStreamConn{Conn: session.conn, stream: stream}, nil +} + +func (session *MuxSession) Accept() (net.Conn, error) { + stream, err := session.session.AcceptStream() + if err != nil { + return nil, err + } + return &muxStreamConn{Conn: session.conn, stream: stream}, nil +} + +func (session *MuxSession) Close() error { + if session.session == nil { + return nil + } + return session.session.Close() +} + +func (session *MuxSession) IsClosed() bool { + if session.session == nil { + return true + } + return session.session.IsClosed() +} + +func (session *MuxSession) NumStreams() int { + return session.session.NumStreams() +} + +type muxStreamConn struct { + net.Conn + stream *smux.Stream +} + +func (c *muxStreamConn) Read(b []byte) (n int, err error) { + return c.stream.Read(b) +} + +func (c *muxStreamConn) Write(b []byte) (n int, err error) { + return c.stream.Write(b) +} + +func (c *muxStreamConn) Close() error { + return c.stream.Close() +} diff --git a/pkg/internal/utils/quic.go b/pkg/internal/utils/quic/quic.go similarity index 99% rename from pkg/internal/utils/quic.go rename to pkg/internal/utils/quic/quic.go index c2f8764..12d8a45 100644 --- a/pkg/internal/utils/quic.go +++ b/pkg/internal/utils/quic/quic.go @@ -1,4 +1,4 @@ -package utils +package quic import ( "crypto/aes" diff --git a/pkg/internal/utils/socks/socks.go b/pkg/internal/utils/socks/socks.go new file mode 100644 index 0000000..91d241d --- /dev/null +++ b/pkg/internal/utils/socks/socks.go @@ -0,0 +1,18 @@ +package socks + +const ( + // MethodTLS is an extended SOCKS5 method with tls encryption support. + MethodTLS uint8 = 0x80 + // MethodTLSAuth is an extended SOCKS5 method with tls encryption and authentication support. + MethodTLSAuth uint8 = 0x82 + // MethodMux is an extended SOCKS5 method for stream multiplexing. + MethodMux = 0x88 +) + +const ( + // CmdMuxBind is an extended SOCKS5 request CMD for + // multiplexing transport with the binding server. + CmdMuxBind uint8 = 0xF2 + // CmdUDPTun is an extended SOCKS5 request CMD for UDP over TCP. + CmdUDPTun uint8 = 0xF3 +) diff --git a/pkg/internal/utils/ss.go b/pkg/internal/utils/ss/ss.go similarity index 98% rename from pkg/internal/utils/ss.go rename to pkg/internal/utils/ss/ss.go index 14f1650..1a26bb3 100644 --- a/pkg/internal/utils/ss.go +++ b/pkg/internal/utils/ss/ss.go @@ -1,4 +1,4 @@ -package utils +package ss import ( "bytes" diff --git a/pkg/internal/utils/tls.go b/pkg/internal/utils/tls/tls.go similarity index 98% rename from pkg/internal/utils/tls.go rename to pkg/internal/utils/tls/tls.go index eeea1f5..bbce7bd 100644 --- a/pkg/internal/utils/tls.go +++ b/pkg/internal/utils/tls/tls.go @@ -1,4 +1,4 @@ -package utils +package tls import ( "crypto/tls" diff --git a/pkg/internal/utils/ws.go b/pkg/internal/utils/ws/ws.go similarity index 97% rename from pkg/internal/utils/ws.go rename to pkg/internal/utils/ws/ws.go index 5723f5f..95105a7 100644 --- a/pkg/internal/utils/ws.go +++ b/pkg/internal/utils/ws/ws.go @@ -1,4 +1,4 @@ -package utils +package ws import ( "net" diff --git a/pkg/listener/http2/h2/listener.go b/pkg/listener/http2/h2/listener.go index daae128..6cb44a5 100644 --- a/pkg/listener/http2/h2/listener.go +++ b/pkg/listener/http2/h2/listener.go @@ -8,6 +8,7 @@ import ( "time" "github.com/go-gost/gost/pkg/internal/utils" + util_tls "github.com/go-gost/gost/pkg/internal/utils/tls" "github.com/go-gost/gost/pkg/listener" "github.com/go-gost/gost/pkg/logger" md "github.com/go-gost/gost/pkg/metadata" @@ -173,7 +174,7 @@ func (l *h2Listener) upgrade(w http.ResponseWriter, r *http.Request) (*conn, err } func (l *h2Listener) parseMetadata(md md.Metadata) (err error) { - l.md.tlsConfig, err = utils.LoadTLSConfig( + l.md.tlsConfig, err = util_tls.LoadTLSConfig( md.GetString(certFile), md.GetString(keyFile), md.GetString(caFile), diff --git a/pkg/listener/http2/listener.go b/pkg/listener/http2/listener.go index fad48e5..35dad9b 100644 --- a/pkg/listener/http2/listener.go +++ b/pkg/listener/http2/listener.go @@ -6,6 +6,7 @@ import ( "net/http" "github.com/go-gost/gost/pkg/internal/utils" + util_tls "github.com/go-gost/gost/pkg/internal/utils/tls" "github.com/go-gost/gost/pkg/listener" "github.com/go-gost/gost/pkg/logger" md "github.com/go-gost/gost/pkg/metadata" @@ -126,7 +127,7 @@ func (l *http2Listener) handleFunc(w http.ResponseWriter, r *http.Request) { } func (l *http2Listener) parseMetadata(md md.Metadata) (err error) { - l.md.tlsConfig, err = utils.LoadTLSConfig( + l.md.tlsConfig, err = util_tls.LoadTLSConfig( md.GetString(certFile), md.GetString(keyFile), md.GetString(caFile), diff --git a/pkg/listener/kcp/listener.go b/pkg/listener/kcp/listener.go index 6cb7461..53e5c3c 100644 --- a/pkg/listener/kcp/listener.go +++ b/pkg/listener/kcp/listener.go @@ -4,7 +4,7 @@ import ( "net" "time" - "github.com/go-gost/gost/pkg/internal/utils" + utils "github.com/go-gost/gost/pkg/internal/utils/kcp" "github.com/go-gost/gost/pkg/listener" "github.com/go-gost/gost/pkg/logger" md "github.com/go-gost/gost/pkg/metadata" diff --git a/pkg/listener/quic/listener.go b/pkg/listener/quic/listener.go index 0489373..3fbc8ed 100644 --- a/pkg/listener/quic/listener.go +++ b/pkg/listener/quic/listener.go @@ -4,7 +4,7 @@ import ( "context" "net" - "github.com/go-gost/gost/pkg/internal/utils" + utils "github.com/go-gost/gost/pkg/internal/utils/quic" "github.com/go-gost/gost/pkg/listener" "github.com/go-gost/gost/pkg/logger" md "github.com/go-gost/gost/pkg/metadata" diff --git a/pkg/listener/tls/listener.go b/pkg/listener/tls/listener.go index 8ded0b7..6e8fd84 100644 --- a/pkg/listener/tls/listener.go +++ b/pkg/listener/tls/listener.go @@ -5,6 +5,7 @@ import ( "net" "github.com/go-gost/gost/pkg/internal/utils" + util_tls "github.com/go-gost/gost/pkg/internal/utils/tls" "github.com/go-gost/gost/pkg/listener" "github.com/go-gost/gost/pkg/logger" md "github.com/go-gost/gost/pkg/metadata" @@ -56,7 +57,7 @@ func (l *tlsListener) Init(md md.Metadata) (err error) { } func (l *tlsListener) parseMetadata(md md.Metadata) (err error) { - l.md.tlsConfig, err = utils.LoadTLSConfig( + l.md.tlsConfig, err = util_tls.LoadTLSConfig( md.GetString(certFile), md.GetString(keyFile), md.GetString(caFile), diff --git a/pkg/listener/tls/mux/listener.go b/pkg/listener/tls/mux/listener.go index c44f00b..6571b9a 100644 --- a/pkg/listener/tls/mux/listener.go +++ b/pkg/listener/tls/mux/listener.go @@ -4,7 +4,7 @@ import ( "crypto/tls" "net" - "github.com/go-gost/gost/pkg/internal/utils" + util_tls "github.com/go-gost/gost/pkg/internal/utils/tls" "github.com/go-gost/gost/pkg/listener" "github.com/go-gost/gost/pkg/logger" md "github.com/go-gost/gost/pkg/metadata" @@ -127,7 +127,7 @@ func (l *mtlsListener) Accept() (conn net.Conn, err error) { } func (l *mtlsListener) parseMetadata(md md.Metadata) (err error) { - l.md.tlsConfig, err = utils.LoadTLSConfig( + l.md.tlsConfig, err = util_tls.LoadTLSConfig( md.GetString(certFile), md.GetString(keyFile), md.GetString(caFile), diff --git a/pkg/listener/ws/listener.go b/pkg/listener/ws/listener.go index 9366d5c..021ad2b 100644 --- a/pkg/listener/ws/listener.go +++ b/pkg/listener/ws/listener.go @@ -5,7 +5,8 @@ import ( "net" "net/http" - "github.com/go-gost/gost/pkg/internal/utils" + util_tls "github.com/go-gost/gost/pkg/internal/utils/tls" + "github.com/go-gost/gost/pkg/internal/utils/ws" "github.com/go-gost/gost/pkg/listener" "github.com/go-gost/gost/pkg/logger" md "github.com/go-gost/gost/pkg/metadata" @@ -115,7 +116,7 @@ func (l *wsListener) Addr() net.Addr { } func (l *wsListener) parseMetadata(md md.Metadata) (err error) { - l.md.tlsConfig, err = utils.LoadTLSConfig( + l.md.tlsConfig, err = util_tls.LoadTLSConfig( md.GetString(certFile), md.GetString(keyFile), md.GetString(caFile), @@ -135,7 +136,7 @@ func (l *wsListener) upgrade(w http.ResponseWriter, r *http.Request) { } select { - case l.connChan <- utils.WebsocketServerConn(conn): + case l.connChan <- ws.WebsocketServerConn(conn): default: conn.Close() l.logger.Warn("connection queue is full") diff --git a/pkg/listener/ws/mux/listener.go b/pkg/listener/ws/mux/listener.go index 84be483..b4bd778 100644 --- a/pkg/listener/ws/mux/listener.go +++ b/pkg/listener/ws/mux/listener.go @@ -5,7 +5,8 @@ import ( "net" "net/http" - "github.com/go-gost/gost/pkg/internal/utils" + util_tls "github.com/go-gost/gost/pkg/internal/utils/tls" + "github.com/go-gost/gost/pkg/internal/utils/ws" "github.com/go-gost/gost/pkg/listener" "github.com/go-gost/gost/pkg/logger" md "github.com/go-gost/gost/pkg/metadata" @@ -111,7 +112,7 @@ func (l *mwsListener) Addr() net.Addr { } func (l *mwsListener) parseMetadata(md md.Metadata) (err error) { - l.md.tlsConfig, err = utils.LoadTLSConfig( + l.md.tlsConfig, err = util_tls.LoadTLSConfig( md.GetString(certFile), md.GetString(keyFile), md.GetString(caFile), @@ -130,7 +131,7 @@ func (l *mwsListener) upgrade(w http.ResponseWriter, r *http.Request) { return } - l.mux(utils.WebsocketServerConn(conn)) + l.mux(ws.WebsocketServerConn(conn)) } func (l *mwsListener) mux(conn net.Conn) {