[svn-commits] file: branch file/pimp_sip_registration r383538 - /team/file/pimp_sip_registr...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Mar 21 14:56:25 CDT 2013


Author: file
Date: Thu Mar 21 14:56:22 2013
New Revision: 383538

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383538
Log:
Incorporate some of the review feedback.

Modified:
    team/file/pimp_sip_registration/res/res_sip_outbound_registration.c
    team/file/pimp_sip_registration/res/res_sip_registrar.c

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=383538&r1=383537&r2=383538
==============================================================================
--- team/file/pimp_sip_registration/res/res_sip_outbound_registration.c (original)
+++ team/file/pimp_sip_registration/res/res_sip_outbound_registration.c Thu Mar 21 14:56:22 2013
@@ -108,10 +108,10 @@
 {
 	/* 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 ||
+		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 {
@@ -133,6 +133,7 @@
 	if (PJSIP_IS_STATUS_IN_CLASS(param->code, 200)) {
 		/* Registration was accepted, yahoo! */
 		state->status = SIP_REGISTRATION_REGISTERED;
+		state->retries = 0;
 	} else if (state->retry_interval && sip_outbound_registration_is_temporal(param->code)) {
 		if (state->retries == state->max_retries) {
 			state->status = SIP_REGISTRATION_REJECTED_PERMANENT;
@@ -164,7 +165,7 @@
 		return;
 	}
 
-	if (state->status != SIP_REGISTRATION_UNREGISTERED) {
+	if (state->status != SIP_REGISTRATION_UNREGISTERED && state->status != SIP_REGISTRATION_REJECTED_PERMANENT) {
 		pjsip_endpt_cancel_timer(ast_sip_get_pjsip_endpoint(), state->timer);
 		state->timer->id = 2;
 		pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(), state->timer, &delay);
@@ -180,7 +181,9 @@
 
 	if (!state) {
 		return NULL;
-	} else if ((pjsip_regc_create(ast_sip_get_pjsip_endpoint(), state, sip_outbound_registration_response_cb, &state->client) != PJ_SUCCESS) ||
+	}
+
+	if ((pjsip_regc_create(ast_sip_get_pjsip_endpoint(), state, sip_outbound_registration_response_cb, &state->client) != PJ_SUCCESS) ||
 		!(state->timer = PJ_POOL_ZALLOC_T(pjsip_regc_get_pool(state->client), struct pj_timer_entry))) {
 		ao2_cleanup(state);
 		return NULL;
@@ -200,6 +203,8 @@
 	struct sip_outbound_registration *registration = obj;
 
 	ao2_cleanup(registration->state);
+
+	ast_string_field_free_memory(registration);
 }
 
 /*! \brief Allocator function for registration information */
@@ -282,10 +287,7 @@
 	pj_str_t server_uri, client_uri, contact_uri;
 	pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
 
-	if (applied->state) {
-		/* Registration state already exists, roll with it */
-		return 0;
-	} else if (!existing) {
+	if (!existing) {
 		/* If no existing registration exists we can just start fresh easily */
 		applied->state = sip_outbound_registration_state_alloc();
 	} else {
@@ -302,7 +304,9 @@
 
 	if (!applied->state) {
 		return -1;
-	} else if (!ast_strlen_zero(applied->transport)) {
+	}
+
+	if (!ast_strlen_zero(applied->transport)) {
 		RAII_VAR(struct ast_sip_transport *, transport, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", applied->transport), ao2_cleanup);
 
 		if (!transport || !transport->state) {
@@ -381,7 +385,7 @@
 		return;
 	}
 
-	ao2_callback(registrations, OBJ_NODATA | OBJ_MULTIPLE, sip_outbound_registration_perform, NULL);
+	ao2_callback(registrations, OBJ_NODATA, sip_outbound_registration_perform, NULL);
 }
 
 static int load_module(void)

Modified: team/file/pimp_sip_registration/res/res_sip_registrar.c
URL: http://svnview.digium.com/svn/asterisk/team/file/pimp_sip_registration/res/res_sip_registrar.c?view=diff&rev=383538&r1=383537&r2=383538
==============================================================================
--- team/file/pimp_sip_registration/res/res_sip_registrar.c (original)
+++ team/file/pimp_sip_registration/res/res_sip_registrar.c Thu Mar 21 14:56:22 2013
@@ -39,8 +39,7 @@
 	if (contact->expires != -1) {
 		/* Expiration was provided with the contact itself */
 		expiration = contact->expires;
-	}
-	else if ((expires = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
+	} else if ((expires = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
 		/* Expiration was provided using the Expires header */
 		expiration = expires->ivalue;
 	}
@@ -53,41 +52,56 @@
 	/* Enforce the range that we will allow for expiration */
 	if (expiration < aor->minimum_expiration) {
 		expiration = aor->minimum_expiration;
-	}
-	else if (expiration > aor->maximum_expiration) {
+	} else if (expiration > aor->maximum_expiration) {
 		expiration = aor->maximum_expiration;
 	}
 
 	return expiration;
 }
+
+/*! \brief Structure used for finding contact */
+struct registrar_contact_details {
+	/*! \brief Pool used for parsing URI */
+	pj_pool_t *pool;
+	/*! \brief URI being looked for */
+	pjsip_uri *uri;
+};
 
 /*! \brief Callback function for finding a contact */
 static int registrar_find_contact(void *obj, void *arg, int flags)
 {
 	struct ast_sip_contact *contact = obj;
-	const char *uri = arg;
-
-	return !strcmp(contact->uri, uri) ? CMP_MATCH | CMP_STOP : 0;
+	const struct registrar_contact_details *details = arg;
+	pjsip_uri *contact_uri = pjsip_parse_uri(details->pool, (char*)contact->uri, strlen(contact->uri), PJSIP_URI_IN_FROMTO_HDR);
+
+	return (pjsip_uri_cmp(PJSIP_URI_IN_CONTACT_HDR, details->uri, contact_uri) == PJ_SUCCESS) ? CMP_MATCH | CMP_STOP : 0;
 }
 
 /*! \brief Internal function which validates provided Contact headers to confirm that they are acceptable, and returns number of contacts */
 static int registrar_validate_contacts(const pjsip_rx_data *rdata, struct ao2_container *contacts, struct ast_sip_aor *aor, int *added, int *updated, int *deleted)
 {
 	pjsip_contact_hdr *previous = NULL, *contact = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
+	struct registrar_contact_details details = {
+		.pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Contact Comparison", 256, 256),
+	};
+
+	if (!details.pool) {
+		return -1;
+	}
 
 	while ((contact = (pjsip_contact_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next))) {
-		pjsip_sip_uri *uri;
-		char contact_uri[PJSIP_MAX_URL_SIZE];
 		int expiration;
 		RAII_VAR(struct ast_sip_contact *, existing, NULL, ao2_cleanup);
 
 		if (contact->star) {
 			/* The expiration MUST be 0 when a '*' contact is used and there must be no other contact */
 			if ((contact->expires != 0) || previous) {
+				pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
 				return -1;
 			}
 		} else if (previous && previous->star) {
 			/* If there is a previous contact and it is a '*' this is a deal breaker */
+			pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
 			return -1;
 		}
 		previous = contact;
@@ -96,12 +110,11 @@
 			continue;
 		}
 
-		uri = pjsip_uri_get_uri(contact->uri);
-		pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, uri, contact_uri, sizeof(contact_uri));
+		details.uri = pjsip_uri_get_uri(contact->uri);
 		expiration = registrar_get_expiration(aor, contact, rdata);
 
 		/* Determine if this is an add, update, or delete for policy enforcement purposes */
-		if (!(existing = ao2_callback(contacts, 0, registrar_find_contact, contact_uri))) {
+		if (!(existing = ao2_callback(contacts, 0, registrar_find_contact, &details))) {
 			if (expiration) {
 				(*added)++;
 			}
@@ -113,6 +126,7 @@
 	}
 
 	/* The provided contacts are acceptable, huzzah! */
+	pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
 	return 0;
 }
 
@@ -174,16 +188,21 @@
 	RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
 	int added = 0, updated = 0, deleted = 0;
 	pjsip_contact_hdr *contact_hdr = NULL;
+	struct registrar_contact_details details = { 0, };
 	pjsip_tx_data *tdata;
 	pjsip_response_addr addr;
 
 	if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_register_method) || !endpoint) {
 		return PJ_FALSE;
-	} else if (ast_strlen_zero(endpoint->aors)) {
+	}
+
+	if (ast_strlen_zero(endpoint->aors)) {
 		/* Short circuit early if the endpoint has no AORs configured on it, which means no registration possible */
 		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
 		return PJ_TRUE;
-	} else if (!PJSIP_URI_SCHEME_IS_SIP(rdata->msg_info.to->uri) && !PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.to->uri)) {
+	}
+
+	if (!PJSIP_URI_SCHEME_IS_SIP(rdata->msg_info.to->uri) && !PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.to->uri)) {
 		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 416, NULL, NULL, NULL);
 		return PJ_TRUE;
 	}
@@ -205,7 +224,7 @@
 		}
 
 		if ((alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias", domain_name))) {
-			snprintf(id, sizeof(id), "%s@%s", user_name, domain_name);
+			snprintf(id, sizeof(id), "%s@%s", user_name, alias->domain);
 			if (!strcmp(aor_name, id)) {
 				break;
 			}
@@ -220,7 +239,9 @@
 		/* The provided AOR name was not found (be it within the configuration or sorcery itself) */
 		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 404, NULL, NULL, NULL);
 		return PJ_TRUE;
-	} else if (!aor->max_contacts) {
+	}
+
+	if (!aor->max_contacts) {
 		/* Registration is not permitted for this AOR */
 		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
 		return PJ_TRUE;
@@ -236,9 +257,16 @@
 		/* The provided Contact headers do not conform to the specification */
 		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 400, NULL, NULL, NULL);
 		return PJ_TRUE;
-	} else if ((MIN(0, added - deleted) + (!aor->remove_existing ? ao2_container_count(contacts) : 0)) > aor->max_contacts) {
+	}
+
+	if (((added - deleted) + (!aor->remove_existing ? ao2_container_count(contacts) : 0)) > aor->max_contacts) {
 		/* Enforce the maximum number of contacts */
 		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
+		return PJ_TRUE;
+	}
+
+	if (!(details.pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Contact Comparison", 256, 256))) {
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
 		return PJ_TRUE;
 	}
 
@@ -252,16 +280,18 @@
 			/* A star means to unregister everything, so do so for the possible contacts */
 			ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, registrar_delete_contact, NULL);
 			break;
-		} else if (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri)) {
+		}
+
+		if (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri)) {
 			/* This registrar only currently supports sip: and sips: URI schemes */
 			continue;
 		}
 
 		expiration = registrar_get_expiration(aor, contact_hdr, rdata);
-		uri = pjsip_uri_get_uri(contact_hdr->uri);
-		pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, uri, contact_uri, sizeof(contact_uri));
-
-		if (!(contact = ao2_callback(contacts, OBJ_UNLINK, registrar_find_contact, contact_uri))) {
+		details.uri = pjsip_uri_get_uri(contact_hdr->uri);
+		pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, details.uri, contact_uri, sizeof(contact_uri));
+
+		if (!(contact = ao2_callback(contacts, OBJ_UNLINK, registrar_find_contact, &details))) {
 			/* If they are actually trying to delete a contact that does not exist... be forgiving */
 			if (!expiration) {
 				ast_verb(3, "Attempted to remove non-existent contact '%s' from AOR '%s' by request\n",
@@ -286,6 +316,8 @@
 		}
 	}
 
+	pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
+
 	/* If the AOR is configured to remove any existing contacts that have not been updated/added as a result of this REGISTER
 	 * do so
 	 */




More information about the svn-commits mailing list