Skip to content
SIP Mastery

Part 3 · SIP mechanics / Module 08

Transactions

How SIP delivers one request and its responses reliably over an unreliable network — the branch that names a transaction, four state machines, the timers that drive retransmissions, and why the ACK for a 2xx is different.

IntermediateAdvancedNOC optionalDEV coredraft

After this module, you can

  • Say what a transaction is, and which elements keep transaction state.
  • Match a request or a response to its transaction with the Via branch, the sent-by, and the method.
  • Follow the INVITE and non-INVITE state machines, on the client side and on the server side.
  • Calculate when a request or response is retransmitted over UDP, and when the attempt times out.
  • Explain why the ACK for a 300–699 response is hop by hop, and the ACK for a 2xx is end to end.
  • Explain the "32-second drop" and find its cause in a trace.

8.1 A transaction: one request and all its responses

SIP does its work in small exchanges. Each exchange is a transaction:

RFC 3261 §17 · Transactions
“Specifically, a SIP transaction consists of a single request and any responses to that request, which include zero or more provisional responses and one or more final responses.”
Read the section ↗

A transaction has two sides. The client transaction sends the request and receives the responses. The server transaction receives the request and sends the responses. Above each side sits the transaction user (TU): the UA core in a phone, or the proxy core in a stateful proxy. The TU decides what to send; the transaction makes sure it arrives.

Transactions exist hop by hop. In a call from Alice through Proxy B to Bob, there are two INVITE transactions: Alice’s client transaction with Proxy B’s server transaction, and Proxy B’s client transaction with Bob’s server transaction. A stateless proxy is not part of either:

RFC 3261 §17 · Transactions
“A stateless proxy does not contain a client or server transaction.”
Read the section ↗
Transaction Dialog (Module 9)
What it is One request and its responses A relationship between two UAs, made of many transactions
Named by The top Via branch (and the method) Call-ID + From tag + To tag
Lives Seconds Minutes or hours — as long as the call
Exists at Each hop: UAs and stateful proxies Only the two UAs (and B2BUAs)

8.2 How elements match a transaction

Every request carries a branch in its top Via. The branch names the transaction, so it must be new for every new request:

RFC 3261 §8.1.1.7 · Via
“The branch parameter value MUST be unique across space and time for all requests sent by the UA. The exceptions to this rule are CANCEL and ACK for non-2xx responses.”
Read the section ↗

The branch starts with the magic cookie z9hG4bK. The cookie tells the receiver that the sender follows RFC 3261, so the branch is unique and can be used as the key:

RFC 3261 §8.1.1.7 · Via
“The branch ID inserted by an element compliant with this specification MUST always begin with the characters "z9hG4bK".”
Read the section ↗
RFC 3261 §17.2.3 · Matching Requests to Server Transactions
“If it is present and begins with the magic cookie "z9hG4bK", the request was generated by a client transaction compliant to this specification.”
Read the section ↗

The two sides match differently:

Receiver Compares Why
Server (a request arrives) Top Via branch, top Via sent-by, method Sent-by, because another client could pick the same branch. Method, so that a CANCEL with the same branch is not taken for the INVITE.
Client (a response arrives) Top Via branch, CSeq method The CSeq method separates the response to a CANCEL from the response to the INVITE it cancels.

There is one exception for the method: an ACK matches the INVITE transaction it acknowledges.

RFC 3261 §17.2.3 · Matching Requests to Server Transactions
“the method of the request matches the one that created the transaction, except for ACK, where the method of the request that created the transaction is INVITE.”
Read the section ↗
RFC 3261 §17.1.3 · Matching Responses to Client Transactions
“The method is needed since a CANCEL request constitutes a different transaction, but shares the same value of the branch parameter.”
Read the section ↗

Pick a message below and watch Bob — or Alice — look for its transaction.

Transaction matcher

Which transaction does this message belong to?

Arriving message

Via: SIP/2.0/UDP 192.0.2.10:5060;branch=z9hG4bK74bf9
CSeq: 1 INVITE
Bob’s open server transactions
TransactionBranchSent-byMethodResult
INVITEz9hG4bK74bf9 · 192.0.2.10:5060Proceeding (ringing)✓✓✓match
OPTIONSz9hG4bK1c33 · 198.51.100.10:5060Completed✗✗✗—

Matches the INVITE transaction

A retransmission. Bob sends the last provisional response (180) again. The TU does not see the copy.

8.3 Four state machines

