Skip to content
SIP Mastery

Part 4 · Registration, authentication, security / Module 12

Registration

How a phone tells its registrar where it is — REGISTER, the binding from an AOR to a Contact, refresh, query, and removal, several devices with q values, 423 and Min-Expires, Path and Service-Route, and the NAT problems that SIP Outbound and GRUU solve.

BasicIntermediateNOC coreDEV coredraft

After this module, you can

  • Explain what a binding is, and why a call to a user with no binding fails.
  • Read a REGISTER and say what its Request-URI, To, From, Call-ID, CSeq, Contact, and Expires mean.
  • Add, refresh, query, and remove bindings, and predict the Contact list in each 200 OK.
  • Explain q values, 423 Interval Too Brief, and why the expiry in the 200 OK is the one that counts.
  • Explain why a registration expiry longer than the NAT mapping timeout breaks incoming calls.
  • Say what Path, Service-Route, SIP Outbound, and GRUU add to registration.

12.1 What registration does: it binds an AOR to a Contact

Alice calls sip:bob@biloxi.example. That URI is Bob’s AORAOR. The public SIP address of a user, such as sip:alice@atlanta.example.: his public address, which does not change. It does not say where Bob’s phone is. Proxy B finds the phone in its location servicelocation service. The database of bindings from AORs to Contact addresses., and the location service learns it from Bob’s phone, with a REGISTER request (Module 3).

RFC 3261 §10.1 · Registrations, Overview
“Registration creates bindings in a location service for a particular domain that associates an address-of-record URI with one or more contact addresses.”
Read the section ↗
Example Changes when…
AOR sip:bob@biloxi.example Never: it is printed on Bob’s business card
Contact sip:bob@203.0.113.20:5060 The phone moves, restarts, or gets a new address
Binding AOR → Contact, for 3600 seconds Each REGISTER adds, refreshes, or removes it

When Proxy B gets a request for the AOR, it sends it to the registered Contacts:

RFC 3261 §10.1 · Registrations, Overview
“Thus, when a proxy for that domain receives a request whose Request-URI matches the address-of-record, the proxy will forward the request to the contact addresses registered to that address-of-record.”
Read the section ↗

No binding means no route to Bob: Proxy B answers 480 Temporarily Unavailable. Registration is for incoming calls. Bob’s phone can often make calls when its registration is broken, so “outgoing works, incoming fails” is the classic sign of a registration problem.

Most registrars challenge the first REGISTER with 401, and the phone sends it again with credentials (Module 13). The flows in this module leave the challenge out, to show the bindings more clearly.

12.2 REGISTER: Request-URI, To, From, Contact, Expires

This is the first REGISTER of Bob’s desk phone:

REGISTER sip:biloxi.example SIP/2.0
Via: SIP/2.0/UDP 203.0.113.20:5060;branch=z9hG4bKr001x7
Max-Forwards: 70
From: Bob <sip:bob@biloxi.example>;tag=76ff7a07
To: Bob <sip:bob@biloxi.example>
Call-ID: 8463jsGq2@203.0.113.20
CSeq: 1 REGISTER
Contact: <sip:bob@203.0.113.20:5060>
Expires: 3600
Content-Length: 0
Field In a REGISTER it means…
Request-URI The domain of the registrar: sip:biloxi.example, with no user part
To The AOR to register: sip:bob@biloxi.example
From Who registers it. The same as To, unless a third party registers for the user
Call-ID The same value for every REGISTER the phone sends to this registrar while it runs
CSeq One higher for each REGISTER, so the registrar can spot an old request that arrives late
Contact The address to bind. No Contact means “only show me the bindings”
Expires How long the phone would like the binding to last. The registrar decides
RFC 3261 §10.2 · Constructing the REGISTER Request
“The Request-URI names the domain of the location service for which the registration is meant (for example, "sip:chicago.com"). The "userinfo" and "@" components of the SIP URI MUST NOT be present.”
Read the section ↗
RFC 3261 §10.2 · Constructing the REGISTER Request
“The To header field contains the address of record whose registration is to be created, queried, or modified.”
Read the section ↗
RFC 3261 §10.2 · Constructing the REGISTER Request
“All registrations from a UAC SHOULD use the same Call-ID header field value for registrations sent to a particular registrar.”
Read the section ↗
RFC 3261 §10.2 · Constructing the REGISTER Request
“A UA MUST increment the CSeq value by one for each REGISTER request with the same Call-ID.”
Read the section ↗

The expiry can be in the Expires header, for every Contact, or in an expires parameter on one Contact. The parameter wins. With neither, the registrar uses its default:

RFC 3261 §10.2 · Constructing the REGISTER Request
“The "expires" parameter indicates how long the UA would like the binding to be valid. The value is a number indicating seconds. If this parameter is not provided, the value of the Expires header field is used instead.”
Read the section ↗

The parameter belongs outside the angle brackets: <sip:bob@203.0.113.20:5060>;expires=600. Inside them, it is part of the URI, and the registrar ignores it (Module 4).

REGISTER is a request outside any dialog. Its 200 OK has a To tag, but no dialog follows, and a Record-Route in a REGISTER means nothing:

RFC 3261 §10.2 · Constructing the REGISTER Request
“A REGISTER request does not establish a dialog.”
Read the section ↗
RFC 3261 §10.2 · Constructing the REGISTER Request
“The Record-Route header field has no meaning in REGISTER requests or responses, and MUST be ignored if present.”
Read the section ↗

The phone sends REGISTER to the registrar that it is configured with. Without one, it uses the domain of its AOR, sip:biloxi.example, and finds the server with DNS (Module 11).

12.3 Refresh, query, and remove a registration

A binding is soft state: it expires unless the phone refreshes it. The same request, REGISTER, does all four jobs. The difference is in Contact and Expires:

Operation Contact Expiry Result
Add The phone’s address More than 0 A new binding
Refresh The same address, same Call-ID, higher CSeq More than 0 The binding runs again from now
Query None — Nothing changes; the 200 OK lists the bindings
Remove one The address expires=0 That binding goes
Remove all * Expires: 0 (required) Every binding of the AOR goes, from every device
RFC 3261 §10.2.2 · Removing Bindings
“Registrations are soft state and expire unless refreshed, but can also be explicitly removed.”
Read the section ↗

Every 200 OK lists all current bindings of the AOR — not only the one in the request — each with the time it has left. The expires value always counts from now.

RFC 3261 §10.3 · Processing REGISTER Requests
“The response MUST contain Contact header field values enumerating all current bindings. Each Contact value MUST feature an "expires" parameter indicating its expiration interval chosen by the registrar.”
Read the section ↗

Step through Bob’s day: add, refresh, query, remove. The table on the right is the registrar’s location service, as RFC 3261 §10.3 builds it.

Location service view

Register, refresh, query, and remove

  • +Added
  • ↻Refreshed
  • −Removed or expired
Bob203.0.113.20Registrarbiloxi.example01REGISTER02200 OK03REGISTER (refresh)04200 OK05REGISTER (query)06200 OK07REGISTER (remove)08200 OK
01/8

Bob's phone starts. It asks the Registrar to bind sip:bob@biloxi.example to its Contact for 3600 seconds.

Location servicet = 0 s

AORsip:bob@biloxi.example

Registrar policy: Min-Expires 60 s · at most 3600 s

  1. +

    sip:bob@203.0.113.20:5060

    expires in 60 minCall-ID 8463jsGq2 · CSeq 1

The registrar answers200 OK

A new binding for 3600 s. The 200 OK lists the binding with the time left.

RFC 3261 §10.2.1 · Adding Bindings

“The 2xx response to the REGISTER request will contain, in a Contact header field, a complete list of bindings that have been registered for this address-of-record at this registrar.”

Read the section ↗
RFC 3261 §10.2.4 · Refreshing Bindings
“The UA then issues a REGISTER request for each of its bindings before the expiration interval has elapsed.”
Read the section ↗
RFC 3261 §10.2.3 · Fetching Bindings
“A success response to any REGISTER request contains the complete list of existing bindings, regardless of whether the request contained a Contact header field. If no Contact header field is present in a REGISTER request, the list of bindings is left unchanged.”
Read the section ↗
RFC 3261 §10.2.2 · Removing Bindings
“A UA requests the immediate removal of a binding by specifying an expiration interval of "0" for that contact address in a REGISTER request.”
Read the section ↗
RFC 3261 §10.2.2 · Removing Bindings
“The REGISTER-specific Contact header field value of "*" applies to all registrations, but it MUST NOT be used unless the Expires header field is present with a value of "0".”
Read the section ↗

