Skip to content

Commit

Permalink
fix dialog leak on uac bye/cancel timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
ireader committed Jun 9, 2023
1 parent 671c661 commit 2f475dc
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 19 deletions.
4 changes: 4 additions & 0 deletions libsip/include/sip-dialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ struct sip_dialog_t

// internal use only
void* session; // user-defined session
void (*ondestroy)(void* param);
void* ondestroyparam;
struct list_head link;
char* ptr;
int32_t ref;
Expand All @@ -61,6 +63,8 @@ int sip_dialog_remove(struct sip_agent_t* sip, struct sip_dialog_t* dialog);
/// call sip_dialog_release
struct sip_dialog_t* sip_dialog_fetch(struct sip_agent_t* sip, const struct cstring_t* callid, const struct cstring_t* local, const struct cstring_t* remote);

int sip_dialog_ondestroy(struct sip_dialog_t* dialog, void (*ondestroy)(void* param), void* param);

#if defined(__cplusplus)
}
#endif
Expand Down
10 changes: 10 additions & 0 deletions libsip/src/sip-dialog.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ int sip_dialog_release(struct sip_dialog_t* dialog)
if (0 != atomic_decrement32(&dialog->ref))
return 0;

if (dialog->ondestroy)
dialog->ondestroy(dialog->ondestroyparam);

sip_uri_free(&dialog->local.target);
sip_contact_free(&dialog->local.uri);
sip_uri_free(&dialog->remote.target);
Expand All @@ -134,6 +137,13 @@ int sip_dialog_addref(struct sip_dialog_t* dialog)
return r;
}

int sip_dialog_ondestroy(struct sip_dialog_t* dialog, void (*ondestroy)(void* param), void* param)
{
dialog->ondestroy = ondestroy;
dialog->ondestroyparam = param;
return 0;
}

