Make PJSUA always retry account registration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hey folks,

I was facing a problem regarding PJSUA account registration.
In our environment, our SIP hosts (servers as well as endpoints) are reconfigured on a regular basis and in some cases, somebody makes a mistake which might lead to request failures.

The problem is, that PJSUA stops retrying to register an account when it gets some kind of error that is considered 'permanent'. In my case, I mistyped a user name and (of course) subsequent registration refresh requests were answered with "404 - Not found". This lead to our testclient reporting the error but then not attempting to ever retry the registration.

After looking at the docs, I found that this is indeed expected behaviour.
However, in the application callback I didn't find a clear way on how to figure out whether the failure the callback is reporting is now considered permanent (yes, there are the docs, but what if the definition changes in some future version?).

This error behaviour is something I have observed 'in the wild' as well.
The case there was some kind of server error, where another server went up to take over. This takeover however took a couple of seconds in which requests failed (in some cases with "404 - Not found").

To get around this, I added an additional option to PJSUA acc to make PJSUA _always_ retry the registration, no matter what the remote peer answers with.
The default behaviour is left as is.
Please see the attachment for the patch.

If someone has a better solution to this, I'm all ears :-)

Best Regards,
Andreas Wehrmann

diff -uNr pjproject-2.9.orig/pjsip/include/pjsua-lib/pjsua.h pjproject-2.9/pjsip/include/pjsua-lib/pjsua.h
--- pjproject-2.9.orig/pjsip/include/pjsua-lib/pjsua.h	2020-02-17 12:43:12.882880787 +0100
+++ pjproject-2.9/pjsip/include/pjsua-lib/pjsua.h	2020-02-17 13:02:49.106745549 +0100
@@ -3620,6 +3620,14 @@
      * Default: PJSUA_UNREG_TIMEOUT
      */
     unsigned	    unreg_timeout;
+    
+    /**
+     * Always attempt reregistration,
+     * even if the remote peer indicates a permanent error.
+     *
+     * Default: PJ_FALSE
+     */
+    pj_bool_t       reg_always_retry;
 
     /** 
      * Number of credentials in the credential array.
diff -uNr pjproject-2.9.orig/pjsip/src/pjsua-lib/pjsua_acc.c pjproject-2.9/pjsip/src/pjsua-lib/pjsua_acc.c
--- pjproject-2.9.orig/pjsip/src/pjsua-lib/pjsua_acc.c	2020-02-17 12:43:12.878880803 +0100
+++ pjproject-2.9/pjsip/src/pjsua-lib/pjsua_acc.c	2020-02-17 13:03:39.182600034 +0100
@@ -1259,6 +1259,7 @@
 	update_reg = PJ_TRUE;
     }
     acc->cfg.unreg_timeout = cfg->unreg_timeout;
+    acc->cfg.reg_always_retry = cfg->reg_always_retry;
     acc->cfg.allow_contact_rewrite = cfg->allow_contact_rewrite;
     acc->cfg.reg_retry_interval = cfg->reg_retry_interval;
     acc->cfg.reg_first_retry_interval = cfg->reg_first_retry_interval;
@@ -2271,6 +2272,7 @@
 {
 
     pjsua_acc *acc = (pjsua_acc*) param->token;
+    pj_bool_t reg_fail = PJ_FALSE;
 
     PJSUA_LOCK();
 
@@ -2288,6 +2290,7 @@
 	pjsua_perror(THIS_FILE, "SIP registration error", 
 		     param->status);
 	pjsip_regc_destroy(acc->regc);
+	reg_fail = PJ_TRUE;
 	acc->regc = NULL;
 	acc->contact.slen = 0;
 	acc->reg_mapped_addr.slen = 0;
@@ -2301,6 +2304,7 @@
 		   param->code, 
 		   (int)param->reason.slen, param->reason.ptr));
 	pjsip_regc_destroy(acc->regc);
+	reg_fail = PJ_TRUE;
 	acc->regc = NULL;
 	acc->contact.slen = 0;
 	acc->reg_mapped_addr.slen = 0;
@@ -2388,13 +2392,14 @@
      * considered to be recoverable in relatively short term.
      */
     if (acc->cfg.reg_retry_interval && 
-	(param->code == PJSIP_SC_REQUEST_TIMEOUT ||
+	((param->code == PJSIP_SC_REQUEST_TIMEOUT ||
 	 param->code == PJSIP_SC_INTERNAL_SERVER_ERROR ||
 	 param->code == PJSIP_SC_BAD_GATEWAY ||
 	 param->code == PJSIP_SC_SERVICE_UNAVAILABLE ||
 	 param->code == PJSIP_SC_SERVER_TIMEOUT ||
 	 param->code == PJSIP_SC_TEMPORARILY_UNAVAILABLE ||
-	 PJSIP_IS_STATUS_IN_CLASS(param->code, 600))) /* Global failure */
+	 PJSIP_IS_STATUS_IN_CLASS(param->code, 600))   /* Global failure */
+	 || (reg_fail == PJ_TRUE && acc->cfg.reg_always_retry)))
     {
 	schedule_reregistration(acc);
     }
_______________________________________________
Visit our blog: http://blog.pjsip.org

pjsip mailing list
pjsip@xxxxxxxxxxxxxxx
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

[Index of Archives]     [Asterisk Users]     [Asterisk App Development]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [Linux API]
  Powered by Linux