From 8f23c8a40403719382979eb1311567eed86253e7 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 16 Mar 2025 09:46:33 +0700 Subject: [PATCH] also send PATH_RESPONSEs for reordered packets (#4990) A reordered PATH_CHALLENGE (or one sent on a slower path) should still trigger a PATH_RESPONSE. The RFC only forbids switching the path unless the non-probing packet has the highest packet number received so far. --- connection.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/connection.go b/connection.go index 9c711d449..b266d7a42 100644 --- a/connection.go +++ b/connection.go @@ -1054,7 +1054,7 @@ func (s *connection) handleShortHeaderPacket(p receivedPacket) (wasProcessed boo } var shouldSwitchPath bool - if pn == s.largestRcvdAppData && !addrsEqual(p.remoteAddr, s.RemoteAddr()) { + if !addrsEqual(p.remoteAddr, s.RemoteAddr()) { if s.pathManager == nil { s.pathManager = newPathManager( s.connIDManager.GetConnIDForPath, @@ -1075,9 +1075,11 @@ func (s *connection) handleShortHeaderPacket(p receivedPacket) (wasProcessed boo s.registerPackedShortHeaderPacket(probe, protocol.ECNNon, p.rcvTime) s.sendQueue.SendProbe(buf, p.remoteAddr) } - } - - if shouldSwitchPath { + // We only switch paths in response to the highest-numbered non-probing packet, + // see section 9.3 of RFC 9000. + if !shouldSwitchPath || pn != s.largestRcvdAppData { + return true, nil + } s.pathManager.SwitchToPath(p.remoteAddr) s.sentPacketHandler.MigratedPath(p.rcvTime, protocol.ByteCount(s.config.InitialPacketSize)) maxPacketSize := protocol.ByteCount(protocol.MaxPacketBufferSize)