ICE-lite agent: answer inbound STUN checks in the controlled role.
Lite vs full
Many media servers sit on a public IP and never need to punch outbound NAT
holes themselves. ICE-lite (RFC 8445) is that mode: the agent publishes
host candidates, verifies MESSAGE-INTEGRITY with its local ice-pwd,
optionally checks USERNAME, merges trickle remote candidates, and responds
to Binding requests. Connectivity is declared when inbound checks include
ICE role attributes (and nomination when required).
Use ice_lite: false on the Peer for XGW.ICE.Full instead.
RFCs
- RFC 8445 -- ICE-lite (controlled role, inbound checks only)
- RFC 8489 -- STUN Binding responses
- RFC 7675 -- consent freshness
Summary
Functions
Adds a trickle remote candidate or records end-of-candidates.
Returns {ip, port} for a parsed candidate (delegates to XGW.ICE.endpoint/1).
Builds ICE-lite state from XGW.Descriptions config.
Handles one STUN datagram from from.
Merges remote candidates (delegates to XGW.ICE.merge_remote/2).
Builds ICE-lite state with explicit credentials (tests and callers without SDP).
Seeds ICE-lite state with remote candidates from the initial offer SDP.
Types
@type from() :: XGW.ICE.endpoint()
Remote UDP endpoint {ip, port}.
@type t() :: %{ ice_ufrag: String.t(), ice_pwd: String.t(), ice_tiebreaker: binary(), remote_ice_ufrag: String.t() | nil, remote_ice_pwd: String.t() | nil, bundle_mids: [String.t()], remote_candidates: [XMediaLib.SDP.Candidate.t()], remote_candidates_eoc?: boolean(), last_consent_at: integer() | nil, connected?: boolean(), selected: from() | nil }
ICE-lite agent state.
ice_ufrag/ice_pwd- local credentials from the answerremote_ice_ufrag- remote ufrag from the offer (username validation)remote_ice_pwd- remote pwd from the offer (outbound STUN integrity)remote_candidates- merged trickle + SDP remote candidates (priority order)remote_candidates_eoc?- true after end-of-candidateslast_consent_at- monotonic ms of last consent refresh (RFC 7675)connected?- true after first ICE connectivity checkselected- validated remote{ip, port}pair
Functions
@spec add_remote_candidate(t(), map() | XMediaLib.SDP.Candidate.t()) :: {:ok, t()} | {:error, term()}
Adds a trickle remote candidate or records end-of-candidates.
@spec endpoint(XMediaLib.SDP.Candidate.t()) :: from()
Returns {ip, port} for a parsed candidate (delegates to XGW.ICE.endpoint/1).
Builds ICE-lite state from XGW.Descriptions config.
@spec handle_binding(binary(), from(), t()) :: {:reply, binary(), t()} | {:connected, binary(), t()} | {:consent, t()} | {:ignore, t()}
Handles one STUN datagram from from.
Returns {:reply, wire, state} for a binding response, optionally
{:connected, wire, state} when the first ICE connectivity check succeeds,
or {:consent, state} for an inbound Binding success (RFC 7675).
@spec merge_remote_candidates([XMediaLib.SDP.Candidate.t()], [ XMediaLib.SDP.Candidate.t() ]) :: [ XMediaLib.SDP.Candidate.t() ]
Merges remote candidates (delegates to XGW.ICE.merge_remote/2).
Builds ICE-lite state with explicit credentials (tests and callers without SDP).
@spec seed_remote_candidates(t(), [XMediaLib.SDP.Candidate.t()]) :: t()
Seeds ICE-lite state with remote candidates from the initial offer SDP.