tunnel: add -keepalive-timeout-secs for dead connection detection
Tracks last server receive time (atomic) and runs a watchdog goroutine that closes the connection if no data arrives within the timeout, triggering reconnection. Also fixes Close() to guard Conn.Close() inside sync.Once so concurrent/repeated calls are safe. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1d919aafc5
commit
1a397c363f
5 changed files with 57 additions and 18 deletions
|
|
@ -57,7 +57,7 @@ pkg/tap/
|
|||
## CLI flags
|
||||
|
||||
Required: `-host`, `-user`
|
||||
Optional: `-pass`, `-port` (443), `-hub` (DEFAULT), `-tap` (auto), `-mac`, `-plain-password`, `-insecure`, `-no-dhcp`, `-accept-default-gateway`, `-accept-static-routes`, `-accept-dns`, `-policy-route-table` (0=disabled), `-connmark`, `-reconnect-delay` (5s)
|
||||
Optional: `-pass`, `-port` (443), `-hub` (DEFAULT), `-tap` (auto), `-mac`, `-plain-password`, `-insecure`, `-no-dhcp`, `-accept-default-gateway`, `-accept-static-routes`, `-accept-dns`, `-policy-route-table` (0=disabled), `-connmark`, `-reconnect-delay` (5s), `-keepalive-timeout-secs` (0=disabled)
|
||||
|
||||
## SoftEther protocol pitfalls
|
||||
|
||||
|
|
@ -99,6 +99,9 @@ Before connecting, resolves server hostname and adds `/32` route via current def
|
|||
### CONNMARK for DNAT reply routing
|
||||
`-connmark` (requires `-policy-route-table`) adds iptables CONNMARK rules so DNAT'd connections (port forwards to namespaces/VMs) have replies routed back through the tunnel. Without this, replies from DNAT targets use the default route because their source IP doesn't match the `from <VPN_IP>` policy rule. CONNMARK marks incoming VPN connections and restores the mark on reply packets.
|
||||
|
||||
### Keepalive timeout watchdog
|
||||
`-keepalive-timeout-secs N` enables a receive-side watchdog. The server sends keepalives every ~3s. The watchdog checks at `N/3` intervals whether any data (frames or keepalives) was received within the last N seconds. If not, it closes the connection, triggering the reconnect loop. Without this, a half-open TCP connection can go undetected for minutes (depends on kernel `tcp_retries2`). `Close()` is guarded by `sync.Once` so the watchdog, Bridge error path, and `defer tunnel.Close()` can all call it safely.
|
||||
|
||||
## Performance
|
||||
|
||||
- **RAM**: 4.6 MB RSS idle, flat under 97 Mbit/s load (vs SoftEther C client: ~23 MB across 4 processes)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue