nextcloud / nextcloud/spreed

Handle out of order answers from the HPB

Open
#5,930 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug feature: call 📹 feature: frontend 🖌️
Dominant language
PHP
Stars
2.2k
Forks
587
Avg merge
18h 27m
Merged PRs (30d)
333

Description

Follow up to #3732:

Out of order answers from the HPB are not properly handled, as the answer for a previous offer can be assigned to a new offer (offer sent, answer delayed, another offer sent due to not having received an answer, answer for previous offer received and assigned to the new offer)

  • When there is a mismatch between offers and answers the media will not be relayed by Janus and its logs show Missing valid SRTP session (packet arrived too early?), skipping....
  • Without HPB it can be known if an answer belongs to an offer with the sid field of peers and messages, but HPB messages do not include that field.
  • Even if there is a mismatch between offer and answer the browser will accept the answer and the connection will be established (kind of); the connection will be stable, and the ICE connection state will not transition to failed, so it can not be relied on the normal reconnection mechanism. However, even if the connection is established the RTCPeerConnection stats show that no media is transmitted (bytesSent in outbound-rtp will be zero). Therefore it may be possible to handle this scenario by adding a watchdog that restarts the connection if no media at all was transmitted, for example, in the first 10 seconds after the media was enabled (it may not be possible to check it in the first 10 seconds after the connection was established because if the media was disabled no media would be transmitted).

How to test

  • Modify the code of the external signaling server to delay handling the received offer and thus sending the answer long enough to cause the browser to send a new offer:
    • In hub.go
      • Add "math/rand" to the imports at the top
      • Before creating the publisher in processMcuMessage, add
        if rand.Intn(100) < 90 { time.Sleep(10 * time.Second) }
        to delay handling most of the offers longer than the timeout used in the WebUI to send new ones.
      • Replace ctx, cancel := context.WithTimeout(context.Background(), h.mcuTimeout) with
        ctx, cancel := context.WithTimeout(context.Background(), time.Duration(18) * time.Second)
        to ensure that the delayed offer will be eventually received by Janus (otherwise it would be cancelled due to the timeout); another option would have been to change the default timeout in the configuration.
  • Setup the MCU
  • Start a call with a user
  • Join the call with another user or guest
Expected result

The participants are eventually connected and they can hear and see each other.

Result without this pull request

The participants are eventually connected, but they can not hear nor see the other participant (if they can join the call again, as the answer was not delayed).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in hub.go around processMcuMessage and the MCU timeout handling, then reproduce the delayed-answer scenario using the listed signaling-server changes. Verify that participants eventually connect and can hear and see each other, rather than showing zero media or Janus SRTP errors. The issue does not identify the WebUI connection-handling entry point, so implementation scope needs investigation.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, javascript
Domain
audio-video-rtc
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.