[Serdev] contribution: SER module implementing Path extension (RFC 3327)

Fermín Galán Márquez fermin.galan at agora-2000.com
Wed Jun 8 15:44:17 UTC 2005


Deear Dragos,

Please find comments inline.

>> The module provides two functions:
>>
>> store_path(): store the content of the "Path" header in the request into
>> a very simple database: key is the SIP URI in "From" (note that 
>> store_path() it's intended to be used during registration in registrar 
>> servers) and value is the "Path" content.
>  
> This is a good start as you can actually call the function to save this
> from the script. But here as an excerpt from TS 24.229 section
>
> 5.4.1.2.2   Protected REGISTER
>
>> 7) check whether a Path header was included in the REGISTER request
>> and construct a list of preloaded Route headers from the list of
>> entries in the Path header. The S-CSCF shall preserve the order of the
>> preloaded Route headers and bind them to the contact information that
>> was received in the REGISTER message;
>>
>> NOTE 4: If this registration is a reregistration, then a list of
>> pre-loaded Route headers will already exist. The new list replaces the
>> old list.
>
> - it must be a list - it would be great if you fixed that bug ;-) - also
> it's preloaded and I assume that you can save the entire content of the
> header as a simple text and later paste the entire thing into  a Route.

Right. The current implementation is limited to just one element in the Path
header (therefore, just one element in the Route header). I think that
overcome this limitation ("fixing the bug" as you said) is easy just playing
around with C "dirty" :) text manipulations.

However, AFAIK, the current utilization of RFC3327 in the 3GPP specs only
needs one element in the Path header: the SIP URI of the P-CSCF associated
with the user.

In addition, note that storing the list as an opaque string from the Path
then pasting into Route could be problematic: Path is something like:

Path: <sip:term at pcsf1.visited1.net;lr>

and the derived Route something like

Route: <sip:pcscf1.visisted1.net;lr>

The 'term' token (corresponding to user in the URL) need to be removed.

> - never trust the From/To header - there are other trustable headers in
> IMS, like P-Asserted-Identity, so binding it to the From is not a good
> ideea as the From can be faked.

>From RFC 3327 (section "5.3 Procudures at registrar")

   If a Path header field exists in a successful REGISTER request, the
   registrar constructs an ordered list of route elements (a path
   vector) from the nodes listed in the Path header field values,
   preserving the order as indicated in the Path header field values.
   *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 [RFC3261])*.  The registrar copies the Path
   header field values into a Path header field in the successful (200
   class) REGISTER response.  In the event that the home proxy and
   registrar are not co-located, the registrar MAY apply a locally-
   determined transformation to the stored path vector.

And RFC3261 states registration bindings are To/From<->Contact associations.
Could you tell me the 3GPP reference that states the registration binding
must be done using P-Asserted-Identity<->Contact instead the standard
procedure, please?

However, if a different address needs to be used as key, just change
HDR_FROM and msg->from in lines 911 and 9112 of path.c with the desired
headers.

> - I am binding it to a contact address as to a SIP URI found in a
> header. Because of the Private/Public Identity mappings in IMS you could
> have many public identities implicitly registered on a single UE and
> maybe just one of them would have the Path saved correctly. Anyway, to
> conclude, the Path is actually used to find the P-CSCF through which the
> UE can be reached, so this is one more reason why this info must pe
> mapped to the contact address of the UE.

AFAIK, a user could have registered several Public addresses, but each
Public address is in fact a different address-of-record SIP URI with an
associated Contact address. Therefore, each AoR<->Contact has associated a
different Path. Or maybe I didn't understand the problem you are explaining?

>>route_based_path(): retrieves the stored value (using the SIP URI in the
>>Request URI as key), put it in a "Route" header and forward the request to
>>that destination.  
>
>it is actually path_based_route(), right? ;-).

Right :)

>> Note that the code is very primitive, more a "proof-of-concept" that a
>> strong and smart implementation. However, I think it could be interesting
>> for others, which maybe want to help to improve it. We aren't SER gurus 
>> :) and maybe there are clever and smarter ways to do the same things in 
>> the code. For example, putting the "Route" header in a smarter place (the
>> current implementation put "Route" always after all other headers, that 
>> is valid but not recommended in RFC 3261).  
>
> I would suggest to put in in the registrar as this info is very similar
> for example to NAT info. I also wanted to do this at first, but ended
> with implementing my own registrar from ground up.

I don't know the internals of SER registrar, therefore I use simple
approaches. Maybe the contribution of a SER guru could improve this :)

> Also, put it as the first Route in the message because in various spots
> the 3GPPs specs say that a CSCF should check the first Route header if
> it is equal to itself and then act accordingly. So here your
> implementation would break. And also if node A receives a message with
> Route: B, A it should first route it through B then B will route back to 
> A.
>
> Here is how I do it
> /**
> * Adds a header to the message as the first one in the message
> * @param msg - the message to add a header to
> * @param content - the str containing the new header
> * @returns 1 on succes, 0 on failure
> */
> int cscf_add_header_first(struct sip_msg *msg, str *hdr)
> {
> [...]
> }
>
> I know that the SIP gurus will argument that it would nicer to add it
> actually after the last Via...

We've implemented three different functions to add the header in path.c
(add_hf_after_all, add_hf_before_all, add_hf_after_max_forwards), but no one
definitively satisfied us. I think your implementation is close to
add_hf_before_all.

As you say, the best place to put the Route header is after the last Via.
We've tried to do so, but programming with lumps is a bit confusing. Maybe
somebody could help, please?

Thank you very much for your comments. We're still working on the module
development and we'll post new versions (maybe the contrib location in the
CVS is the appropriate place), but, in the meanwhile, any contribution to
the code (maybe yours :) is very welcome.

Best regards,

------
Fermín
Agora Systems, S. A.




More information about the Serdev mailing list