mirror of
https://github.com/pion/ice.git
synced 2026-04-22 16:17:11 +08:00
23e8708890
Implements RFC 8838 §11.4 (“Receiving Trickled Candidates”) behavior so
that when a remote peer-reflexive (prflx) candidate is discovered first,
a later signaled equivalent candidate (host/srflx/relay) replaces it
in-place while preserving checklist/pair behavior.
## Key Changes
- **prflx replacement on trickle (RFC 8838 §11.4)**
- Replace redundant remote prflx candidates when a signaled candidate
with the same transport address arrives.
- Upgrade existing checklist pairs in-place (remote candidate swap),
while preserving the pair priority.
- Update local candidate remote-candidate caches so subsequent lookups
use the signaled candidate.
- Avoid creating duplicate pairs when the replacement occurs.
- **prflx priority from inbound STUN (RFC 5245 §7.1.3.2.1)**
- When a prflx candidate is discovered via an inbound Binding Request,
set its priority from the STUN `PRIORITY` attribute.
~~- **Candidate pair priority correctness (RFC 5245)**~~
~~- Fix pair-priority computation to use the RFC 5245 formula with
$2^{32}$ (not $2^{32}-1$).~~
~~- Add an internal helper for the computation and make it overflow-safe
via saturation.~~
~~- Add a pair-level priority override so prflx→signaled replacement can
preserve the previously computed pair priority.~~
(Restored original code, this change was not needed)
- **Handler notifier deadlock/starvation fix**
- Split the notifier’s single `running` flag into independent running
state for connection-state, candidate, and selected-pair queues.
- Prevent callback starvation that could cause tests (and user code)
waiting on connection-state transitions to hang.
~~- **Test stability improvements (Active TCP)**~~
~~- Prefer non-link-local IPv6 addresses and skip IPv6 cases when only
link-local addresses exist.~~
~~- Use mDNS on non-Windows platforms but disable it on Windows to
reduce flakiness.~~
~~- Increase the per-subtest timeout to reduce intermittent CI/dev
timeouts.~~
(Moved to another PR)
#### Reference issue
Fixes #622
102 lines
3.0 KiB
Go
102 lines
3.0 KiB
Go
// SPDX-FileCopyrightText: 2026 The Pion community <https://pion.ly>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package ice
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
receiveMTU = 8192
|
|
defaultLocalPreference = 65535
|
|
|
|
// ComponentRTP indicates that the candidate is used for RTP.
|
|
ComponentRTP uint16 = 1
|
|
// ComponentRTCP indicates that the candidate is used for RTCP.
|
|
ComponentRTCP
|
|
)
|
|
|
|
// Candidate represents an ICE candidate.
|
|
type Candidate interface {
|
|
// An arbitrary string used in the freezing algorithm to
|
|
// group similar candidates. It is the same for two candidates that
|
|
// have the same type, base IP address, protocol (UDP, TCP, etc.),
|
|
// and STUN or TURN server.
|
|
Foundation() string
|
|
|
|
// ID is a unique identifier for just this candidate
|
|
// Unlike the foundation this is different for each candidate
|
|
ID() string
|
|
|
|
// A component is a piece of a data stream.
|
|
// An example is one for RTP, and one for RTCP
|
|
Component() uint16
|
|
SetComponent(uint16)
|
|
|
|
// The last time this candidate received traffic
|
|
LastReceived() time.Time
|
|
|
|
// The last time this candidate sent traffic
|
|
LastSent() time.Time
|
|
|
|
NetworkType() NetworkType
|
|
Address() string
|
|
Port() int
|
|
|
|
Priority() uint32
|
|
|
|
// A transport address related to a
|
|
// candidate, which is useful for diagnostics and other purposes
|
|
RelatedAddress() *CandidateRelatedAddress
|
|
|
|
// Extensions returns a copy of all extension attributes associated with the ICECandidate.
|
|
// In the order of insertion, *(key value).
|
|
// Extension attributes are defined in RFC 5245, Section 15.1:
|
|
// https://datatracker.ietf.org/doc/html/rfc5245#section-15.1
|
|
//.
|
|
Extensions() []CandidateExtension
|
|
// GetExtension returns the value of the extension attribute associated with the ICECandidate.
|
|
// Extension attributes are defined in RFC 5245, Section 15.1:
|
|
// https://datatracker.ietf.org/doc/html/rfc5245#section-15.1
|
|
//.
|
|
GetExtension(key string) (value CandidateExtension, ok bool)
|
|
// AddExtension adds an extension attribute to the ICECandidate.
|
|
// If an extension with the same key already exists, it will be overwritten.
|
|
// Extension attributes are defined in RFC 5245, Section 15.1:
|
|
AddExtension(extension CandidateExtension) error
|
|
// RemoveExtension removes an extension attribute from the ICECandidate.
|
|
// Extension attributes are defined in RFC 5245, Section 15.1:
|
|
RemoveExtension(key string) (ok bool)
|
|
|
|
String() string
|
|
Type() CandidateType
|
|
TCPType() TCPType
|
|
|
|
Equal(other Candidate) bool
|
|
|
|
// DeepEqual same as Equal, But it also compares the candidate extensions.
|
|
DeepEqual(other Candidate) bool
|
|
|
|
Marshal() string
|
|
|
|
// transportAddressEqual checks if the transport address (IP, Port, NetworkType, TCPType) is equal to another
|
|
// candidate.
|
|
transportAddressEqual(other Candidate) bool
|
|
|
|
addr() net.Addr
|
|
filterForLocationTracking() bool
|
|
agent() *Agent
|
|
context() context.Context
|
|
|
|
close() error
|
|
copy() (Candidate, error)
|
|
seen(outbound bool)
|
|
start(a *Agent, conn net.PacketConn, initializedCh <-chan struct{})
|
|
writeTo(raw []byte, dst Candidate) (int, error)
|
|
|
|
replaceRemoteCandidateCacheValues(oldRemote, newRemote Candidate)
|
|
}
|