RFC 3261 defines a state machine for each side of each kind of transaction. INVITE is different because a person must answer it: it can take many seconds, so it uses a three-way handshake (INVITE, final response, ACK). Every other method is a quick two-way exchange.

Machine States
INVITE client Calling → Proceeding → Completed → Terminated
INVITE server Proceeding → Completed → Confirmed → Terminated
Non-INVITE client Trying → Proceeding → Completed → Terminated
Non-INVITE server Trying → Proceeding → Completed → Terminated

The player shows one hop: Alice’s client transaction on the left, Bob’s server transaction on the right, and the messages between them. Step through the call, then press Lose this… on any message and watch the timers take over.

Transaction player

One hop: two state machines and their timers

  • SIP
  • Failure response
  • ✕Lost
  • Current state

Alice · INVITE client transaction

1xx300–699300–699Timer DTimer B2xx2xxTimer MCallingStays in Calling: Timer A: send again↻ProceedingStays in Proceeding: 1xx: pass to TU↻CompletedStays in Completed: copy of 300–699: ACK again↻TerminatedAcceptedStays in Accepted: 2xx: pass to TU↻
  • Timer A fires at 0.5 s in 0.5 s
  • Timer B fires at 32 s in 32 s
Aliceclient transactionBobserver transaction0 sINVITE0 s100 Trying1 s180 Ringing4 s486 Busy Here4 sACK9 sTimer I fires36 sTimer D fires

Bob · INVITE server transaction

300–699ACKTimer ITimer H2xxTimer LProceedingStays in Proceeding: INVITE again: send 1xx again↻CompletedStays in Completed: Timer G: send again↻ConfirmedStays in Confirmed: ACK again: absorb↻TerminatedAcceptedStays in Accepted: INVITE again: absorb↻
  • No timer runs.
0 s
1/7

Alice's TU starts an INVITE client transaction (Calling). Timer A (0.5 s) and Timer B (32 s) start. Bob creates a server transaction (Proceeding) and passes the INVITE to the TU.

Alicenew → Calling on INVITE from TU

Bobnew → Proceeding on request

Things to try:

  • INVITE, 486, lose the 486. Timer G sends it again after 500 ms; Alice’s transaction, already waiting in Completed, ACKs the copy.
  • INVITE, Bob is down, UDP. Seven INVITEs, then Timer B ends the attempt at 32 s. Switch to TCP: the connection fails at once.
  • OPTIONS, answers after 6 s. Bob sends 100 Trying at 3.5 s, and Alice’s retransmissions slow down to one every 4 s.
  • INVITE, 200 OK, every ACK lost. The 32-second drop — see Common mistakes below.

8.4 Timers

All the timers grow from three values:

Value Default Meaning
T1 500 ms Estimate of the round-trip time
T2 4 s Longest interval between retransmissions of a non-INVITE request or an INVITE response
T4 5 s Longest time a message stays in the network
RFC 3261 §17.1.1.1 · Overview of INVITE Transaction
“T1 is an estimate of the round-trip time (RTT), and it defaults to 500 ms.”
Read the section ↗

Retransmit timers start at T1 and double. For an INVITE, there is no cap:

RFC 3261 §17.1.1.2 · Formal Description
“When timer A fires, the client transaction MUST retransmit the request by passing it to the transport layer, and MUST reset the timer with a value of 2*T1.”
Read the section ↗

For everything else, the interval stops growing at T2:

RFC 3261 §17.1.2.2 · Formal Description
“For the default values of T1 and T2, this results in intervals of 500 ms, 1 s, 2 s, 4 s, 4 s, 4 s, etc.”
Read the section ↗

Timeout timers are 64×T1 — 32 seconds by default:

RFC 3261 §17.1.1.2 · Formal Description
“The value of 64*T1 is equal to the amount of time required to send seven requests in the case of an unreliable transport.”
Read the section ↗
Timer Side Value Job
A INVITE client T1, doubling Send the INVITE again (UDP)
B INVITE client 64×T1 Give up: no response
D INVITE client ≥ 32 s UDP, 0 TCP Absorb copies of the 300–699 response
E Non-INVITE client T1, doubling to T2 Send the request again (UDP)
F Non-INVITE client 64×T1 Give up: no final response
G INVITE server T1, doubling to T2 Send the 300–699 response again (UDP)
H INVITE server 64×T1 Give up: no ACK
I INVITE server T4 UDP, 0 TCP Absorb copies of the ACK
J Non-INVITE server 64×T1 UDP, 0 TCP Answer copies of the request
K Non-INVITE client T4 UDP, 0 TCP Absorb copies of the response
L, M INVITE server, client 64×T1 Stay in Accepted after a 2xx (RFC 6026, §8.8)

Timer C is a proxy timer: a stateful proxy uses it to give up on an INVITE branch that has no final response after more than 3 minutes.

RFC 3261 §17.1.1.2 · Formal Description
“The client transaction SHOULD start timer D when it enters the "Completed" state, with a value of at least 32 seconds for unreliable transports, and a value of zero seconds for reliable transports.”
Read the section ↗

Change T1 below and see every schedule stretch with it. A larger T1 suits slow links, such as satellite; the RFC allows it.

Timer timeline

T1 doubles; 64×T1 (32 s) ends the attempt

  • First send
  • Retransmission
  • Timeout

Timer A starts at T1 and doubles each time, with no cap. A 1xx response stops it.

  1. 0 s
  2. 0.5 s+0.5 s
  3. 1.5 s+1 s
  4. 3.5 s+2 s
  5. 7.5 s+4 s
  6. 15.5 s+8 s
  7. 31.5 s+16 s
  8. 32 sTimer B: timeout

After the final response: the waiting timers

TimerValue (UDP)StateWhy it waits
Timer D32 sINVITE client, Completedabsorbs copies of the 300–699
Timer I5 sINVITE server, Confirmedabsorbs copies of the ACK
Timer J32 sNon-INVITE server, Completedanswers copies of the request
Timer K5 sNon-INVITE client, Completedabsorbs copies of the response

8.5 Retransmissions: UDP only

UDP gives no delivery guarantee, so the transaction layer retransmits. TCP and TLS deliver every byte or report an error, so the transaction layer does not:

RFC 3261 §17.1.1.1 · Overview of INVITE Transaction
“The request is not retransmitted over reliable transports.”
Read the section ↗

A retransmission is a byte-for-byte copy: same branch, same CSeq, same everything. The receiver’s transaction absorbs it, and may answer with the last response it sent. The 100 Trying exists mainly to stop INVITE retransmissions early:

RFC 3261 §17.2.1 · INVITE Server Transaction
“This provisional response is needed to quench request retransmissions rapidly in order to avoid network congestion.”
Read the section ↗

Call flow · retransmissions over UDP

Retransmissions over UDP

  • SIP
Alice192.0.2.10Bob203.0.113.2001✕INVITE02INVITE (again)03100 Trying04180 Ringing05✕486 Busy Here06486 Busy Here (again)07ACK
01/07

Alice sends the INVITE over UDP and starts Timer A (500 ms). The network loses the INVITE.

All steps as text
  1. Alice → Bob: INVITE. Alice sends the INVITE over UDP and starts Timer A (500 ms). The network loses the INVITE.
  2. Alice → Bob: INVITE (again). Timer A fires. Alice sends the same INVITE again: same branch, same CSeq, same bytes.
  3. Bob → Alice: 100 Trying. Bob answers 100 Trying at once. Alice stops sending the INVITE.
  4. Bob → Alice: 180 Ringing. Bob's phone rings. The To header now has Bob's tag.
  5. Bob → Alice: 486 Busy Here. Bob rejects the call and starts Timer G (500 ms). The network loses the 486.
  6. Bob → Alice: 486 Busy Here (again). Timer G fires. Bob sends the same 486 again.
  7. Alice → Bob: ACK. Alice ACKs the 486 with the branch of the INVITE. Bob stops sending the 486.

8.6 ACK for a non-2xx and ACK for a 2xx

The ACK comes in two kinds, and they behave very differently:

RFC 3261 §17 · Transactions
“In the case of a transaction where the request was an INVITE (known as an INVITE transaction), the transaction also includes the ACK only if the final response was not a 2xx response. If the response was a 2xx, the ACK is not considered part of the transaction.”
Read the section ↗
ACK for 300–699 ACK for 2xx
Part of The INVITE transaction Its own transaction
Sent by The client transaction The UA core of the caller
Branch Same as the INVITE New
Travels One hop: each stateful proxy ACKs on its own hop End to end, to the callee’s Contact, through the route set
Response retransmitted by The server transaction (Timer G) The UA core of the callee
RFC 3261 §17.1.1.3 · Construction of the ACK Request
“The ACK MUST contain a single Via header field, and this MUST be equal to the top Via header field of the original request. The CSeq header field in the ACK MUST contain the same value for the sequence number as was present in the original request, but the method parameter MUST be equal to "ACK".”
Read the section ↗
RFC 3261 §13.2.2.4 · 2xx Responses
“The UAC core MUST generate an ACK request for each 2xx received from the transaction layer.”
Read the section ↗

