fix: improvements in memory consumption (#100)

* fix: must close the connection after processing

I think it should help to close #80

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

- preallocate config slices
- not used interfaces in consumer
- do not allocate new variables in loops

* feat: close connection after full processing

* feat: correct process sigint signal

* feat: improve build system

* fix: http proxy

* feat: update golangci-lint-action to v3.7.0

* feat: correct process routines

* fix: close http conn correctly

* feat: update golangci-lint-action to v4

* fix: goreleaser used clean now
This commit is contained in:
Evsyukov Denis 2024-02-11 15:45:43 +03:00 committed by GitHub
parent 49f568810c
commit a2d7aecb6f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 205 additions and 140 deletions

View file

@ -11,10 +11,13 @@ import (
"os"
"strconv"
"github.com/armon/go-socks5"
"github.com/sourcegraph/conc"
"github.com/things-go/go-socks5"
"github.com/things-go/go-socks5/bufferpool"
"net/netip"
"golang.zx2c4.com/wireguard/tun/netstack"
"net/netip"
)
// errorLogger is the logger to print error message
@ -47,9 +50,8 @@ type addressPort struct {
func (d VirtualTun) LookupAddr(ctx context.Context, name string) ([]string, error) {
if d.SystemDNS {
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.
@ -121,17 +123,24 @@ func (d VirtualTun) resolveToAddrPort(endpoint *addressPort) (*netip.AddrPort, e
// SpawnRoutine spawns a socks5 server.
func (config *Socks5Config) SpawnRoutine(vt *VirtualTun) {
conf := &socks5.Config{Dial: vt.Tnet.DialContext, Resolver: vt}
var authMethods []socks5.Authenticator
if username := config.Username; username != "" {
validator := CredentialValidator{username: username}
validator.password = config.Password
conf.Credentials = validator
authMethods = append(authMethods, socks5.UserPassAuthenticator{
Credentials: socks5.StaticCredentials{username: config.Password},
})
} else {
authMethods = append(authMethods, socks5.NoAuthAuthenticator{})
}
server, err := socks5.New(conf)
if err != nil {
log.Fatal(err)
options := []socks5.Option{
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 {
log.Fatal(err)
}
@ -161,14 +170,12 @@ func (c CredentialValidator) Valid(username, password string) bool {
return u&p == 1
}
// connForward copy data from `from` to `to`, then close both stream.
// connForward copy data from `from` to `to`
func connForward(from io.ReadWriteCloser, to io.ReadWriteCloser) {
_, err := io.Copy(to, from)
if err != nil {
errorLogger.Printf("Cannot forward traffic: %s\n", err.Error())
}
_ = from.Close()
_ = to.Close()
}
// tcpClientForward starts a new connection via wireguard and forward traffic from `conn`
@ -187,8 +194,20 @@ func tcpClientForward(vt *VirtualTun, raddr *addressPort, conn net.Conn) {
return
}
go connForward(sconn, conn)
go connForward(conn, sconn)
go func() {
wg := conc.NewWaitGroup()
wg.Go(func() {
connForward(sconn, conn)
})
wg.Go(func() {
connForward(conn, sconn)
})
wg.Wait()
_ = sconn.Close()
_ = conn.Close()
sconn = nil
conn = nil
}()
}
// STDIOTcpForward starts a new connection via wireguard and forward traffic from `conn`
@ -213,8 +232,18 @@ func STDIOTcpForward(vt *VirtualTun, raddr *addressPort) {
return
}
go connForward(os.Stdin, sconn)
go connForward(sconn, stdout)
go func() {
wg := conc.NewWaitGroup()
wg.Go(func() {
connForward(os.Stdin, sconn)
})
wg.Go(func() {
connForward(sconn, stdout)
})
wg.Wait()
_ = sconn.Close()
sconn = nil
}()
}
// SpawnRoutine spawns a local TCP server which acts as a proxy to the specified target
@ -264,8 +293,20 @@ func tcpServerForward(vt *VirtualTun, raddr *addressPort, conn net.Conn) {
return
}
go connForward(sconn, conn)
go connForward(conn, sconn)
go func() {
gr := conc.NewWaitGroup()
gr.Go(func() {
connForward(sconn, conn)
})
gr.Go(func() {
connForward(conn, sconn)
})
gr.Wait()
_ = sconn.Close()
_ = conn.Close()
sconn = nil
conn = nil
}()
}
// SpawnRoutine spawns a TCP server on wireguard which acts as a proxy to the specified target