1 /*
2   The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)
3   Copyright (C) 2001-2020 Aymeric MOIZARD amoizard@antisip.com
4 
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9 
10   This library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14 
15   You should have received a copy of the GNU Lesser General Public
16   License along with this library; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19 
20 #include <osip2/internal.h>
21 #include <osip2/osip.h>
22 
23 #include "fsm.h"
24 #include "xixt.h"
25 
26 #include <osip2/osip_dialog.h>
27 
28 #if defined(HAVE_DICT_DICT_H)
29 #include <dict/dict.h>
30 #endif
31 
osip_response_get_destination(osip_message_t * response,char ** address,int * portnum)32 void osip_response_get_destination(osip_message_t *response, char **address, int *portnum) {
33   osip_via_t *via;
34   char *host = NULL;
35   int port = 0;
36 
37   via = (osip_via_t *) osip_list_get(&response->vias, 0);
38 
39   if (via) {
40     osip_generic_param_t *maddr;
41     osip_generic_param_t *received;
42     osip_generic_param_t *rport;
43 
44     osip_via_param_get_byname(via, "maddr", &maddr);
45     osip_via_param_get_byname(via, "received", &received);
46     osip_via_param_get_byname(via, "rport", &rport);
47 
48     /* 1: user should not use the provided information
49        (host and port) if they are using a reliable
50        transport. Instead, they should use the already
51        open socket attached to this transaction. */
52     /* 2: check maddr and multicast usage */
53     if (maddr != NULL)
54       host = maddr->gvalue;
55 
56     /* we should check if this is a multicast address and use
57        set the "ttl" in this case. (this must be done in the
58        UDP message (not at the SIP layer) */
59     else if (received != NULL)
60       host = received->gvalue;
61 
62     else
63       host = via->host;
64 
65     if (rport == NULL || rport->gvalue == NULL) {
66       if (via->port != NULL)
67         port = osip_atoi(via->port);
68 
69       else
70         port = 5060;
71 
72     } else
73       port = osip_atoi(rport->gvalue);
74   }
75 
76   *portnum = port;
77 
78   if (host != NULL)
79     *address = osip_strdup(host);
80 
81   else
82     *address = NULL;
83 }
84 
osip_ixt_lock(osip_t * osip)85 static int osip_ixt_lock(osip_t *osip) {
86 #ifndef OSIP_MONOTHREAD
87   return osip_mutex_lock(osip->ixt_fastmutex);
88 #else
89   return OSIP_SUCCESS;
90 #endif
91 }
92 
osip_ixt_unlock(osip_t * osip)93 static int osip_ixt_unlock(osip_t *osip) {
94 #ifndef OSIP_MONOTHREAD
95   return osip_mutex_unlock(osip->ixt_fastmutex);
96 #else
97   return OSIP_SUCCESS;
98 #endif
99 }
100 
101 int osip_id_mutex_lock(osip_t *osip);
102 int osip_id_mutex_unlock(osip_t *osip);
103 
osip_id_mutex_lock(osip_t * osip)104 int osip_id_mutex_lock(osip_t *osip) {
105 #ifndef OSIP_MONOTHREAD
106   return osip_mutex_lock(osip->id_mutex);
107 #else
108   return OSIP_SUCCESS;
109 #endif
110 }
111 
osip_id_mutex_unlock(osip_t * osip)112 int osip_id_mutex_unlock(osip_t *osip) {
113 #ifndef OSIP_MONOTHREAD
114   return osip_mutex_unlock(osip->id_mutex);
115 #else
116   return OSIP_SUCCESS;
117 #endif
118 }
119 
120 /* these are for transactions that would need retransmission not handled by state machines */
osip_add_ixt(osip_t * osip,ixt_t * ixt)121 static void osip_add_ixt(osip_t *osip, ixt_t *ixt) {
122   /* add in list osip_t->ixt */
123   osip_ixt_lock(osip);
124   osip_list_add(&osip->ixt_retransmissions, (void *) ixt, 0);
125   osip_ixt_unlock(osip);
126 }
127 
ixt_init(ixt_t ** ixt)128 static int ixt_init(ixt_t **ixt) {
129   ixt_t *pixt;
130 
131   *ixt = pixt = (ixt_t *) osip_malloc(sizeof(ixt_t));
132 
133   if (pixt == NULL)
134     return OSIP_NOMEM;
135 
136   pixt->dialog = NULL;
137   pixt->msg2xx = NULL;
138   pixt->ack = NULL;
139   pixt->interval = DEFAULT_T1;
140   osip_gettimeofday(&pixt->start, NULL);
141   add_gettimeofday(&pixt->start, pixt->interval + 10);
142   pixt->counter = 10;
143   pixt->dest = NULL;
144   pixt->port = 5060;
145   pixt->sock = -1;
146   return OSIP_SUCCESS;
147 }
148 
ixt_free(ixt_t * ixt)149 static void ixt_free(ixt_t *ixt) {
150   osip_message_free(ixt->ack);
151   osip_message_free(ixt->msg2xx);
152   osip_free(ixt->dest);
153   osip_free(ixt);
154 }
155 
156 /* usefull for UAs */
osip_start_200ok_retransmissions(osip_t * osip,osip_dialog_t * dialog,osip_message_t * msg200ok,int sock)157 void osip_start_200ok_retransmissions(osip_t *osip, osip_dialog_t *dialog, osip_message_t *msg200ok, int sock) {
158   int i;
159   ixt_t *ixt;
160 
161   i = ixt_init(&ixt);
162 
163   if (i != 0)
164     return;
165 
166   ixt->dialog = dialog;
167   osip_message_clone(msg200ok, &ixt->msg2xx);
168   ixt->sock = sock;
169   osip_response_get_destination(msg200ok, &ixt->dest, &ixt->port);
170   osip_add_ixt(osip, ixt);
171 }
172 
osip_start_ack_retransmissions(osip_t * osip,osip_dialog_t * dialog,osip_message_t * ack,char * dest,int port,int sock)173 void osip_start_ack_retransmissions(osip_t *osip, osip_dialog_t *dialog, osip_message_t *ack, char *dest, int port, int sock) {
174   int i;
175   ixt_t *ixt;
176 
177   i = ixt_init(&ixt);
178 
179   if (i != 0)
180     return;
181 
182   ixt->dialog = dialog;
183   osip_message_clone(ack, &ixt->ack);
184   ixt->dest = osip_strdup(dest);
185   ixt->port = port;
186   ixt->sock = sock;
187   osip_add_ixt(osip, ixt);
188 }
189 
190 /* we stop the 200ok when receiving the corresponding ack */
osip_stop_200ok_retransmissions(osip_t * osip,osip_message_t * ack)191 struct osip_dialog *osip_stop_200ok_retransmissions(osip_t *osip, osip_message_t *ack) {
192   osip_dialog_t *dialog = NULL;
193   int i;
194   ixt_t *ixt;
195 
196   if (ack == NULL || ack->cseq == NULL || ack->cseq->number == NULL)
197     return NULL;
198 
199   osip_ixt_lock(osip);
200 
201   for (i = 0; !osip_list_eol(&osip->ixt_retransmissions, i); i++) {
202     ixt = (ixt_t *) osip_list_get(&osip->ixt_retransmissions, i);
203 
204     if (ixt->msg2xx == NULL || ixt->msg2xx->cseq == NULL || ixt->msg2xx->cseq->number == NULL)
205       continue;
206 
207     if (osip_dialog_match_as_uas(ixt->dialog, ack) == 0 && strcmp(ixt->msg2xx->cseq->number, ack->cseq->number) == 0) {
208       osip_list_remove(&osip->ixt_retransmissions, i);
209       dialog = ixt->dialog;
210       ixt_free(ixt);
211       break;
212     }
213   }
214 
215   osip_ixt_unlock(osip);
216   return dialog;
217 }
218 
219 /* when a dialog is destroyed by the application,
220    it is safer to remove all ixt that are related to it */
osip_stop_retransmissions_from_dialog(osip_t * osip,osip_dialog_t * dialog)221 void osip_stop_retransmissions_from_dialog(osip_t *osip, osip_dialog_t *dialog) {
222   int i;
223   ixt_t *ixt;
224 
225   osip_ixt_lock(osip);
226 
227   for (i = 0; !osip_list_eol(&osip->ixt_retransmissions, i); i++) {
228     ixt = (ixt_t *) osip_list_get(&osip->ixt_retransmissions, i);
229 
230     if (ixt->dialog == dialog) {
231       osip_list_remove(&osip->ixt_retransmissions, i);
232       ixt_free(ixt);
233       i--;
234     }
235   }
236 
237   osip_ixt_unlock(osip);
238 }
239 
ixt_retransmit(osip_t * osip,ixt_t * ixt,struct timeval * current)240 static void ixt_retransmit(osip_t *osip, ixt_t *ixt, struct timeval *current) {
241   if (osip_timercmp(current, &ixt->start, >=)) {
242     ixt->interval = ixt->interval * 2;
243 
244     if (ixt->interval > DEFAULT_T2)
245       ixt->interval = DEFAULT_T2;
246 
247     add_gettimeofday(&ixt->start, ixt->interval);
248 
249     if (ixt->ack != NULL)
250       osip->cb_send_message(NULL, ixt->ack, ixt->dest, ixt->port, ixt->sock);
251 
252     else if (ixt->msg2xx != NULL)
253       osip->cb_send_message(NULL, ixt->msg2xx, ixt->dest, ixt->port, ixt->sock);
254 
255     ixt->counter--;
256   }
257 }
258 
osip_retransmissions_execute(osip_t * osip)259 void osip_retransmissions_execute(osip_t *osip) {
260   int i;
261   ixt_t *ixt;
262   struct timeval current;
263 
264   osip_gettimeofday(&current, NULL);
265 
266   osip_ixt_lock(osip);
267 
268   for (i = 0; !osip_list_eol(&osip->ixt_retransmissions, i); i++) {
269     ixt = (ixt_t *) osip_list_get(&osip->ixt_retransmissions, i);
270     ixt_retransmit(osip, ixt, &current);
271 
272     if (ixt->counter == 0) {
273       /* remove it */
274       osip_list_remove(&osip->ixt_retransmissions, i);
275       ixt_free(ixt);
276       i--;
277     }
278   }
279 
280   osip_ixt_unlock(osip);
281 }
282 
osip_ict_lock(osip_t * osip)283 int osip_ict_lock(osip_t *osip) {
284 #ifndef OSIP_MONOTHREAD
285   return osip_mutex_lock(osip->ict_fastmutex);
286 #else
287   return OSIP_SUCCESS;
288 #endif
289 }
290 
osip_ict_unlock(osip_t * osip)291 int osip_ict_unlock(osip_t *osip) {
292 #ifndef OSIP_MONOTHREAD
293   return osip_mutex_unlock(osip->ict_fastmutex);
294 #else
295   return OSIP_SUCCESS;
296 #endif
297 }
298 
osip_ist_lock(osip_t * osip)299 int osip_ist_lock(osip_t *osip) {
300 #ifndef OSIP_MONOTHREAD
301   return osip_mutex_lock(osip->ist_fastmutex);
302 #else
303   return OSIP_SUCCESS;
304 #endif
305 }
306 
osip_ist_unlock(osip_t * osip)307 int osip_ist_unlock(osip_t *osip) {
308 #ifndef OSIP_MONOTHREAD
309   return osip_mutex_unlock(osip->ist_fastmutex);
310 #else
311   return OSIP_SUCCESS;
312 #endif
313 }
314 
osip_nict_lock(osip_t * osip)315 int osip_nict_lock(osip_t *osip) {
316 #ifndef OSIP_MONOTHREAD
317   return osip_mutex_lock(osip->nict_fastmutex);
318 #else
319   return OSIP_SUCCESS;
320 #endif
321 }
322 
osip_nict_unlock(osip_t * osip)323 int osip_nict_unlock(osip_t *osip) {
324 #ifndef OSIP_MONOTHREAD
325   return osip_mutex_unlock(osip->nict_fastmutex);
326 #else
327   return OSIP_SUCCESS;
328 #endif
329 }
330 
osip_nist_lock(osip_t * osip)331 int osip_nist_lock(osip_t *osip) {
332 #ifndef OSIP_MONOTHREAD
333   return osip_mutex_lock(osip->nist_fastmutex);
334 #else
335   return OSIP_SUCCESS;
336 #endif
337 }
338 
osip_nist_unlock(osip_t * osip)339 int osip_nist_unlock(osip_t *osip) {
340 #ifndef OSIP_MONOTHREAD
341   return osip_mutex_unlock(osip->nist_fastmutex);
342 #else
343   return OSIP_SUCCESS;
344 #endif
345 }
346 
347 #if defined(HAVE_DICT_DICT_H)
348 #define HSIZE 200
349 
350 unsigned s_hash(const unsigned char *p);
351 
s_hash(const unsigned char * p)352 unsigned s_hash(const unsigned char *p) {
353   unsigned hash = 0;
354 
355   while (*p) {
356     hash *= 31;
357     hash ^= *p++;
358   }
359 
360   return hash;
361 }
362 #endif
363 
__osip_add_ict(osip_t * osip,osip_transaction_t * ict)364 int __osip_add_ict(osip_t *osip, osip_transaction_t *ict) {
365 #ifndef OSIP_MONOTHREAD
366   osip_mutex_lock(osip->ict_fastmutex);
367 #endif
368 #if defined(HAVE_DICT_DICT_H)
369   {
370     osip_generic_param_t *b_request = NULL;
371     int rv = -99;
372 
373     osip_via_param_get_byname(ict->topvia, "branch", &b_request);
374 
375     if (b_request != NULL && b_request->gvalue != NULL)
376       rv = dict_insert((dict *) osip->osip_ict_hastable, b_request->gvalue, (void *) ict, FALSE);
377 
378     if (rv == 0) {
379       OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "New key inserted in ict hastable `%s'\n", b_request->gvalue));
380 
381     } else if (rv != -99) {
382       OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "already inserted `%s'\n", b_request->gvalue));
383     }
384   }
385 #endif
386   osip_list_add(&osip->osip_ict_transactions, ict, -1);
387 #ifndef OSIP_MONOTHREAD
388   osip_mutex_unlock(osip->ict_fastmutex);
389 #endif
390   return OSIP_SUCCESS;
391 }
392 
__osip_add_ist(osip_t * osip,osip_transaction_t * ist)393 int __osip_add_ist(osip_t *osip, osip_transaction_t *ist) {
394 #ifndef OSIP_MONOTHREAD
395   osip_mutex_lock(osip->ist_fastmutex);
396 #endif
397 #if defined(HAVE_DICT_DICT_H)
398   {
399     osip_generic_param_t *b_request = NULL;
400     int rv = -99;
401 
402     osip_via_param_get_byname(ist->topvia, "branch", &b_request);
403 
404     if (b_request != NULL && b_request->gvalue != NULL)
405       rv = dict_insert((dict *) osip->osip_ist_hastable, b_request->gvalue, (void *) ist, FALSE);
406 
407     if (rv == 0) {
408       OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "New key inserted in ist hastable `%s'\n", b_request->gvalue));
409 
410     } else if (rv != -99) {
411       OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "already inserted `%s'\n", b_request->gvalue));
412     }
413   }
414 #endif
415   osip_list_add(&osip->osip_ist_transactions, ist, -1);
416 #ifndef OSIP_MONOTHREAD
417   osip_mutex_unlock(osip->ist_fastmutex);
418 #endif
419   return OSIP_SUCCESS;
420 }
421 
__osip_add_nict(osip_t * osip,osip_transaction_t * nict)422 int __osip_add_nict(osip_t *osip, osip_transaction_t *nict) {
423 #ifndef OSIP_MONOTHREAD
424   osip_mutex_lock(osip->nict_fastmutex);
425 #endif
426 #if defined(HAVE_DICT_DICT_H)
427   {
428     osip_generic_param_t *b_request = NULL;
429     int rv = -99;
430 
431     osip_via_param_get_byname(nict->topvia, "branch", &b_request);
432 
433     if (b_request != NULL && b_request->gvalue != NULL)
434       rv = dict_insert((dict *) osip->osip_nict_hastable, b_request->gvalue, (void *) nict, FALSE);
435 
436     if (rv == 0) {
437       OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "New key inserted in nict hastable `%s'\n", b_request->gvalue));
438 
439     } else if (rv != -99) {
440       OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "already inserted `%s'\n", b_request->gvalue));
441     }
442   }
443 #endif
444   osip_list_add(&osip->osip_nict_transactions, nict, -1);
445 #ifndef OSIP_MONOTHREAD
446   osip_mutex_unlock(osip->nict_fastmutex);
447 #endif
448   return OSIP_SUCCESS;
449 }
450 
__osip_add_nist(osip_t * osip,osip_transaction_t * nist)451 int __osip_add_nist(osip_t *osip, osip_transaction_t *nist) {
452 #ifndef OSIP_MONOTHREAD
453   osip_mutex_lock(osip->nist_fastmutex);
454 #endif
455 #if defined(HAVE_DICT_DICT_H)
456   {
457     osip_generic_param_t *b_request = NULL;
458     int rv = -99;
459 
460     osip_via_param_get_byname(nist->topvia, "branch", &b_request);
461 
462     if (b_request != NULL && b_request->gvalue != NULL)
463       rv = dict_insert((dict *) osip->osip_nist_hastable, b_request->gvalue, (void *) nist, FALSE);
464 
465     if (rv == 0) {
466       OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "New key inserted in ict hastable `%s'\n", b_request->gvalue));
467 
468     } else if (rv != -99) {
469       OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "already inserted `%s'\n", b_request->gvalue));
470     }
471   }
472 #endif
473   osip_list_add(&osip->osip_nist_transactions, nist, -1);
474 #ifndef OSIP_MONOTHREAD
475   osip_mutex_unlock(osip->nist_fastmutex);
476 #endif
477   return OSIP_SUCCESS;
478 }
479 
osip_remove_transaction(osip_t * osip,osip_transaction_t * tr)480 int osip_remove_transaction(osip_t *osip, osip_transaction_t *tr) {
481   int i = -1;
482 
483   if (tr == NULL)
484     return OSIP_BADPARAMETER;
485 
486   if (tr->ctx_type == ICT)
487     i = __osip_remove_ict_transaction(osip, tr);
488 
489   else if (tr->ctx_type == IST)
490     i = __osip_remove_ist_transaction(osip, tr);
491 
492   else if (tr->ctx_type == NICT)
493     i = __osip_remove_nict_transaction(osip, tr);
494 
495   else if (tr->ctx_type == NIST)
496     i = __osip_remove_nist_transaction(osip, tr);
497 
498   else
499     return OSIP_BADPARAMETER;
500 
501   return i;
502 }
503 
__osip_remove_ict_transaction(osip_t * osip,osip_transaction_t * ict)504 int __osip_remove_ict_transaction(osip_t *osip, osip_transaction_t *ict) {
505   osip_list_iterator_t iterator;
506   osip_transaction_t *tmp;
507 
508 #ifndef OSIP_MONOTHREAD
509   osip_mutex_lock(osip->ict_fastmutex);
510 #endif
511 
512 #if defined(HAVE_DICT_DICT_H)
513   {
514     osip_generic_param_t *b_request = NULL;
515     int rv;
516 
517     osip_via_param_get_byname(ict->topvia, "branch", &b_request);
518 
519     if (b_request != NULL && b_request->gvalue != NULL) {
520       rv = dict_remove((dict *) osip->osip_ict_hastable, b_request->gvalue, TRUE);
521 
522       if (rv == 0) {
523         OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "New key deleted in ict hastable `%s'\n", b_request->gvalue));
524 
525       } else {
526         OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "key not removed `%s'\n", b_request->gvalue));
527       }
528     }
529   }
530 #endif
531 
532   tmp = (osip_transaction_t *) osip_list_get_first(&osip->osip_ict_transactions, &iterator);
533 
534   while (osip_list_iterator_has_elem(iterator)) {
535     if (tmp->transactionid == ict->transactionid) {
536       osip_list_iterator_remove(&iterator);
537 #ifndef OSIP_MONOTHREAD
538       osip_mutex_unlock(osip->ict_fastmutex);
539 #endif
540       return OSIP_SUCCESS;
541     }
542 
543     tmp = (osip_transaction_t *) osip_list_get_next(&iterator);
544   }
545 
546 #ifndef OSIP_MONOTHREAD
547   osip_mutex_unlock(osip->ict_fastmutex);
548 #endif
549   return OSIP_UNDEFINED_ERROR;
550 }
551 
__osip_remove_ist_transaction(osip_t * osip,osip_transaction_t * ist)552 int __osip_remove_ist_transaction(osip_t *osip, osip_transaction_t *ist) {
553   osip_list_iterator_t iterator;
554   osip_transaction_t *tmp;
555 
556 #ifndef OSIP_MONOTHREAD
557   osip_mutex_lock(osip->ist_fastmutex);
558 #endif
559 
560 #if defined(HAVE_DICT_DICT_H)
561   {
562     osip_generic_param_t *b_request = NULL;
563     int rv;
564 
565     osip_via_param_get_byname(ist->topvia, "branch", &b_request);
566 
567     if (b_request != NULL && b_request->gvalue != NULL) {
568       rv = dict_remove((dict *) osip->osip_ist_hastable, b_request->gvalue, TRUE);
569 
570       if (rv == 0) {
571         OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "New key deleted in ist hastable `%s'\n", b_request->gvalue));
572 
573       } else {
574         OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "key not removed `%s'\n", b_request->gvalue));
575       }
576     }
577   }
578 #endif
579 
580   tmp = (osip_transaction_t *) osip_list_get_first(&osip->osip_ist_transactions, &iterator);
581 
582   while (osip_list_iterator_has_elem(iterator)) {
583     if (tmp->transactionid == ist->transactionid) {
584       osip_list_iterator_remove(&iterator);
585 #ifndef OSIP_MONOTHREAD
586       osip_mutex_unlock(osip->ist_fastmutex);
587 #endif
588       return OSIP_SUCCESS;
589     }
590 
591     tmp = (osip_transaction_t *) osip_list_get_next(&iterator);
592   }
593 
594 #ifndef OSIP_MONOTHREAD
595   osip_mutex_unlock(osip->ist_fastmutex);
596 #endif
597   return OSIP_UNDEFINED_ERROR;
598 }
599 
__osip_remove_nict_transaction(osip_t * osip,osip_transaction_t * nict)600 int __osip_remove_nict_transaction(osip_t *osip, osip_transaction_t *nict) {
601   osip_list_iterator_t iterator;
602   osip_transaction_t *tmp;
603 
604 #ifndef OSIP_MONOTHREAD
605   osip_mutex_lock(osip->nict_fastmutex);
606 #endif
607 
608 #if defined(HAVE_DICT_DICT_H)
609   {
610     osip_generic_param_t *b_request = NULL;
611     int rv;
612 
613     osip_via_param_get_byname(nict->topvia, "branch", &b_request);
614 
615     if (b_request != NULL && b_request->gvalue != NULL) {
616       rv = dict_remove((dict *) osip->osip_nict_hastable, b_request->gvalue, TRUE);
617 
618       if (rv == 0) {
619         OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "New key deleted in nict hastable `%s'\n", b_request->gvalue));
620 
621       } else {
622         OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "key not removed `%s'\n", b_request->gvalue));
623       }
624     }
625   }
626 #endif
627 
628   tmp = (osip_transaction_t *) osip_list_get_first(&osip->osip_nict_transactions, &iterator);
629 
630   while (osip_list_iterator_has_elem(iterator)) {
631     if (tmp->transactionid == nict->transactionid) {
632       osip_list_iterator_remove(&iterator);
633 #ifndef OSIP_MONOTHREAD
634       osip_mutex_unlock(osip->nict_fastmutex);
635 #endif
636       return OSIP_SUCCESS;
637     }
638 
639     tmp = (osip_transaction_t *) osip_list_get_next(&iterator);
640   }
641 
642 #ifndef OSIP_MONOTHREAD
643   osip_mutex_unlock(osip->nict_fastmutex);
644 #endif
645   return OSIP_UNDEFINED_ERROR;
646 }
647 
__osip_remove_nist_transaction(osip_t * osip,osip_transaction_t * nist)648 int __osip_remove_nist_transaction(osip_t *osip, osip_transaction_t *nist) {
649   osip_list_iterator_t iterator;
650   osip_transaction_t *tmp;
651 
652 #ifndef OSIP_MONOTHREAD
653   osip_mutex_lock(osip->nist_fastmutex);
654 #endif
655 
656 #if defined(HAVE_DICT_DICT_H)
657   {
658     osip_generic_param_t *b_request = NULL;
659     int rv;
660 
661     osip_via_param_get_byname(nist->topvia, "branch", &b_request);
662 
663     if (b_request != NULL && b_request->gvalue != NULL) {
664       rv = dict_remove((dict *) osip->osip_nist_hastable, b_request->gvalue, TRUE);
665 
666       if (rv == 0) {
667         OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "New key deleted in ict hastable `%s'\n", b_request->gvalue));
668 
669       } else {
670         OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "key not removed `%s'\n", b_request->gvalue));
671       }
672     }
673   }
674 #endif
675 
676   tmp = (osip_transaction_t *) osip_list_get_first(&osip->osip_nist_transactions, &iterator);
677 
678   while (osip_list_iterator_has_elem(iterator)) {
679     if (tmp->transactionid == nist->transactionid) {
680       osip_list_iterator_remove(&iterator);
681 #ifndef OSIP_MONOTHREAD
682       osip_mutex_unlock(osip->nist_fastmutex);
683 #endif
684       return OSIP_SUCCESS;
685     }
686 
687     tmp = (osip_transaction_t *) osip_list_get_next(&iterator);
688   }
689 
690 #ifndef OSIP_MONOTHREAD
691   osip_mutex_unlock(osip->nist_fastmutex);
692 #endif
693   return OSIP_UNDEFINED_ERROR;
694 }
695 
osip_find_transaction_and_add_event(osip_t * osip,osip_event_t * evt)696 int osip_find_transaction_and_add_event(osip_t *osip, osip_event_t *evt) {
697   osip_transaction_t *transaction = __osip_find_transaction(osip, evt, 1);
698 
699   if (transaction == NULL)
700     return OSIP_UNDEFINED_ERROR;
701 
702   return OSIP_SUCCESS;
703 }
704 
705 #ifdef OSIP_MONOTHREAD
osip_find_transaction(osip_t * osip,osip_event_t * evt)706 osip_transaction_t *osip_find_transaction(osip_t *osip, osip_event_t *evt) {
707   return __osip_find_transaction(osip, evt, 0);
708 }
709 #endif
710 
__osip_find_transaction(osip_t * osip,osip_event_t * evt,int consume)711 osip_transaction_t *__osip_find_transaction(osip_t *osip, osip_event_t *evt, int consume) {
712   osip_transaction_t *transaction = NULL;
713   osip_list_t *transactions = NULL;
714 
715 #ifndef OSIP_MONOTHREAD
716   struct osip_mutex *mut = NULL;
717 #endif
718 
719   if (evt == NULL || evt->sip == NULL || evt->sip->cseq == NULL)
720     return NULL;
721 
722   if (EVT_IS_INCOMINGMSG(evt)) {
723     if (MSG_IS_REQUEST(evt->sip)) {
724       if (0 == strcmp(evt->sip->cseq->method, "INVITE") || 0 == strcmp(evt->sip->cseq->method, "ACK")) {
725         transactions = &osip->osip_ist_transactions;
726 #ifndef OSIP_MONOTHREAD
727         mut = osip->ist_fastmutex;
728 #endif
729 
730       } else {
731         transactions = &osip->osip_nist_transactions;
732 #ifndef OSIP_MONOTHREAD
733         mut = osip->nist_fastmutex;
734 #endif
735       }
736 
737     } else {
738       if (0 == strcmp(evt->sip->cseq->method, "INVITE")) {
739         transactions = &osip->osip_ict_transactions;
740 #ifndef OSIP_MONOTHREAD
741         mut = osip->ict_fastmutex;
742 #endif
743 
744       } else {
745         transactions = &osip->osip_nict_transactions;
746 #ifndef OSIP_MONOTHREAD
747         mut = osip->nict_fastmutex;
748 #endif
749       }
750     }
751 
752   } else if (EVT_IS_OUTGOINGMSG(evt)) {
753     if (MSG_IS_RESPONSE(evt->sip)) {
754       if (0 == strcmp(evt->sip->cseq->method, "INVITE")) {
755         transactions = &osip->osip_ist_transactions;
756 #ifndef OSIP_MONOTHREAD
757         mut = osip->ist_fastmutex;
758 #endif
759 
760       } else {
761         transactions = &osip->osip_nist_transactions;
762 #ifndef OSIP_MONOTHREAD
763         mut = osip->nist_fastmutex;
764 #endif
765       }
766 
767     } else {
768       if (0 == strcmp(evt->sip->cseq->method, "INVITE") || 0 == strcmp(evt->sip->cseq->method, "ACK")) {
769         transactions = &osip->osip_ict_transactions;
770 #ifndef OSIP_MONOTHREAD
771         mut = osip->ict_fastmutex;
772 #endif
773 
774       } else {
775         transactions = &osip->osip_nict_transactions;
776 #ifndef OSIP_MONOTHREAD
777         mut = osip->nict_fastmutex;
778 #endif
779       }
780     }
781   }
782 
783   if (transactions == NULL)
784     return NULL; /* not a message??? */
785 
786 #ifndef OSIP_MONOTHREAD
787   osip_mutex_lock(mut);
788 #endif
789   transaction = osip_transaction_find(transactions, evt);
790 
791   if (consume == 1) { /* we add the event before releasing the mutex!! */
792     if (transaction != NULL) {
793       osip_transaction_add_event(transaction, evt);
794 #ifndef OSIP_MONOTHREAD
795       osip_mutex_unlock(mut);
796 #endif
797       return transaction;
798     }
799   }
800 
801 #ifndef OSIP_MONOTHREAD
802   osip_mutex_unlock(mut);
803 #endif
804 
805   return transaction;
806 }
807 
osip_create_transaction(osip_t * osip,osip_event_t * evt)808 osip_transaction_t *osip_create_transaction(osip_t *osip, osip_event_t *evt) {
809   osip_transaction_t *transaction;
810   int i;
811   osip_fsm_type_t ctx_type;
812 
813   if (evt == NULL)
814     return NULL;
815 
816   if (evt->sip == NULL)
817     return NULL;
818 
819   /* make sure the request's method reflect the cseq value. */
820   if (MSG_IS_REQUEST(evt->sip)) {
821     /* delete request where cseq method does not match
822        the method in request-line */
823     if (evt->sip->cseq == NULL || evt->sip->cseq->method == NULL || evt->sip->sip_method == NULL) {
824       return NULL;
825     }
826 
827     if (0 != strcmp(evt->sip->cseq->method, evt->sip->sip_method)) {
828       OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "core module: Discard invalid message with method!=cseq!\n"));
829       return NULL;
830     }
831   }
832 
833   if (MSG_IS_ACK(evt->sip)) /* ACK never create transactions */
834     return NULL;
835 
836   if (EVT_IS_INCOMINGREQ(evt)) {
837     /* we create a new context for this incoming request */
838     if (0 == strcmp(evt->sip->cseq->method, "INVITE"))
839       ctx_type = IST;
840 
841     else
842       ctx_type = NIST;
843 
844   } else if (EVT_IS_OUTGOINGREQ(evt)) {
845     if (0 == strcmp(evt->sip->cseq->method, "INVITE"))
846       ctx_type = ICT;
847 
848     else
849       ctx_type = NICT;
850 
851   } else {
852     OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "Cannot build a transaction for this message!\n"));
853     return NULL;
854   }
855 
856   i = osip_transaction_init(&transaction, ctx_type, osip, evt->sip);
857 
858   if (i != 0) {
859     return NULL;
860   }
861 
862   evt->transactionid = transaction->transactionid;
863   return transaction;
864 }
865 
osip_transaction_find(osip_list_t * transactions,osip_event_t * evt)866 osip_transaction_t *osip_transaction_find(osip_list_t *transactions, osip_event_t *evt) {
867   osip_list_iterator_t iterator;
868   osip_transaction_t *transaction;
869   osip_t *osip = NULL;
870 
871   transaction = (osip_transaction_t *) osip_list_get_first(transactions, &iterator);
872 
873   if (transaction != NULL)
874     osip = (osip_t *) transaction->config;
875 
876   if (osip == NULL)
877     return NULL;
878 
879   if (EVT_IS_INCOMINGREQ(evt)) {
880 #ifdef HAVE_DICT_DICT_H
881     /* search in hastable! */
882     osip_generic_param_t *b_request;
883     osip_via_t *topvia_request;
884 
885     topvia_request = osip_list_get(&evt->sip->vias, 0);
886 
887     if (topvia_request == NULL) {
888       OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "Remote UA is not compliant: missing a Via header!\n"));
889       return NULL;
890     }
891 
892     osip_via_param_get_byname(topvia_request, "branch", &b_request);
893 
894     if (b_request != NULL && b_request->gvalue != NULL) {
895       if (MSG_IS_INVITE(evt->sip) || MSG_IS_ACK(evt->sip)) {
896         transaction = (osip_transaction_t *) dict_search((dict *) osip->osip_ist_hastable, b_request->gvalue);
897         OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO2, NULL, "Find matching Via header for INVITE(ACK) REQUEST!\n"));
898 
899         if (transaction != NULL)
900           return transaction;
901 
902       } else {
903         transaction = (osip_transaction_t *) dict_search((dict *) osip->osip_nist_hastable, b_request->gvalue);
904         OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO2, NULL, "Find matching Via header for NON-INVITE REQUEST!\n"));
905 
906         if (transaction != NULL)
907           return transaction;
908       }
909     }
910 
911 #endif
912 
913     transaction = (osip_transaction_t *) osip_list_get_first(transactions, &iterator);
914 
915     while (osip_list_iterator_has_elem(iterator)) {
916       if (0 == __osip_transaction_matching_request_osip_to_xist_17_2_3(transaction, evt->sip))
917         return transaction;
918 
919       transaction = (osip_transaction_t *) osip_list_get_next(&iterator);
920     }
921 
922   } else if (EVT_IS_INCOMINGRESP(evt)) {
923 #ifdef HAVE_DICT_DICT_H
924     /* search in hastable! */
925     osip_generic_param_t *b_request;
926     osip_via_t *topvia_request;
927 
928     topvia_request = osip_list_get(&evt->sip->vias, 0);
929 
930     if (topvia_request == NULL) {
931       OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "Remote UA is not compliant: missing a Via header!\n"));
932       return NULL;
933     }
934 
935     osip_via_param_get_byname(topvia_request, "branch", &b_request);
936 
937     if (b_request != NULL && b_request->gvalue != NULL) {
938       if (MSG_IS_RESPONSE_FOR(evt->sip, "INVITE")) {
939         transaction = (osip_transaction_t *) dict_search((dict *) osip->osip_ict_hastable, b_request->gvalue);
940         OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO2, NULL, "Find matching Via header for INVITE ANSWER!\n"));
941 
942         if (transaction != NULL)
943           return transaction;
944 
945       } else {
946         transaction = (osip_transaction_t *) dict_search((dict *) osip->osip_nict_hastable, b_request->gvalue);
947         OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO2, NULL, "Find matching Via header for NON-INVITE ANSWER!\n"));
948 
949         if (transaction != NULL)
950           return transaction;
951       }
952     }
953 
954 #endif
955 
956     transaction = (osip_transaction_t *) osip_list_get_first(transactions, &iterator);
957 
958     while (osip_list_iterator_has_elem(iterator)) {
959       if (0 == __osip_transaction_matching_response_osip_to_xict_17_1_3(transaction, evt->sip))
960         return transaction;
961 
962       transaction = (osip_transaction_t *) osip_list_get_next(&iterator);
963     }
964 
965   } else { /* handle OUTGOING message */
966     /* THE TRANSACTION ID MUST BE SET */
967     transaction = (osip_transaction_t *) osip_list_get_first(transactions, &iterator);
968 
969     while (osip_list_iterator_has_elem(iterator)) {
970       if (transaction->transactionid == evt->transactionid)
971         return transaction;
972 
973       transaction = (osip_transaction_t *) osip_list_get_next(&iterator);
974     }
975   }
976 
977   return NULL;
978 }
979 
osip_init(osip_t ** osip)980 int osip_init(osip_t **osip) {
981   static int ref_count = 0;
982 
983   if (ref_count == 0) {
984     ref_count++;
985     /* load the parser configuration */
986     parser_init();
987   }
988 
989   *osip = (osip_t *) osip_malloc(sizeof(osip_t));
990 
991   if (*osip == NULL)
992     return OSIP_NOMEM; /* allocation failed */
993 
994   memset(*osip, 0, sizeof(osip_t));
995 
996 #ifndef OSIP_MONOTHREAD
997   (*osip)->ict_fastmutex = osip_mutex_init();
998   (*osip)->ist_fastmutex = osip_mutex_init();
999   (*osip)->nict_fastmutex = osip_mutex_init();
1000   (*osip)->nist_fastmutex = osip_mutex_init();
1001 
1002   (*osip)->ixt_fastmutex = osip_mutex_init();
1003   (*osip)->id_mutex = osip_mutex_init();
1004 #endif
1005 
1006   osip_list_init(&(*osip)->osip_ict_transactions);
1007   osip_list_init(&(*osip)->osip_ist_transactions);
1008   osip_list_init(&(*osip)->osip_nict_transactions);
1009   osip_list_init(&(*osip)->osip_nist_transactions);
1010   osip_list_init(&(*osip)->ixt_retransmissions);
1011 
1012   (*osip)->transactionid = 1;
1013 
1014 #if defined(HAVE_DICT_DICT_H)
1015   (*osip)->osip_ict_hastable = (dict *) hashtable_dict_new((dict_cmp_func) strcmp, (dict_hsh_func) s_hash, NULL, NULL, HSIZE);
1016   (*osip)->osip_ist_hastable = (dict *) hashtable_dict_new((dict_cmp_func) strcmp, (dict_hsh_func) s_hash, NULL, NULL, HSIZE);
1017   (*osip)->osip_nict_hastable = (dict *) hashtable_dict_new((dict_cmp_func) strcmp, (dict_hsh_func) s_hash, NULL, NULL, HSIZE);
1018   (*osip)->osip_nist_hastable = (dict *) hashtable_dict_new((dict_cmp_func) strcmp, (dict_hsh_func) s_hash, NULL, NULL, HSIZE);
1019 #endif
1020 
1021   return OSIP_SUCCESS;
1022 }
1023 
osip_release(osip_t * osip)1024 void osip_release(osip_t *osip) {
1025 #ifndef OSIP_MONOTHREAD
1026   osip_mutex_destroy(osip->ict_fastmutex);
1027   osip_mutex_destroy(osip->ist_fastmutex);
1028   osip_mutex_destroy(osip->nict_fastmutex);
1029   osip_mutex_destroy(osip->nist_fastmutex);
1030 
1031   osip_mutex_destroy(osip->ixt_fastmutex);
1032   osip_mutex_destroy(osip->id_mutex);
1033 #endif
1034 
1035   osip_free(osip);
1036 }
1037 
osip_set_application_context(osip_t * osip,void * pointer)1038 void osip_set_application_context(osip_t *osip, void *pointer) {
1039   osip->application_context = pointer;
1040 }
1041 
osip_get_application_context(osip_t * osip)1042 void *osip_get_application_context(osip_t *osip) {
1043   if (osip == NULL)
1044     return NULL;
1045 
1046   return osip->application_context;
1047 }
1048 
osip_ict_execute(osip_t * osip)1049 int osip_ict_execute(osip_t *osip) {
1050   osip_transaction_t *transaction;
1051   osip_event_t *se;
1052   int more_event;
1053   osip_list_iterator_t iterator;
1054   void **array;
1055   int len;
1056   int index = 0;
1057 
1058   /* list must be copied because osip_transaction_execute() may change it */
1059 #ifndef OSIP_MONOTHREAD
1060   osip_mutex_lock(osip->ict_fastmutex);
1061 #endif
1062   len = osip_list_size(&osip->osip_ict_transactions);
1063 
1064   if (0 >= len) {
1065 #ifndef OSIP_MONOTHREAD
1066     osip_mutex_unlock(osip->ict_fastmutex);
1067 #endif
1068     return OSIP_SUCCESS;
1069   }
1070 
1071   array = osip_malloc(sizeof(void *) * len);
1072 
1073   if (array == NULL) {
1074 #ifndef OSIP_MONOTHREAD
1075     osip_mutex_unlock(osip->ict_fastmutex);
1076 #endif
1077     return OSIP_NOMEM; /* OSIP_SUCCESS; */
1078   }
1079 
1080   transaction = (osip_transaction_t *) osip_list_get_first(&osip->osip_ict_transactions, &iterator);
1081 
1082   while (osip_list_iterator_has_elem(iterator)) {
1083     array[index++] = transaction;
1084     transaction = (osip_transaction_t *) osip_list_get_next(&iterator);
1085   }
1086 
1087 #ifndef OSIP_MONOTHREAD
1088   osip_mutex_unlock(osip->ict_fastmutex);
1089 #endif
1090 
1091   for (index = 0; index < len; ++index) {
1092     transaction = (osip_transaction_t *) array[index];
1093     more_event = 1;
1094 
1095     do {
1096       se = (osip_event_t *) osip_fifo_tryget(transaction->transactionff);
1097 
1098       if (se == NULL) /* no more event for this transaction */
1099         more_event = 0;
1100 
1101       else
1102         osip_transaction_execute(transaction, se);
1103     } while (more_event == 1);
1104   }
1105 
1106   osip_free(array);
1107 
1108   return OSIP_SUCCESS;
1109 }
1110 
osip_ist_execute(osip_t * osip)1111 int osip_ist_execute(osip_t *osip) {
1112   osip_transaction_t *transaction;
1113   osip_event_t *se;
1114   int more_event;
1115   osip_list_iterator_t iterator;
1116   void **array;
1117   int len;
1118   int index = 0;
1119 
1120   /* list must be copied because osip_transaction_execute() may change it */
1121 #ifndef OSIP_MONOTHREAD
1122   osip_mutex_lock(osip->ist_fastmutex);
1123 #endif
1124   len = osip_list_size(&osip->osip_ist_transactions);
1125 
1126   if (0 >= len) {
1127 #ifndef OSIP_MONOTHREAD
1128     osip_mutex_unlock(osip->ist_fastmutex);
1129 #endif
1130     return OSIP_SUCCESS;
1131   }
1132 
1133   array = osip_malloc(sizeof(void *) * len);
1134 
1135   if (array == NULL) {
1136 #ifndef OSIP_MONOTHREAD
1137     osip_mutex_unlock(osip->ist_fastmutex);
1138 #endif
1139     return OSIP_NOMEM; /* OSIP_SUCCESS; */
1140   }
1141 
1142   transaction = (osip_transaction_t *) osip_list_get_first(&osip->osip_ist_transactions, &iterator);
1143 
1144   while (osip_list_iterator_has_elem(iterator)) {
1145     array[index++] = transaction;
1146     transaction = (osip_transaction_t *) osip_list_get_next(&iterator);
1147   }
1148 
1149 #ifndef OSIP_MONOTHREAD
1150   osip_mutex_unlock(osip->ist_fastmutex);
1151 #endif
1152 
1153   for (index = 0; index < len; ++index) {
1154     transaction = (osip_transaction_t *) array[index];
1155     more_event = 1;
1156 
1157     do {
1158       se = (osip_event_t *) osip_fifo_tryget(transaction->transactionff);
1159 
1160       if (se == NULL) /* no more event for this transaction */
1161         more_event = 0;
1162 
1163       else
1164         osip_transaction_execute(transaction, se);
1165     } while (more_event == 1);
1166   }
1167 
1168   osip_free(array);
1169 
1170   return OSIP_SUCCESS;
1171 }
1172 
osip_nict_execute(osip_t * osip)1173 int osip_nict_execute(osip_t *osip) {
1174   osip_transaction_t *transaction;
1175   osip_event_t *se;
1176   int more_event;
1177   osip_list_iterator_t iterator;
1178   void **array;
1179   int len;
1180   int index = 0;
1181 
1182   /* list must be copied because osip_transaction_execute() may change it */
1183 #ifndef OSIP_MONOTHREAD
1184   osip_mutex_lock(osip->nict_fastmutex);
1185 #endif
1186   len = osip_list_size(&osip->osip_nict_transactions);
1187 
1188   if (0 >= len) {
1189 #ifndef OSIP_MONOTHREAD
1190     osip_mutex_unlock(osip->nict_fastmutex);
1191 #endif
1192     return OSIP_SUCCESS;
1193   }
1194 
1195   array = osip_malloc(sizeof(void *) * len);
1196 
1197   if (array == NULL) {
1198 #ifndef OSIP_MONOTHREAD
1199     osip_mutex_unlock(osip->nict_fastmutex);
1200 #endif
1201     return OSIP_NOMEM; /* OSIP_SUCCESS; */
1202   }
1203 
1204   transaction = (osip_transaction_t *) osip_list_get_first(&osip->osip_nict_transactions, &iterator);
1205 
1206   while (osip_list_iterator_has_elem(iterator)) {
1207     array[index++] = transaction;
1208     transaction = (osip_transaction_t *) osip_list_get_next(&iterator);
1209   }
1210 
1211 #ifndef OSIP_MONOTHREAD
1212   osip_mutex_unlock(osip->nict_fastmutex);
1213 #endif
1214 
1215   for (index = 0; index < len; ++index) {
1216     transaction = (osip_transaction_t *) array[index];
1217     more_event = 1;
1218 
1219     do {
1220       se = (osip_event_t *) osip_fifo_tryget(transaction->transactionff);
1221 
1222       if (se == NULL) /* no more event for this transaction */
1223         more_event = 0;
1224 
1225       else
1226         osip_transaction_execute(transaction, se);
1227     } while (more_event == 1);
1228   }
1229 
1230   osip_free(array);
1231 
1232   return OSIP_SUCCESS;
1233 }
1234 
osip_nist_execute(osip_t * osip)1235 int osip_nist_execute(osip_t *osip) {
1236   osip_transaction_t *transaction;
1237   osip_event_t *se;
1238   int more_event;
1239   osip_list_iterator_t iterator;
1240   void **array;
1241   int len;
1242   int index = 0;
1243 
1244   /* list must be copied because osip_transaction_execute() may change it */
1245 #ifndef OSIP_MONOTHREAD
1246   osip_mutex_lock(osip->nist_fastmutex);
1247 #endif
1248   len = osip_list_size(&osip->osip_nist_transactions);
1249 
1250   if (0 >= len) {
1251 #ifndef OSIP_MONOTHREAD
1252     osip_mutex_unlock(osip->nist_fastmutex);
1253 #endif
1254     return OSIP_SUCCESS;
1255   }
1256 
1257   array = osip_malloc(sizeof(void *) * len);
1258 
1259   if (array == NULL) {
1260 #ifndef OSIP_MONOTHREAD
1261     osip_mutex_unlock(osip->nist_fastmutex);
1262 #endif
1263     return OSIP_NOMEM; /* OSIP_SUCCESS; */
1264   }
1265 
1266   transaction = (osip_transaction_t *) osip_list_get_first(&osip->osip_nist_transactions, &iterator);
1267 
1268   while (osip_list_iterator_has_elem(iterator)) {
1269     array[index++] = transaction;
1270     transaction = (osip_transaction_t *) osip_list_get_next(&iterator);
1271   }
1272 
1273 #ifndef OSIP_MONOTHREAD
1274   osip_mutex_unlock(osip->nist_fastmutex);
1275 #endif
1276 
1277   for (index = 0; index < len; ++index) {
1278     transaction = (osip_transaction_t *) array[index];
1279     more_event = 1;
1280 
1281     do {
1282       se = (osip_event_t *) osip_fifo_tryget(transaction->transactionff);
1283 
1284       if (se == NULL) /* no more event for this transaction */
1285         more_event = 0;
1286 
1287       else
1288         osip_transaction_execute(transaction, se);
1289     } while (more_event == 1);
1290   }
1291 
1292   osip_free(array);
1293 
1294   return OSIP_SUCCESS;
1295 }
1296 
osip_timers_gettimeout(osip_t * osip,struct timeval * lower_tv)1297 void osip_timers_gettimeout(osip_t *osip, struct timeval *lower_tv) {
1298   struct timeval now;
1299   osip_transaction_t *tr;
1300   osip_list_iterator_t iterator;
1301 
1302   osip_gettimeofday(&now, NULL);
1303   lower_tv->tv_sec = now.tv_sec + 3600 * 24 * 365; /* wake up evry year :-) */
1304   lower_tv->tv_usec = now.tv_usec;
1305 
1306 #ifndef OSIP_MONOTHREAD
1307   osip_mutex_lock(osip->ict_fastmutex);
1308 #endif
1309   /* handle ict timers */
1310   tr = (osip_transaction_t *) osip_list_get_first(&osip->osip_ict_transactions, &iterator);
1311 
1312   while (osip_list_iterator_has_elem(iterator)) {
1313     if (1 <= osip_fifo_size(tr->transactionff)) {
1314       OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO4, NULL, "1 Pending event already in transaction !\n"));
1315       lower_tv->tv_sec = 0;
1316       lower_tv->tv_usec = 0;
1317 #ifndef OSIP_MONOTHREAD
1318       osip_mutex_unlock(osip->ict_fastmutex);
1319 #endif
1320       return;
1321 
1322     } else {
1323       if (tr->state == ICT_CALLING)
1324         min_timercmp(lower_tv, &tr->ict_context->timer_b_start);
1325 
1326       if (tr->state == ICT_CALLING)
1327         min_timercmp(lower_tv, &tr->ict_context->timer_a_start);
1328 
1329       if (tr->state == ICT_COMPLETED)
1330         min_timercmp(lower_tv, &tr->ict_context->timer_d_start);
1331 
1332       if (osip_timercmp(&now, lower_tv, >=)) {
1333         lower_tv->tv_sec = 0;
1334         lower_tv->tv_usec = 0;
1335 #ifndef OSIP_MONOTHREAD
1336         osip_mutex_unlock(osip->ict_fastmutex);
1337 #endif
1338         return;
1339       }
1340     }
1341 
1342     tr = (osip_transaction_t *) osip_list_get_next(&iterator);
1343   }
1344 
1345 #ifndef OSIP_MONOTHREAD
1346   osip_mutex_unlock(osip->ict_fastmutex);
1347 #endif
1348 
1349 #ifndef OSIP_MONOTHREAD
1350   osip_mutex_lock(osip->ist_fastmutex);
1351 #endif
1352   /* handle ist timers */
1353   tr = (osip_transaction_t *) osip_list_get_first(&osip->osip_ist_transactions, &iterator);
1354 
1355   while (osip_list_iterator_has_elem(iterator)) {
1356     if (tr->state == IST_CONFIRMED)
1357       min_timercmp(lower_tv, &tr->ist_context->timer_i_start);
1358 
1359     if (tr->state == IST_COMPLETED)
1360       min_timercmp(lower_tv, &tr->ist_context->timer_h_start);
1361 
1362     if (tr->state == IST_COMPLETED)
1363       min_timercmp(lower_tv, &tr->ist_context->timer_g_start);
1364 
1365     if (osip_timercmp(&now, lower_tv, >=)) {
1366       lower_tv->tv_sec = 0;
1367       lower_tv->tv_usec = 0;
1368 #ifndef OSIP_MONOTHREAD
1369       osip_mutex_unlock(osip->ist_fastmutex);
1370 #endif
1371       return;
1372     }
1373 
1374     tr = (osip_transaction_t *) osip_list_get_next(&iterator);
1375   }
1376 
1377 #ifndef OSIP_MONOTHREAD
1378   osip_mutex_unlock(osip->ist_fastmutex);
1379 #endif
1380 
1381 #ifndef OSIP_MONOTHREAD
1382   osip_mutex_lock(osip->nict_fastmutex);
1383 #endif
1384   /* handle nict timers */
1385   tr = (osip_transaction_t *) osip_list_get_first(&osip->osip_nict_transactions, &iterator);
1386 
1387   while (osip_list_iterator_has_elem(iterator)) {
1388     if (tr->state == NICT_COMPLETED)
1389       min_timercmp(lower_tv, &tr->nict_context->timer_k_start);
1390 
1391     if (tr->state == NICT_PROCEEDING || tr->state == NICT_TRYING)
1392       min_timercmp(lower_tv, &tr->nict_context->timer_f_start);
1393 
1394     if (tr->state == NICT_PROCEEDING || tr->state == NICT_TRYING)
1395       min_timercmp(lower_tv, &tr->nict_context->timer_e_start);
1396 
1397     if (osip_timercmp(&now, lower_tv, >=)) {
1398       lower_tv->tv_sec = 0;
1399       lower_tv->tv_usec = 0;
1400 #ifndef OSIP_MONOTHREAD
1401       osip_mutex_unlock(osip->nict_fastmutex);
1402 #endif
1403       return;
1404     }
1405 
1406     tr = (osip_transaction_t *) osip_list_get_next(&iterator);
1407   }
1408 
1409 #ifndef OSIP_MONOTHREAD
1410   osip_mutex_unlock(osip->nict_fastmutex);
1411 #endif
1412 
1413 #ifndef OSIP_MONOTHREAD
1414   osip_mutex_lock(osip->nist_fastmutex);
1415 #endif
1416   /* handle nist timers */
1417   tr = (osip_transaction_t *) osip_list_get_first(&osip->osip_nist_transactions, &iterator);
1418 
1419   while (osip_list_iterator_has_elem(iterator)) {
1420     if (tr->state == NIST_COMPLETED)
1421       min_timercmp(lower_tv, &tr->nist_context->timer_j_start);
1422 
1423     if (osip_timercmp(&now, lower_tv, >=)) {
1424       lower_tv->tv_sec = 0;
1425       lower_tv->tv_usec = 0;
1426 #ifndef OSIP_MONOTHREAD
1427       osip_mutex_unlock(osip->nist_fastmutex);
1428 #endif
1429       return;
1430     }
1431 
1432     tr = (osip_transaction_t *) osip_list_get_next(&iterator);
1433   }
1434 
1435 #ifndef OSIP_MONOTHREAD
1436   osip_mutex_unlock(osip->nist_fastmutex);
1437 #endif
1438 
1439 #ifndef OSIP_MONOTHREAD
1440   osip_mutex_lock(osip->ixt_fastmutex);
1441 #endif
1442   {
1443     ixt_t *ixt;
1444 
1445     ixt = (ixt_t *) osip_list_get_first(&osip->ixt_retransmissions, &iterator);
1446 
1447     while (osip_list_iterator_has_elem(iterator)) {
1448       min_timercmp(lower_tv, &ixt->start);
1449 
1450       if (osip_timercmp(&now, lower_tv, >=)) {
1451         lower_tv->tv_sec = 0;
1452         lower_tv->tv_usec = 0;
1453 #ifndef OSIP_MONOTHREAD
1454         osip_mutex_unlock(osip->ixt_fastmutex);
1455 #endif
1456         return;
1457       }
1458 
1459       ixt = (ixt_t *) osip_list_get_next(&iterator);
1460     }
1461   }
1462 #ifndef OSIP_MONOTHREAD
1463   osip_mutex_unlock(osip->ixt_fastmutex);
1464 #endif
1465 
1466   lower_tv->tv_sec = lower_tv->tv_sec - now.tv_sec;
1467   lower_tv->tv_usec = lower_tv->tv_usec - now.tv_usec;
1468 
1469   /* just make sure the value is correct! */
1470   if (lower_tv->tv_usec < 0) {
1471     lower_tv->tv_usec = lower_tv->tv_usec + 1000000;
1472     lower_tv->tv_sec--;
1473   }
1474 
1475   if (lower_tv->tv_sec < 0) {
1476     lower_tv->tv_sec = 0;
1477     lower_tv->tv_usec = 0;
1478   }
1479 
1480   if (lower_tv->tv_usec > 1000000) {
1481     lower_tv->tv_usec = lower_tv->tv_usec - 1000000;
1482     lower_tv->tv_sec++;
1483   }
1484 
1485   return;
1486 }
1487 
osip_timers_ict_execute(osip_t * osip)1488 void osip_timers_ict_execute(osip_t *osip) {
1489   osip_transaction_t *tr;
1490   osip_list_iterator_t iterator;
1491 
1492 #ifndef OSIP_MONOTHREAD
1493   osip_mutex_lock(osip->ict_fastmutex);
1494 #endif
1495   /* handle ict timers */
1496   tr = (osip_transaction_t *) osip_list_get_first(&osip->osip_ict_transactions, &iterator);
1497 
1498   while (osip_list_iterator_has_elem(iterator)) {
1499     osip_event_t *evt;
1500 
1501     if (1 <= osip_fifo_size(tr->transactionff)) {
1502       OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO4, NULL, "1 Pending event already in transaction !\n"));
1503 
1504     } else {
1505       evt = __osip_ict_need_timer_b_event(tr->ict_context, tr->state, tr->transactionid);
1506 
1507       if (evt != NULL)
1508         osip_fifo_add(tr->transactionff, evt);
1509 
1510       else {
1511         evt = __osip_ict_need_timer_a_event(tr->ict_context, tr->state, tr->transactionid);
1512 
1513         if (evt != NULL)
1514           osip_fifo_add(tr->transactionff, evt);
1515 
1516         else {
1517           evt = __osip_ict_need_timer_d_event(tr->ict_context, tr->state, tr->transactionid);
1518 
1519           if (evt != NULL)
1520             osip_fifo_add(tr->transactionff, evt);
1521         }
1522       }
1523     }
1524 
1525     tr = (osip_transaction_t *) osip_list_get_next(&iterator);
1526   }
1527 
1528 #ifndef OSIP_MONOTHREAD
1529   osip_mutex_unlock(osip->ict_fastmutex);
1530 #endif
1531 }
1532 
osip_timers_ist_execute(osip_t * osip)1533 void osip_timers_ist_execute(osip_t *osip) {
1534   osip_transaction_t *tr;
1535   osip_list_iterator_t iterator;
1536 
1537 #ifndef OSIP_MONOTHREAD
1538   osip_mutex_lock(osip->ist_fastmutex);
1539 #endif
1540   /* handle ist timers */
1541   tr = (osip_transaction_t *) osip_list_get_first(&osip->osip_ist_transactions, &iterator);
1542 
1543   while (osip_list_iterator_has_elem(iterator)) {
1544     osip_event_t *evt;
1545 
1546     evt = __osip_ist_need_timer_i_event(tr->ist_context, tr->state, tr->transactionid);
1547 
1548     if (evt != NULL)
1549       osip_fifo_add(tr->transactionff, evt);
1550 
1551     else {
1552       evt = __osip_ist_need_timer_h_event(tr->ist_context, tr->state, tr->transactionid);
1553 
1554       if (evt != NULL)
1555         osip_fifo_add(tr->transactionff, evt);
1556 
1557       else {
1558         evt = __osip_ist_need_timer_g_event(tr->ist_context, tr->state, tr->transactionid);
1559 
1560         if (evt != NULL)
1561           osip_fifo_add(tr->transactionff, evt);
1562       }
1563     }
1564 
1565     tr = (osip_transaction_t *) osip_list_get_next(&iterator);
1566   }
1567 
1568 #ifndef OSIP_MONOTHREAD
1569   osip_mutex_unlock(osip->ist_fastmutex);
1570 #endif
1571 }
1572 
osip_timers_nict_execute(osip_t * osip)1573 void osip_timers_nict_execute(osip_t *osip) {
1574   osip_transaction_t *tr;
1575   osip_list_iterator_t iterator;
1576 
1577 #ifndef OSIP_MONOTHREAD
1578   osip_mutex_lock(osip->nict_fastmutex);
1579 #endif
1580   /* handle nict timers */
1581   tr = (osip_transaction_t *) osip_list_get_first(&osip->osip_nict_transactions, &iterator);
1582 
1583   while (osip_list_iterator_has_elem(iterator)) {
1584     osip_event_t *evt;
1585 
1586     evt = __osip_nict_need_timer_k_event(tr->nict_context, tr->state, tr->transactionid);
1587 
1588     if (evt != NULL)
1589       osip_fifo_add(tr->transactionff, evt);
1590 
1591     else {
1592       evt = __osip_nict_need_timer_f_event(tr->nict_context, tr->state, tr->transactionid);
1593 
1594       if (evt != NULL)
1595         osip_fifo_add(tr->transactionff, evt);
1596 
1597       else {
1598         evt = __osip_nict_need_timer_e_event(tr->nict_context, tr->state, tr->transactionid);
1599 
1600         if (evt != NULL)
1601           osip_fifo_add(tr->transactionff, evt);
1602       }
1603     }
1604 
1605     tr = (osip_transaction_t *) osip_list_get_next(&iterator);
1606   }
1607 
1608 #ifndef OSIP_MONOTHREAD
1609   osip_mutex_unlock(osip->nict_fastmutex);
1610 #endif
1611 }
1612 
osip_timers_nist_execute(osip_t * osip)1613 void osip_timers_nist_execute(osip_t *osip) {
1614   osip_transaction_t *tr;
1615   osip_list_iterator_t iterator;
1616 
1617 #ifndef OSIP_MONOTHREAD
1618   osip_mutex_lock(osip->nist_fastmutex);
1619 #endif
1620   /* handle nist timers */
1621   tr = (osip_transaction_t *) osip_list_get_first(&osip->osip_nist_transactions, &iterator);
1622 
1623   while (osip_list_iterator_has_elem(iterator)) {
1624     osip_event_t *evt;
1625 
1626     evt = __osip_nist_need_timer_j_event(tr->nist_context, tr->state, tr->transactionid);
1627 
1628     if (evt != NULL)
1629       osip_fifo_add(tr->transactionff, evt);
1630 
1631     tr = (osip_transaction_t *) osip_list_get_next(&iterator);
1632   }
1633 
1634 #ifndef OSIP_MONOTHREAD
1635   osip_mutex_unlock(osip->nist_fastmutex);
1636 #endif
1637 }
1638 
osip_set_cb_send_message(osip_t * cf,int (* cb)(osip_transaction_t *,osip_message_t *,char *,int,int))1639 void osip_set_cb_send_message(osip_t *cf, int (*cb)(osip_transaction_t *, osip_message_t *, char *, int, int)) {
1640   cf->cb_send_message = cb;
1641 }
1642 
__osip_message_callback(int type,osip_transaction_t * tr,osip_message_t * msg)1643 void __osip_message_callback(int type, osip_transaction_t *tr, osip_message_t *msg) {
1644   osip_t *config = tr->config;
1645 
1646   if (type >= OSIP_MESSAGE_CALLBACK_COUNT) {
1647     OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_BUG, NULL, "invalid callback type %d\n", type));
1648     return;
1649   }
1650 
1651   if (config->msg_callbacks[type] == NULL)
1652     return;
1653 
1654   config->msg_callbacks[type](type, tr, msg);
1655 }
1656 
__osip_kill_transaction_callback(int type,osip_transaction_t * tr)1657 void __osip_kill_transaction_callback(int type, osip_transaction_t *tr) {
1658   osip_t *config = tr->config;
1659 
1660   if (type >= OSIP_KILL_CALLBACK_COUNT) {
1661     OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_BUG, NULL, "invalid callback type %d\n", type));
1662     return;
1663   }
1664 
1665   tr->completed_time = osip_getsystemtime(NULL);
1666   osip_gettimeofday(&tr->destroyed_time, NULL);
1667 
1668   if (config->kill_callbacks[type] == NULL)
1669     return;
1670 
1671   config->kill_callbacks[type](type, tr);
1672 }
1673 
__osip_transport_error_callback(int type,osip_transaction_t * tr,int error)1674 void __osip_transport_error_callback(int type, osip_transaction_t *tr, int error) {
1675   osip_t *config = tr->config;
1676 
1677   if (type >= OSIP_TRANSPORT_ERROR_CALLBACK_COUNT) {
1678     OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_BUG, NULL, "invalid callback type %d\n", type));
1679     return;
1680   }
1681 
1682   if (config->tp_error_callbacks[type] == NULL)
1683     return;
1684 
1685   config->tp_error_callbacks[type](type, tr, error);
1686 }
1687 
osip_set_message_callback(osip_t * config,int type,osip_message_cb_t cb)1688 int osip_set_message_callback(osip_t *config, int type, osip_message_cb_t cb) {
1689   if (type >= OSIP_MESSAGE_CALLBACK_COUNT) {
1690     OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "invalid callback type %d\n", type));
1691     return OSIP_BADPARAMETER;
1692   }
1693 
1694   config->msg_callbacks[type] = cb;
1695 
1696   return OSIP_SUCCESS;
1697 }
1698 
osip_set_kill_transaction_callback(osip_t * config,int type,osip_kill_transaction_cb_t cb)1699 int osip_set_kill_transaction_callback(osip_t *config, int type, osip_kill_transaction_cb_t cb) {
1700   if (type >= OSIP_KILL_CALLBACK_COUNT) {
1701     OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "invalid callback type %d\n", type));
1702     return OSIP_BADPARAMETER;
1703   }
1704 
1705   config->kill_callbacks[type] = cb;
1706   return OSIP_SUCCESS;
1707 }
1708 
osip_set_transport_error_callback(osip_t * config,int type,osip_transport_error_cb_t cb)1709 int osip_set_transport_error_callback(osip_t *config, int type, osip_transport_error_cb_t cb) {
1710   if (type >= OSIP_TRANSPORT_ERROR_CALLBACK_COUNT) {
1711     OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "invalid callback type %d\n", type));
1712     return OSIP_BADPARAMETER;
1713   }
1714 
1715   config->tp_error_callbacks[type] = cb;
1716   return OSIP_SUCCESS;
1717 }
1718