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
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
Functions
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}
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}
@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}