RFC 3261 says only “before the expiry”. Most phones refresh at about half of it, or a fixed time before it. The expiry to use is the one in the 200 OK, which can be shorter than the request (12.5):

RFC 3261 §10.2.4 · Refreshing Bindings
“The UA compares each contact address to see if it created the contact address, using comparison rules in Section 19.1.4. If so, it updates the expiration time interval according to the expires parameter or, if absent, the Expires field value.”
Read the section ↗

A phone keeps one Call-ID while it runs. After a restart it uses a new one. The registrar compares the Call-ID and CSeq, so a delayed REGISTER cannot undo a newer one:

RFC 3261 §10.2.4 · Refreshing Bindings
“A UA SHOULD use the same Call-ID for all registrations during a single boot cycle.”
Read the section ↗
RFC 3261 §10.3 · Processing REGISTER Requests
“If the value is higher than that of the existing binding, it MUST update or remove the binding as above. If not, the update MUST be aborted and the request fails.”
Read the section ↗

12.4 More than one device per AOR; q values

Bob has a desk phone, a mobile app, and a softphone. Each one registers the same AOR, with its own Contact and its own Call-ID. The registrar keeps one binding per Contact, and each 200 OK shows all three.

A q parameter from 0 to 1 on each Contact says which device Bob prefers:

RFC 3261 §10.2.1.2 · Preferences among Contact Addresses
“This list can be prioritized with the "q" parameter in the Contact header field. The "q" parameter indicates a relative preference for the particular Contact header field value compared to other bindings for this address-of-record.”
Read the section ↗

Location service view

Three devices, one AOR

  • +Added
  • ↻Refreshed
  • −Removed or expired
Desk phone203.0.113.20Mobile198.51.100.77Softphone203.0.113.21Registrarbiloxi.example01REGISTER02200 OK03REGISTER04200 OK05REGISTER06200 OK
01/6

The desk phone registers with q=1.0, the highest preference.

Location servicet = 0 s

AORsip:bob@biloxi.example

Registrar policy: Min-Expires 60 s · at most 3600 s

  1. +

    sip:bob@203.0.113.20:5060q=1.0

    expires in 60 minCall-ID Dk72hs01 · CSeq 1

The registrar answers200 OK

A new binding for 3600 s. The 200 OK lists the binding with the time left.

RFC 3261 §10.2.1 · Adding Bindings

“The 2xx response to the REGISTER request will contain, in a Contact header field, a complete list of bindings that have been registered for this address-of-record at this registrar.”

Read the section ↗

Proxy B uses q to order its targets. Devices with the same q can ring together; a higher q rings first:

RFC 3261 §16.6 · Request Forwarding
“Targets are processed from highest qvalue to lowest. Targets with equal qvalues may be processed in parallel.”
Read the section ↗
Bob’s bindings q Proxy B with sequential forking Proxy B with parallel forking
Desk phone 1.0 Rings first All three ring at once
Softphone 0.7 Rings if the desk phone does not answer
Mobile 0.5 Rings last

Without q, all bindings have the same preference, and a proxy usually rings them all at once. Module 9 covers forking: several early dialogs, and what happens when two devices answer.

Each device refreshes and removes only its own binding. One device that removes all bindings with Contact: * logs out the other devices too.

12.5 423 Interval Too Brief and Min-Expires

The registrar chooses the expiry, not the phone. It can shorten a long request, and it can refuse a very short one:

RFC 3261 §10.3 · Processing REGISTER Requests
“The registrar MAY choose an expiration less than the requested expiration interval.”
Read the section ↗
RFC 3261 §10.3 · Processing REGISTER Requests
“If and only if the requested expiration interval is greater than zero AND smaller than one hour AND less than a registrar-configured minimum, the registrar MAY reject the registration with a response of 423 (Interval Too Brief). This response MUST contain a Min-Expires header field that states the minimum expiration interval the registrar is willing to honor.”
Read the section ↗
RFC 3261 §10.2.8 · Error Responses
“If a UA receives a 423 (Interval Too Brief) response, it MAY retry the registration after making the expiration interval of all contact addresses in the REGISTER request equal to or greater than the expiration interval within the Min-Expires header field of the 423 (Interval Too Brief) response.”
Read the section ↗

Location service view

423 Interval Too Brief and Min-Expires

  • +Added
  • ↻Refreshed
  • −Removed or expired
