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(¤t, 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, ¤t);
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