From ef2c0959669b83ab1d7ef3aea64055ba8655c27a Mon Sep 17 00:00:00 2001 From: wweir Date: Sat, 12 Oct 2024 00:20:34 +0800 Subject: [PATCH] fix: http_proxy --- cmd/sower/proxy.go | 100 ++++++++++++++---------------------- cmd/sowerd/main.go | 28 +++++----- go.mod | 33 ++++++------ go.sum | 62 ++++++---------------- router/util.go | 14 +++-- transport/socks5/rfc.go | 8 ++- transport/socks5/socks5.go | 12 +++-- transport/transport_test.go | 4 +- transport/trojan/trojan.go | 9 ++-- 9 files changed, 114 insertions(+), 156 deletions(-) diff --git a/cmd/sower/proxy.go b/cmd/sower/proxy.go index f81272b..3f182e9 100644 --- a/cmd/sower/proxy.go +++ b/cmd/sower/proxy.go @@ -9,7 +9,7 @@ import ( "github.com/pkg/errors" "github.com/sower-proxy/conns/relay" - "github.com/sower-proxy/conns/teeconn" + "github.com/sower-proxy/conns/reread" "github.com/sower-proxy/deferlog/log" "github.com/wweir/sower/router" "github.com/wweir/sower/transport" @@ -77,10 +77,10 @@ func ServeHTTP(ln net.Listener, r *router.Router) { go ServeHTTP(ln, r) start := time.Now() - teeconn := teeconn.New(conn) - defer teeconn.Close() + reread := reread.New(conn) + defer reread.Close() - req, err := http.ReadRequest(bufio.NewReader(teeconn)) + req, err := http.ReadRequest(bufio.NewReader(reread)) if err != nil { log.Error().Err(err).Msg("read http request") return @@ -96,8 +96,8 @@ func ServeHTTP(ln net.Listener, r *router.Router) { } defer rc.Close() - teeconn.Stop().Reread() - err = relay.Relay(teeconn, rc) + reread.Stop().Reread() + err = relay.Relay(reread, rc) log.DebugWarn(err). Str("host", req.Host). Dur("spend", time.Since(start)). @@ -113,11 +113,11 @@ func ServeHTTPS(ln net.Listener, r *router.Router) { go ServeHTTPS(ln, r) start := time.Now() - teeconn := teeconn.New(conn) - defer teeconn.Close() + reread := reread.New(conn) + defer reread.Close() var domain string - tls.Server(teeconn, &tls.Config{ + tls.Server(reread, &tls.Config{ GetConfigForClient: func(hello *tls.ClientHelloInfo) (*tls.Config, error) { domain = hello.ServerName return nil, nil @@ -133,8 +133,8 @@ func ServeHTTPS(ln net.Listener, r *router.Router) { } defer rc.Close() - teeconn.Stop().Reread() - err = relay.Relay(teeconn, rc) + reread.Stop().Reread() + err = relay.Relay(reread, rc) log.DebugWarn(err). Str("host", domain). Dur("spend", time.Since(start)). @@ -150,70 +150,46 @@ func ServeSocks5(ln net.Listener, r *router.Router) { go ServeSocks5(ln, r) defer conn.Close() - teeConn := teeconn.New(conn) + reread := reread.New(conn) - buf1 := make([]byte, 1) - if _, err := teeConn.Read(buf1); err != nil { - log.Warn().Err(err). - Msg("read socks5 version") + byte1 := make([]byte, 1) + if n, err := reread.Read(byte1); err != nil || n != 1 { + log.Error().Err(err).Msg("read first byte") return } - - if buf1[0] != 5 { - teeConn.Reread() - serveHttpProxy(teeConn, r) + reread.Reread() + + if byte1[0] == 5 { + reread.Stop() + if addr, err := socks5.New().Unwrap(reread); err != nil { + log.Error().Err(err).Msg("read socks5 request") + } else { + host, port := addr.(*socks5.AddrHead).Addr() + r.RouteHandle(reread, host, port) + } return } - teeConn.Stop().Reread() - addr, err := socks5.New().Unwrap(teeConn) + req, err := http.ReadRequest(bufio.NewReader(reread)) if err != nil { - log.Warn().Err(err). - Msgf("parse socks5 target: %s", addr) + log.Error().Err(err).Msg("read http request") return } - host, port := addr.(*socks5.AddrHead).Addr() - r.RouteHandle(teeConn, host, port) -} - -func serveHttpProxy(teeConn *teeconn.Conn, r *router.Router) { - req, err := http.ReadRequest(bufio.NewReader(teeConn)) + host, port, err := router.ParseHostPort(req.Host, req.URL) if err != nil { - log.Warn().Err(err). - Msg("read http request") + reread.Stop().Write([]byte("HTTP/1.1 400 Bad Request\r\n\r\n")) return } - teeConn.Stop() - switch req.Method { - case "CONNECT": - if _, err := teeConn.Write([]byte(req.Proto + " 200 Connection established\r\n\r\n")); err != nil { - log.Warn().Err(err). - Msg("write https proxy response") - return - } - - host, port, err := router.ParseHostPort(req.Host, 443) - if err != nil { - log.Warn().Err(err). - Msg("parse https_proxy target") - return - } - - rc, err := r.ProxyDial("tcp", host, port) - if err != nil { - log.Warn().Err(err). - Str("host", host). - Msg("dial proxy") - return - } - defer rc.Close() - - relay.Relay(teeConn, rc) - - default: - teeConn.Reread() - r.RouteHandle(teeConn, req.Host, 80) + if req.Method == http.MethodConnect { + // https + reread.Stop().Reset() + reread.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n")) + } else { + // http + reread.Stop().Reread() } + + r.RouteHandle(reread, host, port) } diff --git a/cmd/sowerd/main.go b/cmd/sowerd/main.go index 99fc65a..81d3271 100644 --- a/cmd/sowerd/main.go +++ b/cmd/sowerd/main.go @@ -10,7 +10,7 @@ import ( "github.com/cristalhq/aconfig" "github.com/sower-proxy/conns/relay" - "github.com/sower-proxy/conns/teeconn" + "github.com/sower-proxy/conns/reread" "github.com/sower-proxy/deferlog" "github.com/sower-proxy/deferlog/log" "github.com/wweir/sower/transport/sower" @@ -46,7 +46,7 @@ func init() { func main() { cacheDir, _ := os.UserCacheDir() cacheDir = filepath.Join(cacheDir, "sower") - if err := os.MkdirAll(cacheDir, 0600); err != nil { + if err := os.MkdirAll(cacheDir, 0o600); err != nil { log.Fatal().Err(err). Str("dir", cacheDir). Msg("make cache dir") @@ -113,8 +113,8 @@ func serve443(ln net.Listener, fakeSite string, sower *sower.Sower, trojan *troj log.Fatal().Err(err).Msg("serve 443 port") } go serve443(ln, fakeSite, sower, trojan) - teeconn := teeconn.New(conn) - defer teeconn.Close() + reread := reread.New(conn) + defer reread.Close() var addr net.Addr var dur time.Duration @@ -125,24 +125,24 @@ func serve443(ln net.Listener, fakeSite string, sower *sower.Sower, trojan *troj }() // 1. detect if it's a sower underlaying connection - teeconn.Reread() - if addr, err = sower.Unwrap(teeconn); err == nil { - teeconn.Stop() + reread.Reread() + if addr, err = sower.Unwrap(reread); err == nil { + reread.Stop() - dur, err = relay.RelayTo(teeconn, addr.String()) + dur, err = relay.RelayTo(reread, addr.String()) return } // 2. detect if it's a trojan underlaying connection - teeconn.Reread() - if addr, err = trojan.Unwrap(teeconn); err == nil { - teeconn.Stop() + reread.Reread() + if addr, err = trojan.Unwrap(reread); err == nil { + reread.Stop() - dur, err = relay.RelayTo(teeconn, addr.String()) + dur, err = relay.RelayTo(reread, addr.String()) return } // 3. fallback to fake site - teeconn.Stop().Reread() - dur, err = relay.RelayTo(teeconn, fakeSite) + reread.Stop().Reread() + dur, err = relay.RelayTo(reread, fakeSite) } diff --git a/go.mod b/go.mod index dae80ed..c04f5a8 100644 --- a/go.mod +++ b/go.mod @@ -1,37 +1,36 @@ module github.com/wweir/sower -go 1.22 - -toolchain go1.22.3 +go 1.23 require ( - github.com/cristalhq/aconfig v0.18.5 + github.com/cristalhq/aconfig v0.18.6 github.com/cristalhq/aconfig/aconfighcl v0.17.1 github.com/cristalhq/aconfig/aconfigtoml v0.17.1 github.com/cristalhq/aconfig/aconfigyaml v0.17.1 github.com/krolaw/dhcp4 v0.0.0-20190909130307-a50d88189771 github.com/libp2p/go-reuseport v0.4.0 - github.com/miekg/dns v1.1.59 - github.com/oschwald/geoip2-golang v1.9.0 + github.com/miekg/dns v1.1.62 + github.com/oschwald/geoip2-golang v1.11.0 github.com/pkg/errors v0.9.1 - github.com/sower-proxy/conns v0.0.3 + github.com/sower-proxy/conns v0.1.0 github.com/sower-proxy/deferlog v1.0.7 github.com/sower-proxy/mem v0.0.3 - golang.org/x/crypto v0.23.0 + golang.org/x/crypto v0.28.0 ) require ( - github.com/BurntSushi/toml v1.3.2 // indirect + github.com/BurntSushi/toml v1.1.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/oschwald/maxminddb-golang v1.12.0 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/oschwald/maxminddb-golang v1.13.0 // indirect github.com/rs/zerolog v1.32.0 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.25.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect - golang.org/x/tools v0.21.0 // indirect + golang.org/x/mod v0.18.0 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect + golang.org/x/tools v0.22.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 3ffec12..7d57732 100644 --- a/go.sum +++ b/go.sum @@ -1,70 +1,40 @@ github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cristalhq/aconfig v0.17.0/go.mod h1:NXaRp+1e6bkO4dJn+wZ71xyaihMDYPtCSvEhMTm/H3E= -github.com/cristalhq/aconfig v0.18.5 h1:QqXH/Gy2c4QUQJTV2BN8UAuL/rqZ3IwhvxeC8OgzquA= -github.com/cristalhq/aconfig v0.18.5/go.mod h1:NXaRp+1e6bkO4dJn+wZ71xyaihMDYPtCSvEhMTm/H3E= -github.com/cristalhq/aconfig/aconfighcl v0.17.1 h1:/hJvmmoP3akvjY8qARiXgN30m/WXeBvpQdQ8v4DE8W8= +github.com/cristalhq/aconfig v0.18.6/go.mod h1:9ogrGEt9yU5V4pif/ThkVUfhj8JkdV+iDeahZGgfnDU= github.com/cristalhq/aconfig/aconfighcl v0.17.1/go.mod h1:oOPqMmdUjVW6pKKO1zkOwQKHSUD0rlu8F5do+pylOQc= -github.com/cristalhq/aconfig/aconfigtoml v0.17.1 h1:TA3xH8mALD8YeULsr4v87cMbKGBma35lWeRga4Xn11Q= github.com/cristalhq/aconfig/aconfigtoml v0.17.1/go.mod h1:xt4kCEjhgvHWO/oDGJHQHrW5CnvSEoBjJhRXVBdYbhQ= -github.com/cristalhq/aconfig/aconfigyaml v0.17.1 h1:xCCbRKVmKrft9gQj3gHOq6U5PduasvlXEIsxtyzmFZ0= github.com/cristalhq/aconfig/aconfigyaml v0.17.1/go.mod h1:5DTsjHkvQ6hfbyxfG32roB1lF0U82rROtFaLxibL8V8= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/krolaw/dhcp4 v0.0.0-20190909130307-a50d88189771 h1:t2c2B9g1ZVhMYduqmANSEGVD3/1WlsrEYNPtVoFlENk= github.com/krolaw/dhcp4 v0.0.0-20190909130307-a50d88189771/go.mod h1:0AqAH3ZogsCrvrtUpvc6EtVKbc3w6xwZhkvGLuqyi3o= -github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= -github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= -github.com/oschwald/geoip2-golang v1.9.0 h1:uvD3O6fXAXs+usU+UGExshpdP13GAqp4GBrzN7IgKZc= -github.com/oschwald/geoip2-golang v1.9.0/go.mod h1:BHK6TvDyATVQhKNbQBdrj9eAvuwOMi2zSFXizL3K81Y= -github.com/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq50AS6wALUMYs= -github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/oschwald/geoip2-golang v1.11.0/go.mod h1:P9zG+54KPEFOliZ29i7SeYZ/GM6tfEL+rgSn03hYuUo= +github.com/oschwald/maxminddb-golang v1.13.0/go.mod h1:BU0z8BfFVhi1LQaonTwwGQlsHUEu9pWNdMfmq4ztm0o= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= -github.com/sower-proxy/conns v0.0.3 h1:3jbkvPhDwC+ph/NZi7Gywks9WakHK4ept7CkjTiNUJ8= -github.com/sower-proxy/conns v0.0.3/go.mod h1:p3ZM/8MolzW4TN0LaiPJnwnhhif3y9sBi2vQEWHvwhg= -github.com/sower-proxy/deferlog v1.0.7 h1:2gRkdTeSHPhnAj6uwBJ74ufqEmn1spT5o1Y3jGXY9zU= +github.com/sower-proxy/conns v0.0.4 h1:xk+ntJc8h0fTpMEP4cpmPrdcgpzipwvPLOakwUe1NmA= +github.com/sower-proxy/conns v0.0.4/go.mod h1:p3ZM/8MolzW4TN0LaiPJnwnhhif3y9sBi2vQEWHvwhg= +github.com/sower-proxy/conns v0.1.0 h1:Is5xeRjGnwBChUgyMhncjgfttou23O2502S8otxbdaM= +github.com/sower-proxy/conns v0.1.0/go.mod h1:p3ZM/8MolzW4TN0LaiPJnwnhhif3y9sBi2vQEWHvwhg= github.com/sower-proxy/deferlog v1.0.7/go.mod h1:TVXk/Pm7TAs1ZqayZfrxSbwCl+SSm7+p1xcEPkKHWvQ= -github.com/sower-proxy/mem v0.0.3 h1:JK86etQ2QxRUXhs9JhoKYz5p3pFBSrI3UXVhwm44OzM= github.com/sower-proxy/mem v0.0.3/go.mod h1:tM3P+gCAZMVBnOixGVAHS34si9Iwj2HU6M4IVEv4rK0= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= -golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/router/util.go b/router/util.go index 790b76b..2a0c301 100644 --- a/router/util.go +++ b/router/util.go @@ -2,17 +2,23 @@ package router import ( "net" + "net/url" "strconv" ) -func ParseHostPort(hostport string, defaultPort uint16) (string, uint16, error) { +func ParseHostPort(hostport string, u *url.URL) (string, uint16, error) { host, port, err := net.SplitHostPort(hostport) if err != nil { + if err.(*net.AddrError).Err == "missing port in address" { + switch u.Scheme { + case "http": + return hostport, 80, nil + case "https": + return hostport, 443, nil + } + } return "", 0, err } - if port == "" { - return host, defaultPort, nil - } portInt, err := strconv.ParseUint(port, 10, 16) if err != nil { diff --git a/transport/socks5/rfc.go b/transport/socks5/rfc.go index 5925270..7eb642f 100644 --- a/transport/socks5/rfc.go +++ b/transport/socks5/rfc.go @@ -17,7 +17,7 @@ type authReq struct { func (req *authReq) Fulfill(r io.Reader) error { buf := make([]byte, 2) - if n, err := r.Read(buf); err != nil || n != 2 { + if n, err := io.ReadFull(r, buf); err != nil || n != 2 { return err } @@ -25,7 +25,7 @@ func (req *authReq) Fulfill(r io.Reader) error { req.NMETHODS = buf[1] req.METHODS = make([]byte, int(req.NMETHODS)) - if n, err := r.Read(req.METHODS); err != nil || n != len(req.METHODS) { + if n, err := io.ReadFull(r, req.METHODS); err != nil || n != len(req.METHODS) { return err } @@ -70,6 +70,7 @@ type addrType interface { } // ATYP: +// // 0x01 -> net.IPv4len // 0x03 -> first byte is length // 0x04 -> net.IPv6len @@ -81,6 +82,7 @@ type addrTypeIPv4 struct { func (a *addrTypeIPv4) Fulfill(r io.Reader) error { return binary.Read(r, binary.BigEndian, a) } + func (a *addrTypeIPv4) Addr() (string, uint16) { return net.IP(a.DST_ADDR[:]).String(), a.DST_PORT } @@ -108,6 +110,7 @@ func (a *addrTypeDomain) Fulfill(r io.Reader) error { return nil } + func (a *addrTypeDomain) Addr() (string, uint16) { return string(a.DST_ADDR[:]), a.DST_PORT } @@ -120,6 +123,7 @@ type addrTypeIPv6 struct { func (a *addrTypeIPv6) Fulfill(r io.Reader) error { return binary.Read(r, binary.BigEndian, a) } + func (a *addrTypeIPv6) Addr() (string, uint16) { return net.IP(a.DST_ADDR[:]).String(), a.DST_PORT } diff --git a/transport/socks5/socks5.go b/transport/socks5/socks5.go index d736e00..f83ad94 100644 --- a/transport/socks5/socks5.go +++ b/transport/socks5/socks5.go @@ -28,14 +28,16 @@ func New() *Socks5 { return &Socks5{} } -var noAuthResp = authResp{VER: 5, METHOD: 0} -var succHeadResp = respHead{VER: 5, REP: 0, RSV: 0, ATYP: 1} +var ( + noAuthResp = authResp{VER: 5, METHOD: 0} + succHeadResp = respHead{VER: 5, REP: 0, RSV: 0, ATYP: 1} +) func (s *Socks5) Unwrap(conn net.Conn) (net.Addr, error) { - { //auth + { // auth auth := new(authReq) - if err := auth.Fulfill(conn); err != nil && !auth.IsValid() { - return nil, errors.Errorf("read head: %v, err: %s", auth, err) + if err := auth.Fulfill(conn); err != nil || !auth.IsValid() { + return nil, errors.Errorf("read auth head: %v, err: %s", auth, err) } if err := binary.Write(conn, binary.BigEndian, noAuthResp); err != nil { diff --git a/transport/transport_test.go b/transport/transport_test.go index be3d770..4553681 100644 --- a/transport/transport_test.go +++ b/transport/transport_test.go @@ -5,7 +5,7 @@ import ( "strings" "testing" - "github.com/sower-proxy/conns/teeconn" + "github.com/sower-proxy/conns/reread" "github.com/sower-proxy/deferlog/log" "github.com/wweir/sower/transport/sower" "github.com/wweir/sower/transport/trojan" @@ -24,7 +24,7 @@ func testPipe(tran Transport) (net.Addr, error) { tran.Wrap(w, "sower", 443) }(w) - return tran.Unwrap(teeconn.New(r)) + return tran.Unwrap(reread.New(r)) } func Test_Transports(t *testing.T) { diff --git a/transport/trojan/trojan.go b/transport/trojan/trojan.go index d9cb631..b6c4474 100644 --- a/transport/trojan/trojan.go +++ b/transport/trojan/trojan.go @@ -71,15 +71,16 @@ func (*domain) Network() string { return "tcp" } func (a *domain) String() string { return net.JoinHostPort(a.ADDR, strconv.Itoa(int(a.PORT))) } + func (a *domain) Fulfill(r io.Reader) error { buf := make([]byte, 1) - if n, err := r.Read(buf); err != nil || n != 1 { + if n, err := io.ReadFull(r, buf); err != nil || n != 1 { return errors.New("read domain length failed") } addrLen := int(buf[0]) buf = make([]byte, addrLen+4) - if n, err := r.Read(buf); err != nil || n != addrLen+4 { + if n, err := io.ReadFull(r, buf); err != nil || n != addrLen+4 { return errors.Wrap(err, "read doamin failed") } @@ -127,12 +128,12 @@ func (t *Trojan) Unwrap(conn net.Conn) (net.Addr, error) { head.CMD, head.ATYP = buf[58], buf[59] switch head.ATYP { - case 0x01: //ipv4 + case 0x01: // ipv4 addr := &ipv4Addr{} err := binary.Read(conn, binary.BigEndian, addr) return addr, errors.Wrap(err, "read addr") - case 0x04: //ipv6 + case 0x04: // ipv6 addr := &ipv6Addr{} err := binary.Read(conn, binary.BigEndian, addr) return addr, errors.Wrap(err, "read addr")