XGW.ICE.Consent (xgw v0.1.0)

Copy Markdown View Source

Keeps an already-selected ICE path "alive" (consent freshness, RFC 7675).

After ICE nominates a pair, the path can still die silently: a NAT binding may expire, a firewall may close UDP state, or a peer may disappear. WebRTC therefore periodically sends lightweight STUN Binding probes. If no fresh consent is observed within a timeout, the connection should be torn down instead of sending media into a black hole.

Helpers here build outbound consent Binding requests and track last_consent_at for both ICE-lite and ICE-full agents.

RFCs

  • RFC 7675 -- ICE consent freshness
  • RFC 8489 -- STUN Binding used as consent probes
  • RFC 8445 -- USERNAME / MESSAGE-INTEGRITY for Binding requests

Summary

Types

ICE agent map with consent fields (lite or full).

Functions

Builds an outbound STUN Binding request for consent freshness.

Returns true when consent has expired (no refresh within timeout_ms).

Records consent freshness at monotonic time now_ms.

Types

ice()

@type ice() :: map()

ICE agent map with consent fields (lite or full).

Functions

binding_request(ice)

@spec binding_request(ice()) :: binary()

Builds an outbound STUN Binding request for consent freshness.

Uses USERNAME remote:local (sender perspective per RFC 8445 pt.7.2.2) and MESSAGE-INTEGRITY with the remote ice-pwd. No ICE role attributes.

expired?(map, now_ms, timeout_ms)

@spec expired?(ice(), integer(), non_neg_integer()) :: boolean()

Returns true when consent has expired (no refresh within timeout_ms).

Examples

iex> XGW.ICE.Consent.expired?(%{last_consent_at: nil}, 1000, 500)
false

iex> XGW.ICE.Consent.expired?(%{last_consent_at: 100}, 700, 500)
true

iex> XGW.ICE.Consent.expired?(%{last_consent_at: 100}, 400, 500)
false

refresh(ice, now_ms)

@spec refresh(ice(), integer()) :: ice()

Records consent freshness at monotonic time now_ms.

Examples

iex> XGW.ICE.Consent.refresh(%{last_consent_at: nil}, 1234)
%{last_consent_at: 1234}