mirror of
https://github.com/openlibrecommunity/olcrtc.git
synced 2026-05-26 07:08:11 +00:00
fix(vp8channel): client ignores frames from other participants
In single-peer mode (client), frames from unknown epochs are now silently dropped instead of triggering a reconnect loop. This prevents the client from mistaking another client's VP8 track for a server restart. Part of #67
This commit is contained in:
@@ -680,19 +680,11 @@ func (p *streamTransport) handleIncomingFrame(frame []byte) {
|
||||
if !p.hadPeer.Swap(true) {
|
||||
p.handleFirstPeer(peerEpoch)
|
||||
} else if prev := p.peerEpoch.Load(); prev != peerEpoch {
|
||||
// Peer restarted its KCP session. Reset ours so the conv state
|
||||
// machines re-converge. CAS guards against double-reset when
|
||||
// fragmented frames straddle the epoch boundary.
|
||||
if p.peerEpoch.CompareAndSwap(prev, peerEpoch) {
|
||||
p.resetKCP()
|
||||
p.reconnectMu.Lock()
|
||||
fn := p.reconnectFn
|
||||
p.reconnectMu.Unlock()
|
||||
if fn != nil {
|
||||
fn()
|
||||
}
|
||||
}
|
||||
// Drop this packet: it predates our fresh KCP session.
|
||||
// In a multi-participant room, other clients also publish VP8
|
||||
// tracks. Their epochs differ from our latched peer (the server).
|
||||
// Simply ignore frames that don't match our peer — they belong to
|
||||
// other participants we don't communicate with.
|
||||
logger.Debugf("vp8channel: ignoring frame from unknown epoch=0x%08x (latched=0x%08x)", peerEpoch, prev)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -374,8 +374,13 @@ func TestHandleIncomingFrameEpochFilteringAndReconnect(t *testing.T) {
|
||||
t.Fatalf("stream reconnect did not reset/callback: reconnected=%v kcp=%v", reconnected, tr.kcp)
|
||||
}
|
||||
reconnected = false
|
||||
tr.handleIncomingFrame(mkFrame(tr.bindingToken, 2, []byte("after-restart")))
|
||||
if !reconnected || tr.peerEpoch.Load() != 2 || tr.kcp == nil {
|
||||
t.Fatalf("epoch change did not reset/reconnect: reconnected=%v epoch=%d kcp=%v", reconnected, tr.peerEpoch.Load(), tr.kcp) //nolint:lll // long test description
|
||||
// In single-peer mode, frames from a different epoch are ignored (other
|
||||
// participants in the room). The client does NOT reconnect.
|
||||
tr.handleIncomingFrame(mkFrame(tr.bindingToken, 2, []byte("other-participant")))
|
||||
if reconnected {
|
||||
t.Fatal("epoch change from another participant should not trigger reconnect")
|
||||
}
|
||||
if tr.peerEpoch.Load() != 1 {
|
||||
t.Fatalf("peer epoch changed unexpectedly: got %d want 1", tr.peerEpoch.Load())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user