[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Linphone-developers] bug in eXosip_process_response_out_of_transaction(
From: |
Машкин С В |
Subject: |
[Linphone-developers] bug in eXosip_process_response_out_of_transaction(), eXosip2/udp.c |
Date: |
Thu, 24 Sep 2009 09:48:30 +0400 |
Hi, Simon!
We have found little bug in eXosip2/udp.c function
eXosip_process_response_out_of_transaction (osip_event_t * evt)
Removed-bug-source is below:
The bug was in call of cb_snd_message (NULL, bye, NULL, 0, -1);
with bye=NULL. The check (bye==NULL) was absent, so, at
some conditions our system fall with "NULL pointer access" error.
Bug area marked with //<<<<<<<, //>>>>>>>
===============================================
static void
eXosip_process_response_out_of_transaction (osip_event_t * evt)
{
eXosip_call_t *jc = NULL;
eXosip_dialog_t *jd = NULL;
time_t now;
now = time (NULL);
if (evt->sip == NULL
|| evt->sip->cseq == NULL
|| evt->sip->cseq->number == NULL
|| evt->sip->to == NULL || evt->sip->from == NULL)
{
osip_event_free (evt);
return;
}
/* search for existing dialog: match branch & to tag */
for (jc = eXosip.j_calls; jc != NULL; jc = jc->next)
{
/* search for calls with only ONE outgoing transaction */
if (jc->c_id >= 1 && jc->c_dialogs != NULL && jc->c_out_tr != NULL)
{
for (jd = jc->c_dialogs; jd != NULL; jd = jd->next)
{
/* only initial request are concerned with this */
if (jd->d_id >= 1 && jd->d_dialog != NULL)
{
/* match answer with dialog */
osip_generic_param_t *tag;
osip_from_get_tag (evt->sip->to, &tag);
if (jd->d_dialog->remote_tag == NULL || tag == NULL)
continue;
if (jd->d_dialog->remote_tag != NULL && tag != NULL
&& tag->gvalue != NULL
&& 0 == strcmp (jd->d_dialog->remote_tag, tag->gvalue))
break;
}
}
if (jd != NULL)
break; /* found a matching dialog! */
/* check if the transaction match this from tag */
if (jc->c_out_tr->orig_request != NULL
&& jc->c_out_tr->orig_request->from != NULL)
{
osip_generic_param_t *tag_invite;
osip_generic_param_t *tag;
osip_from_get_tag (jc->c_out_tr->orig_request->from, &tag_invite);
osip_from_get_tag (evt->sip->from, &tag);
if (tag_invite == NULL || tag == NULL)
continue;
if (tag_invite->gvalue != NULL && tag->gvalue != NULL
&& 0 == strcmp (tag_invite->gvalue, tag->gvalue))
break;
}
}
}
if (jc == NULL)
{
OSIP_TRACE (osip_trace
(__FILE__, __LINE__, OSIP_INFO1, NULL,
"Incoming 2xx has no relations with current calls: Message
discarded.\r\n"));
osip_event_free (evt);
return;
}
#ifndef MINISIZE
if (jc != NULL && jd != NULL)
{
/* we have to restransmit the ACK (if already available) */
OSIP_TRACE (osip_trace
(__FILE__, __LINE__, OSIP_INFO1, NULL,
"2xx restransmission receveid.\r\n"));
/* check if the 2xx is for the same ACK */
if (jd->d_ack != NULL && jd->d_ack->cseq != NULL
&& jd->d_ack->cseq->number != NULL)
{
if (0 ==
osip_strcasecmp (jd->d_ack->cseq->number, evt->sip->cseq->number))
{
cb_snd_message (NULL, jd->d_ack, NULL, 0, -1);
OSIP_TRACE (osip_trace
(__FILE__, __LINE__, OSIP_INFO1, NULL,
"ACK restransmission sent.\r\n"));
}
}
osip_event_free (evt);
return;
}
#endif
if (jc != NULL)
{
/* match answer with dialog */
osip_dialog_t *dlg;
#ifndef MINISIZE
osip_transaction_t *last_tr;
#endif
int i;
/* we match an existing dialog: send a retransmission of ACK */
i = osip_dialog_init_as_uac (&dlg, evt->sip);
if (i != 0 || dlg == NULL)
{
OSIP_TRACE (osip_trace
(__FILE__, __LINE__, OSIP_ERROR, NULL,
"Cannot build dialog for 200ok.\r\n"));
osip_event_free (evt);
return;
}
OSIP_TRACE (osip_trace
(__FILE__, __LINE__, OSIP_INFO1, NULL,
"sending ACK for 2xx out of transaction.\r\n"));
{
osip_message_t *bye;
char *transport = _eXosip_transport_protocol (evt->sip);
#ifndef MINISIZE /* Don't send ACK in MINISIZE mode to save code
size */
osip_message_t *ack;
if (transport == NULL)
i = _eXosip_build_request_within_dialog (&ack, "ACK", dlg, "UDP");
else
i = _eXosip_build_request_within_dialog (&ack, "ACK", dlg, transport);
if (i != 0)
{
osip_dialog_free (dlg);
osip_event_free (evt);
return;
}
/* copy all credentials from INVITE! */
last_tr = jc->c_out_tr;
if (last_tr != NULL)
{
int pos = 0;
int i;
osip_proxy_authorization_t *pa = NULL;
i =
osip_message_get_proxy_authorization (last_tr->orig_request, pos,
&pa);
while (i >= 0 && pa != NULL)
{
osip_proxy_authorization_t *pa2;
i = osip_proxy_authorization_clone (pa, &pa2);
if (i != 0)
{
OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR,
NULL,
"Error in credential from
INVITE\n"));
break;
}
osip_list_add (&ack->proxy_authorizations, pa2, -1);
pa = NULL;
pos++;
i =
osip_message_get_proxy_authorization (last_tr->orig_request,
pos,
&pa);
}
}
cb_snd_message (NULL, ack, NULL, 0, -1);
osip_message_free (ack);
#endif
/* in some case, PRACK and UPDATE may have been sent
so we have to send a cseq which is above the previous
one. */
dlg->local_cseq = dlg->local_cseq + 4;
/* ready to send a BYE */
if (transport == NULL)
i = generating_bye (&bye, dlg, "UDP");
else
i = generating_bye (&bye, dlg, transport);
//<<<<<<<<<<
if(i != OSIP_SUCCESS) {
if(bye) {
osip_message_free (bye);
}
} else {
cb_snd_message (NULL, bye, NULL, 0, -1);
osip_message_free (bye);
}
//>>>>>>>>>>
}
osip_dialog_free (dlg);
osip_event_free (evt);
return;
}
/* we don't match any existing dialog: send a ACK & send a BYE */
osip_event_free (evt);
}
===============================================
Thanks,
Serg Ma
- [Linphone-developers] bug in eXosip_process_response_out_of_transaction(), eXosip2/udp.c,
Машкин С В <=