Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check all remote ICE candidates in Rtc::accepts() #487

Merged
merged 2 commits into from
Mar 21, 2024

Conversation

OxleyS
Copy link
Contributor

@OxleyS OxleyS commented Mar 21, 2024

Sometimes, a WebRTC client will send e.g. DTLS traffic using a candidate pair that has been found successful, but is not the currently nominated pair. In my local tests, this only happens as the connection is being established. My guess is a race condition - if multiple pairs are nominated in sequence, it's possible for traffic to come in via an old nomination before the new one reaches the remote client and takes effect.

If this happens, Rtc::accepts() will reject the traffic due to not being from the current nominated pair. I noticed this while working with Firefox, but it may happen in other WebRTC clients as well. I also noticed that occasionally Firefox will get stuck using the same not-nominated pair to retry DTLS that failed in this manner (although I imagine such behavior is not intended).

To minimize the performance impact, we continue to eagerly check against the nominated pair, and only fallback to checking all candidates as a last resort.

Copy link
Owner

@algesten algesten left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A good start.

One small comment.

We also need to think through the security consequences here. Does this mean we accept traffic for remote candidates that have not been verified with a STUN request/response? Does that matter? The SCTP and RTP traffic will be protected by the DTLS fingerprint, so maybe it's not a big deal 🤔

Wonder how libWebRTC does this? Maybe they only accept unverified remote candidates for a short while?

src/lib.rs Show resolved Hide resolved
@OxleyS
Copy link
Contributor Author

OxleyS commented Mar 21, 2024

That's true, it would be a good idea to sanity check candidates first. I can also try digging into libwebrtc source a bit and see if I find anything.

@OxleyS
Copy link
Contributor Author

OxleyS commented Mar 21, 2024

I digged into libwebrtc source a bit. It seems they have similar logic for deciding what to forward, complete with a fast path for the selected one. Here, Connection basically boils down to a candidate pair, with one created for every non-pruned local-remote combination.

The "non-pruned" bit may be important to us as well, in the spirit of the security consequences you mentioned. libwebrtc seems to prune candidates whose networks have disappeared, or when a re-gather is initiated. str0m's equivalent seems to be discarded?

@OxleyS
Copy link
Contributor Author

OxleyS commented Mar 21, 2024

We could then take one of a few approaches:

  1. Check all non-discarded remote candidates for a matching source address.
  2. Check all candidate pairs with CheckState::Succeeded for a remote candidate with a matching source address (this automatically excludes discarded candidates).
  3. The second solution, but also check the local candidate against the destination address.

Which of these do you feel is most appropriate?

@algesten
Copy link
Owner

I think 2 is a good choice. If it succeeded, we have got a successful request-response. That might match libWebRTC logic here.

…s alone. This check was also moved to IceAgent
Copy link
Owner

@algesten algesten left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like it!

Thanks!

@algesten algesten merged commit 651fcac into algesten:main Mar 21, 2024
21 of 22 checks passed
@OxleyS OxleyS deleted the accepts-check-all-remote branch March 21, 2024 15:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants