XGW.Demux (xgw v0.1.0)

Copy Markdown View Source

Separates mixed UDP packets that share one socket into STUN, DTLS, and media.

Why demux exists

WebRTC reuses a single 5-tuple (same IP/port pair) for several protocols at once: connectivity probes (STUN), the security handshake (DTLS), and the media itself (RTP / RTCP). The first byte of each datagram tells you which protocol it is (RFC 7983). This module only classifies bytes; it does not parse STUN attributes or decrypt SRTP.

RTP and RTCP can also share the same port (RTCP-mux, RFC 5761). When the first-byte range is the media bucket (128-191), classify_media/1 looks at the RTP payload type field: values 64-95 mean RTCP, otherwise RTP.

RFCs

  • RFC 7983 -- first-byte demultiplexing of STUN, DTLS, ZRTP, TURN ChannelData, RTP/RTCP
  • RFC 5761 -- RTP/RTCP multiplexing (payload-type split in the media range)

Summary

Types

Full ingress classification including RTP vs RTCP split.

RFC 7983 first-byte protocol bucket.

Functions

Classifies a packet by its first byte (RFC 7983).

Full ingress classification: RFC 7983 first byte, then media PT split when applicable.

Classifies an RFC 7983 RTP/RTCP-range packet as RTP or RTCP (RFC 5761 mux PT rule).

Types

kind()

@type kind() :: :stun | :zrtp | :dtls | :turn_channel | :rtp | :rtcp | :unknown

Full ingress classification including RTP vs RTCP split.

protocol()

@type protocol() :: :stun | :zrtp | :dtls | :turn_channel | :rtp_rtcp | :unknown

RFC 7983 first-byte protocol bucket.

Functions

classify(arg1)

@spec classify(binary()) :: {:ok, protocol()} | {:error, :empty}

Classifies a packet by its first byte (RFC 7983).

Examples

iex> XGW.Demux.classify(<<0, 0, 0, 0>>)
{:ok, :stun}

iex> XGW.Demux.classify(<<22, 0>>)
{:ok, :dtls}

iex> XGW.Demux.classify(<<128, 0>>)
{:ok, :rtp_rtcp}

iex> XGW.Demux.classify(<<>>)
{:error, :empty}

classify_kind(data)

@spec classify_kind(binary()) :: {:ok, kind()} | {:error, :empty | :too_short}

Full ingress classification: RFC 7983 first byte, then media PT split when applicable.

Examples

iex> XGW.Demux.classify_kind(<<0, 1, 2>>)
{:ok, :stun}

iex> XGW.Demux.classify_kind(<<22, 0>>)
{:ok, :dtls}

iex> XGW.Demux.classify_kind(<<128, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>>)
{:ok, :rtp}

classify_media(arg1)

@spec classify_media(binary()) :: {:ok, :rtp | :rtcp} | {:error, :too_short}

Classifies an RFC 7983 RTP/RTCP-range packet as RTP or RTCP (RFC 5761 mux PT rule).

Examples

iex> XGW.Demux.classify_media(<<2::2, 0::6, 0::1, 63::7, 0::16, 0::32, 0::32>>)
{:ok, :rtp}

iex> XGW.Demux.classify_media(<<2::2, 0::6, 0::1, 64::7, 0::16, 0::32, 0::32>>)
{:ok, :rtcp}

iex> XGW.Demux.classify_media(<<128>>)
{:error, :too_short}