Repository navigation
Open several SSH connections to the tunnel server (--ssh-connections, default 4) - #72
Merged
Merged
Conversation
After a network change port 2010 came back ~18 s later. Nearly all of that was detection: JSch's ServerAliveInterval at 5 s x 3 is ~15 s of silence before the session is dropped. Then the connection check (every 2 s) and the first reconnect (after 1 s); the reconnect itself takes ~0.6 s. - ServerAliveInterval 2 s x 3: a session that hears nothing from the server for ~6 s is dead. The server answers keepalives at once, so a healthy connection, busy or idle, is never that quiet. - Connection check every 500 ms. First reconnect after 250 ms. - Retries 2 s apart while the network is still down, so the first attempt that can get through does not wait long once it is back. 75 retries keep the ~150 s before the tunnel is rebuilt. Measured against a real tunnel VM: - NAT change (old flow blackholed on both ends): 2010 back after 8 s, was ~18-24 s. - 4 s outage: no reconnect. - 20 s outage: 23.6 s, was 25.1 s. - Full proxy suite and perf suite (downloads, uploads, a 300-request burst): no reconnects.
Every browser connection shared one SSH connection, one TCP flow: on a lossy link the whole tunnel got that flow's share (0.6 MB/s at 0.5% loss and 50 ms, where 4 flows got 2.4 MB/s), and one lost packet stalled every request. --ssh-connections N (1-8, default 4). The first connection keeps the hub forward, readiness and the self-test; the others carry browser traffic and reconnect on their own. While another connection forwards, a dropped one neither stops the local proxy nor flips readiness. Each connection's reverse forward goes to its own port in 2020-2035. The tunnel server's tunnel-mux checks them with the probe ForwardProbeHandler answers and then serves 2010 over them. On a server without it 2010 is not served within 3 s of the proxy starting: the client drops the 2020 forward and binds 2010 itself, on one connection, as before.
jochen-testingbot
changed the base branch from
fix/faster-dead-session-detection
to
main
October 25, 2026 15:00
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #71 (it builds on its reconnect timings); GitHub retargets it to
mainwhen #71 merges.Why
Every browser connection through the tunnel shares one SSH connection, i.e. one TCP flow. On a lossy link that caps the whole tunnel at one flow's loss-limited rate, and one lost packet stalls every request until it is resent. Measured in the tunnel-harness perf lab (50 ms, 200 Mbit/s, 0.5% loss, client on CUBIC):
A small request during a download took 1.2–1.7 s instead of 91 ms.
What
--ssh-connections N(1–8, default 4). The first connection works as before and keeps the hub forward (-L, a local port only one connection can hold), readiness and the self-test. The others only carry browser traffic and reconnect on their own; a dropped one never stops the local proxy or flips readiness while another connection still forwards.Each connection's reverse forward goes to its own port in 2020–2035 instead of 2010. On tunnel servers that have it,
tunnel-mux(testingbot/ansible, tunnel02) sees those forwards, checks each with the probe requestForwardProbeHandleralready answers, and only then serves 2010 itself and spreads connections over the healthy forwards. Squid's parent, no-cache tunnels and the device lab keep using 2010 unchanged.Compatibility
--ssh-connections 1never touches 2020–2035.--noproxykeeps one connection, because nothing on this side answers the probe.Tests
SSHTunnelMultiConnectionTest: against an in-JVM SSH server, with a stand-in for tunnel-mux. Covers:--ssh-connections 1never binding 2020–2035;Removing the extra-connection start, or the fallback, fails 4 of the tests.
theForwardsStayPutAcrossForwardingCheckscovers a bug the lab found: each extra connection's monitor looked for the hub forward, called it lost every 5 s and re-registered its reverse forward, often on a new port. The test fails without the fix (2 re-registrations per connection).SshConnectionsOptionTest: covers the option's range.The existing embedded-server tests pin
--ssh-connections 1, which is what they assert. Without the pin they passed too, but each waited out the fallback (17 s → 58 s).Full suite: 1051 tests, 0 failures.
End to end in tunnel-harness (testingbot/ansible,
suite-mux.sh) against real tunnel images:tunnel02-20261025g): 56/56.--ssh-connections 1leave tunnel-mux idle, with sshd holding 2010 on one session.Perf lab (50 ms, 200 Mbit/s, 0.5% loss, client on CUBIC),
--ssh-connections 1against 4:A single download still travels on one connection; what changes is that it no longer holds up everything else.