1.2 SIP in 60 seconds¶
[!IMPORTANT] This handbook assumes SIP literacy at the protocol level. If it's been a while, this page is the minimum vocabulary needed to follow the architecture chapters. RFC 3261 is the canonical reference; below is the operator's-eye-view.
Transactions¶
A transaction is one SIP request plus everything that replies to it: provisional responses, retransmissions, and exactly one final response. Two state machines drive it:
- INVITE transaction — three-way:
INVITE → (1xx)* → 2xx-or-failure → ACK. The ACK closes it. - Non-INVITE transaction — two-way:
REQUEST → (1xx)* → final response. No transaction-level ACK.
Identified by Via:branch + From:tag + Call-ID + CSeq. The transaction layer in Kamailio (tm, chapter 6.1) tracks every in-flight transaction in shm.
Dialogs¶
A dialog is the longer-lived peer relationship between two UAs, established by INVITE/2xx/ACK and torn down by BYE. Multiple transactions run inside one dialog: the setup INVITE, mid-dialog re-INVITEs (hold/resume, SDP renegotiation), UPDATE, REFER, the BYE.
Identified by Call-ID + From-tag + To-tag — the same triple on every in-dialog message. The dialog layer in Kamailio (dialog, chapter 6.2) sits on top of tm and ties transactions into one call.
ACK — the trickiest message in SIP¶
ACK has two different semantics depending on what it's acknowledging. This is the single most surprising thing about SIP for newcomers.
| Acknowledged response | ACK called | Hop scope | New transaction? |
|---|---|---|---|
| 2xx (success) | positive ACK | End-to-end (UAC → UAS, not proxied at the tx layer) | Yes — its own new transaction |
| 3xx–6xx (failure) | negative ACK | Hop-by-hop (within the INVITE transaction) | No — part of the INVITE transaction |
Operational consequences for a proxy:
- Positive ACK bypasses the transaction layer entirely. A proxy that wants to see it must
record_route()during the INVITE so the dialog's route set keeps the proxy on the in-dialog path; otherwise the ACK goes UAC→UAS directly. - Negative ACK is consumed locally by
tmas the closing edge of the INVITE transaction — it's how the transaction terminates cleanly without retransmission storms.
Forgetting the distinction is how proxies end up "losing" 2xx-ACKs and breaking in-dialog routing.
Role of a proxy¶
A SIP proxy is a forwarder — receives requests, makes routing decisions, sends them along. RFC 3261 distinguishes:
- Stateless proxy — receives, decides, forwards. No state retained, no retransmission handling. Cheap and fast, but can't fork or recover failed branches.
- Stateful proxy — creates a transaction per forwarded request. Tracks branches, handles retransmission, can fork, can run
failure_route, can intercept replies. Almost all production deployments.
What a proxy does not do (this is the line separating a proxy from a B2BUA):
- Originate dialogs on its own.
- Terminate dialogs by issuing its own BYE.
- Rewrite
Call-ID, tags, or other dialog identifiers. - Generate replies on behalf of the UAS (narrow exceptions like
100 Trying).
Kamailio is a proxy. Out of the box it stays inside the proxy contract. Modules like uac and topos blur the line when configured — knowing when you've crossed it is on you.
Where these concepts surface in the handbook¶
| Concept | Where |
|---|---|
| Transaction state in shm | 6.1 Transactions (tm) |
| Retransmission timers and timer wheels | 6.1 |
| Dialog state machine | 6.2 Dialogs |
| Reply matching to transactions | 3.5 Forwarding and replies |
| Stateless vs stateful forwarding | 3.5, 2.5 Sizing |
| Forking / branches | 3.5 |
| Proxy-vs-B2BUA boundary | 8.1 Topology hiding, this chapter |
← Table of contents · ← 1.1 Introduction · Next: 2.1 Process model →