Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
dark/nether-voicebridge#128
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Tracking issue for reporting the #127 SSRC-tombstone race upstream to serenity-rs/songbird (and deciding what to do about our vendor divergence). The operator files this by hand — agent PRs/issues to upstream are out.
What to report
Title suggestion: Receive side goes permanently deaf to a user who leaves and rejoins voice within one SSRC-cleanup interval (DAVE packets silently dropped)
Mechanism (all paths as of upstream
current, present since the DAVE PR #291; our tree reproduces it at v0.5.x-vendored):ws.rs:ClientDisconnect→ssrc_signalling.disconnected_users.insert(user_id)— a lazy tombstone.udp_rx/mod.rs: the periodic cleanup (every 5 s) consumes tombstones:user_ssrc_map.remove(&id)→ removes the returned SSRC fromssrc_user_map.ws.rs:Speaking→user_ssrc_map.insert(user, new_ssrc)(re-keying the same user).If the user leaves and rejoins between two sweeps (a moderator kick + a bot's auto-rejoin, a fast channel hop, a voice-server blip), step 3 lands before step 2 — so the sweep removes the live mapping for the new SSRC. From then on every DAVE-encrypted packet from that SSRC fails the
ssrc_user_maplookup in the decrypt path and is silently dropped (that branch has no logging), permanently: the nextSpeakingfor that user won't re-fire (state didn't change), so the mapping is never restored. The receiving client is deaf to that user until the voice connection is rebuilt. Non-DAVE receive is degraded too (SSRC no longer attributable to a user), but DAVE turns it into total loss.Reproduction: two clients in a DAVE voice channel; kick and rejoin client B within ~5 s of a sweep; observe client A's
VoiceTicknever carries B's audio again (B's new SSRC in neitherspeakingnor mapped). Our live CI hit this at ~60 % per attempt; timing-sensitivity tracks Discord's voice-state propagation latency.Fix (what we vendored — commit
a4a94b4in this repo,vendor/songbird/src/driver/tasks/ws.rs): onSpeaking, (a)disconnected_users.remove(user_id)— a re-speaking user is not disconnected, so a pending tombstone must not reap the fresh mapping; (b) eagerly remove the oldssrc_user_mapreverse entry when the SSRC changed. ~10 lines, no API change. Optionally the old SSRC's decoder state could also be retired eagerly (it currently lingers inVoiceTick.silentuntildecode_state_timeout, which is what exposed our recorder artifact — harmless to songbird itself).Also worth mentioning upstream: the three silent-drop branches in the DAVE receive path (
unmapped SSRC,!is_ready(),NoDecryptorForUser) made this bug invisible; we addeddebug!lines to each (same commit) and would suggest upstream do likewise.Also pending upstream (same vendor tree)
Checklist
docs/+ #36 history for the diff and analysis).vendor/songbird, close this + #36 vendor-unwind TODO.