Commit f0a7bd34 authored by Pekka Pessi's avatar Pekka Pessi
Browse files

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