Why the difference? A forked INVITE can be answered by several phones, and the caller must see — and ACK — every 2xx. So proxies forward each 2xx, and the 2xx and its ACK travel between the two UAs. The callee’s UA core sends the 2xx again until the ACK arrives, even over TCP, because a later hop may be UDP:

RFC 3261 §13.3.1.4 · The INVITE is Accepted
“The 2xx response is passed to the transport with an interval that starts at T1 seconds and doubles for each retransmission until it reaches T2 seconds (T1 and T2 are defined in Section 17).”
Read the section ↗

ACK for 486: hop by hop

ACK for a 486: hop by hop

  • SIP
Alice192.0.2.10Proxy B203.0.113.10Bob203.0.113.2001INVITE02100 Trying03INVITE04180 Ringing05180 Ringing06486 Busy Here07ACK08486 Busy Here09ACK
01/09

Alice sends the INVITE to Proxy B. Her branch is z9hG4bK776asdhds.

All steps as text
  1. Alice → Proxy B: INVITE. Alice sends the INVITE to Proxy B. Her branch is z9hG4bK776asdhds.
  2. Proxy B → Alice: 100 Trying. Proxy B answers 100 Trying on this hop.
  3. Proxy B → Bob: INVITE. Proxy B forwards the INVITE. It adds its own Via, with its own branch.
  4. Bob → Proxy B: 180 Ringing. Bob's phone rings.
  5. Proxy B → Alice: 180 Ringing. Proxy B removes its Via and forwards the 180.
  6. Bob → Proxy B: 486 Busy Here. Bob rejects the call with 486.
  7. Proxy B → Bob: ACK. Proxy B ACKs the 486 itself, with the branch of its INVITE. Bob's transaction ends.
  8. Proxy B → Alice: 486 Busy Here. Proxy B forwards the 486 to Alice.
  9. Alice → Proxy B: ACK. Alice ACKs the 486 on her hop, with her own INVITE branch. Proxy B does not forward this ACK.

8.7 CANCEL: its own transaction, aimed at another

A CANCEL copies the top Via of the INVITE it cancels — with the same branch — so each hop can find that INVITE:

RFC 3261 §9.1 · Client Behavior
“A CANCEL constructed by a client MUST have only a single Via header field value matching the top Via value in the request being cancelled.”
Read the section ↗

But its CSeq method is CANCEL, so it is a transaction of its own, with its own 200 OK:

RFC 3261 §9.1 · Client Behavior
“However, the method part of the CSeq header field MUST have a value of CANCEL. This allows it to be identified and processed as a transaction in its own right (See Section 17).”
Read the section ↗

The result is two transactions on each hop: the CANCEL transaction, answered 200 OK, and the INVITE transaction, which ends with 487 Request Terminated and its ACK. Like the ACK for a non-2xx, a CANCEL is hop by hop: each proxy answers it and sends its own CANCEL downstream.

Call flow · CANCEL, hop by hop

Alice hangs up while Bob's phone rings

  • SIP
Alice192.0.2.10Proxy B203.0.113.10Bob203.0.113.2001INVITE02100 Trying03INVITE04180 Ringing05180 Ringing06CANCEL07200 OK (CANCEL)08CANCEL09200 OK (CANCEL)10487 Request Terminated11ACK12487 Request Terminated13ACK
01/13

Alice's phone calls Bob through Proxy B.

All steps as text
  1. Alice → Proxy B: INVITE. Alice's phone calls Bob through Proxy B.
  2. Proxy B → Alice: 100 Trying. Proxy B answers 100 Trying. It keeps state for the INVITE transaction.
  3. Proxy B → Bob: INVITE. Proxy B forwards the INVITE to Bob's phone.
  4. Bob → Proxy B: 180 Ringing. Bob's phone rings.
  5. Proxy B → Alice: 180 Ringing. Alice hears the ringback tone.
  6. Alice → Proxy B: CANCEL. Alice hangs up before Bob answers. The CANCEL copies the Request-URI, Call-ID, From, To, and branch of the INVITE.
  7. Proxy B → Alice: 200 OK (CANCEL). Proxy B answers the CANCEL itself. CANCEL is hop-by-hop.
  8. Proxy B → Bob: CANCEL. Proxy B sends its own CANCEL on its own hop, with the branch of its own INVITE.
  9. Bob → Proxy B: 200 OK (CANCEL). Bob's phone stops ringing and answers the CANCEL.
  10. Bob → Proxy B: 487 Request Terminated. Bob's phone ends the INVITE transaction with 487.
  11. Proxy B → Bob: ACK. Proxy B confirms the 487 on its hop. This ACK reuses the branch of the INVITE.
  12. Proxy B → Alice: 487 Request Terminated. Proxy B forwards the 487 to Alice's phone.
  13. Alice → Proxy B: ACK. Alice's phone confirms the 487. The call never started.

8.8 Later fixes: RFC 6026 and RFC 4320

Field experience found two problems in the RFC 3261 machines.

RFC 6026: the Accepted state. In RFC 3261, an INVITE transaction ends the moment it sends or receives a 2xx. A late copy of the INVITE then matches nothing, and a proxy may treat it as a new call:

RFC 6026 §3 · Reason for Change
“Once any element with a server transaction (say, a proxy in the path of the INVITE) deletes that transaction state, any retransmission of the INVITE will be treated as a new request, potentially forwarded to different locations than the original.”
Read the section ↗

RFC 6026 adds an Accepted state on both sides. The transaction stays there for 64×T1 (Timer L on the server, Timer M on the client), absorbs INVITE copies, and passes each 2xx and ACK to the TU:

RFC 6026 §7.1 · Server Transaction Impacts
“To allow a SIP element to recognize retransmissions of an INVITE as retransmissions instead of new requests, a new state, "Accepted", is added to the INVITE server transaction state machine.”
Read the section ↗

It also stops proxies from forwarding stray responses — responses that match no transaction — which attackers could use to bounce traffic:

RFC 6026 §7.3 · Proxy Considerations
“The proxy MUST NOT forward the response if there is no matching transaction state machine.”
Read the section ↗

Switch the RFC 6026 box in the player above on and off to compare the two machines.

RFC 4320: non-INVITE fixes. A non-INVITE transaction must finish quickly, so RFC 4320 removes two kinds of useless messages. Only 100 is allowed as a provisional response — and over UDP, only after Timer E has grown to T2:

RFC 4320 §4.1 · Action 1
“An SIP element MUST NOT send any provisional response with a Status-Code other than 100 to a non-INVITE request.”
Read the section ↗

And a late 408 is pointless, because the client has already timed out:

RFC 4320 §4.2 · Action 2
“A transaction-stateful SIP element MUST NOT send a response with Status-Code of 408 to a non-INVITE request.”
Read the section ↗

Common mistakes

The 32-second drop

The call connects, both sides talk, and after about 32 seconds the call ends — every time. The 200 OK arrived, but the ACK never reached the callee. The callee’s UA core sends the 200 OK again for 64×T1 and then gives up with BYE.

RFC 3261 §13.3.1.4 · The INVITE is Accepted
“If the server retransmits the 2xx response for 64*T1 seconds without receiving an ACK, the dialog is confirmed, but the session SHOULD be terminated.”
Read the section ↗

The usual cause: the ACK follows the Contact of the 2xx, and that Contact is wrong — a private address behind NAT — while no proxy record-routes to carry the ACK. In a trace, look for repeated 200 OKs, and check where each ACK goes.

Broken

Broken: the ACK never reaches Bob

  • SIP
  • ⚠Problem
Alice192.0.2.10Proxy B203.0.113.10Bob10.0.0.20 · NAT01INVITE02100 Trying03INVITE04180 Ringing05180 Ringing06200 OK07200 OK08✕ACK⚠09200 OK (again)10200 OK (again)11✕ACK (again)12BYE⚠13200 OK
01/13

Alice sends the INVITE to Proxy B.

