add chain
This commit is contained in:
1 parent
ce13b2a82a
commit
3351aa5974
78 files changed
+917
-185
No files matched your search
+34
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
@@ -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=
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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...)
|
||||
}
|
||||
@@ -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]
|
||||
}
|
||||
@@ -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...)
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package connector
|
||||
|
||||
type Metadata map[string]string
|
||||
@@ -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)
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package ss
|
||||
|
||||
const (
|
||||
method = "method"
|
||||
password = "password"
|
||||
)
|
||||
|
||||
type metadata struct {
|
||||
method string
|
||||
password string
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
File renamed without changes.
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
File renamed without changes.
@@ -6,6 +6,5 @@ import (
|
||||
)
|
||||
|
||||
type Handler interface {
|
||||
Init(md Metadata) error
|
||||
Handle(context.Context, net.Conn)
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -3,4 +3,5 @@ package http
|
||||
type metadata struct {
|
||||
addr string
|
||||
proxyAgent string
|
||||
retryCount int
|
||||
}
|
||||
File renamed without changes.
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
)
|
||||
File renamed without changes.
@@ -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"
|
||||
)
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -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"
|
||||
)
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -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"
|
||||
)
|
||||
|
||||
File renamed without changes.
@@ -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"
|
||||
)
|
||||
|
||||
File renamed without changes.
File renamed without changes.
@@ -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"
|
||||
File renamed without changes.
@@ -11,7 +11,6 @@ var (
|
||||
|
||||
// Listener is a server listener, just like a net.Listener.
|
||||
type Listener interface {
|
||||
Init(md Metadata) error
|
||||
net.Listener
|
||||
}
|
||||
|
||||
File renamed without changes.
File renamed without changes.
+3
-3
@@ -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 (
|
||||
File renamed without changes.
File renamed without changes.
@@ -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 (
|
||||
File renamed without changes.
@@ -1,7 +1,7 @@
|
||||
package listener
|
||||
|
||||
import (
|
||||
"github.com/go-gost/gost/logger"
|
||||
"github.com/go-gost/gost/pkg/logger"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
File renamed without changes.
@@ -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 (
|
||||
File renamed without changes.
@@ -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 (
|
||||
File renamed without changes.
@@ -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"
|
||||
)
|
||||
|
||||
File renamed without changes.
File renamed without changes.
@@ -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 (
|
||||
File renamed without changes.
@@ -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"
|
||||
)
|
||||
|
||||
File renamed without changes.
@@ -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"
|
||||
)
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
Reference in new issue
Block a user