1 /*
2  *  This program is free software; you can redistribute it and/or modify
3  *  it under the terms of the GNU General Public License as published by
4  *  the Free Software Foundation; either version 2 of the License, or
5  *  (at your option) any later version.
6  *
7  *  This program is distributed in the hope that it will be useful,
8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *  GNU General Public License for more details.
11  *
12  *  You should have received a copy of the GNU General Public License
13  *  along with this program; if not, write to the Free Software
14  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  *
16  *  Author : Richard GAYRAUD - 04 Nov 2003
17  *           Olivier Jacques
18  *           From Hewlett Packard Company.
19  *           Shriram Natarajan
20  *           Peter Higginson
21  *           Eric Miller
22  *           Venkatesh
23  *           Enrico Hartung
24  *           Nasir Khan
25  *           Lee Ballard
26  *           Guillaume Teissier from FTR&D
27  *           Wolfgang Beck
28  *           Venkatesh
29  *           Vlad Troyanker
30  *           Charles P Wright from IBM Research
31  *           Amit On from Followap
32  *           Jan Andres from Freenet
33  *           Ben Evans from Open Cloud
34  *           Marc Van Diest from Belgacom
35  *           Michael Dwyer from Cibation
36  *           Roland Meub
37  *           Andy Aicken
38  *           Martin H. VanLeeuwen
39  */
40 
41 #include <iterator>
42 #include <algorithm>
43 #include <fstream>
44 #include <iostream>
45 #include <cstring>
46 #include <sys/types.h>
47 #include <sys/wait.h>
48 #include <assert.h>
49 
50 #ifdef PCAPPLAY
51 #include "send_packets.h"
52 #endif
53 #include "sipp.hpp"
54 #include "auth.hpp"
55 #include "deadcall.hpp"
56 #include "config.h"
57 #include "version.h"
58 
59 #define callDebug(...) do { if (useCallDebugf) { _callDebug( __VA_ARGS__ ); } } while (0)
60 
61 extern  map<string, struct sipp_socket *>     map_perip_fd;
62 
63 #ifdef PCAPPLAY
64 /* send_packets pthread wrapper */
65 void *send_wrapper(void *);
66 #endif
67 int call::dynamicId       = 0;
68 int call::maxDynamicId    = 10000+2000*4;      // FIXME both param to be in command line !!!!
69 int call::startDynamicId  = 10000;             // FIXME both param to be in command line !!!!
70 int call::stepDynamicId   = 4;                // FIXME both param to be in command line !!!!
71 
72 /************** Call map and management routines **************/
73 static unsigned int next_number = 1;
74 
get_tdm_map_number()75 static unsigned int get_tdm_map_number()
76 {
77     unsigned int nb = 0;
78     unsigned int i=0;
79     unsigned int interval=0;
80     unsigned int random=0;
81     bool found = false;
82 
83     /* Find a number in the tdm_map which is not in use */
84     interval = (tdm_map_a+1) * (tdm_map_b+1) * (tdm_map_c+1);
85     random = rand() % interval;
86     while ((i<interval) && (!found)) {
87         if (tdm_map[(random + i - 1) % interval] == false) {
88             nb = (random + i - 1) % interval;
89             found = true;
90         }
91         i++;
92     }
93 
94     if (!found) {
95         return 0;
96     } else {
97         return nb+1;
98     }
99 }
100 
101 /* When should this call wake up? */
wake()102 unsigned int call::wake()
103 {
104     unsigned int wake = 0;
105 
106     if (zombie) {
107         return wake;
108     }
109 
110     if (paused_until) {
111         wake = paused_until;
112     }
113 
114     if (next_retrans && (!wake || (next_retrans < wake))) {
115         wake = next_retrans;
116     }
117 
118     if (recv_timeout && (!wake || (recv_timeout < wake))) {
119         wake = recv_timeout;
120     }
121 
122     return wake;
123 }
124 
125 #ifdef PCAPPLAY
find_sdp_eol(char * line)126 static char* find_sdp_eol(char* line)
127 {
128     char* end = &line[strcspn(line, "\r\n")];
129     return end[0] == '\0' ? NULL : end;
130 }
131 
132 /******* Media information management *************************/
133 /*
134  * Look for "c=IN IP4 " pattern in the message and extract the following value
135  * which should be IP address
136  */
get_remote_ip_media(char * msg)137 uint32_t get_remote_ip_media(char *msg)
138 {
139     char pattern[] = "c=IN IP4 ";
140     char *begin, *end;
141     char ip[32];
142     char *my_msg = strdup(msg);
143 
144     if (!my_msg) {
145         return INADDR_NONE;
146     }
147     begin = strstr(my_msg, pattern);
148     if (!begin) {
149         free(my_msg);
150         /* Can't find what we're looking at -> return no address */
151         return INADDR_NONE;
152     }
153     begin += sizeof(pattern) - 1;
154     end = find_sdp_eol(begin);
155     if (!end) {
156         free(my_msg);
157         return INADDR_NONE;
158     }
159     *end = '\0';
160     memset(ip, 0, 32);
161     strncpy(ip, begin, sizeof(ip) - 1);
162     ip[sizeof(ip) - 1] = '\0';
163     free(my_msg);
164     return inet_addr(ip);
165 }
166 
167 /*
168  * Look for "c=IN IP6 " pattern in the message and extract the following value
169  * which should be IPv6 address
170  */
get_remote_ipv6_media(char * msg,struct in6_addr * addr)171 uint8_t get_remote_ipv6_media(char *msg, struct in6_addr *addr)
172 {
173     char pattern[] = "c=IN IP6 ";
174     char *begin, *end;
175     char ip[128];
176     char *my_msg = strdup(msg);
177 
178     memset(addr, 0, sizeof(*addr));
179     memset(ip, 0, 128);
180 
181     if (!my_msg) {
182         return 0;
183     }
184     begin = strstr(my_msg,pattern);
185     if (!begin) {
186         free(my_msg);
187         /* Can't find what we're looking at -> return no address */
188         return 0;
189     }
190     begin += sizeof(pattern) - 1;
191     end = find_sdp_eol(begin);
192     if (!end) {
193         free(my_msg);
194         return 0;
195     }
196     *end = '\0';
197     strncpy(ip, begin, sizeof(ip) -1);
198     ip[sizeof(ip) - 1] = '\0';
199     free(my_msg);
200     if (!inet_pton(AF_INET6, ip, addr)) {
201         return 0;
202     }
203     return 1;
204 }
205 
206 /*
207  * Look for "m=audio ", "m=image " or "m=video " pattern in the message
208  * and extract the following value which should be port number.
209  */
210 enum media_ptn {
211     PAT_AUDIO,
212     PAT_IMAGE,
213     PAT_VIDEO
214 };
get_remote_port_media(const char * msg,enum media_ptn pattype)215 uint16_t get_remote_port_media(const char *msg, enum media_ptn pattype)
216 {
217     const char *pattern;
218     char *begin, *end;
219     char number[6];
220 
221     if (pattype == PAT_AUDIO) {
222         pattern = "m=audio ";
223     } else if (pattype == PAT_IMAGE) {
224         pattern = "m=image ";
225     } else if (pattype == PAT_VIDEO) {
226         pattern = "m=video ";
227     } else {
228         ERROR("Internal error: Undefined media pattern %d\n", 3);
229     }
230 
231     char *my_msg = strdup(msg);
232     if (!my_msg) {
233         return 0;
234     }
235     begin = strstr(my_msg, pattern);
236     if (!begin) {
237         free(my_msg);
238         /* m=audio not found */
239         return 0;
240     }
241     begin += strlen(pattern);
242     end = find_sdp_eol(begin);
243     if (!end) {
244         free(my_msg);
245         ERROR("get_remote_port_media: no CRLF found");
246         return 0;
247     }
248     *end = '\0';
249     memset(number, 0, sizeof(number));
250     strncpy(number, begin, sizeof(number) - 1);
251     number[sizeof(number) - 1] = '\0';
252     free(my_msg);
253     return atoi(number);
254 }
255 
256 /*
257  * IPv{4,6} compliant
258  */
get_remote_media_addr(char * msg)259 void call::get_remote_media_addr(char *msg)
260 {
261     uint16_t audio_port, image_port, video_port;
262     if (media_ip_is_ipv6) {
263         struct in6_addr ip_media;
264         if (get_remote_ipv6_media(msg, &ip_media)) {
265             audio_port = get_remote_port_media(msg, PAT_AUDIO);
266             if (audio_port) {
267                 /* We have audio in the SDP: set the to_audio addr */
268                 (_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_flowinfo = 0;
269                 (_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_scope_id = 0;
270                 (_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_family = AF_INET6;
271                 (_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_port = htons(audio_port);
272                 (_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_addr = ip_media;
273             }
274             image_port = get_remote_port_media(msg, PAT_IMAGE);
275             if (image_port) {
276                 /* We have image in the SDP: set the to_image addr */
277                 (_RCAST(struct sockaddr_in6 *, &(play_args_i.to)))->sin6_flowinfo = 0;
278                 (_RCAST(struct sockaddr_in6 *, &(play_args_i.to)))->sin6_scope_id = 0;
279                 (_RCAST(struct sockaddr_in6 *, &(play_args_i.to)))->sin6_family = AF_INET6;
280                 (_RCAST(struct sockaddr_in6 *, &(play_args_i.to)))->sin6_port = htons(image_port);
281                 (_RCAST(struct sockaddr_in6 *, &(play_args_i.to)))->sin6_addr = ip_media;
282             }
283             video_port = get_remote_port_media(msg, PAT_VIDEO);
284             if (video_port) {
285                 /* We have video in the SDP: set the to_video addr */
286                 (_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_flowinfo = 0;
287                 (_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_scope_id = 0;
288                 (_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_family = AF_INET6;
289                 (_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_port = htons(video_port);
290                 (_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_addr = ip_media;
291             }
292             hasMediaInformation = 1;
293         }
294     } else {
295         uint32_t ip_media;
296         ip_media = get_remote_ip_media(msg);
297         if (ip_media != INADDR_NONE) {
298             audio_port = get_remote_port_media(msg, PAT_AUDIO);
299             if (audio_port) {
300                 /* We have audio in the SDP: set the to_audio addr */
301                 (_RCAST(struct sockaddr_in *, &(play_args_a.to)))->sin_family = AF_INET;
302                 (_RCAST(struct sockaddr_in *, &(play_args_a.to)))->sin_port = htons(audio_port);
303                 (_RCAST(struct sockaddr_in *, &(play_args_a.to)))->sin_addr.s_addr = ip_media;
304             }
305             image_port = get_remote_port_media(msg, PAT_IMAGE);
306             if (image_port) {
307                 /* We have image in the SDP: set the to_image addr */
308                 (_RCAST(struct sockaddr_in *, &(play_args_i.to)))->sin_family = AF_INET;
309                 (_RCAST(struct sockaddr_in *, &(play_args_i.to)))->sin_port = htons(image_port);
310                 (_RCAST(struct sockaddr_in *, &(play_args_i.to)))->sin_addr.s_addr = ip_media;
311             }
312             video_port = get_remote_port_media(msg, PAT_VIDEO);
313             if (video_port) {
314                 /* We have video in the SDP: set the to_video addr */
315                 (_RCAST(struct sockaddr_in *, &(play_args_v.to)))->sin_family = AF_INET;
316                 (_RCAST(struct sockaddr_in *, &(play_args_v.to)))->sin_port = htons(video_port);
317                 (_RCAST(struct sockaddr_in *, &(play_args_v.to)))->sin_addr.s_addr = ip_media;
318             }
319             hasMediaInformation = 1;
320         }
321     }
322 }
323 
324 #endif
325 
326 #ifdef RTP_STREAM
327 /******* Extract RTP remote media infomartion from SDP  *******/
328 /***** Similar to the routines used by the PCAP play code *****/
329 
330 #define SDP_IPADDR_PREFIX    "\nc=IN IP"
331 #define SDP_AUDIOPORT_PREFIX "\nm=audio"
332 #define SDP_IMAGEPORT_PREFIX "\nm=image"
333 #define SDP_VIDEOPORT_PREFIX "\nm=video"
extract_rtp_remote_addr(char * msg)334 void call::extract_rtp_remote_addr (char * msg)
335 {
336   char   *search;
337   char   *copy;
338   char   ip_addr[128];
339   int    ip_ver;
340   int    audio_port = 0;
341   int    image_port = 0;
342   int    video_port = 0;
343 
344   /* Look for start of message body */
345   search= strstr(msg,"\r\n\r\n");
346   if (!search) {
347     ERROR("extract_rtp_remote_addr: SDP message body not found");
348   }
349   msg = search + 2; /* skip past header. point to blank line before body */
350   /* Now search for IP address field */
351   search= strstr(msg,SDP_IPADDR_PREFIX);
352   if (search) {
353     search+= strlen(SDP_IPADDR_PREFIX);
354     /* Get IP version number from c= */
355     if (*search=='4') {
356       ip_ver= 4;
357     } else if (*search=='6') {
358       ip_ver= 6;
359     } else {
360       ERROR("extract_rtp_remote_addr: invalid IP version '%c' in SDP message body",*search);
361     }
362     search++;
363     copy= ip_addr;
364     while ( (*search==' ') || (*search=='\t') ) {
365       search++;
366     }
367     while (!( (*search==' ') || (*search=='\t') || (*search=='\r') || (*search=='\n') )) {
368       *(copy++)= *(search++);
369     }
370     *copy= 0;
371   } else {
372     ERROR("extract_rtp_remote_addr: no IP address found in SDP message body");
373     *ip_addr= 0;
374   }
375   /* Now try to find the port number for the audio stream */
376   search= strstr(msg,SDP_AUDIOPORT_PREFIX);
377   if (search) {
378     search+= strlen(SDP_AUDIOPORT_PREFIX);
379     while ( (*search==' ') || (*search=='\t') ) {
380       search++;
381     }
382     sscanf (search,"%d",&audio_port);
383   }
384   /* And find the port number for the image stream */
385   search= strstr(msg,SDP_IMAGEPORT_PREFIX);
386   if (search) {
387     search+= strlen(SDP_IMAGEPORT_PREFIX);
388     while ( (*search==' ') || (*search=='\t') ) {
389       search++;
390     }
391     sscanf (search,"%d",&image_port);
392   }
393   /* And find the port number for the video stream */
394   search= strstr(msg,SDP_VIDEOPORT_PREFIX);
395   if (search) {
396     search+= strlen(SDP_VIDEOPORT_PREFIX);
397     while ( (*search==' ') || (*search=='\t') ) {
398       search++;
399     }
400     sscanf (search,"%d",&video_port);
401   }
402   if (audio_port == 0 && image_port == 0 && video_port == 0) {
403     ERROR("extract_rtp_remote_addr: no m=audio, m=image or m=video line found in SDP message body");
404   }
405   /* If we get an image_port only, we won't set anything useful.
406    * We cannot use rtpstream for udptl/t38 data because it has
407    * non-linear timing and data size. */
408   rtpstream_set_remote(&rtpstream_callinfo, ip_ver, ip_addr, audio_port, video_port);
409 }
410 #endif
411 
412 /******* Very simple hash for retransmission detection  *******/
413 
hash(const char * msg)414 unsigned long call::hash(const char * msg)
415 {
416     unsigned long hash = 0;
417     int c;
418 
419     if (rtcheck == RTCHECK_FULL) {
420         while ((c = *msg++))
421             hash = c + (hash << 6) + (hash << 16) - hash;
422     } else if (rtcheck == RTCHECK_LOOSE) {
423         /* Based on section 11.5 (bullet 2) of RFC2543 we only take into account
424          * the To, From, Call-ID, and CSeq values. */
425         const char *hdr = get_header_content(msg,"To:");
426         while ((c = *hdr++))
427             hash = c + (hash << 6) + (hash << 16) - hash;
428         hdr = get_header_content(msg,"From:");
429         while ((c = *hdr++))
430             hash = c + (hash << 6) + (hash << 16) - hash;
431         hdr = get_header_content(msg,"Call-ID:");
432         while ((c = *hdr++))
433             hash = c + (hash << 6) + (hash << 16) - hash;
434         hdr = get_header_content(msg,"CSeq:");
435         while ((c = *hdr++))
436             hash = c + (hash << 6) + (hash << 16) - hash;
437         /* For responses, we should also consider the code and body (if any),
438          * because they are not nearly as well defined as the request retransmission. */
439         if (!strncmp(msg, "SIP/2.0", strlen("SIP/2.0"))) {
440             /* Add the first line into the hash. */
441             hdr = msg + strlen("SIP/2.0");
442             while ((c = *hdr++) && (c != '\r'))
443                 hash = c + (hash << 6) + (hash << 16) - hash;
444             /* Add the body (if any) into the hash. */
445             hdr = strstr(msg, "\r\n\r\n");
446             if (hdr) {
447                 hdr += strlen("\r\n\r\n");
448                 while ((c = *hdr++))
449                     hash = c + (hash << 6) + (hash << 16) - hash;
450             }
451         }
452     } else {
453         ERROR("Internal error: Invalid rtcheck %d\n", rtcheck);
454     }
455 
456     return hash;
457 }
458 
459 /******************* Call class implementation ****************/
call(const char * p_id,bool use_ipv6,int userId,struct sockaddr_storage * dest)460 call::call(const char *p_id, bool use_ipv6, int userId, struct sockaddr_storage *dest) : listener(p_id, true)
461 {
462     init(main_scenario, NULL, dest, p_id, userId, use_ipv6, false, false);
463 }
464 
call(const char * p_id,struct sipp_socket * socket,struct sockaddr_storage * dest)465 call::call(const char *p_id, struct sipp_socket *socket, struct sockaddr_storage *dest) : listener(p_id, true)
466 {
467     init(main_scenario, socket, dest, p_id, 0 /* No User. */, socket->ss_ipv6, false /* Not Auto. */, false);
468 }
469 
call(scenario * call_scenario,struct sipp_socket * socket,struct sockaddr_storage * dest,const char * p_id,int userId,bool ipv6,bool isAutomatic,bool isInitialization)470 call::call(scenario * call_scenario, struct sipp_socket *socket, struct sockaddr_storage *dest, const char * p_id, int userId, bool ipv6, bool isAutomatic, bool isInitialization) : listener(p_id, true)
471 {
472     init(call_scenario, socket, dest, p_id, userId, ipv6, isAutomatic, isInitialization);
473 }
474 
add_call(int userId,bool ipv6,struct sockaddr_storage * dest)475 call *call::add_call(int userId, bool ipv6, struct sockaddr_storage *dest)
476 {
477     static char call_id[MAX_HEADER_LEN];
478 
479     const char * src = call_id_string;
480     int count = 0;
481 
482     if(!next_number) {
483         next_number ++;
484     }
485 
486     while (*src && count < MAX_HEADER_LEN-1) {
487         if (*src == '%') {
488             ++src;
489             switch(*src++) {
490             case 'u':
491                 count += snprintf(&call_id[count], MAX_HEADER_LEN-count-1,"%u", next_number);
492                 break;
493             case 'p':
494                 count += snprintf(&call_id[count], MAX_HEADER_LEN-count-1,"%u", pid);
495                 break;
496             case 's':
497                 count += snprintf(&call_id[count], MAX_HEADER_LEN-count-1,"%s", local_ip);
498                 break;
499             default:      // treat all unknown sequences as %%
500                 call_id[count++] = '%';
501                 break;
502             }
503         } else {
504             call_id[count++] = *src++;
505         }
506     }
507     call_id[count] = 0;
508 
509     return new call(main_scenario, NULL, dest, call_id, userId, ipv6, false /* Not Auto. */, false);
510 }
511 
512 
init(scenario * call_scenario,struct sipp_socket * socket,struct sockaddr_storage * dest,const char * p_id,int userId,bool ipv6,bool isAutomatic,bool isInitCall)513 void call::init(scenario * call_scenario, struct sipp_socket *socket, struct sockaddr_storage *dest, const char * p_id, int userId, bool ipv6, bool isAutomatic, bool isInitCall)
514 {
515     this->call_scenario = call_scenario;
516     zombie = false;
517 
518     debugBuffer = NULL;
519     debugLength = 0;
520 
521     msg_index = 0;
522     last_send_index = 0;
523     last_send_msg = NULL;
524     last_send_len = 0;
525 
526     last_recv_hash = 0;
527     last_recv_index = -1;
528     last_recv_msg = NULL;
529 
530     recv_retrans_hash = 0;
531     recv_retrans_recv_index = -1;
532     recv_retrans_send_index = -1;
533 
534     dialog_route_set = NULL;
535     next_req_url = NULL;
536 
537     cseq = 0;
538 
539     next_retrans = 0;
540     nb_retrans = 0;
541     nb_last_delay = 0;
542 
543     paused_until = 0;
544 
545     call_port = 0;
546     comp_state = NULL;
547 
548     start_time = clock_tick;
549     call_established=false ;
550     ack_is_pending=false ;
551     last_recv_msg = NULL;
552     cseq = base_cseq;
553     nb_last_delay = 0;
554     use_ipv6 = ipv6;
555     queued_msg = NULL;
556 
557     dialog_authentication = NULL;
558     dialog_challenge_type = 0;
559 
560 #ifdef USE_OPENSSL
561     m_ctx_ssl = NULL ;
562     m_bio = NULL ;
563 #endif
564 #ifdef RTP_STREAM
565   /* check and warn on rtpstream_new_call result? -> error alloc'ing mem */
566   rtpstream_new_call (&rtpstream_callinfo);
567 #endif
568 
569 #ifdef PCAPPLAY
570     hasMediaInformation = 0;
571 #endif
572 
573     call_remote_socket = NULL;
574     if (socket) {
575         associate_socket(socket);
576         socket->ss_count++;
577     } else {
578         call_socket = NULL;
579     }
580     if (dest) {
581         memcpy(&call_peer, dest, SOCK_ADDR_SIZE(dest));
582     } else {
583         memset(&call_peer, 0, sizeof(call_peer));
584     }
585 
586     // initialising the CallVariable with the Scenario variable
587     int i;
588     VariableTable *userVars = NULL;
589     bool putUserVars = false;
590     if (userId) {
591         int_vt_map::iterator it = userVarMap.find(userId);
592         if (it != userVarMap.end()) {
593             userVars = it->second;
594         }
595     } else {
596         userVars = new VariableTable(userVariables);
597         /* Creating this table creates a reference to it, but if it is really used,
598          * then the refcount will be increased. */
599         putUserVars = true;
600     }
601     if (call_scenario->allocVars->size > 0) {
602         M_callVariableTable = new VariableTable(userVars, call_scenario->allocVars->size);
603     } else if (userVars && userVars->size > 0) {
604         M_callVariableTable = userVars->getTable();
605     } else if (globalVariables->size > 0) {
606         M_callVariableTable = globalVariables->getTable();
607     } else {
608         M_callVariableTable = NULL;
609     }
610     if (putUserVars) {
611         userVars->putTable();
612     }
613 
614     if (call_scenario->transactions.size() > 0) {
615         transactions = (struct txnInstanceInfo *)malloc(sizeof(txnInstanceInfo) * call_scenario->transactions.size());
616         memset(transactions, 0, sizeof(struct txnInstanceInfo) * call_scenario->transactions.size());
617     } else {
618         transactions = NULL;
619     }
620 
621     // If not updated by a message we use the start time
622     // information to compute rtd information
623     start_time_rtd = (unsigned long long *)malloc(sizeof(unsigned long long) * call_scenario->stats->nRtds());
624     if (!start_time_rtd) {
625         ERROR("Could not allocate RTD times!");
626     }
627     rtd_done = (bool *)malloc(sizeof(bool) * call_scenario->stats->nRtds());
628     if (!start_time_rtd) {
629         ERROR("Could not allocate RTD done!");
630     }
631     for (i = 0; i < call_scenario->stats->nRtds(); i++) {
632         start_time_rtd[i] = getmicroseconds();
633         rtd_done[i] = false;
634     }
635 
636     // by default, last action result is NO_ERROR
637     last_action_result = call::E_AR_NO_ERROR;
638 
639     this->userId = userId;
640 
641     /* For automatic answer calls to an out of call request, we must not */
642     /* increment the input files line numbers to not disturb */
643     /* the input files read mechanism (otherwise some lines risk */
644     /* to be systematically skipped */
645     if (!isAutomatic) {
646         m_lineNumber = new file_line_map();
647         for (file_map::iterator file_it = inFiles.begin();
648                 file_it != inFiles.end();
649                 file_it++) {
650             (*m_lineNumber)[file_it->first] = file_it->second->nextLine(userId);
651         }
652     } else {
653         m_lineNumber = NULL;
654     }
655     this->initCall = isInitCall;
656 
657 #ifdef PCAPPLAY
658     memset(&(play_args_a.to), 0, sizeof(struct sockaddr_storage));
659     memset(&(play_args_i.to), 0, sizeof(struct sockaddr_storage));
660     memset(&(play_args_v.to), 0, sizeof(struct sockaddr_storage));
661     memset(&(play_args_a.from), 0, sizeof(struct sockaddr_storage));
662     memset(&(play_args_i.from), 0, sizeof(struct sockaddr_storage));
663     memset(&(play_args_v.from), 0, sizeof(struct sockaddr_storage));
664     hasMediaInformation = 0;
665     media_thread = 0;
666 #endif
667 
668     peer_tag = NULL;
669     recv_timeout = 0;
670     send_timeout = 0;
671     timewait = false;
672 
673     if (!isAutomatic) {
674         /* Not advancing the number is safe, because for automatic calls we do not
675          * assign the identifier,  the only other place it is used is for the auto
676          * media port. */
677         number = next_number++;
678 
679         if (use_tdmmap) {
680             tdm_map_number = get_tdm_map_number();
681             if (tdm_map_number == 0) {
682                 /* Can't create the new call */
683                 WARNING("Can't create new outgoing call: all tdm_map circuits busy");
684                 computeStat(CStat::E_CALL_FAILED);
685                 computeStat(CStat::E_FAILED_OUTBOUND_CONGESTION);
686                 this->zombie = true;
687                 return;
688             }
689             /* Mark the entry in the list as busy */
690             tdm_map[tdm_map_number - 1] = true;
691         } else {
692             tdm_map_number = 0;
693         }
694     }
695 
696     callDebug("Starting call %s\n", id);
697 
698     setRunning();
699 }
700 
_callDebug(const char * fmt,...)701 int call::_callDebug(const char *fmt, ...)
702 {
703     va_list ap;
704 
705     if (!useCallDebugf) {
706         return 0;
707     }
708 
709     /* First we figure out how much to allocate. */
710     va_start(ap, fmt);
711     int ret = vsnprintf(NULL, 0, fmt, ap);
712     va_end(ap);
713 
714     debugBuffer = (char *)realloc(debugBuffer, debugLength + ret + TIME_LENGTH + 2);
715     if (!debugBuffer) {
716         ERROR("Could not allocate buffer (%d bytes) for callDebug file!", debugLength + ret + TIME_LENGTH + 2);
717     }
718 
719     struct timeval now;
720     gettimeofday(&now, NULL);
721     debugLength += snprintf(debugBuffer + debugLength, TIME_LENGTH + 2, "%s ", CStat::formatTime(&now));
722 
723     va_start(ap, fmt);
724     debugLength += vsnprintf(debugBuffer + debugLength, ret + 1, fmt, ap);
725     va_end(ap);
726 
727     return ret;
728 }
729 
~call()730 call::~call()
731 {
732     computeStat(CStat::E_ADD_CALL_DURATION, clock_tick - start_time);
733 
734     if(comp_state) {
735         comp_free(&comp_state);
736     }
737 
738     if (call_remote_socket && (call_remote_socket != main_remote_socket)) {
739         sipp_close_socket(call_remote_socket);
740     }
741 
742     /* Deletion of the call variable */
743     if(M_callVariableTable) {
744         M_callVariableTable->putTable();
745     }
746     if (m_lineNumber) {
747         delete m_lineNumber;
748     }
749     if (userId) {
750         CallGenerationTask::free_user(userId);
751     }
752 
753     if (transactions) {
754         for (unsigned int i = 0; i < call_scenario->transactions.size(); i++) {
755             free(transactions[i].txnID);
756         }
757         free(transactions);
758     }
759 
760     if(last_recv_msg) {
761         free(last_recv_msg);
762     }
763     if(last_send_msg) {
764         free(last_send_msg);
765     }
766     if(peer_tag) {
767         free(peer_tag);
768     }
769 
770     if(dialog_route_set) {
771         free(dialog_route_set);
772     }
773 
774     if(next_req_url) {
775         free(next_req_url);
776     }
777 
778 #ifdef RTP_STREAM
779   rtpstream_end_call (&rtpstream_callinfo);
780 #endif
781 
782     if(dialog_authentication) {
783         free(dialog_authentication);
784     }
785 
786     if (use_tdmmap) {
787         tdm_map[tdm_map_number] = false;
788     }
789 
790 # ifdef PCAPPLAY
791     if (media_thread != 0) {
792         pthread_cancel(media_thread);
793         pthread_join(media_thread, NULL);
794     }
795 #endif
796 
797 
798     free(start_time_rtd);
799     free(rtd_done);
800     free(debugBuffer);
801 }
802 
computeStat(CStat::E_Action P_action)803 void call::computeStat (CStat::E_Action P_action)
804 {
805     if (initCall) {
806         return;
807     }
808     call_scenario->stats->computeStat(P_action);
809 }
810 
computeStat(CStat::E_Action P_action,unsigned long P_value)811 void call::computeStat (CStat::E_Action P_action, unsigned long P_value)
812 {
813     if (initCall) {
814         return;
815     }
816     call_scenario->stats->computeStat(P_action, P_value);
817 }
818 
computeStat(CStat::E_Action P_action,unsigned long P_value,int which)819 void call::computeStat (CStat::E_Action P_action, unsigned long P_value, int which)
820 {
821     if (initCall) {
822         return;
823     }
824     call_scenario->stats->computeStat(P_action, P_value, which);
825 }
826 
827 /* Dump call info to error log. */
dump()828 void call::dump()
829 {
830     char s[MAX_HEADER_LEN];
831     char tmpbuf[MAX_HEADER_LEN];
832     sprintf(s, "%s: State %d", id, msg_index);
833     if (next_retrans) {
834         snprintf(tmpbuf, 64, "%s (next retrans %u)", s, next_retrans);
835         strcat(s, tmpbuf);
836     }
837     if (paused_until) {
838         snprintf(tmpbuf, 64, "%s (paused until %u)", s, paused_until);
839         strcat(s, tmpbuf);
840     }
841     if (recv_timeout) {
842         snprintf(tmpbuf, 64, "%s (recv timeout %u)", s, recv_timeout);
843         strcat(s, tmpbuf);
844     }
845     if (send_timeout) {
846         snprintf(tmpbuf, 64, "%s (send timeout %u)", s, send_timeout);
847         strcat(s, tmpbuf);
848     }
849     WARNING("%s", s);
850 }
851 
connect_socket_if_needed()852 bool call::connect_socket_if_needed()
853 {
854     bool existing;
855 
856     if(call_socket) return true;
857     if(!multisocket) return true;
858 
859     if(transport == T_UDP) {
860         struct sockaddr_storage saddr;
861 
862         if(sendMode != MODE_CLIENT)
863             return true;
864 
865         char peripaddr[256];
866         if (!peripsocket) {
867             if ((associate_socket(new_sipp_call_socket(use_ipv6, transport, &existing))) == NULL) {
868                 ERROR_NO("Unable to get a UDP socket (1)");
869             }
870         } else {
871             char *tmp = peripaddr;
872             getFieldFromInputFile(ip_file, peripfield, NULL, tmp);
873             map<string, struct sipp_socket *>::iterator i;
874             i = map_perip_fd.find(peripaddr);
875             if (i == map_perip_fd.end()) {
876                 // Socket does not exist
877                 if ((associate_socket(new_sipp_call_socket(use_ipv6, transport, &existing))) == NULL) {
878                     ERROR_NO("Unable to get a UDP socket (2)");
879                 } else {
880                     /* Ensure that it stays persistent, because it is recorded in the map. */
881                     call_socket->ss_count++;
882                     map_perip_fd[peripaddr] = call_socket;
883                 }
884             } else {
885                 // Socket exists already
886                 associate_socket(i->second);
887                 existing = true;
888                 i->second->ss_count++;
889             }
890         }
891         if (existing) {
892             return true;
893         }
894 
895         memset(&saddr, 0, sizeof(struct sockaddr_storage));
896 
897         memcpy(&saddr,
898                local_addr_storage->ai_addr,
899                SOCK_ADDR_SIZE(
900                    _RCAST(struct sockaddr_storage *,local_addr_storage->ai_addr)));
901 
902         if (use_ipv6) {
903             saddr.ss_family       = AF_INET6;
904         } else {
905             saddr.ss_family       = AF_INET;
906         }
907 
908         if (peripsocket) {
909             struct addrinfo * h ;
910             struct addrinfo   hints;
911             memset((char*)&hints, 0, sizeof(hints));
912             hints.ai_flags  = AI_PASSIVE;
913             hints.ai_family = PF_UNSPEC;
914             getaddrinfo(peripaddr,
915                         NULL,
916                         &hints,
917                         &h);
918             memcpy(&saddr, h->ai_addr,
919                    SOCK_ADDR_SIZE(_RCAST(struct sockaddr_storage*, h->ai_addr)));
920 
921             if (use_ipv6) {
922                 (_RCAST(struct sockaddr_in6*, &saddr))->sin6_port = htons(local_port);
923             } else {
924                 (_RCAST(struct sockaddr_in*, &saddr))->sin_port = htons(local_port);
925             }
926             freeaddrinfo(h);
927         }
928 
929         if (sipp_bind_socket(call_socket, &saddr, &call_port)) {
930             ERROR_NO("Unable to bind UDP socket");
931         }
932     } else { /* TCP, SCTP or TLS. */
933         struct sockaddr_storage *L_dest = &remote_sockaddr;
934 
935         if ((associate_socket(new_sipp_call_socket(use_ipv6, transport, &existing))) == NULL) {
936             ERROR_NO("Unable to get a TCP/SCTP/TLS socket");
937         }
938 
939         if (existing) {
940             return true;
941         }
942 
943         sipp_customize_socket(call_socket);
944 
945         if (use_remote_sending_addr) {
946             L_dest = &remote_sending_sockaddr;
947         }
948 
949         if (sipp_connect_socket(call_socket, L_dest)) {
950             if (reconnect_allowed()) {
951                 if(errno == EINVAL) {
952                     /* This occurs sometime on HPUX but is not a true INVAL */
953                     WARNING("Unable to connect a TCP/SCTP/TLS socket, remote peer error");
954                 } else {
955                     WARNING("Unable to connect a TCP/SCTP/TLS socket");
956                 }
957                 /* This connection failed.  We must be in multisocket mode, because
958                      * otherwise we would already have a call_socket.  This call can not
959                      * succeed, but does not affect any of our other calls. We do decrement
960                  * the reconnection counter however. */
961                 if (reset_number != -1) {
962                     reset_number--;
963                 }
964 
965                 computeStat(CStat::E_CALL_FAILED);
966                 computeStat(CStat::E_FAILED_TCP_CONNECT);
967                 delete this;
968 
969                 return false;
970             } else {
971                 if(errno == EINVAL) {
972                     /* This occurs sometime on HPUX but is not a true INVAL */
973                     ERROR("Unable to connect a TCP/SCTP/TLS socket, remote peer error");
974                 } else {
975                     ERROR_NO("Unable to connect a TCP/SCTP/TLS socket");
976                 }
977             }
978         }
979     }
980     return true;
981 }
982 
lost(int index)983 bool call::lost(int index)
984 {
985     static int inited = 0;
986     double percent = global_lost;
987 
988     if(!lose_packets) return false;
989 
990     if (call_scenario->messages[index]->lost >= 0) {
991         percent = call_scenario->messages[index]->lost;
992     }
993 
994     if (percent == 0) {
995         return false;
996     }
997 
998     if(!inited) {
999         srand((unsigned int) time(NULL));
1000         inited = 1;
1001     }
1002 
1003     return (((double)rand() / (double)RAND_MAX) < (percent / 100.0));
1004 }
1005 
send_raw(const char * msg,int index,int len)1006 int call::send_raw(const char * msg, int index, int len)
1007 {
1008     struct sipp_socket *sock;
1009     int rc;
1010 
1011     callDebug("Sending %s message for call %s (index %d, hash %lu):\n%s\n\n",
1012               TRANSPORT_TO_STRING(transport), id, index, hash(msg), msg);
1013 
1014     if((index!=-1) && (lost(index))) {
1015         TRACE_MSG("%s message voluntary lost (while sending).", TRANSPORT_TO_STRING(transport));
1016         callDebug("%s message voluntary lost (while sending) (index %d, hash %lu).\n",
1017                   TRANSPORT_TO_STRING(transport), index, hash(msg));
1018 
1019         if(comp_state) {
1020             comp_free(&comp_state);
1021         }
1022         call_scenario->messages[index] -> nb_lost++;
1023         return 0;
1024     }
1025 
1026     sock = call_socket;
1027 
1028     if ((use_remote_sending_addr) && (sendMode == MODE_SERVER)) {
1029         if (!call_remote_socket) {
1030             if (multisocket || !main_remote_socket) {
1031                 struct sockaddr_storage *L_dest = &remote_sending_sockaddr;
1032 
1033                 if((call_remote_socket= new_sipp_socket(use_ipv6, transport)) == NULL) {
1034                     ERROR_NO("Unable to get a socket for rsa option");
1035                 }
1036 
1037                 sipp_customize_socket(call_remote_socket);
1038 
1039                 if(transport != T_UDP) {
1040                     if (sipp_connect_socket(call_remote_socket, L_dest)) {
1041                         if(errno == EINVAL) {
1042                             /* This occurs sometime on HPUX but is not a true INVAL */
1043                             ERROR("Unable to connect a %s socket for rsa option, remote peer error", TRANSPORT_TO_STRING(transport));
1044                         } else {
1045                             ERROR_NO("Unable to connect a socket for rsa option");
1046                         }
1047                     }
1048                 }
1049                 if (!multisocket) {
1050                     main_remote_socket = call_remote_socket;
1051                 }
1052             }
1053 
1054             if (!multisocket) {
1055                 call_remote_socket = main_remote_socket;
1056                 main_remote_socket->ss_count++;
1057             }
1058         }
1059         sock=call_remote_socket ;
1060     }
1061 
1062     // If the length hasn't been explicitly specified, treat the message as a string
1063     if (len==0) {
1064         len = strlen(msg);
1065     }
1066 
1067     assert(sock);
1068 
1069     rc = write_socket(sock, msg, len, WS_BUFFER, &call_peer);
1070     if(rc < 0 && errno == EWOULDBLOCK) {
1071         return rc;
1072     }
1073 
1074     if(rc < 0) {
1075         computeStat(CStat::E_CALL_FAILED);
1076         computeStat(CStat::E_FAILED_CANNOT_SEND_MSG);
1077         delete this;
1078     }
1079 
1080     return rc; /* OK */
1081 }
1082 
1083 /* This method is used to send messages that are not */
1084 /* part of the XML scenario                          */
sendBuffer(char * msg,int len)1085 void call::sendBuffer(char * msg, int len)
1086 {
1087     /* call send_raw but with a special scenario index */
1088     if (send_raw(msg, -1, len) < 0) {
1089         if (sendbuffer_warn) {
1090             ERROR_NO("Error sending raw message");
1091         } else {
1092             WARNING_NO("Error sending raw message");
1093         }
1094     }
1095 }
1096 
get_header_field_code(const char * msg,const char * name)1097 char * call::get_header_field_code(const char *msg, const char * name)
1098 {
1099     static char code[MAX_HEADER_LEN];
1100     const char * last_header;
1101     int i;
1102 
1103     last_header = NULL;
1104     i = 0;
1105     /* If we find the field in msg */
1106     last_header = get_header_content(msg, name);
1107     if(last_header) {
1108         /* Extract the integer value of the field */
1109         while(isspace(*last_header)) last_header++;
1110         sscanf(last_header,"%d", &i);
1111         sprintf(code, "%s %d", name, i);
1112     }
1113     return code;
1114 }
1115 
get_last_header(const char * name)1116 char * call::get_last_header(const char * name)
1117 {
1118     int len;
1119 
1120     if((!last_recv_msg) || (!strlen(last_recv_msg))) {
1121         return NULL;
1122     }
1123 
1124     len = strlen(name);
1125 
1126     /* Ideally this check should be moved to the XML parser so that it is not
1127      * along a critical path.  We could also handle lowercasing there. */
1128     if (len > MAX_HEADER_LEN) {
1129         ERROR("call::get_last_header: Header to parse bigger than %d (%zu)", MAX_HEADER_LEN, strlen(name));
1130     }
1131 
1132     if (name[len - 1] == ':') {
1133         return get_header(last_recv_msg, name, false);
1134     } else {
1135         char with_colon[MAX_HEADER_LEN];
1136         sprintf(with_colon, "%s:", name);
1137         return get_header(last_recv_msg, with_colon, false);
1138     }
1139 }
1140 
1141 /* Return the last request URI from the To header. On any error returns the
1142  * empty string.  The caller must free the result. */
get_last_request_uri()1143 char * call::get_last_request_uri()
1144 {
1145     char * tmp;
1146     char * tmp2;
1147     char * last_request_uri;
1148     int tmp_len;
1149 
1150     char * last_To = get_last_header("To:");
1151     if (!last_To) {
1152         return strdup("");
1153     }
1154 
1155     tmp = strchr(last_To, '<');
1156     if (!tmp) {
1157         return strdup("");
1158     }
1159     tmp++;
1160 
1161     tmp2 = strchr(last_To, '>');
1162     if (!tmp2) {
1163         return strdup("");
1164     }
1165 
1166     tmp_len = strlen(tmp) - strlen(tmp2);
1167     if (tmp_len < 0) {
1168         return strdup("");
1169     }
1170 
1171     if (!(last_request_uri = (char *)malloc(tmp_len + 1))) {
1172         ERROR("Cannot allocate !\n");
1173     }
1174 
1175     last_request_uri[0] = '\0';
1176     if (tmp && (tmp_len > 0)) {
1177         strncpy(last_request_uri, tmp, tmp_len);
1178     }
1179     last_request_uri[tmp_len] = '\0';
1180 
1181     return last_request_uri;
1182 }
1183 
send_scene(int index,int * send_status,int * len)1184 char * call::send_scene(int index, int *send_status, int *len)
1185 {
1186 #define MAX_MSG_NAME_SIZE 30
1187     static char msg_name[MAX_MSG_NAME_SIZE];
1188     char *L_ptr1 ;
1189     char *L_ptr2 ;
1190     int uselen = 0;
1191     int tmplen;
1192     char *hdrbdry;
1193 
1194     assert(send_status);
1195 
1196     /* Socket port must be known before string substitution */
1197     if (!connect_socket_if_needed()) {
1198         *send_status = -2;
1199         return NULL;
1200     }
1201 
1202     assert(call_socket);
1203 
1204     assert(call_scenario->messages[index]->send_scheme);
1205 
1206     if (!len) {
1207         len = &uselen;
1208     }
1209 
1210     char * dest;
1211     dest = createSendingMessage(call_scenario->messages[index] -> send_scheme, index, len);
1212 
1213     if (!dest) {
1214         *send_status = -2;
1215         return NULL;
1216     }
1217 
1218     L_ptr1=msg_name ;
1219     L_ptr2=dest ;
1220     while ((*L_ptr2 != ' ') && (*L_ptr2 != '\n') && (*L_ptr2 != '\t'))  {
1221         *L_ptr1 = *L_ptr2;
1222         L_ptr1 ++;
1223         L_ptr2 ++;
1224     }
1225     *L_ptr1 = '\0' ;
1226 
1227     if (strcmp(msg_name,"ACK") == 0) {
1228         call_established = true ;
1229         ack_is_pending = false ;
1230     }
1231 
1232     /* Fix: Remove extra "\r\n" if message body ends with "\r\n\r\n" */
1233     tmplen = (*len) - 1;
1234     if ((dest[tmplen] == dest[tmplen-2] && dest[tmplen] == '\n')
1235             && (dest[tmplen-1] == dest[tmplen-3] && dest[tmplen-1] == '\r'))  {
1236         hdrbdry = strstr(dest, "\r\n\r\n");
1237         if (NULL != hdrbdry &&  hdrbdry != dest+(tmplen-3))  {
1238             *len = (*len) - 2;
1239         }
1240     }
1241 
1242     *send_status = send_raw(dest, index, *len);
1243 
1244     return dest;
1245 }
1246 
do_bookkeeping(message * curmsg)1247 void call::do_bookkeeping(message *curmsg)
1248 {
1249     /* If this message increments a counter, do it now. */
1250     if(int counter = curmsg -> counter) {
1251         computeStat(CStat::E_ADD_GENERIC_COUNTER, 1, counter - 1);
1252     }
1253 
1254     /* If this message can be used to compute RTD, do it now */
1255     if(int rtd = curmsg -> start_rtd) {
1256         start_time_rtd[rtd - 1] = getmicroseconds();
1257     }
1258 
1259     if(int rtd = curmsg -> stop_rtd) {
1260         if (!rtd_done[rtd - 1]) {
1261             unsigned long long start = start_time_rtd[rtd - 1];
1262             unsigned long long end = getmicroseconds();
1263 
1264             if(dumpInRtt) {
1265                 call_scenario->stats->computeRtt(start, end, rtd);
1266             }
1267 
1268             computeStat(CStat::E_ADD_RESPONSE_TIME_DURATION,
1269                         (end - start) / 1000, rtd - 1);
1270 
1271             if (!curmsg -> repeat_rtd) {
1272                 rtd_done[rtd - 1] = true;
1273             }
1274         }
1275     }
1276 }
1277 
tcpClose()1278 void call::tcpClose()
1279 {
1280     terminate(CStat::E_FAILED_TCP_CLOSED);
1281 }
1282 
terminate(CStat::E_Action reason)1283 void call::terminate(CStat::E_Action reason)
1284 {
1285     char reason_str[100];
1286 
1287     stopListening();
1288 
1289     // Call end -> was it successful?
1290     if(call::last_action_result != call::E_AR_NO_ERROR) {
1291         switch(call::last_action_result) {
1292         case call::E_AR_REGEXP_DOESNT_MATCH:
1293             computeStat(CStat::E_CALL_FAILED);
1294             computeStat(CStat::E_FAILED_REGEXP_DOESNT_MATCH);
1295             if (deadcall_wait && !initCall) {
1296                 sprintf(reason_str, "regexp match failure at index %d", msg_index);
1297                 new deadcall(id, reason_str);
1298             }
1299             break;
1300         case call::E_AR_REGEXP_SHOULDNT_MATCH:
1301             computeStat(CStat::E_CALL_FAILED);
1302             computeStat(CStat::E_FAILED_REGEXP_SHOULDNT_MATCH);
1303             if (deadcall_wait && !initCall) {
1304                 sprintf(reason_str, "regexp matched, but shouldn't at index %d", msg_index);
1305                 new deadcall(id, reason_str);
1306             }
1307             break;
1308         case call::E_AR_HDR_NOT_FOUND:
1309             computeStat(CStat::E_CALL_FAILED);
1310             computeStat(CStat::E_FAILED_REGEXP_HDR_NOT_FOUND);
1311             if (deadcall_wait && !initCall) {
1312                 sprintf(reason_str, "regexp header not found at index %d", msg_index);
1313                 new deadcall(id, reason_str);
1314             }
1315             break;
1316         case E_AR_CONNECT_FAILED:
1317             computeStat(CStat::E_CALL_FAILED);
1318             computeStat(CStat::E_FAILED_TCP_CONNECT);
1319             if (deadcall_wait && !initCall) {
1320                 sprintf(reason_str, "connection failed %d", msg_index);
1321                 new deadcall(id, reason_str);
1322             }
1323             break;
1324         case call::E_AR_NO_ERROR:
1325         case call::E_AR_STOP_CALL:
1326             /* Do nothing. */
1327             break;
1328         }
1329     } else {
1330         if (reason == CStat::E_CALL_SUCCESSFULLY_ENDED || timewait) {
1331             computeStat(CStat::E_CALL_SUCCESSFULLY_ENDED);
1332             if (deadcall_wait && !initCall) {
1333                 new deadcall(id, "successful");
1334             }
1335         } else {
1336             computeStat(CStat::E_CALL_FAILED);
1337             if (reason != CStat::E_NO_ACTION) {
1338                 computeStat(reason);
1339             }
1340             if (deadcall_wait && !initCall) {
1341                 sprintf(reason_str, "failed at index %d", msg_index);
1342                 new deadcall(id, reason_str);
1343             }
1344         }
1345     }
1346     delete this;
1347 }
1348 
next()1349 bool call::next()
1350 {
1351     msgvec * msgs = &call_scenario->messages;
1352     if (initCall) {
1353         msgs = &call_scenario->initmessages;
1354     }
1355 
1356     int test;
1357     /* What is the next message index? */
1358     /* Default without branching: use the next message */
1359     int new_msg_index = msg_index + 1;
1360     /* If branch needed, overwrite this default */
1361     if (msg_index >= 0 && ((*msgs)[msg_index]->next >= 0) &&
1362             (((test = ((*msgs)[msg_index]->test)) == -1) ||
1363              M_callVariableTable->getVar(test)->isSet())) {
1364         /* Branching possible, check the probability */
1365         int chance = (*msgs)[msg_index]->chance;
1366         if ((chance <= 0) || (rand() > chance )) {
1367             /* Branch == overwrite with the 'next' attribute value */
1368             new_msg_index = (*msgs)[msg_index]->next;
1369         }
1370     }
1371     msg_index = new_msg_index;
1372     recv_timeout = 0;
1373     if (msg_index >= (int)((*msgs).size())) {
1374         terminate(CStat::E_CALL_SUCCESSFULLY_ENDED);
1375         return false;
1376     }
1377 
1378     return true;
1379 }
1380 
executeMessage(message * curmsg)1381 bool call::executeMessage(message *curmsg)
1382 {
1383     if (curmsg->pause_distribution || curmsg->pause_variable != -1) {
1384         unsigned int pause;
1385         if (curmsg->pause_distribution) {
1386             double actualpause = curmsg->pause_distribution->sample();
1387             if (actualpause < 1) {
1388                 // Protect against distribution samples that give
1389                 // negative results (and so pause for ~50 hours when
1390                 // cast to a unsigned int).
1391                 pause = 0;
1392             } else {
1393                 pause  = (unsigned int)actualpause;
1394             };
1395         } else {
1396             int varId = curmsg->pause_variable;
1397             pause = (int) M_callVariableTable->getVar(varId)->getDouble();
1398         }
1399         if (pause > INT_MAX) {
1400             pause = INT_MAX;
1401         }
1402         paused_until = clock_tick + pause;
1403 
1404         /* This state is used as the last message of a scenario, just for handling
1405          * final retransmissions. If the connection closes, we do not mark it is
1406          * failed. */
1407         this->timewait = curmsg->timewait;
1408 
1409         /* Increment the number of sessions in pause state */
1410         curmsg->sessions++;
1411         do_bookkeeping(curmsg);
1412         executeAction(NULL, curmsg);
1413         callDebug("Pausing call until %d (is now %ld).\n", paused_until, clock_tick);
1414         setPaused();
1415         return true;
1416     } else if(curmsg -> M_type == MSG_TYPE_SENDCMD) {
1417         int send_status;
1418 
1419         if(next_retrans) {
1420             return true;
1421         }
1422 
1423         send_status = sendCmdMessage(curmsg);
1424 
1425         if(send_status != 0) { /* Send error */
1426             return false; /* call deleted */
1427         }
1428         curmsg -> M_nbCmdSent++;
1429         next_retrans = 0;
1430 
1431         do_bookkeeping(curmsg);
1432         executeAction(NULL, curmsg);
1433         return(next());
1434     } else if(curmsg -> M_type == MSG_TYPE_NOP) {
1435         callDebug("Executing NOP at index %d.\n", curmsg->index);
1436         do_bookkeeping(curmsg);
1437         executeAction(NULL, curmsg);
1438         return(next());
1439     }
1440 
1441     else if(curmsg -> send_scheme) {
1442         char * msg_snd;
1443         int msgLen;
1444         int send_status;
1445 
1446         /* Do not send a new message until the previous one which had
1447          * retransmission enabled is acknowledged */
1448 
1449         if(next_retrans) {
1450             setPaused();
1451             return true;
1452         }
1453 
1454         /* Handle counters and RTDs for this message. */
1455         do_bookkeeping(curmsg);
1456 
1457         /* decide whether to increment cseq or not
1458          * basically increment for anything except response, ACK or CANCEL
1459          * Note that cseq is only used by the [cseq] keyword, and
1460          * not by default
1461          */
1462 
1463         int incr_cseq = 0;
1464         if (!curmsg->send_scheme->isAck() &&
1465                 !curmsg->send_scheme->isCancel() &&
1466                 !curmsg->send_scheme->isResponse()) {
1467             ++cseq;
1468             incr_cseq = 1;
1469         }
1470 
1471         msg_snd = send_scene(msg_index, &send_status, &msgLen);
1472         if(send_status < 0 && errno == EWOULDBLOCK) {
1473             if (incr_cseq) --cseq;
1474             /* Have we set the timeout yet? */
1475             if (send_timeout) {
1476                 /* If we have actually timed out. */
1477                 if (clock_tick > send_timeout) {
1478                     WARNING("Call-Id: %s, send timeout on message %s:%d: aborting call",
1479                             id, curmsg->desc, curmsg->index);
1480                     computeStat(CStat::E_CALL_FAILED);
1481                     computeStat(CStat::E_FAILED_TIMEOUT_ON_SEND);
1482                     if (default_behaviors & DEFAULT_BEHAVIOR_BYE) {
1483                         return (abortCall(true));
1484                     } else {
1485                         delete this;
1486                         return false;
1487                     }
1488                 }
1489             } else if (curmsg->timeout) {
1490                 /* Initialize the send timeout to the per message timeout. */
1491                 send_timeout = clock_tick + curmsg->timeout;
1492             } else if (defl_send_timeout) {
1493                 /* Initialize the send timeout to the global timeout. */
1494                 send_timeout = clock_tick + defl_send_timeout;
1495             }
1496             return true; /* No step, nothing done, retry later */
1497         } else if(send_status < 0) { /* Send error */
1498             /* The call was already deleted by connect_socket_if_needed or send_raw,
1499              * so we should no longer access members. */
1500             return false;
1501         }
1502         /* We have sent the message, so the timeout is no longer needed. */
1503         send_timeout = 0;
1504 
1505         last_send_index = curmsg->index;
1506         last_send_len = msgLen;
1507         realloc_ptr = (char *) realloc(last_send_msg, msgLen+1);
1508         if (realloc_ptr) {
1509             last_send_msg = realloc_ptr;
1510         } else {
1511             free(last_send_msg);
1512             ERROR("Out of memory!");
1513             return false;
1514         }
1515         memcpy(last_send_msg, msg_snd, msgLen);
1516         last_send_msg[msgLen] = '\0';
1517 
1518         if (curmsg->start_txn) {
1519             transactions[curmsg->start_txn - 1].txnID = (char *)realloc(transactions[curmsg->start_txn - 1].txnID, MAX_HEADER_LEN);
1520             extract_transaction(transactions[curmsg->start_txn - 1].txnID, last_send_msg);
1521         }
1522         if (curmsg->ack_txn) {
1523             transactions[curmsg->ack_txn - 1].ackIndex = curmsg->index;
1524         }
1525 
1526         if(last_recv_index >= 0) {
1527             /* We are sending just after msg reception. There is a great
1528              * chance that we will be asked to retransmit this message */
1529             recv_retrans_hash       = last_recv_hash;
1530             recv_retrans_recv_index = last_recv_index;
1531             recv_retrans_send_index = curmsg->index;
1532 
1533             callDebug("Set Retransmission Hash: %lu (recv index %d, send index %d)\n",
1534                       recv_retrans_hash, recv_retrans_recv_index, recv_retrans_send_index);
1535 
1536             /* Prevent from detecting the cause relation between send and recv
1537              * in the next valid send */
1538             last_recv_hash = 0;
1539         }
1540 
1541         /* Update retransmission information */
1542         if(curmsg -> retrans_delay) {
1543             if((transport == T_UDP) && (retrans_enabled)) {
1544                 next_retrans = clock_tick + curmsg -> retrans_delay;
1545                 nb_retrans = 0;
1546                 nb_last_delay = curmsg->retrans_delay;
1547             }
1548         } else {
1549             next_retrans = 0;
1550         }
1551 
1552         executeAction(msg_snd, curmsg);
1553 
1554         /* Update scenario statistics */
1555         curmsg -> nb_sent++;
1556 
1557         return next();
1558     } else if (curmsg->M_type == MSG_TYPE_RECV
1559                || curmsg->M_type == MSG_TYPE_RECVCMD
1560               ) {
1561         if (queued_msg) {
1562             char *msg = queued_msg;
1563             queued_msg = NULL;
1564             bool ret = process_incoming(msg);
1565             free(msg);
1566             return ret;
1567         } else if (recv_timeout) {
1568             if(recv_timeout > getmilliseconds()) {
1569                 setPaused();
1570                 return true;
1571             }
1572             recv_timeout = 0;
1573             curmsg->nb_timeout++;
1574             if (curmsg->on_timeout < 0) {
1575                 // if you set a timeout but not a label, the call is aborted
1576                 WARNING("Call-Id: %s, receive timeout on message %s:%d without label to jump to (ontimeout attribute): aborting call",
1577                         id, curmsg->desc, curmsg->index);
1578                 computeStat(CStat::E_CALL_FAILED);
1579                 computeStat(CStat::E_FAILED_TIMEOUT_ON_RECV);
1580                 if (default_behaviors & DEFAULT_BEHAVIOR_BYE) {
1581                     return (abortCall(true));
1582                 } else {
1583                     delete this;
1584                     return false;
1585                 }
1586             }
1587             WARNING("Call-Id: %s, receive timeout on message %s:%d, jumping to label %d",
1588                     id, curmsg->desc, curmsg->index, curmsg->on_timeout);
1589             /* FIXME: We should do something like set index here, but it probably
1590              * does not matter too much as only nops are allowed in the init stanza. */
1591             msg_index = curmsg->on_timeout;
1592             recv_timeout = 0;
1593             if (msg_index < (int)call_scenario->messages.size()) return true;
1594             // special case - the label points to the end - finish the call
1595             computeStat(CStat::E_CALL_FAILED);
1596             computeStat(CStat::E_FAILED_TIMEOUT_ON_RECV);
1597             if (default_behaviors & DEFAULT_BEHAVIOR_BYE) {
1598                 return (abortCall(true));
1599             } else {
1600                 delete this;
1601                 return false;
1602             }
1603         } else if (curmsg->timeout || defl_recv_timeout) {
1604             if (curmsg->timeout)
1605                 // If timeout is specified on message receive, use it
1606                 recv_timeout = getmilliseconds() + curmsg->timeout;
1607             else
1608                 // Else use the default timeout if specified
1609                 recv_timeout = getmilliseconds() + defl_recv_timeout;
1610             return true;
1611         } else {
1612             /* We are going to wait forever. */
1613             setPaused();
1614         }
1615     } else {
1616         WARNING("Unknown message type at %s:%d: %d", curmsg->desc, curmsg->index, curmsg->M_type);
1617     }
1618     return true;
1619 }
1620 
run()1621 bool call::run()
1622 {
1623     bool            bInviteTransaction = false;
1624 
1625     assert(running);
1626 
1627     if (zombie) {
1628         delete this;
1629         return false;
1630     }
1631 
1632     getmilliseconds();
1633 
1634     message *curmsg;
1635     if (initCall) {
1636         if(msg_index >= (int)call_scenario->initmessages.size()) {
1637             ERROR("Scenario initialization overrun for call %s (%p) (index = %d)\n", id, _RCAST(void*, this), msg_index);
1638         }
1639         curmsg = call_scenario->initmessages[msg_index];
1640     } else {
1641         if(msg_index >= (int)call_scenario->messages.size()) {
1642             ERROR("Scenario overrun for call %s (%p) (index = %d)\n", id, _RCAST(void*, this), msg_index);
1643         }
1644         curmsg = call_scenario->messages[msg_index];
1645     }
1646 
1647     callDebug("Processing message %d of type %d for call %s at %lu.\n", msg_index, curmsg->M_type, id, clock_tick);
1648 
1649     if (curmsg->condexec != -1) {
1650         bool exec = M_callVariableTable->getVar(curmsg->condexec)->isSet();
1651         if (curmsg->condexec_inverse) {
1652             exec = !exec;
1653         }
1654         if (!exec) {
1655             callDebug("Conditional variable %s %s set, so skipping message %d.\n", call_scenario->allocVars->getName(curmsg->condexec), curmsg->condexec_inverse ? "" : "not", msg_index);
1656             return next();
1657         }
1658     }
1659 
1660     /* Manages retransmissions or delete if max retrans reached */
1661     if(next_retrans && (next_retrans < clock_tick)) {
1662         nb_retrans++;
1663 
1664         if ( (0 == strncmp (last_send_msg, "INVITE", 6)) ) {
1665             bInviteTransaction = true;
1666         }
1667 
1668         int rtAllowed = min(bInviteTransaction ? max_invite_retrans : max_non_invite_retrans, max_udp_retrans);
1669 
1670         callDebug("Retransmisison required (%d retransmissions, max %d)\n", nb_retrans, rtAllowed);
1671 
1672         if(nb_retrans > rtAllowed) {
1673             call_scenario->messages[last_send_index] -> nb_timeout ++;
1674             if (call_scenario->messages[last_send_index]->on_timeout >= 0) {  // action on timeout
1675                 WARNING("Call-Id: %s, timeout on max UDP retrans for message %d, jumping to label %d ",
1676                         id, msg_index, call_scenario->messages[last_send_index]->on_timeout);
1677                 msg_index = call_scenario->messages[last_send_index]->on_timeout;
1678                 next_retrans = 0;
1679                 recv_timeout = 0;
1680                 if (msg_index < (int)call_scenario->messages.size()) {
1681                     return true;
1682                 }
1683 
1684                 // here if asked to go to the last label  delete the call
1685                 computeStat(CStat::E_CALL_FAILED);
1686                 computeStat(CStat::E_FAILED_MAX_UDP_RETRANS);
1687                 if (default_behaviors & DEFAULT_BEHAVIOR_BYE) {
1688                     // Abort the call by sending proper SIP message
1689                     return(abortCall(true));
1690                 } else {
1691                     // Just delete existing call
1692                     delete this;
1693                     return false;
1694                 }
1695             }
1696             computeStat(CStat::E_CALL_FAILED);
1697             computeStat(CStat::E_FAILED_MAX_UDP_RETRANS);
1698             if (default_behaviors & DEFAULT_BEHAVIOR_BYE) {
1699                 // Abort the call by sending proper SIP message
1700                 WARNING("Aborting call on UDP retransmission timeout for Call-ID '%s'", id);
1701                 return(abortCall(true));
1702             } else {
1703                 // Just delete existing call
1704                 delete this;
1705                 return false;
1706             }
1707         } else {
1708             nb_last_delay *= 2;
1709             if (global_t2 < nb_last_delay) {
1710                 if (!bInviteTransaction) {
1711                     nb_last_delay = global_t2;
1712                 }
1713             }
1714             if(send_raw(last_send_msg, last_send_index, last_send_len) < -1) {
1715                 return false;
1716             }
1717             call_scenario->messages[last_send_index] -> nb_sent_retrans++;
1718             computeStat(CStat::E_RETRANSMISSION);
1719             next_retrans = clock_tick + nb_last_delay;
1720         }
1721     }
1722 
1723     if(paused_until) {
1724         /* Process a pending pause instruction until delay expiration */
1725         if(paused_until > clock_tick) {
1726             callDebug("Call is paused until %d (now %ld).\n", paused_until, clock_tick);
1727             setPaused();
1728             callDebug("Running: %d (wake %d).\n", running, wake());
1729             return true;
1730         }
1731         /* Our pause is over. */
1732         callDebug("Pause complete, waking up.\n");
1733         paused_until = 0;
1734         return next();
1735     }
1736     return executeMessage(curmsg);
1737 }
1738 
1739 const char *default_message_names[] = {
1740     "3pcc_abort",
1741     "ack",
1742     "ack2",
1743     "bye",
1744     "cancel",
1745     "200",
1746 };
1747 const char *default_message_strings[] = {
1748     /* 3pcc_abort */
1749     "call-id: [call_id]\ninternal-cmd: abort_call\n\n",
1750     /* ack */
1751     "ACK [last_Request_URI] SIP/2.0\n"
1752     "[last_Via]\n"
1753     "[last_From]\n"
1754     "[last_To]\n"
1755     "Call-ID: [call_id]\n"
1756     "CSeq: [last_cseq_number] ACK\n"
1757     "Contact: <sip:sipp@[local_ip]:[local_port];transport=[transport]>\n"
1758     "Max-Forwards: 70\n"
1759     "Subject: Performance Test\n"
1760     "Content-Length: 0\n\n",
1761     /* ack2, the only difference is Via, I don't quite know why. */
1762     "ACK [last_Request_URI] SIP/2.0\n"
1763     "Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
1764     "[last_From]\n"
1765     "[last_To]\n"
1766     "Call-ID: [call_id]\n"
1767     "CSeq: [last_cseq_number] ACK\n"
1768     "Contact: <sip:sipp@[local_ip]:[local_port];transport=[transport]>\n"
1769     "Max-Forwards: 70\n"
1770     "Subject: Performance Test\n"
1771     "Content-Length: 0\n\n",
1772     /* bye */
1773     "BYE [last_Request_URI] SIP/2.0\n"
1774     "Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
1775     "[last_From]\n"
1776     "[last_To]\n"
1777     "Call-ID: [call_id]\n"
1778     "CSeq: [last_cseq_number+1] BYE\n"
1779     "Max-Forwards: 70\n"
1780     "Contact: <sip:sipp@[local_ip]:[local_port];transport=[transport]>\n"
1781     "Content-Length: 0\n\n",
1782     /* cancel */
1783     "CANCEL [last_Request_URI] SIP/2.0\n"
1784     "[last_Via]\n"
1785     "[last_From]\n"
1786     "[last_To]\n"
1787     "Call-ID: [call_id]\n"
1788     "CSeq: [last_cseq_number] CANCEL\n"
1789     "Max-Forwards: 70\n"
1790     "Contact: <sip:sipp@[local_ip]:[local_port];transport=[transport]>\n"
1791     "Content-Length: 0\n\n",
1792     /* 200 */
1793     "SIP/2.0 200 OK\n"
1794     "[last_Via:]\n"
1795     "[last_From:]\n"
1796     "[last_To:]\n"
1797     "[last_Call-ID:]\n"
1798     "[last_CSeq:]\n"
1799     "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
1800     "Content-Length: 0\n\n"
1801 };
1802 
1803 SendingMessage **default_messages;
1804 
init_default_messages()1805 void init_default_messages()
1806 {
1807     int messages = sizeof(default_message_strings)/sizeof(default_message_strings[0]);
1808     default_messages = new SendingMessage* [messages];
1809     for (int i = 0; i < messages; i++) {
1810         default_messages[i] = new SendingMessage(main_scenario, const_cast<char*>(default_message_strings[i]));
1811     }
1812 }
1813 
free_default_messages()1814 void free_default_messages()
1815 {
1816     int messages = sizeof(default_message_strings)/sizeof(default_message_strings[0]);
1817     if (!default_messages) {
1818         return;
1819     }
1820     for (int i = 0; i < messages; i++) {
1821         delete default_messages[i];
1822     }
1823     delete [] default_messages;
1824 }
1825 
get_default_message(const char * which)1826 SendingMessage *get_default_message(const char *which)
1827 {
1828     int messages = sizeof(default_message_names)/sizeof(default_message_names[0]);
1829     for (int i = 0; i < messages; i++) {
1830         if (!strcmp(which, default_message_names[i])) {
1831             return default_messages[i];
1832         }
1833     }
1834     ERROR("Internal Error: Unknown default message: %s!", which);
1835 }
1836 
set_default_message(const char * which,char * msg)1837 void set_default_message(const char *which, char *msg)
1838 {
1839     int messages = sizeof(default_message_names)/sizeof(default_message_names[0]);
1840     for (int i = 0; i < messages; i++) {
1841         if (!strcmp(which, default_message_names[i])) {
1842             default_message_strings[i] = msg;
1843             return;
1844         }
1845     }
1846     ERROR("Internal Error: Unknown default message: %s!", which);
1847 }
1848 
process_unexpected(char * msg)1849 bool call::process_unexpected(char * msg)
1850 {
1851     char buffer[MAX_HEADER_LEN];
1852     char *desc = buffer;
1853     int res = 0;
1854 
1855     message *curmsg = call_scenario->messages[msg_index];
1856 
1857     curmsg->nb_unexp++;
1858 
1859     if (default_behaviors & DEFAULT_BEHAVIOR_ABORTUNEXP) {
1860         desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "Aborting ");
1861     } else {
1862         desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "Continuing ");
1863     }
1864     desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "call on unexpected message for Call-Id '%s': ", id);
1865 
1866     if (curmsg -> M_type == MSG_TYPE_RECV) {
1867         if (curmsg -> recv_request) {
1868             desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while expecting '%s' ", curmsg -> recv_request);
1869         } else {
1870             desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while expecting '%d' ", curmsg -> recv_response);
1871         }
1872     } else if (curmsg -> M_type == MSG_TYPE_SEND) {
1873         desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while sending ");
1874     } else if (curmsg -> M_type == MSG_TYPE_PAUSE) {
1875         desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while pausing ");
1876     } else if (curmsg -> M_type == MSG_TYPE_SENDCMD) {
1877         desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while sending command ");
1878     } else if (curmsg -> M_type == MSG_TYPE_RECVCMD) {
1879         desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while expecting command ");
1880     } else {
1881         desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while in message type %d ", curmsg->M_type);
1882     }
1883     snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "(index %d)", msg_index);
1884 
1885     WARNING("%s, received '%s'", buffer, msg);
1886 
1887     TRACE_MSG("-----------------------------------------------\n"
1888               "Unexpected %s message received:\n\n%s\n",
1889               TRANSPORT_TO_STRING(transport),
1890               msg);
1891 
1892     callDebug("Unexpected %s message received (index %d, hash %lu):\n\n%s\n",
1893               TRANSPORT_TO_STRING(transport), msg_index, hash(msg), msg);
1894 
1895     if (get_reply_code(msg)) {
1896         this->call_scenario->stats->error_codes.push_back(get_reply_code(msg));
1897     }
1898 
1899     if (default_behaviors & DEFAULT_BEHAVIOR_ABORTUNEXP) {
1900         // if twin socket call => reset the other part here
1901         if (twinSippSocket && (msg_index > 0)) {
1902             res = sendCmdBuffer(createSendingMessage(get_default_message("3pcc_abort"), -1));
1903             if (res < 0) {
1904                 WARNING("sendCmdBuffer returned %d", res);
1905                 return false;
1906             }
1907         }
1908 
1909         // usage of last_ keywords => for call aborting
1910         realloc_ptr = (char *) realloc(last_recv_msg, strlen(msg) + 1);
1911         if (realloc_ptr) {
1912             last_recv_msg = realloc_ptr;
1913         } else {
1914             free(last_recv_msg);
1915             ERROR("Out of memory!");
1916             return false;
1917         }
1918 
1919         strcpy(last_recv_msg, msg);
1920 
1921         computeStat(CStat::E_CALL_FAILED);
1922         computeStat(CStat::E_FAILED_UNEXPECTED_MSG);
1923         if (default_behaviors & DEFAULT_BEHAVIOR_BYE) {
1924             return (abortCall(true));
1925         } else {
1926             delete this;
1927             return false;
1928         }
1929     } else {
1930         // Do not abort call nor send anything in reply if default behavior is disabled
1931         return false;
1932     }
1933 }
1934 
abort()1935 void call::abort()
1936 {
1937     WARNING("Aborted call with Call-ID '%s'", id);
1938     abortCall(false);
1939 }
1940 
abortCall(bool writeLog)1941 bool call::abortCall(bool writeLog)
1942 {
1943     int is_inv;
1944 
1945     char * src_recv = NULL ;
1946 
1947     callDebug("Aborting call %s (index %d).\n", id, msg_index);
1948 
1949     if (last_send_msg != NULL) {
1950         is_inv = !strncmp(last_send_msg, "INVITE", 6);
1951     } else {
1952         is_inv = false;
1953     }
1954     if ((creationMode != MODE_SERVER) && (msg_index > 0)) {
1955         if ((call_established == false) && (is_inv)) {
1956             src_recv = last_recv_msg ;
1957 
1958             // Answer unexpected errors (4XX, 5XX and beyond) with an ACK
1959             // Contributed by F. Tarek Rogers
1960             if((src_recv) && (get_reply_code(src_recv) >= 400)) {
1961                 sendBuffer(createSendingMessage(get_default_message("ack"), -2));
1962             } else if (src_recv) {
1963                 /* Call is not established and the reply is not a 4XX, 5XX */
1964                 /* And we already received a message. */
1965                 if (ack_is_pending == true) {
1966                     /* If an ACK is expected from the other side, send it
1967                      * and send a BYE afterwards                           */
1968                     ack_is_pending = false;
1969                     /* Send an ACK */
1970                     sendBuffer(createSendingMessage(get_default_message("ack"), -1));
1971 
1972                     /* Send the BYE */
1973                     sendBuffer(createSendingMessage(get_default_message("bye"), -1));
1974                 } else {
1975                     /* Send a CANCEL */
1976                     sendBuffer(createSendingMessage(get_default_message("cancel"), -1));
1977                 }
1978             } else {
1979                 /* Call is not established and the reply is not a 4XX, 5XX */
1980                 /* and we didn't received any message. This is the case when */
1981                 /* we are aborting after having send an INVITE and not received */
1982                 /* any answer. */
1983                 /* Do nothing ! */
1984             }
1985         } else if (last_recv_msg) {
1986             /* The call may not be established, if we haven't yet received a message,
1987              * because the earlier check depends on the first message being an INVITE
1988              * (although it could be something like a message message, therefore we
1989              * check that we received a message. */
1990             sendBuffer(createSendingMessage(get_default_message("bye"), -1));
1991         }
1992     }
1993 
1994     if (writeLog && useCallDebugf) {
1995         TRACE_CALLDEBUG ("-------------------------------------------------------------------------------\n");
1996         TRACE_CALLDEBUG ("Call debugging information for call %s:\n", id);
1997         TRACE_CALLDEBUG("%s", debugBuffer);
1998     }
1999 
2000     stopListening();
2001     if (deadcall_wait && !initCall) {
2002         char reason[100];
2003         sprintf(reason, "aborted at index %d", msg_index);
2004         new deadcall(id, reason);
2005     }
2006     delete this;
2007 
2008     return false;
2009 }
2010 
rejectCall()2011 bool call::rejectCall()
2012 {
2013     computeStat(CStat::E_CALL_FAILED);
2014     computeStat(CStat::E_FAILED_CALL_REJECTED);
2015     delete this;
2016     return false;
2017 }
2018 
2019 
sendCmdMessage(message * curmsg)2020 int call::sendCmdMessage(message *curmsg)
2021 {
2022     char * dest;
2023     char delimitor[2];
2024     delimitor[0]=27;
2025     delimitor[1]=0;
2026 
2027     /* 3pcc extended mode */
2028     char * peer_dest;
2029     struct sipp_socket **peer_socket;
2030 
2031     if(curmsg -> M_sendCmdData) {
2032         // WARNING("---PREPARING_TWIN_CMD---%s---", scenario[index] -> M_sendCmdData);
2033         dest = createSendingMessage(curmsg -> M_sendCmdData, -1);
2034         strcat(dest, delimitor);
2035         //WARNING("---SEND_TWIN_CMD---%s---", dest);
2036 
2037         int rc;
2038 
2039         /* 3pcc extended mode */
2040         peer_dest = curmsg->peer_dest;
2041         if(peer_dest) {
2042             peer_socket = get_peer_socket(peer_dest);
2043             rc = write_socket(*peer_socket, dest, strlen(dest), WS_BUFFER, &call_peer);
2044         } else {
2045             rc = write_socket(twinSippSocket, dest, strlen(dest), WS_BUFFER, &call_peer);
2046         }
2047         if(rc <  0) {
2048             computeStat(CStat::E_CALL_FAILED);
2049             computeStat(CStat::E_FAILED_CMD_NOT_SENT);
2050             delete this;
2051             return(-1);
2052         }
2053 
2054         return(0);
2055     } else
2056         return(-1);
2057 }
2058 
2059 
sendCmdBuffer(char * cmd)2060 int call::sendCmdBuffer(char* cmd)
2061 {
2062     char * dest;
2063     char delimitor[2];
2064     int  rc;
2065 
2066     delimitor[0]=27;
2067     delimitor[1]=0;
2068 
2069     dest = cmd ;
2070 
2071     strcat(dest, delimitor);
2072 
2073     rc = write_socket(twinSippSocket, dest, strlen(dest), WS_BUFFER, &twinSippSocket->ss_remote_sockaddr);
2074     if(rc <  0) {
2075         computeStat(CStat::E_CALL_FAILED);
2076         computeStat(CStat::E_FAILED_CMD_NOT_SENT);
2077         delete this;
2078         return(-1);
2079     }
2080 
2081     return(0);
2082 }
2083 
2084 
createSendingMessage(SendingMessage * src,int P_index,int * msgLen)2085 char* call::createSendingMessage(SendingMessage *src, int P_index, int *msgLen)
2086 {
2087     static char msg_buffer[SIPP_MAX_MSG_SIZE+2];
2088     return createSendingMessage(src, P_index, msg_buffer, sizeof(msg_buffer), msgLen);
2089 }
2090 
createSendingMessage(SendingMessage * src,int P_index,char * msg_buffer,int buf_len,int * msgLen)2091 char* call::createSendingMessage(SendingMessage *src, int P_index, char *msg_buffer, int buf_len, int *msgLen)
2092 {
2093     char * length_marker = NULL;
2094     char * auth_marker = NULL;
2095     MessageComponent *auth_comp = NULL;
2096     bool auth_comp_allocated = false;
2097     int    len_offset = 0;
2098     char *dest = msg_buffer;
2099     bool suppresscrlf = false;
2100 
2101     *dest = '\0';
2102 
2103     for (int i = 0; i < src->numComponents(); i++) {
2104         MessageComponent *comp = src->getComponent(i);
2105         int left = buf_len - (dest - msg_buffer);
2106         switch(comp->type) {
2107         case E_Message_Literal:
2108             if (suppresscrlf) {
2109                 char *ptr = comp->literal;
2110                 while (isspace(*ptr)) ptr++;
2111                 dest += snprintf(dest, left, "%s", ptr);
2112                 suppresscrlf = false;
2113             } else {
2114                 memcpy(dest, comp->literal, comp->literalLen);
2115                 dest += comp->literalLen;
2116                 *dest = '\0';
2117             }
2118             break;
2119         case E_Message_Remote_IP:
2120             dest += snprintf(dest, left, "%s", remote_ip_escaped);
2121             break;
2122         case E_Message_Remote_Host:
2123             dest += snprintf(dest, left, "%s", remote_host);
2124             break;
2125         case E_Message_Remote_Port:
2126             dest += snprintf(dest, left, "%d", remote_port + comp->offset);
2127             break;
2128         case E_Message_Local_IP:
2129             dest += snprintf(dest, left, "%s", local_ip_escaped);
2130             break;
2131         case E_Message_Local_Port:
2132             int port;
2133             if((transport == T_UDP) && (multisocket) && (sendMode != MODE_SERVER)) {
2134                 port = call_port;
2135             } else {
2136                 port =  local_port;
2137             }
2138             dest += snprintf(dest, left, "%d", port + comp->offset);
2139             break;
2140         case E_Message_Transport:
2141             dest += snprintf(dest, left, "%s", TRANSPORT_TO_STRING(transport));
2142             break;
2143         case E_Message_Local_IP_Type:
2144             dest += snprintf(dest, left, "%s", (local_ip_is_ipv6 ? "6" : "4"));
2145             break;
2146         case E_Message_Server_IP: {
2147             /* We should do this conversion once per socket creation, rather than
2148              * repeating it every single time. */
2149             struct sockaddr_storage server_sockaddr;
2150 
2151             sipp_socklen_t len = sizeof(server_sockaddr);
2152             getsockname(call_socket->ss_fd,
2153                         (sockaddr *)(void *)&server_sockaddr, &len);
2154 
2155             char address[INET6_ADDRSTRLEN];
2156             if (getnameinfo(_RCAST(sockaddr*, &server_sockaddr), len, address, sizeof(address),
2157                             NULL, 0, NI_NUMERICHOST) < 0) {
2158                 ERROR_NO("Unable to get socket name information");
2159             }
2160 
2161             dest += snprintf(dest, left, "%s", address);
2162         }
2163         break;
2164         case E_Message_Media_IP:
2165             dest += snprintf(dest, left, "%s", media_ip_escaped);
2166             break;
2167         case E_Message_Media_Port:
2168         case E_Message_Auto_Media_Port: {
2169             int port = media_port + comp->offset;
2170             if (comp->type == E_Message_Auto_Media_Port) {
2171                 port = media_port + (4 * (number - 1)) % 10000 + comp->offset;
2172             }
2173 #ifdef PCAPPLAY
2174             char *begin = dest;
2175             while (begin > msg_buffer) {
2176                 if (*begin == '\n') {
2177                     break;
2178                 }
2179                 begin--;
2180             }
2181             if (begin == msg_buffer) {
2182                 ERROR("Can not find beginning of a line for the media port!\n");
2183             }
2184             play_args_t *play_args = NULL;
2185             if (strstr(begin, "audio")) {
2186                 play_args = &play_args_a;
2187             } else if (strstr(begin, "image")) {
2188                 play_args = &play_args_i;
2189             } else if (strstr(begin, "video")) {
2190                 play_args = &play_args_v;
2191             } else {
2192                 ERROR("media_port keyword with no audio or video on the current line (%s)", begin);
2193             }
2194             if (media_ip_is_ipv6) {
2195                 (_RCAST(struct sockaddr_in6 *, &(play_args->from)))->sin6_port = htons(port);
2196             } else {
2197                 (_RCAST(struct sockaddr_in *, &(play_args->from)))->sin_port = htons(port);
2198             }
2199 #endif
2200             dest += sprintf(dest, "%u", port);
2201             break;
2202         }
2203 #ifdef RTP_STREAM
2204       case E_Message_RTPStream_Audio_Port:
2205         {
2206           int temp_audio_port= rtpstream_get_audioport (&rtpstream_callinfo);
2207           if (!temp_audio_port) {
2208             /* Make this a warning instead? */
2209             ERROR("cannot assign a free audio port to this call - using 0 for [rtpstream_audio_port]");
2210           }
2211           dest += snprintf(dest, left, "%d",temp_audio_port);
2212         }
2213         break;
2214       case E_Message_RTPStream_Video_Port:
2215         {
2216           int temp_video_port= rtpstream_get_videoport (&rtpstream_callinfo);
2217           if (!temp_video_port) {
2218             /* Make this a warning instead? */
2219             ERROR("cannot assign a free video port to this call - using 0 for [rtpstream_video_port]");
2220           }
2221           dest += snprintf(dest, left, "%d",temp_video_port);
2222         }
2223         break;
2224 #endif
2225         case E_Message_Media_IP_Type:
2226             dest += snprintf(dest, left, "%s", (media_ip_is_ipv6 ? "6" : "4"));
2227             break;
2228         case E_Message_Call_Number:
2229             dest += snprintf(dest, left, "%u", number);
2230             break;
2231         case E_Message_DynamicId:
2232             dest += snprintf(dest, left, "%u", call::dynamicId);
2233             // increment at each request
2234             dynamicId += stepDynamicId;
2235             if ( this->dynamicId > maxDynamicId ) {
2236                 call::dynamicId = call::startDynamicId;
2237             } ;
2238             break;
2239         case E_Message_Call_ID:
2240             dest += snprintf(dest, left, "%s", id);
2241             break;
2242         case E_Message_CSEQ:
2243             dest += snprintf(dest, left, "%u", cseq + comp->offset);
2244             break;
2245         case E_Message_PID:
2246             dest += snprintf(dest, left, "%d", pid);
2247             break;
2248         case E_Message_Service:
2249             dest += snprintf(dest, left, "%s", service);
2250             break;
2251         case E_Message_Branch:
2252             /* Branch is magic cookie + call number + message index in scenario */
2253             if(P_index == -2) {
2254                 dest += snprintf(dest, left, "z9hG4bK-%u-%u-%d", pid, number, msg_index-1 + comp->offset);
2255             } else {
2256                 dest += snprintf(dest, left, "z9hG4bK-%u-%u-%d", pid, number, P_index + comp->offset);
2257             }
2258             break;
2259         case E_Message_Index:
2260             dest += snprintf(dest, left, "%d", P_index);
2261             break;
2262         case E_Message_Next_Url:
2263             if (next_req_url) {
2264                 dest += sprintf(dest, "%s", next_req_url);
2265             }
2266             break;
2267         case E_Message_Len:
2268             length_marker = dest;
2269             dest += snprintf(dest, left, "     ");
2270             len_offset = comp->offset;
2271             break;
2272         case E_Message_Authentication:
2273             if (auth_marker) {
2274                 ERROR("Only one [authentication] keyword is currently supported!\n");
2275             }
2276             auth_marker = dest;
2277             dest += snprintf(dest, left, "[authentication place holder]");
2278             auth_comp = comp;
2279             break;
2280         case E_Message_Peer_Tag_Param:
2281             if(peer_tag) {
2282                 dest += snprintf(dest, left, ";tag=%s", peer_tag);
2283             }
2284             break;
2285         case E_Message_Routes:
2286             if (dialog_route_set) {
2287                 dest += sprintf(dest, "Route: %s", dialog_route_set);
2288             } else if (*(dest - 1) == '\n') {
2289                 suppresscrlf = true;
2290             }
2291             break;
2292         case E_Message_ClockTick:
2293             dest += snprintf(dest, left, "%lu", clock_tick);
2294             break;
2295         case E_Message_Timestamp:
2296             struct timeval currentTime;
2297             gettimeofday(&currentTime, NULL);
2298             dest += snprintf(dest, left, "%s", CStat::formatTime(&currentTime));
2299             break;
2300         case E_Message_Date:
2301             char buf[256];
2302             time_t t;
2303             struct tm *tm;
2304 
2305             t = time(NULL);
2306             tm = gmtime(&t);
2307 
2308             strftime(buf, 256, "%a, %d %b %Y %T %Z", tm);
2309             dest += snprintf(dest, left, "%s", buf);
2310             break;
2311         case E_Message_Users:
2312             dest += snprintf(dest, left, "%d", users);
2313             break;
2314         case E_Message_UserID:
2315             dest += snprintf(dest, left, "%d", userId);
2316             break;
2317         case E_Message_SippVersion:
2318             /* Drop the initial "v" from the VERSION string for legacy reasons. */
2319             dest += snprintf(dest, left, "%s", (const char*)VERSION + 1);
2320             break;
2321         case E_Message_Variable: {
2322             int varId = comp->varId;
2323             CCallVariable *var = M_callVariableTable->getVar(varId);
2324             if(var->isSet()) {
2325                 if (var->isRegExp()) {
2326                     dest += sprintf(dest, "%s", var->getMatchingValue());
2327                 } else if (var->isDouble()) {
2328                     dest += sprintf(dest, "%lf", var->getDouble());
2329                 } else if (var->isString()) {
2330                     dest += sprintf(dest, "%s", var->getString());
2331                 } else if (var->isBool()) {
2332                     dest += sprintf(dest, "true");
2333                 }
2334             } else if (var->isBool()) {
2335                 dest += sprintf(dest, "false");
2336             }
2337             if (*(dest - 1) == '\n') {
2338                 suppresscrlf = true;
2339             }
2340             break;
2341         }
2342         case E_Message_Fill: {
2343             int varId = comp->varId;
2344             int length = (int) M_callVariableTable->getVar(varId)->getDouble();
2345             if (length < 0) {
2346                 length = 0;
2347             }
2348             char *filltext = comp->literal;
2349             int filllen = strlen(filltext);
2350             if (filllen == 0) {
2351                 ERROR("Internal error: [fill] keyword has zero-length text.");
2352             }
2353             for (int i = 0, j = 0; i < length; i++, j++) {
2354                 *dest++ = filltext[j % filllen];
2355             }
2356             *dest = '\0';
2357             break;
2358         }
2359         case E_Message_File: {
2360             char buffer[MAX_HEADER_LEN];
2361             createSendingMessage(comp->comp_param.filename, -2, buffer, sizeof(buffer));
2362             FILE *f = fopen(buffer, "r");
2363             if (!f) {
2364                 ERROR("Could not open '%s': %s\n", buffer, strerror(errno));
2365             }
2366             int ret;
2367             while ((ret = fread(dest, 1, left, f)) > 0) {
2368                 left -= ret;
2369                 dest += ret;
2370             }
2371             if (ret < 0) {
2372                 ERROR("Error reading '%s': %s\n", buffer, strerror(errno));
2373             }
2374             fclose(f);
2375             break;
2376         }
2377         case E_Message_Injection: {
2378             char *orig_dest = dest;
2379             getFieldFromInputFile(comp->comp_param.field_param.filename, comp->comp_param.field_param.field, comp->comp_param.field_param.line, dest);
2380             /* We are injecting an authentication line. */
2381             if (char *tmp = strstr(orig_dest, "[authentication")) {
2382                 if (auth_marker) {
2383                     ERROR("Only one [authentication] keyword is currently supported!\n");
2384                 }
2385                 auth_marker = tmp;
2386                 auth_comp = (struct MessageComponent *)calloc(1, sizeof(struct MessageComponent));
2387                 if (!auth_comp) {
2388                     ERROR("Out of memory!");
2389                 }
2390                 auth_comp_allocated = true;
2391 
2392                 tmp = strchr(auth_marker, ']');
2393                 char c = *tmp;
2394                 *tmp = '\0';
2395                 SendingMessage::parseAuthenticationKeyword(call_scenario, auth_comp, auth_marker);
2396                 *tmp = c;
2397             }
2398             if (*(dest - 1) == '\n') {
2399                 suppresscrlf = true;
2400             }
2401             break;
2402         }
2403         case E_Message_Last_Header: {
2404             char * last_header = get_last_header(comp->literal);
2405             if(last_header) {
2406                 dest += sprintf(dest, "%s", last_header);
2407             }
2408             if (*(dest - 1) == '\n') {
2409                 suppresscrlf = true;
2410             }
2411             break;
2412         }
2413         case E_Message_Custom: {
2414             dest += comp->comp_param.fxn(this, comp, dest, left);
2415             break;
2416         }
2417         case E_Message_Last_Message:
2418             if(last_recv_msg && strlen(last_recv_msg)) {
2419                 dest += sprintf(dest, "%s", last_recv_msg);
2420             }
2421             break;
2422         case E_Message_Last_Request_URI: {
2423             char * last_request_uri = get_last_request_uri();
2424             dest += sprintf(dest, "%s", last_request_uri);
2425             free(last_request_uri);
2426             break;
2427         }
2428         case E_Message_Last_CSeq_Number: {
2429             int last_cseq = 0;
2430 
2431             char *last_header = get_last_header("CSeq:");
2432             if(last_header) {
2433                 last_header += 5;
2434                 /* Extract the integer value of the field */
2435                 while(isspace(*last_header)) last_header++;
2436                 sscanf(last_header,"%d", &last_cseq);
2437             }
2438             dest += sprintf(dest, "%d", last_cseq + comp->offset);
2439             break;
2440         }
2441         case E_Message_TDM_Map:
2442             if (!use_tdmmap)
2443                 ERROR("[tdmmap] keyword without -tdmmap parameter on command line");
2444             dest += snprintf(dest, left, "%d.%d.%d/%d",
2445                              tdm_map_x+(int((tdm_map_number)/((tdm_map_b+1)*(tdm_map_c+1))))%(tdm_map_a+1),
2446                              tdm_map_h,
2447                              tdm_map_y+(int((tdm_map_number)/(tdm_map_c+1)))%(tdm_map_b+1),
2448                              tdm_map_z+(tdm_map_number)%(tdm_map_c+1)
2449                             );
2450             break;
2451         }
2452     }
2453     /* Need the body for length and auth-int calculation */
2454     char *body;
2455     const char *auth_body = NULL;
2456     if (length_marker || auth_marker) {
2457         body = strstr(msg_buffer, "\r\n\r\n");
2458         if (body) {
2459             auth_body = body;
2460             auth_body += strlen("\r\n\r\n");
2461         }
2462     }
2463     if (!auth_body) {
2464         auth_body = "";
2465     }
2466 
2467     /* Fix up the length. */
2468     if (length_marker) {
2469         if (auth_marker > body) {
2470             ERROR("The authentication keyword should appear in the message header, not the body!");
2471         }
2472 
2473         if (body && dest - body > 4 && dest - body < 100004) {
2474             char tmp = length_marker[5];
2475             sprintf(length_marker, "%5u", (unsigned)(dest - body - 4 + len_offset));
2476             length_marker[5] = tmp;
2477         } else {
2478             // Other cases: Content-Length is 0
2479             sprintf(length_marker, "    0\r\n\r\n");
2480         }
2481     }
2482 
2483     if (msgLen) {
2484         *msgLen = dest - msg_buffer;
2485     }
2486 
2487     /*
2488      * The authentication substitution must be done outside the above
2489      * loop because auth-int will use the body (which must have already
2490      * been keyword substituted) to build the md5 hash
2491      */
2492     if (auth_marker) {
2493         if (!dialog_authentication) {
2494             ERROR("Authentication keyword without dialog_authentication!");
2495         }
2496 
2497         int  auth_marker_len;
2498         char * tmp;
2499         int  authlen;
2500 
2501         auth_marker_len = (strchr(auth_marker, ']') + 1) - auth_marker;
2502 
2503         /* Need the Method name from the CSeq of the Challenge */
2504         char method[MAX_HEADER_LEN];
2505         tmp = get_last_header("CSeq:");
2506         if(!tmp) {
2507             ERROR("Could not extract method from cseq of challenge");
2508         }
2509         tmp += 5;
2510         while(isspace(*tmp) || isdigit(*tmp)) tmp++;
2511         sscanf(tmp,"%s", method);
2512 
2513         /* Determine the type of credentials. */
2514         char result[MAX_HEADER_LEN];
2515         if (dialog_challenge_type == 401) {
2516             /* Registrars use Authorization */
2517             authlen = sprintf(result, "Authorization: ");
2518         } else {
2519             /* Proxies use Proxy-Authorization */
2520             authlen = sprintf(result, "Proxy-Authorization: ");
2521         }
2522 
2523         /* Build the auth credenticals */
2524         char uri[MAX_HEADER_LEN];
2525         sprintf (uri, "%s:%d", remote_ip, remote_port);
2526         /* These cause this function to  not be reentrant. */
2527         static char my_auth_user[MAX_HEADER_LEN + 2];
2528         static char my_auth_pass[MAX_HEADER_LEN + 2];
2529         static char my_aka_OP[MAX_HEADER_LEN + 2];
2530         static char my_aka_AMF[MAX_HEADER_LEN + 2];
2531         static char my_aka_K[MAX_HEADER_LEN + 2];
2532 
2533         createSendingMessage(auth_comp->comp_param.auth_param.auth_user, -2, my_auth_user, sizeof(my_auth_user));
2534         createSendingMessage(auth_comp->comp_param.auth_param.auth_pass, -2, my_auth_pass, sizeof(my_auth_pass));
2535         createSendingMessage(auth_comp->comp_param.auth_param.aka_K, -2, my_aka_K, sizeof(my_aka_K));
2536         createSendingMessage(auth_comp->comp_param.auth_param.aka_AMF, -2, my_aka_AMF, sizeof(my_aka_AMF));
2537         createSendingMessage(auth_comp->comp_param.auth_param.aka_OP, -2, my_aka_OP, sizeof(my_aka_OP));
2538 
2539         if (createAuthHeader(my_auth_user, my_auth_pass, method, uri, auth_body, dialog_authentication,
2540                              my_aka_OP, my_aka_AMF, my_aka_K, result + authlen) == 0) {
2541             ERROR("%s", result + authlen);
2542         }
2543         authlen = strlen(result);
2544 
2545         /* Shift the end of the message to its rightful place. */
2546         memmove(auth_marker + authlen, auth_marker + auth_marker_len, strlen(auth_marker + auth_marker_len) + 1);
2547         /* Copy our result into the hole. */
2548         memcpy(auth_marker, result, authlen);
2549         if (msgLen) {
2550             *msgLen += (authlen -  auth_marker_len);
2551         }
2552     }
2553 
2554     if (auth_comp_allocated) {
2555         SendingMessage::freeMessageComponent(auth_comp);
2556     }
2557 
2558     return msg_buffer;
2559 }
2560 
process_twinSippCom(char * msg)2561 bool call::process_twinSippCom(char * msg)
2562 {
2563     int             search_index;
2564     bool            found = false;
2565     T_ActionResult  actionResult;
2566 
2567     callDebug("Processing incoming command for call-ID %s:\n%s\n\n", id, msg);
2568 
2569     setRunning();
2570 
2571     if (checkInternalCmd(msg) == false) {
2572 
2573         for(search_index = msg_index;
2574                 search_index < (int)call_scenario->messages.size();
2575                 search_index++) {
2576             if(call_scenario->messages[search_index] -> M_type != MSG_TYPE_RECVCMD) {
2577                 if ((call_scenario->messages[search_index] -> optional) ||
2578                     (call_scenario->messages[search_index] -> M_type == MSG_TYPE_NOP)) {
2579                     continue;
2580                 }
2581                 /* The received message is different from the expected one */
2582                 TRACE_MSG("Unexpected control message received (I was expecting a different type of message):\n%s\n", msg);
2583                 callDebug("Unexpected control message received (I was expecting a different type of message):\n%s\n\n", msg);
2584                 return rejectCall();
2585             } else {
2586                 if(extendedTwinSippMode) {                  // 3pcc extended mode
2587                     if(check_peer_src(msg, search_index)) {
2588                         found = true;
2589                         break;
2590                     } else {
2591                         WARNING("Unexpected sender for the received peer message \n%s\n", msg);
2592                         return rejectCall();
2593                     }
2594                 } else {
2595                     found = true;
2596                     break;
2597                 }
2598             }
2599         }
2600 
2601         if (found) {
2602             call_scenario->messages[search_index]->M_nbCmdRecv ++;
2603             do_bookkeeping(call_scenario->messages[search_index]);
2604 
2605             // variable treatment
2606             // Remove \r, \n at the end of a received command
2607             // (necessary for transport, to be removed for usage)
2608             while ( (msg[strlen(msg)-1] == '\n') &&
2609                     (msg[strlen(msg)-2] == '\r') ) {
2610                 msg[strlen(msg)-2] = 0;
2611             }
2612             actionResult = executeAction(msg, call_scenario->messages[search_index]);
2613 
2614             if(actionResult != call::E_AR_NO_ERROR) {
2615                 // Store last action result if it is an error
2616                 // and go on with the scenario
2617                 call::last_action_result = actionResult;
2618                 if (actionResult == E_AR_STOP_CALL) {
2619                     return rejectCall();
2620                 } else if (actionResult == E_AR_CONNECT_FAILED) {
2621                     terminate(CStat::E_FAILED_TCP_CONNECT);
2622                     return false;
2623                 }
2624             }
2625         } else {
2626             TRACE_MSG("Unexpected control message received (no such message found):\n%s\n", msg);
2627             callDebug("Unexpected control message received (no such message found):\n%s\n\n", msg);
2628             return rejectCall();
2629         }
2630         msg_index = search_index; //update the state machine
2631         return(next());
2632     } else {
2633         return (false);
2634     }
2635 }
2636 
checkInternalCmd(char * cmd)2637 bool call::checkInternalCmd(char * cmd)
2638 {
2639 
2640     char * L_ptr1, * L_ptr2, L_backup;
2641 
2642     L_ptr1 = strstr(cmd, "internal-cmd:");
2643     if (!L_ptr1) {
2644         return (false);
2645     }
2646     L_ptr1 += 13 ;
2647     while((*L_ptr1 == ' ') || (*L_ptr1 == '\t')) {
2648         L_ptr1++;
2649     }
2650     if (!(*L_ptr1)) {
2651         return (false);
2652     }
2653     L_ptr2 = L_ptr1;
2654     while((*L_ptr2) &&
2655             (*L_ptr2 != ' ') &&
2656             (*L_ptr2 != '\t') &&
2657             (*L_ptr2 != '\r') &&
2658             (*L_ptr2 != '\n')) {
2659         L_ptr2 ++;
2660     }
2661     if(!*L_ptr2) {
2662         return (false);
2663     }
2664     L_backup = *L_ptr2;
2665     *L_ptr2 = 0;
2666 
2667     if (strcmp(L_ptr1, "abort_call") == 0) {
2668         *L_ptr2 = L_backup;
2669         computeStat(CStat::E_CALL_FAILED);
2670         abortCall(true);
2671         return (true);
2672     }
2673 
2674     *L_ptr2 = L_backup;
2675     return (false);
2676 }
2677 
check_peer_src(char * msg,int search_index)2678 bool call::check_peer_src(char * msg, int search_index)
2679 {
2680     char * L_ptr1, * L_ptr2, L_backup ;
2681 
2682     L_ptr1 = strstr(msg, "From:");
2683     if (!L_ptr1) {
2684         return (false);
2685     }
2686     L_ptr1 += 5 ;
2687     while((*L_ptr1 == ' ') || (*L_ptr1 == '\t')) {
2688         L_ptr1++;
2689     }
2690     if (!(*L_ptr1)) {
2691         return (false);
2692     }
2693     L_ptr2 = L_ptr1;
2694     while((*L_ptr2) &&
2695             (*L_ptr2 != ' ') &&
2696             (*L_ptr2 != '\t') &&
2697             (*L_ptr2 != '\r') &&
2698             (*L_ptr2 != '\n')) {
2699         L_ptr2 ++;
2700     }
2701     if(!*L_ptr2) {
2702         return (false);
2703     }
2704     L_backup = *L_ptr2;
2705     *L_ptr2 = 0;
2706     if (strcmp(L_ptr1, call_scenario->messages[search_index] -> peer_src) == 0) {
2707         *L_ptr2 = L_backup;
2708         return(true);
2709     }
2710 
2711     *L_ptr2 = L_backup;
2712     return (false);
2713 }
2714 
2715 
extract_cseq_method(char * method,char * msg)2716 void call::extract_cseq_method (char* method, char* msg)
2717 {
2718     char* cseq ;
2719     if ((cseq = strstr (msg, "CSeq"))) {
2720         char * value ;
2721         if (( value = strchr (cseq,  ':'))) {
2722             value++;
2723             while ( isspace(*value)) value++;  // ignore any white spaces after the :
2724             while ( !isspace(*value)) value++;  // ignore the CSEQ number
2725             while ( isspace(*value)) value++;  // ignore spaces after CSEQ number
2726             char *end = value;
2727             int nbytes = 0;
2728             /* A '\r' terminates the line, so we want to catch that too. */
2729             while ((*end != '\r') && (*end != '\n')) {
2730                 end++;
2731                 nbytes++;
2732             }
2733             if (nbytes > 0) strncpy (method, value, nbytes);
2734             method[nbytes] = '\0';
2735         }
2736     }
2737 }
2738 
extract_transaction(char * txn,char * msg)2739 void call::extract_transaction (char* txn, char* msg)
2740 {
2741     char *via = get_header_content(msg, "via:");
2742     if (!via) {
2743         txn[0] = '\0';
2744         return;
2745     }
2746 
2747     char *branch = strstr(via, ";branch=");
2748     if (!branch) {
2749         txn[0] = '\0';
2750         return;
2751     }
2752 
2753     branch += strlen(";branch=");
2754     while (*branch && *branch != ';' && *branch != ',' && !isspace(*branch)) {
2755         *txn++ = *branch++;
2756     }
2757     *txn = '\0';
2758 }
2759 
formatNextReqUrl(char * next_req_url)2760 void call::formatNextReqUrl (char* next_req_url)
2761 {
2762 
2763     /* clean up the next_req_url -- Record routes may have extra gunk
2764        that needs to be removed
2765      */
2766     char* actual_req_url = strchr(next_req_url, '<');
2767     if (actual_req_url) {
2768         /* using a temporary buffer */
2769         char tempBuffer[MAX_HEADER_LEN];
2770         strncpy(tempBuffer, actual_req_url + 1, sizeof(tempBuffer) - 1);
2771         actual_req_url = strrchr(tempBuffer, '>');
2772         *actual_req_url = '\0';
2773         strcpy(next_req_url, tempBuffer);
2774     }
2775 
2776 }
2777 
computeRouteSetAndRemoteTargetUri(char * rr,char * contact,bool bRequestIncoming)2778 void call::computeRouteSetAndRemoteTargetUri (char* rr, char* contact, bool bRequestIncoming)
2779 {
2780     if (0 >=strlen (rr)) {
2781         //
2782         // there are no RR headers. Simply set up the contact as our target uri
2783         //
2784         if (0 < strlen(contact)) {
2785             strcpy (next_req_url, contact);
2786         }
2787 
2788         formatNextReqUrl(next_req_url);
2789 
2790         return;
2791     }
2792 
2793     char actual_rr[MAX_HEADER_LEN];
2794     char targetURI[MAX_HEADER_LEN];
2795     memset(actual_rr, 0, sizeof(actual_rr));
2796 
2797     bool isFirst = true;
2798     bool bCopyContactToRR = false;
2799 
2800     while (1) {
2801         char* pointer = NULL;
2802         if (bRequestIncoming) {
2803             pointer = strchr (rr, ',');
2804         } else {
2805             pointer = strrchr(rr, ',');
2806         }
2807 
2808         if (pointer) {
2809             if (!isFirst) {
2810                 if (strlen(actual_rr) ) {
2811                     strcat(actual_rr, pointer + 1);
2812                 } else {
2813                     strcpy(actual_rr, pointer + 1);
2814                 }
2815                 strcat(actual_rr, ",");
2816             } else {
2817                 isFirst = false;
2818                 if (NULL == strstr (pointer, ";lr")) {
2819                     /* bottom most RR is the next_req_url */
2820                     strncpy(targetURI, pointer + 1, sizeof(targetURI) - 1);
2821                     bCopyContactToRR = true;
2822                 } else {
2823                     /* the hop is a loose router. Thus, the target URI should be the
2824                      * contact
2825                      */
2826                     strcpy (targetURI, contact);
2827                     strcpy(actual_rr, pointer + 1);
2828                     strcat(actual_rr, ",");
2829                 }
2830             }
2831         } else {
2832             if (!isFirst) {
2833                 strcat(actual_rr, rr);
2834             }
2835             //
2836             // this is the *only* RR header that was found
2837             //
2838             else {
2839                 if (NULL == strstr (rr, ";lr")) {
2840                     /* bottom most RR is the next_req_url */
2841                     strcpy (targetURI, rr);
2842                     bCopyContactToRR = true;
2843                 } else {
2844                     /* the hop is a loose router. Thus, the target URI should be the
2845                      * contact
2846                      */
2847                     strcpy (actual_rr, rr);
2848                     strcpy (targetURI, contact);
2849                 }
2850             }
2851             break;
2852         }
2853         *pointer = '\0';
2854     }
2855 
2856     if (bCopyContactToRR) {
2857         if (0 < strlen (actual_rr)) {
2858             strcat(actual_rr, ",");
2859             strcat(actual_rr, contact);
2860         } else {
2861             strcpy(actual_rr, contact);
2862         }
2863     }
2864 
2865     if (strlen(actual_rr)) {
2866         dialog_route_set = (char *)
2867                            calloc(1, strlen(actual_rr) + 2);
2868         sprintf(dialog_route_set, "%s", actual_rr);
2869     }
2870 
2871     if (strlen (targetURI)) {
2872         strcpy (next_req_url, targetURI);
2873         formatNextReqUrl (next_req_url);
2874     }
2875 }
2876 
matches_scenario(unsigned int index,int reply_code,char * request,char * responsecseqmethod,char * txn)2877 bool call::matches_scenario(unsigned int index, int reply_code, char * request, char * responsecseqmethod, char *txn)
2878 {
2879     message *curmsg = call_scenario->messages[index];
2880 
2881     if ((curmsg -> recv_request)) {
2882         if (curmsg->regexp_match) {
2883             if (curmsg -> regexp_compile == NULL) {
2884                 regex_t *re = new regex_t;
2885                 if (regcomp(re, curmsg -> recv_request, REG_EXTENDED|REG_NOSUB)) {
2886                     ERROR("Invalid regular expression for index %d: %s", index, curmsg->recv_request);
2887                 }
2888                 curmsg -> regexp_compile = re;
2889             }
2890             return !regexec(curmsg -> regexp_compile, request, (size_t)0, NULL, 0);
2891         } else {
2892             return !strcmp(curmsg -> recv_request, request);
2893         }
2894     } else if (curmsg->recv_response && (curmsg->recv_response == reply_code)) {
2895         /* This is a potential candidate, we need to match transactions. */
2896         if (curmsg->response_txn) {
2897             if (transactions[curmsg->response_txn - 1].txnID && !strcmp(transactions[curmsg->response_txn - 1].txnID, txn)) {
2898                 return true;
2899             } else {
2900                 return false;
2901             }
2902         } else if (index == 0) {
2903             /* Always true for the first message. */
2904             return true;
2905         } else if (curmsg->recv_response_for_cseq_method_list &&
2906                    strstr(curmsg->recv_response_for_cseq_method_list, responsecseqmethod)) {
2907             /* If we do not have a transaction defined, we just check the CSEQ method. */
2908             return true;
2909         } else {
2910             return false;
2911         }
2912     }
2913 
2914     return false;
2915 }
2916 
queue_up(char * msg)2917 void call::queue_up(char *msg)
2918 {
2919     free(queued_msg);
2920     queued_msg = strdup(msg);
2921 }
2922 
process_incoming(char * msg,struct sockaddr_storage * src)2923 bool call::process_incoming(char * msg, struct sockaddr_storage *src)
2924 {
2925     int             reply_code;
2926     static char     request[65];
2927     char            responsecseqmethod[65];
2928     char            txn[MAX_HEADER_LEN];
2929     unsigned long   cookie = 0;
2930     char          * ptr;
2931     int             search_index;
2932     bool            found = false;
2933     T_ActionResult  actionResult;
2934 
2935     getmilliseconds();
2936     callDebug("Processing %zu byte incoming message for call-ID %s (hash %lu):\n%s\n\n",
2937               strlen(msg), id, hash(msg), msg);
2938 
2939     setRunning();
2940 
2941     /* Ignore the messages received during a pause if -pause_msg_ign is set */
2942     if(call_scenario->messages[msg_index] -> M_type == MSG_TYPE_PAUSE && pause_msg_ign) return(true);
2943 
2944     /* Get our destination if we have none. */
2945     if (call_peer.ss_family == AF_UNSPEC && src) {
2946         memcpy(&call_peer, src, SOCK_ADDR_SIZE(src));
2947     }
2948 
2949     /* Authorize nop as a first command, even in server mode */
2950     if((msg_index == 0) && (call_scenario->messages[msg_index] -> M_type == MSG_TYPE_NOP)) {
2951         queue_up (msg);
2952         paused_until = 0;
2953         return run();
2954     }
2955     responsecseqmethod[0] = '\0';
2956     txn[0] = '\0';
2957 
2958     /* Check that we have a To:-header */
2959     if (!get_header(msg, "To:", false)[0] && !process_unexpected(msg)) {
2960         return false;
2961     }
2962 
2963     if ((transport == T_UDP) && (retrans_enabled)) {
2964         /* Detects retransmissions from peer and retransmit the
2965          * message which was sent just after this one was received */
2966         cookie = hash(msg);
2967         if((recv_retrans_recv_index >= 0) && (recv_retrans_hash == cookie)) {
2968 
2969             int status;
2970 
2971             if(lost(recv_retrans_recv_index)) {
2972                 TRACE_MSG("%s message (retrans) lost (recv).",
2973                           TRANSPORT_TO_STRING(transport));
2974                 callDebug("%s message (retrans) lost (recv) (hash %lu)\n", TRANSPORT_TO_STRING(transport), hash(msg));
2975 
2976                 if(comp_state) {
2977                     comp_free(&comp_state);
2978                 }
2979                 call_scenario->messages[recv_retrans_recv_index] -> nb_lost++;
2980                 return true;
2981             }
2982 
2983             call_scenario->messages[recv_retrans_recv_index] -> nb_recv_retrans++;
2984 
2985             send_scene(recv_retrans_send_index, &status, NULL);
2986 
2987             if(status >= 0) {
2988                 call_scenario->messages[recv_retrans_send_index] -> nb_sent_retrans++;
2989                 computeStat(CStat::E_RETRANSMISSION);
2990             } else if(status < 0) {
2991                 return false;
2992             }
2993 
2994             return true;
2995         }
2996 
2997         if((last_recv_index >= 0) && (last_recv_hash == cookie)) {
2998             /* This one has already been received, but not processed
2999              * yet => (has not triggered something yet) so we can discard.
3000              *
3001              * This case appears when the UAS has send a 200 but not received
3002              * a ACK yet. Thus, the UAS retransmit the 200 (invite transaction)
3003              * until it receives a ACK. In this case, it nevers sends the 200
3004              * from the  BYE, until it has reveiced the previous 200. Thus,
3005              * the UAC retransmit the BYE, and this BYE is considered as an
3006              * unexpected.
3007              *
3008              * This case can also appear in case of message duplication by
3009              * the network. This should not be considered as an unexpected.
3010              */
3011             call_scenario->messages[last_recv_index]->nb_recv_retrans++;
3012             return true;
3013         }
3014     }
3015 
3016 #ifdef RTP_STREAM
3017   /* Check if message has a SDP in it; and extract media information. */
3018   if (!strcmp(get_header_content(msg, (char*)"Content-Type:"),"application/sdp") &&
3019           (hasMedia == 1)) {
3020     extract_rtp_remote_addr(msg);
3021   }
3022 #endif
3023 
3024     /* Is it a response ? */
3025     if((msg[0] == 'S') &&
3026             (msg[1] == 'I') &&
3027             (msg[2] == 'P') &&
3028             (msg[3] == '/') &&
3029             (msg[4] == '2') &&
3030             (msg[5] == '.') &&
3031             (msg[6] == '0')    ) {
3032 
3033         reply_code = get_reply_code(msg);
3034         if(!reply_code) {
3035             if (!process_unexpected(msg)) {
3036                 return false; // Call aborted by unexpected message handling
3037             }
3038 #ifdef PCAPPLAY
3039         } else if ((hasMedia == 1) && *(strstr(msg, "\r\n\r\n")+4) != '\0') {
3040             /* Get media info if we find something like an SDP */
3041             get_remote_media_addr(msg);
3042 #endif
3043         }
3044         /* It is a response: update peer_tag */
3045         ptr = get_peer_tag(msg);
3046         if (ptr) {
3047             if(strlen(ptr) > (MAX_HEADER_LEN - 1)) {
3048                 ERROR("Peer tag too long. Change MAX_HEADER_LEN and recompile sipp");
3049             }
3050             if(peer_tag) {
3051                 free(peer_tag);
3052             }
3053             peer_tag = strdup(ptr);
3054             if (!peer_tag) {
3055                 ERROR("Out of memory allocating peer tag.");
3056             }
3057         }
3058         request[0]=0;
3059         // extract the cseq method from the response
3060         extract_cseq_method (responsecseqmethod, msg);
3061         extract_transaction (txn, msg);
3062     } else if((ptr = strchr(msg, ' '))) {
3063         if((ptr - msg) < 64) {
3064             memcpy(request, msg, ptr - msg);
3065             request[ptr - msg] = 0;
3066             // Check if we received an ACK => call established
3067             if (strcmp(request,"ACK")==0) {
3068                 call_established=true;
3069             }
3070 #ifdef PCAPPLAY
3071             /* In case of INVITE or re-INVITE, ACK or PRACK
3072                get the media info if needed (= we got a pcap
3073                play action) */
3074             if (((strncmp(request, "INVITE", 6) == 0)
3075                     || (strncmp(request, "ACK", 3) == 0)
3076                     || (strncmp(request, "PRACK", 5) == 0))
3077                     && (hasMedia == 1))
3078                 get_remote_media_addr(msg);
3079 #endif
3080 
3081             reply_code = 0;
3082         } else {
3083             ERROR("SIP method too long in received message '%s'",
3084                   msg);
3085         }
3086     } else {
3087         ERROR("Invalid sip message received '%s'",
3088               msg);
3089     }
3090 
3091     /* Try to find it in the expected non mandatory responses
3092      * until the first mandatory response  in the scenario */
3093     for(search_index = msg_index;
3094             search_index < (int)call_scenario->messages.size();
3095             search_index++) {
3096         if(!matches_scenario(search_index, reply_code, request, responsecseqmethod, txn)) {
3097             if(call_scenario->messages[search_index] -> optional) {
3098                 continue;
3099             }
3100             /* The received message is different for the expected one */
3101             break;
3102         }
3103 
3104         found = true;
3105         /* TODO : this is a little buggy: If a 100 trying from an INVITE
3106          * is delayed by the network until the BYE is sent, it may
3107          * stop BYE transmission erroneously, if the BYE also expects
3108          * a 100 trying. */
3109         break;
3110     }
3111 
3112     /* Try to find it in the old non-mandatory receptions */
3113     if(!found) {
3114         bool contig = true;
3115         for(search_index = msg_index - 1;
3116                 search_index >= 0;
3117                 search_index--) {
3118             if (call_scenario->messages[search_index]->optional == OPTIONAL_FALSE) contig = false;
3119             if(matches_scenario(search_index, reply_code, request, responsecseqmethod, txn)) {
3120                 if (contig || call_scenario->messages[search_index]->optional == OPTIONAL_GLOBAL) {
3121                     found = true;
3122                     break;
3123                 } else {
3124                     if (int checkTxn = call_scenario->messages[search_index]->response_txn) {
3125                         /* This is a reply to an old transaction. */
3126                         if (!strcmp(transactions[checkTxn - 1].txnID, txn)) {
3127                             /* This reply is provisional, so it should have no effect if we recieve it out-of-order. */
3128                             if (reply_code >= 100 && reply_code <= 199) {
3129                                 TRACE_MSG("-----------------------------------------------\n"
3130                                           "Ignoring provisional %s message for transaction %s:\n\n%s\n",
3131                                           TRANSPORT_TO_STRING(transport), call_scenario->transactions[checkTxn - 1].name, msg);
3132                                 callDebug("Ignoring provisional %s message for transaction %s (hash %lu):\n\n%s\n",
3133                                           TRANSPORT_TO_STRING(transport), call_scenario->transactions[checkTxn - 1].name, hash(msg), msg);
3134                                 return true;
3135                             } else if (int ackIndex = transactions[checkTxn - 1].ackIndex) {
3136                                 /* This is the message before an ACK, so verify that this is an invite transaction. */
3137                                 assert (call_scenario->transactions[checkTxn - 1].isInvite);
3138                                 sendBuffer(createSendingMessage(call_scenario->messages[ackIndex] -> send_scheme, ackIndex));
3139                                 return true;
3140                             } else {
3141                                 assert (!call_scenario->transactions[checkTxn - 1].isInvite);
3142                                 /* This is a non-provisional message for the transaction, and
3143                                  * we have already gotten our allowable response.  Just make sure
3144                                  * that it is not a retransmission of the final response. */
3145                                 if (transactions[checkTxn - 1].txnResp == hash(msg)) {
3146                                     /* We have gotten this retransmission out-of-order, let's just ignore it. */
3147                                     TRACE_MSG("-----------------------------------------------\n"
3148                                               "Ignoring final %s message for transaction %s:\n\n%s\n",
3149                                               TRANSPORT_TO_STRING(transport), call_scenario->transactions[checkTxn - 1].name, msg);
3150                                     callDebug("Ignoring final %s message for transaction %s (hash %lu):\n\n%s\n",
3151                                               TRANSPORT_TO_STRING(transport), call_scenario->transactions[checkTxn - 1].name, hash(msg), msg);
3152                                     WARNING("Ignoring final %s message for transaction %s (hash %lu):\n\n%s\n",
3153                                             TRANSPORT_TO_STRING(transport), call_scenario->transactions[checkTxn - 1].name, hash(msg), msg);
3154                                     return true;
3155                                 }
3156                             }
3157                         }
3158                     } else {
3159                         /*
3160                          * we received a non mandatory msg for an old transaction (this could be due to a retransmit.
3161                          * If this response is for an INVITE transaction, retransmit the ACK to quench retransmits.
3162                          */
3163                         if ( (reply_code) &&
3164                                 (0 == strncmp (responsecseqmethod, "INVITE", strlen(responsecseqmethod)) ) &&
3165                                 (call_scenario->messages[search_index+1]->M_type == MSG_TYPE_SEND) &&
3166                                 (call_scenario->messages[search_index+1]->send_scheme->isAck()) ) {
3167                             sendBuffer(createSendingMessage(call_scenario->messages[search_index+1] -> send_scheme, (search_index+1)));
3168                             return true;
3169                         }
3170                     }
3171                 }
3172             }
3173         }
3174     }
3175 
3176     /* If it is still not found, process an unexpected message */
3177     if(!found) {
3178         if (call_scenario->unexpected_jump >= 0) {
3179             bool recursive = false;
3180             if (call_scenario->retaddr >= 0) {
3181                 if (M_callVariableTable->getVar(call_scenario->retaddr)->getDouble() != 0) {
3182                     /* We are already in a jump! */
3183                     recursive = true;
3184                 } else {
3185                     M_callVariableTable->getVar(call_scenario->retaddr)->setDouble(msg_index);
3186                 }
3187             }
3188             if (!recursive) {
3189                 if (call_scenario->pausedaddr >= 0) {
3190                     M_callVariableTable->getVar(call_scenario->pausedaddr)->setDouble(paused_until);
3191                 }
3192                 msg_index = call_scenario->unexpected_jump;
3193                 queue_up(msg);
3194                 paused_until = 0;
3195                 return run();
3196             } else {
3197                 if (!process_unexpected(msg)) {
3198                     return false; // Call aborted by unexpected message handling
3199                 }
3200             }
3201         } else {
3202             T_AutoMode L_case;
3203             if ((L_case = checkAutomaticResponseMode(request)) == 0) {
3204                 if (!process_unexpected(msg)) {
3205                     return false; // Call aborted by unexpected message handling
3206                 }
3207             } else {
3208                 // call aborted by automatic response mode if needed
3209                 return automaticResponseMode(L_case, msg);
3210             }
3211         }
3212     }
3213 
3214     int test = (!found) ? -1 : call_scenario->messages[search_index]->test;
3215     /* test==0: No branching"
3216      * test==-1 branching without testing"
3217      * test>0   branching with testing
3218      */
3219 
3220     /* Simulate loss of messages */
3221     if(lost(search_index)) {
3222         TRACE_MSG("%s message lost (recv).",
3223                   TRANSPORT_TO_STRING(transport));
3224         callDebug("%s message lost (recv) (hash %lu).\n",
3225                   TRANSPORT_TO_STRING(transport), hash(msg));
3226         if(comp_state) {
3227             comp_free(&comp_state);
3228         }
3229         call_scenario->messages[search_index] -> nb_lost++;
3230         return true;
3231     }
3232 
3233     /* If we are part of a transaction, mark this as the final response. */
3234     if (int checkTxn = call_scenario->messages[search_index]->response_txn) {
3235         transactions[checkTxn - 1].txnResp = hash(msg);
3236     }
3237 
3238 
3239     /* Handle counters and RTDs for this message. */
3240     do_bookkeeping(call_scenario->messages[search_index]);
3241 
3242     /* Increment the recv counter */
3243     call_scenario->messages[search_index] -> nb_recv++;
3244 
3245     // Action treatment
3246     if (found) {
3247         //WARNING("---EXECUTE_ACTION_ON_MSG---%s---", msg);
3248 
3249         actionResult = executeAction(msg, call_scenario->messages[search_index]);
3250 
3251         if(actionResult != call::E_AR_NO_ERROR) {
3252             // Store last action result if it is an error
3253             // and go on with the scenario
3254             call::last_action_result = actionResult;
3255             if (actionResult == E_AR_STOP_CALL) {
3256                 return rejectCall();
3257             } else if (actionResult == E_AR_CONNECT_FAILED) {
3258                 terminate(CStat::E_FAILED_TCP_CONNECT);
3259                 return false;
3260             }
3261         }
3262     }
3263 
3264     if (*request) { // update [cseq] with received CSeq
3265         unsigned long int rcseq = get_cseq_value(msg);
3266         if (rcseq > cseq) cseq = rcseq;
3267     }
3268 
3269     /* This is an ACK/PRACK or a response, and its index is greater than the
3270      * current active retransmission message, so we stop the retrans timer.
3271      * True also for CANCEL and BYE that we also want to answer to */
3272     if(((reply_code) ||
3273             ((!strcmp(request, "ACK")) ||
3274              (!strcmp(request, "CANCEL")) || (!strcmp(request, "BYE")) ||
3275              (!strcmp(request, "PRACK"))))  &&
3276             (search_index > last_send_index)) {
3277         /*
3278          * We should stop any retransmission timers on receipt of a provisional response only for INVITE
3279          * transactions. Non INVITE transactions continue to retransmit at T2 until a final response is
3280          * received
3281          */
3282         if ( (0 == reply_code) || // means this is a request.
3283                 (200 <= reply_code) ||  // final response
3284                 ((0 != reply_code) && (0 == strncmp (responsecseqmethod, "INVITE", strlen(responsecseqmethod)))) ) { // prov for INVITE
3285             next_retrans = 0;
3286         } else {
3287             /*
3288              * We are here due to a provisional response for non INVITE. Update our next retransmit.
3289              */
3290             next_retrans = clock_tick + global_t2;
3291             nb_last_delay = global_t2;
3292 
3293         }
3294     }
3295 
3296     /* This is a response with 200 so set the flag indicating that an
3297      * ACK is pending (used to prevent from release a call with CANCEL
3298      * when an ACK+BYE should be sent instead)                         */
3299     if (reply_code == 200) {
3300         ack_is_pending = true;
3301     }
3302 
3303     /* store the route set only once. TODO: does not support target refreshes!! */
3304     if (call_scenario->messages[search_index] -> bShouldRecordRoutes &&
3305             NULL == dialog_route_set ) {
3306 
3307         realloc_ptr = (char*) realloc(next_req_url, MAX_HEADER_LEN);
3308         if (realloc_ptr) {
3309             next_req_url = realloc_ptr;
3310         } else {
3311             free(next_req_url);
3312             ERROR("Out of memory!");
3313             return false;
3314         }
3315 
3316 
3317         char rr[MAX_HEADER_LEN];
3318         memset(rr, 0, sizeof(rr));
3319         strncpy(rr, get_header_content(msg, (char*)"Record-Route:"), sizeof(rr) - 1);
3320 
3321         // WARNING("rr [%s]", rr);
3322         char ch[MAX_HEADER_LEN];
3323         strncpy(ch, get_header_content(msg, (char*)"Contact:"), sizeof(rr) - 1);
3324 
3325         /* decorate the contact with '<' and '>' if it does not have it */
3326         char* contDecorator = strchr(ch, '<');
3327         if (NULL == contDecorator) {
3328             char tempBuffer[MAX_HEADER_LEN];
3329             sprintf(tempBuffer, "<%s>", ch);
3330             strcpy(ch, tempBuffer);
3331         }
3332 
3333         /* should cache the route set */
3334         if (reply_code) {
3335             computeRouteSetAndRemoteTargetUri (rr, ch, false);
3336         } else {
3337             computeRouteSetAndRemoteTargetUri (rr, ch, true);
3338         }
3339         // WARNING("next_req_url is [%s]", next_req_url);
3340     }
3341 
3342     /* store the authentication info */
3343     if ((call_scenario->messages[search_index] -> bShouldAuthenticate) &&
3344             (reply_code == 401 || reply_code == 407)) {
3345 
3346         /* is a challenge */
3347         char auth[MAX_HEADER_LEN];
3348         memset(auth, 0, sizeof(auth));
3349         strncpy(auth, get_header_content(msg, (char*)"Proxy-Authenticate:"), sizeof(auth) - 1);
3350         if (auth[0] == 0) {
3351             strncpy(auth, get_header_content(msg, (char*)"WWW-Authenticate:"), sizeof(auth) - 1);
3352         }
3353         if (auth[0] == 0) {
3354             ERROR("Couldn't find 'Proxy-Authenticate' or 'WWW-Authenticate' in 401 or 407!");
3355         }
3356 
3357         realloc_ptr = (char *) realloc(dialog_authentication, strlen(auth) + 2);
3358         if (realloc_ptr) {
3359             dialog_authentication = realloc_ptr;
3360         } else {
3361             free(dialog_authentication);
3362             ERROR("Out of memory!");
3363             return false;
3364         }
3365 
3366 
3367         sprintf(dialog_authentication, "%s", auth);
3368 
3369         /* Store the code of the challenge for building the proper header */
3370         dialog_challenge_type = reply_code;
3371     }
3372 
3373     /* If we are not advancing state, we should quite before we change this stuff. */
3374     if (!call_scenario->messages[search_index]->advance_state) {
3375         return true;
3376     }
3377 
3378     /* Store last received message information for all messages so that we can
3379      * correctly identify retransmissions, and use its body for inclusion
3380      * in our messages. */
3381     last_recv_index = search_index;
3382     last_recv_hash = cookie;
3383     callDebug("Set Last Recv Hash: %lu (recv index %d)\n", last_recv_hash, last_recv_index);
3384     realloc_ptr = (char *) realloc(last_recv_msg, strlen(msg) + 1);
3385     if (realloc_ptr) {
3386         last_recv_msg = realloc_ptr;
3387     } else {
3388         free(last_recv_msg);
3389         ERROR("Out of memory!");
3390         return false;
3391     }
3392 
3393 
3394     strcpy(last_recv_msg, msg);
3395 
3396     /* If this was a mandatory message, or if there is an explicit next label set
3397      * we must update our state machine.  */
3398     if (!call_scenario->messages[search_index]->optional ||
3399             (call_scenario->messages[search_index]->next &&
3400              (test == -1 || M_callVariableTable->getVar(test)->isSet()))) {
3401         /* If we are paused, then we need to wake up so that we properly go through the state machine. */
3402         paused_until = 0;
3403         msg_index = search_index;
3404         return next();
3405     } else {
3406         unsigned int timeout = wake();
3407         unsigned int candidate;
3408 
3409         if (call_scenario->messages[search_index]->next && M_callVariableTable->getVar(test)->isSet()) {
3410             WARNING("Last message generates an error and will not be used for next sends (for last_ variables):\r\n%s",msg);
3411         }
3412 
3413         /* We are just waiting for a message to be received, if any of the
3414          * potential messages have a timeout we set it as our timeout. We
3415          * start from the next message and go until any non-receives. */
3416         for(search_index++; search_index < (int)call_scenario->messages.size(); search_index++) {
3417             if(call_scenario->messages[search_index] -> M_type != MSG_TYPE_RECV) {
3418                 break;
3419             }
3420             candidate = call_scenario->messages[search_index] -> timeout;
3421             if (candidate == 0) {
3422                 if (defl_recv_timeout == 0) {
3423                     continue;
3424                 }
3425                 candidate = defl_recv_timeout;
3426             }
3427             if (!timeout || (clock_tick + candidate < timeout)) {
3428                 timeout = clock_tick + candidate;
3429             }
3430         }
3431 
3432         setPaused();
3433     }
3434     return true;
3435 }
3436 
get_rhs(CAction * currentAction)3437 double call::get_rhs(CAction *currentAction)
3438 {
3439     if (currentAction->getVarInId()) {
3440         return M_callVariableTable->getVar(currentAction->getVarInId())->getDouble();
3441     } else {
3442         return currentAction->getDoubleValue();
3443     }
3444 }
3445 
executeAction(char * msg,message * curmsg)3446 call::T_ActionResult call::executeAction(char * msg, message *curmsg)
3447 {
3448     CActions*  actions;
3449     CAction*   currentAction;
3450 
3451     actions = curmsg->M_actions;
3452     // looking for action to do on this message
3453     if(actions == NULL) {
3454         return(call::E_AR_NO_ERROR);
3455     }
3456 
3457     for(int i=0; i<actions->getActionSize(); i++) {
3458         currentAction = actions->getAction(i);
3459         if(currentAction == NULL) {
3460             continue;
3461         }
3462 
3463         if(currentAction->getActionType() == CAction::E_AT_ASSIGN_FROM_REGEXP) {
3464             char msgPart[MAX_SUB_MESSAGE_LENGTH];
3465 
3466             /* Where to look. */
3467             char *haystack;
3468 
3469             if(currentAction->getLookingPlace() == CAction::E_LP_HDR) {
3470                 extractSubMessage (msg,
3471                                    currentAction->getLookingChar(),
3472                                    msgPart,
3473                                    currentAction->getCaseIndep(),
3474                                    currentAction->getOccurrence(),
3475                                    currentAction->getHeadersOnly());
3476                 if(currentAction->getCheckIt() == true && (strlen(msgPart) == 0)) {
3477                     // the sub message is not found and the checking action say it
3478                     // MUST match --> Call will be marked as failed but will go on
3479                     WARNING("Failed regexp match: header %s not found in message %s\n", currentAction->getLookingChar(), msg);
3480                     return(call::E_AR_HDR_NOT_FOUND);
3481                 }
3482                 haystack = msgPart;
3483             } else if(currentAction->getLookingPlace() == CAction::E_LP_BODY) {
3484                 haystack = strstr(msg, "\r\n\r\n");
3485                 if (!haystack) {
3486                     if (currentAction->getCheckIt() == true) {
3487                         WARNING("Failed regexp match: body not found in message %s\n", msg);
3488                         return(call::E_AR_HDR_NOT_FOUND);
3489                     }
3490                     msgPart[0] = '\0';
3491                     haystack = msgPart;
3492                 }
3493                 haystack += strlen("\r\n\r\n");
3494             } else if(currentAction->getLookingPlace() == CAction::E_LP_MSG) {
3495                 haystack = msg;
3496             } else if(currentAction->getLookingPlace() == CAction::E_LP_VAR) {
3497                 /* Get the input variable. */
3498                 haystack = M_callVariableTable->getVar(currentAction->getVarInId())->getString();
3499                 if (!haystack) {
3500                     if (currentAction->getCheckIt() == true) {
3501                         WARNING("Failed regexp match: variable $%d not set\n", currentAction->getVarInId());
3502                         return(call::E_AR_HDR_NOT_FOUND);
3503                     }
3504                 }
3505             } else {
3506                 ERROR("Invalid looking place: %d\n", currentAction->getLookingPlace());
3507             }
3508             bool did_match = (currentAction->executeRegExp(haystack, M_callVariableTable) > 0);
3509 
3510             if (!did_match && currentAction->getCheckIt()) {
3511                 // the message doesn't match and the checkit action say it MUST match
3512                 // Allow easier regexp debugging
3513                 WARNING("Failed regexp match: looking in '%s', with regexp '%s'",
3514                         haystack, currentAction->getRegularExpression());
3515                 return(call::E_AR_REGEXP_DOESNT_MATCH);
3516             } else if (did_match && currentAction->getCheckItInverse()) {
3517                 // The inverse of the above
3518                 WARNING("Regexp matched but should not: looking in '%s', with regexp '%s'",
3519                         haystack, currentAction->getRegularExpression());
3520                 return(call::E_AR_REGEXP_SHOULDNT_MATCH);
3521             }
3522         } else if (currentAction->getActionType() == CAction::E_AT_ASSIGN_FROM_VALUE) {
3523             double operand = get_rhs(currentAction);
3524             M_callVariableTable->getVar(currentAction->getVarId())->setDouble(operand);
3525         } else if (currentAction->getActionType() == CAction::E_AT_ASSIGN_FROM_INDEX) {
3526             M_callVariableTable->getVar(currentAction->getVarId())->setDouble(msg_index);
3527         } else if (currentAction->getActionType() == CAction::E_AT_ASSIGN_FROM_GETTIMEOFDAY) {
3528             struct timeval tv;
3529             gettimeofday(&tv, NULL);
3530             M_callVariableTable->getVar(currentAction->getVarId())->setDouble((double)tv.tv_sec);
3531             M_callVariableTable->getVar(currentAction->getSubVarId(0))->setDouble((double)tv.tv_usec);
3532         } else if (currentAction->getActionType() == CAction::E_AT_LOOKUP) {
3533             /* Create strings from the sending messages. */
3534             char *file = strdup(createSendingMessage(currentAction->getMessage(0), -2));
3535             char *key = strdup(createSendingMessage(currentAction->getMessage(1), -2));
3536 
3537             if (inFiles.find(file) == inFiles.end()) {
3538                 ERROR("Invalid injection file for insert: %s", file);
3539             }
3540 
3541             double value = inFiles[file]->lookup(key);
3542 
3543             M_callVariableTable->getVar(currentAction->getVarId())->setDouble(value);
3544             free(file);
3545             free(key);
3546         } else if (currentAction->getActionType() == CAction::E_AT_INSERT) {
3547             /* Create strings from the sending messages. */
3548             char *file = strdup(createSendingMessage(currentAction->getMessage(0), -2));
3549             char *value = strdup(createSendingMessage(currentAction->getMessage(1), -2));
3550 
3551             if (inFiles.find(file) == inFiles.end()) {
3552                 ERROR("Invalid injection file for insert: %s", file);
3553             }
3554 
3555             inFiles[file]->insert(value);
3556 
3557             free(file);
3558             free(value);
3559         } else if (currentAction->getActionType() == CAction::E_AT_REPLACE) {
3560             /* Create strings from the sending messages. */
3561             char *file = strdup(createSendingMessage(currentAction->getMessage(0), -2));
3562             char *line = strdup(createSendingMessage(currentAction->getMessage(1), -2));
3563             char *value = strdup(createSendingMessage(currentAction->getMessage(2), -2));
3564 
3565             if (inFiles.find(file) == inFiles.end()) {
3566                 ERROR("Invalid injection file for replace: %s", file);
3567             }
3568 
3569             char *endptr;
3570             int lineNum = (int)strtod(line, &endptr);
3571             if (*endptr) {
3572                 ERROR("Invalid line number for replace: %s", line);
3573             }
3574 
3575             inFiles[file]->replace(lineNum, value);
3576 
3577             free(file);
3578             free(line);
3579             free(value);
3580         } else if (currentAction->getActionType() == CAction::E_AT_CLOSE_CON) {
3581             if (call_socket) {
3582                 sipp_socket_invalidate(call_socket);
3583                 sipp_close_socket(call_socket);
3584                 call_socket = NULL;
3585             }
3586         } else if (currentAction->getActionType() == CAction::E_AT_SET_DEST) {
3587             /* Change the destination for this call. */
3588             char *str_host = strdup(createSendingMessage(currentAction->getMessage(0), -2));
3589             char *str_port = strdup(createSendingMessage(currentAction->getMessage(1), -2));
3590             char *str_protocol = strdup(createSendingMessage(currentAction->getMessage(2), -2));
3591 
3592             char *endptr;
3593             int port = (int)strtod(str_port, &endptr);
3594             if (*endptr) {
3595                 ERROR("Invalid port for setdest: %s", str_port);
3596             }
3597 
3598             int protocol;
3599             if (!strcmp(str_protocol, "udp") || !strcmp(str_protocol, "UDP")) {
3600                 protocol = T_UDP;
3601             } else if (!strcmp(str_protocol, "tcp") || !strcmp(str_protocol, "TCP")) {
3602                 protocol = T_TCP;
3603             } else if (!strcmp(str_protocol, "tls") || !strcmp(str_protocol, "TLS")) {
3604                 protocol = T_TLS;
3605             } else if (!strcmp(str_protocol, "sctp") || !strcmp(str_protocol, "SCTP")) {
3606                 protocol = T_SCTP;
3607             } else {
3608                 ERROR("Unknown transport for setdest: '%s'", str_protocol);
3609             }
3610 
3611             if (!call_socket && ((protocol == T_TCP && transport == T_TCP) ||
3612                                  (protocol == T_SCTP && transport == T_SCTP))) {
3613                 bool existing;
3614                 if ((associate_socket(new_sipp_call_socket(use_ipv6, transport, &existing))) == NULL) {
3615                     switch (protocol) {
3616                     case T_SCTP:
3617                         ERROR_NO("Unable to get a SCTP socket");
3618                         break;
3619                     default:
3620                         ERROR_NO("Unable to get a TCP socket");
3621                     }
3622                 }
3623 
3624                 if (!existing) {
3625                     sipp_customize_socket(call_socket);
3626                 }
3627             }
3628 
3629             if (!call_socket) {
3630                 ERROR("Unable to get a socket");
3631             }
3632 
3633             if (protocol != call_socket->ss_transport) {
3634                 ERROR("Can not switch protocols during setdest.");
3635             }
3636 
3637             if (protocol == T_UDP) {
3638                 /* Nothing to do. */
3639             } else if (protocol == T_TLS) {
3640                 ERROR("Changing destinations is not supported for TLS.");
3641             } else if (protocol == T_TCP || protocol == T_SCTP) {
3642                 if (!multisocket) {
3643                     ERROR("Changing destinations for TCP or SCTP requires multisocket mode.");
3644                 }
3645                 if (call_socket->ss_count > 1) {
3646                     ERROR("Can not change destinations for a TCP/SCTP socket that has more than one user.");
3647                 }
3648             }
3649 
3650             struct addrinfo   hints;
3651             struct addrinfo * local_addr;
3652             memset((char*)&hints, 0, sizeof(hints));
3653             hints.ai_flags  = AI_PASSIVE;
3654             hints.ai_family = PF_UNSPEC;
3655             is_ipv6 = false;
3656 
3657             if (getaddrinfo(str_host, NULL, &hints, &local_addr) != 0) {
3658                 ERROR("Unknown host '%s' for setdest", str_host);
3659             }
3660             if (_RCAST(struct sockaddr_storage *, local_addr->ai_addr)->ss_family != call_peer.ss_family) {
3661                 ERROR("Can not switch between IPv4 and IPV6 using setdest!");
3662             }
3663             memcpy(&call_peer, local_addr->ai_addr,
3664                    SOCK_ADDR_SIZE(_RCAST(struct sockaddr_storage*, local_addr->ai_addr)));
3665             freeaddrinfo(local_addr);
3666 
3667             if (call_peer.ss_family == AF_INET) {
3668                 (_RCAST(struct sockaddr_in*, &call_peer))->sin_port = htons(port);
3669             } else {
3670                 (_RCAST(struct sockaddr_in6*, &call_peer))->sin6_port = htons(port);
3671             }
3672             memcpy(&call_socket->ss_dest, &call_peer,
3673                    SOCK_ADDR_SIZE(_RCAST(struct sockaddr_storage*, &call_peer)));
3674 
3675             free(str_host);
3676             free(str_port);
3677             free(str_protocol);
3678 
3679             if (protocol == T_TCP || protocol == T_SCTP) {
3680                 close(call_socket->ss_fd);
3681                 call_socket->ss_fd = -1;
3682                 call_socket->ss_changed_dest = true;
3683                 if (sipp_reconnect_socket(call_socket)) {
3684                     if (reconnect_allowed()) {
3685                         if(errno == EINVAL) {
3686                             /* This occurs sometime on HPUX but is not a true INVAL */
3687                             WARNING("Unable to connect a TCP/SCTP/TLS socket, remote peer error");
3688                         } else {
3689                             WARNING("Unable to connect a TCP/SCTP/TLS socket");
3690                         }
3691                         /* This connection failed.  We must be in multisocket mode, because
3692                          * otherwise we would already have a call_socket.  This call can not
3693                          * succeed, but does not affect any of our other calls. We do decrement
3694                          * the reconnection counter however. */
3695                         if (reset_number != -1) {
3696                             reset_number--;
3697                         }
3698 
3699                         return E_AR_CONNECT_FAILED;
3700                     } else {
3701                         if(errno == EINVAL) {
3702                             /* This occurs sometime on HPUX but is not a true INVAL */
3703                             ERROR("Unable to connect a TCP/SCTP/TLS socket, remote peer error");
3704                         } else {
3705                             ERROR_NO("Unable to connect a TCP/SCTP/TLS socket");
3706                         }
3707                     }
3708                 }
3709             }
3710         } else if (currentAction->getActionType() == CAction::E_AT_VERIFY_AUTH) {
3711             bool result;
3712             char *lf;
3713             char *end;
3714 
3715             lf = strchr(msg, '\n');
3716             end = strchr(msg, ' ');
3717 
3718             if (!lf || !end) {
3719                 result = false;
3720             } else if (lf < end) {
3721                 result = false;
3722             } else {
3723                 char *auth = get_header(msg, "Authorization:", true);
3724                 char *method = (char *)malloc(end - msg + 1);
3725                 strncpy(method, msg, end - msg);
3726                 method[end - msg] = '\0';
3727 
3728                 /* Generate the username to verify it against. */
3729                 char *tmp = createSendingMessage(currentAction->getMessage(0), -2 /* do not add crlf*/);
3730                 char *username = strdup(tmp);
3731                 /* Generate the password to verify it against. */
3732                 tmp= createSendingMessage(currentAction->getMessage(1), -2 /* do not add crlf*/);
3733                 char *password = strdup(tmp);
3734                 /* Need the body for length and auth-int calculation */
3735                 char *body;
3736                 const char *auth_body = NULL;
3737                 body = strstr(msg, "\r\n\r\n");
3738                 if (body) {
3739                     auth_body = body;
3740                     auth_body += strlen("\r\n\r\n");
3741                 } else {
3742                     auth_body = "";
3743                 }
3744 
3745                 result = verifyAuthHeader(username, password, method, auth, auth_body);
3746 
3747                 free(username);
3748                 free(password);
3749                 free(method);
3750             }
3751 
3752             M_callVariableTable->getVar(currentAction->getVarId())->setBool(result);
3753         } else if (currentAction->getActionType() == CAction::E_AT_JUMP) {
3754             double operand = get_rhs(currentAction);
3755             if (msg_index == ((int)operand)) {
3756                 ERROR("Jump statement at index %d jumps to itself and causes an infinite loop", msg_index);
3757             }
3758             msg_index = (int)operand - 1;
3759             /* -1 is allowed to go to the first label, but watch out
3760              * when using msg_index. */
3761             if (msg_index < -1 || msg_index >= (int)call_scenario->messages.size()) {
3762                 ERROR("Jump statement out of range (not 0 <= %d <= %zu)",
3763                       msg_index + 1, call_scenario->messages.size());
3764             }
3765         } else if (currentAction->getActionType() == CAction::E_AT_PAUSE_RESTORE) {
3766             double operand = get_rhs(currentAction);
3767             paused_until = (int)operand;
3768         } else if (currentAction->getActionType() == CAction::E_AT_VAR_ADD) {
3769             double value = M_callVariableTable->getVar(currentAction->getVarId())->getDouble();
3770             double operand = get_rhs(currentAction);
3771             M_callVariableTable->getVar(currentAction->getVarId())->setDouble(value + operand);
3772         } else if (currentAction->getActionType() == CAction::E_AT_VAR_SUBTRACT) {
3773             double value = M_callVariableTable->getVar(currentAction->getVarId())->getDouble();
3774             double operand = get_rhs(currentAction);
3775             M_callVariableTable->getVar(currentAction->getVarId())->setDouble(value - operand);
3776         } else if (currentAction->getActionType() == CAction::E_AT_VAR_MULTIPLY) {
3777             double value = M_callVariableTable->getVar(currentAction->getVarId())->getDouble();
3778             double operand = get_rhs(currentAction);
3779             M_callVariableTable->getVar(currentAction->getVarId())->setDouble(value * operand);
3780         } else if (currentAction->getActionType() == CAction::E_AT_VAR_DIVIDE) {
3781             double value = M_callVariableTable->getVar(currentAction->getVarId())->getDouble();
3782             double operand = get_rhs(currentAction);
3783             if (operand == 0) {
3784                 WARNING("Action failure: Can not divide by zero ($%d/$%d)!\n", currentAction->getVarId(), currentAction->getVarInId());
3785             } else {
3786                 M_callVariableTable->getVar(currentAction->getVarId())->setDouble(value / operand);
3787             }
3788         } else if (currentAction->getActionType() == CAction::E_AT_VAR_TEST) {
3789             double value = currentAction->compare(M_callVariableTable);
3790             M_callVariableTable->getVar(currentAction->getVarId())->setBool(value);
3791         } else if (currentAction->getActionType() == CAction::E_AT_VAR_STRCMP) {
3792             char *rhs = M_callVariableTable->getVar(currentAction->getVarInId())->getString();
3793             char *lhs;
3794             if (currentAction->getVarIn2Id()) {
3795                 lhs = M_callVariableTable->getVar(currentAction->getVarIn2Id())->getString();
3796             } else {
3797                 lhs = currentAction->getStringValue();
3798             }
3799             int value = strcmp(rhs, lhs);
3800             M_callVariableTable->getVar(currentAction->getVarId())->setDouble((double)value);
3801         } else if (currentAction->getActionType() == CAction::E_AT_VAR_TRIM) {
3802             CCallVariable *var = M_callVariableTable->getVar(currentAction->getVarId());
3803             char *in = var->getString();
3804             char *p = in;
3805             while (isspace(*p)) {
3806                 p++;
3807             }
3808             char *q = strdup(p);
3809             var->setString(q);
3810             int l = strlen(q);
3811             for (int i = l - 1; (i >= 0) && isspace(q[i]); i--) {
3812                 q[i] = '\0';
3813             }
3814         } else if (currentAction->getActionType() == CAction::E_AT_VAR_TO_DOUBLE) {
3815             double value;
3816 
3817             if (M_callVariableTable->getVar(currentAction->getVarInId())->toDouble(&value)) {
3818                 M_callVariableTable->getVar(currentAction->getVarId())->setDouble(value);
3819             } else {
3820                 WARNING("Invalid double conversion from $%d to $%d", currentAction->getVarInId(), currentAction->getVarId());
3821             }
3822         } else if (currentAction->getActionType() == CAction::E_AT_ASSIGN_FROM_SAMPLE) {
3823             double value = currentAction->getDistribution()->sample();
3824             M_callVariableTable->getVar(currentAction->getVarId())->setDouble(value);
3825         } else if (currentAction->getActionType() == CAction::E_AT_ASSIGN_FROM_STRING) {
3826             char* x = createSendingMessage(currentAction->getMessage(), -2 /* do not add crlf*/);
3827             char *str = strdup(x);
3828             if (!str) {
3829                 ERROR("Out of memory duplicating string for assignment!");
3830             }
3831             M_callVariableTable->getVar(currentAction->getVarId())->setString(str);
3832         } else if (currentAction->getActionType() == CAction::E_AT_LOG_TO_FILE) {
3833             char* x = createSendingMessage(currentAction->getMessage(), -2 /* do not add crlf*/);
3834             LOG_MSG("%s\n", x);
3835         } else if (currentAction->getActionType() == CAction::E_AT_LOG_WARNING) {
3836             char* x = createSendingMessage(currentAction->getMessage(), -2 /* do not add crlf*/);
3837             WARNING("%s", x);
3838         } else if (currentAction->getActionType() == CAction::E_AT_LOG_ERROR) {
3839             char* x = createSendingMessage(currentAction->getMessage(), -2 /* do not add crlf*/);
3840             ERROR("%s", x);
3841         } else if (currentAction->getActionType() == CAction::E_AT_EXECUTE_CMD) {
3842             char* x = createSendingMessage(currentAction->getMessage(), -2 /* do not add crlf*/);
3843             // TRACE_MSG("Trying to execute [%s]", x);
3844             pid_t l_pid;
3845             switch(l_pid = fork()) {
3846             case -1:
3847                 // error when forking !
3848                 ERROR_NO("Forking error main");
3849                 break;
3850 
3851             case 0:
3852                 // first child process - execute the command
3853                 if((l_pid = fork()) < 0) {
3854                     ERROR_NO("Forking error child");
3855                 } else {
3856                     if( l_pid == 0) {
3857                         int ret;
3858                         ret = system(x); // second child runs
3859                         if(ret == -1) {
3860                             WARNING("system call error for %s",x);
3861                         }
3862                     }
3863                     exit(EXIT_OTHER);
3864                 }
3865                 break;
3866             default:
3867                 // parent process continue
3868                 // reap first child immediately
3869                 pid_t ret;
3870                 while ((ret=waitpid(l_pid, NULL, 0)) != l_pid) {
3871                     if (ret != -1) {
3872                         ERROR("waitpid returns %1d for child %1d",ret,l_pid);
3873                     }
3874                 }
3875                 break;
3876             }
3877         } else if (currentAction->getActionType() == CAction::E_AT_EXEC_INTCMD) {
3878             switch (currentAction->getIntCmd()) {
3879             case CAction::E_INTCMD_STOP_ALL:
3880                 quitting = 1;
3881                 break;
3882             case CAction::E_INTCMD_STOP_NOW:
3883                 sipp_exit(EXIT_TEST_RES_INTERNAL);
3884                 break;
3885             case CAction::E_INTCMD_STOPCALL:
3886             default:
3887                 return(call::E_AR_STOP_CALL);
3888                 break;
3889             }
3890 #ifdef PCAPPLAY
3891         } else if ((currentAction->getActionType() == CAction::E_AT_PLAY_PCAP_AUDIO) ||
3892                    (currentAction->getActionType() == CAction::E_AT_PLAY_PCAP_IMAGE) ||
3893                    (currentAction->getActionType() == CAction::E_AT_PLAY_PCAP_VIDEO)) {
3894             play_args_t *play_args;
3895             if (currentAction->getActionType() == CAction::E_AT_PLAY_PCAP_AUDIO) {
3896                 play_args = &(this->play_args_a);
3897             } else if (currentAction->getActionType() == CAction::E_AT_PLAY_PCAP_IMAGE) {
3898                 play_args = &(this->play_args_i);
3899             } else if (currentAction->getActionType() == CAction::E_AT_PLAY_PCAP_VIDEO) {
3900                 play_args = &(this->play_args_v);
3901             } else {
3902                 ERROR("Can't find pcap data to play");
3903             }
3904 
3905             play_args->pcap = currentAction->getPcapPkts();
3906             /* port number is set in [auto_]media_port interpolation */
3907             if (media_ip_is_ipv6) {
3908                 struct sockaddr_in6 *from = (struct sockaddr_in6 *)(void *) &(play_args->from);
3909                 from->sin6_family = AF_INET6;
3910                 inet_pton(AF_INET6, media_ip, &(from->sin6_addr));
3911             } else {
3912                 struct sockaddr_in *from = (struct sockaddr_in *)(void *) &(play_args->from);
3913                 from->sin_family = AF_INET;
3914                 from->sin_addr.s_addr = inet_addr(media_ip);
3915             }
3916             /* Create a thread to send RTP or UDPTL packets */
3917             pthread_attr_t attr;
3918             pthread_attr_init(&attr);
3919 #ifndef PTHREAD_STACK_MIN
3920 #define PTHREAD_STACK_MIN  16384
3921 #endif
3922             //pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN);
3923             if (media_thread != 0) {
3924                 // If a media_thread is already active, kill it before starting a new one
3925                 pthread_cancel(media_thread);
3926                 pthread_join(media_thread, NULL);
3927                 media_thread = 0;
3928             }
3929             int ret = pthread_create(&media_thread, &attr, send_wrapper,
3930                                      (void *) play_args);
3931             if(ret)
3932                 ERROR("Can't create thread to send RTP packets");
3933             pthread_attr_destroy(&attr);
3934 #endif
3935 
3936 #ifdef RTP_STREAM
3937     } else if (currentAction->getActionType() == CAction::E_AT_RTP_STREAM_PAUSE) {
3938       rtpstream_pause (&rtpstream_callinfo);
3939     } else if (currentAction->getActionType() == CAction::E_AT_RTP_STREAM_RESUME) {
3940       rtpstream_resume (&rtpstream_callinfo);
3941     } else if (currentAction->getActionType() == CAction::E_AT_RTP_STREAM_PLAY) {
3942       rtpstream_play (&rtpstream_callinfo,currentAction->getRTPStreamActInfo());
3943 #endif
3944         } else {
3945             ERROR("call::executeAction unknown action");
3946         }
3947     } // end for
3948     return(call::E_AR_NO_ERROR);
3949 }
3950 
extractSubMessage(char * msg,char * matchingString,char * result,bool case_indep,int occurrence,bool headers)3951 void call::extractSubMessage(char * msg, char * matchingString, char* result, bool case_indep, int occurrence, bool headers)
3952 {
3953 
3954     char *ptr, *ptr1;
3955     int sizeOf;
3956     int i = 0;
3957     int len = strlen(matchingString);
3958     char mat1 = tolower(*matchingString);
3959     char mat2 = toupper(*matchingString);
3960 
3961     ptr = msg;
3962     while (*ptr) {
3963         if (!case_indep) {
3964             ptr = strstr(ptr, matchingString);
3965             if (ptr == NULL) break;
3966             if (headers == true && ptr != msg && *(ptr-1) != '\n') {
3967                 ++ptr;
3968                 continue;
3969             }
3970         } else {
3971             if (headers) {
3972                 if (ptr != msg) {
3973                     ptr = strchr(ptr, '\n');
3974                     if (ptr == NULL) break;
3975                     ++ptr;
3976                     if (*ptr == 0) break;
3977                 }
3978             } else {
3979                 ptr1 = strchr(ptr, mat1);
3980                 ptr = strchr(ptr, mat2);
3981                 if (ptr == NULL) {
3982                     if (ptr1 == NULL) break;
3983                     ptr = ptr1;
3984                 } else {
3985                     if (ptr1 != NULL && ptr1 < ptr) ptr = ptr1;
3986                 }
3987             }
3988             if (strncasecmp(ptr, matchingString, len) != 0) {
3989                 ++ptr;
3990                 continue;
3991             }
3992         }
3993         // here with ptr pointing to a matching string
3994         if (occurrence <= 1) break;
3995         --occurrence;
3996         ++ptr;
3997     }
3998 
3999     if(ptr != NULL && *ptr != 0) {
4000         strncpy(result, ptr+len, MAX_SUB_MESSAGE_LENGTH);
4001         sizeOf = strlen(result);
4002         if(sizeOf >= MAX_SUB_MESSAGE_LENGTH)
4003             sizeOf = MAX_SUB_MESSAGE_LENGTH-1;
4004         while((i<sizeOf) && (result[i] != '\n') && (result[i] != '\r'))
4005             i++;
4006         result[i] = '\0';
4007     } else {
4008         result[0] = '\0';
4009     }
4010 }
4011 
getFieldFromInputFile(const char * fileName,int field,SendingMessage * lineMsg,char * & dest)4012 void call::getFieldFromInputFile(const char *fileName, int field, SendingMessage *lineMsg, char*& dest)
4013 {
4014     if (m_lineNumber == NULL) {
4015         ERROR("Automatic calls (created by -aa, -oocsn or -oocsf) cannot use input files!");
4016     }
4017     if (inFiles.find(fileName) == inFiles.end()) {
4018         ERROR("Invalid injection file: %s", fileName);
4019     }
4020     int line = (*m_lineNumber)[fileName];
4021     if (lineMsg) {
4022         char lineBuffer[20];
4023         char *endptr;
4024         createSendingMessage(lineMsg, -2, lineBuffer, sizeof(lineBuffer));
4025         line = (int) strtod(lineBuffer, &endptr);
4026         if (*endptr != 0) {
4027             ERROR("Invalid line number generated: '%s'", lineBuffer);
4028         }
4029         if (line > inFiles[fileName]->numLines()) {
4030             line = -1;
4031         }
4032     }
4033     if (line < 0) {
4034         return;
4035     }
4036     dest += inFiles[fileName]->getField(line, field, dest, SIPP_MAX_MSG_SIZE);
4037 }
4038 
checkAutomaticResponseMode(char * P_recv)4039 call::T_AutoMode call::checkAutomaticResponseMode(char * P_recv)
4040 {
4041     if (strcmp(P_recv, "BYE")==0) {
4042         return E_AM_UNEXP_BYE;
4043     } else if (strcmp(P_recv, "CANCEL") == 0) {
4044         return E_AM_UNEXP_CANCEL;
4045     } else if (strcmp(P_recv, "PING") == 0) {
4046         return E_AM_PING;
4047     } else if (auto_answer &&
4048                ((strcmp(P_recv, "INFO") == 0) ||
4049                 (strcmp(P_recv, "NOTIFY") == 0) ||
4050                 (strcmp(P_recv, "OPTIONS") == 0) ||
4051                 (strcmp(P_recv, "UPDATE") == 0))) {
4052         return E_AM_AA;
4053     } else {
4054         return E_AM_DEFAULT;
4055     }
4056 }
4057 
setLastMsg(const char * msg)4058 void call::setLastMsg(const char *msg)
4059 {
4060     realloc_ptr = (char *) realloc(last_recv_msg, strlen(msg) + 1);
4061     if (realloc_ptr) {
4062         last_recv_msg = realloc_ptr;
4063     } else {
4064         free(last_recv_msg);
4065         ERROR("Out of memory!");
4066         return;
4067     }
4068 
4069     strcpy(last_recv_msg, msg);
4070 }
4071 
automaticResponseMode(T_AutoMode P_case,char * P_recv)4072 bool call::automaticResponseMode(T_AutoMode P_case, char * P_recv)
4073 {
4074 
4075     int res ;
4076     char * old_last_recv_msg = NULL;
4077     bool last_recv_msg_saved = false;
4078 
4079     switch (P_case) {
4080     case E_AM_UNEXP_BYE: // response for an unexpected BYE
4081         // usage of last_ keywords
4082         realloc_ptr = (char *) realloc(last_recv_msg, strlen(P_recv) + 1);
4083         if (realloc_ptr) {
4084             last_recv_msg = realloc_ptr;
4085         } else {
4086             free(last_recv_msg);
4087             ERROR("Out of memory!");
4088             return false;
4089         }
4090 
4091 
4092         strcpy(last_recv_msg, P_recv);
4093 
4094         // The BYE is unexpected, count it
4095         call_scenario->messages[msg_index] -> nb_unexp++;
4096         if (default_behaviors & DEFAULT_BEHAVIOR_ABORTUNEXP) {
4097             WARNING("Aborting call on an unexpected BYE for call: %s", (id==NULL)?"none":id);
4098             if (default_behaviors & DEFAULT_BEHAVIOR_BYE) {
4099                 sendBuffer(createSendingMessage(get_default_message("200"), -1));
4100             }
4101 
4102             // if twin socket call => reset the other part here
4103             if (twinSippSocket && (msg_index > 0)) {
4104                 res = sendCmdBuffer(createSendingMessage(get_default_message("3pcc_abort"), -1));
4105                 if (res) {
4106                     WARNING("sendCmdBuffer returned %d", res);
4107                     return false;
4108                 }
4109             }
4110             computeStat(CStat::E_CALL_FAILED);
4111             computeStat(CStat::E_FAILED_UNEXPECTED_MSG);
4112             delete this;
4113         } else {
4114             WARNING("Continuing call on an unexpected BYE for call: %s", (id==NULL)?"none":id);
4115         }
4116         break ;
4117 
4118     case E_AM_UNEXP_CANCEL: // response for an unexpected cancel
4119         // usage of last_ keywords
4120         realloc_ptr = (char *) realloc(last_recv_msg, strlen(P_recv) + 1);
4121         if (realloc_ptr) {
4122             last_recv_msg = realloc_ptr;
4123         } else {
4124             free(last_recv_msg);
4125             ERROR("Out of memory!");
4126             return false;
4127         }
4128 
4129 
4130         strcpy(last_recv_msg, P_recv);
4131 
4132         // The CANCEL is unexpected, count it
4133         call_scenario->messages[msg_index] -> nb_unexp++;
4134         if (default_behaviors & DEFAULT_BEHAVIOR_ABORTUNEXP) {
4135             WARNING("Aborting call on an unexpected CANCEL for call: %s", (id==NULL)?"none":id);
4136             if (default_behaviors & DEFAULT_BEHAVIOR_BYE) {
4137                 sendBuffer(createSendingMessage(get_default_message("200"), -1));
4138             }
4139 
4140             // if twin socket call => reset the other part here
4141             if (twinSippSocket && (msg_index > 0)) {
4142                 res = sendCmdBuffer(createSendingMessage(get_default_message("3pcc_abort"), -1));
4143                 if (res) {
4144                     WARNING("sendCmdBuffer returned %d", res);
4145                     return false;
4146                 }
4147             }
4148 
4149             computeStat(CStat::E_CALL_FAILED);
4150             computeStat(CStat::E_FAILED_UNEXPECTED_MSG);
4151             delete this;
4152         } else {
4153             WARNING("Continuing call on unexpected CANCEL for call: %s", (id==NULL)?"none":id);
4154         }
4155         break ;
4156 
4157     case E_AM_PING: // response for a random ping
4158         // usage of last_ keywords
4159         realloc_ptr = (char *) realloc(last_recv_msg, strlen(P_recv) + 1);
4160         if (realloc_ptr) {
4161             last_recv_msg = realloc_ptr;
4162         } else {
4163             free(last_recv_msg);
4164             ERROR("Out of memory!");
4165             return false;
4166         }
4167 
4168 
4169         strcpy(last_recv_msg, P_recv);
4170 
4171         if (default_behaviors & DEFAULT_BEHAVIOR_PINGREPLY) {
4172             WARNING("Automatic response mode for an unexpected PING for call: %s", (id==NULL)?"none":id);
4173             sendBuffer(createSendingMessage(get_default_message("200"), -1));
4174             // Note: the call ends here but it is not marked as bad. PING is a
4175             //       normal message.
4176             // if twin socket call => reset the other part here
4177             if (twinSippSocket && (msg_index > 0)) {
4178                 res = sendCmdBuffer(createSendingMessage(get_default_message("3pcc_abort"), -1));
4179                 if (res) {
4180                     WARNING("sendCmdBuffer returned %d", res);
4181                     return false;
4182                 }
4183             }
4184 
4185             CStat::globalStat(CStat::E_AUTO_ANSWERED);
4186             delete this;
4187         } else {
4188             WARNING("Do not answer on an unexpected PING for call: %s", (id==NULL)?"none":id);
4189         }
4190         break ;
4191 
4192     case E_AM_AA: // response for a random INFO, NOTIFY, OPTIONS or UPDATE
4193         // store previous last msg if msg is INFO, NOTIFY, OPTIONS or UPDATE
4194         // restore last_recv_msg to previous one
4195         // after sending ok
4196         old_last_recv_msg = NULL;
4197         if (last_recv_msg != NULL) {
4198             last_recv_msg_saved = true;
4199             old_last_recv_msg = (char *) malloc(strlen(last_recv_msg)+1);
4200             strcpy(old_last_recv_msg,last_recv_msg);
4201         }
4202         // usage of last_ keywords
4203         realloc_ptr = (char *) realloc(last_recv_msg, strlen(P_recv) + 1);
4204         if (realloc_ptr) {
4205             last_recv_msg = realloc_ptr;
4206         } else {
4207             free(last_recv_msg);
4208             free(old_last_recv_msg);
4209             ERROR("Out of memory!");
4210             return false;
4211         }
4212 
4213 
4214         strcpy(last_recv_msg, P_recv);
4215 
4216         WARNING("Automatic response mode for an unexpected INFO, NOTIFY, OPTIONS or UPDATE for call: %s",
4217                 (id == NULL) ? "none" : id);
4218         sendBuffer(createSendingMessage(get_default_message("200"), -1));
4219 
4220         // restore previous last msg
4221         if (last_recv_msg_saved == true) {
4222             realloc_ptr = (char *) realloc(last_recv_msg, strlen(old_last_recv_msg) + 1);
4223             if (realloc_ptr) {
4224                 last_recv_msg = realloc_ptr;
4225             } else {
4226                 free(last_recv_msg);
4227                 ERROR("Out of memory!");
4228                 return false;
4229             }
4230 
4231 
4232             strcpy(last_recv_msg, old_last_recv_msg);
4233             if (old_last_recv_msg != NULL) {
4234                 free(old_last_recv_msg);
4235                 old_last_recv_msg = NULL;
4236             }
4237         }
4238         CStat::globalStat(CStat::E_AUTO_ANSWERED);
4239         return true;
4240         break;
4241 
4242     default:
4243         ERROR("Internal error for automaticResponseMode - mode %d is not implemented!", P_case);
4244         break ;
4245     }
4246 
4247     return false;
4248 }
4249 
4250 #ifdef PCAPPLAY
send_wrapper(void * arg)4251 void *send_wrapper(void *arg)
4252 {
4253     play_args_t *s = (play_args_t *) arg;
4254     //struct sched_param param;
4255     //int ret;
4256     //param.sched_priority = 10;
4257     //ret = pthread_setschedparam(pthread_self(), SCHED_RR, &param);
4258     //if(ret)
4259     //  ERROR("Can't set RTP play thread realtime parameters");
4260     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
4261     pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
4262     send_packets(s);
4263     pthread_exit(NULL);
4264     return NULL;
4265 }
4266 #endif
4267