Managing Client-Initiated Connections in the Session Initiation Protocol (SIP)
updates
Extracted elements (31)
Multiple flows to different servers reduce the avalanche restart problem: when a server fails, UAs with only that flow reconnect simultaneously causing load spikes, but UAs with a surviving secondary flow delay reconnection by a backoff period, spreading reconnect load across time.
STUN was chosen for UDP keep-alives over SIP-request-based approaches because the SIP Working Group concluded that achieving both good performance and full backwards compatibility with SIP-based keep-alives were mutually exclusive goals. STUN is robust and can detect changed IP address and port mappings.
Sending a double-CRLF over a connection-oriented transport is backwards compatible with RFC 3261 Section 7.5; however, only implementations that support RFC 5626 will respond to a ping with a pong. A UA that did not register using outbound procedures cannot expect a CRLF pong unless explicitly indicated.
Sending STUN binary data on the same UDP ports used for SIP is a significant non-backwards-compatible change to RFC 3261. A SIP node MUST NOT send STUN requests to a next-hop SIP node that has not explicitly indicated support; doing so could cause the node to be blacklisted for UDP traffic.
A SIP node MUST NOT send STUN requests over a flow unless it has an explicit indication that the target next-hop SIP server claims to support this specification. UACs MUST NOT use ambiguous configuration options to imply next-hop STUN support.
A UA MUST support outbound-proxy-sets with at least two outbound proxy URIs and SHOULD support sets with up to four URIs. If the set has more than one URI, the UAC MUST send a REGISTER request to at least two of the default outbound proxies.
A UA SHOULD create a UUID URN (RFC 4122) as its instance-id. If a URN scheme other than UUID is used, the UA MUST only use URNs for which an RFC from the IETF stream defines how the URN is constructed and used in the '+sip.instance' Contact header field parameter.
All edge proxies compliant with this specification MUST implement support for STUN NAT keep-alives on their SIP UDP ports. When a server receives a double CRLF sequence between SIP messages on a connection-oriented transport, it MUST immediately respond with a single CRLF over the same connection.
Each UA MUST have an Instance Identifier URN that uniquely identifies the device. This URN MUST be persistent across power cycles and MUST NOT change as the device moves from one network to another.
If a pong is not received within 10 seconds after sending a ping (or immediately after processing any incoming message being received when that 10 seconds expires), then the client MUST treat the flow as failed.
If a proxy receives information indicating no future messages will be delivered on a specific flow (e.g., a TCP socket closing or a destination-unreachable ICMP error), the proxy MUST invalidate all bindings in the target set that use that flow, regardless of AOR.
In a third-party registration, a UA MUST NOT include a 'reg-id' header field parameter if the registering UA is not the same instance as the UA referred to by the target Contact header field. A UAC also MUST NOT include an instance-id feature tag or reg-id parameter in a request to un-register all Contacts.
REGISTER requests MUST include an instance-id media feature tag. A UAC conforming to this specification MUST include a 'reg-id' parameter in the Contact header field that is distinct from other reg-id parameters used in other registrations with the same '+sip.instance' and AOR.
The authoritative proxy MUST NOT populate the target set with more than one contact with the same AOR and instance-id at a time. If a request fails with a 430 (Flow Failed) response, the proxy SHOULD replace the failed branch with another target with the same AOR and instance-id but a different reg-id.
The CRLF keep-alive MUST only be used with connection-oriented transports such as TCP or SCTP; it MUST NOT be used with connection-less transports such as UDP. Clients MUST support CRLF keep-alives.
The sequence of reg-id values MUST be exactly the same each time the UA instance power cycles or reboots, so that the reg-id values will collide with previously used values, enabling the registrar to replace older registrations.
The STUN keep-alive MUST only be used with connection-less transports such as UDP; it MUST NOT be used for connection-oriented transports. If the XOR-MAPPED-ADDRESS in the STUN Binding Response changes, the UA MUST treat this event as a failure on the flow. Clients MUST support STUN-based keep-alives.
When a successful registration response contains the Flow-Timer header field, the UA MUST send keep-alives at least as often as the number of seconds indicated. If using the server-recommended frequency, the UA SHOULD send keep-alives with interval randomly distributed between 80% and 100% of the server-provided time.
When an edge proxy is the first SIP node after the UAC, it either MUST store a flow token (containing information about the flow from the previous hop) in its Path URI or reject the request. The flow token MUST be an identifier that is unique to this network flow, and the first node MUST include an 'ob' URI parameter in its Path header field value.
When receiving a REGISTER, if the registrar is not the first hop and the Path header is missing or the first URI does not have an 'ob' URI parameter, outbound processing MUST NOT be applied. If the REGISTER contains reg-id and the outbound option tag in a Supported header field, the registrar MUST respond with 439 (First Hop Lacks Outbound Support).
A Flow Token is an identifier placed in the user portion of a SIP URI (typically in the Path header) by the first edge proxy that uniquely identifies a transport-layer flow. It allows the edge proxy to map future requests back to the correct flow and provides indirect authentication via the registrar.
The Flow-Timer header field, included in a successful 2xx registration response when the outbound option-tag is present in Require, conveys the number of seconds the server is prepared to wait without receiving keep-alives before considering the flow dead.
The 'ob' URI parameter has context-dependent meaning: in a Path header value it indicates the first edge proxy added a flow token; in a Contact or Route header field value it indicates the UA wants subsequent dialog requests routed over the same flow.
The 'reg-id' Contact header field parameter distinguishes concurrent registrations from the same UA instance over different flows for the same AOR. The registrar uses instance-id plus reg-id together as the binding key instead of the Contact URI.
The 'sip.instance' media feature tag (encoded as '+sip.instance' in the Contact header field parameter) carries a URN uniquely identifying a UA instance. It is used by registrars to associate multiple registrations over different flows with the same UA.
RFC 5626 registers the 'Flow-Timer' SIP header field, the 'reg-id' Contact header field parameter, the 'ob' SIP/SIPS URI parameter, the 'outbound' SIP option tag, the 430 (Flow Failed) response code, the 439 (First Hop Lacks Outbound Support) response code, and the 'sip.instance' media feature tag.
A UA that makes an anonymous request or has other privacy concerns MAY omit the 'sip.instance' media feature tag from its Contact header field, since the instance-id provides a persistent, globally unique identifier that can be used to track the UA across registrations.
Flow tokens MUST be unforgeable: the example algorithm uses an HMAC-SHA1-80 keyed by a 20-octet per-proxy secret over the flow's protocol, local address/port, and remote address/port, then base64-encodes the HMAC concatenated with the input. If the HMAC check fails, the proxy SHOULD send a 403 (Forbidden).
Flow recovery uses exponential backoff: upper-bound wait W = min(max-time, base-time × 2^consecutive-failures). If all flows have failed, base-time defaults to 30s; if at least one flow is active, base-time defaults to 90s; max-time defaults to 1800s. The actual retry delay is a uniform random value between 50% and 100% of W.
STUN Binding Requests used for keep-alives require no STUN attributes; corresponding Binding Responses MUST include the XOR-MAPPED-ADDRESS attribute. STUN packets are distinguished from SIP on UDP because the first octet of a STUN Binding method is 0 or 1, while SIP first octets are never 0 or 1.
The CRLF keep-alive ping is a double-CRLF sequence (CR LF CR LF, 4 octets); the pong is a single CRLF (CR LF, 2 octets). These sequences must be sent between SIP messages and not in the middle of a SIP message; when sent over TLS or SigComp they are inside those channels.