All steps as text
  1. Alice → Proxy B: INVITE. Alice sends the INVITE to Proxy B.
  2. Proxy B → Alice: 100 Trying. Proxy B answers 100 Trying on this hop.
  3. Proxy B → Bob: INVITE. Proxy B forwards the INVITE to Bob through the NAT router. It does not add Record-Route.
  4. Bob → Proxy B: 180 Ringing. Bob's phone rings. Its Contact is a private address: 10.0.0.20.
  5. Proxy B → Alice: 180 Ringing. Proxy B forwards the 180 with the private Contact.
  6. Bob → Proxy B: 200 OK. Bob answers. Bob's UA core starts to send the 200 OK again until an ACK arrives.
  7. Proxy B → Alice: 200 OK. Proxy B forwards the 200 OK. The route set is empty: no Record-Route.
  8. Alice → Bob: ACK. Alice sends the ACK straight to the Contact, 10.0.0.20. That address is private, so the ACK never arrives. Problem: The ACK goes to a private address. No router on the Internet can deliver it.
  9. Bob → Proxy B: 200 OK (again). No ACK after 500 ms. Bob's phone sends the 200 OK again, and again, up to 32 seconds.
  10. Proxy B → Alice: 200 OK (again). Proxy B forwards each copy.
  11. Alice → Bob: ACK (again). Alice ACKs each copy. Every ACK goes to the same private address.
  12. Bob → Alice: BYE. After 64×T1 (32 seconds) with no ACK, Bob's phone ends the call with BYE. Problem: The call drops 32 seconds after the answer, every time.
  13. Alice → Bob: 200 OK. Alice answers the BYE. The NAT router lets this response through to Bob.

A new branch on the ACK for a non-2xx

The ACK for a 300–699 response belongs to the INVITE transaction, so it must reuse the INVITE’s branch. With a new branch, the server cannot match it: it keeps sending the response until Timer H, and may report a failure.

Broken

Broken: ACK for the 407 with a new branch

  • SIP
  • ⚠Problem
Alice192.0.2.10Proxy A198.51.100.1001INVITE02407 Proxy Auth Required03ACK (new branch)⚠04INVITE (credentials)05100 Trying06407 (retransmission)⚠07ACK (new branch)⚠
01/07

Alice sends an INVITE. It has no credentials.

All steps as text
  1. Alice → Proxy A: INVITE. Alice sends an INVITE. It has no credentials.
  2. Proxy A → Alice: 407 Proxy Auth Required. Proxy A rejects the INVITE with 407 and a challenge.
  3. Alice → Proxy A: ACK (new branch). Alice sends ACK with a new branch value. Problem: The branch does not match the INVITE. Proxy A cannot match this ACK to the transaction.
  4. Alice → Proxy A: INVITE (credentials). Alice sends a new INVITE with Proxy-Authorization. CSeq is 2 and the branch is new.
  5. Proxy A → Alice: 100 Trying. Proxy A accepts the credentials and continues with the call.
  6. Proxy A → Alice: 407 (retransmission). Timer G fires, so Proxy A sends the same 407 again. Problem: Proxy A retransmits the 407 because it has no matching ACK.
  7. Alice → Proxy A: ACK (new branch). Alice ACKs the retransmitted 407 with the same wrong branch. The loop continues until Timer H fires. Problem: Proxy A never matches these ACKs, so Timer H ends the transaction with a failure.

The same branch on the ACK for a 2xx

The ACK for a 2xx is a new transaction and needs a new branch. With the INVITE’s branch, an element that still holds the INVITE transaction may match the ACK to it and absorb it, instead of passing it on. The ACK never reaches the callee — and the call drops after 32 seconds.

Remember: ACK for 300–699 → same branch as the INVITE. ACK for 2xx → new branch, built like any request in the dialog.

Counting retransmissions as new calls

A monitoring tool or a script that counts every INVITE it sees reports seven “calls” for one unanswered INVITE over UDP. Retransmissions have the same Call-ID, CSeq, and branch.

Remember: count transactions (branch + method), or calls (Call-ID), not packets.

Summary

  • A transaction is one request and its responses, between a client transaction and a server transaction on one hop. UAs and stateful proxies keep transactions; stateless proxies do not.
  • The top Via branch, starting with z9hG4bK, names the transaction. Servers also compare the sent-by and the method; clients compare the CSeq method.
  • Four state machines: INVITE and non-INVITE, client and server.
  • Over UDP, requests and responses are retransmitted at T1, 2×T1, 4×T1… (capped at T2 except for Timer A). After 64×T1 = 32 s, the attempt times out. Over TCP and TLS, the transaction layer does not retransmit.
  • The ACK for 300–699 is part of the INVITE transaction: same branch, hop by hop. The ACK for 2xx is a new transaction: new branch, end to end. A lost ACK for a 2xx ends the call after 32 seconds.
  • CANCEL shares the INVITE’s branch but is its own transaction.
  • RFC 6026 adds the Accepted state and stops stray responses; RFC 4320 removes late 408s and early provisional responses to non-INVITE requests.