Commit f0a7bd34 authored by Pekka Pessi's avatar Pekka Pessi

Added better error checking to nua_creq_msg().

Fixed Service-Route header processing, too.

darcs-hash:20060425154524-65a35-7bfd40c96a82906f31cf51363ab649951138125e.gz
parent 1da99b11
......@@ -336,6 +336,8 @@ void nua_stack_signal(nua_t *nua, su_msg_r msg, nua_event_data_t *e)
nua_handle_t *nh = e->e_nh;
tagi_t *tags = e->e_tags;
assert(tags);
if (nh) {
if (!nh->nh_prev)
nh_append(nua, nh);
......@@ -922,9 +924,10 @@ msg_t *nua_creq_msg(nua_t *nua, nua_handle_t *nh,
struct nua_dialog_state *ds = nh->nh_ds;
msg_t *msg;
sip_t *sip;
ta_list ta;
url_string_t const *url = NULL;
long seq = -1;
int copy = 1;
int copy = 1, use_dialog = 0, add_contact = 0, add_service_route;
/* If restarting, use existing message */
if (restart) {
......@@ -953,6 +956,7 @@ msg_t *nua_creq_msg(nua_t *nua, nua_handle_t *nh,
sip_t *nh_sip = sip_object(cr->cr_msg);
if (nh_sip && nh_sip->sip_cseq)
seq = nh_sip->sip_cseq->cs_seq;
/* ACK/CANCEL cannot be restarted so we do not copy message */
copy = 0;
}
else
......@@ -963,14 +967,13 @@ msg_t *nua_creq_msg(nua_t *nua, nua_handle_t *nh,
sip_add_tl(msg, sip_object(msg), TAG_NEXT(nh->nh_tags));
}
if (msg) {
ta_list ta;
int use_dialog = 0, add_contact = 0;
sip = sip_object(msg);
ta_start(ta, tag, value);
ta_start(ta, tag, value);
sip = sip_object(msg);
if (!sip)
goto error;
{
tl_gets(ta_args(ta),
NUTAG_URL_REF(url),
NUTAG_USE_DIALOG_REF(use_dialog),
......@@ -993,68 +996,62 @@ msg_t *nua_creq_msg(nua_t *nua, nua_handle_t *nh,
}
if (ds->ds_leg) {
add_service_route = 0;
/* If leg has established route, use it, not original URL */
if (ds->ds_route)
url = NULL;
if (sip_add_tl(msg, sip, ta_tags(ta)) < 0 ||
nta_msg_request_complete(msg, ds->ds_leg, method, name, url) < 0)
msg_destroy(msg), msg = NULL;
goto error;
}
else {
// tl_gets(ta_args(ta), TAG_END());
if ((sip_add_tl(msg, sip,
TAG_IF(method != sip_method_register,
SIPTAG_ROUTE(nua->nua_service_route)),
ta_tags(ta)) < 0)
if (sip_add_tl(msg, sip, ta_tags(ta)) < 0
|| (ds->ds_remote_tag &&
sip_to_tag(nh->nh_home, sip->sip_to, ds->ds_remote_tag) < 0)
|| nta_msg_request_complete(msg, nua->nua_dhandle->nh_ds->ds_leg,
method, name, url) < 0
|| (sip->sip_from == NULL &&
sip_add_dup(msg, sip, (sip_header_t *)nua->nua_from) < 0))
msg_destroy(msg), msg = NULL;
if (use_dialog && msg) {
sip_route_t *route = sip->sip_route;
goto error;
if (method == sip_method_invite ||
method == sip_method_subscribe ||
method == sip_method_notify)
route = NULL;
ds->ds_leg = nta_leg_tcreate(nua->nua_nta, nua_stack_process_request, nh,
if (use_dialog) {
ds->ds_leg = nta_leg_tcreate(nua->nua_nta,
nua_stack_process_request, nh,
SIPTAG_CALL_ID(sip->sip_call_id),
SIPTAG_FROM(sip->sip_from),
SIPTAG_TO(sip->sip_to),
SIPTAG_ROUTE(route),
SIPTAG_CSEQ(sip->sip_cseq),
TAG_END());
if (!sip->sip_from->a_tag) {
nta_leg_tag(ds->ds_leg, NULL);
sip_from_tag(msg_home(msg),
sip->sip_from,
nta_leg_get_tag(ds->ds_leg));
}
/* XXX - check error */
}
}
if (!ds->ds_leg)
goto error;
if (add_contact && msg && !sip->sip_contact) {
/* We are missing contact */
/* If application did not specify an empty contact, use ours */
if (!tl_find(nh->nh_tags, siptag_contact) &&
!tl_find(nh->nh_tags, siptag_contact_str) &&
!tl_find(ta_args(ta), siptag_contact) &&
!tl_find(ta_args(ta), siptag_contact_str)) {
sip_contact_t const *m;
m = nua_contact_by_aor(nh->nh_nua, sip->sip_request->rq_url, 0);
sip_add_dup(msg, sip, (void const *)m);
if (!sip->sip_from->a_tag &&
sip_from_tag(msg_home(msg), sip->sip_from,
nta_leg_tag(ds->ds_leg, NULL)) < 0)
goto error;
}
add_service_route = !restart;
}
/*
* If application did not specify an empty contact,
* use contact generated by stack.
*/
if (!add_contact ||
sip->sip_contact ||
tl_find(nh->nh_tags, siptag_contact) ||
tl_find(nh->nh_tags, siptag_contact_str) ||
tl_find(ta_args(ta), siptag_contact) ||
tl_find(ta_args(ta), siptag_contact_str))
add_contact = 0;
if (add_contact || add_service_route)
nua_add_contact_by_aor(nh, sip->sip_request->rq_url, msg, sip,
add_contact, add_service_route);
if (!sip->sip_user_agent && NH_PGET(nh, user_agent))
sip_add_dup(msg, sip, (sip_header_t *)NH_PGET(nh, user_agent));
......@@ -1080,7 +1077,7 @@ msg_t *nua_creq_msg(nua_t *nua, nua_handle_t *nh,
method != sip_method_update &&
/* auc_authorize() removes existing authentication headers */
auc_authorize(&nh->nh_auth, msg, sip) < 0)
msg_destroy(msg), msg = NULL;
goto error;
}
}
else /* ACK */ {
......@@ -1112,6 +1109,11 @@ msg_t *nua_creq_msg(nua_t *nua, nua_handle_t *nh,
}
return msg;
error:
ta_end(ta);
msg_destroy(msg);
return NULL;
}
/**@internal
......
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