Bob203.0.113.20Registrarbiloxi.example01REGISTER02423 Interval Too Brief03REGISTER04200 OK
01/4

The phone asks for a short registration, 60 seconds, to keep its NAT mapping open.

Location servicet = 0 s

AORsip:bob@biloxi.example

Registrar policy: Min-Expires 300 s · at most 3600 s

No bindings. A call to bob@biloxi.example gets 480 Temporarily Unavailable.

The registrar answers423 Interval Too BriefMin-Expires: 300

The request asks for 60 s, but the registrar keeps a binding for at least 300 s. Nothing changes.

RFC 3261 §10.3 · Processing REGISTER Requests

“If and only if the requested expiration interval is greater than zero AND smaller than one hour AND less than a registrar-configured minimum, the registrar MAY reject the registration with a response of 423 (Interval Too Brief). This response MUST contain a Min-Expires header field that states the minimum expiration interval the registrar is willing to honor.”

Read the section ↗

Why would a phone ask for 60 seconds? Every REGISTER goes out through Bob’s NAT router, and an outgoing packet keeps the router’s mapping open. A short expiry is a crude keepalive. For the registrar, it is load: 10,000 phones that register every 60 seconds send almost 170 REGISTER requests per second, and each one may also need a digest check. That is why registrars set a Min-Expires, though RFC 3261 asks them to keep it low:

RFC 3261 §10.3 · Processing REGISTER Requests
“Therefore, registrars should accept brief registrations; a request should only be rejected if the interval is so short that the refreshes would degrade registrar performance.”
Read the section ↗

Expiry and the NAT mapping

Two timers decide whether a call reaches Bob behind NAT, and they are not related:

  • The registration expiry, at the registrar: does Proxy B know where Bob is?
  • The NAT mapping timeout, in Bob’s router: does the router still let packets in on that public port?
RFC 4787 §4.3 · Mapping Refresh
“There is great variation in the values used by different NATs. REQ-5: A NAT UDP mapping timer MUST NOT expire in less than two minutes, unless REQ-5a applies.”
Read the section ↗
RFC 4787 §4.3 · Mapping Refresh
“REQ-6: The NAT mapping Refresh Direction MUST have a "NAT Outbound refresh behavior" of "True".”
Read the section ↗

Only outgoing packets keep the mapping open. An incoming INVITE does not. When the mapping is gone, the INVITE from Proxy B arrives at a closed port, and the router drops it. Bob’s phone still shows “Registered”. When the phone sends something again, the router may open a new mapping on a new public port — and the binding still has the old one until the next REGISTER.

Change the settings and select a point in the hour to send Alice’s INVITE:

Expiry clock

One hour of Bob's phone behind a NAT router

  • REGISTER and binding
  • Keepalive
  • NAT mapping
  • Call fails
Bob asks for
Registrar allows at most
Bob refreshes at half of
NAT mapping timeout
Keepalives

300 sbinding granted

24REGISTERs per hour

120keepalives per hour

100%of the hour, a call reaches Bob

REGISTER
Binding
Keepalives
NAT mapping
port 40112
Call to Bob
0102030405060 min

Select a point on the timeline, or use the arrow keys, to choose when Alice calls.

Alice calls at 15:00 (t = 900 s)

Reaches Bob

The INVITE reaches Bob. The registrar's Contact uses public port 40112, and the NAT router still has that mapping.

RFC 5626 §4.4.2 · Keep-Alive with STUN

“When a Flow-Timer header field is not included in a successful registration response, the time between each keep-alive request SHOULD be a random number between 24 and 29 seconds.”

Read the section ↗
Fix How it keeps the mapping open Cost
Keepalives from the phone: a double CRLF, a STUN request, or an OPTIONS request A small outgoing packet every 15 to 30 seconds Almost none, but not every phone can do it
Short registration expiry Each REGISTER is an outgoing packet Load on the registrar, which may answer 423
OPTIONS from the proxy to the phone The phone’s 200 OK to the OPTIONS goes out through the router Load on the proxy; common in Kamailio and OpenSIPS set-ups
SIP Outbound (12.7) Keepalives on a flow the phone opened, defined in an RFC Both sides must support RFC 5626

RFC 5626 picked its UDP keepalive interval for exactly this reason:

RFC 5626 §4.4.2 · Keep-Alive with STUN
“Note on selection of time values: the upper bound of 29 seconds was selected, as many NATs have UDP timeouts as low as 30 seconds.”
Read the section ↗

12.6 Path and Service-Route

Many providers put an edge proxy between the phones and the core: an SBC, or the P-CSCF in IMS (Module 27). Calls to Bob must go through the edge proxy, because only it can reach Bob’s phone — it holds the connection, or it knows the NAT mapping. But Proxy B only has Bob’s Contact. How does it know to go through the edge?

Path (RFC 3327) records the edge proxy during registration. The edge proxy adds a Path header to the REGISTER, the registrar stores it with the binding, and Proxy B puts it in Route when it sends a request to that Contact:

RFC 3327 §5.2 · Procedures at Intermediate Proxies
“When a proxy processing a REGISTER request wishes to be on the path for future requests toward the UA originating that REGISTER request, the proxy inserts a URI for that proxy as the topmost value in the Path header field (or inserts a new topmost Path header) before proxying that request.”
Read the section ↗
RFC 3327 §5.3 · Procedures at the Registrar
“The registrar then stores this path vector in association with that contact and the address-of-record indicated in the REGISTER request (the "binding" as defined in [1]).”
Read the section ↗
RFC 3327 §5.4 · Procedures at the Home Proxy
“With the addition of Path, the home proxy also copies the stored path vector associated with the specific contact in the registrar database into the Route header field of the outgoing request as a preloaded route.”
Read the section ↗

Location service view

Path and Service-Route

  • +Added
  • ↻Refreshed
  • −Removed or expired
Alice192.0.2.10Proxy B203.0.113.10Registrarbiloxi.exampleEdge proxyedge.biloxi.exampleBob203.0.113.2001REGISTER02REGISTER03200 OK04200 OK05INVITE06INVITE07INVITE08180 Ringing09180 Ringing10180 Ringing
01/10

Bob's phone sends REGISTER to its edge proxy. Supported: path says it understands Path.

Location servicet = 0 s

AORsip:bob@biloxi.example

Registrar policy: Min-Expires 60 s · at most 3600 s

No bindings. A call to bob@biloxi.example gets 480 Temporarily Unavailable.

The registrar does not see this message.

RFC 3327 §5.1 · Procedures at the UA

“The UA SHOULD include the option tag "path" as a header field value in all Supported header fields, and SHOULD include a Supported header field in all requests.”

Read the section ↗

Path looks like Record-Route, but it lives longer:

RFC 3327 §4 · Path Header Field Definition and Syntax
“Furthermore, the vector established by Record-Route applies only to requests within the dialog that established that Record-Route, whereas the vector established by Path applies to future dialogs.”
Read the section ↗

Service-Route (RFC 3608) goes the other way. The registrar returns it in the 200 OK, and the phone uses it as a pre-loaded Route for its own new requests (Module 10.7), so they reach the proxy that serves Bob:

RFC 3608 §3 · Discussion of Mechanism
“A registrar may use a Service-Route header field to inform a UA of a service route that, if used by the UA, will provide services from a proxy or set of proxies associated with that registrar.”
Read the section ↗
RFC 3608 §6.1 · Procedures at the UA
“If so, it uses the content of the Service-Route header field as a preloaded Route header field in outgoing initial requests [3].”
Read the section ↗

When Bob calls Carol, his phone puts its outbound proxy first, then the Service-Route:

INVITE sip:carol@chicago.example SIP/2.0
Route: <sip:edge.biloxi.example;lr>, <sip:orig@proxy.biloxi.example;lr>
Record-Route Path Service-Route
Added by A proxy, on the request that creates a dialog A proxy, on a REGISTER The registrar, in the 200 OK to REGISTER
Used by Both ends of the dialog The proxy that looks up the binding The registering phone
For Later requests in this dialog Requests to the phone, in future dialogs Requests from the phone, in future dialogs
Needs ;lr Yes Yes Yes

A phone shows support with Supported: path. Without it, a registrar should refuse a REGISTER that has a Path, with 420 Bad Extension, because a proxy may have added itself to the path without the phone’s knowledge:

RFC 3327 §5.1 · Procedures at the UA
“The UA SHOULD include the option tag "path" as a header field value in all Supported header fields, and SHOULD include a Supported header field in all requests.”
Read the section ↗

