SS2022 inbound: Don't end a UDP session when its first source address expires

The relay session context was derived from the inbound connection of the
source address that created the session. After a client changes its source
address (NAT rebinding), the UDP worker of the old address is cleaned up after
~2 minutes of inactivity and cancels that context, which tears down the
dispatched outbound flow; the next packet then creates a brand-new session and
outbound flow (new local port on the server, reset replay window).

Sessions are routed by client session ID (SIP022 3.2.4), so detach the session
context from the originating connection's cancellation and let the session's
own inactivity timer govern its lifetime.
This commit is contained in:
Roman Rublev
2026-10-18 16:28:31 +03:00
parent 8d0a7cf856
commit 83147cf3a7
2 changed files with 99 additions and 1 deletions
+4 -1
View File
@@ -63,7 +63,10 @@ func (s *ServerUDPSession) EnsureLink(
s.currentConn.Store(conn)
sessCtx, cancel := context.WithCancel(ctx)
// The session is routed by client session ID and may outlive the inbound
// connection of the source address it started from (SIP022 §3.2.4), so its
// lifetime is governed by its own timer rather than by that connection.
sessCtx, cancel := context.WithCancel(context.WithoutCancel(ctx))
inbound := session.InboundFromContext(sessCtx)
if inbound != nil && s.User != nil {
inbound.User = s.User