From 3351aa59740859516ede9332a7309cbc8714c10b Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Tue, 26 Oct 2021 21:07:46 +0800 Subject: [PATCH] add chain --- .gitignore | 34 +++++ client/client.go | 11 -- client/dialer/option.go | 17 --- cmd/gost/main.go | 99 +++++++++++++ go.mod | 4 +- go.sum | 70 +++++++--- pkg/chain/chain.go | 33 +++++ pkg/chain/node.go | 59 ++++++++ pkg/chain/route.go | 93 +++++++++++++ pkg/chain/selector.go | 41 ++++++ pkg/chain/transport.go | 66 +++++++++ .../components}/connector/connector.go | 2 +- pkg/components/connector/http/connector.go | 99 +++++++++++++ pkg/components/connector/http/metadata.go | 18 +++ pkg/components/connector/metadata.go | 3 + .../components/connector}/option.go | 9 +- pkg/components/connector/ss/connector.go | 54 ++++++++ pkg/components/connector/ss/metadata.go | 11 ++ {client => pkg/components}/dialer/dialer.go | 7 +- {client => pkg/components}/dialer/metadata.go | 0 pkg/components/dialer/option.go | 32 +++++ .../components}/dialer/tcp/dialer.go | 23 +++- .../components}/dialer/tcp/metadata.go | 0 {server => pkg/components}/handler/handler.go | 1 - .../components}/handler/http/handler.go | 130 ++++++++---------- .../components}/handler/http/metadata.go | 1 + .../components}/handler/metadata.go | 0 pkg/components/handler/option.go | 25 ++++ .../components}/handler/ss/handler.go | 4 +- .../components}/handler/ss/metadata.go | 0 .../components}/handler/ssu/handler.go | 4 +- .../components}/handler/ssu/metadata.go | 0 .../components}/handler/transport.go | 0 .../components/internal/utils}/kcp.go | 0 .../components/internal/utils}/quic.go | 0 .../components/internal/utils}/tcp.go | 0 .../components/internal/utils}/tls.go | 0 .../components/internal/utils}/ws.go | 0 .../components}/listener/ftcp/conn.go | 0 .../components}/listener/ftcp/listener.go | 4 +- .../components}/listener/ftcp/metadata.go | 0 .../components}/listener/http2/conn.go | 0 .../components}/listener/http2/h2/conn.go | 0 .../components}/listener/http2/h2/listener.go | 6 +- .../components}/listener/http2/h2/metadata.go | 0 .../components}/listener/http2/listener.go | 6 +- .../components}/listener/http2/metadata.go | 0 .../components}/listener/kcp/config.go | 0 .../components}/listener/kcp/listener.go | 6 +- .../components}/listener/kcp/metadata.go | 0 .../components}/listener/listener.go | 1 - .../components}/listener/metadata.go | 0 .../components}/listener/obfs/http/conn.go | 0 .../listener/obfs/http/listener.go | 6 +- .../listener/obfs/http/metadata.go | 0 .../components}/listener/obfs/tls/conn.go | 0 .../components}/listener/obfs/tls/listener.go | 6 +- .../components}/listener/obfs/tls/metadata.go | 0 {server => pkg/components}/listener/option.go | 2 +- .../components}/listener/quic/listener.go | 6 +- .../components}/listener/quic/metadata.go | 0 .../components}/listener/tcp/listener.go | 6 +- .../components}/listener/tcp/metadata.go | 0 .../components}/listener/tls/listener.go | 6 +- .../components}/listener/tls/metadata.go | 0 .../components}/listener/tls/mux/listener.go | 6 +- .../components}/listener/tls/mux/metadata.go | 0 .../components}/listener/udp/conn.go | 0 .../components}/listener/udp/listener.go | 4 +- .../components}/listener/udp/metadata.go | 0 .../components}/listener/ws/listener.go | 6 +- .../components}/listener/ws/metadata.go | 0 .../components}/listener/ws/mux/listener.go | 6 +- .../components}/listener/ws/mux/metadata.go | 0 {logger => pkg/logger}/gost_logger.go | 0 {logger => pkg/logger}/logger.go | 0 pkg/service/service.go | 63 +++++++++ server/server.go | 12 -- 78 files changed, 917 insertions(+), 185 deletions(-) create mode 100644 .gitignore delete mode 100644 client/client.go delete mode 100644 client/dialer/option.go create mode 100644 cmd/gost/main.go create mode 100644 pkg/chain/chain.go create mode 100644 pkg/chain/node.go create mode 100644 pkg/chain/route.go create mode 100644 pkg/chain/selector.go create mode 100644 pkg/chain/transport.go rename {client => pkg/components}/connector/connector.go (81%) create mode 100644 pkg/components/connector/http/connector.go create mode 100644 pkg/components/connector/http/metadata.go create mode 100644 pkg/components/connector/metadata.go rename {server/handler => pkg/components/connector}/option.go (59%) create mode 100644 pkg/components/connector/ss/connector.go create mode 100644 pkg/components/connector/ss/metadata.go rename {client => pkg/components}/dialer/dialer.go (55%) rename {client => pkg/components}/dialer/metadata.go (100%) create mode 100644 pkg/components/dialer/option.go rename {client => pkg/components}/dialer/tcp/dialer.go (52%) rename {client => pkg/components}/dialer/tcp/metadata.go (100%) rename {server => pkg/components}/handler/handler.go (81%) rename {server => pkg/components}/handler/http/handler.go (76%) rename {server => pkg/components}/handler/http/metadata.go (82%) rename {server => pkg/components}/handler/metadata.go (100%) create mode 100644 pkg/components/handler/option.go rename {server => pkg/components}/handler/ss/handler.go (96%) rename {server => pkg/components}/handler/ss/metadata.go (100%) rename {server => pkg/components}/handler/ssu/handler.go (94%) rename {server => pkg/components}/handler/ssu/metadata.go (100%) rename {server => pkg/components}/handler/transport.go (100%) rename {utils => pkg/components/internal/utils}/kcp.go (100%) rename {utils => pkg/components/internal/utils}/quic.go (100%) rename {utils => pkg/components/internal/utils}/tcp.go (100%) rename {utils => pkg/components/internal/utils}/tls.go (100%) rename {utils => pkg/components/internal/utils}/ws.go (100%) rename {server => pkg/components}/listener/ftcp/conn.go (100%) rename {server => pkg/components}/listener/ftcp/listener.go (96%) rename {server => pkg/components}/listener/ftcp/metadata.go (100%) rename {server => pkg/components}/listener/http2/conn.go (100%) rename {server => pkg/components}/listener/http2/h2/conn.go (100%) rename {server => pkg/components}/listener/http2/h2/listener.go (96%) rename {server => pkg/components}/listener/http2/h2/metadata.go (100%) rename {server => pkg/components}/listener/http2/listener.go (94%) rename {server => pkg/components}/listener/http2/metadata.go (100%) rename {server => pkg/components}/listener/kcp/config.go (100%) rename {server => pkg/components}/listener/kcp/listener.go (95%) rename {server => pkg/components}/listener/kcp/metadata.go (100%) rename {server => pkg/components}/listener/listener.go (93%) rename {server => pkg/components}/listener/metadata.go (100%) rename {server => pkg/components}/listener/obfs/http/conn.go (100%) rename {server => pkg/components}/listener/obfs/http/listener.go (90%) rename {server => pkg/components}/listener/obfs/http/metadata.go (100%) rename {server => pkg/components}/listener/obfs/tls/conn.go (100%) rename {server => pkg/components}/listener/obfs/tls/listener.go (90%) rename {server => pkg/components}/listener/obfs/tls/metadata.go (100%) rename {server => pkg/components}/listener/option.go (85%) rename {server => pkg/components}/listener/quic/listener.go (94%) rename {server => pkg/components}/listener/quic/metadata.go (100%) rename {server => pkg/components}/listener/tcp/listener.go (89%) rename {server => pkg/components}/listener/tcp/metadata.go (100%) rename {server => pkg/components}/listener/tls/listener.go (88%) rename {server => pkg/components}/listener/tls/metadata.go (100%) rename {server => pkg/components}/listener/tls/mux/listener.go (94%) rename {server => pkg/components}/listener/tls/mux/metadata.go (100%) rename {server => pkg/components}/listener/udp/conn.go (100%) rename {server => pkg/components}/listener/udp/listener.go (97%) rename {server => pkg/components}/listener/udp/metadata.go (100%) rename {server => pkg/components}/listener/ws/listener.go (94%) rename {server => pkg/components}/listener/ws/metadata.go (100%) rename {server => pkg/components}/listener/ws/mux/listener.go (95%) rename {server => pkg/components}/listener/ws/mux/metadata.go (100%) rename {logger => pkg/logger}/gost_logger.go (100%) rename {logger => pkg/logger}/logger.go (100%) create mode 100644 pkg/service/service.go delete mode 100644 server/server.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0cd5cca --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test +release +debian +bin + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.swp +*.swo + +*.exe +*.test + +*.bak + +cmd/gost/gost +snap diff --git a/client/client.go b/client/client.go deleted file mode 100644 index 868296d..0000000 --- a/client/client.go +++ /dev/null @@ -1,11 +0,0 @@ -package client - -import ( - "github.com/go-gost/gost/client/connector" - "github.com/go-gost/gost/client/dialer" -) - -type Client struct { - Connector connector.Connector - Dialer dialer.Dialer -} diff --git a/client/dialer/option.go b/client/dialer/option.go deleted file mode 100644 index f059dc9..0000000 --- a/client/dialer/option.go +++ /dev/null @@ -1,17 +0,0 @@ -package dialer - -import ( - "github.com/go-gost/gost/logger" -) - -type Options struct { - Logger logger.Logger -} - -type Option func(opts *Options) - -func LoggerOption(logger logger.Logger) Option { - return func(opts *Options) { - opts.Logger = logger - } -} diff --git a/cmd/gost/main.go b/cmd/gost/main.go new file mode 100644 index 0000000..23aec9c --- /dev/null +++ b/cmd/gost/main.go @@ -0,0 +1,99 @@ +package main + +import ( + "bufio" + "log" + "net/http" + "net/http/httputil" + "time" + + "github.com/go-gost/gost/pkg/chain" + "github.com/go-gost/gost/pkg/components/connector" + httpc "github.com/go-gost/gost/pkg/components/connector/http" + tcpd "github.com/go-gost/gost/pkg/components/dialer/tcp" + "github.com/go-gost/gost/pkg/components/handler" + httph "github.com/go-gost/gost/pkg/components/handler/http" + "github.com/go-gost/gost/pkg/components/listener" + tcpl "github.com/go-gost/gost/pkg/components/listener/tcp" + "github.com/go-gost/gost/pkg/service" + "golang.org/x/net/context" +) + +func main() { + log.SetFlags(log.LstdFlags | log.Lshortfile) + + testChain() + testHTTPHandler() +} + +func testHTTPHandler() { + ln := tcpl.NewListener() + if err := ln.Init(listener.Metadata{ + "addr": ":1080", + }); err != nil { + log.Fatal(err) + } + + chain := createChain() + h := httph.NewHandler( + handler.ChainOption(chain), + ) + svc := (&service.Service{}). + WithListener(ln). + WithHandler(h) + log.Fatal(svc.Run()) +} + +func createChain() *chain.Chain { + c := httpc.NewConnector() + c.Init(connector.Metadata{ + //"userAgent": "gost-client-3", + "username": "admin", + "password": "123456", + }) + tr := (&chain.Transport{}). + WithDialer(tcpd.NewDialer()). + WithConnector(c) + + node := chain.NewNode("local", "localhost:8080"). + WithTransport(tr) + + ch := &chain.Chain{} + ch.AddNodeGroup(chain.NewNodeGroup(node)) + + return ch +} + +func testChain() { + chain := createChain() + r := chain.GetRoute() + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + conn, err := r.Dial(ctx, "tcp", "www.google.com:80") + if err != nil { + log.Fatal(err) + } + defer conn.Close() + + log.Println(conn.LocalAddr(), conn.RemoteAddr()) + + req, err := http.NewRequest("GET", "http://www.google.com", nil) + if err != nil { + log.Fatal(err) + } + if err := req.Write(conn); err != nil { + log.Fatal(err) + } + data, _ := httputil.DumpRequest(req, true) + log.Println(string(data)) + + resp, err := http.ReadResponse(bufio.NewReader(conn), req) + if err != nil { + log.Fatal(err) + } + defer resp.Body.Close() + + data, _ = httputil.DumpResponse(resp, true) + log.Println(string(data)) +} diff --git a/go.mod b/go.mod index a24d702..be86284 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/golang/snappy v0.0.3 github.com/google/gopacket v1.1.19 // indirect github.com/gorilla/websocket v1.4.2 - github.com/lucas-clemente/quic-go v0.20.1 + github.com/lucas-clemente/quic-go v0.24.0 github.com/shadowsocks/go-shadowsocks2 v0.1.4 github.com/shadowsocks/shadowsocks-go v0.0.0-20200409064450-3e585ff90601 github.com/sirupsen/logrus v1.8.1 @@ -18,5 +18,5 @@ require ( github.com/xtaci/smux v1.5.15 github.com/xtaci/tcpraw v1.2.25 golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 - golang.org/x/net v0.0.0-20200707034311-ab3426394381 + golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 ) diff --git a/go.sum b/go.sum index 6517e5f..d76cab1 100644 --- a/go.sum +++ b/go.sum @@ -30,22 +30,22 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/ginuerzh/tls-dissector v0.0.1 h1:yF6fIt78TO4CdjiLLn6R8r0XajQJE1Lbnuq6rP8mGW8= -github.com/ginuerzh/tls-dissector v0.0.1/go.mod h1:u/kbBOqIOgJv39gywuUb3VwyzdZG5DKquOqfToKE6lk= github.com/ginuerzh/tls-dissector v0.0.2-0.20201202075250-98fa925912da h1:CPNdzkS5TMPghHVTYJp08SUdSneNVSwJSePAPGDuYgY= github.com/ginuerzh/tls-dissector v0.0.2-0.20201202075250-98fa925912da/go.mod h1:YyzP8PQrGwDH/XsfHJXwqdHLwWvBYxu77YVKm0+68f0= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= 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-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/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -54,6 +54,9 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -61,6 +64,7 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= @@ -88,15 +92,16 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lucas-clemente/quic-go v0.20.1 h1:hb5m76V8QS/8Nw/suHvXqo3BMHAozvIkcnzpJdpanSk= -github.com/lucas-clemente/quic-go v0.20.1/go.mod h1:fZq/HUDIM+mW6X6wtzORjC0E/WDBMKe5Hf9bgjISwLk= +github.com/lucas-clemente/quic-go v0.24.0 h1:ToR7SIIEdrgOhgVTHvPgdVRJfgVy+N0wQAagH7L4d5g= +github.com/lucas-clemente/quic-go v0.24.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= -github.com/marten-seemann/qtls-go1-15 v0.1.4 h1:RehYMOyRW8hPVEja1KBVsFVNSm35Jj9Mvs5yNoZZ28A= github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= -github.com/marten-seemann/qtls-go1-16 v0.1.3 h1:XEZ1xGorVy9u+lJq+WXNE+hiqRYLNvJGYmwfwKQN2gU= -github.com/marten-seemann/qtls-go1-16 v0.1.3/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= +github.com/marten-seemann/qtls-go1-16 v0.1.4 h1:xbHbOGGhrenVtII6Co8akhLEdrawwB2iHl5yhJRpnco= +github.com/marten-seemann/qtls-go1-16 v0.1.4/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= +github.com/marten-seemann/qtls-go1-17 v0.1.0 h1:P9ggrs5xtwiqXv/FHNwntmuLMNq3KaSIG93AtAZ48xk= +github.com/marten-seemann/qtls-go1-17 v0.1.0/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz3taBQ8rN2X6FqvaWo8= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/mmcloughlin/avo v0.0.0-20200803215136-443f81d77104 h1:ULR/QWMgcgRiZLUjSSJMU+fW+RDMstRdmnDWj9Q+AsA= @@ -105,15 +110,19 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= +github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -160,6 +169,7 @@ github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:Udh github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= @@ -182,6 +192,8 @@ github.com/xtaci/tcpraw v1.2.25 h1:VDlqo0op17JeXBM6e2G9ocCNLOJcw9mZbobMbJjo0vk= github.com/xtaci/tcpraw v1.2.25/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/arch v0.0.0-20190909030613-46d78d1859ac/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4= @@ -203,8 +215,9 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -219,8 +232,11 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -233,6 +249,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -247,13 +265,21 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200808120158-1030fc2bf1d9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201231184435-2d18734c6014 h1:joucsQqXmyBVxViHCPFjG3hx8JzIFSaym3l3MM/Jsdg= -golang.org/x/sys v0.0.0-20201231184435-2d18734c6014/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -265,8 +291,10 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200425043458-8463f397d07c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200808161706-5bf02b21f123 h1:4JSJPND/+4555t1HfXYF4UEqDqiSKCgeV0+hbA8hMs4= golang.org/x/tools v0.0.0-20200808161706-5bf02b21f123/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.1 h1:wGiQel/hW0NnEkJUk8lbzkX2gFJU6PFxf1v5OlCfuOs= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -294,6 +322,9 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -303,8 +334,9 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= diff --git a/pkg/chain/chain.go b/pkg/chain/chain.go new file mode 100644 index 0000000..383d69a --- /dev/null +++ b/pkg/chain/chain.go @@ -0,0 +1,33 @@ +package chain + +type Chain struct { + groups []*NodeGroup +} + +func (c *Chain) AddNodeGroup(group *NodeGroup) { + c.groups = append(c.groups, group) +} + +func (c *Chain) GetRoute() (r *Route) { + if c == nil || len(c.groups) == 0 { + return + } + + r = &Route{} + for _, group := range c.groups { + node := group.Next() + if node == nil { + return + } + // TODO: bypass + + if node.Transport().IsMultiplex() { + tr := node.Transport().WithRoute(r) + node = node.WithTransport(tr) + r = &Route{} + } + + r.AddNode(node) + } + return r +} diff --git a/pkg/chain/node.go b/pkg/chain/node.go new file mode 100644 index 0000000..e47dcc0 --- /dev/null +++ b/pkg/chain/node.go @@ -0,0 +1,59 @@ +package chain + +type Node struct { + name string + addr string + transport *Transport +} + +func NewNode(name, addr string) *Node { + return &Node{ + name: name, + addr: addr, + } +} + +func (node *Node) Name() string { + return node.name +} + +func (node *Node) Addr() string { + return node.addr +} + +func (node *Node) Transport() *Transport { + return node.transport +} + +func (node *Node) WithTransport(tr *Transport) *Node { + node.transport = tr + return node +} + +type NodeGroup struct { + nodes []*Node + selector Selector +} + +func NewNodeGroup(nodes ...*Node) *NodeGroup { + return &NodeGroup{ + nodes: nodes, + } +} + +func (g *NodeGroup) AddNode(node *Node) { + g.nodes = append(g.nodes, node) +} + +func (g *NodeGroup) WithSelector(selector Selector) { + g.selector = selector +} + +func (g *NodeGroup) Next() *Node { + selector := g.selector + if selector == nil { + // selector = defaultSelector + return g.nodes[0] + } + return selector.Select(g.nodes...) +} diff --git a/pkg/chain/route.go b/pkg/chain/route.go new file mode 100644 index 0000000..8536918 --- /dev/null +++ b/pkg/chain/route.go @@ -0,0 +1,93 @@ +package chain + +import ( + "context" + "errors" + "net" +) + +type Route struct { + nodes []*Node +} + +func (r *Route) AddNode(node *Node) { + r.nodes = append(r.nodes, node) +} + +func (r *Route) Connect(ctx context.Context) (conn net.Conn, err error) { + if r.IsEmpty() { + return nil, errors.New("empty route") + } + + node := r.nodes[0] + cc, err := node.Transport().Dial(ctx, r.nodes[0].Addr()) + if err != nil { + return + } + + cn, err := node.Transport().Handshake(ctx, cc) + if err != nil { + cc.Close() + return + } + + preNode := node + for _, node := range r.nodes[1:] { + cc, err = preNode.Transport().Connect(ctx, cn, "tcp", node.Addr()) + if err != nil { + cn.Close() + return + } + cc, err = node.transport.Handshake(ctx, cc) + if err != nil { + cn.Close() + } + cn = cc + preNode = node + } + + conn = cn + return +} + +func (r *Route) Dial(ctx context.Context, network, address string) (net.Conn, error) { + if r.IsEmpty() { + return r.dialDirect(ctx, network, address) + } + + conn, err := r.Connect(ctx) + if err != nil { + return nil, err + } + + cc, err := r.Last().Transport().Connect(ctx, conn, network, address) + if err != nil { + conn.Close() + return nil, err + } + return cc, nil +} + +func (r *Route) dialDirect(ctx context.Context, network, address string) (net.Conn, error) { + switch network { + case "udp", "udp4", "udp6": + if address == "" { + return net.ListenUDP(network, nil) + } + default: + } + + d := &net.Dialer{} + return d.DialContext(ctx, network, address) +} + +func (r *Route) IsEmpty() bool { + return r == nil || len(r.nodes) == 0 +} + +func (r Route) Last() *Node { + if r.IsEmpty() { + return nil + } + return r.nodes[len(r.nodes)-1] +} diff --git a/pkg/chain/selector.go b/pkg/chain/selector.go new file mode 100644 index 0000000..cc70e75 --- /dev/null +++ b/pkg/chain/selector.go @@ -0,0 +1,41 @@ +package chain + +var ( + defaultSelector Selector = NewSelector(nil) +) + +type Filter interface { + Filter(nodes ...*Node) []*Node + String() string +} + +type Strategy interface { + Apply(nodes ...*Node) *Node + String() string +} + +type Selector interface { + Select(nodes ...*Node) *Node +} + +type selector struct { + strategy Strategy + filters []Filter +} + +func NewSelector(strategy Strategy, filters ...Filter) Selector { + return &selector{ + filters: filters, + strategy: strategy, + } +} + +func (s *selector) Select(nodes ...*Node) *Node { + for _, filter := range s.filters { + nodes = filter.Filter(nodes...) + } + if len(nodes) == 0 { + return nil + } + return s.strategy.Apply(nodes...) +} diff --git a/pkg/chain/transport.go b/pkg/chain/transport.go new file mode 100644 index 0000000..83c4081 --- /dev/null +++ b/pkg/chain/transport.go @@ -0,0 +1,66 @@ +package chain + +import ( + "context" + "net" + + "github.com/go-gost/gost/pkg/components/connector" + "github.com/go-gost/gost/pkg/components/dialer" +) + +type Transport struct { + route *Route + dialer dialer.Dialer + connector connector.Connector +} + +func (tr *Transport) WithDialer(dialer dialer.Dialer) *Transport { + tr.dialer = dialer + return tr +} + +func (tr *Transport) WithConnector(connector connector.Connector) *Transport { + tr.connector = connector + return tr +} + +func (tr *Transport) Dial(ctx context.Context, addr string) (net.Conn, error) { + return tr.dialer.Dial(ctx, addr, tr.dialOptions()...) +} + +func (tr *Transport) dialOptions() []dialer.DialOption { + var opts []dialer.DialOption + if tr.route != nil { + opts = append(opts, + dialer.DialFuncDialOption( + func(ctx context.Context, addr string) (net.Conn, error) { + return tr.route.Dial(ctx, "tcp", addr) + }, + ), + ) + } + return opts +} + +func (tr *Transport) Handshake(ctx context.Context, conn net.Conn) (net.Conn, error) { + if hs, ok := tr.dialer.(dialer.Handshaker); ok { + return hs.Handshake(ctx, conn) + } + return conn, nil +} + +func (tr *Transport) Connect(ctx context.Context, conn net.Conn, network, address string) (net.Conn, error) { + return tr.connector.Connect(ctx, conn, network, address) +} + +func (tr *Transport) IsMultiplex() bool { + if mux, ok := tr.dialer.(dialer.Multiplexer); ok { + return mux.IsMultiplex() + } + return false +} + +func (tr *Transport) WithRoute(r *Route) *Transport { + tr.route = r + return tr +} diff --git a/client/connector/connector.go b/pkg/components/connector/connector.go similarity index 81% rename from client/connector/connector.go rename to pkg/components/connector/connector.go index 2c113e2..f876e19 100644 --- a/client/connector/connector.go +++ b/pkg/components/connector/connector.go @@ -7,5 +7,5 @@ import ( // Connector is responsible for connecting to the destination address. type Connector interface { - Connect(ctx context.Context, conn net.Conn, network, address string) (net.Conn, error) + Connect(ctx context.Context, conn net.Conn, network, address string, opts ...ConnectOption) (net.Conn, error) } diff --git a/pkg/components/connector/http/connector.go b/pkg/components/connector/http/connector.go new file mode 100644 index 0000000..8538f30 --- /dev/null +++ b/pkg/components/connector/http/connector.go @@ -0,0 +1,99 @@ +package http + +import ( + "bufio" + "context" + "encoding/base64" + "fmt" + "log" + "net" + "net/http" + "net/url" + + "github.com/go-gost/gost/pkg/components/connector" + "github.com/go-gost/gost/pkg/logger" +) + +var ( + _ connector.Connector = (*Connector)(nil) +) + +type Connector struct { + md metadata + logger logger.Logger +} + +func NewConnector(opts ...connector.Option) *Connector { + options := &connector.Options{} + for _, opt := range opts { + opt(options) + } + + return &Connector{ + logger: options.Logger, + } +} + +func (c *Connector) Init(md connector.Metadata) (err error) { + c.md, err = c.parseMetadata(md) + if err != nil { + return + } + return nil +} + +func (c *Connector) Connect(ctx context.Context, conn net.Conn, network, address string, opts ...connector.ConnectOption) (net.Conn, error) { + req := &http.Request{ + Method: http.MethodConnect, + URL: &url.URL{Host: address}, + Host: address, + ProtoMajor: 1, + ProtoMinor: 1, + Header: make(http.Header), + } + if c.md.UserAgent != "" { + log.Println(c.md.UserAgent) + req.Header.Set("User-Agent", c.md.UserAgent) + } + req.Header.Set("Proxy-Connection", "keep-alive") + + if user := c.md.User; user != nil { + u := user.Username() + p, _ := user.Password() + req.Header.Set("Proxy-Authorization", + "Basic "+base64.StdEncoding.EncodeToString([]byte(u+":"+p))) + } + + req = req.WithContext(ctx) + if err := req.Write(conn); err != nil { + return nil, err + } + + resp, err := http.ReadResponse(bufio.NewReader(conn), req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("%s", resp.Status) + } + + return conn, nil +} + +func (c *Connector) parseMetadata(md connector.Metadata) (m metadata, err error) { + if md == nil { + md = connector.Metadata{} + } + m.UserAgent = md[userAgent] + if m.UserAgent == "" { + m.UserAgent = defaultUserAgent + } + + if v, ok := md[username]; ok { + m.User = url.UserPassword(v, md[password]) + } + + return +} diff --git a/pkg/components/connector/http/metadata.go b/pkg/components/connector/http/metadata.go new file mode 100644 index 0000000..cfe883f --- /dev/null +++ b/pkg/components/connector/http/metadata.go @@ -0,0 +1,18 @@ +package http + +import "net/url" + +const ( + userAgent = "userAgent" + username = "username" + password = "password" +) + +const ( + defaultUserAgent = "Chrome/78.0.3904.106" +) + +type metadata struct { + UserAgent string + User *url.Userinfo +} diff --git a/pkg/components/connector/metadata.go b/pkg/components/connector/metadata.go new file mode 100644 index 0000000..a2901bb --- /dev/null +++ b/pkg/components/connector/metadata.go @@ -0,0 +1,3 @@ +package connector + +type Metadata map[string]string diff --git a/server/handler/option.go b/pkg/components/connector/option.go similarity index 59% rename from server/handler/option.go rename to pkg/components/connector/option.go index 75a4095..ca2889c 100644 --- a/server/handler/option.go +++ b/pkg/components/connector/option.go @@ -1,7 +1,7 @@ -package handler +package connector import ( - "github.com/go-gost/gost/logger" + "github.com/go-gost/gost/pkg/logger" ) type Options struct { @@ -15,3 +15,8 @@ func LoggerOption(logger logger.Logger) Option { opts.Logger = logger } } + +type ConnectOptions struct { +} + +type ConnectOption func(opts *ConnectOptions) diff --git a/pkg/components/connector/ss/connector.go b/pkg/components/connector/ss/connector.go new file mode 100644 index 0000000..712cc81 --- /dev/null +++ b/pkg/components/connector/ss/connector.go @@ -0,0 +1,54 @@ +package ss + +import ( + "context" + "net" + + "github.com/go-gost/gost/pkg/components/connector" + "github.com/go-gost/gost/pkg/logger" +) + +var ( + _ connector.Connector = (*Connector)(nil) +) + +type Connector struct { + md metadata + logger logger.Logger +} + +func NewConnector(opts ...connector.Option) *Connector { + options := &connector.Options{} + for _, opt := range opts { + opt(options) + } + + return &Connector{ + logger: options.Logger, + } +} + +func (c *Connector) Init(md connector.Metadata) (err error) { + c.md, err = c.parseMetadata(md) + if err != nil { + return + } + + return nil +} + +func (c *Connector) Connect(ctx context.Context, conn net.Conn, network, address string, opts ...connector.ConnectOption) (net.Conn, error) { + + return conn, nil +} + +func (c *Connector) parseMetadata(md connector.Metadata) (m metadata, err error) { + if md == nil { + md = connector.Metadata{} + } + + m.method = md[method] + m.password = md[password] + + return +} diff --git a/pkg/components/connector/ss/metadata.go b/pkg/components/connector/ss/metadata.go new file mode 100644 index 0000000..7143faf --- /dev/null +++ b/pkg/components/connector/ss/metadata.go @@ -0,0 +1,11 @@ +package ss + +const ( + method = "method" + password = "password" +) + +type metadata struct { + method string + password string +} diff --git a/client/dialer/dialer.go b/pkg/components/dialer/dialer.go similarity index 55% rename from client/dialer/dialer.go rename to pkg/components/dialer/dialer.go index 86f373f..47318ff 100644 --- a/client/dialer/dialer.go +++ b/pkg/components/dialer/dialer.go @@ -5,10 +5,9 @@ import ( "net" ) -// Dialer dials to target server. +// Transporter is responsible for dialing to the proxy server. type Dialer interface { - Init(md Metadata) error - Dial(ctx context.Context, addr string) (net.Conn, error) + Dial(ctx context.Context, addr string, opts ...DialOption) (net.Conn, error) } type Handshaker interface { @@ -16,5 +15,5 @@ type Handshaker interface { } type Multiplexer interface { - Multiplexed() bool + IsMultiplex() bool } diff --git a/client/dialer/metadata.go b/pkg/components/dialer/metadata.go similarity index 100% rename from client/dialer/metadata.go rename to pkg/components/dialer/metadata.go diff --git a/pkg/components/dialer/option.go b/pkg/components/dialer/option.go new file mode 100644 index 0000000..44d2fc4 --- /dev/null +++ b/pkg/components/dialer/option.go @@ -0,0 +1,32 @@ +package dialer + +import ( + "context" + "net" + + "github.com/go-gost/gost/pkg/logger" +) + +type Options struct { + Logger logger.Logger +} + +type Option func(opts *Options) + +func LoggerOption(logger logger.Logger) Option { + return func(opts *Options) { + opts.Logger = logger + } +} + +type DialOptions struct { + DialFunc func(ctx context.Context, addr string) (net.Conn, error) +} + +type DialOption func(opts *DialOptions) + +func DialFuncDialOption(dialf func(ctx context.Context, addr string) (net.Conn, error)) DialOption { + return func(opts *DialOptions) { + opts.DialFunc = dialf + } +} diff --git a/client/dialer/tcp/dialer.go b/pkg/components/dialer/tcp/dialer.go similarity index 52% rename from client/dialer/tcp/dialer.go rename to pkg/components/dialer/tcp/dialer.go index fd4bc12..607c40f 100644 --- a/client/dialer/tcp/dialer.go +++ b/pkg/components/dialer/tcp/dialer.go @@ -4,8 +4,12 @@ import ( "context" "net" - "github.com/go-gost/gost/client/dialer" - "github.com/go-gost/gost/logger" + "github.com/go-gost/gost/pkg/components/dialer" + "github.com/go-gost/gost/pkg/logger" +) + +var ( + _ dialer.Dialer = (*Dialer)(nil) ) type Dialer struct { @@ -32,8 +36,19 @@ func (d *Dialer) Init(md dialer.Metadata) (err error) { return nil } -func (d *Dialer) Dial(ctx context.Context, addr string) (net.Conn, error) { - return nil, nil +func (d *Dialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOption) (net.Conn, error) { + var options dialer.DialOptions + for _, opt := range opts { + opt(&options) + } + + dial := options.DialFunc + if dial != nil { + return dial(ctx, addr) + } + + var netd net.Dialer + return netd.DialContext(ctx, "tcp", addr) } func (d *Dialer) parseMetadata(md dialer.Metadata) (m metadata, err error) { diff --git a/client/dialer/tcp/metadata.go b/pkg/components/dialer/tcp/metadata.go similarity index 100% rename from client/dialer/tcp/metadata.go rename to pkg/components/dialer/tcp/metadata.go diff --git a/server/handler/handler.go b/pkg/components/handler/handler.go similarity index 81% rename from server/handler/handler.go rename to pkg/components/handler/handler.go index 3a87239..7331652 100644 --- a/server/handler/handler.go +++ b/pkg/components/handler/handler.go @@ -6,6 +6,5 @@ import ( ) type Handler interface { - Init(md Metadata) error Handle(context.Context, net.Conn) } diff --git a/server/handler/http/handler.go b/pkg/components/handler/http/handler.go similarity index 76% rename from server/handler/http/handler.go rename to pkg/components/handler/http/handler.go index 9f5f34a..f1b6035 100644 --- a/server/handler/http/handler.go +++ b/pkg/components/handler/http/handler.go @@ -6,8 +6,9 @@ import ( "net" "net/http" - "github.com/go-gost/gost/logger" - "github.com/go-gost/gost/server/handler" + "github.com/go-gost/gost/pkg/chain" + "github.com/go-gost/gost/pkg/components/handler" + "github.com/go-gost/gost/pkg/logger" ) var ( @@ -15,6 +16,7 @@ var ( ) type Handler struct { + chain *chain.Chain logger logger.Logger md metadata } @@ -26,6 +28,7 @@ func NewHandler(opts ...handler.Option) *Handler { } return &Handler{ + chain: options.Chain, logger: options.Logger, } } @@ -47,10 +50,10 @@ func (h *Handler) Handle(ctx context.Context, conn net.Conn) { } defer req.Body.Close() - h.handleRequest(conn, req) + h.handleRequest(ctx, conn, req) } -func (h *Handler) handleRequest(conn net.Conn, req *http.Request) { +func (h *Handler) handleRequest(ctx context.Context, conn net.Conn, req *http.Request) { if req == nil { return } @@ -89,7 +92,10 @@ func (h *Handler) handleRequest(conn net.Conn, req *http.Request) { ProtoMinor: 1, Header: http.Header{}, } - resp.Header.Add("Proxy-Agent", h.md.proxyAgent) + + if h.md.proxyAgent != "" { + resp.Header.Add("Proxy-Agent", h.md.proxyAgent) + } /* if !Can("tcp", host, h.options.Whitelist, h.options.Blacklist) { @@ -146,81 +152,25 @@ func (h *Handler) handleRequest(conn net.Conn, req *http.Request) { req.Header.Del("Proxy-Authorization") - /* - retries := 1 - if h.options.Chain != nil && h.options.Chain.Retries > 0 { - retries = h.options.Chain.Retries - } - if h.options.Retries > 0 { - retries = h.options.Retries - } - - var err error - var cc net.Conn - var route *Chain - for i := 0; i < retries; i++ { - route, err = h.options.Chain.selectRouteFor(host) - if err != nil { - log.Logf("[http] %s -> %s : %s", - conn.RemoteAddr(), conn.LocalAddr(), err) - continue - } - - buf := bytes.Buffer{} - fmt.Fprintf(&buf, "%s -> %s -> ", - conn.RemoteAddr(), h.options.Node.String()) - for _, nd := range route.route { - fmt.Fprintf(&buf, "%d@%s -> ", nd.ID, nd.String()) - } - fmt.Fprintf(&buf, "%s", host) - log.Log("[route]", buf.String()) - - // forward http request - lastNode := route.LastNode() - if req.Method != http.MethodConnect && lastNode.Protocol == "http" { - err = h.forwardRequest(conn, req, route) - if err == nil { - return - } - log.Logf("[http] %s -> %s : %s", conn.RemoteAddr(), conn.LocalAddr(), err) - continue - } - - cc, err = route.Dial(host, - TimeoutChainOption(h.options.Timeout), - HostsChainOption(h.options.Hosts), - ResolverChainOption(h.options.Resolver), - ) - if err == nil { - break - } - log.Logf("[http] %s -> %s : %s", conn.RemoteAddr(), conn.LocalAddr(), err) - } - - if err != nil { - resp.StatusCode = http.StatusServiceUnavailable + cc, err := h.dial(ctx, host) + if err != nil { + resp.StatusCode = http.StatusServiceUnavailable + /* if Debug { dump, _ := httputil.DumpResponse(resp, false) log.Logf("[http] %s <- %s\n%s", conn.RemoteAddr(), conn.LocalAddr(), string(dump)) } - - resp.Write(conn) - return - } - */ - cc, err := net.Dial("tcp", host) - if err != nil { - resp.StatusCode = http.StatusServiceUnavailable + */ resp.Write(conn) return } defer cc.Close() if req.Method == http.MethodConnect { - b := []byte("HTTP/1.1 200 Connection established\r\n" + - "Proxy-Agent: " + h.md.proxyAgent + "\r\n\r\n") - conn.Write(b) + resp.StatusCode = http.StatusOK + resp.Status = "200 Connection established" + resp.Write(conn) } else { req.Header.Del("Proxy-Connection") @@ -231,3 +181,45 @@ func (h *Handler) handleRequest(conn net.Conn, req *http.Request) { handler.Transport(conn, cc) } + +func (h *Handler) dial(ctx context.Context, addr string) (conn net.Conn, err error) { + count := h.md.retryCount + 1 + if count <= 0 { + count = 1 + } + + for i := 0; i < count; i++ { + route := h.chain.GetRoute() + + /* + buf := bytes.Buffer{} + fmt.Fprintf(&buf, "%s -> %s -> ", + conn.RemoteAddr(), h.options.Node.String()) + for _, nd := range route.route { + fmt.Fprintf(&buf, "%d@%s -> ", nd.ID, nd.String()) + } + fmt.Fprintf(&buf, "%s", host) + log.Log("[route]", buf.String()) + */ + + /* + // forward http request + lastNode := route.LastNode() + if req.Method != http.MethodConnect && lastNode.Protocol == "http" { + err = h.forwardRequest(conn, req, route) + if err == nil { + return + } + log.Logf("[http] %s -> %s : %s", conn.RemoteAddr(), conn.LocalAddr(), err) + continue + } + */ + + conn, err = route.Dial(ctx, "tcp", addr) + if err != nil { + continue + } + } + + return +} diff --git a/server/handler/http/metadata.go b/pkg/components/handler/http/metadata.go similarity index 82% rename from server/handler/http/metadata.go rename to pkg/components/handler/http/metadata.go index 2b8c70d..7893903 100644 --- a/server/handler/http/metadata.go +++ b/pkg/components/handler/http/metadata.go @@ -3,4 +3,5 @@ package http type metadata struct { addr string proxyAgent string + retryCount int } diff --git a/server/handler/metadata.go b/pkg/components/handler/metadata.go similarity index 100% rename from server/handler/metadata.go rename to pkg/components/handler/metadata.go diff --git a/pkg/components/handler/option.go b/pkg/components/handler/option.go new file mode 100644 index 0000000..42478c4 --- /dev/null +++ b/pkg/components/handler/option.go @@ -0,0 +1,25 @@ +package handler + +import ( + "github.com/go-gost/gost/pkg/chain" + "github.com/go-gost/gost/pkg/logger" +) + +type Options struct { + Chain *chain.Chain + Logger logger.Logger +} + +type Option func(opts *Options) + +func LoggerOption(logger logger.Logger) Option { + return func(opts *Options) { + opts.Logger = logger + } +} + +func ChainOption(chain *chain.Chain) Option { + return func(opts *Options) { + opts.Chain = chain + } +} diff --git a/server/handler/ss/handler.go b/pkg/components/handler/ss/handler.go similarity index 96% rename from server/handler/ss/handler.go rename to pkg/components/handler/ss/handler.go index 3145e6c..95fb47b 100644 --- a/server/handler/ss/handler.go +++ b/pkg/components/handler/ss/handler.go @@ -7,8 +7,8 @@ import ( "time" "github.com/go-gost/gosocks5" - "github.com/go-gost/gost/logger" - "github.com/go-gost/gost/server/handler" + "github.com/go-gost/gost/pkg/components/handler" + "github.com/go-gost/gost/pkg/logger" "github.com/shadowsocks/go-shadowsocks2/core" ss "github.com/shadowsocks/shadowsocks-go/shadowsocks" ) diff --git a/server/handler/ss/metadata.go b/pkg/components/handler/ss/metadata.go similarity index 100% rename from server/handler/ss/metadata.go rename to pkg/components/handler/ss/metadata.go diff --git a/server/handler/ssu/handler.go b/pkg/components/handler/ssu/handler.go similarity index 94% rename from server/handler/ssu/handler.go rename to pkg/components/handler/ssu/handler.go index 0588241..143fb6a 100644 --- a/server/handler/ssu/handler.go +++ b/pkg/components/handler/ssu/handler.go @@ -5,8 +5,8 @@ import ( "net" "time" - "github.com/go-gost/gost/logger" - "github.com/go-gost/gost/server/handler" + "github.com/go-gost/gost/pkg/components/handler" + "github.com/go-gost/gost/pkg/logger" "github.com/shadowsocks/go-shadowsocks2/core" ss "github.com/shadowsocks/shadowsocks-go/shadowsocks" ) diff --git a/server/handler/ssu/metadata.go b/pkg/components/handler/ssu/metadata.go similarity index 100% rename from server/handler/ssu/metadata.go rename to pkg/components/handler/ssu/metadata.go diff --git a/server/handler/transport.go b/pkg/components/handler/transport.go similarity index 100% rename from server/handler/transport.go rename to pkg/components/handler/transport.go diff --git a/utils/kcp.go b/pkg/components/internal/utils/kcp.go similarity index 100% rename from utils/kcp.go rename to pkg/components/internal/utils/kcp.go diff --git a/utils/quic.go b/pkg/components/internal/utils/quic.go similarity index 100% rename from utils/quic.go rename to pkg/components/internal/utils/quic.go diff --git a/utils/tcp.go b/pkg/components/internal/utils/tcp.go similarity index 100% rename from utils/tcp.go rename to pkg/components/internal/utils/tcp.go diff --git a/utils/tls.go b/pkg/components/internal/utils/tls.go similarity index 100% rename from utils/tls.go rename to pkg/components/internal/utils/tls.go diff --git a/utils/ws.go b/pkg/components/internal/utils/ws.go similarity index 100% rename from utils/ws.go rename to pkg/components/internal/utils/ws.go diff --git a/server/listener/ftcp/conn.go b/pkg/components/listener/ftcp/conn.go similarity index 100% rename from server/listener/ftcp/conn.go rename to pkg/components/listener/ftcp/conn.go diff --git a/server/listener/ftcp/listener.go b/pkg/components/listener/ftcp/listener.go similarity index 96% rename from server/listener/ftcp/listener.go rename to pkg/components/listener/ftcp/listener.go index 9402603..81e7941 100644 --- a/server/listener/ftcp/listener.go +++ b/pkg/components/listener/ftcp/listener.go @@ -6,8 +6,8 @@ import ( "sync" "sync/atomic" - "github.com/go-gost/gost/logger" - "github.com/go-gost/gost/server/listener" + "github.com/go-gost/gost/pkg/components/listener" + "github.com/go-gost/gost/pkg/logger" "github.com/xtaci/tcpraw" ) diff --git a/server/listener/ftcp/metadata.go b/pkg/components/listener/ftcp/metadata.go similarity index 100% rename from server/listener/ftcp/metadata.go rename to pkg/components/listener/ftcp/metadata.go diff --git a/server/listener/http2/conn.go b/pkg/components/listener/http2/conn.go similarity index 100% rename from server/listener/http2/conn.go rename to pkg/components/listener/http2/conn.go diff --git a/server/listener/http2/h2/conn.go b/pkg/components/listener/http2/h2/conn.go similarity index 100% rename from server/listener/http2/h2/conn.go rename to pkg/components/listener/http2/h2/conn.go diff --git a/server/listener/http2/h2/listener.go b/pkg/components/listener/http2/h2/listener.go similarity index 96% rename from server/listener/http2/h2/listener.go rename to pkg/components/listener/http2/h2/listener.go index b736089..9a71e53 100644 --- a/server/listener/http2/h2/listener.go +++ b/pkg/components/listener/http2/h2/listener.go @@ -7,9 +7,9 @@ import ( "net/http" "time" - "github.com/go-gost/gost/logger" - "github.com/go-gost/gost/server/listener" - "github.com/go-gost/gost/utils" + "github.com/go-gost/gost/pkg/components/internal/utils" + "github.com/go-gost/gost/pkg/components/listener" + "github.com/go-gost/gost/pkg/logger" "golang.org/x/net/http2" ) diff --git a/server/listener/http2/h2/metadata.go b/pkg/components/listener/http2/h2/metadata.go similarity index 100% rename from server/listener/http2/h2/metadata.go rename to pkg/components/listener/http2/h2/metadata.go diff --git a/server/listener/http2/listener.go b/pkg/components/listener/http2/listener.go similarity index 94% rename from server/listener/http2/listener.go rename to pkg/components/listener/http2/listener.go index be6cdf6..1298810 100644 --- a/server/listener/http2/listener.go +++ b/pkg/components/listener/http2/listener.go @@ -6,9 +6,9 @@ import ( "net" "net/http" - "github.com/go-gost/gost/logger" - "github.com/go-gost/gost/server/listener" - "github.com/go-gost/gost/utils" + "github.com/go-gost/gost/pkg/components/internal/utils" + "github.com/go-gost/gost/pkg/components/listener" + "github.com/go-gost/gost/pkg/logger" "golang.org/x/net/http2" ) diff --git a/server/listener/http2/metadata.go b/pkg/components/listener/http2/metadata.go similarity index 100% rename from server/listener/http2/metadata.go rename to pkg/components/listener/http2/metadata.go diff --git a/server/listener/kcp/config.go b/pkg/components/listener/kcp/config.go similarity index 100% rename from server/listener/kcp/config.go rename to pkg/components/listener/kcp/config.go diff --git a/server/listener/kcp/listener.go b/pkg/components/listener/kcp/listener.go similarity index 95% rename from server/listener/kcp/listener.go rename to pkg/components/listener/kcp/listener.go index a85a79c..2879ca5 100644 --- a/server/listener/kcp/listener.go +++ b/pkg/components/listener/kcp/listener.go @@ -5,9 +5,9 @@ import ( "net" "time" - "github.com/go-gost/gost/logger" - "github.com/go-gost/gost/server/listener" - "github.com/go-gost/gost/utils" + "github.com/go-gost/gost/pkg/components/internal/utils" + "github.com/go-gost/gost/pkg/components/listener" + "github.com/go-gost/gost/pkg/logger" "github.com/xtaci/kcp-go/v5" "github.com/xtaci/smux" "github.com/xtaci/tcpraw" diff --git a/server/listener/kcp/metadata.go b/pkg/components/listener/kcp/metadata.go similarity index 100% rename from server/listener/kcp/metadata.go rename to pkg/components/listener/kcp/metadata.go diff --git a/server/listener/listener.go b/pkg/components/listener/listener.go similarity index 93% rename from server/listener/listener.go rename to pkg/components/listener/listener.go index 30110dc..3597e9a 100644 --- a/server/listener/listener.go +++ b/pkg/components/listener/listener.go @@ -11,7 +11,6 @@ var ( // Listener is a server listener, just like a net.Listener. type Listener interface { - Init(md Metadata) error net.Listener } diff --git a/server/listener/metadata.go b/pkg/components/listener/metadata.go similarity index 100% rename from server/listener/metadata.go rename to pkg/components/listener/metadata.go diff --git a/server/listener/obfs/http/conn.go b/pkg/components/listener/obfs/http/conn.go similarity index 100% rename from server/listener/obfs/http/conn.go rename to pkg/components/listener/obfs/http/conn.go diff --git a/server/listener/obfs/http/listener.go b/pkg/components/listener/obfs/http/listener.go similarity index 90% rename from server/listener/obfs/http/listener.go rename to pkg/components/listener/obfs/http/listener.go index c8c5f54..5e1a86b 100644 --- a/server/listener/obfs/http/listener.go +++ b/pkg/components/listener/obfs/http/listener.go @@ -6,9 +6,9 @@ import ( "strconv" "time" - "github.com/go-gost/gost/logger" - "github.com/go-gost/gost/server/listener" - "github.com/go-gost/gost/utils" + "github.com/go-gost/gost/pkg/components/internal/utils" + "github.com/go-gost/gost/pkg/components/listener" + "github.com/go-gost/gost/pkg/logger" ) var ( diff --git a/server/listener/obfs/http/metadata.go b/pkg/components/listener/obfs/http/metadata.go similarity index 100% rename from server/listener/obfs/http/metadata.go rename to pkg/components/listener/obfs/http/metadata.go diff --git a/server/listener/obfs/tls/conn.go b/pkg/components/listener/obfs/tls/conn.go similarity index 100% rename from server/listener/obfs/tls/conn.go rename to pkg/components/listener/obfs/tls/conn.go diff --git a/server/listener/obfs/tls/listener.go b/pkg/components/listener/obfs/tls/listener.go similarity index 90% rename from server/listener/obfs/tls/listener.go rename to pkg/components/listener/obfs/tls/listener.go index 92e34b3..9d1598d 100644 --- a/server/listener/obfs/tls/listener.go +++ b/pkg/components/listener/obfs/tls/listener.go @@ -6,9 +6,9 @@ import ( "strconv" "time" - "github.com/go-gost/gost/logger" - "github.com/go-gost/gost/server/listener" - "github.com/go-gost/gost/utils" + "github.com/go-gost/gost/pkg/components/internal/utils" + "github.com/go-gost/gost/pkg/components/listener" + "github.com/go-gost/gost/pkg/logger" ) var ( diff --git a/server/listener/obfs/tls/metadata.go b/pkg/components/listener/obfs/tls/metadata.go similarity index 100% rename from server/listener/obfs/tls/metadata.go rename to pkg/components/listener/obfs/tls/metadata.go diff --git a/server/listener/option.go b/pkg/components/listener/option.go similarity index 85% rename from server/listener/option.go rename to pkg/components/listener/option.go index 362b964..299bf03 100644 --- a/server/listener/option.go +++ b/pkg/components/listener/option.go @@ -1,7 +1,7 @@ package listener import ( - "github.com/go-gost/gost/logger" + "github.com/go-gost/gost/pkg/logger" ) type Options struct { diff --git a/server/listener/quic/listener.go b/pkg/components/listener/quic/listener.go similarity index 94% rename from server/listener/quic/listener.go rename to pkg/components/listener/quic/listener.go index 5f6bd62..0063a06 100644 --- a/server/listener/quic/listener.go +++ b/pkg/components/listener/quic/listener.go @@ -5,9 +5,9 @@ import ( "errors" "net" - "github.com/go-gost/gost/logger" - "github.com/go-gost/gost/server/listener" - "github.com/go-gost/gost/utils" + "github.com/go-gost/gost/pkg/components/internal/utils" + "github.com/go-gost/gost/pkg/components/listener" + "github.com/go-gost/gost/pkg/logger" "github.com/lucas-clemente/quic-go" ) diff --git a/server/listener/quic/metadata.go b/pkg/components/listener/quic/metadata.go similarity index 100% rename from server/listener/quic/metadata.go rename to pkg/components/listener/quic/metadata.go diff --git a/server/listener/tcp/listener.go b/pkg/components/listener/tcp/listener.go similarity index 89% rename from server/listener/tcp/listener.go rename to pkg/components/listener/tcp/listener.go index be2344d..dbb7c24 100644 --- a/server/listener/tcp/listener.go +++ b/pkg/components/listener/tcp/listener.go @@ -6,9 +6,9 @@ import ( "strconv" "time" - "github.com/go-gost/gost/logger" - "github.com/go-gost/gost/server/listener" - "github.com/go-gost/gost/utils" + "github.com/go-gost/gost/pkg/components/internal/utils" + "github.com/go-gost/gost/pkg/components/listener" + "github.com/go-gost/gost/pkg/logger" ) var ( diff --git a/server/listener/tcp/metadata.go b/pkg/components/listener/tcp/metadata.go similarity index 100% rename from server/listener/tcp/metadata.go rename to pkg/components/listener/tcp/metadata.go diff --git a/server/listener/tls/listener.go b/pkg/components/listener/tls/listener.go similarity index 88% rename from server/listener/tls/listener.go rename to pkg/components/listener/tls/listener.go index 510209c..c97d407 100644 --- a/server/listener/tls/listener.go +++ b/pkg/components/listener/tls/listener.go @@ -6,9 +6,9 @@ import ( "net" "time" - "github.com/go-gost/gost/logger" - "github.com/go-gost/gost/server/listener" - "github.com/go-gost/gost/utils" + "github.com/go-gost/gost/pkg/components/internal/utils" + "github.com/go-gost/gost/pkg/components/listener" + "github.com/go-gost/gost/pkg/logger" ) var ( diff --git a/server/listener/tls/metadata.go b/pkg/components/listener/tls/metadata.go similarity index 100% rename from server/listener/tls/metadata.go rename to pkg/components/listener/tls/metadata.go diff --git a/server/listener/tls/mux/listener.go b/pkg/components/listener/tls/mux/listener.go similarity index 94% rename from server/listener/tls/mux/listener.go rename to pkg/components/listener/tls/mux/listener.go index 0b7746a..9afb862 100644 --- a/server/listener/tls/mux/listener.go +++ b/pkg/components/listener/tls/mux/listener.go @@ -5,9 +5,9 @@ import ( "errors" "net" - "github.com/go-gost/gost/logger" - "github.com/go-gost/gost/server/listener" - "github.com/go-gost/gost/utils" + "github.com/go-gost/gost/pkg/components/internal/utils" + "github.com/go-gost/gost/pkg/components/listener" + "github.com/go-gost/gost/pkg/logger" "github.com/xtaci/smux" ) diff --git a/server/listener/tls/mux/metadata.go b/pkg/components/listener/tls/mux/metadata.go similarity index 100% rename from server/listener/tls/mux/metadata.go rename to pkg/components/listener/tls/mux/metadata.go diff --git a/server/listener/udp/conn.go b/pkg/components/listener/udp/conn.go similarity index 100% rename from server/listener/udp/conn.go rename to pkg/components/listener/udp/conn.go diff --git a/server/listener/udp/listener.go b/pkg/components/listener/udp/listener.go similarity index 97% rename from server/listener/udp/listener.go rename to pkg/components/listener/udp/listener.go index f328489..7e117da 100644 --- a/server/listener/udp/listener.go +++ b/pkg/components/listener/udp/listener.go @@ -6,8 +6,8 @@ import ( "sync" "sync/atomic" - "github.com/go-gost/gost/logger" - "github.com/go-gost/gost/server/listener" + "github.com/go-gost/gost/pkg/components/listener" + "github.com/go-gost/gost/pkg/logger" ) var ( diff --git a/server/listener/udp/metadata.go b/pkg/components/listener/udp/metadata.go similarity index 100% rename from server/listener/udp/metadata.go rename to pkg/components/listener/udp/metadata.go diff --git a/server/listener/ws/listener.go b/pkg/components/listener/ws/listener.go similarity index 94% rename from server/listener/ws/listener.go rename to pkg/components/listener/ws/listener.go index d3ed2f5..21ea15b 100644 --- a/server/listener/ws/listener.go +++ b/pkg/components/listener/ws/listener.go @@ -6,9 +6,9 @@ import ( "net" "net/http" - "github.com/go-gost/gost/logger" - "github.com/go-gost/gost/server/listener" - "github.com/go-gost/gost/utils" + "github.com/go-gost/gost/pkg/components/internal/utils" + "github.com/go-gost/gost/pkg/components/listener" + "github.com/go-gost/gost/pkg/logger" "github.com/gorilla/websocket" ) diff --git a/server/listener/ws/metadata.go b/pkg/components/listener/ws/metadata.go similarity index 100% rename from server/listener/ws/metadata.go rename to pkg/components/listener/ws/metadata.go diff --git a/server/listener/ws/mux/listener.go b/pkg/components/listener/ws/mux/listener.go similarity index 95% rename from server/listener/ws/mux/listener.go rename to pkg/components/listener/ws/mux/listener.go index b522c15..e7cd56e 100644 --- a/server/listener/ws/mux/listener.go +++ b/pkg/components/listener/ws/mux/listener.go @@ -6,9 +6,9 @@ import ( "net" "net/http" - "github.com/go-gost/gost/logger" - "github.com/go-gost/gost/server/listener" - "github.com/go-gost/gost/utils" + "github.com/go-gost/gost/pkg/components/internal/utils" + "github.com/go-gost/gost/pkg/components/listener" + "github.com/go-gost/gost/pkg/logger" "github.com/gorilla/websocket" "github.com/xtaci/smux" ) diff --git a/server/listener/ws/mux/metadata.go b/pkg/components/listener/ws/mux/metadata.go similarity index 100% rename from server/listener/ws/mux/metadata.go rename to pkg/components/listener/ws/mux/metadata.go diff --git a/logger/gost_logger.go b/pkg/logger/gost_logger.go similarity index 100% rename from logger/gost_logger.go rename to pkg/logger/gost_logger.go diff --git a/logger/logger.go b/pkg/logger/logger.go similarity index 100% rename from logger/logger.go rename to pkg/logger/logger.go diff --git a/pkg/service/service.go b/pkg/service/service.go new file mode 100644 index 0000000..eb36f0b --- /dev/null +++ b/pkg/service/service.go @@ -0,0 +1,63 @@ +package service + +import ( + "context" + "net" + "time" + + "github.com/go-gost/gost/pkg/components/handler" + "github.com/go-gost/gost/pkg/components/listener" +) + +type Service struct { + listener listener.Listener + handler handler.Handler +} + +func (s *Service) WithListener(ln listener.Listener) *Service { + s.listener = ln + return s +} + +func (s *Service) WithHandler(h handler.Handler) *Service { + s.handler = h + return s +} + +func (s *Service) Addr() net.Addr { + return s.listener.Addr() +} + +func (s *Service) Run() error { + return s.serve() +} + +func (s *Service) Close() error { + return s.listener.Close() +} + +func (s *Service) serve() error { + var tempDelay time.Duration + for { + conn, e := s.listener.Accept() + if e != nil { + if ne, ok := e.(net.Error); ok && ne.Temporary() { + if tempDelay == 0 { + tempDelay = 5 * time.Millisecond + } else { + tempDelay *= 2 + } + if max := 1 * time.Second; tempDelay > max { + tempDelay = max + } + // log.Logf("server: Accept error: %v; retrying in %v", e, tempDelay) + time.Sleep(tempDelay) + continue + } + return e + } + tempDelay = 0 + + go s.handler.Handle(context.Background(), conn) + } +} diff --git a/server/server.go b/server/server.go deleted file mode 100644 index 83f0a8c..0000000 --- a/server/server.go +++ /dev/null @@ -1,12 +0,0 @@ -package server - -import ( - "github.com/go-gost/gost/server/handler" - "github.com/go-gost/gost/server/listener" -) - -// Server is a proxy server. -type Server struct { - Handler handler.Handler - Listener listener.Listener -}