Environment
- TinyTun:
v0.0.3-alpha.2 (8c57833dba9a7614262e90121d3e1fae61fed203)
- v2rayA: 2.4.6
- OS: Arch Linux
- Kernel: Linux 7.1
- Physical interface:
bond0
- TUN interface:
tun0
Configuration
The SOCKS5 server is a local listener created by v2rayA:
tun:
name: tun0
ip: 198.18.0.1
netmask: 255.255.255.255
auto_route: true
socks5:
name: proxy
address: 127.0.0.1:52345
route:
auto_detect_interface: true
TinyTun correctly detects bond0 and installs the two default-route halves:
0.0.0.0/1 dev tun0 proto static
128.0.0.0/1 dev tun0 proto static
Steps to reproduce
- Start a SOCKS5 server on
127.0.0.1:52345.
- Start TinyTun with the configuration above on Linux.
- Send TCP traffic through
tun0.
Expected behavior
TinyTun connects to the local SOCKS5 listener through the loopback device and forwards the captured flow.
Actual behavior
Every captured connection eventually times out:
[Warning] SOCKS5 connect timed out for FlowKey { src: 198.18.0.1:40040, dst: 149.154.175.100:443 }
Proxied DNS fails for the same reason because its SOCKS5 UDP-associate control channel also uses open_tcp_to_proxy:
[Warning] DNS forwarding failed: SOCKS5 handshake timed out for DNS upstream 1.1.1.1:53
The local SOCKS5 listener itself works when contacted directly:
curl --socks5-hostname 127.0.0.1:52345 https://cloudflare.com
# succeeds
However, sockets opened by TinyTun remain in this state:
SYN-SENT 192.168.88.75%bond0:<ephemeral> 127.0.0.1:52345
Root cause
Socks5Client::open_tcp_to_proxy applies SO_BINDTODEVICE whenever an outbound interface was detected. It also applies it when the configured proxy address is loopback.
Binding a socket whose destination is 127.0.0.1 to bond0 prevents the SYN from reaching the loopback listener. This causes both TCP forwarding and proxied DNS to hang even though the SOCKS5 server is healthy.
SO_BINDTODEVICE is still needed for a remote SOCKS5 server to prevent routing loops, but it should be skipped when config.address.ip().is_loopback() is true. The same applies to IPv6 loopback (::1).
I have a patch with IPv4/IPv6 loopback regression tests and will link the pull request here.
Environment
v0.0.3-alpha.2(8c57833dba9a7614262e90121d3e1fae61fed203)bond0tun0Configuration
The SOCKS5 server is a local listener created by v2rayA:
TinyTun correctly detects
bond0and installs the two default-route halves:Steps to reproduce
127.0.0.1:52345.tun0.Expected behavior
TinyTun connects to the local SOCKS5 listener through the loopback device and forwards the captured flow.
Actual behavior
Every captured connection eventually times out:
Proxied DNS fails for the same reason because its SOCKS5 UDP-associate control channel also uses
open_tcp_to_proxy:The local SOCKS5 listener itself works when contacted directly:
However, sockets opened by TinyTun remain in this state:
Root cause
Socks5Client::open_tcp_to_proxyappliesSO_BINDTODEVICEwhenever an outbound interface was detected. It also applies it when the configured proxy address is loopback.Binding a socket whose destination is
127.0.0.1tobond0prevents the SYN from reaching the loopback listener. This causes both TCP forwarding and proxied DNS to hang even though the SOCKS5 server is healthy.SO_BINDTODEVICEis still needed for a remote SOCKS5 server to prevent routing loops, but it should be skipped whenconfig.address.ip().is_loopback()is true. The same applies to IPv6 loopback (::1).I have a patch with IPv4/IPv6 loopback regression tests and will link the pull request here.