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