Changes between Version 37 and Version 38 of FAQ

May 4, 2008 11:55:25 AM (16 years ago)



  • FAQ

    v37 v38  
     657=== I'm trying to register to a server, but PJSIP treats the 200/OK response as unregistration. Why? === #regc 
     659Since circa version 0.8, the registration client session (pjsip_regc.c) has stricter checks on the Contact header(s) sent by registrar in the 200/OK response to REGISTER request. This is necessary to support multiple registrations (the same AOR is registered more than once in the server by multiple user agents), and this is how it is supposed to be done in the first place according to RFC 3261. 
     661Unfortunately this breaks "compatibility" with some servers, because these servers incorrectly return different Contact header(s) in the response, causing PJSIP to fail to find it's registered Contact header. When this happens, PJSIP will treat the response as unregistration response, regardless whether it's a successful (200 class) response. 
     663The treatment of Contact header(s) in REGISTER response are specified in ''Section 10.2.4 Refreshing Bindings'' of RFC 3261: 
     664  ''"The 200 (OK) response from the registrar contains a list of Contact fields enumerating all current 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."'' 
     667Some common mistakes by the server: 
     668 1. Server modifies the Contact header when client is behind NAT. For example, client (PJSIP) sends this REGISTER request with private IP address in the Contact: 
     669    {{{ 
     670     REGISTER SIP/2.0 
     671     Contact: <sip:user@> 
     672     .. 
     673    }}} 
     674    and server responds with this response which modifies the Contact header with the source (public) address of the request: 
     675    {{{ 
     676     SIP/2.0 200 OK 
     677     Contact: <sip:user@>;expires=300 
     678     .. 
     679    }}} 
     680    This for example happens with wrong configuration in (Open)SER, where the configuration script uses '''fix_nated_contact()''' instead of '''fix_nated_register()''' in the registration handler. 
     681 1. Server does not return the '''exact''' URI in the response, causing URI comparison (to find the registered Contact header in the response) to fail. The URI comparison rules are very strict, and they are described in ''Section 19.1.4 URI Comparison'' of RFC 3261. Particularly, one has to note the bullet 5 of Section 19.1.4: 
     682      ''"A URI omitting any component with a default value will not match a URI explicitly containing that component with its default value."'' 
     684 This means these two URI's are '''not equivalent''' (port number is not specified, eventhough it's the default): 
     685   {{{<sip:user@>}}} [[BR]] 
     686   {{{<sip:user@>}}} 
     688 And neither are these (transport parameter is omitted, eventhough it's the default): 
     689   {{{<sip:user@;transport=udp>}}} [[BR]] 
     690   {{{<sip:user@>}}} 
     692==== Solutions ==== 
     693There are few solutions to handle this situation: 
     694 a. If the server is (Open)SER, use '''fix_nated_contact()''' instead of '''fix_nated_register()''' in the registration handler. 
     695 a. For other servers, fix the server because it violates the standard. 
     696 a. And finally as the last resort if you are unable to do the above, you can disable the strict registration Contact header checking in PJSIP. There are couple of new configuration options introduced in PJSIP v0.9 to control this: 
     697    - to disable the strict checks on compile time, declare this in your {{{config_site.h}}}: 
     698      {{{ 
     700      }}} 
     701    - to disable the check on run-time, add this statement anywhere before sending the REGISTER request (you may do this even before initializing PJSIP) to change the process wide setting: 
     702      {{{ 
     703      #include <pjsip/sip_config.h> 
     705      pjsip_cfg()->regc.check_contact = PJ_FALSE; 
     706      }}} 
     707 When the strict check is disabled, the client registration session will calculate the expiration time (which determines whether it should treat the resposne as successful registration or unregistration) with the following rule instead: 
     708    - it will skip the Contact headers and get the expiration time from the ''Expires'' header instead. 
     709    - when ''Expires'' header is not present, it will get the value from the expires parameter of the Contact header, regardless of the URI specified in the Contact header