The 17:42 log shows a proxy that works stably from Android failing 166
of 301 new desktop connects: the desktop client kills proxied connect
attempts after kMinConnectedTimeout (1s), reconnects, and bursts new
FakeTLS handshakes 150ms apart from every reconnecting session - the
exact pattern that gets an endpoint throttled.
Three coordinated changes:
- SessionPrivate::armWaitForConnectedTimer() floors the wait at the
connections' own fullConnectTimeout() when a proxy is configured, so
an attempt gets its whole budget (TCP with SYN retransmits + FakeTLS
handshake) before being destroyed. Direct connections keep the short
first wait.
- ResolvingConnection gives the last remaining route a patient 8s
timeout (kOnlyRouteAttemptTimeout) instead of the 4s racing timeout:
with no alternative route to race, killing the only attempt early
gains nothing and costs a handshake. fullConnectTimeout() reflects
the new budget.
- The open scheduler adds failure-driven adaptive spacing per endpoint,
independent of the stealth connection pattern: each connect timeout
doubles the gap between new opens (500ms..6s), each success halves
it back toward zero. EndpointHealth feeds it from reportFailure()/
reportSuccess(), so all sessions collectively approach a throttling
proxy gently instead of stampeding it.