[asterisk-commits] kmoore: trunk r400142 - in /trunk: ./ channels/ configs/ res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Sep 30 10:57:14 CDT 2013


Author: kmoore
Date: Mon Sep 30 10:57:11 2013
New Revision: 400142

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=400142
Log:
Allow Asterisk to retry after 403 on register

This adds a global option in chan_sip to allow it to continue
attempting registration if a 403 is received, clearing the cached nonce
and treating it as a non-fatal response. Normally, this would cause
registration attempts to that endpoint to stop.

This also adds a similar per-outbound-registration option to chan_pjsip
which allows the retry interval to be altered for 403 responses to
REGISTER requests.

(closes issue ASTERISK-17138)
Review: https://reviewboard.asterisk.org/r/2874/
Reported by: Rudi
........

Merged revisions 400137 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 400140 from http://svn.asterisk.org/svn/asterisk/branches/11
........

Merged revisions 400141 from http://svn.asterisk.org/svn/asterisk/branches/12

Modified:
    trunk/   (props changed)
    trunk/CHANGES
    trunk/channels/chan_sip.c
    trunk/configs/pjsip.conf.sample
    trunk/configs/sip.conf.sample
    trunk/res/res_pjsip_outbound_registration.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-12-merged' - no diff available.

Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=400142&r1=400141&r2=400142
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Mon Sep 30 10:57:11 2013
@@ -853,6 +853,10 @@
 
  * Added 'ignore_requested_pref'. When enabled, this will use the preferred
    codecs configured for a peer instead of the requested codec.
+
+ * The option "register_retry_403" has been added to chan_sip to work around
+   servers that are known to erroneously send 403 in response to valid
+   REGISTER requests and allows Asterisk to continue attepmting to connect.
 
 chan_skinny
 ------------------

Modified: trunk/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_sip.c?view=diff&rev=400142&r1=400141&r2=400142
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Mon Sep 30 10:57:11 2013
@@ -819,6 +819,7 @@
 static int global_rtpkeepalive;     /*!< Send RTP keepalives */
 static int global_reg_timeout;      /*!< Global time between attempts for outbound registrations */
 static int global_regattempts_max;  /*!< Registration attempts before giving up */
+static int global_reg_retry_403;    /*!< Treat 403 responses to registrations as 401 responses */
 static int global_shrinkcallerid;   /*!< enable or disable shrinking of caller id  */
 static int global_callcounter;      /*!< Enable call counters for all devices. This is currently enabled by setting the peer
                                      *   call-limit to INT_MAX. When we remove the call-limit from the code, we can make it
@@ -21143,6 +21144,7 @@
 	ast_cli(a->fd, "  Sub. max duration:      %d secs\n", max_subexpiry);
 	ast_cli(a->fd, "  Outbound reg. timeout:  %d secs\n", global_reg_timeout);
 	ast_cli(a->fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
+	ast_cli(a->fd, "  Outbound reg. retry 403:%d\n", global_reg_retry_403);
 	ast_cli(a->fd, "  Notify ringing state:   %s\n", AST_CLI_YESNO(sip_cfg.notifyringing));
 	if (sip_cfg.notifyringing) {
 		ast_cli(a->fd, "    Include CID:          %s%s\n",
@@ -31373,6 +31375,7 @@
 	sip_cfg.compactheaders = DEFAULT_COMPACTHEADERS;
 	global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
 	global_regattempts_max = 0;
+	global_reg_retry_403 = 0;
 	sip_cfg.pedanticsipchecking = DEFAULT_PEDANTIC;
 	sip_cfg.autocreatepeer = DEFAULT_AUTOCREATEPEER;
 	global_autoframing = 0;
@@ -31761,6 +31764,8 @@
 			}
 		} else if (!strcasecmp(v->name, "registerattempts")) {
 			global_regattempts_max = atoi(v->value);
+		} else if (!strcasecmp(v->name, "register_retry_403")) {
+			global_reg_retry_403 = ast_true(v->value);
 		} else if (!strcasecmp(v->name, "bindaddr") || !strcasecmp(v->name, "udpbindaddr")) {
 			if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) {
 				ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);

Modified: trunk/configs/pjsip.conf.sample
URL: http://svnview.digium.com/svn/asterisk/trunk/configs/pjsip.conf.sample?view=diff&rev=400142&r1=400141&r2=400142
==============================================================================
--- trunk/configs/pjsip.conf.sample (original)
+++ trunk/configs/pjsip.conf.sample Mon Sep 30 10:57:11 2013
@@ -147,6 +147,7 @@
 ;client_uri=sip:1234567890 at sip.example.com
 ;contact_user=1234567890
 ;retry_interval=60
+;forbidden_retry_interval=600
 ;expiration=3600
 
 ;[mytrunk_auth]

Modified: trunk/configs/sip.conf.sample
URL: http://svnview.digium.com/svn/asterisk/trunk/configs/sip.conf.sample?view=diff&rev=400142&r1=400141&r2=400142
==============================================================================
--- trunk/configs/sip.conf.sample (original)
+++ trunk/configs/sip.conf.sample Mon Sep 30 10:57:11 2013
@@ -787,6 +787,9 @@
                                 ; 0 = continue forever, hammering the other server
                                 ; until it accepts the registration
                                 ; Default is 0 tries, continue forever
+;register_retry_403=yes         ; Treat 403 responses to registrations as if they were
+                                ; 401 responses and continue retrying according to normal
+                                ; retry rules.
 
 ;----------------------------------------- OUTBOUND MWI SUBSCRIPTIONS -------------------------
 ; Asterisk can subscribe to receive the MWI from another SIP server and store it locally for retrieval

Modified: trunk/res/res_pjsip_outbound_registration.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_pjsip_outbound_registration.c?view=diff&rev=400142&r1=400141&r2=400142
==============================================================================
--- trunk/res/res_pjsip_outbound_registration.c (original)
+++ trunk/res/res_pjsip_outbound_registration.c Mon Sep 30 10:57:11 2013
@@ -85,6 +85,17 @@
 				<configOption name="retry_interval" default="60">
 					<synopsis>Interval in seconds between retries if outbound registration is unsuccessful</synopsis>
 				</configOption>
+				<configOption name="forbidden_retry_interval" default="0">
+					<synopsis>Interval used when receiving a 403 Forbidden response.</synopsis>
+					<description><para>
+						If a 403 Forbidden is received, chan_pjsip will wait
+						<replaceable>forbidden_retry_interval</replaceable> seconds before
+						attempting registration again. If 0 is specified, chan_pjsip will not
+						retry after receiving a 403 Forbidden response. Setting this to a non-zero
+						value goes against a "SHOULD NOT" in RFC3261, but can be used to work around
+						buggy registrars.
+					</para></description>
+				</configOption>
 				<configOption name="server_uri">
 					<synopsis>SIP URI of the server to register against</synopsis>
 					<description><para>
@@ -159,6 +170,8 @@
 	unsigned int max_retries;
 	/*! \brief Interval at which retries should occur for temporal responses */
 	unsigned int retry_interval;
+	/*! \brief Interval at which retries should occur for permanent responses */
+	unsigned int forbidden_retry_interval;
 	/*! \brief Treat authentication challenges that we cannot handle as permanent failures */
 	unsigned int auth_rejection_permanent;
 	/*! \brief Serializer for stuff and things */
@@ -198,6 +211,8 @@
 	unsigned int expiration;
 	/*! \brief Interval at which retries should occur for temporal responses */
 	unsigned int retry_interval;
+	/*! \brief Interval at which retries should occur for permanent responses */
+	unsigned int forbidden_retry_interval;
 	/*! \brief Treat authentication challenges that we cannot handle as permanent failures */
 	unsigned int auth_rejection_permanent;
 	/*! \brief Maximum number of retries permitted */
@@ -412,10 +427,21 @@
 				response->code, server_uri, client_uri, response->client_state->retry_interval);
 		}
 	} else {
-		/* Finally if there's no hope of registering give up */
-		response->client_state->status = SIP_REGISTRATION_REJECTED_PERMANENT;
-		ast_log(LOG_WARNING, "Fatal response '%d' received from '%s' on registration attempt to '%s', stopping outbound registration\n",
-			response->code, server_uri, client_uri);
+		if (response->code == 403
+			&& response->client_state->forbidden_retry_interval
+			&& response->client_state->retries < response->client_state->max_retries) {
+			/* A forbidden response retry interval is configured and there are retries remaining */
+			response->client_state->status = SIP_REGISTRATION_REJECTED_TEMPORARY;
+			response->client_state->retries++;
+			schedule_registration(response->client_state, response->client_state->forbidden_retry_interval);
+			ast_log(LOG_WARNING, "403 Forbidden fatal response received from '%s' on registration attempt to '%s', retrying in '%d' seconds\n",
+				server_uri, client_uri, response->client_state->forbidden_retry_interval);
+		} else {
+			/* Finally if there's no hope of registering give up */
+			response->client_state->status = SIP_REGISTRATION_REJECTED_PERMANENT;
+			ast_log(LOG_WARNING, "Fatal response '%d' received from '%s' on registration attempt to '%s', stopping outbound registration\n",
+				response->code, server_uri, client_uri);
+		}
 	}
 
 	ast_system_publish_registry("PJSIP", client_uri, server_uri, sip_outbound_registration_status_str[response->client_state->status], NULL);
@@ -716,6 +742,7 @@
 	}
 	registration->state->client_state->outbound_auths.num = registration->outbound_auths.num;
 	registration->state->client_state->retry_interval = registration->retry_interval;
+	registration->state->client_state->forbidden_retry_interval = registration->forbidden_retry_interval;
 	registration->state->client_state->max_retries = registration->max_retries;
 	registration->state->client_state->retries = 0;
 
@@ -911,6 +938,7 @@
 	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, outbound_proxy));
 	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "expiration", "3600", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, expiration));
 	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "retry_interval", "60", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, retry_interval));
+	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "forbidden_retry_interval", "0", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, forbidden_retry_interval));
 	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "max_retries", "10", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, max_retries));
 	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "auth_rejection_permanent", "yes", OPT_BOOL_T, 1, FLDSET(struct sip_outbound_registration, auth_rejection_permanent));
 	ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "registration", "outbound_auth", "", outbound_auth_handler, NULL, 0, 0);




More information about the asterisk-commits mailing list