[Devel] Processing REGISTER requests

Dan Pascu dan at ag-projects.com
Mon Oct 3 09:49:11 CEST 2005


I've checked the registrar module and noticed that openser uses only the 
contact to match a REGISTER request against an older REGISTER request (that 
is to know if it has to add an entry to user location or if it has to update 
an older entry).

Now I think there are several problems with this approach and I can outline 3 
here (all refer to cases where phones are behind NAT):

1. If you save the contact after calling fix_contact() you get the NAT address 
in the user location, but this address may change from one REGISTER request 
to another. I've seen this case with a NAT that uses a different port every 
request and that phone ended up with 200 contacts in the user location table.
This is not something you'd want in your user location table, even though the 
proxy and phone will work correctly: the proxy will send 200 INVITE request 
when someone calls that phone and the phone will pick one branch to answer 
and reject the other 199, but the traffic is multiplied by 200.

2. If you save the unmodified contact (the private address behind NAT) then 
there is a chance of contact collision. Consider someone with a SIP account 
and multiple phones in different locations. If he uses the same private IP 
address in multiple networks for his phones, those phones will overwrite each 
others entries in usrloc and only 1 phone will be available at a time (the 
one that sent the last REGISTER request).
You may think that this situation is very rare, but I think it has big chances 
to appear because people tend to standardize the environment they work in for 
simplification. This makes it very likely that someone will use the same 
network classes in setting up private networks in different locations and 
that he uses the same IP addresses for his phones in those locations, so he 
knows that his phone is always found at the same address no matter what 
network he is in.

3. If you save the unmodified contact (the private address behind NAT) then 
there is another chance of collision: if the proxy serves multiple domains 
and there are 2 users with the same username but in different domains and 
they use the same private IP address for their phone then both contacts will 
look like sip:username at ip:port and they will overwrite each others 
subscription as explained above.

To overcome these problems I think we should use a different approach to 
identify the phone to which a REGISTER request belongs to. I've checked the 
RFC and there is the following recommendation for the Call-ID and CSeq fields 
with REGISTER requests:

      Call-ID: All registrations from a UAC SHOULD use the same Call-ID
           header field value for registrations sent to a particular
           registrar.

           If the same client were to use different Call-ID values, a
           registrar could not detect whether a delayed REGISTER request
           might have arrived out of order.

      CSeq: The CSeq value guarantees proper ordering of REGISTER
           requests.  A UA MUST increment the CSeq value by one for each
           REGISTER request with the same Call-ID.

As you can see they recommend (not mandate) that phones use the same callid 
for a given registrar. I've checked with the phones and almost all of them 
follow this recommendation.

So I think we can use this in our advantage, by first checking the callid and 
if it's the same and the cseq is bigger than the old one, then update that 
entry and also overwrite the contact with the new one if different. Next, if 
there is no entry with that callid but there is an entry with the same 
contact field than update that entry. Of course we can use extra checks like 
cseq shouldn't be bigger than old_one+2, or that contact is the same with old 
one if using private IPs to make sure we find the right entry, but overall 
this way we have less chances to get the wrong entry than currently.

Using this we can eliminate the above mentioned problems for phones that 
follow the RFC recommendation, while for the others we continue to function 
the same way as before.

I've checked the user agents in use on my platform and how they behave in this 
regard and among them I found only one which doesn't follow this 
recommendation (DrayTek UA versions 1.1.5 through 1.2.1) and a lot that do 
(over 41 different user agents).

-- 
Dan



More information about the Devel mailing list