12.7 SIP Outbound and GRUU (overview)

SIP Outbound: the phone keeps the connection

Behind NAT or a firewall, nobody can open a connection to Bob’s phone. RFC 5626, SIP Outbound, turns this around: the phone opens the connection, keeps it alive, and the server sends Bob’s calls back over it.

RFC 5626 §1 · Introduction
“The key idea of this specification is that when a UA sends a REGISTER request or a dialog-forming request, the proxy can later use this same network "flow" -- whether this is a bidirectional stream of UDP datagrams, a TCP connection, or an analogous concept in another transport protocol -- to forward any incoming requests that need to go to this UA in the context of the registration or dialog.”
Read the section ↗

Registration needs two new Contact parameters for this:

  • +sip.instance: a permanent, unique name for the device, the instance IDinstance ID. A permanent, unique URN for one device, sent in the +sip.instance Contact parameter (RFC 5626). It does not change when the device reboots or moves.. It does not change when the phone restarts or moves.
  • reg-id: the number of the flow. A device can register over two flows, to two edge proxies, for redundancy.
RFC 5626 §3.1 · Summary of Mechanism
“Each UA has a unique instance-id that stays the same for this UA even if the UA reboots or is power cycled.”
Read the section ↗

Without them, the registrar only sees Contact URIs. When Bob’s mobile moves from Wi-Fi to 4G, its new Contact is a second binding, and the old one, which leads nowhere, stays until it expires. Calls to Bob fork to both, and the old branch fails slowly. With an instance ID and reg-id, the registrar knows that the new Contact replaces the old one. Compare the two:

Location service view

Without SIP Outbound: a new address adds a binding

  • +Added
  • ↻Refreshed
  • −Removed or expired
Mobile198.51.100.77Registrarbiloxi.example01REGISTER02200 OK03REGISTER04200 OK⚠
01/4

Bob's mobile app registers over TCP on Wi-Fi.

Location servicet = 0 s

AORsip:bob@biloxi.example

Registrar policy: Min-Expires 60 s · at most 3600 s

  1. +

    sip:bob@198.51.100.77:41270;transport=tcp

    expires in 10 minCall-ID Mb48wn93 · CSeq 1

The registrar answers200 OK

A new binding for 600 s. The 200 OK lists the binding with the time left.

RFC 3261 §10.2.1 · Adding Bindings

“The 2xx response to the REGISTER request will contain, in a Contact header field, a complete list of bindings that have been registered for this address-of-record at this registrar.”

Read the section ↗
RFC 5626 §3.2 · Single Registrar and UA
“If the instance-id and reg-id are the same as a previous registration for the same AOR, the registrar replaces the old Contact URI and flow information.”
Read the section ↗

On the flow, the phone sends keepalives. On TCP and TLS, a keepalive is a double CRLF, and the server answers with one CRLF. On UDP, it is a STUN request.

RFC 5626 §3.5.1 · CRLF Keep-Alive Technique
“The client periodically sends a double-CRLF (the "ping") then waits to receive a single CRLF (the "pong").”
Read the section ↗
RFC 5626 §4.4.1 · Keep-Alive with CRLF
“The fixed upper bound or the default configurable upper bound SHOULD be 120 seconds (95 seconds for the lower bound) where battery power is not a concern and 840 seconds (672 seconds for the lower bound) where battery power is a concern.”
Read the section ↗
RFC 5626 §4.4.2 · Keep-Alive with STUN
“When a Flow-Timer header field is not included in a successful registration response, the time between each keep-alive request SHOULD be a random number between 24 and 29 seconds.”
Read the section ↗

The registrar confirms Outbound with Require: outbound in the 200 OK. If it is missing, Outbound is not in use, and the phone must fall back to the methods in 12.5. Module 20 covers NAT traversal in detail.

GRUU: an address for one device

The AOR reaches all of Bob’s devices. Sometimes a request must reach exactly one: Alice transfers Bob’s call to Carol, and Carol’s phone must call Bob’s desk phone, not his voicemail and not his mobile. The Contact address cannot do this, because it is often a private address behind NAT. A GRUUGRUU. A URI that reaches one device of a user, not all of them (RFC 5627). It has the gr parameter. can:

RFC 5627 §1 · Introduction
“This specification describes a mechanism for providing a unique user-agent identifier which is still globally routable. This identifier is called a Globally Routable User Agent (UA) URI (GRUU).”
Read the section ↗

