Repository navigation
Send prflx type preference in PRIORITY attribute - #1026
Merged
Merged
Conversation
RFC 8445 Section 7.1.1 requires the PRIORITY attribute of a Binding request to carry the local candidate's priority computed with the type preference of peer-reflexive candidates. The selectors and the renomination path sent Candidate.Priority() instead, so a host candidate announced itself with the host type preference (126). Since pion#877 a remote agent assigns a newly discovered peer-reflexive candidate the priority from the request (Section 7.3.1.3). When a pion peer behind a NAT reaches a pion agent whose signalled host candidate is also validated, the peer-reflexive pair now ties the host pair, the older peer-reflexive pair stays the best valid pair and nomination waits PrflxAcceptanceMinWait (1 s) although the host pair succeeded within milliseconds. libwebrtc sends the peer-reflexive type preference here (Connection::prflx_priority), so this also aligns the priorities pion peers advertise with what browsers advertise. Add Candidate.prflxPriority, use it for every Binding request, and test that the controlling, controlled and nomination requests carry it. Resolves pion#1025 Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Member
|
Just one correction #877 didn't introduce this, it just made the bug more visible with pion to pion connections. also ai descriptions are banned per our contributions guide please write a manual description next time |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1026 +/- ##
==========================================
+ Coverage 91.73% 91.76% +0.02%
==========================================
Files 45 45
Lines 5447 5450 +3
==========================================
+ Hits 4997 5001 +4
+ Misses 450 449 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
JoTurk
approved these changes
Oct 6, 2026
Member
|
Thank you for fixing this! Can we merge this PR now? |
Contributor
Author
Of course! |
Member
|
I'll cherry pick it to v4 |
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.
Description
Binding requests sent
PriorityAttr(local.Priority()): the local candidate's own priority, with the host type preference (126) for a host candidate. RFC 8445 §7.1.1 requires the PRIORITY attribute to be computed "for the local candidate, but with the candidate type preference of peer-reflexive candidates", which is what libwebrtc sends (Connection::prflx_priority()).Since #877 a receiving agent assigns a discovered peer-reflexive candidate the request's PRIORITY (§7.3.1.3). With the sender bug, a pion peer that reaches a pion agent through NAT gets a peer-reflexive candidate with host priority; when the agent can also validate the peer's signalled host candidate, the two pairs tie,
getBestValidCandidatePairkeeps the earlier peer-reflexive pair, and nomination waitsPrflxAcceptanceMinWait(1 s) although the host pair succeeded within milliseconds. Before #877 the host pair outranked the peer-reflexive pair (126 vs 110) and was nominated immediately.This change:
Candidate.prflxPriority(): the candidate's priority with the top byte replaced by the peer-reflexive type preference (TCP offset applied as forTypePreference), keeping local preference and component, including for candidates with a priority override, as libwebrtc does;controllingSelector.PingCandidate,controllingSelector.nominatePair,controlledSelector.PingCandidateandAgent.sendNominationRequest;TestBindingRequestPriorityAttr, which decodes the sent request and checks the attribute for the controlling ping, the controlled ping, the nomination and the renomination request. Againstmainthe test fails at all four assertions.Compatibility: receivers without #877 ignore the attribute. Receivers with #877 now rank peer-reflexive candidates discovered from pion peers as they ranked them before #877, and as they already rank the ones discovered from browsers.
Observed in production with a LiveKit SFU (livekit/ice v4.4.0 fork) and Go SDK participants in the same VPC: moving the SFU from v4.2.2 to v4.4.0 took 75-90% of those connects from ~0.01 s to ~1.0 s, browsers unaffected. A v4 backport is on
ilay-decart/icebranchprflx-priority-attr-v4and applies cleanly tov4; happy to open it as a PR if wanted.go test -race ./...andgolangci-lint run(v2.10.1) pass locally.Resolves #1025
Co-authored-by: Claude Fable 5.1 noreply@anthropic.com