Commit 4c809e8c authored by Pekka Pessi's avatar Pekka Pessi

nua module: fixed memory leak in REGISTER, SUBSCRIBE and PUBLISH refresh.

Use a copy instead of a reference to the message template when refreshing
in nua_register.c, nua_subnotref.c and nua_publish.c.

darcs-hash:20060517125712-65a35-6362a5765b3bffbc3bfec5c18254a59d9667e6f4.gz
parent a2edef9b
......@@ -55,8 +55,6 @@
struct publish_usage {
sip_etag_t *pu_etag;
sip_content_type_t *pu_content_type;
sip_payload_t *pu_body;
};
static char const *nua_publish_usage_name(nua_dialog_usage_t const *du);
......@@ -221,7 +219,7 @@ int nua_stack_publish2(nua_t *nua, nua_handle_t *nh, nua_event_t e,
struct nua_client_request *cr = nh->nh_cr;
msg_t *msg = NULL;
sip_t *sip;
int add_body = 0;
int remove_body = 0;
if (nh->nh_special && nh->nh_special != nua_r_publish) {
return UA_EVENT2(e, 900, "Invalid handle for PUBLISH");
......@@ -250,47 +248,30 @@ int nua_stack_publish2(nua_t *nua, nua_handle_t *nh, nua_event_t e,
pu = nua_dialog_usage_private(du); assert(pu);
if (refresh) {
msg_t *omsg;
sip_t *osip;
cr->cr_msg = omsg = msg_ref_create(du->du_msg);
osip = sip_object(omsg);
if (osip == NULL) {
}
else if (pu->pu_etag) {
if (osip->sip_payload)
msg_header_remove(omsg, (void *)osip, (void *)osip->sip_payload);
if (osip->sip_content_type)
msg_header_remove(omsg, (void *)osip, (void *)osip->sip_content_type);
}
else {
add_body = !du->du_terminating;
}
if (cr->cr_msg)
msg_destroy(cr->cr_msg);
cr->cr_msg = msg_copy(du->du_msg);
remove_body = pu->pu_etag != NULL;
}
msg = nua_creq_msg(nua, nh, cr, cr->cr_retry_count || refresh,
SIP_METHOD_PUBLISH,
NUTAG_ADD_CONTACT(0),
TAG_NEXT(tags));
sip = sip_object(msg);
if (!msg || !sip)
goto error;
du->du_terminating =
e != nua_r_publish ||
(sip && sip->sip_expires && sip->sip_expires->ex_delta == 0);
if (sip && !du->du_terminating && !refresh) {
sip_t *osip;
(sip->sip_expires && sip->sip_expires->ex_delta == 0);
if (!du->du_terminating && !refresh) {
/* Save template */
if (du->du_msg)
msg_destroy(du->du_msg);
du->du_msg = msg_ref_create(cr->cr_msg);
osip = sip_object(du->du_msg);
pu->pu_content_type = osip->sip_content_type;
pu->pu_body = osip->sip_payload;
}
cr->cr_orq =
......@@ -298,24 +279,24 @@ int nua_stack_publish2(nua_t *nua, nua_handle_t *nh, nua_event_t e,
process_response_to_publish, nh, NULL,
msg,
SIPTAG_IF_MATCH(pu->pu_etag),
TAG_IF(add_body, SIPTAG_PAYLOAD(pu->pu_body)),
TAG_IF(add_body,
SIPTAG_CONTENT_TYPE(pu->pu_content_type)),
TAG_IF(remove_body, SIPTAG_PAYLOAD(NONE)),
TAG_IF(remove_body, SIPTAG_CONTENT_TYPE(NONE)),
TAG_IF(e != nua_r_publish,
SIPTAG_EXPIRES_STR("0")),
SIPTAG_END(), TAG_NEXT(tags));
if (!cr->cr_orq) {
msg_destroy(msg);
if (!du->du_ready)
nua_dialog_usage_remove(nh, nh->nh_ds, du);
return UA_EVENT1(e, NUA_INTERNAL_ERROR);
}
if (!cr->cr_orq)
goto error;
nh->nh_special = nua_r_publish;
cr->cr_usage = du;
return cr->cr_event = e;
error:
msg_destroy(msg);
if (!du->du_ready)
nua_dialog_usage_remove(nh, nh->nh_ds, du);
return UA_EVENT1(e, NUA_INTERNAL_ERROR);
}
......
......@@ -606,7 +606,7 @@ refresh_register(nua_handle_t *nh, nua_dialog_usage_t *du, sip_time_t now)
outbound_stop_keepalive(nr->nr_ob);
cr->cr_msg = msg_ref_create(du->du_msg);
cr->cr_msg = msg_copy(du->du_msg);
msg = nua_creq_msg(nua, nh, cr, 1,
SIP_METHOD_REGISTER,
NUTAG_USE_DIALOG(1),
......
......@@ -979,7 +979,7 @@ msg_t *nua_creq_msg(nua_t *nua,
NUTAG_ADD_CONTACT_REF(add_contact),
TAG_END());
if (method == sip_method_register && url == NULL) {
if (method == sip_method_register && url == NULL && !sip->sip_request) {
tl_gets(ta_args(ta), NUTAG_REGISTRAR_REF(url), TAG_END());
if (url == NULL)
tl_gets(nh->nh_tags, NUTAG_REGISTRAR_REF(url), TAG_END());
......@@ -988,8 +988,17 @@ msg_t *nua_creq_msg(nua_t *nua,
}
if (seq != -1) {
sip_cseq_t *cseq =
sip_cseq_create(msg_home(msg), seq, method, name);
sip_cseq_t *cseq;
assert(method != sip_method_unknown || name || sip->sip_request);
if (method || name)
cseq = sip_cseq_create(msg_home(msg), seq, method, name);
else
cseq = sip_cseq_create(msg_home(msg), seq,
sip->sip_request->rq_method,
sip->sip_request->rq_method_name);
sip_header_insert(msg, sip, (sip_header_t *)cseq);
}
......@@ -1355,7 +1364,7 @@ int nua_creq_check_restart(nua_handle_t *nh,
return
nua_creq_restart_with(nh, cr, orq,
100, "Re-Negotiating Subscription Expiration",
100, "Re-Negotiating Expiration",
restart_function,
SIPTAG_EXPIRES(ex),
TAG_END());
......
......@@ -331,9 +331,9 @@ static int process_response_to_subscribe(nua_handle_t *nh,
else if (gracefully && substate != nua_substate_terminated)
/* Post un-subscribe event */
nua_stack_post_signal(nh, nua_r_unsubscribe,
SIPTAG_EVENT(du->du_event),
SIPTAG_EXPIRES_STR("0"),
TAG_END());
SIPTAG_EVENT(du->du_event),
SIPTAG_EXPIRES_STR("0"),
TAG_END());
}
nua_stack_process_response(nh, cr, orq, sip,
......@@ -364,7 +364,7 @@ refresh_subscribe(nua_handle_t *nh, nua_dialog_usage_t *du, sip_time_t now)
else
e = nua_r_destroy, du->du_terminating = 1;
cr->cr_msg = msg_ref_create(du->du_msg);
cr->cr_msg = msg_copy(du->du_msg);
{
/* Remove initial route */
......@@ -374,12 +374,12 @@ refresh_subscribe(nua_handle_t *nh, nua_dialog_usage_t *du, sip_time_t now)
}
msg = nua_creq_msg(nua, nh, cr, 1,
SIP_METHOD_SUBSCRIBE,
NUTAG_USE_DIALOG(1),
NUTAG_ADD_CONTACT(1),
TAG_IF(du->du_terminating,
SIPTAG_EXPIRES_STR("0")),
TAG_END());
SIP_METHOD_SUBSCRIBE,
NUTAG_USE_DIALOG(1),
NUTAG_ADD_CONTACT(1),
TAG_IF(du->du_terminating,
SIPTAG_EXPIRES_STR("0")),
TAG_END());
sip = sip_object(msg);
......
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