Parrot.Sip.Headers.RecordRoute (Parrot Platform v0.0.1-alpha.3)

Module for working with SIP Record-Route headers as defined in RFC 3261 Section 20.30.

The Record-Route header is used by SIP proxies to force future messages in a dialog to be routed through the proxy. Each proxy that requires itself to be in the path of subsequent requests adds a Record-Route header.

Record-Route serves critical functions in SIP dialog management:

  • Ensuring proxies remain in the signaling path for the entire dialog
  • Enabling features like accounting, authorization, and call control
  • Supporting NAT traversal and firewall traversal
  • Facilitating mid-dialog request routing

The UAC copies all Record-Route header field values from responses into Route header field values in reverse order for subsequent requests within the dialog. The 'lr' (loose routing) parameter MUST be included for RFC 3261 compliance.

References:

  • RFC 3261 Section 12.1.1: UAC Behavior (Record-Route processing)
  • RFC 3261 Section 16.6: Request Forwarding (proxy adding Record-Route)
  • RFC 3261 Section 16.7: Response Processing (proxy must not modify Record-Route)
  • RFC 3261 Section 20.30: Record-Route Header Field
  • RFC 3261 Section 20.34: Route Header Field (relationship to Record-Route)

Summary

Functions

Formats a Record-Route header as a string.

Formats a list of Record-Route headers as a string.

Creates a new Record-Route header.

Parses a Record-Route header string into a Record-Route struct.

Parses a list of Record-Route headers.

Types

t()

@type t() :: %Parrot.Sip.Headers.RecordRoute{
  display_name: String.t() | nil,
  parameters: map(),
  uri: String.t() | Parrot.Sip.Uri.t()
}

Functions

format(record_route)

@spec format(t()) :: String.t()

Formats a Record-Route header as a string.

Examples

iex> record_route = %Parrot.Sip.Headers.RecordRoute{display_name: nil, uri: "sip:proxy.example.com;lr", parameters: %{}}
iex> Parrot.Sip.Headers.RecordRoute.format(record_route)
"<sip:proxy.example.com;lr>"

iex> record_route = %Parrot.Sip.Headers.RecordRoute{display_name: "Example Proxy", uri: "sip:proxy.example.com;lr", parameters: %{}}
iex> Parrot.Sip.Headers.RecordRoute.format(record_route)
"Example Proxy <sip:proxy.example.com;lr>"

iex> record_route = %Parrot.Sip.Headers.RecordRoute{display_name: "Complex Name", uri: "sip:proxy.example.com;lr", parameters: %{"param" => "value"}}
iex> Parrot.Sip.Headers.RecordRoute.format(record_route)
""Complex Name" <sip:proxy.example.com;lr>;param=value"

format_list(record_routes)

@spec format_list([t()]) :: String.t()

Formats a list of Record-Route headers as a string.

Examples

iex> record_routes = [
...>   %Parrot.Sip.Headers.RecordRoute{display_name: nil, uri: "sip:proxy1.example.com;lr", parameters: %{}},
...>   %Parrot.Sip.Headers.RecordRoute{display_name: nil, uri: "sip:proxy2.example.com;lr", parameters: %{}}
...> ]
iex> Parrot.Sip.Headers.RecordRoute.format_list(record_routes)
"<sip:proxy1.example.com;lr>, <sip:proxy2.example.com;lr>"

new(uri, display_name \\ nil, parameters \\ %{})

@spec new(String.t() | Parrot.Sip.Uri.t(), String.t() | nil, map()) :: t()

Creates a new Record-Route header.

Examples

iex> Parrot.Sip.Headers.RecordRoute.new("sip:proxy.example.com;lr")
%Parrot.Sip.Headers.RecordRoute{display_name: nil, uri: "sip:proxy.example.com;lr", parameters: %{}}

iex> Parrot.Sip.Headers.RecordRoute.new("sip:proxy.example.com;lr", "Example Proxy")
%Parrot.Sip.Headers.RecordRoute{display_name: "Example Proxy", uri: "sip:proxy.example.com;lr", parameters: %{}}

parse(string)

@spec parse(String.t()) :: t()

Parses a Record-Route header string into a Record-Route struct.

Examples

iex> Parrot.Sip.Headers.RecordRoute.parse("<sip:proxy.example.com;lr>")
%Parrot.Sip.Headers.RecordRoute{display_name: nil, uri: "sip:proxy.example.com;lr", parameters: %{}}

iex> Parrot.Sip.Headers.RecordRoute.parse("Example Proxy <sip:proxy.example.com;lr>")
%Parrot.Sip.Headers.RecordRoute{display_name: "Example Proxy", uri: "sip:proxy.example.com;lr", parameters: %{}}

iex> Parrot.Sip.Headers.RecordRoute.parse(""Complex Name" <sip:proxy.example.com;lr>;param=value")
%Parrot.Sip.Headers.RecordRoute{display_name: "Complex Name", uri: "sip:proxy.example.com;lr", parameters: %{"param" => "value"}}

parse_list(string)

@spec parse_list(String.t()) :: [t()]

Parses a list of Record-Route headers.

Examples

iex> Parrot.Sip.Headers.RecordRoute.parse_list("<sip:proxy1.example.com;lr>, <sip:proxy2.example.com;lr>")
[
  %Parrot.Sip.Headers.RecordRoute{display_name: nil, uri: "sip:proxy1.example.com;lr", parameters: %{}},
  %Parrot.Sip.Headers.RecordRoute{display_name: nil, uri: "sip:proxy2.example.com;lr", parameters: %{}}
]