ITADN

[Bug]: Jingle calls fail after Smacks resume (IQ-result handler for session-accept wiped on reconnect causes ICE deadlock)

#1601Closed815rx1 创建于 2026-03-08
8
815rx1commented
### What Monal Release channel are you using? Alpha ### iOS system version (if applicable) 26.3 ### macOS system version (if applicable) _No response_ ### Monal version Alpha 2348142b ### Used XMPP server (domain) xmpp.euhd.de ### Which XMPP-Server software are you using? Prosody ### XMPP Server Software Version 0.13 ### How many accounts are you using in Monal? 1 ### What happened? First of all: Thank you for the quick fix in #1588! Commit `1523dc8` elegantly solves the 18-second wakeup delay by making the unfreeze synchronous. Since #1588 is now closed, I am opening this new, dedicated issue to address the second, separate problem we discussed in the later comments: Jingle calls still fail if a network switch or TCP reconnect (Smacks resume) occurs right after the call is initiated. _**Real-world test confirms: Handler-Wipe (not Push infrastructure)**:_ - To isolate the bug, I ran a strict real-world test today. **Scenario:** Monal is in deep sleep (display off, extended standby) -> Caller (Monocles) switches network -> Monocles initiates a Jingle call. **Observed behavior:** - VoIP Push delivered correctly -> Monal wakes up instantly and the CallKit screen rings. - ICE failure → The caller side (Monocles) receives "connection failed" almost instantly. **What this proves:** The Push infrastructure works perfectly. The failure occurs strictly within the Jingle state machine during the Smacks Resume that happens when Monal wakes up. > **Note:** The fix from #1588 does **not** address this path the failure occurs even when Monal wakes correctly via Push and CallKit responds immediately. This is a second, independent bug. **Technical Root Cause (The Orphaned State Machine)** When the connection drops and Smacks resumes, Monal clears its IQ handlers. My raw logs confirm this directly: when the state is serialized during disconnect, `persistentIqHandlers={}` the Jingle IQ-result handler was **never added to the persistent structure in the first place**, so it cannot survive any TCP reconnect. ``` 10 --> persistState(saved at 2026-03-03 13:59:42 +0000): isDoingFullReconnect=NO, ... streamID=fL6YruLBbS_1 persistentIqHandlers={ } ... RECV Stanza: <resumed h='5824' previd='fL6YruLBbS_1' xmlns='urn:xmpp:sm:3'/> ``` This means every pending IQ callback is flushed including the one registered for the Jingle `session-accept` acknowledgment. ### Why this breaks the call (XEP-0176 violation) The core issue isn't the *content* of the result IQ it's the handler acting as a **mandatory state transition trigger**. XEP-0176 (Jingle ICE-UDP Transport) § 4.2 explicitly states: > "The responder MUST NOT send any candidate-bearing transport-info stanzas until it has received an IQ-result from the initiator in response to the session-accept." The IQ result is the mandatory synchronization point. The failure chain is: 1. The IQ-result arrives from the caller acknowledging the `session-accept`. 2. Monal discards it and the handler was wiped because it was never registered in `persistentIqHandlers`. 3. Monal's internal state machine is "orphaned": it stalls indefinitely in *"waiting for session-accept acknowledgment"*. 4. Monal never starts the ICE exchange (`transport-info`). 5. The caller times out waiting for candidates → connection fails. **Comparison with other clients** Robust Jingle implementations (e.g. `JingleRtpConnection` in Conversations or lib-jitsi-meet) use explicit IQ callbacks to drive this exact state transition. The receipt of the acknowledgment is what moves the session from `pending` to `established`. If that callback is lost during a network hiccup, the next state is never entered. **A possible fix maybe** Option 1: The `persistentIqHandlers` structure **already exists** for exactly this purpose. The fix is targeted: when a Jingle `session-accept` is sent, its IQ-result handler must be registered in `persistentIqHandlers` (not the ephemeral handler dict), so it survives a Smacks resume. Option 2: Re-registering all in-progress session handlers on a successful resume would also work, but requires iterating active Jingle sessions on reconnect and is a larger, riskier change. - On sending `session-accept`: register the IQ-result handler in `persistentIqHandlers` instead of the ephemeral dict. - On session teardown (accept confirmed or call ended): remove the handler from `persistentIqHandlers` to avoid leaks. ### Anything else? _No response_ ### FAQ - [x] I have [checked the FAQ](https://github.com/monal-im/Monal/wiki/FAQ---Frequently-Asked-Questions) for my issue ### Considerations for XMPP users - [x] I have checked if my issue can be solved with [Considerations for XMPP users](https://github.com/monal-im/Monal/wiki/Considerations-for-XMPP-users) and [Considerations for XMPP server admins](https://github.com/monal-im/Monal/wiki/Considerations-for-XMPP-server-admins) ### XEP-Check - [x] I have checked that at least XEP-198, XEP-0280, XEP-0352, XEP-0357, XEP-0313 and XEP-0163 are activated on my server and shown as 'green' under Settings --> Account--> (i) in advanced settings ### Notifications-Menu - [x] I have checked that all checkmarks are present under Settings --> Notifications
关闭于 2026-03-09 1 条评论