Indication of Support for Keep-Alive
Extracted elements (25)
Keep-alive negotiation is per-direction: willingness to receive keep-alives from an adjacent entity does not imply willingness to send them. This requires each direction to be independently negotiated, avoiding unintended asymmetric keep-alive flows.
RFC 5626 (SIP Outbound) defines keep-alive mechanisms but does not provide explicit negotiation for all cases: dialog-initiated outbound flows, entities that don't support Outbound, and non-registered UAs (e.g., emergency calls) all lack implicit negotiation. The "keep" parameter fills this gap and also extends negotiation beyond the UA-to-edge-proxy scope enforced by Outbound.
The Flow-Timer header field from SIP Outbound only travels between a UA and an edge proxy, so a single Flow-Timer value cannot carry different recommended frequencies for different hops. The "keep" parameter solves this by embedding the recommended frequency per-hop in the Via header field.
The "keep" parameter value is placed in the Via header of responses (not requests) by the receiving entity, because responses travel back hop-by-hop along the same path, ensuring the frequency recommendation reaches the correct sender without being seen by other nodes.
The specification explicitly does not forbid sending double-CRLF keep-alives to an entity even without negotiation, because many SIP entities already do so. However, the "keep" parameter remains necessary so the adjacent entity knows keep-alives are supported and does not fall back to short registration refresh intervals to maintain NAT bindings.
If an INVITE is used for keep-alive negotiation, at least one provisional or final response containing a "keep" parameter with a value constitutes confirmation that the downstream entity is willing to receive keep-alives. Multiple responses to the same INVITE must carry identical parameter values.
This specification does not define a connection reuse mechanism. Entities that want to reuse connections MUST use a separate mechanism (e.g., RFC 5923 "alias" parameter) alongside the "keep" parameter, as the keep-alive mechanism only negotiates keep-alive sending/receiving and does not address the security aspects of connection reuse.
A SIP entity MUST NOT indicate willingness to send (or receive) keep-alives associated with a dialog unless it has also inserted itself in the dialog route set.
A SIP entity MUST NOT insert a "keep" parameter in the topmost Via header field of an ACK request because ACK has no associated response and thus cannot complete the negotiation; such parameters MUST be ignored if received.
A SIP proxy MUST NOT place a value into the "keep" parameter of the topmost Via header field of a request it receives before forwarding it. A proxy SHOULD remove any "keep" parameter values in Via header fields below the topmost one in responses before forwarding them.
If a SIP entity receives a "keep" parameter with a non-zero value, it MUST use the procedures defined for the Flow-Timer header field (RFC 5626), sending keep-alives at least as often as the recommended frequency, randomly distributed between 80% and 100% of that value.
If a SIP entity that adds a "keep" parameter value also inserts a Flow-Timer header field in the same message, the Flow-Timer header field value and the "keep" parameter value MUST be identical.
Once keep-alives associated with a dialog have been negotiated, they MUST be sent for the lifetime of the dialog until it is terminated. Re-negotiation of dialog keep-alives is not possible.
Once keep-alives for a dialog have been negotiated, the SIP entity MUST NOT insert a "keep" parameter in any subsequent SIP requests associated with that dialog towards that adjacent entity; such parameters MUST be ignored if received.
When a SIP entity is willing to receive keep-alives, it MUST add a parameter value to the "keep" parameter before sending or forwarding the response. For INVITE, it MUST add a value in at least one reliable response, MUST NOT add different values across multiple responses to the same request, and SHOULD indicate willingness as soon as possible.
When a SIP entity sends STUN keep-alives and does not receive a STUN response (per RFC 5389 Section 7.2.1), it MUST stop sending keep-alives for the remaining dialog duration, or until keep-alives are re-negotiated for the registration.
When a SIP entity wants to negotiate the sending of keep-alives associated with a registration or dialog, it MUST insert a "keep" parameter in the topmost Via header field that it adds to the request.
When a subsequent registration refresh request is sent, if the SIP entity wishes to continue sending keep-alives, usage MUST be re-negotiated. If not successfully re-negotiated, the SIP entity MUST cease sending keep-alives associated with the registration.
When the SIP entity receives the associated response and the topmost Via header field contains a "keep" parameter value, it MUST start sending keep-alives towards the same destination used for subsequent requests associated with the registration or dialog.
The "keep" Via header field parameter allows adjacent SIP entities to explicitly negotiate NAT keep-alive usage. Inserted in the topmost Via of a request to indicate willingness to send keep-alives; a parameter value is added in the response to indicate willingness to receive them.
IANA registered the "keep" parameter in the "Header Field Parameters and Parameter Values" sub-registry (created by RFC 3968) for the Via header field, with no predefined values.
A malicious downstream SIP entity can insert or modify "keep" parameter values in non-topmost Via header fields of forwarded responses. A proxy that blindly forwards responses without inspecting the new topmost Via after stripping its own entry may unexpectedly start receiving STUN requests. Proxies should remove "keep" values from non-topmost Via fields before forwarding.
Without hop-by-hop integrity protection (e.g., TLS or DTLS), a man-in-the-middle can modify Via header fields to suppress keep-alive negotiation or set an artificially low frequency value, causing excessive resource consumption from frequent keep-alives.
Keep-alive negotiation for a registration: idle → negotiated (on REGISTER with "keep" response bearing a value) → active (sending keep-alives) → terminated (on registration expiry or refresh without re-negotiation). For a dialog: idle → negotiated (on initial INVITE or mid-dialog request with "keep" value in response) → active for dialog lifetime → terminated on BYE.
The "keep" parameter extends the SIP Via header ABNF as: `keep = "keep" [ EQUAL 1*(DIGIT) ]`. The optional numeric value represents the recommended keep-alive frequency in seconds. A value of zero means no recommended frequency.