Files
lueyoungandClaude Opus 5.5 6911ecd304 fix(mtls,mtcp,mws): let concurrent redials converge on one session
When no live session exists, each request dials a conn of its own and
registers it in Dial, then builds the session on it in Handshake, each
step under sessionMutex. A Dial that finds a registration still waiting
for its handshake takes it for dead (IsClosed reports true while
session is nil) and replaces it, so the earlier request's Handshake no
longer finds its own conn and fails with "unrecognized connection".
Since c210b74 the replacing Dial also closes that conn.

Once requests queue for the lock, another request's Dial can sit
between every Dial and its Handshake, and no session is completed for
as long as requests keep arriving. Seen on a three-hop relay chain
whose last hop is mtls: after the client host woke from sleep, nearly
every request on a chain with ~28 concurrent clients failed this way
for 80 minutes, until the load happened to drop.

Dial now closes the base conn only of a session that was established
and died; a session still waiting for its handshake belongs to the
request that dialed it, whose Handshake either builds the session on
it or closes it. Handshake no longer fails on a mismatch: if the
registered session is live it uses that and closes its own conn,
otherwise it builds the session on its own conn and registers it, and
the other request's Handshake then finds a live session to use.

The tests dial twice before either handshake, in both orders, against
the package's own listener. On master they fail with "unrecognized
connection", and with "use of closed network connection" when only
Handshake is changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 08:50:41 -04:00
..
2022-11-29 09:45:51 +08:00
2022-04-07 23:03:31 +08:00
2025-08-05 20:24:00 +08:00
2024-10-10 22:49:56 +08:00
2024-10-10 22:49:56 +08:00
2023-10-15 23:55:52 +08:00
2023-09-18 23:14:55 +08:00
2024-07-08 22:38:21 +08:00