[Asterisk-code-review] res pjsip outbound registration: registration stops due to 4... (asterisk[certified/13.1])

Kevin Harwell asteriskteam at digium.com
Wed Oct 21 12:46:35 CDT 2015


Kevin Harwell has uploaded a new change for review.

  https://gerrit.asterisk.org/1474

Change subject: res_pjsip_outbound_registration: registration stops due to 400 response
......................................................................

res_pjsip_outbound_registration: registration stops due to 400 response

When Asterisk sends outbound registrations to a registrar, due to possible
problems with the registrar it will sometimes send back a 400 thus Asterisk
ceases registration for the given endpoint.

Added an option 'fatal_retry_interval' that allows registration to continue
for any fatal/permanent response that is received.

Change-Id: Ibc2c7b47164ac89cc803433c0bbe7063bfa143a2
---
M CHANGES
M configs/samples/pjsip.conf.sample
A contrib/ast-db-manage/config/versions/28ce1e718f05_add_fatal_response_interval.py
M res/res_pjsip_outbound_registration.c
4 files changed, 56 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/74/1474/1

diff --git a/CHANGES b/CHANGES
index 9127f08..5629856 100644
--- a/CHANGES
+++ b/CHANGES
@@ -28,6 +28,13 @@
   before terminating the call due to lack of received RTP. These are identical
   to chan_sip's rtptimeout and rtpholdtimeout options.
 
+res_pjsip_outbound_registration
+-------------------------------
+* A new 'fatal_retry_internal' option has been added to outbound registration.
+  When set (default is zero), and upon receiving a failure response to an
+  outbound registration, registration is retried at the given interval up to
+  'max_retries'.
+
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 13.1.0-cert1 to Asterisk 13.1-cert2 --
 ------------------------------------------------------------------------------
diff --git a/configs/samples/pjsip.conf.sample b/configs/samples/pjsip.conf.sample
index 78de2cd..9c41714 100644
--- a/configs/samples/pjsip.conf.sample
+++ b/configs/samples/pjsip.conf.sample
@@ -910,6 +910,8 @@
                         ; registration is unsuccessful (default: "60")
 ;forbidden_retry_interval=0     ; Interval used when receiving a 403 Forbidden
                                 ; response (default: "0")
+;fatal_retry_interval=0     ; Interval used when receiving a fatal response
+                            ; (default: "0")
 ;server_uri=    ; SIP URI of the server to register against (default: "")
 ;transport=     ; Transport used for outbound authentication (default: "")
 ;type=  ; Must be of type registration (default: "")
diff --git a/contrib/ast-db-manage/config/versions/28ce1e718f05_add_fatal_response_interval.py b/contrib/ast-db-manage/config/versions/28ce1e718f05_add_fatal_response_interval.py
new file mode 100644
index 0000000..b9ee6e8
--- /dev/null
+++ b/contrib/ast-db-manage/config/versions/28ce1e718f05_add_fatal_response_interval.py
@@ -0,0 +1,22 @@
+"""add fatal_response_interval
+
+Revision ID: 28ce1e718f05
+Revises: 26f10cadc157
+Create Date: 2015-10-20 17:57:45.560585
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '28ce1e718f05'
+down_revision = '26f10cadc157'
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+    op.add_column('ps_registrations', sa.Column('fatal_retry_interval', sa.Integer))
+
+
+def downgrade():
+    op.drop_column('ps_registrations', 'fatal_retry_interval')
diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c
index 8cf8106..6d65cf8 100644
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -99,6 +99,17 @@
 						buggy registrars.
 					</para></description>
 				</configOption>
+				<configOption name="fatal_retry_interval" default="0">
+					<synopsis>Interval used when receiving a Fatal response.</synopsis>
+					<description><para>
+						If a fatal response is received, chan_pjsip will wait
+						<replaceable>fatal_retry_interval</replaceable> seconds before
+						attempting registration again. If 0 is specified, chan_pjsip will not
+						retry after receiving a fatal response. Setting this to a non-zero
+						value may go 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>
@@ -236,6 +247,8 @@
 	unsigned int retry_interval;
 	/*! \brief Interval at which retries should occur for permanent responses */
 	unsigned int forbidden_retry_interval;
+	/*! \brief Interval at which retries should occur for all permanent responses */
+	unsigned int fatal_retry_interval;
 	/*! \brief Treat authentication challenges that we cannot handle as permanent failures */
 	unsigned int auth_rejection_permanent;
 	/*! \brief Maximum number of retries permitted */
@@ -266,6 +279,8 @@
 	unsigned int retry_interval;
 	/*! \brief Interval at which retries should occur for permanent responses */
 	unsigned int forbidden_retry_interval;
+	/*! \brief Interval at which retries should occur for all permanent responses */
+	unsigned int fatal_retry_interval;
 	/*! \brief Treat authentication challenges that we cannot handle as permanent failures */
 	unsigned int auth_rejection_permanent;
 	/*! \brief Determines whether SIP Path support should be advertised */
@@ -666,6 +681,14 @@
 			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 '%u' seconds\n",
 				server_uri, client_uri, response->client_state->forbidden_retry_interval);
+		} else if (response->client_state->fatal_retry_interval
+			   && response->client_state->retries < response->client_state->max_retries) {
+			/* Some kind of fatal failure response received, so retry according to configured interval */
+			response->client_state->status = SIP_REGISTRATION_REJECTED_TEMPORARY;
+			response->client_state->retries++;
+			schedule_registration(response->client_state, response->client_state->fatal_retry_interval);
+			ast_log(LOG_WARNING, "'%d' fatal response received from '%s' on registration attempt to '%s', retrying in '%u' seconds\n",
+				response->code, server_uri, client_uri, response->client_state->fatal_retry_interval);
 		} else {
 			/* Finally if there's no hope of registering give up */
 			response->client_state->status = SIP_REGISTRATION_REJECTED_PERMANENT;
@@ -1010,6 +1033,7 @@
 	}
 	state->client_state->retry_interval = registration->retry_interval;
 	state->client_state->forbidden_retry_interval = registration->forbidden_retry_interval;
+	state->client_state->fatal_retry_interval = registration->fatal_retry_interval;
 	state->client_state->max_retries = registration->max_retries;
 	state->client_state->retries = 0;
 	state->client_state->support_path = registration->support_path;
@@ -1672,6 +1696,7 @@
 	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", "fatal_retry_interval", "0", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, fatal_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, outbound_auths_to_str, outbound_auths_to_var_list, 0, 0);

-- 
To view, visit https://gerrit.asterisk.org/1474
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibc2c7b47164ac89cc803433c0bbe7063bfa143a2
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: certified/13.1
Gerrit-Owner: Kevin Harwell <kharwell at digium.com>



More information about the asterisk-code-review mailing list