A phone that sends an instance ID and Supported: gruu gets two GRUUs in the 200 OK:

RFC 5627 §3.2 · Obtaining a GRUU
“The registrar detects this header field parameter and provides two GRUUs in the REGISTER response. One of these is a temporary GRUU, and the other is the public GRUU.”
Read the section ↗
Contact: <sip:bob@198.51.100.77:41270;transport=tcp>
 ;+sip.instance="<urn:uuid:5f3c0a2e-6b1d-4c8e-9a47-2d61b0e8c3f5>";reg-id=1
 ;pub-gruu="sip:bob@biloxi.example;gr=urn:uuid:5f3c0a2e-6b1d-4c8e-9a47-2d61b0e8c3f5"
 ;temp-gruu="sip:tgruu.1er2har@biloxi.example;gr";expires=600
Public GRUU Temporary GRUU
Looks like The AOR with ;gr= and the instance ID An opaque name, with ;gr
Shows who Bob is Yes No: for anonymous calls
Changes Never, for this device A new one with each refresh; the older ones still work
RFC 5627 §3.1.1 · GRUUs That Expose the Underlying AOR
“It is constructed by taking the AOR, and adding the "gr" URI parameter with a value chosen by the registrar in the domain.”
Read the section ↗

The phone then puts its GRUU in the Contact of its INVITEs and 200 OKs. Proxy B receives a request for the GRUU and sends it only to the Contacts of that one device:

RFC 5627 §3.3 · Using a GRUU
“First, it uses them as the contents of the Contact header field in non-REGISTER requests and responses that it emits (for example, an INVITE request and 200 OK response).”
Read the section ↗

IMS uses instance IDs and GRUUs (Module 27). Many other networks use neither SIP Outbound nor GRUU: they rely on rport, keepalives, and an SBC or a proxy that rewrites the Contact (Module 20).

Common mistakes

A registration expiry longer than the NAT mapping timeout

Bob’s phone registers for 3600 seconds, and the registrar is happy. But the NAT router closes the mapping after 60 seconds of silence. From then on, Proxy B sends each INVITE to a public port that the router no longer forwards. Bob’s phone shows “Registered”, outgoing calls work, and incoming calls fail — except in the minute after each REGISTER. In a trace taken at the proxy, the INVITE goes out and nothing comes back.

Expiry clock

Broken: a 1-hour registration behind a 60-second NAT timeout

  • REGISTER and binding
  • Keepalive
  • NAT mapping
  • Call fails
Bob asks for
Registrar allows at most
Bob refreshes at half of
NAT mapping timeout
Keepalives

3600 sbinding granted

2REGISTERs per hour

0keepalives per hour

3%of the hour, a call reaches Bob

REGISTER
Binding
Keepalives
none
NAT mapping
Call to Bob
0102030405060 min

Select a point on the timeline, or use the arrow keys, to choose when Alice calls.

Alice calls at 15:00 (t = 900 s)

Dropped at NAT

Proxy B sends the INVITE to port 40112, but the NAT router closed that mapping and drops the packet. After Timer B (32 s), Proxy B answers Alice with 408 Request Timeout.

First failure at 1:00: the NAT mapping closed.

RFC 4787 §4.3 · Mapping Refresh

“There is great variation in the values used by different NATs. REQ-5: A NAT UDP mapping timer MUST NOT expire in less than two minutes, unless REQ-5a applies.”

Read the section ↗
RFC 5626 §4.4.2 · Keep-Alive with STUN
“When a Flow-Timer header field is not included in a successful registration response, the time between each keep-alive request SHOULD be a random number between 24 and 29 seconds.”
Read the section ↗

Remember: turn on keepalives shorter than the shortest NAT timeout you expect — 25 seconds is a common value — or let the proxy send OPTIONS to the phone. If you must use a short registration expiry instead, check the registrar’s Min-Expires and its load.

Contact: * without Expires: 0

A phone that logs out sends Contact: * to remove all its bindings, but leaves out Expires, or sends Expires: 3600. The registrar must refuse the request with 400, and every binding stays. Calls keep ringing a device that the user logged out of.

RFC 3261 §10.3 · Processing REGISTER Requests
“If the request has additional Contact fields or an expiration time other than zero, the request is invalid, and the server MUST return a 400 (Invalid Request) and skip the remaining steps.”
Read the section ↗

