Skip to content

Commit e971299

Browse files
committed
socks5: improve throughput performance in stream copying
1 parent 1682809 commit e971299

5 files changed

Lines changed: 33 additions & 54 deletions

File tree

cmd/awl-tray/go.mod

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ module awl-tray
22

33
go 1.25.0
44

5+
replace (
6+
github.com/anywherelan/awl => ../../
7+
github.com/haxii/socks5 => github.com/anywherelan/socks5 v0.0.0-20260110104142-f70546922210
8+
github.com/ipfs/go-log/v2 => github.com/anywherelan/go-log/v2 v2.0.3-0.20221101180049-46e3967f6fe5
9+
github.com/ncruces/zenity => github.com/pymq/zenity v0.0.0-20230509161854-c117c448544d
10+
)
11+
512
require (
613
fyne.io/systray v1.11.1-0.20250812065214-4856ac3adc3c
714
github.com/GrigoryKrasnochub/updaterini v0.1.0
@@ -15,12 +22,6 @@ require (
1522
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
1623
)
1724

18-
replace (
19-
github.com/anywherelan/awl => ../../
20-
github.com/ipfs/go-log/v2 => github.com/anywherelan/go-log/v2 v2.0.3-0.20221101180049-46e3967f6fe5
21-
github.com/ncruces/zenity => github.com/pymq/zenity v0.0.0-20230509161854-c117c448544d
22-
)
23-
2425
require (
2526
git.sr.ht/~jackmordaunt/go-toast v1.1.2 // indirect
2627
github.com/akavel/rsrc v0.10.2 // indirect

cmd/awl-tray/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ github.com/akavel/rsrc v0.10.2 h1:Zxm8V5eI1hW4gGaYsJQUhxpjkENuG91ki8B4zCrvEsw=
1111
github.com/akavel/rsrc v0.10.2/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
1212
github.com/anywherelan/go-log/v2 v2.0.3-0.20221101180049-46e3967f6fe5 h1:uQsw+HnQo6Ru5eFgUdEQYKMwkiYkoNZDQmY2ob1E58Y=
1313
github.com/anywherelan/go-log/v2 v2.0.3-0.20221101180049-46e3967f6fe5/go.mod h1:r8UEDyeHO6bYVcP9R2/HnK2ZSZ5CJp89gubcHLKfRv0=
14+
github.com/anywherelan/socks5 v0.0.0-20260110104142-f70546922210 h1:osLzU7/Y0tdqV6TwuP9bcObHdPzi5eQ6VZahxyIYrZM=
15+
github.com/anywherelan/socks5 v0.0.0-20260110104142-f70546922210/go.mod h1:KpbKhNH2RqojJGPVT9faDXnYWkqzfgpKeehC8xTKaeY=
1416
github.com/anywherelan/ts-dns v0.0.0-20240721135326-6d6b7b811853 h1:RVKWGnppAfxgD2wphkq+OYDOqqI8zgbymBLl2pxYKzY=
1517
github.com/anywherelan/ts-dns v0.0.0-20240721135326-6d6b7b811853/go.mod h1:ly7HpPle1G3D0jwrr12uolTGWKN3DPgxzBYNR086BLo=
1618
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
@@ -88,8 +90,6 @@ github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aN
8890
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
8991
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
9092
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
91-
github.com/haxii/socks5 v1.0.0 h1:78BIzd4lHibdRNOKdMwKCnnsgYLW9SeotqU+nMhWSSo=
92-
github.com/haxii/socks5 v1.0.0/go.mod h1:6O9Ba2yrLlvuSe/L1e84eZI8cPw6H+q1Ilr4hjgm4uY=
9393
github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=
9494
github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
9595
github.com/illarion/gonotify v1.0.1 h1:F1d+0Fgbq/sDWjj/r66ekjDG+IDeecQKUFH4wNwsoio=

go.mod

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ module github.com/anywherelan/awl
22

33
go 1.25.0
44

5+
replace (
6+
github.com/haxii/socks5 => github.com/anywherelan/socks5 v0.0.0-20260110104142-f70546922210
7+
github.com/ipfs/go-log/v2 => github.com/anywherelan/go-log/v2 v2.0.3-0.20221101180049-46e3967f6fe5
8+
)
9+
510
require (
611
github.com/GrigoryKrasnochub/updaterini v0.1.0
712
github.com/anywherelan/ts-dns v0.0.0-20240721135326-6d6b7b811853
@@ -11,7 +16,6 @@ require (
1116
github.com/ipfs/go-datastore v0.9.0
1217
github.com/ipfs/go-log/v2 v2.9.0
1318
github.com/labstack/echo/v4 v4.14.0
14-
github.com/libp2p/go-buffer-pool v0.1.0
1519
github.com/libp2p/go-libp2p v0.46.0
1620
github.com/libp2p/go-libp2p-kad-dht v0.36.0
1721
github.com/libp2p/go-libp2p-kbucket v0.8.0
@@ -35,8 +39,6 @@ require (
3539
golang.zx2c4.com/wireguard/windows v0.5.3
3640
)
3741

38-
replace github.com/ipfs/go-log/v2 => github.com/anywherelan/go-log/v2 v2.0.3-0.20221101180049-46e3967f6fe5
39-
4042
require (
4143
github.com/benbjohnson/clock v1.3.5 // indirect
4244
github.com/beorn7/perks v1.0.1 // indirect
@@ -72,6 +74,7 @@ require (
7274
github.com/koron/go-ssdp v0.0.6 // indirect
7375
github.com/labstack/gommon v0.4.2 // indirect
7476
github.com/leodido/go-urn v1.4.0 // indirect
77+
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
7578
github.com/libp2p/go-cidranger v1.1.0 // indirect
7679
github.com/libp2p/go-flow-metrics v0.3.0 // indirect
7780
github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ github.com/GrigoryKrasnochub/updaterini v0.1.0 h1:csl3bqQIShuI8RnXzKprTgEhqi3I59
33
github.com/GrigoryKrasnochub/updaterini v0.1.0/go.mod h1:w+8blQZCZzGmJGXqmXbeSOsUOF6LqyeqckxSiZah7RI=
44
github.com/anywherelan/go-log/v2 v2.0.3-0.20221101180049-46e3967f6fe5 h1:uQsw+HnQo6Ru5eFgUdEQYKMwkiYkoNZDQmY2ob1E58Y=
55
github.com/anywherelan/go-log/v2 v2.0.3-0.20221101180049-46e3967f6fe5/go.mod h1:r8UEDyeHO6bYVcP9R2/HnK2ZSZ5CJp89gubcHLKfRv0=
6+
github.com/anywherelan/socks5 v0.0.0-20260110104142-f70546922210 h1:osLzU7/Y0tdqV6TwuP9bcObHdPzi5eQ6VZahxyIYrZM=
7+
github.com/anywherelan/socks5 v0.0.0-20260110104142-f70546922210/go.mod h1:KpbKhNH2RqojJGPVT9faDXnYWkqzfgpKeehC8xTKaeY=
68
github.com/anywherelan/ts-dns v0.0.0-20240721135326-6d6b7b811853 h1:RVKWGnppAfxgD2wphkq+OYDOqqI8zgbymBLl2pxYKzY=
79
github.com/anywherelan/ts-dns v0.0.0-20240721135326-6d6b7b811853/go.mod h1:ly7HpPle1G3D0jwrr12uolTGWKN3DPgxzBYNR086BLo=
810
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
@@ -71,8 +73,6 @@ github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aN
7173
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
7274
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
7375
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
74-
github.com/haxii/socks5 v1.0.0 h1:78BIzd4lHibdRNOKdMwKCnnsgYLW9SeotqU+nMhWSSo=
75-
github.com/haxii/socks5 v1.0.0/go.mod h1:6O9Ba2yrLlvuSe/L1e84eZI8cPw6H+q1Ilr4hjgm4uY=
7676
github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=
7777
github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
7878
github.com/illarion/gonotify v1.0.1 h1:F1d+0Fgbq/sDWjj/r66ekjDG+IDeecQKUFH4wNwsoio=

service/socks5.go

Lines changed: 16 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@ import (
44
"context"
55
"errors"
66
"fmt"
7-
"io"
87
"net"
98
"slices"
109
"strings"
11-
"sync"
1210
"time"
1311

12+
socks5Proxy "github.com/haxii/socks5"
1413
"github.com/ipfs/go-log/v2"
15-
pool "github.com/libp2p/go-buffer-pool"
1614
"github.com/libp2p/go-libp2p/core/network"
1715

1816
"github.com/anywherelan/awl/config"
@@ -129,7 +127,7 @@ func (s *SOCKS5) ProxyStreamHandler(stream network.Stream) {
129127
// e.g reader on the other side may not read everything we sent because of stream.Reset()
130128
// in case of socks5 errors (small payload), receiver could get EOF
131129
// TODO: make better workaround for this. stream.CloseWrite(), etc doesn't help
132-
time.Sleep(20 * time.Millisecond)
130+
time.Sleep(50 * time.Millisecond)
133131
}
134132

135133
func (s *SOCKS5) ServeConns(ctx context.Context) {
@@ -144,6 +142,8 @@ func (s *SOCKS5) ServeConns(ctx context.Context) {
144142
_ = conn.Close()
145143
}()
146144

145+
s.logger.Debug("got new SOCKS5 proxy client connection")
146+
147147
err := s.proxyConn(ctx, conn)
148148
if err != nil {
149149
_ = s.server.SendServerFailureReply(conn)
@@ -191,50 +191,25 @@ func (s *SOCKS5) proxyConn(ctx context.Context, conn net.Conn) error {
191191

192192
s.handleStream(conn, stream)
193193

194+
// stream.Write() + stream.Reset() are not guaranteed to run sequentially
195+
// e.g reader on the other side may not read everything we sent because of stream.Reset()
196+
// in case of socks5 errors (small payload), receiver could get EOF
197+
// TODO: make better workaround for this. stream.CloseWrite(), etc doesn't help
198+
time.Sleep(50 * time.Millisecond)
199+
194200
return nil
195201
}
196202

197203
func (s *SOCKS5) handleStream(conn net.Conn, stream network.Stream) {
198-
// TODO: SetDeadline on conn for ~5 min just in case?
199-
wg := &sync.WaitGroup{}
200-
wg.Add(2)
204+
doneCh := make(chan struct{})
201205
go func() {
202-
defer wg.Done()
206+
defer close(doneCh)
203207
// Copy from conn to stream
204-
_ = s.copyStream(conn, stream)
205-
}()
206-
207-
go func() {
208-
defer wg.Done()
209-
// Copy from stream to conn
210-
_ = s.copyStream(stream, conn)
211-
}()
212-
213-
wg.Wait()
214-
}
215-
216-
func (s *SOCKS5) copyStream(from io.ReadCloser, to io.WriteCloser) error {
217-
const bufSize = 32 * 1024
218-
buf := pool.Get(bufSize)
219-
220-
defer func() {
221-
pool.Put(buf)
208+
_ = socks5Proxy.ProxyStream(conn, stream)
222209
}()
223-
_, err := io.CopyBuffer(to, from, buf)
224210

225-
type closeWriter interface {
226-
CloseWrite() error
227-
}
228-
if conn, ok := to.(closeWriter); ok {
229-
_ = conn.CloseWrite()
230-
}
231-
232-
type closeReader interface {
233-
CloseRead() error
234-
}
235-
if conn, ok := from.(closeReader); ok {
236-
_ = conn.CloseRead()
237-
}
211+
// Copy from stream to conn
212+
_ = socks5Proxy.ProxyStream(stream, conn)
238213

239-
return err
214+
<-doneCh
240215
}

0 commit comments

Comments
 (0)