[asterisk-commits] file: branch file/pimp_sip_registration r382898 - in /team/file/pimp_sip_regi...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Mar 12 14:03:13 CDT 2013


Author: file
Date: Tue Mar 12 14:03:09 2013
New Revision: 382898

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=382898
Log:
Implement retry functionality.

Modified:
    team/file/pimp_sip_registration/include/asterisk/res_sip.h
    team/file/pimp_sip_registration/res/res_sip_outbound_registration.c

Modified: team/file/pimp_sip_registration/include/asterisk/res_sip.h
URL: http://svnview.digium.com/svn/asterisk/team/file/pimp_sip_registration/include/asterisk/res_sip.h?view=diff&rev=382898&r1=382897&r2=382898
==============================================================================
--- team/file/pimp_sip_registration/include/asterisk/res_sip.h (original)
+++ team/file/pimp_sip_registration/include/asterisk/res_sip.h Tue Mar 12 14:03:09 2013
@@ -143,22 +143,6 @@
 	unsigned int remove_existing;
 	/*! Any statically configured contacts */
 	struct ao2_container *static_contacts;
-};
-
-/*!
- * \brief Outbound registration
- */
-struct ast_sip_registration {
-	AST_DECLARE_STRING_FIELDS(
-		/*! Username for the registration */
-		AST_STRING_FIELD(username);
-		/*! Password for the registration */
-		AST_STRING_FIELD(password);
-	);
-	/*! Host to send registration to. Address and port */
-	struct ast_sockaddr host;
-	/*! Next registration in the list */
-	AST_LIST_ENTRY(ast_sip_registration) next;
 };
 
 /*!

Modified: team/file/pimp_sip_registration/res/res_sip_outbound_registration.c
URL: http://svnview.digium.com/svn/asterisk/team/file/pimp_sip_registration/res/res_sip_outbound_registration.c?view=diff&rev=382898&r1=382897&r2=382898
==============================================================================
--- team/file/pimp_sip_registration/res/res_sip_outbound_registration.c (original)
+++ team/file/pimp_sip_registration/res/res_sip_outbound_registration.c Tue Mar 12 14:03:09 2013
@@ -50,6 +50,10 @@
 	pjsip_regc *client;
 	/*! \brief Timer entry for retrying on temporal responses */
 	pj_timer_entry timer;
+	/*! \brief Current number of retries */
+	unsigned int retries;
+	/*! \brief Maximum number of retries permitted */
+	unsigned int max_retries;
 	/*! \brief Interval at which retries should occur for temporal responses */
 	unsigned int retry_interval;
 };
@@ -75,6 +79,8 @@
 	unsigned int expiration;
 	/*! \brief Interval at which retries should occur for temporal responses */
 	unsigned int retry_interval;
+	/*! \brief Maximum number of retries permitted */
+	unsigned int max_retries;
 	/*! \brief Outbound registration state */
 	struct sip_outbound_registration_state *state;
 };
@@ -91,23 +97,54 @@
 	pjsip_regc_send(entry->user_data, tdata);
 }
 
+/* \brief Helper funtion which determines if a response code is temporal or not */
+static int sip_outbound_registration_is_temporal(unsigned int code)
+{
+	/* Shamelessly taken from pjsua */
+	if (code == PJSIP_SC_REQUEST_TIMEOUT ||
+	 	code == PJSIP_SC_INTERNAL_SERVER_ERROR ||
+	 	code == PJSIP_SC_BAD_GATEWAY ||
+	 	code == PJSIP_SC_SERVICE_UNAVAILABLE ||
+	 	code == PJSIP_SC_SERVER_TIMEOUT ||
+		PJSIP_IS_STATUS_IN_CLASS(code, 600)) {
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
 /*! \brief Callback function for outbound registration client */
 static void sip_outbound_registration_response_cb(struct pjsip_regc_cbparam *param)
 {
 	struct sip_outbound_registration_state *state = param->token;
 	pjsip_regc_info info;
+	char server_uri[PJSIP_MAX_URL_SIZE], client_uri[PJSIP_MAX_URL_SIZE];
+
 	pjsip_regc_get_info(param->regc, &info);
+	ast_copy_pj_str(server_uri, &info.server_uri, sizeof(server_uri));
+	ast_copy_pj_str(client_uri, &info.client_uri, sizeof(client_uri));
 
 	if (PJSIP_IS_STATUS_IN_CLASS(param->code, 200)) {
 		/* Registration was accepted, yahoo! */
 		state->status = SIP_REGISTRATION_REGISTERED;
+	} else if (state->retry_interval && sip_outbound_registration_is_temporal(param->code)) {
+		if (state->retries == state->max_retries) {
+			state->status = SIP_REGISTRATION_REJECTED_PERMANENT;
+			ast_log(LOG_WARNING, "Maximum retries reached when attempting outbound registration to '%s' with client '%s', stopping registration attempt\n",
+				server_uri, client_uri);;
+		} else {
+			pj_time_val delay = { .sec = state->retry_interval, };
+
+			state->status = SIP_REGISTRATION_REJECTED_TEMPORARY;
+			state->retries++;
+			pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(), &state->timer, &delay);
+			ast_log(LOG_WARNING, "Temporal response '%d' received from '%s' on registration attempt to '%s', retrying in '%d' seconds\n",
+				param->code, server_uri, client_uri, state->retry_interval);
+		}
 	} else {
-		pj_time_val delay = { .sec = 5, };
-
 		state->status = SIP_REGISTRATION_REJECTED_PERMANENT;
-
-		ast_log(LOG_NOTICE, "Registration failed\n");
-		pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(), &state->timer, &delay);
+		ast_log(LOG_WARNING, "Fatal response '%d' received from '%s' on registration attempt to '%s', stopping outbound registration\n",
+			param->code, server_uri, client_uri);
 	}
 }
 
@@ -319,8 +356,9 @@
 	struct sip_outbound_registration *registration = obj;
 	pj_time_val delay = { .sec = 1, };
 
-	/* We update the retry interval in case it has changed, as it can be */
 	registration->state->retry_interval = registration->retry_interval;
+	registration->state->max_retries = registration->max_retries;
+	registration->state->retries = 0;
 
 	pjsip_regc_update_expires(registration->state->client, registration->expiration);
 
@@ -361,6 +399,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", "max_retries", "10", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, max_retries));
 	ast_sorcery_reload_object(ast_sip_get_sorcery(), "registration");
 	sip_outbound_registration_perform_all();
 




More information about the asterisk-commits mailing list