diff --git a/proxy/shadowsocks_2022/packet.go b/proxy/shadowsocks_2022/packet.go index 76f713f30..ebe6d1338 100644 --- a/proxy/shadowsocks_2022/packet.go +++ b/proxy/shadowsocks_2022/packet.go @@ -397,16 +397,10 @@ type serverSessionState struct { } func (st *serverSessionState) check(packetID uint64) bool { - if st.window == nil { - st.window = new(SlidingWindow) - } return st.window.Check(packetID) } func (st *serverSessionState) add(packetID uint64) { - if st.window == nil { - st.window = new(SlidingWindow) - } st.window.Add(packetID) } @@ -479,6 +473,7 @@ func (s *ClientUDPSession) getServerSession(sessionID uint64, now int64) (*serve newState := &serverSessionState{ sessionID: sessionID, + window: new(SlidingWindow), cipher: bodyAead, } newState.lastSeen.Store(now) diff --git a/proxy/shadowsocks_2022/replay.go b/proxy/shadowsocks_2022/replay.go index 45ffb227a..13beb86e4 100644 --- a/proxy/shadowsocks_2022/replay.go +++ b/proxy/shadowsocks_2022/replay.go @@ -100,21 +100,12 @@ type ServerUDPSession struct { func (s *ServerUDPSession) CheckPacketID(packetID uint64) bool { s.Lock() defer s.Unlock() - if s.Window == nil { - s.Window = new(SlidingWindow) - } return s.Window.Check(packetID) } -// CommitPacketID records a packet ID after the packet has been fully validated. -// It re-checks the window under the lock, so when the same packet is validated -// concurrently (e.g. by the workers of two client source addresses), only one is accepted. func (s *ServerUDPSession) CommitPacketID(packetID uint64) bool { s.Lock() defer s.Unlock() - if s.Window == nil { - s.Window = new(SlidingWindow) - } return s.Window.CheckAndAdd(packetID) } @@ -127,9 +118,6 @@ func (s *ServerUDPSession) getClientBodyCipher() cipher.AEAD { func (s *ServerUDPSession) commitClientPacket(packetID uint64, bodyAead cipher.AEAD) bool { s.Lock() defer s.Unlock() - if s.Window == nil { - s.Window = new(SlidingWindow) - } if !s.Window.CheckAndAdd(packetID) { return false } @@ -161,6 +149,7 @@ func (m *UDPSessionManager) GetOrCreate(sessionID uint64) *ServerUDPSession { s := &ServerUDPSession{ SessionID: sessionID, + Window: new(SlidingWindow), manager: m, } s.LastActive.Store(now) diff --git a/proxy/shadowsocks_2022/shadowsocks_2022.go b/proxy/shadowsocks_2022/shadowsocks_2022.go index 25c894f9d..28d8b88c1 100644 --- a/proxy/shadowsocks_2022/shadowsocks_2022.go +++ b/proxy/shadowsocks_2022/shadowsocks_2022.go @@ -63,9 +63,8 @@ func (s *ServerUDPSession) EnsureLink( s.currentConn.Store(conn) - // 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. + // UDP Session might travel across multiple connections + // don't bind its lifetime to a parent context sessCtx, cancel := context.WithCancel(context.WithoutCancel(ctx)) inbound := session.InboundFromContext(sessCtx) if inbound != nil && s.User != nil {