Builds and validates STUN Binding messages used as ICE connectivity checks.
Plain language
STUN (Session Traversal Utilities for NAT) is a small request/response
protocol often carried in UDP. ICE uses STUN Binding requests as
"can you hear me on this address?" probes. Successful checks prove a
candidate pair works; attributes such as ICE-CONTROLLING /
ICE-CONTROLLED and USE-CANDIDATE carry nomination and role info.
Integrity uses the SDP ice-pwd as a MESSAGE-INTEGRITY key. This module is
shared by ICE-lite (mostly inbound responses) and ICE-full (outbound checks
plus responses).
RFCs
- RFC 8489 -- STUN Binding request/response, MESSAGE-INTEGRITY, FINGERPRINT
- RFC 8445 -- ICE connectivity checks, USERNAME form, role attrs, USE-CANDIDATE
Summary
Functions
Builds an outbound ICE connectivity check Binding request.
Builds a Binding success response for an inbound request.
Returns true when the request is an ICE connectivity check (role attrs present).
Decodes STUN Binding packets.
Returns true when the request includes USE-CANDIDATE (nomination).
Returns true when USERNAME matches RFC 8445 inbound checks.
Types
@type creds() :: %{ optional(:ice_ufrag) => String.t(), optional(:ice_pwd) => String.t(), optional(:remote_ice_ufrag) => String.t() | nil, optional(:remote_ice_pwd) => String.t() | nil, optional(:tiebreaker) => binary(), optional(:role) => :controlling | :controlled }
Credential map for STUN encode/decode during ICE checks.
Fields
:ice_ufrag/:ice_pwd- local ICE credentials from SDP:remote_ice_ufrag/:remote_ice_pwd- remote credentials (optional until known):tiebreaker- ICE role conflict tie-breaker:role-:controllingor:controlled
Functions
@spec build_check_request(creds(), non_neg_integer(), keyword()) :: binary()
Builds an outbound ICE connectivity check Binding request.
USERNAME is remote:local (peer ufrag first); MESSAGE-INTEGRITY uses the
remote pwd (RFC 8445 pt.7.2.2).
@spec build_success( XMediaLib.Stun.t(), {:inet.ip_address(), :inet.port_number()}, creds() ) :: binary()
Builds a Binding success response for an inbound request.
@spec connectivity_check?(XMediaLib.Stun.t()) :: boolean()
Returns true when the request is an ICE connectivity check (role attrs present).
@spec decode(binary(), creds()) :: {:ok, XMediaLib.Stun.t()} | {:error, term()}
Decodes STUN Binding packets.
Tries local ice_pwd first (ICE-lite inbound checks), then remote_ice_pwd
when set (peer-signed consent / full-ICE responses).
@spec use_candidate?(XMediaLib.Stun.t()) :: boolean()
Returns true when the request includes USE-CANDIDATE (nomination).
@spec valid_username?(XMediaLib.Stun.t(), creds()) :: boolean()
Returns true when USERNAME matches RFC 8445 inbound checks.
The sender sets USERNAME to remote_candidate_ufrag:local_candidate_ufrag,
which at the receiver is ice_ufrag:remote_ice_ufrag.