Skip to content

ares-novacom: two fixes to --forward — throughput and a forward that cannot tell a dead tunnel from an idle one - #18

Merged
mariotaku merged 2 commits into
mainfrom
fix/novacom-forward-liveness
Aug 27, 2026
Merged

ares-novacom: two fixes to --forward — throughput and a forward that cannot tell a dead tunnel from an idle one#18
mariotaku merged 2 commits into
mainfrom
fix/novacom-forward-liveness

Conversation

@mariotaku

Copy link
Copy Markdown
Member

Two independent fixes to --forward as it ships today. Split out of #17, which builds on them.

1. Throughput

The pump waited 50 ms on the device after every buffer it sent, whether or not the device had anything to say. On a busy connection that's 50 ms per 16 KB, which caps a forward at a few hundred KB/s — 5 MB through a forward took 32 s.

It now polls for 1 ms while bytes are still moving and falls back to 50 ms once both sides go quiet, so an idle connection still doesn't spin. The same 5 MB takes 1.9 s (~2.6 MB/s), measured against a UP7560.

2. A forward that can't tell a dead tunnel from an idle one

A forward found running on a workstation had spent two hours pointed at a TV that had stopped listening:

  • host: ESTAB 192.168.89.16:46389 → 192.168.89.31:22, owned by ares-novacom
  • TV: no such connection, and the forwarded port not open

Nothing looked wrong from the forward's side, so it went on waiting for connections that could no longer arrive — and the person relying on it had no way to tell.

That's the shape of a device dropping off Wi-Fi rather than closing the session: no FIN, no RST, nothing for libssh to report. The connection reads as live because as far as TCP is concerned it is.

TCP keepalive makes the silence into an error — probe after 30 s idle, every 10 s, three times — so the socket fails instead of lying. Verified with ss -tno that the timer is armed on the session socket (timer:(keepalive,27sec,0)).

socket2 is added as a direct dependency; it was already in the lockfile transitively. The Windows path for the fd handling and probe count is written and cfg-gated, but only the Linux build was exercised here — worth a CI check.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Gde2tcn5SbUHKhesuTNB7a

Mariotaku and others added 2 commits August 27, 2026 13:49
The pump waited 50ms on the device after every buffer it sent, whether or
not the device had anything to say. On a busy connection that is 50ms per
16KB, which caps a forward at a few hundred KB/s: 5MB through a forward
took 32s.

Poll for 1ms while bytes are still moving and fall back to 50ms once both
sides go quiet, so an idle connection still does not spin. The same 5MB
now takes 1.9s, about 2.6 MB/s, measured against a UP7560.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gde2tcn5SbUHKhesuTNB7a
A forward found running on a workstation had spent two hours pointed at a
TV that had stopped listening: the host still called the socket
ESTABLISHED, the TV had no such connection, and the forwarded port was not
open on the device. Nothing looked wrong from the forward's side, so it
went on waiting for connections that could no longer arrive, and the
person relying on it had no way to tell.

That is the shape of a device dropping off Wi-Fi rather than closing the
session: no FIN, no RST, nothing for libssh to report. The connection
reads as live because as far as TCP is concerned it is.

Keep it alive so the silence becomes an error - probe after 30s idle,
every 10s, three times - and the socket fails instead of lying.

Verified with `ss -tno` that the timer is armed on the session socket.
Windows counts its own probe retries, so the retry count is set only where
there is a knob for it; that path is written but not built here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gde2tcn5SbUHKhesuTNB7a
@mariotaku
mariotaku merged commit 8407047 into main Aug 27, 2026
4 checks passed
@mariotaku
mariotaku deleted the fix/novacom-forward-liveness branch August 27, 2026 23:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant