Skip to content
SIP Mastery

Part 2 · The SIP language / Module 07

Headers and parameters

The headers you meet in every trace — the mandatory six, tags, Via and Contact parameters, routing, identity and privacy, redirect history, and session timers — and which element adds, changes, or removes each one.

IntermediateNOC coreDEV coredraft

After this module, you can

  • Name the headers that every request must carry, and say what each one does.
  • Explain From and To tags, and why a dialog needs both.
  • Read the Via, Contact, and URI parameters you meet in traces.
  • Tell P-Asserted-Identity from From, and explain how Privacy hides it.
  • Read History-Info and Diversion to see why a call was forwarded.
  • Explain how Session-Expires and Min-SE keep a call alive, and end a dead one.

7.1 The headers in every request

Six headers are the minimum for any request; an INVITE also needs Contact.

RFC 3261 §8.1.1 · Generating the Request
“A valid SIP request formulated by a UAC MUST, at a minimum, contain the following header fields: To, From, CSeq, Call-ID, Max-Forwards, and Via; all of these header fields are mandatory in all SIP requests.”
Read the section ↗
Header Job Changes on the way?
Via The path back for responses; the top branch names the transaction Each hop adds one; the next hop may add received and rport
Max-Forwards Stops loops Each proxy subtracts 1
From The sender, and the sender’s tag No (a B2BUA writes a new one)
To The target, and the other side’s tag The UAS adds its tag
Call-ID Groups the messages of one call or one registration No (a B2BUA writes a new one)
CSeq Orders the requests from one side, and names the method +1 for each new request from that side
Contact (INVITE) Where to send the next requests in the dialog Rewritten by SBCs and NAT fixes
RFC 3261 §8.1.1.6 · Max-Forwards
“It consists of an integer that is decremented by one at each hop. If the Max-Forwards value reaches 0 before the request reaches its destination, it will be rejected with a 483(Too Many Hops) error response.”
Read the section ↗

The header reference below covers these and about forty more. Search for a header, or pick a group, to see who adds, changes, and removes it.

Header reference

47 headers: what they mean, who touches them

  • +Adds
  • ~Changes
  • −Removes

Every request

Routing

Identity and privacy

Authentication

Capabilities

Body

Session and timers

Events and transfer

Information

Viacompact: v

Every requestin every request

Records the path of the request. Responses follow the Via headers back, and the top branch identifies the transaction.

Adds
Every element that sends or forwards a request, at the top
Changes
The next hop adds received and rport
Removes
Each element removes its own Via from the response
Via: SIP/2.0/UDP 192.0.2.10:5060;branch=z9hG4bK74bf9;rport
RFC 3261 §20.42 ↗

Watch the headers travel

Here is one INVITE on its way from Alice’s phone, behind a NAT router, through Proxy A, an SBC, and Proxy B to Bob’s phone. Each column is one hop; each marked cell is a change at that hop. Turn on Show only the headers that change to see what each element does.

Header journey

One INVITE, four hops: what each element changes

  • +Added here
  • ~Changed here
  • −Removed here
HeaderHop 1Alice → Proxy AHop 2Proxy A → SBCHop 3SBC → Proxy BHop 4Proxy B → Bob
sip:bob@biloxi.examplesip:bob@biloxi.examplesip:bob@biloxi.example~sip:bob@203.0.113.20:5060
SIP/2.0/UDP 192.168.1.20:5060;branch=z9hG4bK74bf9;rport~SIP/2.0/UDP 198.51.100.10:5060;branch=z9hG4bKpa4790
SIP/2.0/UDP 192.168.1.20:5060;branch=z9hG4bK74bf9;received=192.0.2.10;rport=40112
~SIP/2.0/UDP 198.51.100.200:5060;branch=z9hG4bK-sbc-5b2e~SIP/2.0/UDP 203.0.113.10:5060;branch=z9hG4bKpb721e
SIP/2.0/UDP 198.51.100.200:5060;branch=z9hG4bK-sbc-5b2e
70~69~68~67
Alice <sip:alice@atlanta.example>;tag=9fxced76slAlice <sip:alice@atlanta.example>;tag=9fxced76sl~Alice <sip:alice@atlanta.example>;tag=sbc-3c9d0fAlice <sip:alice@atlanta.example>;tag=sbc-3c9d0f
Bob <sip:bob@biloxi.example>Bob <sip:bob@biloxi.example>Bob <sip:bob@biloxi.example>Bob <sip:bob@biloxi.example>
3848276298220188511@192.168.1.203848276298220188511@192.168.1.20~9e7d6c5b4a21@198.51.100.2009e7d6c5b4a21@198.51.100.200
1 INVITE1 INVITE1 INVITE1 INVITE
<sip:alice@192.168.1.20:5060><sip:alice@192.168.1.20:5060>~<sip:alice@198.51.100.200:5060><sip:alice@198.51.100.200:5060>
<tel:+14045550101>−removed——
timer, 100reltimer, 100reltimer, 100reltimer, 100rel
180018001800~900
90909090
INVITE, ACK, CANCEL, BYE, OPTIONS, UPDATE, REFERINVITE, ACK, CANCEL, BYE, OPTIONS, UPDATE, REFERINVITE, ACK, CANCEL, BYE, OPTIONS, UPDATE, REFERINVITE, ACK, CANCEL, BYE, OPTIONS, UPDATE, REFER
Linphone/5.2Linphone/5.2−removed—
application/sdpapplication/sdpapplication/sdpapplication/sdp
162162~158158
alice 2890844526 2890844526 IN IP4 192.168.1.20alice 2890844526 2890844526 IN IP4 192.168.1.20~sbc 1700000 1700000 IN IP4 198.51.100.200sbc 1700000 1700000 IN IP4 198.51.100.200
IN IP4 192.168.1.20IN IP4 192.168.1.20~IN IP4 198.51.100.200IN IP4 198.51.100.200
—+<sip:proxy.atlanta.example;lr>−removed+<sip:proxy.biloxi.example;lr>
—+"Alice" <sip:alice@atlanta.example>, <tel:+14045550101>"Alice" <sip:alice@atlanta.example>, <tel:+14045550101>"Alice" <sip:alice@atlanta.example>, <tel:+14045550101>

Via

Records the path of the request. Responses follow the Via headers back, and the top branch identifies the transaction. RFC 3261 §20.42 ↗

  1. Alice → Proxy AunchangedSIP/2.0/UDP 192.168.1.20:5060;branch=z9hG4bK74bf9;rport
  2. Proxy A → SBCchangedSIP/2.0/UDP 198.51.100.10:5060;branch=z9hG4bKpa4790 SIP/2.0/UDP 192.168.1.20:5060;branch=z9hG4bK74bf9;received=192.0.2.10;rport=40112
  3. SBC → Proxy BchangedSIP/2.0/UDP 198.51.100.200:5060;branch=z9hG4bK-sbc-5b2e
  4. Proxy B → BobchangedSIP/2.0/UDP 203.0.113.10:5060;branch=z9hG4bKpb721e SIP/2.0/UDP 198.51.100.200:5060;branch=z9hG4bK-sbc-5b2e

Call flow · the same INVITE, hop by hop

One INVITE, four hops

  • SIP
Alice192.168.1.20Proxy A198.51.100.10SBC198.51.100.200Proxy B203.0.113.10Bob203.0.113.2001INVITE02INVITE03INVITE (outer side)04INVITE
01/04

Alice's phone builds the INVITE behind a NAT router. It asks for its phone number as identity.

All steps as text
  1. Alice → Proxy A: INVITE. Alice's phone builds the INVITE behind a NAT router. It asks for its phone number as identity.
  2. Proxy A → SBC: INVITE. Proxy A records the NAT address in Alice's Via, asserts Alice's identity, and adds Record-Route.
  3. SBC → Proxy B: INVITE (outer side). The SBC starts a new INVITE. It hides every inner address and keeps the asserted identity for a trusted peer.
  4. Proxy B → Bob: INVITE. Proxy B routes to Bob's Contact, adds Record-Route, and lowers the session timer to its own limit.

7.2 Tags

A tag is a random string in From and To. The UAC adds its tag to From in the first request; the UAS adds its tag to To in its response. Together with the Call-ID, the two tags name the dialog.

RFC 3261 §19.3 · Tags
“It serves as a general mechanism to identify a dialog, which is the combination of the Call-ID along with two tags, one from each participant in the dialog.”
Read the section ↗

Why two tags, and not just the Call-ID? Because a forked INVITE can be answered by several phones. Each one adds its own To tag, so the caller can tell the dialogs apart:

RFC 3261 §19.3 · Tags
“This also explains the need for the two-sided dialog identifier; without a contribution from the recipients, the originator could not disambiguate the multiple dialogs established from a single request.”
Read the section ↗

Every request inside the dialog repeats both tags, in the right places. From the caller’s side, From carries the caller’s tag; from the callee’s side — for example in Bob’s BYE — the two swap: From carries Bob’s tag, To carries Alice’s.

7.3 Via parameters

Parameter Added by Means
branch The sender of the request Names the transaction. Starts with z9hG4bK (Module 8).
received The next hop The source IP address the packet really came from, if it differs from the Via
rport The sender adds it empty; the next hop fills it The source port the packet came from: send the response there (RFC 3581)
maddr Rarely used A multicast or override address for responses

In the journey above, Alice’s phone writes its private address in Via and adds an empty rport. Proxy A fills in what it really saw: received=192.0.2.10;rport=40112 — the public address and port of the NAT router (Module 2).

RFC 3261 §18.2.1 · Receiving Requests
“If the host portion of the "sent-by" parameter contains a domain name, or if it contains an IP address that differs from the packet source address, the server MUST add a "received" parameter to that Via header field value.”
Read the section ↗
RFC 3581 §4 · Server Behavior
“If this Via header field value contains an "rport" parameter with no value, it MUST set the value of the parameter to the source port of the request.”
Read the section ↗

7.4 Contact parameters

Parameter Used in Means
expires REGISTER and its 200 OK How long this binding lasts, in seconds
q REGISTER, 3xx Preference among several Contacts, 0 to 1
+sip.instance REGISTER A permanent, unique id of the device (RFC 5626)
reg-id REGISTER Which of the device’s connections this registration uses (RFC 5626)
Contact: <sip:alice@192.0.2.10:5060;transport=tcp>;expires=3600;q=1.0
  ;+sip.instance="<urn:uuid:00000000-0000-1000-8000-000A95A0E128>";reg-id=1
RFC 5626 §2.1 · SIP Outbound, Definitions
“When a UA registers multiple times, each for a different flow, each concurrent registration gets a unique reg-id value.”
Read the section ↗

7.5 URI parameters

URI parameters live inside the angle brackets (Module 4):

Parameter Means
transport=tcp Use this transport to reach the URI
lr Loose router: this proxy follows RFC 3261 routing (Module 10)
user=phone The user part is a telephone number
maddr Send to this address instead of the host — avoid; use Route
ob SIP Outbound: keep using the connection this request came on

7.6 Routing headers

Record-Route is added by a proxy that wants to see the rest of the dialog. The UAs turn the list into a route set, and later requests carry it as Route headers. Each proxy removes its own Route entry. Module 10 explains the details; for now, notice in the journey that Proxy A and Proxy B add Record-Route — and that the SBC removes Proxy A’s entry to hide the inner network.

7.7 Identity and privacy

The From header is written by the caller’s phone, so it proves nothing. A network that has authenticated the caller says so in P-Asserted-Identity (PAI):

