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).
“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:
“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 |
“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 ↗
“The To header field contains the address of record whose registration is to be created, queried, or modified.”Read the section ↗
“All registrations from a UAC SHOULD use the same Call-ID header field value for registrations sent to a particular registrar.”Read the section ↗
“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:
“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:
“A REGISTER request does not establish a dialog.”Read the section ↗
“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 |
“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.
“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
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
- +
sip:bob@203.0.113.20:5060
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 ↗“The UA then issues a REGISTER request for each of its bindings before the expiration interval has elapsed.”Read the section ↗
“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 ↗
“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 ↗
“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):
“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:
“A UA SHOULD use the same Call-ID for all registrations during a single boot cycle.”Read the section ↗
“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:
“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
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
- +
sip:bob@203.0.113.20:5060q=1.0
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:
“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:
“The registrar MAY choose an expiration less than the requested expiration interval.”Read the section ↗
“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 ↗
“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
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:
“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?
“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 ↗
“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
300 sbinding granted
24REGISTERs per hour
120keepalives per hour
100%of the hour, a call reaches Bob
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:
“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:
“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 ↗
“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 ↗
“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
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:
“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:
“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 ↗
“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:
“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.
“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.
“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
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
- +
sip:bob@198.51.100.77:41270;transport=tcp
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 ↗“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.
“The client periodically sends a double-CRLF (the "ping") then waits to receive a single CRLF (the "pong").”Read the section ↗
“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 ↗
“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:
“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:
“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 |
“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:
“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
3600 sbinding granted
2REGISTERs per hour
0keepalives per hour
3%of the hour, a call reaches Bob
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 ↗“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.
“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
The desk phone registers for 3600 seconds.
All steps as text
- Desk phone → Registrar: REGISTER. The desk phone registers for 3600 seconds.
- Registrar → Desk phone: 200 OK. One binding.
- Mobile → Registrar: REGISTER. One minute later, the mobile app registers too.
- Registrar → Mobile: 200 OK. Two bindings for sip:bob@biloxi.example.
- Desk phone → Registrar: REGISTER (remove all). The desk phone sends Contact: * to log out, but with no Expires header. Problem: Contact: * needs Expires: 0.
- 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.
“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
Bob's phone asks for 3600 seconds.
All steps as text
- Bob → Registrar: REGISTER. Bob's phone asks for 3600 seconds.
- Registrar → Bob: 200 OK. The Registrar allows at most 600 seconds. The 200 OK says so: expires=600.
- Alice → Proxy B: INVITE. Fifteen minutes later, Alice calls Bob.
- Proxy B → Alice: 480 Temporarily Unavailable. Bob's binding ran out at 600 seconds. Proxy B finds no Contact for Bob.
- Alice → Proxy B: ACK. Alice acknowledges the 480. The call fails, although Bob's phone shows "Registered".
- 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.
- 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=0removes one binding, andContact: *withExpires: 0removes 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.