feat: migration to github.com/things-go/go-socks5

- preallocate config slices
- not used interfaces in consumer
- do not allocate new variables in loops
This commit is contained in:
Evsyukov Denis 2024-02-08 15:16:52 +03:00
parent bc9c2c8473
commit 229ad7a95d
No known key found for this signature in database
6 changed files with 74 additions and 71 deletions

View file

@ -8,7 +8,7 @@ import (
"syscall" "syscall"
"github.com/akamensky/argparse" "github.com/akamensky/argparse"
"github.com/octeep/wireproxy" "github.com/pufferffish/wireproxy"
"golang.zx2c4.com/wireguard/device" "golang.zx2c4.com/wireguard/device"
"suah.dev/protect" "suah.dev/protect"
) )

View file

@ -125,8 +125,9 @@ func parseNetIP(section *ini.Section, keyName string) ([]netip.Addr, error) {
return []netip.Addr{}, nil return []netip.Addr{}, nil
} }
var ips []netip.Addr keys := key.StringsWithShadows(",")
for _, str := range key.StringsWithShadows(",") { var ips = make([]netip.Addr, 0, len(keys))
for _, str := range keys {
str = strings.TrimSpace(str) str = strings.TrimSpace(str)
ip, err := netip.ParseAddr(str) ip, err := netip.ParseAddr(str)
if err != nil { if err != nil {
@ -143,8 +144,9 @@ func parseCIDRNetIP(section *ini.Section, keyName string) ([]netip.Addr, error)
return []netip.Addr{}, nil return []netip.Addr{}, nil
} }
var ips []netip.Addr keys := key.StringsWithShadows(",")
for _, str := range key.StringsWithShadows(",") { var ips = make([]netip.Addr, 0, len(keys))
for _, str := range keys {
prefix, err := netip.ParsePrefix(str) prefix, err := netip.ParsePrefix(str)
if err != nil { if err != nil {
return nil, err return nil, err
@ -162,8 +164,9 @@ func parseAllowedIPs(section *ini.Section) ([]netip.Prefix, error) {
return []netip.Prefix{}, nil return []netip.Prefix{}, nil
} }
var ips []netip.Prefix keys := key.StringsWithShadows(",")
for _, str := range key.StringsWithShadows(",") { var ips = make([]netip.Prefix, 0, len(keys))
for _, str := range keys {
prefix, err := netip.ParsePrefix(str) prefix, err := netip.ParsePrefix(str)
if err != nil { if err != nil {
return nil, err return nil, err
@ -237,7 +240,7 @@ func ParseInterface(cfg *ini.File, device *DeviceConfig) error {
return nil return nil
} }
// ParsePeer parses the [Peer] section and extract the information into `peers` // ParsePeers parses the [Peer] section and extract the information into `peers`
func ParsePeers(cfg *ini.File, peers *[]PeerConfig) error { func ParsePeers(cfg *ini.File, peers *[]PeerConfig) error {
sections, err := cfg.SectionsByName("Peer") sections, err := cfg.SectionsByName("Peer")
if len(sections) < 1 || err != nil { if len(sections) < 1 || err != nil {

23
go.mod
View file

@ -1,23 +1,24 @@
module github.com/octeep/wireproxy module github.com/pufferffish/wireproxy
go 1.18 go 1.21.1
toolchain go1.21.6
require ( require (
github.com/MakeNowJust/heredoc/v2 v2.0.1 github.com/MakeNowJust/heredoc/v2 v2.0.1
github.com/akamensky/argparse v1.3.1 github.com/akamensky/argparse v1.4.0
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
github.com/go-ini/ini v1.67.0 github.com/go-ini/ini v1.67.0
golang.zx2c4.com/wireguard v0.0.0-20231010133717-42ec952eadc2 github.com/things-go/go-socks5 v0.0.5
suah.dev/protect v1.2.0 golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173
suah.dev/protect v1.2.3
) )
require ( require (
github.com/google/btree v1.1.2 // indirect github.com/google/btree v1.1.2 // indirect
github.com/stretchr/testify v1.8.0 // indirect golang.org/x/crypto v0.19.0 // indirect
golang.org/x/crypto v0.17.0 // indirect golang.org/x/net v0.21.0 // indirect
golang.org/x/net v0.17.0 // indirect golang.org/x/sys v0.17.0 // indirect
golang.org/x/sys v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259 // indirect gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259 // indirect
) )

44
go.sum
View file

@ -1,10 +1,7 @@
github.com/MakeNowJust/heredoc/v2 v2.0.1 h1:rlCHh70XXXv7toz95ajQWOWQnN4WNLt0TdpZYIR/J6A= github.com/MakeNowJust/heredoc/v2 v2.0.1 h1:rlCHh70XXXv7toz95ajQWOWQnN4WNLt0TdpZYIR/J6A=
github.com/MakeNowJust/heredoc/v2 v2.0.1/go.mod h1:6/2Abh5s+hc3g9nbWLe9ObDIOhaRrqsyY9MWy+4JdRM= github.com/MakeNowJust/heredoc/v2 v2.0.1/go.mod h1:6/2Abh5s+hc3g9nbWLe9ObDIOhaRrqsyY9MWy+4JdRM=
github.com/akamensky/argparse v1.3.1 h1:kP6+OyvR0fuBH6UhbE6yh/nskrDEIQgEA1SUXDPjx4g= github.com/akamensky/argparse v1.4.0 h1:YGzvsTqCvbEZhL8zZu2AiA5nq805NZh75JNj4ajn1xc=
github.com/akamensky/argparse v1.3.1/go.mod h1:S5kwC7IuDcEr5VeXtGPRVZ5o/FdhcMlQz4IZQuw64xA= github.com/akamensky/argparse v1.4.0/go.mod h1:S5kwC7IuDcEr5VeXtGPRVZ5o/FdhcMlQz4IZQuw64xA=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 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/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
@ -13,29 +10,26 @@ github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/things-go/go-socks5 v0.0.5 h1:qvKaGcBkfDrUL33SchHN93srAmYGzb4CxSM2DPYufe8=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/things-go/go-socks5 v0.0.5/go.mod h1:mtzInf8v5xmsBpHZVbIw2YQYhc4K0jRwzfsH64Uh0IQ=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
golang.zx2c4.com/wireguard v0.0.0-20231010133717-42ec952eadc2 h1:I9wdPjBlr0efFqY7IHryfOXBdTxA4j8F0ynd227sYVU= golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4=
golang.zx2c4.com/wireguard v0.0.0-20231010133717-42ec952eadc2/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA= golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259 h1:TbRPT0HtzFP3Cno1zZo7yPzEEnfu8EjLfl6IU9VfqkQ= gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259 h1:TbRPT0HtzFP3Cno1zZo7yPzEEnfu8EjLfl6IU9VfqkQ=
gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259/go.mod h1:AVgIgHMwK63XvmAzWG9vLQ41YnVHN0du0tEC46fI7yY= gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259/go.mod h1:AVgIgHMwK63XvmAzWG9vLQ41YnVHN0du0tEC46fI7yY=
suah.dev/protect v1.2.0 h1:4G4V43yVYXCjLFzaE9QJR0fLo3rf5vNBS9YxyoI19DU= suah.dev/protect v1.2.3 h1:aHeoNwZ9YPp64hrYaN0g0djNE1eRujgH63CrfRrUKdc=
suah.dev/protect v1.2.0/go.mod h1:Ocn1yqUskqe/is6N2bxQxtT+fegbvQsOFyHbJAQu9XE= suah.dev/protect v1.2.3/go.mod h1:n1R3XIbsnryKX7C1PO88i5Wgo0v8OTXm9K9FIKt4rfs=

21
http.go
View file

@ -62,7 +62,7 @@ func (s *HTTPServer) handleConn(req *http.Request, conn net.Conn) (peer net.Conn
_, err = conn.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n")) _, err = conn.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n"))
if err != nil { if err != nil {
peer.Close() _ = peer.Close()
peer = nil peer = nil
} }
@ -83,7 +83,7 @@ func (s *HTTPServer) handle(req *http.Request) (peer net.Conn, err error) {
err = req.Write(peer) err = req.Write(peer)
if err != nil { if err != nil {
peer.Close() _ = peer.Close()
peer = nil peer = nil
return peer, fmt.Errorf("conn write failed: %w", err) return peer, fmt.Errorf("conn write failed: %w", err)
} }
@ -92,10 +92,8 @@ func (s *HTTPServer) handle(req *http.Request) (peer net.Conn, err error) {
} }
func (s *HTTPServer) serve(conn net.Conn) error { func (s *HTTPServer) serve(conn net.Conn) error {
defer conn.Close() var rd = bufio.NewReader(conn)
req, err := http.ReadRequest(rd)
var rd io.Reader = bufio.NewReader(conn)
req, err := http.ReadRequest(rd.(*bufio.Reader))
if err != nil { if err != nil {
return fmt.Errorf("read request failed: %w", err) return fmt.Errorf("read request failed: %w", err)
} }
@ -124,11 +122,6 @@ func (s *HTTPServer) serve(conn net.Conn) error {
} }
defer peer.Close() defer peer.Close()
go func() {
defer peer.Close()
defer conn.Close()
_, _ = io.Copy(conn, peer)
}()
_, err = io.Copy(peer, conn) _, err = io.Copy(peer, conn)
return err return err
@ -136,13 +129,14 @@ func (s *HTTPServer) serve(conn net.Conn) error {
// ListenAndServe is used to create a listener and serve on it // ListenAndServe is used to create a listener and serve on it
func (s *HTTPServer) ListenAndServe(network, addr string) error { func (s *HTTPServer) ListenAndServe(network, addr string) error {
server, err := net.Listen("tcp", s.config.BindAddress) server, err := net.Listen(network, addr)
if err != nil { if err != nil {
return fmt.Errorf("listen tcp failed: %w", err) return fmt.Errorf("listen tcp failed: %w", err)
} }
defer server.Close() defer server.Close()
var conn net.Conn
for { for {
conn, err := server.Accept() conn, err = server.Accept()
if err != nil { if err != nil {
return fmt.Errorf("accept request failed: %w", err) return fmt.Errorf("accept request failed: %w", err)
} }
@ -152,6 +146,7 @@ func (s *HTTPServer) ListenAndServe(network, addr string) error {
log.Println(err) log.Println(err)
} }
_ = conn.Close() _ = conn.Close()
conn = nil
}(conn) }(conn)
} }
} }

View file

@ -11,10 +11,12 @@ import (
"os" "os"
"strconv" "strconv"
"github.com/armon/go-socks5" "github.com/things-go/go-socks5"
"github.com/things-go/go-socks5/bufferpool"
"net/netip"
"golang.zx2c4.com/wireguard/tun/netstack" "golang.zx2c4.com/wireguard/tun/netstack"
"net/netip"
) )
// errorLogger is the logger to print error message // errorLogger is the logger to print error message
@ -47,9 +49,8 @@ type addressPort struct {
func (d VirtualTun) LookupAddr(ctx context.Context, name string) ([]string, error) { func (d VirtualTun) LookupAddr(ctx context.Context, name string) ([]string, error) {
if d.SystemDNS { if d.SystemDNS {
return net.DefaultResolver.LookupHost(ctx, name) return net.DefaultResolver.LookupHost(ctx, name)
} else {
return d.Tnet.LookupContextHost(ctx, name)
} }
return d.Tnet.LookupContextHost(ctx, name)
} }
// ResolveAddrWithContext resolves a hostname and returns an AddrPort. // ResolveAddrWithContext resolves a hostname and returns an AddrPort.
@ -121,17 +122,24 @@ func (d VirtualTun) resolveToAddrPort(endpoint *addressPort) (*netip.AddrPort, e
// SpawnRoutine spawns a socks5 server. // SpawnRoutine spawns a socks5 server.
func (config *Socks5Config) SpawnRoutine(vt *VirtualTun) { func (config *Socks5Config) SpawnRoutine(vt *VirtualTun) {
conf := &socks5.Config{Dial: vt.Tnet.DialContext, Resolver: vt} var authMethods []socks5.Authenticator
if username := config.Username; username != "" { if username := config.Username; username != "" {
validator := CredentialValidator{username: username} authMethods = append(authMethods, socks5.UserPassAuthenticator{
validator.password = config.Password Credentials: socks5.StaticCredentials{username: config.Password},
conf.Credentials = validator })
} else {
authMethods = append(authMethods, socks5.NoAuthAuthenticator{})
} }
server, err := socks5.New(conf)
if err != nil { options := []socks5.Option{
log.Fatal(err) socks5.WithDial(vt.Tnet.DialContext),
socks5.WithResolver(vt),
socks5.WithAuthMethods(authMethods),
socks5.WithBufferPool(bufferpool.NewPool(256 * 1024)),
} }
server := socks5.NewServer(options...)
if err := server.ListenAndServe("tcp", config.BindAddress); err != nil { if err := server.ListenAndServe("tcp", config.BindAddress); err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -229,8 +237,9 @@ func (conf *TCPClientTunnelConfig) SpawnRoutine(vt *VirtualTun) {
log.Fatal(err) log.Fatal(err)
} }
var conn net.Conn
for { for {
conn, err := server.Accept() conn, err = server.Accept()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -281,8 +290,9 @@ func (conf *TCPServerTunnelConfig) SpawnRoutine(vt *VirtualTun) {
log.Fatal(err) log.Fatal(err)
} }
var conn net.Conn
for { for {
conn, err := server.Accept() conn, err = server.Accept()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }