Tags: pion/ice
Tags
Support append rewrite rule for UDP/TCP mux (#923) Wrap the conn returned by UDP/TCP mux GetConn in a ref-counted sharedPacketConn so AddressRewriteAppend can hand out multiple alias host candidates that share a single underlying mux conn. The underlying conn is closed only when the last wrapper is released. Close mux conn in error paths in gather to avoid leak. Close #922
Fix race and disconnection after candidate replace (#913) This PR fixes two race conditions introduced by peer-reflexive candidate replacement and addresses a connectivity regression where an agent could transition from Connected to Disconnected/Failed shortly after replacement. ## Problems 1. Data race in candidate pair access: - `replaceRedundantPeerReflexiveCandidates` updated `pair.Remote` in place. - At the same time, hot-path reads (for example `CandidatePair.Write`) could read `pair.Remote` without synchronization. 2. Data race in remote candidate cache map: - `candidateBase.handleInboundPacket` (non-STUN path) read/wrote `remoteCandidateCaches` from recv loop goroutines. - Concurrent writes also happened from agent-loop code (`replaceRemoteCandidateCacheValues`). 3. Connectivity regression after replacement: - When replacing a selected pair's remote candidate (prflx -> signaled), the new candidate could have zero `LastReceived`/`LastSent`. - `validateSelectedPair` uses `selectedPair.Remote.LastReceived()`, which could cause quick `Connected -> Disconnected -> Failed` transitions. ## Root Cause Replacement logic preserved pair priority but mutated shared objects in place and did not preserve candidate activity timestamps across candidate object replacement. ## Fixes ### 1) Replace candidate pair objects instead of mutating `pair.Remote` - Added helper `replacePairRemote(pair, remote)` to clone pair state into a new `CandidatePair`. - Preserved pair fields and runtime stats: - `id`, role, state, nomination flags, binding counters. - RTT fields, packet/byte counters, request/response counters. - timestamp `atomic.Value` fields. - Replaced references in: - `a.checklist[i]` - `a.pairsByID[pair.id]` - If old pair was selected, published replacement via `a.setSelectedPair(replacement)`. ### 2) Serialize remote cache access on agent loop - Updated non-STUN path in `candidateBase.handleInboundPacket`: - Cache validation, remote candidate lookup, `seen(false)`, and cache insert now run inside `agent.loop.Run(...)`. - This removes concurrent map read/write between recv loop and agent-loop updates. ### 3) Preserve candidate activity on replacement - Added `copyCandidateActivity(dst, src)` to transfer: - `LastReceived` - `LastSent` - Applied before replacing references so selected-pair liveness checks remain stable.
Fixed TCP bugs, added TURN transport type option (#908) Fix relay transport semantics and decouple TURN control transport from relay candidate network type ## Summary This change fixes relay transport handling in two critical areas: 1. Some relay candidates were exposed with `tcp` network in the candidate line, even though relayed endpoints are UDP. 2. Relay connectivity could fail when pion/ice was configured with TCP-only network types, because TURN control transport selection and relay candidate transport were incorrectly coupled. The patch separates these concerns: - Relay candidate transport is treated as UDP (current TURN allocation behavior). - TURN client-to-server transport is selected independently from URL scheme/proto and a dedicated TURN transport protocol configuration. ## Bugs Fixed ### 1) Incorrect relay candidate network type in candidate lines Before this change, relay candidates created through TURN over TCP/TLS paths could carry TCP network in candidate metadata. Now relay candidates are always emitted as UDP network candidates, matching actual relayed endpoint behavior. ### 2) Relay connection failure in TCP-only configurations Before this change, relay gathering used candidate network type filtering to drive TURN control connection transport, which could block valid TURN/TCP or TURNS flows depending on configured candidate network types. Now TURN control transport selection is independent and based on: - Effective URL transport (explicit `transport` or implicit defaults: TURN->UDP, TURNS->TCP) - Allowed TURN transport protocols configuration This enables relay connectivity in scenarios where TURN control transport is TCP while relay endpoints remain UDP. ## Key Implementation Changes - Introduced dedicated TURN control transport filtering path for relay gathering. - Kept relay candidate publication gated by UDP candidate support (relay allocations currently produce UDP endpoints). - Ensured relay candidate creation uses UDP network type regardless of TURN control channel transport. - Removed early remote candidate rejection based only on local network type filters, so candidates are stored and compatibility is handled later at pairing/sending stages. - Added sanitization/deduplication for network-type based options and TURN transport protocol options. ## API/Config Notes - `WithNetworkTypes(...)` continues to control candidate network types exposed/used for pairing. - `WithTURNTransportProtocols(...)` controls TURN client<->server transport independently. - Config comments were updated to clarify these responsibilities and defaults. ## Test Coverage Added/Updated - Added comprehensive relay/srflx/host transport matrix coverage in `transport_filtering_matrix_test.go`. - Added explicit TURN/TURNS and implicit transport-default test cases. - Added regression test verifying TURN-over-TCP still produces UDP relay candidates. - Updated remote-candidate behavior tests to reflect store-first semantics. - Added/updated option sanitization tests for network type and TURN transport protocol handling.
Fix controlled agent STUN busy loop Once a candidate pair reaches Succeeded state with a selected pair, controlledSelector.HandleBindingRequest no longer sends a triggered check (PingCandidate). Previously, every inbound Binding Request unconditionally called PingCandidate, creating a ping-pong loop where each Response triggered a new Request at 1/RTT speed. After connection is established, consent freshness is maintained by checkKeepalive() on a timer, so triggered checks are not needed. Added regression tests verifying: - No triggered check for succeeded+selected pairs - Triggered check still sent during ICE checking phase
Respect transport parameters and allowed net types (#901) ## Summary This change makes transport/network-type handling consistent across candidate gathering and remote candidate admission. It fixes cases where the ICE agent could use STUN/TURN URLs with mismatched transport or accept remote candidates on disabled network types. ## What changed ### 1) Remote candidate filtering by configured network types - Added a guard in `addRemoteCandidate` to ignore candidates whose `NetworkType` is not enabled in `AgentConfig.NetworkTypes`. - Added logging for ignored candidates. ### 2) URL transport interpretation and filtering - Added helpers: - `effectiveURLProtoType` (applies default transport when URI transport is omitted) - `urlSupportsSrflxGathering` - `relayNetworkTypesForURL` - `configuredNetworkTypes` - Applied this logic to srflx gathering (`gatherCandidatesSrflx`, `gatherCandidatesSrflxUDPMux`) so only valid UDP URLs are used. ### 3) Relay gathering honors network types and filtered local binds - Refactored relay gathering to select per-URL/per-network-type behavior instead of hardcoded network assumptions. - Kept support for interface/IP filtered local binding addresses in relay/srflx paths. - Replaced manual host:port formatting in srflx paths with `net.JoinHostPort(..., strconv.Itoa(...))` for safer address construction. ### 4) IPv6 TURN status (important) - IPv6 TURN code paths were updated and covered by tests, but full IPv6 TURN support is not complete yet. - For now, IPv6 TURN relay gathering is intentionally disabled in runtime path. - Related IPv6 relay test scenario is present but currently skipped (`t.Skip("IPv6 TURN is not supported yet")`). ### Reference issue Fixes #367
Cancel gathering before removing candidates (#842) #### Description When ICE agent is closed, the connections from UDP/TCP mux were removed before gathering was canceled. This led to candidate gathering adding entries to UDP mux which were not cleaned up. ~Also passing into logger to the mux as ICE agent logger could have more context and is useful to see the context.~
PreviousNext