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 extern osip_statemachine_t ict_fsm;
27 extern osip_statemachine_t ist_fsm;
28 extern osip_statemachine_t nict_fsm;
29 extern osip_statemachine_t nist_fsm;
30
31 int osip_id_mutex_lock(osip_t *osip);
32 int osip_id_mutex_unlock(osip_t *osip);
33
34 static int __osip_transaction_set_topvia(osip_transaction_t *transaction, osip_via_t *topvia);
35 static int __osip_transaction_set_from(osip_transaction_t *transaction, osip_from_t *from);
36 static int __osip_transaction_set_to(osip_transaction_t *transaction, osip_to_t *to);
37 static int __osip_transaction_set_call_id(osip_transaction_t *transaction, osip_call_id_t *call_id);
38 static int __osip_transaction_set_cseq(osip_transaction_t *transaction, osip_cseq_t *cseq);
39
__osip_transaction_set_topvia(osip_transaction_t * transaction,osip_via_t * topvia)40 static int __osip_transaction_set_topvia(osip_transaction_t *transaction, osip_via_t *topvia) {
41 int i;
42
43 if (transaction == NULL)
44 return OSIP_BADPARAMETER;
45
46 i = osip_via_clone(topvia, &(transaction->topvia));
47
48 if (i == 0)
49 return OSIP_SUCCESS;
50
51 transaction->topvia = NULL;
52 return i;
53 }
54
__osip_transaction_set_from(osip_transaction_t * transaction,osip_from_t * from)55 static int __osip_transaction_set_from(osip_transaction_t *transaction, osip_from_t *from) {
56 int i;
57
58 if (transaction == NULL)
59 return OSIP_BADPARAMETER;
60
61 i = osip_from_clone(from, &(transaction->from));
62
63 if (i == 0)
64 return OSIP_SUCCESS;
65
66 transaction->from = NULL;
67 return i;
68 }
69
__osip_transaction_set_to(osip_transaction_t * transaction,osip_to_t * to)70 static int __osip_transaction_set_to(osip_transaction_t *transaction, osip_to_t *to) {
71 int i;
72
73 if (transaction == NULL)
74 return OSIP_BADPARAMETER;
75
76 i = osip_to_clone(to, &(transaction->to));
77
78 if (i == 0)
79 return OSIP_SUCCESS;
80
81 transaction->to = NULL;
82 return i;
83 }
84
__osip_transaction_set_call_id(osip_transaction_t * transaction,osip_call_id_t * call_id)85 static int __osip_transaction_set_call_id(osip_transaction_t *transaction, osip_call_id_t *call_id) {
86 int i;
87
88 if (transaction == NULL)
89 return OSIP_BADPARAMETER;
90
91 i = osip_call_id_clone(call_id, &(transaction->callid));
92
93 if (i == 0)
94 return OSIP_SUCCESS;
95
96 transaction->callid = NULL;
97 return i;
98 }
99
__osip_transaction_set_cseq(osip_transaction_t * transaction,osip_cseq_t * cseq)100 static int __osip_transaction_set_cseq(osip_transaction_t *transaction, osip_cseq_t *cseq) {
101 int i;
102
103 if (transaction == NULL)
104 return OSIP_BADPARAMETER;
105
106 i = osip_cseq_clone(cseq, &(transaction->cseq));
107
108 if (i == 0)
109 return OSIP_SUCCESS;
110
111 transaction->cseq = NULL;
112 return i;
113 }
114
osip_transaction_init(osip_transaction_t ** transaction,osip_fsm_type_t ctx_type,osip_t * osip,osip_message_t * request)115 int osip_transaction_init(osip_transaction_t **transaction, osip_fsm_type_t ctx_type, osip_t *osip, osip_message_t *request) {
116 osip_via_t *topvia;
117
118 int i;
119
120 *transaction = NULL;
121
122 if (request == NULL)
123 return OSIP_BADPARAMETER;
124
125 if (request->call_id == NULL)
126 return OSIP_BADPARAMETER;
127
128 if (request->call_id->number == NULL)
129 return OSIP_BADPARAMETER;
130
131 *transaction = (osip_transaction_t *) osip_malloc(sizeof(osip_transaction_t));
132
133 if (*transaction == NULL)
134 return OSIP_NOMEM;
135
136 memset(*transaction, 0, sizeof(osip_transaction_t));
137
138 (*transaction)->birth_time = osip_getsystemtime(NULL);
139 osip_gettimeofday(&((*transaction)->created_time), NULL);
140 osip_id_mutex_lock(osip);
141 (*transaction)->transactionid = osip->transactionid++;
142 osip_id_mutex_unlock(osip);
143 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO2, NULL, "allocating transaction resource %i %s\n", (*transaction)->transactionid, request->call_id->number));
144
145 /* those lines must be called before "osip_transaction_free" */
146 (*transaction)->ctx_type = ctx_type;
147 (*transaction)->ict_context = NULL;
148 (*transaction)->ist_context = NULL;
149 (*transaction)->nict_context = NULL;
150 (*transaction)->nist_context = NULL;
151 (*transaction)->config = osip;
152
153 topvia = osip_list_get(&request->vias, 0);
154
155 if (topvia == NULL) {
156 osip_transaction_free(*transaction);
157 *transaction = NULL;
158 return OSIP_SYNTAXERROR;
159 }
160
161 i = __osip_transaction_set_topvia(*transaction, topvia);
162
163 if (i != 0) {
164 osip_transaction_free(*transaction);
165 *transaction = NULL;
166 return i;
167 }
168
169 /* In some situation, some of those informtions might
170 be useless. Mostly, I prefer to keep them in all case
171 for backward compatibility. */
172 i = __osip_transaction_set_from(*transaction, request->from);
173
174 if (i != 0) {
175 osip_transaction_free(*transaction);
176 *transaction = NULL;
177 return i;
178 }
179
180 i = __osip_transaction_set_to(*transaction, request->to);
181
182 if (i != 0) {
183 osip_transaction_free(*transaction);
184 *transaction = NULL;
185 return i;
186 }
187
188 i = __osip_transaction_set_call_id(*transaction, request->call_id);
189
190 if (i != 0) {
191 osip_transaction_free(*transaction);
192 *transaction = NULL;
193 return i;
194 }
195
196 i = __osip_transaction_set_cseq(*transaction, request->cseq);
197
198 if (i != 0) {
199 osip_transaction_free(*transaction);
200 *transaction = NULL;
201 return i;
202 }
203
204 /* RACE conditions can happen for server transactions */
205 /* (*transaction)->orig_request = request; */
206 (*transaction)->orig_request = NULL;
207
208 (*transaction)->transactionff = (osip_fifo_t *) osip_malloc(sizeof(osip_fifo_t));
209
210 if ((*transaction)->transactionff == NULL) {
211 osip_transaction_free(*transaction);
212 *transaction = NULL;
213 return OSIP_NOMEM;
214 }
215
216 osip_fifo_init((*transaction)->transactionff);
217
218 if (ctx_type == ICT) {
219 (*transaction)->state = ICT_PRE_CALLING;
220 i = __osip_ict_init(&((*transaction)->ict_context), osip, request);
221
222 if (i != 0) {
223 osip_transaction_free(*transaction);
224 *transaction = NULL;
225 return i;
226 }
227
228 __osip_add_ict(osip, *transaction);
229
230 } else if (ctx_type == IST) {
231 (*transaction)->state = IST_PRE_PROCEEDING;
232 i = __osip_ist_init(&((*transaction)->ist_context), osip, request);
233
234 if (i != 0) {
235 osip_transaction_free(*transaction);
236 *transaction = NULL;
237 return i;
238 }
239
240 __osip_add_ist(osip, *transaction);
241
242 } else if (ctx_type == NICT) {
243 (*transaction)->state = NICT_PRE_TRYING;
244 i = __osip_nict_init(&((*transaction)->nict_context), osip, request);
245
246 if (i != 0) {
247 osip_transaction_free(*transaction);
248 *transaction = NULL;
249 return i;
250 }
251
252 __osip_add_nict(osip, *transaction);
253
254 } else {
255 (*transaction)->state = NIST_PRE_TRYING;
256 i = __osip_nist_init(&((*transaction)->nist_context), osip, request);
257
258 if (i != 0) {
259 osip_transaction_free(*transaction);
260 *transaction = NULL;
261 return i;
262 }
263
264 __osip_add_nist(osip, *transaction);
265 }
266
267 return OSIP_SUCCESS;
268 }
269
270 /* This method automaticly remove the transaction context from
271 the osip stack. This task is required for proper operation
272 when a transaction goes in the TERMINATED STATE.
273 However the user might want to just take the context out of
274 the SIP stack andf keep it for future use without freeing
275 all resource.... This way the transaction context can be
276 kept without being used by the oSIP stack.
277
278 new methods that replace this one:
279 osip_remove_transaction
280 +
281 osip_transaction_free2();
282
283 */
osip_transaction_free(osip_transaction_t * transaction)284 int osip_transaction_free(osip_transaction_t *transaction) {
285 int i;
286
287 if (transaction == NULL)
288 return OSIP_BADPARAMETER;
289
290 i = osip_remove_transaction(transaction->config, transaction);
291
292 if (i != 0) { /* yet removed ??? */
293 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO4, NULL, "transaction already removed from list %i!\n", transaction->transactionid));
294 }
295
296 return osip_transaction_free2(transaction);
297 }
298
299 /* same as osip_transaction_free() but assume the transaction is
300 already removed from the list of transaction in the osip stack */
osip_transaction_free2(osip_transaction_t * transaction)301 int osip_transaction_free2(osip_transaction_t *transaction) {
302 osip_event_t *evt;
303
304 if (transaction == NULL)
305 return OSIP_BADPARAMETER;
306
307 if (transaction->orig_request != NULL && transaction->orig_request->call_id != NULL && transaction->orig_request->call_id->number != NULL) {
308 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO2, NULL, "free transaction resource %i %s\n", transaction->transactionid, transaction->orig_request->call_id->number));
309 }
310
311 if (transaction->ctx_type == ICT) {
312 __osip_ict_free(transaction->ict_context);
313
314 } else if (transaction->ctx_type == IST) {
315 __osip_ist_free(transaction->ist_context);
316
317 } else if (transaction->ctx_type == NICT) {
318 __osip_nict_free(transaction->nict_context);
319
320 } else {
321 __osip_nist_free(transaction->nist_context);
322 }
323
324 /* empty the fifo */
325 if (transaction->transactionff != NULL) {
326 evt = osip_fifo_tryget(transaction->transactionff);
327
328 while (evt != NULL) {
329 osip_message_free(evt->sip);
330 osip_free(evt);
331 evt = osip_fifo_tryget(transaction->transactionff);
332 }
333
334 osip_fifo_free(transaction->transactionff);
335 }
336
337 osip_message_free(transaction->orig_request);
338 osip_message_free(transaction->last_response);
339 osip_message_free(transaction->ack);
340
341 osip_via_free(transaction->topvia);
342 osip_from_free(transaction->from);
343 osip_to_free(transaction->to);
344 osip_call_id_free(transaction->callid);
345 osip_cseq_free(transaction->cseq);
346
347 osip_free(transaction);
348 return OSIP_SUCCESS;
349 }
350
osip_transaction_add_event(osip_transaction_t * transaction,osip_event_t * evt)351 int osip_transaction_add_event(osip_transaction_t *transaction, osip_event_t *evt) {
352 if (evt == NULL)
353 return OSIP_BADPARAMETER;
354
355 if (transaction == NULL)
356 return OSIP_BADPARAMETER;
357
358 evt->transactionid = transaction->transactionid;
359 osip_fifo_add(transaction->transactionff, evt);
360 return OSIP_SUCCESS;
361 }
362
osip_transaction_execute(osip_transaction_t * transaction,osip_event_t * evt)363 int osip_transaction_execute(osip_transaction_t *transaction, osip_event_t *evt) {
364 osip_statemachine_t *statemachine;
365
366 /* to kill the process, simply send this type of event. */
367 if (EVT_IS_KILL_TRANSACTION(evt)) {
368 /* MAJOR CHANGE!
369 TRANSACTION MUST NOW BE RELEASED BY END-USER:
370 So Any usefull data can be save and re-used */
371 /* osip_transaction_free(transaction);
372 osip_free(transaction); */
373 osip_free(evt);
374 return OSIP_SUCCESS;
375 }
376
377 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO4, NULL, "sipevent tr->transactionid: %i\n", transaction->transactionid));
378 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO4, NULL, "sipevent tr->state: %i\n", transaction->state));
379 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO4, NULL, "sipevent evt->type: %i\n", evt->type));
380 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO4, NULL, "sipevent evt->sip: %x\n", evt->sip));
381
382 if (transaction->ctx_type == ICT)
383 statemachine = &ict_fsm;
384
385 else if (transaction->ctx_type == IST)
386 statemachine = &ist_fsm;
387
388 else if (transaction->ctx_type == NICT)
389 statemachine = &nict_fsm;
390
391 else
392 statemachine = &nist_fsm;
393
394 if (0 != fsm_callmethod(evt->type, transaction->state, statemachine, evt, transaction)) {
395 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "USELESS event!\n"));
396
397 /* message is useless. */
398 if (EVT_IS_MSG(evt)) {
399 if (evt->sip != NULL) {
400 osip_message_free(evt->sip);
401 }
402 }
403
404 } else {
405 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO4, NULL, "sipevent evt: method called!\n"));
406 }
407
408 osip_free(evt); /* this is the ONLY place for freeing event!! */
409 return 1;
410 }
411
osip_transaction_get_destination(osip_transaction_t * transaction,char ** ip,int * port)412 int osip_transaction_get_destination(osip_transaction_t *transaction, char **ip, int *port) {
413 *ip = NULL;
414 *port = 0;
415
416 if (transaction == NULL)
417 return OSIP_BADPARAMETER;
418
419 if (transaction->ict_context != NULL) {
420 *ip = transaction->ict_context->destination;
421 *port = transaction->ict_context->port;
422 return OSIP_SUCCESS;
423
424 } else if (transaction->nict_context != NULL) {
425 *ip = transaction->nict_context->destination;
426 *port = transaction->nict_context->port;
427 return OSIP_SUCCESS;
428 }
429
430 return OSIP_UNDEFINED_ERROR;
431 }
432
osip_transaction_set_srv_record(osip_transaction_t * transaction,osip_srv_record_t * record)433 int osip_transaction_set_srv_record(osip_transaction_t *transaction, osip_srv_record_t *record) {
434 if (transaction == NULL)
435 return OSIP_BADPARAMETER;
436
437 memcpy(&transaction->record, record, sizeof(osip_srv_record_t));
438 return OSIP_SUCCESS;
439 }
440
osip_transaction_set_naptr_record(osip_transaction_t * transaction,osip_naptr_t * record)441 int osip_transaction_set_naptr_record(osip_transaction_t *transaction, osip_naptr_t *record) {
442 if (transaction == NULL)
443 return OSIP_BADPARAMETER;
444
445 transaction->naptr_record = record;
446 return OSIP_SUCCESS;
447 }
448
osip_transaction_set_your_instance(osip_transaction_t * transaction,void * ptr)449 int osip_transaction_set_your_instance(osip_transaction_t *transaction, void *ptr) {
450 if (transaction == NULL)
451 return OSIP_BADPARAMETER;
452
453 transaction->reserved1 = ptr;
454 return OSIP_SUCCESS;
455 }
456
osip_transaction_set_reserved1(osip_transaction_t * transaction,void * ptr)457 int osip_transaction_set_reserved1(osip_transaction_t *transaction, void *ptr) {
458 if (transaction == NULL)
459 return OSIP_BADPARAMETER;
460
461 transaction->reserved1 = ptr;
462 return OSIP_SUCCESS;
463 }
464
osip_transaction_set_reserved2(osip_transaction_t * transaction,void * ptr)465 int osip_transaction_set_reserved2(osip_transaction_t *transaction, void *ptr) {
466 if (transaction == NULL)
467 return OSIP_BADPARAMETER;
468
469 transaction->reserved2 = ptr;
470 return OSIP_SUCCESS;
471 }
472
osip_transaction_set_reserved3(osip_transaction_t * transaction,void * ptr)473 int osip_transaction_set_reserved3(osip_transaction_t *transaction, void *ptr) {
474 if (transaction == NULL)
475 return OSIP_BADPARAMETER;
476
477 transaction->reserved3 = ptr;
478 return OSIP_SUCCESS;
479 }
480
osip_transaction_set_reserved4(osip_transaction_t * transaction,void * ptr)481 int osip_transaction_set_reserved4(osip_transaction_t *transaction, void *ptr) {
482 if (transaction == NULL)
483 return OSIP_BADPARAMETER;
484
485 transaction->reserved4 = ptr;
486 return OSIP_SUCCESS;
487 }
488
osip_transaction_set_reserved5(osip_transaction_t * transaction,void * ptr)489 int osip_transaction_set_reserved5(osip_transaction_t *transaction, void *ptr) {
490 if (transaction == NULL)
491 return OSIP_BADPARAMETER;
492
493 transaction->reserved5 = ptr;
494 return OSIP_SUCCESS;
495 }
496
osip_transaction_set_reserved6(osip_transaction_t * transaction,void * ptr)497 int osip_transaction_set_reserved6(osip_transaction_t *transaction, void *ptr) {
498 if (transaction == NULL)
499 return OSIP_BADPARAMETER;
500
501 transaction->reserved6 = ptr;
502 return OSIP_SUCCESS;
503 }
504
osip_transaction_get_your_instance(osip_transaction_t * transaction)505 void *osip_transaction_get_your_instance(osip_transaction_t *transaction) {
506 if (transaction == NULL)
507 return NULL;
508
509 return transaction->reserved1;
510 }
511
osip_transaction_get_reserved1(osip_transaction_t * transaction)512 void *osip_transaction_get_reserved1(osip_transaction_t *transaction) {
513 if (transaction == NULL)
514 return NULL;
515
516 return transaction->reserved1;
517 }
518
osip_transaction_get_reserved2(osip_transaction_t * transaction)519 void *osip_transaction_get_reserved2(osip_transaction_t *transaction) {
520 if (transaction == NULL)
521 return NULL;
522
523 return transaction->reserved2;
524 }
525
osip_transaction_get_reserved3(osip_transaction_t * transaction)526 void *osip_transaction_get_reserved3(osip_transaction_t *transaction) {
527 if (transaction == NULL)
528 return NULL;
529
530 return transaction->reserved3;
531 }
532
osip_transaction_get_reserved4(osip_transaction_t * transaction)533 void *osip_transaction_get_reserved4(osip_transaction_t *transaction) {
534 if (transaction == NULL)
535 return NULL;
536
537 return transaction->reserved4;
538 }
539
osip_transaction_get_reserved5(osip_transaction_t * transaction)540 void *osip_transaction_get_reserved5(osip_transaction_t *transaction) {
541 if (transaction == NULL)
542 return NULL;
543
544 return transaction->reserved5;
545 }
546
osip_transaction_get_reserved6(osip_transaction_t * transaction)547 void *osip_transaction_get_reserved6(osip_transaction_t *transaction) {
548 if (transaction == NULL)
549 return NULL;
550
551 return transaction->reserved6;
552 }
553
__osip_transaction_set_state(osip_transaction_t * transaction,state_t state)554 int __osip_transaction_set_state(osip_transaction_t *transaction, state_t state) {
555 if (transaction == NULL)
556 return OSIP_BADPARAMETER;
557
558 transaction->state = state;
559 return OSIP_SUCCESS;
560 }
561
osip_transaction_set_in_socket(osip_transaction_t * transaction,int sock)562 int osip_transaction_set_in_socket(osip_transaction_t *transaction, int sock) {
563 if (transaction == NULL)
564 return OSIP_BADPARAMETER;
565
566 transaction->in_socket = sock;
567 return OSIP_SUCCESS;
568 }
569
osip_transaction_set_out_socket(osip_transaction_t * transaction,int sock)570 int osip_transaction_set_out_socket(osip_transaction_t *transaction, int sock) {
571 if (transaction == NULL)
572 return OSIP_BADPARAMETER;
573
574 transaction->out_socket = sock;
575 return OSIP_SUCCESS;
576 }
577
__osip_transaction_matching_response_osip_to_xict_17_1_3(osip_transaction_t * tr,osip_message_t * response)578 int __osip_transaction_matching_response_osip_to_xict_17_1_3(osip_transaction_t *tr, osip_message_t *response) {
579 osip_generic_param_t *b_request;
580 osip_generic_param_t *b_response;
581 osip_via_t *topvia_response;
582
583 /* some checks to avoid crashing on bad requests */
584 if (tr == NULL || (tr->ict_context == NULL && tr->nict_context == NULL) ||
585 /* only ict and nict can match a response */
586 response == NULL || response->cseq == NULL || response->cseq->method == NULL)
587 return OSIP_BADPARAMETER;
588
589 topvia_response = osip_list_get(&response->vias, 0);
590
591 if (topvia_response == NULL) {
592 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "Remote UA is not compliant: missing a Via header!\n"));
593 return OSIP_SYNTAXERROR;
594 }
595
596 osip_via_param_get_byname(tr->topvia, "branch", &b_request);
597
598 if (b_request == NULL) {
599 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_BUG, NULL, "You created a transaction without any branch! THIS IS NOT ALLOWED\n"));
600 return OSIP_SYNTAXERROR;
601 }
602
603 osip_via_param_get_byname(topvia_response, "branch", &b_response);
604
605 if (b_response == NULL) {
606 #ifdef FWDSUPPORT
607
608 /* the from tag (unique) */
609 if (from_tag_match(tr->from, response->from) != 0)
610 return OSIP_UNDEFINED_ERROR;
611
612 /* the Cseq field */
613 if (cseq_match(tr->cseq, response->cseq) != 0)
614 return OSIP_UNDEFINED_ERROR;
615
616 /* the To field */
617 if (response->to->url->username == NULL && tr->from->url->username != NULL)
618 return OSIP_UNDEFINED_ERROR;
619
620 if (response->to->url->username != NULL && tr->from->url->username == NULL)
621 return OSIP_UNDEFINED_ERROR;
622
623 if (response->to->url->username != NULL && tr->from->url->username != NULL) {
624 if (strcmp(response->to->url->host, tr->from->url->host) || strcmp(response->to->url->username, tr->from->url->username))
625 return OSIP_UNDEFINED_ERROR;
626
627 } else {
628 if (strcmp(response->to->url->host, tr->from->url->host))
629 return OSIP_UNDEFINED_ERROR;
630 }
631
632 /* the Call-ID field */
633 if (call_id_match(tr->callid, response->call_id) != 0)
634 return OSIP_UNDEFINED_ERROR;
635
636 return OSIP_SUCCESS;
637 #else
638 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_BUG, NULL, "Remote UA is not compliant: missing a branch parameter in Via header!\n"));
639 return OSIP_SYNTAXERROR;
640 #endif
641 }
642
643 if ((b_request->gvalue == NULL) || (b_response->gvalue == NULL)) {
644 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_BUG, NULL, "Remote UA is not compliant: missing a branch parameter in Via header!\n"));
645 return OSIP_SYNTAXERROR;
646 }
647
648 /*
649 A response matches a client transaction under two
650 conditions:
651
652 1. If the response has the same value of the branch parameter
653 in the top Via header field as the branch parameter in the
654 top Via header field of the request that created the
655 transaction.
656 */
657 if (0 != strcmp(b_request->gvalue, b_response->gvalue))
658 return OSIP_UNDEFINED_ERROR;
659
660 /*
661 2. If the method parameter in the CSeq header field matches
662 the method of the request that created the transaction. The
663 method is needed since a CANCEL request constitutes a
664 different transaction, but shares the same value of the
665 branch parameter.
666 AMD NOTE: cseq->method is ALWAYS the same than the METHOD of the request.
667 */
668 if (0 == strcmp(response->cseq->method, tr->cseq->method)) /* general case */
669 return OSIP_SUCCESS;
670
671 return OSIP_UNDEFINED_ERROR;
672 }
673
__osip_transaction_matching_request_osip_to_xist_17_2_3(osip_transaction_t * tr,osip_message_t * request)674 int __osip_transaction_matching_request_osip_to_xist_17_2_3(osip_transaction_t *tr, osip_message_t *request) {
675 osip_generic_param_t *b_origrequest;
676 osip_generic_param_t *b_request;
677 osip_via_t *topvia_request;
678 size_t length_br;
679 size_t length_br2;
680
681 /* some checks to avoid crashing on bad requests */
682 if (tr == NULL || (tr->ist_context == NULL && tr->nist_context == NULL) ||
683 /* only ist and nist can match a request */
684 request == NULL || request->cseq == NULL || request->cseq->method == NULL)
685 return OSIP_BADPARAMETER;
686
687 topvia_request = osip_list_get(&request->vias, 0);
688
689 if (topvia_request == NULL) {
690 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "Remote UA is not compliant: missing a Via header!\n"));
691 return OSIP_SYNTAXERROR;
692 }
693
694 osip_via_param_get_byname(topvia_request, "branch", &b_request);
695 osip_via_param_get_byname(tr->topvia, "branch", &b_origrequest);
696
697 if ((b_origrequest == NULL && b_request != NULL) || (b_origrequest != NULL && b_request == NULL))
698 return OSIP_SYNTAXERROR; /* one request is compliant, the other one is not... */
699
700 /* Section 17.2.3 Matching Requests to Server Transactions:
701 "The branch parameter in the topmost Via header field of the request
702 is examined. If it is present and begins with the magic cookie
703 "z9hG4bK", the request was generated by a client transaction
704 compliant to this specification."
705 */
706
707 if (b_origrequest != NULL && b_request != NULL)
708 /* case where both request contains a branch */
709 {
710 if (!b_origrequest->gvalue)
711 return OSIP_UNDEFINED_ERROR;
712
713 if (!b_request->gvalue)
714 return OSIP_UNDEFINED_ERROR;
715
716 length_br = strlen(b_origrequest->gvalue);
717 length_br2 = strlen(b_request->gvalue);
718
719 if (length_br != length_br2)
720 return OSIP_UNDEFINED_ERROR;
721
722 /* can't be the same */
723 if (0 == strncmp(b_origrequest->gvalue, "z9hG4bK", 7) && 0 == strncmp(b_request->gvalue, "z9hG4bK", 7)) {
724 /* both request comes from a compliant UA */
725 /* The request matches a transaction if the branch parameter
726 in the request is equal to the one in the top Via header
727 field of the request that created the transaction, the
728 sent-by value in the top Via of the request is equal to
729 the one in the request that created the transaction, and in
730 the case of a CANCEL request, the method of the request
731 that created the transaction was also CANCEL.
732 */
733 if (0 != strcmp(b_origrequest->gvalue, b_request->gvalue))
734 return OSIP_UNDEFINED_ERROR; /* branch param does not match */
735
736 {
737 /* check the sent-by values */
738 char *b_port = via_get_port(topvia_request);
739 char *b_origport = via_get_port(tr->topvia);
740 char *b_host = via_get_host(topvia_request);
741 char *b_orighost = via_get_host(tr->topvia);
742
743 if ((b_host == NULL || b_orighost == NULL))
744 return OSIP_UNDEFINED_ERROR;
745
746 if (0 != strcmp(b_orighost, b_host))
747 return OSIP_UNDEFINED_ERROR;
748
749 if (b_port != NULL && b_origport == NULL && 0 != strcmp(b_port, "5060"))
750 return OSIP_UNDEFINED_ERROR;
751
752 else if (b_origport != NULL && b_port == NULL && 0 != strcmp(b_origport, "5060"))
753 return OSIP_UNDEFINED_ERROR;
754
755 else if (b_origport != NULL && b_port != NULL && 0 != strcmp(b_origport, b_port))
756 return OSIP_UNDEFINED_ERROR;
757 }
758 #ifdef AC_BUG
759
760 /* audiocodes bug (MP108-fxs-SIP-4-0-282-380) */
761 if (0 != osip_from_tag_match(tr->from, request->from))
762 return OSIP_UNDEFINED_ERROR;
763
764 #endif
765
766 if (/* MSG_IS_CANCEL(request)&& <<-- BUG from the spec?
767 I always check the CSeq */
768 (!(0 == strcmp(tr->cseq->method, "INVITE") && 0 == strcmp(request->cseq->method, "ACK"))) && 0 != strcmp(tr->cseq->method, request->cseq->method))
769 return OSIP_UNDEFINED_ERROR;
770
771 return OSIP_SUCCESS;
772 }
773 }
774
775 /* Back to the old backward compatibilty mechanism for matching requests */
776 if (0 != osip_call_id_match(tr->callid, request->call_id))
777 return OSIP_UNDEFINED_ERROR;
778
779 if (MSG_IS_ACK(request)) {
780 osip_generic_param_t *tag_from1;
781 osip_generic_param_t *tag_from2;
782
783 osip_from_param_get_byname(tr->to, "tag", &tag_from1);
784 osip_from_param_get_byname(request->to, "tag", &tag_from2);
785
786 if (tag_from1 == NULL && tag_from2 != NULL) {
787 /* do not check it as it can be a new tag when the final
788 answer has a tag while an INVITE doesn't have one */
789 } else if (tag_from1 != NULL && tag_from2 == NULL) {
790 return OSIP_UNDEFINED_ERROR;
791
792 } else {
793 if (0 != osip_to_tag_match(tr->to, request->to))
794 return OSIP_UNDEFINED_ERROR;
795 }
796
797 } else {
798 if (tr->orig_request == NULL || tr->orig_request->to == NULL)
799 return OSIP_UNDEFINED_ERROR;
800
801 if (0 != osip_to_tag_match(tr->orig_request->to, request->to))
802 return OSIP_UNDEFINED_ERROR;
803 }
804
805 if (0 != osip_from_tag_match(tr->from, request->from))
806 return OSIP_UNDEFINED_ERROR;
807
808 if (0 != osip_cseq_match(tr->cseq, request->cseq))
809 return OSIP_UNDEFINED_ERROR;
810
811 if (0 != osip_via_match(tr->topvia, topvia_request))
812 return OSIP_UNDEFINED_ERROR;
813
814 return OSIP_SUCCESS;
815 }
816
__osip_transaction_need_timer_x_event(void * xixt,struct timeval * timer,int cond_state,int transactionid,int TIMER_VAL)817 osip_event_t *__osip_transaction_need_timer_x_event(void *xixt, struct timeval *timer, int cond_state, int transactionid, int TIMER_VAL) {
818 struct timeval now;
819
820 osip_gettimeofday(&now, NULL);
821
822 if (xixt == NULL)
823 return NULL;
824
825 if (cond_state) {
826 if (timer->tv_sec == -1)
827 return NULL;
828
829 if (osip_timercmp(&now, timer, >=))
830 return __osip_event_new(TIMER_VAL, transactionid);
831 }
832
833 return NULL;
834 }
835
__osip_transaction_snd_xxx(osip_transaction_t * ist,osip_message_t * msg)836 int __osip_transaction_snd_xxx(osip_transaction_t *ist, osip_message_t *msg) {
837 osip_t *osip = (osip_t *) ist->config;
838 osip_via_t *via;
839 char *host;
840 int port;
841 osip_generic_param_t *maddr;
842 osip_generic_param_t *received;
843 osip_generic_param_t *rport;
844
845 via = (osip_via_t *) osip_list_get(&msg->vias, 0);
846
847 if (!via)
848 return OSIP_SYNTAXERROR;
849
850 osip_via_param_get_byname(via, "maddr", &maddr);
851 osip_via_param_get_byname(via, "received", &received);
852 osip_via_param_get_byname(via, "rport", &rport);
853
854 /* 1: user should not use the provided information
855 (host and port) if they are using a reliable
856 transport. Instead, they should use the already
857 open socket attached to this transaction. */
858 /* 2: check maddr and multicast usage */
859 if (maddr != NULL)
860 host = maddr->gvalue;
861
862 /* we should check if this is a multicast address and use
863 set the "ttl" in this case. (this must be done in the
864 UDP message (not at the SIP layer) */
865 else if (received != NULL)
866 host = received->gvalue;
867
868 else
869 host = via->host;
870
871 if (rport == NULL || rport->gvalue == NULL) {
872 if (via->port != NULL)
873 port = osip_atoi(via->port);
874
875 else
876 port = 5060;
877
878 } else
879 port = osip_atoi(rport->gvalue);
880
881 return osip->cb_send_message(ist, msg, host, port, ist->out_socket);
882 }
883