Commit 61198fd7 authored by Pekka Pessi's avatar Pekka Pessi

nua: passing the culprit to the dialog usage removal functions

If a session was terminated because of a error response returned to a
request (as specified by RFC 5157), the nua_i_state event was not sent.

Even with this fix, if a dialog has multiple usages, the event usages can be
terminated without any indication to the application.

darcs-hash:20080307163336-65a35-cd2e979af405323e2131c7c8dc662e0ab645bbac.gz
parent 62aac1fa
......@@ -60,7 +60,9 @@
/* Dialog handling */
static void nua_dialog_usage_remove_at(nua_owner_t*, nua_dialog_state_t*,
nua_dialog_usage_t**);
nua_dialog_usage_t**,
nua_client_request_t *cr,
nua_server_request_t *sr);
static void nua_dialog_log_usage(nua_owner_t *, nua_dialog_state_t *);
/**@internal
......@@ -331,7 +333,9 @@ nua_dialog_usage_t *nua_dialog_usage_add(nua_owner_t *own,
/** @internal Remove dialog usage. */
void nua_dialog_usage_remove(nua_owner_t *own,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du)
nua_dialog_usage_t *du,
nua_client_request_t *cr,
nua_server_request_t *sr)
{
nua_dialog_usage_t **at;
......@@ -343,7 +347,7 @@ void nua_dialog_usage_remove(nua_owner_t *own,
assert(*at);
nua_dialog_usage_remove_at(own, ds, at);
nua_dialog_usage_remove_at(own, ds, at, cr, sr);
}
/** @internal Remove dialog usage.
......@@ -353,7 +357,9 @@ void nua_dialog_usage_remove(nua_owner_t *own,
static
void nua_dialog_usage_remove_at(nua_owner_t *own,
nua_dialog_state_t *ds,
nua_dialog_usage_t **at)
nua_dialog_usage_t **at,
nua_client_request_t *cr0,
nua_server_request_t *sr0)
{
if (*at) {
nua_dialog_usage_t *du = *at;
......@@ -368,10 +374,10 @@ void nua_dialog_usage_remove_at(nua_owner_t *own,
SU_DEBUG_5(("nua(%p): removing %s usage%s%s\n",
(void *)own, nua_dialog_usage_name(du),
o ? " with event " : "", o ? o->o_type :""));
du->du_class->usage_remove(own, ds, du);
du->du_class->usage_remove(own, ds, du, cr0, sr0);
/* Destroy saved client request */
if (nua_client_is_bound(du->du_cr)) {
if (cr0 != du->du_cr && nua_client_is_bound(du->du_cr)) {
nua_client_bind(cr = du->du_cr, NULL);
if (nua_client_is_queued(cr))
......@@ -391,8 +397,11 @@ void nua_dialog_usage_remove_at(nua_owner_t *own,
for (sr = ds->ds_sr; sr; sr = sr_next) {
sr_next = sr->sr_next;
if (sr->sr_usage == du)
nua_server_request_destroy(sr);
if (sr->sr_usage == du) {
if (sr != sr0)
nua_server_request_destroy(sr);
sr->sr_usage = NULL;
}
}
su_home_unref(own);
......@@ -454,7 +463,7 @@ void nua_dialog_deinit(nua_owner_t *own,
ds->ds_terminating = 1;
while (ds->ds_usage) {
nua_dialog_usage_remove_at(own, ds, &ds->ds_usage);
nua_dialog_usage_remove_at(own, ds, &ds->ds_usage, NULL, NULL);
}
nua_dialog_remove(own, ds, NULL);
......
......@@ -286,12 +286,12 @@ struct nua_client_request
url_t *cr_target;
uint32_t cr_seq;
char const *cr_phrase; /**< Latest status phrase */
unsigned short cr_status; /**< Latest status */
unsigned short cr_retry_count; /**< Retry count for this request */
uint32_t cr_seq;
/* Flags used with offer-answer */
unsigned short cr_answer_recv; /**< Recv answer in response
* with this status.
......@@ -382,7 +382,9 @@ typedef struct {
nua_dialog_usage_t *du);
void (*usage_remove)(nua_owner_t *,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du);
nua_dialog_usage_t *du,
nua_client_request_t *cr,
nua_server_request_t *sr);
char const *(*usage_name)(nua_dialog_usage_t const *du);
void (*usage_peer_info)(nua_dialog_usage_t *du,
nua_dialog_state_t const *ds,
......@@ -446,7 +448,9 @@ nua_dialog_usage_t *nua_dialog_usage_get(nua_dialog_state_t const *ds,
void nua_dialog_usage_remove(nua_owner_t *,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du);
nua_dialog_usage_t *du,
nua_client_request_t *cr,
nua_server_request_t *sr);
void nua_dialog_deinit(nua_owner_t *own,
nua_dialog_state_t *ds);
......
......@@ -74,8 +74,10 @@ static int nua_notify_usage_add(nua_handle_t *nh,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du);
static void nua_notify_usage_remove(nua_handle_t *nh,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du);
nua_dialog_state_t *ds,
nua_dialog_usage_t *du,
nua_client_request_t *cr,
nua_server_request_t *sr);
static void nua_notify_usage_refresh(nua_handle_t *nh,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du,
......@@ -102,8 +104,8 @@ static char const *nua_notify_usage_name(nua_dialog_usage_t const *du)
static
int nua_notify_usage_add(nua_handle_t *nh,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du)
nua_dialog_state_t *ds,
nua_dialog_usage_t *du)
{
ds->ds_has_events++;
ds->ds_has_notifys++;
......@@ -112,8 +114,10 @@ int nua_notify_usage_add(nua_handle_t *nh,
static
void nua_notify_usage_remove(nua_handle_t *nh,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du)
nua_dialog_state_t *ds,
nua_dialog_usage_t *du,
nua_client_request_t *cr,
nua_server_request_t *sr)
{
ds->ds_has_events--;
ds->ds_has_notifys--;
......@@ -796,7 +800,7 @@ static void nua_notify_usage_refresh(nua_handle_t *nh,
NUTAG_SUBSTATE(nua_substate_terminated),
TAG_END());
nua_dialog_usage_remove(nh, ds, du);
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
}
/** @interal Shut down NOTIFY usage.
......@@ -827,7 +831,7 @@ static int nua_notify_usage_shutdown(nua_handle_t *nh,
return 0;
}
nua_dialog_usage_remove(nh, ds, du);
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
return 200;
}
......
......@@ -60,8 +60,10 @@ static int nua_publish_usage_add(nua_handle_t *nh,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du);
static void nua_publish_usage_remove(nua_handle_t *nh,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du);
nua_dialog_state_t *ds,
nua_dialog_usage_t *du,
nua_client_request_t *cr,
nua_server_request_t *sr);
static void nua_publish_usage_refresh(nua_handle_t *nh,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du,
......@@ -101,8 +103,11 @@ int nua_publish_usage_add(nua_handle_t *nh,
static
void nua_publish_usage_remove(nua_handle_t *nh,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du)
nua_dialog_state_t *ds,
nua_dialog_usage_t *du,
nua_client_request_t *cr,
nua_server_request_t *sr
)
{
struct publish_usage *pu = nua_dialog_usage_private(du);
......@@ -433,7 +438,7 @@ static void nua_publish_usage_refresh(nua_handle_t *nh,
nua_r_publish, NUA_ERROR_AT(__FILE__, __LINE__),
NULL);
nua_dialog_usage_remove(nh, ds, du);
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
}
/** @interal Shut down PUBLISH usage.
......@@ -454,7 +459,7 @@ static int nua_publish_usage_shutdown(nua_handle_t *nh,
}
/* XXX - report to user */
nua_dialog_usage_remove(nh, ds, du);
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
return 200;
}
......
......@@ -104,7 +104,9 @@ static int nua_register_usage_add(nua_handle_t *nh,
nua_dialog_usage_t *du);
static void nua_register_usage_remove(nua_handle_t *nh,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du);
nua_dialog_usage_t *du,
nua_client_request_t *cr,
nua_server_request_t *sr);
static void nua_register_usage_peer_info(nua_dialog_usage_t *du,
nua_dialog_state_t const *ds,
sip_t const *sip);
......@@ -196,7 +198,9 @@ static int nua_register_usage_add(nua_handle_t *nh,
static void nua_register_usage_remove(nua_handle_t *nh,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du)
nua_dialog_usage_t *du,
nua_client_request_t *cr,
nua_server_request_t *sr)
{
nua_registration_t *nr = nua_dialog_usage_private(du);
......@@ -1050,7 +1054,7 @@ static void nua_register_usage_refresh(nua_handle_t *nh,
/* Report that we have de-registered */
nua_stack_event(nua, nh, NULL, nua_r_register, NUA_ERROR_AT(__FILE__, __LINE__), NULL);
nua_dialog_usage_remove(nh, ds, du);
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
}
/** @interal Shut down REGISTER usage.
......@@ -1078,7 +1082,7 @@ static int nua_register_usage_shutdown(nua_handle_t *nh,
if (nr->nr_tport)
tport_decref(&nr->nr_tport), nr->nr_tport = NULL;
nua_dialog_usage_remove(nh, ds, du);
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
return 200;
}
......
This diff is collapsed.
......@@ -861,7 +861,7 @@ void nua_stack_shutdown(nua_t *nua)
for (nh = nua->nua_handles; nh; nh = nh_next) {
nh_next = nh->nh_next;
while (nh->nh_ds && nh->nh_ds->ds_usage) {
nua_dialog_usage_remove(nh, nh->nh_ds, nh->nh_ds->ds_usage);
nua_dialog_usage_remove(nh, nh->nh_ds, nh->nh_ds->ds_usage, NULL, NULL);
}
}
su_timer_destroy(nua->nua_timer), nua->nua_timer = NULL;
......@@ -1867,14 +1867,14 @@ int nua_base_server_report(nua_server_request_t *sr, tagi_t const *tags)
else
terminated = sip_response_terminates_dialog(status, sr->sr_method, NULL);
if (usage && terminated)
nua_dialog_usage_remove(nh, nh->nh_ds, usage, NULL, sr);
nua_server_request_destroy(sr);
if (!terminated)
return 1;
if (usage)
nua_dialog_usage_remove(nh, nh->nh_ds, usage);
if (!initial) {
if (terminated > 0)
return 2;
......@@ -2351,7 +2351,7 @@ msg_t *nua_client_request_template(nua_client_request_t *cr)
/** Restart the request message.
*
* A restarted request has not completed successfully.
* A restarted request has not been completed successfully.
*
* @retval 0 if request is pending
* @retval >=1 if error event has been sent
......@@ -2690,6 +2690,7 @@ int nua_client_response(nua_client_request_t *cr,
return 0;
cr->cr_status = status;
cr->cr_phrase = phrase;
if (status < 200) {
/* Xyzzy */
......@@ -2735,6 +2736,7 @@ int nua_client_response(nua_client_request_t *cr,
cr->cr_methods->crm_preliminary(cr, status, phrase, sip);
else
nua_base_client_response(cr, status, phrase, sip, NULL);
cr->cr_phrase = NULL;
return 0;
}
......@@ -2853,6 +2855,7 @@ int nua_base_client_check_restart(nua_client_request_t *cr,
cr->cr_waiting = cr->cr_wait_for_cred = 1;
nua_client_report(cr, status, phrase, NULL, orq, NULL);
nta_outgoing_destroy(orq);
cr->cr_status = 0, cr->cr_phrase = NULL;
return 1;
}
......@@ -2877,6 +2880,7 @@ int nua_base_client_check_restart(nua_client_request_t *cr,
cr->cr_waiting = cr->cr_wait_for_timer = 1;
nua_client_report(cr, 100, phrase, NULL, orq, NULL);
nta_outgoing_destroy(orq);
cr->cr_status = 0, cr->cr_phrase = NULL;
return 1;
}
......@@ -3065,7 +3069,7 @@ int nua_base_client_response(nua_client_request_t *cr,
if (cr->cr_terminated ||
(!du->du_ready && status >= 300 && nua_client_is_bound(cr))) {
/* Usage has been destroyed */
nua_dialog_usage_remove(nh, nh->nh_ds, du), cr->cr_usage = NULL;
nua_dialog_usage_remove(nh, nh->nh_ds, du, cr, NULL), cr->cr_usage = NULL;
}
else if (cr->cr_graceful) {
/* Terminate usage gracefully */
......@@ -3078,6 +3082,7 @@ int nua_base_client_response(nua_client_request_t *cr,
nua_dialog_remove(nh, nh->nh_ds, NULL), cr->cr_usage = NULL;
}
cr->cr_phrase = NULL;
cr->cr_reporting = 0, nh->nh_ds->ds_reporting = 0;
if (!nua_client_is_queued(cr) && !nua_client_is_bound(cr))
......
......@@ -74,7 +74,9 @@ static int nua_subscribe_usage_add(nua_handle_t *nh,
nua_dialog_usage_t *du);
static void nua_subscribe_usage_remove(nua_handle_t *nh,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du);
nua_dialog_usage_t *du,
nua_client_request_t *cr,
nua_server_request_t *sr);
static void nua_subscribe_usage_refresh(nua_handle_t *,
nua_dialog_state_t *,
nua_dialog_usage_t *,
......@@ -113,7 +115,9 @@ int nua_subscribe_usage_add(nua_handle_t *nh,
static
void nua_subscribe_usage_remove(nua_handle_t *nh,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du)
nua_dialog_usage_t *du,
nua_client_request_t *cr,
nua_server_request_t *sr)
{
ds->ds_has_events--;
ds->ds_has_subscribes--;
......@@ -446,7 +450,7 @@ static void nua_subscribe_usage_refresh(nua_handle_t *nh,
NUTAG_SUBSTATE(nua_substate_terminated),
SIPTAG_EVENT(du->du_event),
TAG_END());
nua_dialog_usage_remove(nh, ds, du);
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
return;
}
......@@ -469,7 +473,7 @@ static void nua_subscribe_usage_refresh(nua_handle_t *nh,
SIPTAG_EVENT(du->du_event),
TAG_END());
nua_dialog_usage_remove(nh, ds, du);
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
}
/** Terminate subscription.
......@@ -492,7 +496,7 @@ static int nua_subscribe_usage_shutdown(nua_handle_t *nh,
return 0;
}
nua_dialog_usage_remove(nh, ds, du);
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
return 200;
}
......@@ -874,7 +878,7 @@ static int nua_refer_client_request(nua_client_request_t *cr,
}
if (du0)
nua_dialog_usage_remove(nh, nh->nh_ds, du0);
nua_dialog_usage_remove(nh, nh->nh_ds, du0, NULL, NULL);
eu = nua_dialog_usage_private(cr->cr_usage = du);
eu ->eu_refer = 1;
......
......@@ -1269,7 +1269,8 @@ tag_typedef_t nutag_autoack = BOOLTAG_TYPEDEF(autoACK);
/**@def NUTAG_ENABLEINVITE(x)
*
* Enable incoming INVITE
* Enable incoming INVITE.
*
*
* @par Used with
* nua_set_params() \n
......@@ -2570,7 +2571,8 @@ tag_typedef_t nutag_path_enable = BOOLTAG_TYPEDEF(path_enable);
/**@def NUTAG_SERVICE_ROUTE_ENABLE(x)
*
* Use route from @ServiceRoute header in response to REGISTER.
* Use route taken from the @ServiceRoute header in the 200 class response
* to REGISTER.
*
* @par Used with
* - nua_create(), nua_set_params(), nua_get_params()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment