Sync develop: call robustness, native codec, mute, doctor, client UI - #44
Merged
Conversation
- session wires nativemlow.WrapEncoder (identity without the tag) - Dockerfile ARG NATIVE=1 builds opus_mlow (pinned SHA) and links the nativemlow encoder statically; NATIVE=0 keeps the pure-Go build - docker.yml publishes both variants (default tags = native, -pure suffix) - ci.yml native job builds and tests the tagged variant
- drop per-frame fallback to the stateful Go encoder (state desync risk); construction-time fallback only, surfaced by WrapEncoder's mode return - session logs the ACTIVE encode path, Warn on native degradation - Dockerfile selects the build stage via VARIANT so pure builds never clone or compile the native toolchain - explicit runtime.KeepAlive across cgo calls - race-detector coverage for the tagged variant in CI plus a concurrent Encode/Close test
feat: optional native MLow encoder via opus_mlow build tag
Redesign session pages into account console with rename support
Move VoipSocket seam out of voip/core
Surface connected relay as a pill on the identity strip
Dial the FNA relay first on inbound calls
Fail fast with a clear message when the microphone is unavailable
Add call mute with mute_v2 signaling both ways
Parse voip_settings and log the selected audio codec
Record per-call event timeline to JSONL for support
Survive a browser refresh during an active call
Reorder inbound audio through a jitter buffer with concealment
feat: detect the external public ip via stun in the doctor
- fan out terminate reason=accepted_elsewhere to the callee devices that did not answer, using the device list enumerated for the offer - first accept wins: a later accept from another device no longer swaps acceptedByJid and rekeys srtp mid-call - a late reject/terminate from a non-answering device no longer tears down the live call
the first-accept guard now only blocks accepts from sibling devices; a retransmitted accept from the answering device reaches the decrypt/rekey block again, which is the only repair path when the first accept's call key failed to decrypt on a transient signal-session desync. the accepted_elsewhere fanout stays one-shot.
…ion-accept fix: stop sibling devices ringing when a companion answers
- classify by rtp version bits + second byte in the rtcp type range (192-223) instead of exact first bytes: an rtcp compound with more than one report block (0x82+) was misrouted to the rtp path, and an rtp packet with the marker bit and no extension (0x80) was swallowed by the rtcp path - the peer subscription bootstrap now runs only after srtp auth succeeds, so rtp-shaped bytes with a spoofed ssrc can no longer redirect the subscription (the old classifier shielded one such shape by accident; the invariant is now explicit)
fix: demux rtp/rtcp by version and packet type range
Drop stale call offers replayed after offline reconnect
Each OfflineSyncPreview arms a 30s AfterFunc backstop that is never cancelled — not by OfflineSyncCompleted, nor by a newer Preview. With reconnects in quick succession (unstable network, exactly when WhatsApp replays buffered offers), the first reconnect's orphaned timer fires mid-way through the second reconnect's replay window and clears offlineReplaying early, reopening the ghost-ring hole for buffered offers younger than staleOfferThreshold. Tag each window with an atomic generation counter and have the backstop closure only clear the flag if its generation is still current. Keeps the lock-free atomic.Bool design; isStaleOffer itself is untouched. Fixes the edge case reported in JotaDev66#43. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fix(session): guard replay-window backstop with a generation token
maxOpenRelays closed relays by OnOpen race order ("closing loser"), which
could shut the is_fna relay carrying the peer's inbound media when it
opened third. prioritizeFNA only guards the dial order, not OnOpen. Keep
maxDialRelays=3 so the dialed set stays bounded.
fix(transport): remove maxOpenRelays cap to keep the is_fna relay open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Media & call robustness
maxOpenRelayscap that raced the is_fna relay shut, keepingmaxDialRelays=3(the peer's inbound media only arrives on the is_fna relay).StartCallfails before setup.Native codec (CPU)
nativemlowbuild tag.Mute
mute_v2signaling; mute button and peer-mute indicator in the client.Doctor / STUN
WACALLS_STUN_SERVERconfig with public STUN defaults.Session / API / onboarding UI
Diagnostics & docs
WACALLS_DIAG_DIRis set.WACALLS_STUN_SERVERand the doctor STUN check; list the call mute endpoint in the API table.Test plan
/healthzreturns{"status":"ok"}