int sip_dialog_setlocaltag(struct sip_dialog_t* dialog, const struct cstring_t* tag)
{
const char* end;
Expand Down
8 changes: 4 additions & 4 deletions libsip/src/uac/sip-uac-bye.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
#include "sip-message.h"
#include "sip-uac-transaction.h"

int sip_uac_onbye(struct sip_uac_transaction_t* t, const struct sip_message_t* reply)
int sip_uac_onbye(struct sip_uac_transaction_t* t, int code)
{
struct sip_dialog_t* dialog;
if ( (200 <= reply->u.s.code && reply->u.s.code < 300) || 481 == reply->u.s.code )
//if ( (200 <= reply->u.s.code && reply->u.s.code < 300) || 481 == reply->u.s.code )
{
dialog = sip_dialog_fetch(t->agent, &reply->callid, &reply->from.tag, &reply->to.tag);
dialog = sip_dialog_fetch(t->agent, &t->req->callid, &t->req->from.tag, &t->req->to.tag);
if (dialog)
{
sip_dialog_remove(t->agent, dialog);
Expand All @@ -33,7 +33,7 @@ struct sip_uac_transaction_t* sip_uac_bye(struct sip_agent_t* sip, struct sip_di
}

t = sip_uac_transaction_create(sip, req);
// t->onhandle = sip_uac_onbye;
t->onhandle = sip_uac_onbye;
t->onreply = onbye;
t->param = param;
return t;
Expand Down
8 changes: 4 additions & 4 deletions libsip/src/uac/sip-uac-cancel.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
#include <stdlib.h>
#include <string.h>

int sip_uac_oncancel(struct sip_uac_transaction_t* t, const struct sip_message_t* reply)
int sip_uac_oncancel(struct sip_uac_transaction_t* t, int code)
{
struct sip_dialog_t* dialog;
if (200 <= reply->u.s.code && reply->u.s.code < 300)
//if (200 <= reply->u.s.code && reply->u.s.code < 300)
{
dialog = sip_dialog_fetch(t->agent, &reply->callid, &reply->from.tag, &reply->to.tag);
dialog = sip_dialog_fetch(t->agent, &t->req->callid, &t->req->from.tag, &t->req->to.tag);
if (dialog)
{
sip_dialog_remove(t->agent, dialog);
Expand Down Expand Up @@ -46,7 +46,7 @@ struct sip_uac_transaction_t* sip_uac_cancel(struct sip_agent_t* sip, struct sip
memcpy(&req->u.c.method, &req->cseq.method, sizeof(req->u.c.method));

t = sip_uac_transaction_create(sip, req);
// t->onhandle = sip_uac_oncancel;
t->onhandle = sip_uac_oncancel;
t->onreply = oncancel;
t->param = param;
return t;
Expand Down
11 changes: 5 additions & 6 deletions libsip/src/uac/sip-uac-transaction-noninvite.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,11 @@ static int sip_uac_transaction_noninvite_completed(struct sip_uac_transaction_t*
r = t->onreply(t->param, reply, t, reply->u.s.code);

// post-handle
if(sip_message_isbye(t->req))
sip_uac_onbye(t, reply);
else if(sip_message_iscancel(t->req))
sip_uac_oncancel(t, reply);
// if (t->onhandle)
// t->onhandle(t, reply);
if (t->onhandle)
{
t->onhandle(t, reply->u.s.code);
t->onhandle = NULL;
}

// wait for in-flight response
sip_uac_transaction_timewait(t, t->reliable ? 1 : TIMER_K);
Expand Down
12 changes: 10 additions & 2 deletions libsip/src/uac/sip-uac-transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ int sip_uac_transaction_release(struct sip_uac_transaction_t* t)
{
sip_dialog_release(t->dialog);
}


assert(NULL == t->onhandle);
sip_message_destroy(t->req);
locker_destroy(&t->locker);
free(t);
Expand Down Expand Up @@ -102,7 +103,7 @@ static void sip_uac_transaction_onretransmission(void* usrptr)
}

timeout = T1 * (1 << t->retries++);
t->timera = sip_uac_start_timer(t->agent, t, MIN(t->t2, timeout), sip_uac_transaction_onretransmission);
t->timera = sip_uac_start_timer(t->agent, t, MIN(t->t2, MAX(T1, timeout)), sip_uac_transaction_onretransmission);
}
locker_unlock(&t->locker);

Expand Down Expand Up @@ -145,6 +146,13 @@ static void sip_uac_transaction_ontimeout(void* usrptr)
t->onreply(t->param, NULL, t, 408/*Request Timeout*/);

// ignore return value, nothing to do

// post-handle
if (t->onhandle)
{
t->onhandle(t, 408);
t->onhandle = NULL;
}
}
locker_unlock(&t->locker);
sip_uac_transaction_release(t);
Expand Down
2 changes: 1 addition & 1 deletion libsip/src/uac/sip-uac-transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct sip_uac_transaction_t

struct sip_agent_t* agent;
struct sip_dialog_t* dialog;
// int (*onhandle)(struct sip_uac_transaction_t* t, const struct sip_message_t* reply);
int (*onhandle)(struct sip_uac_transaction_t* t, int code);
sip_uac_onsubscribe onsubscribe;
sip_uac_oninvite oninvite;
sip_uac_onreply onreply;
Expand Down
4 changes: 3 additions & 1 deletion libsip/src/uas/sip-uas-bye.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

int sip_uas_onbye(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param)
{
void* session;
//dialog = sip_dialog_find(&t->uas->dialogs, req);
if (!dialog)
{
// 481 Call/Transaction Does Not Exist
return sip_uas_transaction_noninvite_reply(t, 481, NULL, 0, param);
}

session = dialog ? dialog->session : NULL; // get session before dialog remove
if (0 != sip_dialog_remove(t->agent, dialog))
{
// 481 Call/Transaction Does Not Exist
Expand All @@ -18,5 +20,5 @@ int sip_uas_onbye(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog,
// The UAS MUST still respond to any pending requests received for that
// dialog. It is RECOMMENDED that a 487 (Request Terminated) response be
// generated to those pending requests.
return t->handler->onbye(param, req, t, dialog ? dialog->session : NULL);
return t->handler->onbye(param, req, t, session);
}
2 changes: 1 addition & 1 deletion libsip/src/uas/sip-uas-transaction-invite.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ static void sip_uas_transaction_onretransmission(void* usrptr)

assert(!t->reliable);
timeout = T1 * (1 << t->retries++);
t->timerg = sip_uas_start_timer(t->agent, t, MIN(t->t2, timeout), sip_uas_transaction_onretransmission);
t->timerg = sip_uas_start_timer(t->agent, t, MIN(t->t2, MAX(T1, timeout)), sip_uas_transaction_onretransmission);
}

locker_unlock(&t->locker);
Expand Down

0 comments on commit 2f475dc

Please sign in to comment.