[asterisk-commits] file: branch file/pimp_sip_registration r383538 - /team/file/pimp_sip_registr...
SVN commits to the Asterisk project
asterisk-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 asterisk-commits
mailing list