[asterisk-commits] file: branch file/pimp_sip_registration r383035 - /team/file/pimp_sip_registr...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Mar 13 12:21:39 CDT 2013
Author: file
Date: Wed Mar 13 12:21:35 2013
New Revision: 383035
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383035
Log:
Move destruction to the timer callback to fix a race condition between retrying and destroying.
Modified:
team/file/pimp_sip_registration/res/res_sip_outbound_registration.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=383035&r1=383034&r2=383035
==============================================================================
--- team/file/pimp_sip_registration/res/res_sip_outbound_registration.c (original)
+++ team/file/pimp_sip_registration/res/res_sip_outbound_registration.c Wed Mar 13 12:21:35 2013
@@ -49,7 +49,7 @@
/*! \brief Outbound registration client */
pjsip_regc *client;
/*! \brief Timer entry for retrying on temporal responses */
- pj_timer_entry timer;
+ pj_timer_entry *timer;
/*! \brief Current number of retries */
unsigned int retries;
/*! \brief Maximum number of retries permitted */
@@ -85,16 +85,22 @@
struct sip_outbound_registration_state *state;
};
-/*! \brief Callback function for outbound registration attempt */
+/*! \brief Callback function for outbound registration attempt or destruction */
static void sip_outbound_registration_attempt_cb(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry)
{
pjsip_tx_data *tdata;
- if (pjsip_regc_register(entry->user_data, PJ_TRUE, &tdata) != PJ_SUCCESS) {
- return;
- }
-
- pjsip_regc_send(entry->user_data, tdata);
+ if (entry->id == 1) {
+ if (pjsip_regc_register(entry->user_data, PJ_TRUE, &tdata) != PJ_SUCCESS) {
+ return;
+ }
+ pjsip_regc_send(entry->user_data, tdata);
+ } else if (entry->id == 2) {
+ if (pjsip_regc_unregister(entry->user_data, &tdata) == PJ_SUCCESS) {
+ pjsip_regc_send(entry->user_data, tdata);
+ }
+ pjsip_regc_destroy(entry->user_data);
+ }
}
/* \brief Helper funtion which determines if a response code is temporal or not */
@@ -131,13 +137,13 @@
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);;
+ 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);
+ 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);
}
@@ -152,23 +158,19 @@
static void sip_outbound_registration_state_destroy(void *obj)
{
struct sip_outbound_registration_state *state = obj;
+ pj_time_val delay = { .sec = 1, };
if (!state->client) {
return;
}
- pjsip_endpt_cancel_timer(ast_sip_get_pjsip_endpoint(), &state->timer);
-
- /* If we have at least attempted registering once send an unregister */
- if (state->timer.id) {
- pjsip_tx_data *tdata;
-
- if (pjsip_regc_unregister(state->client, &tdata) == PJ_SUCCESS) {
- pjsip_regc_send(state->client, tdata);
- }
- }
-
- pjsip_regc_destroy(state->client);
+ if (state->status != SIP_REGISTRATION_UNREGISTERED) {
+ 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);
+ } else {
+ pjsip_regc_destroy(state->client);
+ }
}
/*! \brief Allocator function for registration state */
@@ -178,15 +180,16 @@
if (!state) {
return NULL;
- } else if ((pjsip_regc_create(ast_sip_get_pjsip_endpoint(), state, sip_outbound_registration_response_cb, &state->client) != PJ_SUCCESS)) {
+ } else 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;
}
state->status = SIP_REGISTRATION_UNREGISTERED;
- state->timer.id = 0;
- state->timer.user_data = state->client;
- state->timer.cb = sip_outbound_registration_attempt_cb;
+ state->timer->id = 1;
+ state->timer->user_data = state->client;
+ state->timer->cb = sip_outbound_registration_attempt_cb;
return state;
}
@@ -363,10 +366,8 @@
pjsip_regc_update_expires(registration->state->client, registration->expiration);
/* Cancel retry attept if present and try a new registration */
- pjsip_endpt_cancel_timer(ast_sip_get_pjsip_endpoint(), ®istration->state->timer);
-
- registration->state->timer.id = 1;
- pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(), ®istration->state->timer, &delay);
+ pjsip_endpt_cancel_timer(ast_sip_get_pjsip_endpoint(), registration->state->timer);
+ pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(), registration->state->timer, &delay);
return 0;
}
More information about the asterisk-commits
mailing list