Correct Transaction Handling for 2xx Responses to Session Initiation Protocol (SIP) INVITE Requests
updates
- rfc-3261 — SIP: Session Initiation Protocol
Extracted elements (28)
RFC 3261 required immediate destruction of INVITE server transaction state on forwarding a 2xx response and stateless forwarding of stray responses. Implementation experience showed this causes INVITE retransmissions to be treated as new requests, and the stateless forwarding requirement is exploitable as an anonymizing proxy for DoS attacks or non-SIP content tunneling.
The 'Accepted' state in the client transaction exists to allow the client transaction to continue receiving and passing to the TU retransmissions of the 2xx response and additional 2xx responses from other branches of a forked INVITE, distinguishing them from stray responses.
The 'Accepted' state in the server transaction absorbs INVITE retransmissions entirely within the server transaction without passing them to the TU, since downstream UAS cores that accepted the request have taken responsibility for reliability and will retransmit their 2xx responses.
Timer L is set to 64*T1 to match Timer B in the next upstream client state machine (the time the previous hop waits for a response when no provisionals have been sent) and the time a UAS core might retransmit the 2xx while waiting for an ACK.
RFC 2543 clients do not include a unique branch parameter, so the transaction ID calculation for INVITE and ACK requests will be the same. When an ACK matching an INVITE server transaction lacks the magic cookie, the 'Accepted' state must be checked and the ACK passed to the TU rather than absorbed.
The changes introduced are backward-compatible: transaction behavior will be no less correct, and possibly more correct, when only one peer in a transaction implements these changes. Deploying RFC 6026 implementations alongside RFC 3261 implementations adds no additional security concerns beyond those noted.
A server transaction MUST NOT discard transaction state based solely on encountering a non-recoverable transport error when sending a response; the state machine MUST remain in its current state, allowing timers to eventually drive it to 'Terminated'.
An element encountering an unrecoverable transport error when sending a response to an INVITE request MUST NOT immediately destroy the associated INVITE server transaction state, to ensure correct processing of retransmissions of the request.
An element sending or receiving a 2xx to an INVITE transaction MUST NOT destroy any matching INVITE transaction state, as this state is necessary for correct processing of retransmissions of the request and subsequent 2xx and ACK messages.
Any 2xx responses matching the client transaction received while in the 'Accepted' state MUST be passed up to the TU. When Timer M fires in 'Accepted', the client transaction MUST move to 'Terminated' and be destroyed immediately.
Any ACKs received from the network while the INVITE server transaction is in the 'Accepted' state MUST be passed directly to the TU and not absorbed by the state machine.
Any response received that does not match an existing client transaction state machine is simply dropped; elements other than stateless proxies MUST silently discard unmatched responses.
If a 2xx response is received while the INVITE client transaction is in the 'Calling' or 'Proceeding' states, it MUST transition to the 'Accepted' state, pass the 2xx to the TU, and set Timer M to 64*T1.
In Section 17.2.4 (transport error handling), the server transaction SHOULD inform the TU that a failure has occurred and MUST remain in the current state rather than transitioning to 'Terminated'.
The INVITE client transaction MUST NOT generate an ACK to any 2xx response on its own; ACK generation is delegated to the TU. A UAC core sends ACK via a new transaction; a proxy core forwards the 2xx upstream.
The INVITE server transaction MUST NOT generate 2xx retransmissions on its own; retransmissions are handled by the TU. Any 2xx retransmission passed from the TU to the transaction while in 'Accepted' MUST be forwarded to the transport layer.
When receiving an ACK matching an existing INVITE server transaction that lacks the RFC 3261 magic cookie branch parameter, the transaction MUST be checked for the 'Accepted' state; if in that state, the ACK must be passed directly to the TU rather than absorbed, to handle RFC 2543 clients.
When receiving any SIP response, a transaction-stateful proxy MUST compare the transaction identifier against its existing transaction state machines and MUST NOT forward the response if there is no matching transaction state machine.
When the INVITE server transaction TU issues a 2xx response while in the 'Proceeding' state, the state machine MUST transition to the 'Accepted' state and set Timer L to 64*T1.
When Timer L fires and the INVITE server transaction is in the 'Accepted' state, the machine MUST transition to 'Terminated' and MUST be destroyed immediately.
Timer L: value 64*T1, defined in Section 17.2.1. Controls the wait time in the INVITE server transaction 'Accepted' state for retransmissions of an accepted INVITE request before transitioning to 'Terminated'.
Timer M: value 64*T1, defined in Section 17.1.1. Controls the wait time in the INVITE client transaction 'Accepted' state for retransmissions of the 2xx response to an INVITE or additional 2xx responses from other branches of a forked INVITE.
The IANA SIP Parameters: Method and Response Codes registry is updated to add RFC 6026 as a co-reference for the INVITE method alongside RFC 3261.
RFC 3261 required stateless forwarding of stray 2xx responses, enabling conformant proxies to be forced to forward attacker-crafted packets to arbitrary destinations—enabling anonymizing proxies for DoS attacks and non-SIP content tunneling. This document reverses that requirement, making forwarding stray responses a spec violation.
Stateless proxies (which maintain no transaction state) remain inherently vulnerable to the stray-response abuse described in Section 3; operators can mitigate this by carefully controlling which peer elements can present traffic to a given stateless proxy.
The state machine changes cause elements to hold each accepted INVITE transaction state approximately 32 seconds longer than specified in RFC 3261 (64*T1 via Timer L/M), directly increasing the work required for state-exhaustion attacks against SIP elements.
The INVITE client transaction gains a new 'Accepted' state. A 2xx response received in 'Calling' or 'Proceeding' causes transition to 'Accepted' with Timer M set to 64*T1 and the 2xx passed to the TU. Further 2xx responses in 'Accepted' are also passed to the TU. Timer M firing causes transition to 'Terminated'.
The INVITE server transaction gains a new 'Accepted' state. Transition from 'Proceeding' to 'Accepted' occurs when the TU issues a 2xx response; Timer L is set to 64*T1. In 'Accepted', INVITE retransmissions are absorbed (not passed to TU), TU-originated 2xx retransmissions are forwarded to transport, and ACKs are passed to the TU. Timer L firing causes transition to 'Terminated'.