pufferffish / wireproxy

Wireguard client that exposes itself as a socks5 proxy
ISC License
4.55k stars 272 forks source link

When server closes connection, connection hangs on client (between two wireproxy) #130

Open leahneukirchen opened 4 months ago

leahneukirchen commented 4 months ago

Say you connect two Wireproxy instances:

[Interface]
Address = 10.11.11.2/32
PrivateKey = xxx

[Peer]
PublicKey = yyy
Endpoint = zzz:19999

[TCPServerTunnel]
ListenPort = 9100
Target = 127.0.0.1:9100

and

[Interface]
Address = 10.11.11.1/32
PrivateKey = vvv
ListenPort = 19999

[Peer]
PublicKey = www
AllowedIPs = 10.11.11.2/32

[TCPClientTunnel]
BindAddress = 127.0.0.1:9102
Target = 10.11.11.2:9100

Now, run a trivial TCP server on the one side:

ncat -l 9100 --sh-exec "echo hello"

And connect on the other side:

% ncat 127.0.0.1 9102
hello
<HANGS>

I think this happens because the two pattern of running two io.Copy goroutines doesn't notice a connection is closed in both directions? When I patch the goroutines to close conn and sconn after one io.Copy terminates, my use case works. But I'm not sure that is correct when half-open TCP connections are being used.

This probably doesn't occur when one side is a kernel-based WireGuard stack, as then the OS TCP stack will handle the connection closing... [EDIT: also happens when using WireGuard on FreeBSD directly instead of a TCPClientTunnel there.]