RFC 3325 §4 · Asserted Identity, Overview
“A proxy server which handles a message can, after authenticating the originating user in some way (for example: Digest authentication), insert such a P-Asserted-Identity header field into the message and forward it to other trusted proxies.”
Read the section ↗
  • The phone may suggest which of its identities to use with P-Preferred-Identity. The first trusted proxy removes it and adds PAI.
  • PAI is trusted only inside a trust domain — between elements that have agreed to trust each other, such as a carrier and its customers’ SBCs. A proxy that receives PAI from an untrusted source must replace or remove it:
RFC 3325 §5 · Proxy Behavior
“If the proxy received the message from an element that it does not trust and there is a P-Asserted-Identity header present which contains a SIP or SIPS URI, the proxy MUST replace that SIP or SIPS URI with a single SIP or SIPS URI or remove this header field.”
Read the section ↗
  • Privacy asks the network to hide things. Privacy: id asks the network to remove PAI before the call leaves the trust domain; the caller’s phone also writes an anonymous From.
From: "Anonymous" <sip:anonymous@anonymous.invalid>;tag=1928301774
P-Asserted-Identity: "Alice" <sip:alice@atlanta.example>, <tel:+14045550101>
Privacy: id
RFC 3325 §9.3 · The "id" Privacy Type
“The presence of this privacy type in a Privacy header field indicates that the user would like the Network Asserted Identity to be kept private with respect to SIP entities outside the Trust Domain with which the user authenticated.”
Read the section ↗
RFC 3323 §4.1 · Constructing Private Messages
“The following SIP headers, when generated by a user agent, can directly or indirectly reveal identity information about the originator of a message: From, Contact, Reply-To, Via, Call-Info, User-Agent, Organization, Server, Subject, Call-ID, In-Reply-To and Warning.”
Read the section ↗

7.8 Redirect history: Diversion and History-Info

When a call is forwarded, the new target often needs to know who was called first and why the call moved — a voicemail system needs to know whose mailbox to open.

  • Diversion (RFC 5806) answers both questions in one entry per forwarding. The RFC is Historic, but many carriers and PBXs still use it.
RFC 5806 §3 · Diversion Indication, Overview
“Question 1: From whom was the request diverted? Question 2: Why was the request diverted?”
Read the section ↗
Diversion: <sip:+14045550102@atlanta.example>;reason=no-answer;counter=1
  • History-Info (RFC 7044) is the standard replacement. Each element that forwards the request adds an entry, with an index that shows the order and a parameter that shows how the target changed: rc (same user, new Contact), mp (another user), or np (no change).
History-Info: <sip:bob@biloxi.example>;index=1
History-Info: <sip:bob@biloxi.example>;np=1;index=1.1
History-Info: <sip:bob@203.0.113.20>;index=1.1.1;rc=1.1
RFC 7044 §1 · History-Info, Introduction
“This request history information allows the receiving application to obtain information about how and why the SIP request arrived at the application/user.”
Read the section ↗

7.9 Session timers

SIP has no built-in keepalive for a call. If a BYE is lost, or a phone crashes, the proxies and the other phone may keep the call open for hours. Session timers (RFC 4028) fix this: one side refreshes the session with a re-INVITE or an UPDATE, and if no refresh comes, both sides end the call.

RFC 4028 §1 · Session Timer, Introduction
“If a session refresh request is not received before the interval passes, the session is considered terminated. Both UAs are supposed to send a BYE, and call stateful proxies can remove any state for the call.”
Read the section ↗
Header Means
Supported: timer “I support session timers.”
Session-Expires: 1800;refresher=uac The session interval in seconds, and who refreshes. A proxy may lower it.
Min-SE: 90 The shortest interval this element accepts. Never below 90 seconds.
422 Session Interval Too Small The interval is shorter than the receiver’s Min-SE. The response carries the Min-SE to retry with.
RFC 4028 §4 · Session-Expires Header Field Definition
“However, 1800 seconds (30 minutes) is RECOMMENDED as the value for the Session-Expires header field.”
Read the section ↗