Broken

Broken: Contact: * without Expires: 0

  • SIP
  • ⚠Problem
Desk phone203.0.113.20Mobile198.51.100.77Registrarbiloxi.example01REGISTER02200 OK03REGISTER04200 OK05REGISTER (remove all)⚠06400 Bad Request
01/06

The desk phone registers for 3600 seconds.

All steps as text
  1. Desk phone → Registrar: REGISTER. The desk phone registers for 3600 seconds.
  2. Registrar → Desk phone: 200 OK. One binding.
  3. Mobile → Registrar: REGISTER. One minute later, the mobile app registers too.
  4. Registrar → Mobile: 200 OK. Two bindings for sip:bob@biloxi.example.
  5. Desk phone → Registrar: REGISTER (remove all). The desk phone sends Contact: * to log out, but with no Expires header. Problem: Contact: * needs Expires: 0.
  6. Registrar → Desk phone: 400 Bad Request. The Registrar rejects the request. Both bindings stay, so calls still ring the desk phone.

Remember: Contact: * always goes with Expires: 0, and it removes the bindings of every device of the AOR. To remove one device, send its own Contact with expires=0.

Ignoring the shorter expiry in the 200 OK

The phone asks for 3600 seconds, and plans its next refresh from that number. The registrar grants only 600, and says so in the expires parameter of the 200 OK. After 600 seconds the binding is gone, and calls fail with 480, until the phone refreshes at 1800 seconds. Then the cycle repeats: Bob can be reached for 10 minutes in every 30.

RFC 3261 §10.2.4 · Refreshing Bindings
“The UA compares each contact address to see if it created the contact address, using comparison rules in Section 19.1.4. If so, it updates the expiration time interval according to the expires parameter or, if absent, the Expires field value.”
Read the section ↗

Broken

Broken: the phone ignores the shorter expiry

  • SIP
  • ⚠Problem
Alice192.0.2.10Proxy Bproxy.biloxi.exampleBob203.0.113.20Registrarbiloxi.example01REGISTER02200 OK03INVITE04480 Temporarily Unavailable05ACK06REGISTER (refresh)⚠07200 OK
01/07

Bob's phone asks for 3600 seconds.

All steps as text
  1. Bob → Registrar: REGISTER. Bob's phone asks for 3600 seconds.
  2. Registrar → Bob: 200 OK. The Registrar allows at most 600 seconds. The 200 OK says so: expires=600.
  3. Alice → Proxy B: INVITE. Fifteen minutes later, Alice calls Bob.
  4. Proxy B → Alice: 480 Temporarily Unavailable. Bob's binding ran out at 600 seconds. Proxy B finds no Contact for Bob.
  5. Alice → Proxy B: ACK. Alice acknowledges the 480. The call fails, although Bob's phone shows "Registered".
  6. Bob → Registrar: REGISTER (refresh). The phone refreshes at half of what it asked for: 1800 seconds. That is 20 minutes too late. Problem: The binding ran out at 600 seconds.
  7. Registrar → Bob: 200 OK. The Registrar adds the binding again, for 600 seconds. The phone plans its next refresh at 3600.

Remember: the expiry that counts is the expires parameter on the phone’s own Contact in the 200 OK. When a user is “registered” but unreachable at regular intervals, compare the refresh interval in the trace with that value.

Summary

  • Registration stores a binding from an AOR to a Contact in the location service. No binding means a call to the user fails, often with 480.
  • A REGISTER has the domain in its Request-URI and the AOR in To. It keeps one Call-ID while the phone runs, and adds one to CSeq each time.
  • One request does it all: a Contact adds or refreshes, no Contact queries, expires=0 removes one binding, and Contact: * with Expires: 0 removes all.
  • Every 200 OK lists all bindings of the AOR, each with the time left. The registrar may shorten the expiry; the phone must refresh before the expiry in the 200 OK.
  • Several devices can register one AOR; q values order them. 423 with Min-Expires refuses a very short expiry.
  • Behind NAT, the mapping timeout matters as much as the registration expiry: keep the mapping open with keepalives.
  • Path puts edge proxies in the route to the phone; Service-Route gives the phone its route for outgoing requests. SIP Outbound replaces a moved device’s binding and keeps its flow alive; a GRUU reaches one device.