XGW.ICE.Binding (xgw v0.1.0)

Copy Markdown View Source

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

Types

Credential map for STUN encode/decode during ICE checks.

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

creds()

@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 - :controlling or :controlled

Functions

build_check_request(creds, priority, opts \\ [])

@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).

build_success(req, arg, creds)

@spec build_success(
  XMediaLib.Stun.t(),
  {:inet.ip_address(), :inet.port_number()},
  creds()
) :: binary()

Builds a Binding success response for an inbound request.

connectivity_check?(stun)

@spec connectivity_check?(XMediaLib.Stun.t()) :: boolean()

Returns true when the request is an ICE connectivity check (role attrs present).

decode(data, creds)

@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).

use_candidate?(stun)

@spec use_candidate?(XMediaLib.Stun.t()) :: boolean()

Returns true when the request includes USE-CANDIDATE (nomination).

valid_username?(arg1, creds)

@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.