The refresher sends its refresh halfway through the interval:

RFC 4028 §7.2 · Processing a 2xx Response
“It is RECOMMENDED that this refresh be sent once half the session interval has elapsed.”
Read the section ↗

In the journey above, Proxy B lowers Session-Expires from 1800 to 900: it wants to know within 15 minutes if a call is dead.

7.10 Other headers you will meet

Header Says
User-Agent / Server The software of the UAC / UAS. Often the fastest clue in a trace — and removed by SBCs that hide the topology.
Reason Why a request ends something (Module 6)
Warning Extra detail for a response, such as 304 … "Media type not available"
Date The sender’s clock; registrars send it, and some phones set their clock from it
Subject A short text about the call

Common mistakes

Changing the From tag or To tag inside a dialog

The tags, with the Call-ID, are the dialog. A request with another tag belongs to no dialog: the other side answers 481, and the call it was meant to change or end stays up.

Broken

Broken: BYE with a changed tag

  • SIP
  • Error
  • ⚠Problem
Alice192.0.2.10Bob203.0.113.2001INVITE02180 Ringing03200 OK04ACK05BYE⚠06481 Call/Transaction Does Not Exist⚠
01/06

Alice's phone calls Bob's phone.

All steps as text
  1. Alice → Bob: INVITE. Alice's phone calls Bob's phone.
  2. Bob → Alice: 180 Ringing. Bob's phone rings.
  3. Bob → Alice: 200 OK. Bob answers, at the same moment that Alice decides to hang up.
  4. Alice → Bob: ACK. Alice's phone confirms the 200 OK. The call is now set up.
  5. Alice → Bob: BYE. Alice's phone ends the call, but it writes a new To tag into the BYE. Problem: The To tag must be the tag from Bob's 200 OK. With another tag, the BYE matches no dialog.
  6. Bob → Alice: 481 Call/Transaction Does Not Exist. Bob's phone finds no dialog with these tags. It rejects the BYE, and the call stays up. Problem: Alice's phone thinks the call has ended. Bob's phone still sends media.

Using the same Call-ID for unrelated calls

A phone or script that reuses one Call-ID for every call makes all of them look like one dialog. Registrars, proxies, and analysis tools then merge unrelated calls, reject requests as retransmissions, or answer 481.

Remember: a new Call-ID for every new call. A retry after 401 or 407 keeps the Call-ID; a new call does not.

Trusting From for the caller's identity

Anybody can write anything in From. Billing, emergency services, and call blocking must use an identity that the network verified: P-Asserted-Identity from a trusted peer, or a verified STIR Identity header (Module 28).

Remember: From is a claim. PAI from a trusted peer is an assertion. Accept PAI only from peers you trust.

Not decrementing Max-Forwards

A proxy or a B2BUA that forwards without decrementing Max-Forwards — or resets it to 70 — disables loop protection. A routing loop between two servers then runs until something else breaks, instead of ending with 483 Too Many Hops.

Remember: every proxy subtracts 1. A B2BUA that starts a new request should still carry the received value down, not reset it.

Summary

  • Every request has Via, Max-Forwards, From, To, Call-ID, and CSeq; an INVITE also has Contact.
  • The From tag and the To tag, with the Call-ID, name a dialog. They never change inside it.
  • Via gets received and rport from the next hop, so responses find their way back through NAT.
  • Contact parameters (expires, q, +sip.instance, reg-id) describe a registration; URI parameters (transport, lr, user=phone, ob) describe how to reach a URI.
  • P-Asserted-Identity is a verified identity, trusted only inside a trust domain. Privacy: id hides it outside that domain.
  • Diversion and History-Info record why a call was forwarded.
  • Session-Expires and Min-SE make sure a dead call ends, even when a BYE is lost.