Ticket #534 (closed enhancement: fixed)
Client register/registration support for various registrar brokenness
|Reported by:||bennylp||Owned by:||bennylp|
|Backport to 1.x milestone:||Backported:|
Since 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.
Unfortunately 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 treated the response as unregistration response, regardless whether it's a successful (200 class) response.
This ticket implements new expiration calculation algorithm to improve compatibility with these broken registrars. To calculate the expiration value, when successful response to registration is received:
- First it tries to match the URI returned in the response using URI comparison rule in RFC 3261 Section 19.1.4. If application doesn't want this URI comparison, it can disable it by setting PJ_FALSE to pjsip_cfg()->regc.check_contact run-time setting or PJSIP_REGISTER_CLIENT_CHECK_CONTACT. However now it's not recommended to disable this checking since the algorithm will fallback to the processing below anyway.
- If it couldn't find the contact URI, and if pjsip_cfg()->regc.add_xuid_param is non-zero (default value is PJSIP_REGISTER_CLIENT_ADD_XUID_PARAM, which is zero), then the client registration will add an extension parameter to the contacts that it registers, then match the contacts in the response by just matching this parameter. So even when the registrar modifies the host part of the contact URI, it will still be matched as long as the registrar returns all the parameters in the URI unmodified. This process is by default disabled since it adds non-standard extension parameter to the Contact, and it will cause incoming INVITE to the client to contain this additional parameter, which although is harmless, may not be expected by the client.
- If no matching contact is found, it checks whether the response contains same number of contacts as in the session. If it does, then assumes that we are the only user agent registering for the AOR, hence we can get the expiration value from the response.
- For all the steps above, the expiration value will be taken from the expires parameter of the Contact header. If no expires parameter is found, or if no matching contact is found at this stage, get the expiration value from Expires header if it's present, or from the expiration set in the request, or failing all that, set the expiration to 3600 (the default value for malformed REGISTER request/response according to RFC 3261).
Thanks Alan J. Bond and Electrocut for the discussions over this topic on PJSIP list.