[tools] / trunk / publicdemo / sipp / call.cpp Repository:
ViewVC logotype

View of /trunk/publicdemo/sipp/call.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 70 - (download) (annotate)
Thu May 5 20:35:33 2011 UTC (2 years ago) by jhermanski
File size: 111305 byte(s)
Package all media, etc. needed for Public demo system into one tree
    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  */
   37 
   38 #include <iterator>
   39 #include <algorithm>
   40 #include <fstream>
   41 #include <iostream>
   42 #include <sys/types.h>
   43 #include <sys/wait.h>
   44 
   45 #ifdef PCAPPLAY
   46 #include "send_packets.h"
   47 #endif
   48 #include "sipp.hpp"
   49 #include "assert.h"
   50 
   51 #ifdef _USE_OPENSSL
   52 extern  SSL                 *ssl_list[];
   53 extern  struct pollfd        pollfiles[];
   54 extern  SSL_CTX             *sip_trp_ssl_ctx;
   55 #endif
   56 
   57 extern  map<string, struct sipp_socket *>     map_perip_fd;
   58 
   59 call_map calls;
   60 call_list running_calls;
   61 timewheel paused_calls;
   62 
   63  socket_call_map_map socket_to_calls;
   64 
   65 #ifdef PCAPPLAY
   66 /* send_packets pthread wrapper */
   67 void *send_wrapper(void *);
   68 #endif
   69 
   70 /************** Call map and management routines **************/
   71 call_map * get_calls()
   72 {
   73   return & calls;
   74 }
   75 
   76 static unsigned int next_number = 1;
   77 
   78 unsigned int get_tdm_map_number(unsigned int number) {
   79   unsigned int nb = 0;
   80   unsigned int i=0;
   81   unsigned int interval=0;
   82   unsigned int random=0;
   83   bool found = false;
   84 
   85   /* Find a number in the tdm_map which is not in use */
   86   interval = (tdm_map_a+1) * (tdm_map_b+1) * (tdm_map_c+1);
   87   random = rand() % interval;
   88   while ((i<interval) && (!found)) {
   89     if (tdm_map[(random + i - 1) % interval] == false) {
   90       nb = (random + i - 1) % interval;
   91       found = true;
   92     }
   93     i++;
   94   }
   95 
   96   if (!found) {
   97     return 0;
   98   } else {
   99     return nb+1;
  100   }
  101 }
  102 
  103 struct sipp_socket *call::associate_socket(struct sipp_socket *socket) {
  104   if (socket) {
  105     this->call_socket = socket;
  106     add_call_to_socket(socket, this);
  107   }
  108   return socket;
  109 }
  110 
  111 struct sipp_socket *call::dissociate_socket() {
  112   struct sipp_socket *ret = this->call_socket;
  113 
  114   remove_call_from_socket(this->call_socket, this);
  115   this->call_socket = NULL;
  116 
  117   return ret;
  118 }
  119 
  120 call * add_call(char * call_id , bool use_ipv6, int userId)
  121 {
  122   return add_call(call_id, use_ipv6, userId, false /* Is not automatic. */);
  123 }
  124 
  125 call * add_call(char * call_id , bool use_ipv6, int userId, bool isAutomatic)
  126 {
  127   call * new_call;
  128   unsigned int nb;
  129 
  130   if(!next_number) { next_number ++; }
  131 
  132   if (use_tdmmap) {
  133     nb = get_tdm_map_number(next_number);
  134     if (nb != 0) {
  135       /* Mark the entry in the list as busy */
  136       tdm_map[nb - 1] = true;
  137     } else {
  138       /* Can't create the new call */
  139       WARNING("Can't create new outgoing call: all tdm_map circuits busy");
  140       return NULL;
  141     }
  142   }
  143 
  144   new_call = new call(call_id, userId, use_ipv6, isAutomatic);
  145 
  146   if(!new_call) {
  147     ERROR("Memory Overflow");
  148   }
  149 
  150   /* All calls must exist in the map. */
  151   calls[std::string(call_id)] = new_call;
  152   /* All calls start off in the running state. */
  153   add_running_call(new_call);
  154 
  155   new_call -> number = next_number;
  156   new_call -> tdm_map_number = nb - 1;
  157 
  158   /* Vital counters update */
  159   if (!isAutomatic) {
  160     next_number++;
  161   } else {
  162     /* We do not update the call_id counter, for we create here a call */
  163     /* to answer to an out of call message */
  164   }
  165   open_calls++;
  166 
  167   /* Statistics update */
  168   calls_since_last_rate_change++;
  169   total_calls ++;
  170 
  171   if(open_calls > open_calls_peak) {
  172     open_calls_peak = open_calls;
  173     open_calls_peak_time = clock_tick / 1000;
  174   }
  175 
  176   return new_call;
  177 }
  178 
  179 call * add_call(char * call_id , struct sipp_socket *socket) {
  180   call *new_call = add_call(call_id, socket->ss_ipv6, 0 /* No User. */, false /* Not Auto. */);
  181   new_call->associate_socket(socket);
  182   return new_call;
  183 }
  184 
  185 call * add_call(char * call_id , struct sipp_socket *socket, bool isAutomatic) {
  186   call *new_call = add_call(call_id, socket->ss_ipv6, 0 /* No User. */, isAutomatic);
  187   new_call->associate_socket(socket);
  188   return new_call;
  189 }
  190 
  191 call * add_call(int userId, bool ipv6)
  192 {
  193   static char call_id[MAX_HEADER_LEN];
  194 
  195   char * src = call_id_string;
  196   int count = 0;
  197 
  198   if(!next_number) { next_number ++; }
  199 
  200   while (*src && count < MAX_HEADER_LEN-1) {
  201       if (*src == '%') {
  202           ++src;
  203           switch(*src++) {
  204           case 'u':
  205               count += snprintf(&call_id[count], MAX_HEADER_LEN-count-1,"%u", next_number);
  206               break;
  207           case 'p':
  208               count += snprintf(&call_id[count], MAX_HEADER_LEN-count-1,"%u", pid);
  209               break;
  210           case 's':
  211               count += snprintf(&call_id[count], MAX_HEADER_LEN-count-1,"%s", local_ip);
  212               break;
  213           default:      // treat all unknown sequences as %%
  214               call_id[count++] = '%';
  215               break;
  216           }
  217       } else {
  218         call_id[count++] = *src++;
  219       }
  220   }
  221   call_id[count] = 0;
  222 
  223   return add_call(call_id, ipv6, userId);
  224 }
  225 
  226 call * get_call(char * call_id)
  227 {
  228 
  229   call * call_ptr;
  230 
  231   call_map::iterator call_it ;
  232   call_it = calls.find(call_map::key_type(call_id));
  233   call_ptr = (call_it != calls.end()) ? call_it->second : NULL ;
  234 
  235   return call_ptr;
  236 }
  237 
  238 void delete_call(char * call_id)
  239 {
  240   call * call_ptr;
  241   call_map::iterator call_it ;
  242   call_it = calls.find(call_map::key_type(call_id));
  243   call_ptr = (call_it != calls.end()) ? call_it->second : NULL ;
  244 
  245   if(call_ptr) {
  246     if (use_tdmmap)
  247       tdm_map[call_ptr->tdm_map_number] = false;
  248     calls.erase(call_it);
  249 
  250     if (call_ptr->running) {
  251       remove_running_call(call_ptr);
  252     } else {
  253       paused_calls.remove_paused_call(call_ptr);
  254     }
  255 
  256     delete call_ptr;
  257     open_calls--;
  258   } else {
  259     if (start_calls == 0) {
  260       ERROR("Call not found");
  261     }
  262   }
  263 }
  264 
  265 void delete_calls(void)
  266 {
  267   call * call_ptr;
  268 
  269   call_map::iterator call_it ;
  270   call_it = calls.begin();
  271   while (call_it != calls.end()) {
  272     call_ptr = (call_it != calls.end()) ? call_it->second : NULL ;
  273     WARNING_P1("Aborting call with Call-Id '%s'", call_ptr->id);
  274     call_ptr->abortCall();
  275     call_it = calls.begin();
  276   }
  277 
  278 }
  279 
  280 /* Routines for running calls. */
  281 
  282 /* Get the overall list of running calls. */
  283 call_list * get_running_calls()
  284 {
  285   return & running_calls;
  286 }
  287 
  288 /* Put this call in the run queue. */
  289 void add_running_call(call *call) {
  290   call->runit = running_calls.insert(running_calls.end(), call);
  291   call->running = true;
  292 }
  293 
  294 /* Remove this call from the run queue. */
  295 bool remove_running_call(call *call) {
  296   if (!call->running) {
  297     return false;
  298     }
  299   running_calls.erase(call->runit);
  300   call->running = false;
  301   return true;
  302 }
  303 
  304 /* When should this call wake up? */
  305 unsigned int call_wake(call *call) {
  306   unsigned int wake = 0;
  307 
  308   if (call->paused_until) {
  309     wake = call->paused_until;
  310   }
  311 
  312   if (call->next_retrans && (!wake || (call->next_retrans < wake))) {
  313     wake = call->next_retrans;
  314   }
  315 
  316   if (call->recv_timeout && (!wake || (call->recv_timeout < wake))) {
  317     wake = call->recv_timeout;
  318   }
  319 
  320   return wake;
  321 }
  322 
  323 call_list *timewheel::call2list(call *call) {
  324   unsigned int wake = call_wake(call);
  325   unsigned int wake_sigbits = wake;
  326   unsigned int base_sigbits = wheel_base;
  327 
  328   if (wake == 0) {
  329     return &forever_list;
  330   }
  331 
  332   wake_sigbits /= LEVEL_ONE_SLOTS;
  333   base_sigbits /= LEVEL_ONE_SLOTS;
  334   if (wake_sigbits == base_sigbits) {
  335     return &wheel_one[wake % LEVEL_ONE_SLOTS];
  336   }
  337   wake_sigbits /= LEVEL_TWO_SLOTS;
  338   base_sigbits /= LEVEL_TWO_SLOTS;
  339   if (wake_sigbits == base_sigbits) {
  340     return &wheel_two[(wake / LEVEL_ONE_SLOTS) % LEVEL_TWO_SLOTS];
  341   }
  342   assert(wake_sigbits < LEVEL_THREE_SLOTS);
  343   return &wheel_three[wake_sigbits];
  344 }
  345 
  346 int expire_paused_calls() {
  347   return paused_calls.expire_paused_calls();
  348 }
  349 int paused_calls_count() {
  350   return paused_calls.size();
  351 }
  352 void remove_paused_call(call *call) {
  353   assert(!call->running);
  354   paused_calls.remove_paused_call(call);
  355 }
  356 
  357 /* Iterate through our sorted set of paused calls, removing those that
  358  * should no longer be paused, and adding them to the run queue. */
  359 int timewheel::expire_paused_calls() {
  360   int found = 0;
  361 
  362   while (wheel_base < clock_tick) {
  363     int slot1 = wheel_base % LEVEL_ONE_SLOTS;
  364 
  365     /* Migrate calls from slot2 when we hit 0. */
  366     if (slot1 == 0) {
  367       int slot2 = (wheel_base / LEVEL_ONE_SLOTS) % LEVEL_TWO_SLOTS;
  368 
  369       /* If slot2 is also zero, we must migrate calls from slot3 into slot2. */
  370       if (slot2 == 0) {
  371   int slot3 = ((wheel_base / LEVEL_ONE_SLOTS) / LEVEL_TWO_SLOTS);
  372   assert(slot3 < LEVEL_THREE_SLOTS);
  373 
  374   for (call_list::iterator l3it = wheel_three[slot3].begin();
  375        l3it != wheel_three[slot3].end();
  376        l3it++) {
  377     /* Migrate this call to wheel two. */
  378     add_paused_call(*l3it, false);
  379         }
  380 
  381   wheel_three[slot3].clear();
  382       }
  383 
  384       for (call_list::iterator l2it = wheel_two[slot2].begin();
  385     l2it != wheel_two[slot2].end();
  386     l2it++) {
  387   /* Migrate this call to wheel one. */
  388   add_paused_call(*l2it, false);
  389       }
  390 
  391       wheel_two[slot2].clear();
  392     }
  393 
  394     found += wheel_one[slot1].size();
  395     for(call_list::iterator it = wheel_one[slot1].begin();
  396   it != wheel_one[slot1].end(); it++) {
  397       add_running_call(*it);
  398       count--;
  399     }
  400     wheel_one[slot1].clear();
  401 
  402     wheel_base++;
  403   }
  404 
  405   return found;
  406 }
  407 
  408 void timewheel::add_paused_call(call *call, bool increment) {
  409   call_list *list = call2list(call);
  410   call->pauseit = list->insert(list->end(), call);
  411   if (increment) {
  412     count++;
  413   }
  414 }
  415 
  416 void timewheel::remove_paused_call(call *call) {
  417   call_list *list = call2list(call);
  418   list->erase(call->pauseit);
  419   count--;
  420 }
  421 
  422 timewheel::timewheel() {
  423   count = 0;
  424   wheel_base = clock_tick;
  425 }
  426 
  427 int timewheel::size() {
  428   return count;
  429 }
  430 
  431 /* The caller must delete this list. */
  432 call_list *get_calls_for_socket(struct sipp_socket *socket) {
  433   call_list *l = new call_list;
  434 
  435   socket_call_map_map::iterator map_it = socket_to_calls.find(socket);
  436 
  437   /* No map defined for this socket. */
  438   if (map_it == socket_to_calls.end()) {
  439     return l;
  440   }
  441 
  442   call_map *socket_call_map = (call_map *) map_it->second;
  443   call_map::iterator call_it;
  444 
  445   for (call_it = socket_call_map->begin();
  446        call_it != socket_call_map->end();
  447        call_it++) {
  448   l->insert(l->end(), call_it->second);
  449   }
  450 
  451   return l;
  452 }
  453 
  454 void add_call_to_socket(struct sipp_socket *socket, call *call) {
  455   socket_call_map_map::iterator map_it = socket_to_calls.find(socket);
  456   /* No map defined for this socket. */
  457   if (map_it == socket_to_calls.end()) {
  458     socket_to_calls.insert(socket_map_pair(socket, new call_map));
  459     map_it = socket_to_calls.find(socket);
  460     assert(map_it != socket_to_calls.end());
  461   }
  462 
  463  call_map *socket_call_map = (call_map *) map_it->second;
  464  socket_call_map->insert(string_call_pair(call->id, call));
  465 }
  466 
  467 void remove_call_from_socket(struct sipp_socket *socket, call *call) {
  468   socket_call_map_map::iterator map_it = socket_to_calls.find(socket);
  469   /* We must have  a map for this socket. */
  470   assert(map_it != socket_to_calls.end());
  471 
  472   call_map *socket_call_map = (call_map *) map_it->second;
  473   call_map::iterator call_it = socket_call_map->find(call->id);
  474   /* And our call must exist in the map. */
  475   assert(call_it != socket_call_map->end());
  476   socket_call_map->erase(call_it);
  477 
  478   /* If we have no more calls, we can delete this entry. */
  479   if (socket_call_map->begin() == socket_call_map->end()) {
  480     delete socket_call_map;
  481     socket_to_calls.erase(map_it);
  482   }
  483 }
  484 
  485 #ifdef PCAPPLAY
  486 /******* Media information management *************************/
  487 /*
  488  * Look for "c=IN IP4 " pattern in the message and extract the following value
  489  * which should be IP address
  490  */
  491 uint32_t get_remote_ip_media(char *msg)
  492 {
  493     char pattern[] = "c=IN IP4 ";
  494     char *begin, *end;
  495     char ip[32];
  496     begin = strstr(msg, pattern);
  497     if (!begin) {
  498       /* Can't find what we're looking at -> return no address */
  499       return INADDR_NONE;
  500     }
  501     begin += sizeof("c=IN IP4 ") - 1;
  502     end = strstr(begin, "\r\n");
  503     if (!end)
  504       return INADDR_NONE;
  505     memset(ip, 0, 32);
  506     strncpy(ip, begin, end - begin);
  507     return inet_addr(ip);
  508 }
  509 
  510 /*
  511  * Look for "c=IN IP6 " pattern in the message and extract the following value
  512  * which should be IPv6 address
  513  */
  514 uint8_t get_remote_ipv6_media(char *msg, struct in6_addr addr)
  515 {
  516     char pattern[] = "c=IN IP6 ";
  517     char *begin, *end;
  518     char ip[128];
  519 
  520     memset(&addr, 0, sizeof(addr));
  521     memset(ip, 0, 128);
  522 
  523     begin = strstr(msg, pattern);
  524     if (!begin) {
  525       /* Can't find what we're looking at -> return no address */
  526       return 0;
  527     }
  528     begin += sizeof("c=IN IP6 ") - 1;
  529     end = strstr(begin, "\r\n");
  530     if (!end)
  531       return 0;
  532     strncpy(ip, begin, end - begin);
  533     if (!inet_pton(AF_INET6, ip, &addr)) {
  534       return 0;
  535     }
  536     return 1;
  537 }
  538 
  539 /*
  540  * Look for "m=audio " pattern in the message and extract the following value
  541  * which should be port number
  542  */
  543 uint16_t get_remote_audio_port_media(char *msg)
  544 {
  545     char pattern[] = "m=audio ";
  546     char *begin, *end;
  547     char number[6];
  548     begin = strstr(msg, pattern);
  549     if (!begin) {
  550       /* m=audio not found */
  551       return 0;
  552     }
  553     begin += sizeof("m=audio ") - 1;
  554     end = strstr(begin, "\r\n");
  555     if (!end)
  556       ERROR("get_remote_audio_port_media: no CRLF found");
  557     memset(number, 0, sizeof(number));
  558     strncpy(number, begin, sizeof(number) - 1);
  559     return atoi(number);
  560 }
  561 
  562 /*
  563  * Look for "m=video " pattern in the message and extract the following value
  564  * which should be port number
  565  */
  566 uint16_t get_remote_video_port_media(char *msg)
  567 {
  568     char pattern[] = "m=video ";
  569     char *begin, *end;
  570     char number[5];
  571     begin = strstr(msg, pattern);
  572     if (!begin) {
  573       /* m=video not found */
  574       return 0;
  575     }
  576     begin += sizeof("m=video ") - 1;
  577     end = strstr(begin, "\r\n");
  578     if (!end)
  579       ERROR("get_remote_video_port_media: no CRLF found");
  580     memset(number, 0, 5);
  581     strncpy(number, begin, end - begin);
  582     return atoi(number);
  583 }
  584 
  585 /*
  586  * IPv{4,6} compliant
  587  */
  588 void call::get_remote_media_addr(char *msg) {
  589   uint16_t video_port, audio_port;
  590   if (media_ip_is_ipv6) {
  591   struct in6_addr ip_media;
  592     if (get_remote_ipv6_media(msg, ip_media)) {
  593       audio_port = get_remote_audio_port_media(msg);
  594       if (audio_port) {
  595         /* We have audio in the SDP: set the to_audio addr */
  596         (_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_flowinfo = 0;
  597         (_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_scope_id = 0;
  598         (_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_family = AF_INET6;
  599         (_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_port = audio_port;
  600         (_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_addr = ip_media;
  601       }
  602       video_port = get_remote_video_port_media(msg);
  603       if (video_port) {
  604         /* We have video in the SDP: set the to_video addr */
  605         (_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_flowinfo = 0;
  606         (_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_scope_id = 0;
  607         (_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_family = AF_INET6;
  608         (_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_port = video_port;
  609         (_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_addr = ip_media;
  610       }
  611       hasMediaInformation = 1;
  612     }
  613   }
  614   else {
  615     uint32_t ip_media;
  616     ip_media = get_remote_ip_media(msg);
  617     if (ip_media != INADDR_NONE) {
  618       audio_port = get_remote_audio_port_media(msg);
  619       if (audio_port) {
  620         /* We have audio in the SDP: set the to_audio addr */
  621         (_RCAST(struct sockaddr_in *, &(play_args_a.to)))->sin_family = AF_INET;
  622         (_RCAST(struct sockaddr_in *, &(play_args_a.to)))->sin_port = audio_port;
  623         (_RCAST(struct sockaddr_in *, &(play_args_a.to)))->sin_addr.s_addr = ip_media;
  624       }
  625       video_port = get_remote_video_port_media(msg);
  626       if (video_port) {
  627         /* We have video in the SDP: set the to_video addr */
  628         (_RCAST(struct sockaddr_in *, &(play_args_v.to)))->sin_family = AF_INET;
  629         (_RCAST(struct sockaddr_in *, &(play_args_v.to)))->sin_port = video_port;
  630         (_RCAST(struct sockaddr_in *, &(play_args_v.to)))->sin_addr.s_addr = ip_media;
  631       }
  632       hasMediaInformation = 1;
  633     }
  634   }
  635 }
  636 
  637 #endif
  638 
  639 /******* Very simple hash for retransmission detection  *******/
  640 
  641 unsigned long hash(char * msg) {
  642   unsigned long hash = 0;
  643   int c;
  644 
  645   while (c = *msg++)
  646     hash = c + (hash << 6) + (hash << 16) - hash;
  647 
  648   return hash;
  649 }
  650 
  651 /******************* Call class implementation ****************/
  652 
  653 call::call(char * p_id, int userId, bool ipv6, bool isAutomatic) : use_ipv6(ipv6)
  654 {
  655   memset(this, 0, sizeof(call));
  656   id = strdup(p_id);
  657   start_time = clock_tick;
  658   call_established=false ;
  659   count_in_stats=true ;
  660   ack_is_pending=false ;
  661   last_recv_msg = NULL;
  662   cseq = base_cseq;
  663   nb_last_delay = 0;
  664   tdm_map_number = 0;
  665 
  666 #ifdef _USE_OPENSSL
  667   m_ctx_ssl = NULL ;
  668   m_bio = NULL ;
  669 #endif
  670 
  671   call_remote_socket = 0;
  672 
  673   // initialising the CallVariable with the Scenario variable
  674   int i;
  675   if (maxVariableUsed >= 0) {
  676   M_callVariableTable = new CCallVariable *[maxVariableUsed + 1];
  677   }
  678   for(i=0; i<=maxVariableUsed; i++)
  679     {
  680       if (variableUsed[i]) {
  681         M_callVariableTable[i] = new CCallVariable();
  682         if (M_callVariableTable[i] == NULL) {
  683           ERROR ("call variable allocation failed");
  684         }
  685       } else {
  686         M_callVariableTable[i] = NULL;
  687       }
  688     }
  689 
  690   // If not updated by a message we use the start time
  691   // information to compute rtd information
  692   for (i = 0; i < MAX_RTD_INFO_LENGTH; i++) {
  693     start_time_rtd[i] = getmicroseconds();
  694     rtd_done[i] = false;
  695   }
  696 
  697   // by default, last action result is NO_ERROR
  698   last_action_result = call::E_AR_NO_ERROR;
  699 
  700   this->userId = userId;
  701 
  702   /* For automatic answer calls to an out of call request, we must not */
  703   /* increment the input files line numbers to not disturb */
  704   /* the input files read mechanism (otherwise some lines risk */
  705   /* to be systematically skipped */
  706   if (!isAutomatic) {
  707     m_lineNumber = new file_line_map();
  708     for (file_map::iterator file_it = inFiles.begin();
  709   file_it != inFiles.end();
  710   file_it++) {
  711       (*m_lineNumber)[file_it->first] = file_it->second->nextLine(userId);
  712     }
  713   }
  714 
  715 #ifdef PCAPPLAY
  716   memset(&(play_args_a.to), 0, sizeof(struct sockaddr_storage));
  717   memset(&(play_args_v.to), 0, sizeof(struct sockaddr_storage));
  718   memset(&(play_args_a.from), 0, sizeof(struct sockaddr_storage));
  719   memset(&(play_args_v.from), 0, sizeof(struct sockaddr_storage));
  720   hasMediaInformation = 0;
  721   media_thread = 0;
  722 #endif
  723 
  724   peer_tag = NULL;
  725   recv_timeout = 0;
  726   send_timeout = 0;
  727 }
  728 
  729 call::~call()
  730 {
  731   deleted += 1;
  732 
  733   if(comp_state) { comp_free(&comp_state); }
  734 
  735   if(count_in_stats) {
  736     CStat::instance()->computeStat(CStat::E_ADD_CALL_DURATION,
  737                                    clock_tick - start_time);
  738   }
  739 
  740   sipp_close_socket(dissociate_socket());
  741   if (call_remote_socket) {
  742     sipp_close_socket(call_remote_socket);
  743   }
  744 
  745   /* Deletion of the call variable */
  746   for(int i=0; i<=maxVariableUsed; i++) {
  747     if(M_callVariableTable[i] != NULL) {
  748       delete M_callVariableTable[i] ;
  749       M_callVariableTable[i] = NULL;
  750     }
  751   }
  752   if(M_callVariableTable) { delete M_callVariableTable; }
  753   delete m_lineNumber;
  754   if (userId) {
  755     freeUsers.push_front(userId);
  756   }
  757 
  758   if(id) { free(id); }
  759   if(last_recv_msg) { free(last_recv_msg); }
  760   if(last_send_msg) { free(last_send_msg); }
  761   if(peer_tag) { free(peer_tag); }
  762 
  763   if(dialog_route_set) {
  764        free(dialog_route_set);
  765   }
  766 
  767   if(next_req_url) {
  768        free(next_req_url);
  769   }
  770 
  771 
  772 #ifdef _USE_OPENSSL
  773   if(dialog_authentication) {
  774        free(dialog_authentication);
  775   }
  776 #endif
  777   call_established= false ;
  778 }
  779 
  780 void call::connect_socket_if_needed()
  781 {
  782   bool existing;
  783 
  784   if(call_socket) return;
  785   if(!multisocket) return;
  786 
  787   if(transport == T_UDP) {
  788     struct sockaddr_storage saddr;
  789 
  790     if(toolMode != MODE_CLIENT)
  791       return;
  792 
  793     char peripaddr[256];
  794     if (!peripsocket) {
  795       if ((associate_socket(new_sipp_call_socket(use_ipv6, transport, &existing))) == NULL) {
  796   ERROR_NO("Unable to get a UDP socket");
  797       }
  798     } else {
  799       char *tmp = peripaddr;
  800       getFieldFromInputFile(ip_file, peripfield, tmp);
  801       map<string, struct sipp_socket *>::iterator i;
  802       i = map_perip_fd.find(peripaddr);
  803       if (i == map_perip_fd.end()) {
  804   // Socket does not exist
  805   if ((associate_socket(new_sipp_call_socket(use_ipv6, transport, &existing))) == NULL) {
  806     ERROR_NO("Unable to get a UDP socket");
  807   } else {
  808     /* Ensure that it stays persistent, because it is recorded in the map. */
  809     call_socket->ss_count++;
  810     map_perip_fd[peripaddr] = call_socket;
  811   }
  812       } else {
  813   // Socket exists already
  814   associate_socket(i->second);
  815   existing = true;
  816   i->second->ss_count++;
  817       }
  818     }
  819     if (existing) {
  820   return;
  821     }
  822 
  823     memset(&saddr, 0, sizeof(struct sockaddr_storage));
  824 
  825     memcpy(&saddr,
  826      local_addr_storage->ai_addr,
  827            SOCK_ADDR_SIZE(
  828              _RCAST(struct sockaddr_storage *,local_addr_storage->ai_addr)));
  829 
  830     if (use_ipv6) {
  831       saddr.ss_family       = AF_INET6;
  832     } else {
  833       saddr.ss_family       = AF_INET;
  834     }
  835 
  836     if (peripsocket) {
  837       struct addrinfo * h ;
  838       struct addrinfo   hints;
  839       memset((char*)&hints, 0, sizeof(hints));
  840       hints.ai_flags  = AI_PASSIVE;
  841       hints.ai_family = PF_UNSPEC;
  842       getaddrinfo(peripaddr,
  843                   NULL,
  844                   &hints,
  845                   &h);
  846       memcpy(&saddr,
  847              h->ai_addr,
  848              SOCK_ADDR_SIZE(
  849                 _RCAST(struct sockaddr_storage *,h->ai_addr)));
  850 
  851       if (use_ipv6) {
  852        (_RCAST(struct sockaddr_in6 *, &saddr))->sin6_port = htons(local_port);
  853       } else {
  854        (_RCAST(struct sockaddr_in *, &saddr))->sin_port = htons(local_port);
  855       }
  856     }
  857 
  858     if (sipp_bind_socket(call_socket, &saddr, &call_port)) {
  859       ERROR_NO("Unable to bind UDP socket");
  860     }
  861   } else { /* TCP or TLS. */
  862     struct sockaddr_storage *L_dest = &remote_sockaddr;
  863 
  864     if ((associate_socket(new_sipp_call_socket(use_ipv6, transport, &existing))) == NULL) {
  865       ERROR_NO("Unable to get a TCP socket");
  866     }
  867 
  868     if (existing) {
  869       return;
  870     }
  871 
  872     sipp_customize_socket(call_socket);
  873 
  874     if (use_remote_sending_addr) {
  875       L_dest = &remote_sending_sockaddr;
  876     }
  877 
  878     if (sipp_connect_socket(call_socket, L_dest)) {
  879       if (reset_number > 0) {
  880         if(errno == EINVAL){
  881           /* This occurs sometime on HPUX but is not a true INVAL */
  882           WARNING("Unable to connect a TCP socket, remote peer error");
  883         } else {
  884           WARNING("Unable to connect a TCP socket");
  885         }
  886         start_calls = 1;
  887       } else {
  888   if(errno == EINVAL){
  889     /* This occurs sometime on HPUX but is not a true INVAL */
  890     ERROR("Unable to connect a TCP socket, remote peer error");
  891   } else {
  892     ERROR_NO("Unable to connect a TCP socket");
  893   }
  894       }
  895     }
  896   }
  897 }
  898 
  899 bool lost(int index)
  900 {
  901   static int inited = 0;
  902   double percent = global_lost;
  903 
  904   if(!lose_packets) return false;
  905 
  906   if (scenario[index]->lost >= 0) {
  907     percent = scenario[index]->lost;
  908   }
  909 
  910   if (percent == 0) {
  911     return false;
  912   }
  913 
  914   if(!inited) {
  915     srand((unsigned int) time(NULL));
  916     inited = 1;
  917   }
  918 
  919   return (((double)rand() / (double)RAND_MAX) < (percent / 100.0));
  920 }
  921 
  922 int call::send_raw(char * msg, int index)
  923 {
  924   struct sipp_socket *sock;
  925   int rc;
  926 
  927   if (useShortMessagef == 1) {
  928       struct timeval currentTime;
  929       GET_TIME (&currentTime);
  930       char* cs=get_header_content(msg,"CSeq:");
  931       TRACE_SHORTMSG((s, "%s\tS\t%s\tCSeq:%s\t%s\n",
  932              CStat::instance()->formatTime(&currentTime),id, cs, get_first_line(msg)));
  933   }
  934 
  935   if((index!=-1) && (lost(index))) {
  936     TRACE_MSG((s, "%s message voluntary lost (while sending).", TRANSPORT_TO_STRING(transport)));
  937 
  938     if(comp_state) { comp_free(&comp_state); }
  939     scenario[index] -> nb_lost++;
  940     return 0;
  941   }
  942 
  943   sock = call_socket;
  944 
  945   if ((use_remote_sending_addr) && (toolMode == MODE_SERVER)) {
  946     if (!call_remote_socket) {
  947       struct sockaddr_storage *L_dest = &remote_sending_sockaddr;
  948 
  949       if((call_remote_socket= new_sipp_socket(use_ipv6, transport)) == NULL) {
  950   ERROR_NO("Unable to get a socket for rsa option");
  951       }
  952 
  953       sipp_customize_socket(call_remote_socket);
  954 
  955       if(transport != T_UDP) {
  956   if (sipp_connect_socket(call_remote_socket, L_dest)) {
  957     if(errno == EINVAL){
  958       /* This occurs sometime on HPUX but is not a true INVAL */
  959       ERROR_P1("Unable to connect a %s socket for rsa option, remote peer error", TRANSPORT_TO_STRING(transport));
  960     } else {
  961       ERROR_NO("Unable to connect a socket for rsa option");
  962     }
  963   }
  964       }
  965     }
  966     sock=call_remote_socket ;
  967   }
  968 
  969   rc = write_socket(sock, msg, strlen(msg), WS_BUFFER);
  970   if(rc == -1 && errno == EWOULDBLOCK) {
  971     return -1;
  972   }
  973 
  974   if(rc < 0) {
  975     CStat::instance()->computeStat(CStat::E_CALL_FAILED);
  976     CStat::instance()->computeStat(CStat::E_FAILED_CANNOT_SEND_MSG);
  977     delete_call(id);
  978   }
  979 
  980   return rc; /* OK */
  981 }
  982 
  983 /* This method is used to send messages that are not */
  984 /* part of the XML scenario                          */
  985 void call::sendBuffer(char * msg)
  986 {
  987   /* call send_raw but with a special scenario index */
  988   if (send_raw(msg, -1) < 0) {
  989     ERROR_NO("Error sending raw message");
  990   }
  991 }
  992 
  993 
  994 char * call::compute_cseq(char * src)
  995 {
  996   static char cseq[MAX_HEADER_LEN];
  997 
  998     /* If we find a CSeq in incoming msg */
  999   char * last_header = get_last_header("CSeq:");
 1000     if(last_header) {
 1001       int i;
 1002       /* Extract the integer value of the last CSeq */
 1003       last_header = strstr(last_header, ":");
 1004       last_header++;
 1005       while(isspace(*last_header)) last_header++;
 1006       sscanf(last_header,"%d", &i);
 1007       /* Add 1 to the last CSeq value */
 1008       sprintf(cseq, "%s%d",  "CSeq: ", (i+1));
 1009     } else {
 1010       sprintf(cseq, "%s",  "CSeq: 2");
 1011     }
 1012     return cseq;
 1013 }
 1014 
 1015 char * call::get_header_field_code(char *msg, char * name)
 1016 {
 1017   static char code[MAX_HEADER_LEN];
 1018   char * last_header;
 1019   int i;
 1020 
 1021     last_header = NULL;
 1022     i = 0;
 1023     /* If we find the field in msg */
 1024     last_header = get_header_content(msg, name);
 1025     if(last_header) {
 1026       /* Extract the integer value of the field */
 1027       while(isspace(*last_header)) last_header++;
 1028       sscanf(last_header,"%d", &i);
 1029       sprintf(code, "%s %d", name, i);
 1030     }
 1031     return code;
 1032 }
 1033 
 1034 char * call::get_last_header(char * name)
 1035 {
 1036   int len;
 1037 
 1038   if((!last_recv_msg) || (!strlen(last_recv_msg))) {
 1039     return NULL;
 1040   }
 1041 
 1042   len = strlen(name);
 1043 
 1044   /* Ideally this check should be moved to the XML parser so that it is not
 1045    * along a critical path.  We could also handle lowercasing there. */
 1046   if (len > MAX_HEADER_LEN) {
 1047     ERROR_P2("call::get_last_header: Header to parse bigger than %d (%zu)", MAX_HEADER_LEN, strlen(name));
 1048   }
 1049 
 1050   if (name[len - 1] == ':') {
 1051     return get_header(last_recv_msg, name, false);
 1052   } else {
 1053     char with_colon[MAX_HEADER_LEN];
 1054     sprintf(with_colon, "%s:", name);
 1055     return get_header(last_recv_msg, with_colon, false);
 1056   }
 1057 }
 1058 
 1059 char * call::get_header_content(char* message, char * name)
 1060 {
 1061   return get_header(message, name, true);
 1062 }
 1063 
 1064 /* If content is true, we only return the header's contents. */
 1065 char * call::get_header(char* message, char * name, bool content)
 1066 {
 1067   /* non reentrant. consider accepting char buffer as param */
 1068   static char last_header[MAX_HEADER_LEN * 10];
 1069   char * src, *dest, *start, *ptr;
 1070   /* Are we searching for a short form header? */
 1071   bool short_form = false;
 1072   bool first_time = true;
 1073   char src_tmp[MAX_HEADER_LEN + 1];
 1074 
 1075   /* returns empty string in case of error */
 1076   last_header[0] = '\0';
 1077 
 1078   if((!message) || (!strlen(message))) {
 1079     return last_header;
 1080   }
 1081 
 1082   /* for safety's sake */
 1083   if (NULL == name || NULL == strrchr(name, ':')) {
 1084     WARNING_P1("Can not searching for header (no colon): %s", name ? name : "(null)");
 1085     return last_header;
 1086   }
 1087 
 1088   do
 1089   {
 1090     snprintf(src_tmp, MAX_HEADER_LEN, "\n%s", name);
 1091     src = message;
 1092     dest = last_header;
 1093 
 1094     while(src = strcasestr2(src, src_tmp)) {
 1095       if (content || !first_time) {
 1096         /* just want the header's content */
 1097         src += strlen(name) + 1;
 1098       } else {
 1099        src++;
 1100       }
 1101       first_time = false;
 1102       ptr = strchr(src, '\n');
 1103 
 1104       /* Multiline headers always begin with a tab or a space
 1105        * on the subsequent lines */
 1106       while((ptr) &&
 1107     ((*(ptr+1) == ' ' ) ||
 1108      (*(ptr+1) == '\t')    )) {
 1109   ptr = strchr(ptr + 1, '\n');
 1110       }
 1111 
 1112       if(ptr) { *ptr = 0; }
 1113       // Add "," when several headers are present
 1114       if (dest != last_header) {
 1115   /* Remove trailing whitespaces, tabs, and CRs */
 1116   while ((dest > last_header) &&
 1117       ((*(dest-1) == ' ') || (*(dest-1) == '\r') || (*(dest-1) == '\n') || (*(dest-1) == '\t'))) {
 1118     *(--dest) = 0;
 1119   }
 1120 
 1121   dest += sprintf(dest, ",");
 1122       }
 1123       dest += sprintf(dest, "%s", src);
 1124       if(ptr) { *ptr = '\n'; }
 1125 
 1126       src++;
 1127     }
 1128     /* We found the header. */
 1129     if(dest != last_header) {
 1130   break;
 1131     }
 1132     /* We didn't find the header, even in its short form. */
 1133     if (short_form) {
 1134       return last_header;
 1135     }
 1136 
 1137     /* We should retry with the short form. */
 1138     short_form = true;
 1139     if (!strcasecmp(name, "call-id:")) {
 1140       name = "i:";
 1141     } else if (!strcasecmp(name, "contact:")) {
 1142       name = "m:";
 1143     } else if (!strcasecmp(name, "content-encoding:")) {
 1144       name = "e:";
 1145     } else if (!strcasecmp(name, "content-length:")) {
 1146       name = "l:";
 1147     } else if (!strcasecmp(name, "content-type:")) {
 1148       name = "c:";
 1149     } else if (!strcasecmp(name, "from:")) {
 1150       name = "f:";
 1151     } else if (!strcasecmp(name, "to:")) {
 1152       name = "t:";
 1153     } else if (!strcasecmp(name, "via:")) {
 1154       name = "v:";
 1155     } else {
 1156       /* There is no short form to try. */
 1157       return last_header;
 1158     }
 1159   }
 1160   while (1);
 1161 
 1162   *(dest--) = 0;
 1163 
 1164   /* Remove trailing whitespaces, tabs, and CRs */
 1165   while ((dest > last_header) &&
 1166          ((*dest == ' ') || (*dest == '\r')|| (*dest == '\t'))) {
 1167     *(dest--) = 0;
 1168   }
 1169 
 1170   /* Remove leading whitespaces */
 1171   for (start = last_header; *start == ' '; start++);
 1172 
 1173   /* remove enclosed CRs in multilines */
 1174   /* don't remove enclosed CRs for multiple headers (e.g. Via) (Rhys) */
 1175   while((ptr = strstr(last_header, "\r\n")) != NULL
 1176         && (   *(ptr + 2) == ' '
 1177             || *(ptr + 2) == '\r'
 1178             || *(ptr + 2) == '\t') ) {
 1179     /* Use strlen(ptr) to include trailing zero */
 1180     memmove(ptr, ptr+1, strlen(ptr));
 1181   }
 1182 
 1183   /* Remove illegal double CR characters */
 1184   while((ptr = strstr(last_header, "\r\r")) != NULL) {
 1185     memmove(ptr, ptr+1, strlen(ptr));
 1186   }
 1187   /* Remove illegal double Newline characters */
 1188   while((ptr = strstr(last_header, "\n\n")) != NULL) {
 1189     memmove(ptr, ptr+1, strlen(ptr));
 1190   }
 1191 
 1192   return start;
 1193 }
 1194 
 1195 char * call::get_first_line(char * message)
 1196 {
 1197   /* non reentrant. consider accepting char buffer as param */
 1198   static char last_header[MAX_HEADER_LEN * 10];
 1199   char * src, *dest;
 1200 
 1201   /* returns empty string in case of error */
 1202   memset(last_header, 0, sizeof(last_header));
 1203 
 1204   if((!message) || (!strlen(message))) {
 1205     return last_header;
 1206   }
 1207 
 1208   src = message;
 1209   dest = last_header;
 1210 
 1211   int i=0;
 1212   while (*src){
 1213     if((*src=='\n')||(*src=='\r')){
 1214       break;
 1215     }
 1216     else
 1217     {
 1218       last_header[i]=*src;
 1219     }
 1220     i++;
 1221     src++;
 1222   }
 1223 
 1224   return last_header;
 1225 }
 1226 
 1227 /* Return the last request URI from the To header. On any error returns the
 1228  * empty string.  The caller must free the result. */
 1229 char * call::get_last_request_uri ()
 1230 {
 1231      char * tmp;
 1232      char * tmp2;
 1233      char * last_request_uri;
 1234      int tmp_len;
 1235 
 1236      char * last_To = get_last_header("To:");
 1237      if (!last_To) {
 1238   return strdup("");
 1239      }
 1240 
 1241      tmp = strchr(last_To, '<');
 1242      if (!tmp) {
 1243   return strdup("");
 1244      }
 1245      tmp++;
 1246 
 1247      tmp2 = strchr(last_To, '>');
 1248      if (!tmp2) {
 1249   return strdup("");
 1250      }
 1251 
 1252      tmp_len = strlen(tmp) - strlen(tmp2);
 1253      if (tmp_len < 0) {
 1254   return strdup("");
 1255      }
 1256 
 1257      if(!(last_request_uri = (char *) malloc(tmp_len+1))) ERROR("Cannot allocate !\n");
 1258      memset(last_request_uri, 0, sizeof(last_request_uri));
 1259      if(tmp && (tmp_len > 0)){
 1260        strncpy(last_request_uri, tmp, tmp_len);
 1261      }
 1262      last_request_uri[tmp_len] = '\0';
 1263      return last_request_uri;
 1264 
 1265 }
 1266 
 1267 char * call::send_scene(int index, int *send_status)
 1268 {
 1269   static char msg_buffer[SIPP_MAX_MSG_SIZE];
 1270 
 1271 #define MAX_MSG_NAME_SIZE 30
 1272   static char msg_name[MAX_MSG_NAME_SIZE];
 1273   char *L_ptr1 ;
 1274   char *L_ptr2 ;
 1275 
 1276   /* Socket port must be known before string substitution */
 1277   connect_socket_if_needed();
 1278 
 1279   assert(call_socket);
 1280 
 1281   if (call_socket->ss_congested) {
 1282     *send_status = -1;
 1283     return NULL;
 1284   }
 1285 
 1286   if(scenario[index] -> send_scheme) {
 1287     char * dest;
 1288     dest = createSendingMessage(scenario[index] -> send_scheme, index);
 1289     strcpy(msg_buffer, dest);
 1290 
 1291     if (dest) {
 1292       L_ptr1=msg_name ;
 1293       L_ptr2=msg_buffer ;
 1294       while ((*L_ptr2 != ' ') && (*L_ptr2 != '\n') && (*L_ptr2 != '\t'))  {
 1295         *L_ptr1 = *L_ptr2;
 1296         L_ptr1 ++;
 1297         L_ptr2 ++;
 1298       }
 1299       *L_ptr1 = '\0' ;
 1300     }
 1301 
 1302     if (strcmp(msg_name,"ACK") == 0) {
 1303       call_established = true ;
 1304       ack_is_pending = false ;
 1305     }
 1306 
 1307     if(send_status) {
 1308       *send_status = send_raw(msg_buffer, index);
 1309     } else {
 1310       send_raw(msg_buffer, index);
 1311     }
 1312   } else {
 1313     ERROR("Unsupported 'send' message in scenario");
 1314   }
 1315 
 1316   return msg_buffer;
 1317 }
 1318 
 1319 void call::do_bookkeeping(int index) {
 1320   /* If this message increments a counter, do it now. */
 1321   if(int counter = scenario[index] -> counter) {
 1322     CStat::instance()->computeStat(CStat::E_ADD_GENERIC_COUNTER, 1, counter - 1);
 1323   }
 1324 
 1325   /* If this message can be used to compute RTD, do it now */
 1326   if(int rtd = scenario[index] -> start_rtd) {
 1327     start_time_rtd[rtd - 1] = getmicroseconds();
 1328   }
 1329 
 1330   if(int rtd = scenario[index] -> stop_rtd) {
 1331     if (!rtd_done[rtd - 1]) {
 1332       unsigned long long start = start_time_rtd[rtd - 1];
 1333       unsigned long long end = getmicroseconds();
 1334 
 1335       if(dumpInRtt) {
 1336   CStat::instance()->computeRtt(start, end, rtd);
 1337       }
 1338 
 1339       CStat::instance()->computeStat(CStat::E_ADD_RESPONSE_TIME_DURATION,
 1340     (end - start) / 1000, rtd - 1);
 1341 
 1342       if (!scenario[index] -> repeat_rtd) {
 1343   rtd_done[rtd - 1] = true;
 1344       }
 1345     }
 1346   }
 1347 }
 1348 
 1349 bool call::next()
 1350 {
 1351   int test = scenario[msg_index]->test;
 1352   /* What is the next message index? */
 1353   /* Default without branching: use the next message */
 1354   int new_msg_index = msg_index+1;
 1355   /* If branch needed, overwrite this default */
 1356   if ( scenario[msg_index]->next &&
 1357        ((test == -1) ||
 1358         (test <= maxVariableUsed && M_callVariableTable[test] != NULL && M_callVariableTable[test]->isSet()))
 1359      ) {
 1360     /* Branching possible, check the probability */
 1361     int chance = scenario[msg_index]->chance;
 1362     if ((chance <= 0) || (rand() > chance )) {
 1363       /* Branch == overwrite with the 'next' attribute value */
 1364       new_msg_index = labelArray[scenario[msg_index]->next];
 1365     }
 1366   }
 1367   msg_index=new_msg_index;
 1368   recv_timeout = 0;
 1369   if(msg_index >= scenario_len) {
 1370     // Call end -> was it successful?
 1371     if(call::last_action_result != call::E_AR_NO_ERROR) {
 1372       switch(call::last_action_result) {
 1373         case call::E_AR_REGEXP_DOESNT_MATCH:
 1374           CStat::instance()->computeStat(CStat::E_CALL_FAILED);
 1375           CStat::instance()->computeStat(CStat::E_FAILED_REGEXP_DOESNT_MATCH);
 1376           break;
 1377         case call::E_AR_HDR_NOT_FOUND:
 1378           CStat::instance()->computeStat(CStat::E_CALL_FAILED);
 1379           CStat::instance()->computeStat(CStat::E_FAILED_REGEXP_HDR_NOT_FOUND);
 1380           break;
 1381   case call::E_AR_NO_ERROR:
 1382   case call::E_AR_STOP_CALL:
 1383     /* Do nothing. */
 1384     break;
 1385       }
 1386     } else {
 1387       CStat::instance()->computeStat(CStat::E_CALL_SUCCESSFULLY_ENDED);
 1388     }
 1389     delete_call(id);
 1390     return false;
 1391   }
 1392 
 1393   return run();
 1394 }
 1395 
 1396 bool call::run()
 1397 {
 1398   bool            bInviteTransaction = false;
 1399   int             actionResult = 0;
 1400 
 1401   assert(running);
 1402 
 1403   clock_tick = getmilliseconds();
 1404 
 1405   if(msg_index >= scenario_len) {
 1406     ERROR_P3("Scenario overrun for call %s (%p) (index = %d)\n",
 1407              id, this, msg_index);
 1408   }
 1409 
 1410   /* Manages retransmissions or delete if max retrans reached */
 1411   if(next_retrans && (next_retrans < clock_tick)) {
 1412     nb_retrans++;
 1413 
 1414     if ( (0 == strncmp (last_send_msg, "INVITE", 6)) )
 1415     {
 1416       bInviteTransaction = true;
 1417     }
 1418 
 1419     if((nb_retrans > (bInviteTransaction ? max_invite_retrans : max_non_invite_retrans)) ||
 1420        (nb_retrans > max_udp_retrans)) {
 1421       scenario[last_send_index] -> nb_timeout ++;
 1422       if (scenario[last_send_index]->on_timeout) {  // action on timeout
 1423           WARNING_P3("Call-Id: %s, timeout on max UDP retrans for message %d, jumping to label %d ",
 1424                       id, msg_index, scenario[last_send_index]->on_timeout);
 1425           msg_index = labelArray[scenario[last_send_index]->on_timeout];
 1426           next_retrans = 0;
 1427           recv_timeout = 0;
 1428           if (msg_index < scenario_len) {
 1429     return true;
 1430     }
 1431 
 1432           // here if asked to go to the last label  delete the call
 1433           CStat::instance()->computeStat(CStat::E_CALL_FAILED);
 1434           CStat::instance()->computeStat(CStat::E_FAILED_MAX_UDP_RETRANS);
 1435           if (default_behavior) {
 1436             // Abort the call by sending proper SIP message
 1437             return(abortCall());
 1438           } else {
 1439             // Just delete existing call
 1440             delete_call(id);
 1441             return false;
 1442           }
 1443       }
 1444       CStat::instance()->computeStat(CStat::E_CALL_FAILED);
 1445       CStat::instance()->computeStat(CStat::E_FAILED_MAX_UDP_RETRANS);
 1446       if (default_behavior) {
 1447         // Abort the call by sending proper SIP message
 1448         WARNING_P1("Aborting call on UDP retransmission timeout for Call-ID '%s'", id);
 1449         return(abortCall());
 1450       } else {
 1451         // Just delete existing call
 1452         delete_call(id);
 1453         return false;
 1454       }
 1455     } else {
 1456       nb_last_delay *= 2;
 1457       if (DEFAULT_T2_TIMER_VALUE < nb_last_delay)
 1458       {
 1459         if (!bInviteTransaction)
 1460         {
 1461           nb_last_delay = DEFAULT_T2_TIMER_VALUE;
 1462       }
 1463       }
 1464       if(send_raw(last_send_msg, last_send_index) < -1) {
 1465         return false;
 1466       }
 1467       scenario[last_send_index] -> nb_sent_retrans++;
 1468       CStat::instance()->computeStat(CStat::E_RETRANSMISSION);
 1469       next_retrans = clock_tick + nb_last_delay;
 1470     }
 1471   }
 1472 
 1473   if(paused_until) {
 1474     /* Process a pending pause instruction until delay expiration */
 1475     if(paused_until > clock_tick) {
 1476       if (!remove_running_call(this)) {
 1477   ERROR("Tried to remove a running call that wasn't running!\n");
 1478       }
 1479       paused_calls.add_paused_call(this, true);
 1480       return true;
 1481     }
 1482     /* Our pause is over. */
 1483     paused_until = 0;
 1484     return next();
 1485   } else if(scenario[msg_index] -> pause_distribution || scenario[msg_index]->pause_variable) {
 1486     unsigned int pause;
 1487     if (scenario[msg_index]->pause_distribution) {
 1488       pause  = (int)(scenario[msg_index] -> pause_distribution -> sample());
 1489     } else {
 1490       int varId = scenario[msg_index]->pause_variable;
 1491       if(varId <= maxVariableUsed && M_callVariableTable[varId]) {
 1492   pause = (int) M_callVariableTable[varId]->getDouble();
 1493       } else {
 1494   pause = 0;
 1495       }
 1496     }
 1497     if (pause < 0) {
 1498       pause = 0;
 1499     }
 1500     if (pause > INT_MAX) {
 1501       pause = INT_MAX;
 1502     }
 1503     paused_until = clock_tick + pause;
 1504 
 1505     /* Increment the number of sessions in pause state */
 1506     ++scenario[msg_index]->sessions;
 1507     return run(); /* In case delay is 0 */
 1508   }
 1509 #ifdef __3PCC__
 1510   else if(scenario[msg_index] -> M_type == MSG_TYPE_SENDCMD) {
 1511     int send_status;
 1512 
 1513     if(next_retrans) {
 1514       return true;
 1515     }
 1516 
 1517     send_status = sendCmdMessage(msg_index);
 1518 
 1519     if(send_status != 0) { /* Send error */
 1520       return false; /* call deleted */
 1521     }
 1522     scenario[msg_index] -> M_nbCmdSent++;
 1523     next_retrans = 0;
 1524     return(next());
 1525   }
 1526 #endif
 1527   else if(scenario[msg_index] -> M_type == MSG_TYPE_NOP) {
 1528     do_bookkeeping(msg_index);
 1529     actionResult = executeAction(NULL, msg_index);
 1530     return(next());
 1531   }
 1532 
 1533   else if(scenario[msg_index] -> send_scheme) {
 1534     char * msg_snd;
 1535     int send_status;
 1536 
 1537     /* Do not send a new message until the previous one which had
 1538      * retransmission enabled is acknowledged */
 1539 
 1540     if(next_retrans) {
 1541       if (!remove_running_call(this)) {
 1542   ERROR("Tried to remove a running call that wasn't running!\n");
 1543       }
 1544       paused_calls.add_paused_call(this, true);
 1545       return true;
 1546     }
 1547 
 1548     /* Handle counters and RTDs for this message. */
 1549     do_bookkeeping(msg_index);
 1550 
 1551     /* decide whether to increment cseq or not
 1552      * basically increment for anything except response, ACK or CANCEL
 1553      * Note that cseq is only used by the [cseq] keyword, and
 1554      * not by default
 1555      */
 1556 
 1557     int incr_cseq = 0;
 1558     if (!scenario[msg_index]->send_scheme->isAck() &&
 1559         !scenario[msg_index]->send_scheme->isCancel() &&
 1560         !scenario[msg_index]->send_scheme->isResponse()) {
 1561           ++cseq;
 1562           incr_cseq = 1;
 1563     }
 1564 
 1565     msg_snd = send_scene(msg_index, &send_status);
 1566     if(send_status == -1 && errno == EWOULDBLOCK) {
 1567       if (incr_cseq) --cseq;
 1568       /* Have we set the timeout yet? */
 1569       if (send_timeout) {
 1570   /* If we have actually timed out. */
 1571   if (clock_tick > send_timeout) {
 1572     WARNING_P2("Call-Id: %s, send timeout on message %d: aborting call",
 1573         id, msg_index);
 1574     CStat::instance()->computeStat(CStat::E_CALL_FAILED);
 1575     CStat::instance()->computeStat(CStat::E_FAILED_TIMEOUT_ON_SEND);
 1576     if (default_behavior) {
 1577       return (abortCall());
 1578     } else {
 1579       delete_call(id);
 1580       return false;
 1581     }
 1582   }
 1583       } else if (scenario[msg_index]->timeout) {
 1584   /* Initialize the send timeout to the per message timeout. */
 1585   send_timeout = clock_tick + scenario[msg_index]->timeout;
 1586       } else if (defl_send_timeout) {
 1587   /* Initialize the send timeout to the global timeout. */
 1588   send_timeout = clock_tick + defl_send_timeout;
 1589       }
 1590       return true; /* No step, nothing done, retry later */
 1591     } else if(send_status < 0) { /* Send error */
 1592       /* The timeout will not be sent, so the timeout is no longer needed. */
 1593       send_timeout = 0;
 1594       return false; /* call deleted */
 1595     }
 1596     /* We have sent the message, so the timeout is no longer needed. */
 1597     send_timeout = 0;
 1598 
 1599     last_send_index = msg_index;
 1600     last_send_msg = (char *) realloc(last_send_msg, strlen(msg_snd) + 1);
 1601     strcpy(last_send_msg, msg_snd);
 1602 
 1603     if(last_recv_hash) {
 1604       /* We are sending just after msg reception. There is a great
 1605        * chance that we will be asked to retransmit this message */
 1606       recv_retrans_hash       = last_recv_hash;
 1607       recv_retrans_recv_index = last_recv_index;
 1608       recv_retrans_send_index = msg_index;
 1609 
 1610       /* Prevent from detecting the cause relation between send and recv
 1611        * in the next valid send */
 1612       last_recv_hash = 0;
 1613     }
 1614 
 1615     /* Update retransmission information */
 1616     if(scenario[msg_index] -> retrans_delay) {
 1617       if((transport == T_UDP) && (retrans_enabled)) {
 1618         next_retrans = clock_tick + scenario[msg_index] -> retrans_delay;
 1619         nb_retrans = 0;
 1620         nb_last_delay = scenario[msg_index]->retrans_delay;
 1621       }
 1622     } else {
 1623       next_retrans = 0;
 1624     }
 1625 
 1626 #ifdef PCAPPLAY
 1627     actionResult = executeAction(msg_snd, msg_index);
 1628 #endif
 1629 
 1630     /* Update scenario statistics */
 1631     scenario[msg_index] -> nb_sent++;
 1632 
 1633     return next();
 1634   } else if (scenario[msg_index]->M_type == MSG_TYPE_RECV
 1635 #ifdef __3PCC__
 1636          || scenario[msg_index]->M_type == MSG_TYPE_RECVCMD
 1637 #endif
 1638                                                  ) {
 1639     if (recv_timeout) {
 1640       if(recv_timeout > clock_tick || recv_timeout > getmilliseconds()) {
 1641   if (!remove_running_call(this)) {
 1642     ERROR("Tried to remove a running call that wasn't running!\n");
 1643   }
 1644   paused_calls.add_paused_call(this, true);
 1645   return true;
 1646       }
 1647       recv_timeout = 0;
 1648       ++scenario[msg_index]->nb_timeout;
 1649       if (scenario[msg_index]->on_timeout == 0) {
 1650         // if you set a timeout but not a label, the call is aborted
 1651         WARNING_P2("Call-Id: %s, receive timeout on message %d without label to jump to (ontimeout attribute): aborting call",
 1652                    id, msg_index);
 1653         CStat::instance()->computeStat(CStat::E_CALL_FAILED);
 1654         CStat::instance()->computeStat(CStat::E_FAILED_TIMEOUT_ON_RECV);
 1655         if (default_behavior) {
 1656           return (abortCall());
 1657         } else {
 1658           delete_call(id);
 1659           return false;
 1660         }
 1661       }
 1662       WARNING_P3("Call-Id: %s, receive timeout on message %d, jumping to label %d",
 1663                   id, msg_index, scenario[msg_index]->on_timeout);
 1664       msg_index = labelArray[scenario[msg_index]->on_timeout];
 1665       recv_timeout = 0;
 1666       if (msg_index < scenario_len) return true;
 1667       // special case - the label points to the end - finish the call
 1668       CStat::instance()->computeStat(CStat::E_CALL_FAILED);
 1669       CStat::instance()->computeStat(CStat::E_FAILED_TIMEOUT_ON_RECV);
 1670       if (default_behavior) {
 1671         return (abortCall());
 1672       } else {
 1673         delete_call(id);
 1674         return false;
 1675       }
 1676     } else if ((scenario[msg_index]->timeout) || (defl_recv_timeout)) {
 1677       if (scenario[msg_index]->timeout)
 1678         // If timeout is specified on message receive, use it
 1679         recv_timeout = getmilliseconds() + scenario[msg_index]->timeout;
 1680       else
 1681         // Else use the default timeout if specified
 1682         recv_timeout = getmilliseconds() + defl_recv_timeout;
 1683   return true;
 1684     } else {
 1685   /* We are going to wait forever. */
 1686   if (!remove_running_call(this)) {
 1687     ERROR("Tried to remove a running call that wasn't running!\n");
 1688   }
 1689   paused_calls.add_paused_call(this, true);
 1690     }
 1691   }
 1692   return true;
 1693 }
 1694 
 1695 bool call::process_unexpected(char * msg)
 1696 {
 1697   char buffer[MAX_HEADER_LEN];
 1698   char *desc = buffer;
 1699 
 1700   scenario[msg_index] -> nb_unexp++;
 1701 
 1702   if (default_behavior) {
 1703   desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "Aborting ");
 1704   } else {
 1705   desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "Continuing ");
 1706   }
 1707   desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "call on unexpected message for Call-Id '%s': ", id);
 1708 
 1709   if (scenario[msg_index] -> M_type == MSG_TYPE_RECV) {
 1710     if (scenario[msg_index] -> recv_request) {
 1711       desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while expecting '%s' ", scenario[msg_index] -> recv_request);
 1712     } else {
 1713       desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while expecting '%d' ", scenario[msg_index] -> recv_response);
 1714     }
 1715   } else if (scenario[msg_index] -> M_type == MSG_TYPE_SEND) {
 1716       desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while sending ");
 1717   } else if (scenario[msg_index] -> M_type == MSG_TYPE_PAUSE) {
 1718       desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while pausing ");
 1719   } else if (scenario[msg_index] -> M_type == MSG_TYPE_SENDCMD) {
 1720       desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while sending command ");
 1721   } else if (scenario[msg_index] -> M_type == MSG_TYPE_RECVCMD) {
 1722       desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while expecting command ");
 1723   } else {
 1724       desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while in message type %d ", scenario[msg_index]->M_type);
 1725   }
 1726   desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "(index %d)", msg_index);
 1727 
 1728   WARNING_P2("%s, received '%s'", buffer, msg);
 1729 
 1730   TRACE_MSG((s, "-----------------------------------------------\n"
 1731              "Unexpected %s message received:\n\n%s\n",
 1732              TRANSPORT_TO_STRING(transport),
 1733              msg));
 1734 
 1735   if (default_behavior) {
 1736     // if twin socket call => reset the other part here
 1737     if (twinSippSocket && (msg_index > 0)) {
 1738       //WARNING_P2("call-ID '%s', internal-cmd: abort_call %s",id, "");
 1739       sendCmdBuffer
 1740   (createSendingMessage((char*)"call-id: [call_id]\ninternal-cmd: abort_call\n\n", -1));
 1741     }
 1742 
 1743     // usage of last_ keywords => for call aborting
 1744     last_recv_msg = (char *) realloc(last_recv_msg, strlen(msg) + 1);
 1745     strcpy(last_recv_msg, msg);
 1746 
 1747     CStat::instance()->computeStat(CStat::E_CALL_FAILED);
 1748     CStat::instance()->computeStat(CStat::E_FAILED_UNEXPECTED_MSG);
 1749     return (abortCall());
 1750   } else {
 1751     // Do not abort call nor send anything in reply if default behavior is disabled
 1752     return false;
 1753   }
 1754 }
 1755 
 1756 bool call::abortCall()
 1757 {
 1758   int is_inv;
 1759 
 1760   char * src_send = NULL ;
 1761   char * src_recv = NULL ;
 1762 
 1763   if (last_send_msg != NULL) {
 1764     is_inv = !strncmp(last_send_msg, "INVITE", 6);
 1765   } else {
 1766     is_inv = false;
 1767   }
 1768   if ((toolMode != MODE_SERVER) && (msg_index > 0)) {
 1769     if ((call_established == false) && (is_inv)) {
 1770       src_recv = last_recv_msg ;
 1771       char   L_msg_buffer[SIPP_MAX_MSG_SIZE];
 1772       L_msg_buffer[0] = '\0';
 1773       char * L_param = L_msg_buffer;
 1774 
 1775       // Answer unexpected errors (4XX, 5XX and beyond) with an ACK
 1776       // Contributed by F. Tarek Rogers
 1777       if((src_recv) && (get_reply_code(src_recv) >= 400)) {
 1778         strcpy(L_param,  "ACK [last_Request_URI] SIP/2.0\n");
 1779         sprintf(L_param, "%s%s", L_param, "[last_Via]\n");
 1780         sprintf(L_param, "%s%s", L_param, "[last_From]\n");
 1781         sprintf(L_param, "%s%s", L_param, "[last_To]\n");
 1782         sprintf(L_param, "%s%s", L_param, "Call-ID: [call_id]\n");
 1783         char * cseq;
 1784         cseq = get_header_field_code(src_recv,(char *) "CSeq:");
 1785         if (cseq != NULL) {
 1786           sprintf(L_param, "%s%s ACK\n", L_param, cseq);
 1787         }
 1788         sprintf(L_param, "%s%s", L_param, "Contact: <sip:sipp@[local_ip]:[local_port];transport=[transport]>\n");
 1789         sprintf(L_param, "%s%s", L_param, "Max-Forwards: 70\n");
 1790         sprintf(L_param, "%s%s", L_param, "Subject: Performance Test\n");
 1791         sprintf(L_param, "%s%s", L_param, "Content-Length: 0\n\n");
 1792 
 1793         sendBuffer(createSendingMessage((char*)(L_param), -2));
 1794 
 1795       } else if (src_recv) {
 1796         /* Call is not established and the reply is not a 4XX, 5XX */
 1797         /* And we already received a message. */
 1798         if (ack_is_pending == true) {
 1799           char * cseq = NULL;
 1800 
 1801           /* If an ACK is expected from the other side, send it
 1802            * and send a BYE afterwards                           */
 1803           ack_is_pending = false;
 1804           /* Send an ACK */
 1805           strcpy(L_param,  "ACK [last_Request_URI] SIP/2.0\n");
 1806           sprintf(L_param, "%s%s", L_param, "Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n");
 1807           sprintf(L_param, "%s%s", L_param, "[last_From]\n");
 1808           sprintf(L_param, "%s%s", L_param, "[last_To]\n");
 1809           sprintf(L_param, "%s%s", L_param, "Call-ID: [call_id]\n");
 1810           src_send = last_send_msg ;
 1811           cseq = get_header_field_code(src_recv,"CSeq:");
 1812           if (cseq != NULL) {
 1813             sprintf(L_param, "%s%s ACK\n", L_param, cseq);
 1814           }
 1815         sprintf(L_param, "%s%s", L_param, "Max-Forwards: 70\n");
 1816           sprintf(L_param, "%s%s", L_param, "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n");
 1817           sprintf(L_param, "%s%s", L_param, "Content-Length: 0\n\n");
 1818           sendBuffer(createSendingMessage((char*)(L_param),-1));
 1819 
 1820           /* Send the BYE */
 1821           cseq = NULL;
 1822           strcpy(L_param,  "BYE [last_Request_URI] SIP/2.0\n");
 1823           sprintf(L_param, "%s%s", L_param, "Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n");
 1824           sprintf(L_param, "%s%s", L_param, "[last_From]\n");
 1825           sprintf(L_param, "%s%s", L_param, "[last_To]\n");
 1826           sprintf(L_param, "%s%s", L_param, "Call-ID: [call_id]\n");
 1827           cseq = compute_cseq(src_recv);
 1828           if (cseq != NULL) {
 1829             sprintf(L_param, "%s%s BYE\n", L_param, compute_cseq(src_recv));
 1830           }
 1831       sprintf(L_param, "%s%s", L_param, "Max-Forwards: 70\n");
 1832           sprintf(L_param, "%s%s", L_param,  "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n");
 1833           sprintf(L_param, "%s%s", L_param,  "Content-Length: 0\n\n");
 1834           sendBuffer(createSendingMessage((char*)(L_param),-1));
 1835         } else {
 1836           /* Send a CANCEL */
 1837           strcpy(L_param,  "CANCEL [last_Request_URI] SIP/2.0\n");
 1838           sprintf(L_param, "%s%s", L_param, "[last_Via]\n");
 1839           sprintf(L_param, "%s%s", L_param, "[last_From]\n");
 1840           sprintf(L_param, "%s%s", L_param, "[last_To]\n");
 1841           sprintf(L_param, "%s%s", L_param, "Call-ID: [call_id]\n");
 1842           sprintf(L_param, "%sCSeq: 1 CANCEL\n", L_param);
 1843         sprintf(L_param, "%s%s", L_param, "Max-Forwards: 70\n");
 1844           sprintf(L_param, "%s%s", L_param, "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n");
 1845           sprintf(L_param, "%s%s", L_param, "Content-Length: 0\n\n");
 1846           sendBuffer(createSendingMessage((char*)(L_param),-2));
 1847         }
 1848       } else {
 1849         /* Call is not established and the reply is not a 4XX, 5XX */
 1850         /* and we didn't received any message. This is the case when */
 1851         /* we are aborting after having send an INVITE and not received */
 1852         /* any answer. */
 1853         /* Do nothing ! */
 1854       }
 1855     } else if (last_recv_msg) {
 1856       /* The call may not be established, if we haven't yet received a message,
 1857        * because the earlier check depends on the first message being an INVITE
 1858        * (although it could be something like a message message, therefore we
 1859        * check that we received a message. */
 1860       char * src_recv = last_recv_msg ;
 1861       char   L_msg_buffer[SIPP_MAX_MSG_SIZE];
 1862       L_msg_buffer[0] = '\0';
 1863       char * L_param = L_msg_buffer;
 1864       strcpy(L_param,  "BYE [last_Request_URI] SIP/2.0\n");
 1865       sprintf(L_param, "%s%s", L_param, "Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n");
 1866       sprintf(L_param, "%s%s", L_param, "[last_From:]\n");
 1867       sprintf(L_param, "%s%s", L_param, "[last_To:]\n");
 1868       sprintf(L_param, "%s%s", L_param, "Call-ID: [call_id]\n");
 1869       char * cseq;
 1870       cseq = compute_cseq(src_recv);
 1871       if (cseq != NULL) {
 1872         sprintf(L_param, "%s%s BYE\n", L_param, compute_cseq(src_recv));
 1873       }
 1874      sprintf(L_param, "%s%s", L_param, "Max-Forwards: 70\n");
 1875       sprintf(L_param, "%s%s", L_param,  "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n");
 1876       sprintf(L_param, "%s%s", L_param,  "Content-Length: 0\n\n");
 1877       sendBuffer(createSendingMessage((char*)(L_param),-1));
 1878     }
 1879   }
 1880 
 1881   delete_call(id);
 1882   return false;
 1883 }
 1884 
 1885 bool call::rejectCall()
 1886 {
 1887   CStat::instance()->computeStat(CStat::E_CALL_FAILED);
 1888   CStat::instance()->computeStat(CStat::E_FAILED_CALL_REJECTED);
 1889   delete_call(id);
 1890   return false;
 1891 }
 1892 
 1893 
 1894 int call::sendCmdMessage(int index)
 1895 {
 1896   char * dest;
 1897   char delimitor[2];
 1898   delimitor[0]=27;
 1899   delimitor[1]=0;
 1900 
 1901   /* 3pcc extended mode */
 1902   char * peer_dest;
 1903   struct sipp_socket **peer_socket;
 1904 
 1905   if(scenario[index] -> M_sendCmdData) {
 1906     // WARNING_P1("---PREPARING_TWIN_CMD---%s---", scenario[index] -> M_sendCmdData);
 1907     dest = createSendingMessage(scenario[index] -> M_sendCmdData, -1);
 1908     strcat(dest, delimitor);
 1909     //WARNING_P1("---SEND_TWIN_CMD---%s---", dest);
 1910 
 1911     int rc;
 1912 
 1913     /* 3pcc extended mode */
 1914     peer_dest = scenario[index]->peer_dest;
 1915     if(peer_dest){
 1916       peer_socket = get_peer_socket(peer_dest);
 1917       rc = write_socket(*peer_socket, dest, strlen(dest), WS_BUFFER);
 1918     }else {
 1919       rc = write_socket(twinSippSocket, dest, strlen(dest), WS_BUFFER);
 1920     }
 1921     if(rc <  0) {
 1922       CStat::instance()->computeStat(CStat::E_CALL_FAILED);
 1923       CStat::instance()->computeStat(CStat::E_FAILED_CMD_NOT_SENT);
 1924       delete_call(id);
 1925       return(-1);
 1926     }
 1927 
 1928     return(0);
 1929   }
 1930   else
 1931     return(-1);
 1932 }
 1933 
 1934 
 1935 int call::sendCmdBuffer(char* cmd)
 1936 {
 1937   char * dest;
 1938   char delimitor[2];
 1939   int  rc;
 1940 
 1941   delimitor[0]=27;
 1942   delimitor[1]=0;
 1943 
 1944   dest = cmd ;
 1945 
 1946   strcat(dest, delimitor);
 1947 
 1948   rc = write_socket(twinSippSocket, dest, strlen(dest), WS_BUFFER);
 1949   if(rc <  0) {
 1950     CStat::instance()->computeStat(CStat::E_CALL_FAILED);
 1951     CStat::instance()->computeStat(CStat::E_FAILED_CMD_NOT_SENT);
 1952     delete_call(id);
 1953     return(-1);
 1954   }
 1955 
 1956   return(0);
 1957 }
 1958 
 1959 char* call::createSendingMessage(SendingMessage *src, int P_index)
 1960 {
 1961   char * length_marker = NULL;
 1962   char * auth_marker = NULL;
 1963   MessageComponent *auth_comp = NULL;
 1964   bool auth_comp_allocated = false;
 1965   int    len_offset = 0;
 1966   static char msg_buffer[SIPP_MAX_MSG_SIZE+2];
 1967   char *dest = msg_buffer;
 1968   bool supresscrlf = false;
 1969 
 1970   *dest = '\0';
 1971 
 1972   for (int i = 0; i < src->numComponents(); i++) {
 1973     MessageComponent *comp = src->getComponent(i);
 1974     int left = sizeof(msg_buffer) - (dest - msg_buffer);
 1975     switch(comp->type) {
 1976       case E_Message_Literal:
 1977   if (supresscrlf) {
 1978     char *ptr = comp->literal;
 1979     while (isspace(*ptr)) ptr++;
 1980     dest += snprintf(dest, left, "%s", ptr);
 1981     supresscrlf = false;
 1982   } else {
 1983     dest += snprintf(dest, left, "%s", comp->literal);
 1984   }
 1985   break;
 1986       case E_Message_Remote_IP:
 1987   dest += snprintf(dest, left, "%s", remote_ip_escaped);
 1988   break;
 1989       case E_Message_Remote_Port:
 1990   dest += snprintf(dest, left, "%d", remote_port + comp->offset);
 1991   break;
 1992       case E_Message_Local_IP:
 1993   dest += snprintf(dest, left, "%s", local_ip_escaped);
 1994   break;
 1995       case E_Message_Local_Port:
 1996   int port;
 1997   if((transport == T_UDP) && (multisocket) && (toolMode != MODE_SERVER)) {
 1998     port = call_port;
 1999   } else {
 2000     port =  local_port;
 2001   }
 2002   dest += snprintf(dest, left, "%d", port + comp->offset);
 2003   break;
 2004       case E_Message_Transport:
 2005   dest += snprintf(dest, left, "%s", TRANSPORT_TO_STRING(transport));
 2006   break;
 2007       case E_Message_Local_IP_Type:
 2008   dest += snprintf(dest, left, "%s", (local_ip_is_ipv6 ? "6" : "4"));
 2009   break;
 2010       case E_Message_Server_IP: {
 2011     /* We should do this conversion once per socket creation, rather than
 2012      * repeating it every single time. */
 2013     struct sockaddr_storage server_sockaddr;
 2014 
 2015     sipp_socklen_t len = SOCK_ADDR_SIZE(&server_sockaddr);
 2016     getsockname(call_socket->ss_fd,
 2017         (sockaddr *)(void *)&server_sockaddr, &len);
 2018 
 2019     if (server_sockaddr.ss_family == AF_INET6) {
 2020       char * temp_dest;
 2021       temp_dest = (char *) malloc(INET6_ADDRSTRLEN);
 2022       memset(temp_dest,0,INET6_ADDRSTRLEN);
 2023       inet_ntop(AF_INET6,
 2024     &((_RCAST(struct sockaddr_in6 *,&server_sockaddr))->sin6_addr),
 2025     temp_dest,
 2026     INET6_ADDRSTRLEN);
 2027       dest += snprintf(dest, left, "%s",temp_dest);
 2028     } else {
 2029       dest += snprintf(dest, left, "%s",
 2030     inet_ntoa((_RCAST(struct sockaddr_in *,&server_sockaddr))->sin_addr));
 2031     }
 2032   }
 2033   break;
 2034       case E_Message_Media_IP:
 2035   dest += snprintf(dest, left, "%s", media_ip_escaped);
 2036   break;
 2037       case E_Message_Media_Port:
 2038       case E_Message_Auto_Media_Port: {
 2039   int port = media_port + comp->offset;
 2040   if (comp->type == E_Message_Auto_Media_Port) {
 2041     port = media_port + (4 * (number - 1)) % 10000 + comp->offset;
 2042   }
 2043 #ifdef PCAPPLAY
 2044   char *begin = dest;
 2045   while (begin > msg_buffer) {
 2046     if (*begin == '\n') {
 2047       break;
 2048     }
 2049     begin--;
 2050   }
 2051   if (begin == msg_buffer) {
 2052     ERROR("Can not find beginning of a line for the media port!\n");
 2053   }
 2054   if (strstr(begin, "audio")) {
 2055     if (media_ip_is_ipv6) {
 2056       (_RCAST(struct sockaddr_in6 *, &(play_args_a.from)))->sin6_port = port;
 2057     } else {
 2058       (_RCAST(struct sockaddr_in *, &(play_args_a.from)))->sin_port = port;
 2059     }
 2060   } else if (strstr(begin, "video")) {
 2061     if (media_ip_is_ipv6) {
 2062       (_RCAST(struct sockaddr_in6 *, &(play_args_v.from)))->sin6_port = port;
 2063     } else {
 2064       (_RCAST(struct sockaddr_in *, &(play_args_v.from)))->sin_port = port;
 2065     }
 2066   } else {
 2067     ERROR_P1("media_port keyword with no audio or video on the current line (%s)", begin);
 2068   }
 2069 #endif
 2070   dest += sprintf(dest, "%u", port);
 2071   break;
 2072       }
 2073       case E_Message_Media_IP_Type:
 2074   dest += snprintf(dest, left, "%s", (media_ip_is_ipv6 ? "6" : "4"));
 2075   break;
 2076       case E_Message_Call_Number:
 2077   dest += snprintf(dest, left, "%u", number);
 2078   break;
 2079       case E_Message_Call_ID:
 2080   dest += snprintf(dest, left, "%s", id);
 2081   break;
 2082       case E_Message_CSEQ:
 2083   dest += snprintf(dest, left, "%u", cseq + comp->offset);
 2084   break;
 2085       case E_Message_PID:
 2086   dest += snprintf(dest, left, "%d", pid);
 2087   break;
 2088       case E_Message_Service:
 2089   dest += snprintf(dest, left, "%s", service);
 2090   break;
 2091       case E_Message_Branch:
 2092   /* Branch is magic cookie + call number + message index in scenario */
 2093   if(P_index == -2){
 2094     dest += snprintf(dest, left, "z9hG4bK-%u-%u-%d", pid, number, msg_index-1 + comp->offset);
 2095   } else {
 2096     dest += snprintf(dest, left, "z9hG4bK-%u-%u-%d", pid, number, P_index + comp->offset);
 2097   }
 2098   break;
 2099       case E_Message_Index:
 2100   dest += snprintf(dest, left, "%d", P_index);
 2101   break;
 2102       case E_Message_Next_Url:
 2103   if (next_req_url) {
 2104     dest += sprintf(dest, "%s", next_req_url);
 2105   }
 2106   break;
 2107       case E_Message_Len:
 2108   length_marker = dest;
 2109   dest += snprintf(dest, left, "     ");
 2110   len_offset = comp->offset;
 2111   break;
 2112       case E_Message_Authentication:
 2113   if (auth_marker) {
 2114     ERROR("Only one [authentication] keyword is currently supported!\n");
 2115   }
 2116   auth_marker = dest;
 2117   dest += snprintf(dest, left, "[authentication place holder]");
 2118   auth_comp = comp;
 2119   break;
 2120       case E_Message_Peer_Tag_Param:
 2121   if(peer_tag) {
 2122     dest += snprintf(dest, left, ";tag=%s", peer_tag);
 2123   }
 2124   break;
 2125       case E_Message_Routes:
 2126   if (dialog_route_set) {
 2127     dest += sprintf(dest, "Route: %s", dialog_route_set);
 2128   } else if (*(dest - 1) == '\n') {
 2129     supresscrlf = true;
 2130   }
 2131   break;
 2132       case E_Message_ClockTick:
 2133   dest += snprintf(dest, left, "%lu", clock_tick);
 2134   break;
 2135       case E_Message_Variable: {
 2136    int varId = comp->varId;
 2137    if(varId <= maxVariableUsed) {
 2138      if(M_callVariableTable[varId] != NULL) {
 2139        if(M_callVariableTable[varId]->isSet()) {
 2140          if (M_callVariableTable[varId]->isRegExp()) {
 2141      dest += sprintf(dest, "%s", M_callVariableTable[varId]->getMatchingValue());
 2142          } else if (M_callVariableTable[varId]->isDouble()) {
 2143      dest += sprintf(dest, "%lf", M_callVariableTable[varId]->getDouble());
 2144          } else if (M_callVariableTable[varId]->isString()) {
 2145      dest += sprintf(dest, "%s", M_callVariableTable[varId]->getString());
 2146          } else if (M_callVariableTable[varId]->isBool()) {
 2147      dest += sprintf(dest, "true");
 2148          }
 2149        } else if (M_callVariableTable[varId]->isBool()) {
 2150          dest += sprintf(dest, "false");
 2151        }
 2152      }
 2153    }
 2154    break;
 2155       }
 2156       case E_Message_Fill: {
 2157         int varId = comp->varId;
 2158   int length = 0;
 2159   if(varId <= maxVariableUsed && M_callVariableTable[varId]) {
 2160     length = (int) M_callVariableTable[varId]->getDouble();
 2161     if (length < 0) {
 2162       length = 0;
 2163     }
 2164   }
 2165   char *filltext = comp->literal;
 2166   int filllen = strlen(filltext);
 2167   if (filllen == 0) {
 2168     ERROR("Internal error: [fill] keyword has zero-length text.");
 2169   }
 2170   for (int i = 0, j = 0; i < length; i++, j++) {
 2171     *dest++ = filltext[j % filllen];
 2172   }
 2173   *dest = '\0';
 2174   break;
 2175       }
 2176       case E_Message_Injection: {
 2177   char *orig_dest = dest;
 2178   getFieldFromInputFile(comp->comp_param.field_param.filename, comp->comp_param.field_param.field, dest);
 2179   /* We are injecting an authentication line. */
 2180   if (char *tmp = strstr(orig_dest, "[authentication")) {
 2181     if (auth_marker) {
 2182       ERROR("Only one [authentication] keyword is currently supported!\n");
 2183     }
 2184     auth_marker = tmp;
 2185     auth_comp = (struct MessageComponent *)calloc(1, sizeof(struct MessageComponent));
 2186     if (!auth_comp) { ERROR("Out of memory!"); }
 2187     auth_comp_allocated = true;
 2188 
 2189     tmp = strchr(auth_marker, ']');
 2190     char c = *tmp;
 2191     *tmp = '\0';
 2192     SendingMessage::parseAuthenticationKeyword(auth_comp, auth_marker);
 2193     *tmp = c;
 2194   }
 2195   if (*(dest - 1) == '\n') {
 2196     supresscrlf = true;
 2197   }
 2198   break;
 2199       }
 2200       case E_Message_Last_Header: {
 2201   char * last_header = get_last_header(comp->literal);
 2202   if(last_header) {
 2203     dest += sprintf(dest, "%s", last_header);
 2204   }
 2205   if (*(dest - 1) == '\n') {
 2206     supresscrlf = true;
 2207   }
 2208   break;
 2209       }
 2210       case E_Message_Last_Request_URI: {
 2211        char * last_request_uri = get_last_request_uri();
 2212        dest += sprintf(dest, "%s", last_request_uri);
 2213        free(last_request_uri);
 2214    break;
 2215       }
 2216       case E_Message_TDM_Map:
 2217   if (!use_tdmmap)
 2218     ERROR("[tdmmap] keyword without -tdmmap parameter on command line");
 2219   dest += snprintf(dest, left, "%d.%d.%d/%d",
 2220       tdm_map_x+(int((tdm_map_number)/((tdm_map_b+1)*(tdm_map_c+1))))%(tdm_map_a+1),
 2221       tdm_map_h,
 2222       tdm_map_y+(int((tdm_map_number)/(tdm_map_c+1)))%(tdm_map_b+1),
 2223       tdm_map_z+(tdm_map_number)%(tdm_map_c+1)
 2224       );
 2225   break;
 2226     }
 2227   }
 2228   /* Need the body for length and auth-int calculation */
 2229   char *body;
 2230   if (length_marker || auth_marker) {
 2231     body = strstr(msg_buffer, "\r\n\r\n");
 2232   }
 2233 
 2234   /* Fix up the length. */
 2235   if (length_marker) {
 2236     if (auth_marker > body) {
 2237       ERROR("The authentication keyword should appear in the message header, not the body!");
 2238     }
 2239 
 2240     if (body && dest - body > 4 && dest - body < 100004) {
 2241       char tmp = length_marker[5];
 2242       sprintf(length_marker, "%5u", dest - body - 4 + len_offset);
 2243       length_marker[5] = tmp;
 2244     } else {
 2245       // Other cases: Content-Length is 0
 2246       sprintf(length_marker, "    0\r\n\r\n");
 2247     }
 2248   }
 2249 
 2250   /*
 2251    * The authentication substitution must be done outside the above
 2252    * loop because auth-int will use the body (which must have already
 2253    * been keyword substituted) to build the md5 hash
 2254    */
 2255   if (auth_marker) {
 2256 #ifndef _USE_OPENSSL
 2257     ERROR("Authentication requires OpenSSL!");
 2258 #else
 2259     if (!dialog_authentication) {
 2260       ERROR("Authentication keyword without dialog_authentication!");
 2261     }
 2262 
 2263     int    auth_marker_len;
 2264     char * tmp;
 2265     int  authlen;
 2266 
 2267     auth_marker_len = (strchr(auth_marker, ']') + 1) - auth_marker;
 2268 
 2269     /* Need the Method name from the CSeq of the Challenge */
 2270     char method[MAX_HEADER_LEN];
 2271     tmp = get_last_header("CSeq:") + 5;
 2272     if(!tmp) {
 2273       ERROR("Could not extract method from cseq of challenge");
 2274     }
 2275     while(isspace(*tmp) || isdigit(*tmp)) tmp++;
 2276     sscanf(tmp,"%s", method);
 2277 
 2278     if (!body) {
 2279       body = "";
 2280     }
 2281 
 2282     /* Determine the type of credentials. */
 2283     char result[MAX_HEADER_LEN];
 2284     if (dialog_challenge_type == 401) {
 2285       /* Registrars use Authorization */
 2286       authlen = sprintf(result, "Authorization: ");
 2287     } else {
 2288       /* Proxies use Proxy-Authorization */
 2289       authlen = sprintf(result, "Proxy-Authorization: ");
 2290     }
 2291 
 2292     /* Build the auth credenticals */
 2293     char uri[MAX_HEADER_LEN];
 2294     sprintf (uri, "%s:%d", remote_ip, remote_port);
 2295     if (createAuthHeader(auth_comp->comp_param.auth_param.auth_user, auth_comp->comp_param.auth_param.auth_pass,
 2296     method, uri, body, dialog_authentication,
 2297     auth_comp->comp_param.auth_param.aka_OP, auth_comp->comp_param.auth_param.aka_AMF, auth_comp->comp_param.auth_param.aka_K,
 2298     result + authlen) == 0) {
 2299       ERROR_P1("%s", result + authlen);
 2300     }
 2301     authlen = strlen(result);
 2302 
 2303     /* Shift the end of the message to its rightful place. */
 2304     memmove(auth_marker + authlen, auth_marker + auth_marker_len, strlen(auth_marker + auth_marker_len) + 1);
 2305     /* Copy our result into the hole. */
 2306     memcpy(auth_marker, result, authlen);
 2307 #endif
 2308   }
 2309 
 2310   if (auth_comp_allocated) {
 2311     SendingMessage::freeMessageComponent(auth_comp);
 2312   }
 2313 
 2314   return msg_buffer;
 2315 }
 2316 
 2317 char* call::createSendingMessage(char *src, int P_index, bool skip_sanity)
 2318 {
 2319   if (src == NULL) {
 2320     ERROR("Unsupported 'send' message in scenario");
 2321   }
 2322 
 2323   SendingMessage *msgsrc = new SendingMessage(src, skip_sanity);
 2324   char *msg = createSendingMessage(msgsrc, P_index);
 2325   delete msgsrc;
 2326   return msg;
 2327 }
 2328 
 2329 
 2330 
 2331 #ifdef __3PCC__
 2332 bool call::process_twinSippCom(char * msg)
 2333 {
 2334   int     search_index;
 2335   bool            found = false;
 2336   T_ActionResult  actionResult;
 2337 
 2338   if (!running) {
 2339     paused_calls.remove_paused_call(this);
 2340     add_running_call(this);
 2341   }
 2342 
 2343   if (checkInternalCmd(msg) == false) {
 2344 
 2345     for(search_index = msg_index;
 2346       search_index < scenario_len;
 2347       search_index++) {
 2348       if(scenario[search_index] -> M_type != MSG_TYPE_RECVCMD) {
 2349         if(scenario[search_index] -> optional) {
 2350           continue;
 2351         }
 2352         /* The received message is different from the expected one */
 2353   TRACE_MSG((s, "Unexpected control message received (I was expecting a different type of message):\n%s\n", msg));
 2354         return rejectCall();
 2355       } else {
 2356         if(extendedTwinSippMode){                   // 3pcc extended mode
 2357     if(check_peer_src(msg, search_index)){
 2358             found = true;
 2359             break;
 2360     } else{
 2361       WARNING_P1("Unexpected sender for the received peer message \n%s\n", msg);
 2362       return rejectCall();
 2363       }
 2364    }
 2365    else {
 2366         found = true;
 2367         break;
 2368       }
 2369     }
 2370     }
 2371 
 2372     if (found) {
 2373       scenario[search_index]->M_nbCmdRecv ++;
 2374 
 2375       // variable treatment
 2376       // Remove \r, \n at the end of a received command
 2377       // (necessary for transport, to be removed for usage)
 2378       while ( (msg[strlen(msg)-1] == '\n') &&
 2379       (msg[strlen(msg)-2] == '\r') ) {
 2380         msg[strlen(msg)-2] = 0;
 2381       }
 2382       actionResult = executeAction(msg, search_index);
 2383 
 2384       if(actionResult != call::E_AR_NO_ERROR) {
 2385         // Store last action result if it is an error
 2386         // and go on with the scenario
 2387         call::last_action_result = actionResult;
 2388         if (actionResult == E_AR_STOP_CALL) {
 2389             return rejectCall();
 2390         }
 2391       }
 2392     } else {
 2393       TRACE_MSG((s, "Unexpected control message received (no such message found):\n%s\n", msg));
 2394       return rejectCall();
 2395     }
 2396     msg_index = search_index; //update the state machine
 2397     return(next());
 2398 
 2399   } else {
 2400     return (false);
 2401   }
 2402 }
 2403 
 2404 bool call::checkInternalCmd(char * cmd)
 2405 {
 2406 
 2407   char * L_ptr1, * L_ptr2, L_backup;
 2408 
 2409   L_ptr1 = strstr(cmd, "internal-cmd:");
 2410   if (!L_ptr1) {return (false);}
 2411   L_ptr1 += 13 ;
 2412   while((*L_ptr1 == ' ') || (*L_ptr1 == '\t')) { L_ptr1++; }
 2413   if (!(*L_ptr1)) {return (false);}
 2414   L_ptr2 = L_ptr1;
 2415   while((*L_ptr2) &&
 2416         (*L_ptr2 != ' ') &&
 2417         (*L_ptr2 != '\t') &&
 2418         (*L_ptr2 != '\r') &&
 2419         (*L_ptr2 != '\n')) {
 2420     L_ptr2 ++;
 2421   }
 2422   if(!*L_ptr2) { return (false); }
 2423   L_backup = *L_ptr2;
 2424   *L_ptr2 = 0;
 2425 
 2426   if (strcmp(L_ptr1, "abort_call") == 0) {
 2427     *L_ptr2 = L_backup;
 2428     abortCall();
 2429     CStat::instance()->computeStat(CStat::E_CALL_FAILED);
 2430     return (true);
 2431   }
 2432 
 2433   *L_ptr2 = L_backup;
 2434   return (false);
 2435 }
 2436 
 2437 bool call::check_peer_src(char * msg, int search_index)
 2438 {
 2439  char * L_ptr1, * L_ptr2, L_backup ;
 2440 
 2441  L_ptr1 = strstr(msg, "From:");
 2442  if (!L_ptr1) {return (false);}
 2443  L_ptr1 += 5 ;
 2444  while((*L_ptr1 == ' ') || (*L_ptr1 == '\t')) { L_ptr1++; }
 2445  if (!(*L_ptr1)) {return (false);}
 2446  L_ptr2 = L_ptr1;
 2447   while((*L_ptr2) &&
 2448         (*L_ptr2 != ' ') &&
 2449         (*L_ptr2 != '\t') &&
 2450         (*L_ptr2 != '\r') &&
 2451         (*L_ptr2 != '\n')) {
 2452     L_ptr2 ++;
 2453   }
 2454   if(!*L_ptr2) { return (false); }
 2455   L_backup = *L_ptr2;
 2456   *L_ptr2 = 0;
 2457   if (strcmp(L_ptr1, scenario[search_index] -> peer_src) == 0) {
 2458     *L_ptr2 = L_backup;
 2459     return(true);
 2460   }
 2461 
 2462   *L_ptr2 = L_backup;
 2463   return (false);
 2464 }
 2465 #endif
 2466 
 2467 
 2468 void call::extract_cseq_method (char* method, char* msg)
 2469 {
 2470   char* cseq ;
 2471   if (cseq = strstr (msg, "CSeq"))
 2472   {
 2473     char * value ;
 2474     if ( value = strchr (cseq,  ':'))
 2475     {
 2476       value++;
 2477       while ( isspace(*value)) value++;  // ignore any white spaces after the :
 2478       while ( !isspace(*value)) value++;  // ignore the CSEQ numnber
 2479       value++;
 2480       char *end = value;
 2481       int nbytes = 0;
 2482       /* A '\r' terminates the line, so we want to catch that too. */
 2483       while ((*end != '\r') && (*end != '\n')) { end++; nbytes++; }
 2484       if (nbytes > 0) strncpy (method, value, nbytes);
 2485       method[nbytes] = '\0';
 2486     }
 2487   }
 2488 }
 2489 
 2490 void call::formatNextReqUrl (char* next_req_url)
 2491 {
 2492 
 2493   /* clean up the next_req_url -- Record routes may have extra gunk
 2494      that needs to be removed
 2495    */
 2496   char* actual_req_url = strchr(next_req_url, '<');
 2497   if (actual_req_url)
 2498   {
 2499     /* using a temporary buffer */
 2500     char tempBuffer[MAX_HEADER_LEN];
 2501     strcpy(tempBuffer, actual_req_url + 1);
 2502     actual_req_url = strrchr(tempBuffer, '>');
 2503     *actual_req_url = '\0';
 2504     strcpy(next_req_url, tempBuffer);
 2505   }
 2506 
 2507 }
 2508 
 2509 void call::computeRouteSetAndRemoteTargetUri (char* rr, char* contact, bool bRequestIncoming)
 2510 {
 2511   if (0 >=strlen (rr))
 2512   {
 2513     //
 2514     // there are no RR headers. Simply set up the contact as our target uri
 2515     //
 2516     if (0 < strlen(contact))
 2517     {
 2518       strcpy (next_req_url, contact);
 2519     }
 2520 
 2521     formatNextReqUrl(next_req_url);
 2522 
 2523     return;
 2524   }
 2525 
 2526   char actual_rr[MAX_HEADER_LEN];
 2527   char targetURI[MAX_HEADER_LEN];
 2528   memset(actual_rr, 0, sizeof(actual_rr));
 2529 
 2530   bool isFirst = true;
 2531   bool bCopyContactToRR = false;
 2532 
 2533   while (1)
 2534   {
 2535       char* pointer = NULL;
 2536       if (bRequestIncoming)
 2537       {
 2538         pointer = strchr (rr, ',');
 2539       }
 2540       else
 2541       {
 2542         pointer = strrchr(rr, ',');
 2543       }
 2544 
 2545       if (pointer)
 2546       {
 2547         if (!isFirst)
 2548         {
 2549           if (strlen(actual_rr) )
 2550           {
 2551             strcat(actual_rr, pointer + 1);
 2552           }
 2553           else
 2554           {
 2555             strcpy(actual_rr, pointer + 1);
 2556           }
 2557           strcat(actual_rr, ",");
 2558         }
 2559         else
 2560         {
 2561           isFirst = false;
 2562           if (NULL == strstr (pointer, ";lr"))
 2563           {
 2564             /* bottom most RR is the next_req_url */
 2565             strcpy (targetURI, pointer + 1);
 2566             bCopyContactToRR = true;
 2567           }
 2568           else
 2569           {
 2570             /* the hop is a loose router. Thus, the target URI should be the
 2571              * contact
 2572              */
 2573             strcpy (targetURI, contact);
 2574             strcpy(actual_rr, pointer + 1);
 2575             strcat(actual_rr, ",");
 2576           }
 2577         }
 2578       }
 2579       else
 2580       {
 2581         if (!isFirst)
 2582         {
 2583             strcat(actual_rr, rr);
 2584         }
 2585         //
 2586         // this is the *only* RR header that was found
 2587         //
 2588         else
 2589         {
 2590           if (NULL == strstr (rr, ";lr"))
 2591           {
 2592             /* bottom most RR is the next_req_url */
 2593             strcpy (targetURI, rr);
 2594             bCopyContactToRR = true;
 2595           }
 2596           else
 2597           {
 2598             /* the hop is a loose router. Thus, the target URI should be the
 2599              * contact
 2600              */
 2601             strcpy (actual_rr, rr);
 2602             strcpy (targetURI, contact);
 2603           }
 2604         }
 2605         break;
 2606       }
 2607       *pointer = '\0';
 2608   }
 2609 
 2610   if (bCopyContactToRR)
 2611   {
 2612     if (0 < strlen (actual_rr))
 2613     {
 2614       strcat(actual_rr, ",");
 2615       strcat(actual_rr, contact);
 2616     }
 2617     else
 2618     {
 2619       strcpy(actual_rr, contact);
 2620     }
 2621   }
 2622 
 2623   if (strlen(actual_rr))
 2624   {
 2625     dialog_route_set = (char *)
 2626         calloc(1, strlen(actual_rr) + 2);
 2627     sprintf(dialog_route_set, "%s", actual_rr);
 2628   }
 2629 
 2630   if (strlen (targetURI))
 2631   {
 2632     strcpy (next_req_url, targetURI);
 2633     formatNextReqUrl (next_req_url);
 2634   }
 2635 }
 2636 
 2637 bool call::matches_scenario(unsigned int index, int reply_code, char * request, char * responsecseqmethod)
 2638 {
 2639   int        result;
 2640 
 2641   if ((reply_code) && ((scenario[index] -> recv_response) == reply_code) && \
 2642      (index == 0 || ((scenario[index]->recv_response_for_cseq_method_list) && \
 2643      (strstr(scenario[index]->recv_response_for_cseq_method_list, responsecseqmethod))))) {
 2644         return true;
 2645   }
 2646 
 2647   if ((scenario[index] -> recv_request) && \
 2648      (!strcmp(scenario[index] -> recv_request, request))) {
 2649         return true;
 2650   }
 2651 
 2652   if ((scenario[index] -> recv_request) && (scenario[index] -> regexp_match)) {
 2653 
 2654      if (scenario[index] -> regexp_compile == NULL) {
 2655         regex_t *re = new regex_t;
 2656         if (regcomp(re, scenario[index] -> recv_request, REG_EXTENDED|REG_NOSUB)) {
 2657            // regexp is not well formed
 2658            scenario[index] -> regexp_match = 0;
 2659            free(re);
 2660            return false;
 2661         }
 2662         scenario[index] -> regexp_compile = re;
 2663      }
 2664 
 2665      result = regexec(scenario[index] -> regexp_compile, request, (size_t)0, NULL, 0);
 2666      if (!result) return true;
 2667   }
 2668 
 2669   return false;
 2670 }
 2671 
 2672 bool call::process_incoming(char * msg)
 2673 {
 2674   int             reply_code;
 2675   static char     request[65];
 2676   char            responsecseqmethod[65];
 2677   unsigned long   cookie;
 2678   char          * ptr;
 2679   int             search_index;
 2680   bool            found = false;
 2681   T_ActionResult  actionResult;
 2682 
 2683   int             L_case = 0 ;
 2684 
 2685   if (!running) {
 2686     paused_calls.remove_paused_call(this);
 2687     add_running_call(this);
 2688   }
 2689 
 2690   /* Ignore the messages received during a pause if -pause_msg_ign is set */
 2691   if(scenario[msg_index] -> M_type == MSG_TYPE_PAUSE && pause_msg_ign) return(true);
 2692 
 2693   /* Authorize nop as a first command, even in server mode */
 2694   if((msg_index == 0) && (scenario[msg_index] -> M_type == MSG_TYPE_NOP)) {
 2695     actionResult = executeAction(NULL, msg_index);
 2696     return next();
 2697   }
 2698   responsecseqmethod[0] = '\0';
 2699 
 2700   if((transport == T_UDP) && (retrans_enabled)) {
 2701     /* Detects retransmissions from peer and retransmit the
 2702      * message which was sent just after this one was received */
 2703     cookie = hash(msg);
 2704     if(recv_retrans_hash == cookie) {
 2705 
 2706       int status;
 2707 
 2708       if(lost(recv_retrans_recv_index)) {
 2709   TRACE_MSG((s, "%s message (retrans) lost (recv).",
 2710         TRANSPORT_TO_STRING(transport)));
 2711 
 2712   if(comp_state) { comp_free(&comp_state); }
 2713   scenario[recv_retrans_recv_index] -> nb_lost++;
 2714   return true;
 2715       }
 2716 
 2717       scenario[recv_retrans_recv_index] -> nb_recv_retrans++;
 2718 
 2719       send_scene(recv_retrans_send_index, &status);
 2720 
 2721       if(status == 0) {
 2722   scenario[recv_retrans_send_index] -> nb_sent_retrans++;
 2723   CStat::instance()->computeStat(CStat::E_RETRANSMISSION);
 2724       } else if(status < 0) {
 2725   return false;
 2726       }
 2727 
 2728       return true;
 2729     }
 2730 
 2731     if(last_recv_hash == cookie) {
 2732       /* This one has already been received, but not processed
 2733        * yet => (has not triggered something yet) so we can discard.
 2734        *
 2735        * This case appears when the UAS has send a 200 but not received
 2736        * a ACK yet. Thus, the UAS retransmit the 200 (invite transaction)
 2737        * until it receives a ACK. In this case, it nevers sends the 200
 2738        * from the  BYE, until it has reveiced the previous 200. Thus,
 2739        * the UAC retransmit the BYE, and this BYE is considered as an
 2740        * unexpected.
 2741        *
 2742        * This case can also appear in case of message duplication by
 2743        * the network. This should not be considered as an unexpected.
 2744        */
 2745       scenario[last_recv_index]->nb_recv_retrans++;
 2746       return true;
 2747     }
 2748   }
 2749 
 2750   /* Is it a response ? */
 2751   if((msg[0] == 'S') &&
 2752      (msg[1] == 'I') &&
 2753      (msg[2] == 'P') &&
 2754      (msg[3] == '/') &&
 2755      (msg[4] == '2') &&
 2756      (msg[5] == '.') &&
 2757      (msg[6] == '0')    ) {
 2758 
 2759     reply_code = get_reply_code(msg);
 2760     if(!reply_code) {
 2761       if (!process_unexpected(msg)) {
 2762         return false; // Call aborted by unexpected message handling
 2763       }
 2764 #ifdef PCAPPLAY
 2765     } else if ((hasMedia == 1) && *(strstr(msg, "\r\n\r\n")+4) != '\0') {
 2766       /* Get media info if we find something like an SDP */
 2767       get_remote_media_addr(msg);
 2768 #endif
 2769     }
 2770     /* It is a response: update peer_tag */
 2771     ptr = get_peer_tag(msg);
 2772     if (ptr) {
 2773       if(strlen(ptr) > (MAX_HEADER_LEN - 1)) {
 2774         ERROR("Peer tag too long. Change MAX_HEADER_LEN and recompile sipp");
 2775       }
 2776       if(peer_tag) { free(peer_tag); }
 2777       peer_tag = strdup(ptr);
 2778       if (!peer_tag) {
 2779   ERROR("Out of memory allocating peer tag.");
 2780       }
 2781     }
 2782     request[0]=0;
 2783     // extract the cseq method from the response
 2784     extract_cseq_method (responsecseqmethod, msg);
 2785   } else if(ptr = strchr(msg, ' ')) {
 2786     if((ptr - msg) < 64) {
 2787       memcpy(request, msg, ptr - msg);
 2788       request[ptr - msg] = 0;
 2789       // Check if we received an ACK => call established
 2790       if (strcmp(request,"ACK")==0) {
 2791         call_established=true;
 2792       }
 2793 #ifdef PCAPPLAY
 2794       /* In case of INVITE or re-INVITE, ACK or PRACK
 2795          get the media info if needed (= we got a pcap
 2796          play action) */
 2797       if ((strncmp(request, "INVITE", 6) == 0)
 2798        || (strncmp(request, "ACK", 3) == 0)
 2799        || (strncmp(request, "PRACK", 5) == 0)
 2800        && (hasMedia == 1))
 2801         get_remote_media_addr(msg);
 2802 #endif
 2803 
 2804       reply_code = 0;
 2805     } else {
 2806       ERROR_P1("SIP method too long in received message '%s'",
 2807                msg);
 2808     }
 2809   } else {
 2810     ERROR_P1("Invalid sip message received '%s'",
 2811              msg);
 2812   }
 2813 
 2814   /* Try to find it in the expected non mandatory responses
 2815    * until the first mandatory response  in the scenario */
 2816   for(search_index = msg_index;
 2817       search_index < scenario_len;
 2818       search_index++) {
 2819     if(!matches_scenario(search_index, reply_code, request, responsecseqmethod)) {
 2820       if(scenario[search_index] -> optional) {
 2821         continue;
 2822       }
 2823       /* The received message is different for the expected one */
 2824       break;
 2825     }
 2826 
 2827     found = true;
 2828     /* TODO : this is a little buggy: If a 100 trying from an INVITE
 2829      * is delayed by the network until the BYE is sent, it may
 2830      * stop BYE transmission erroneously, if the BYE also expects
 2831      * a 100 trying. */
 2832     break;
 2833   }
 2834 
 2835   /* Try to find it in the old non-mandatory receptions */
 2836   if(!found) {
 2837     bool contig = true;
 2838     for(search_index = msg_index - 1;
 2839         search_index >= 0;
 2840         search_index--) {
 2841       if (scenario[search_index]->optional == OPTIONAL_FALSE) contig = false;
 2842       if(matches_scenario(search_index, reply_code, request, responsecseqmethod)) {
 2843         if (contig || scenario[search_index]->optional == OPTIONAL_GLOBAL) {
 2844          found = true;
 2845          break;
 2846         } else {
 2847           /*
 2848            * we received a non mandatory msg for an old transaction (this could be due to a retransmit.
 2849            * If this response is for an INVITE transaction, retransmit the ACK to quench retransmits.
 2850            */
 2851           if ( (reply_code) &&
 2852              (0 == strncmp (responsecseqmethod, "INVITE", strlen(responsecseqmethod)) ) &&
 2853              (scenario[search_index+1]->M_type == MSG_TYPE_SEND) &&
 2854              (scenario[search_index+1]->send_scheme->isAck()) ) {
 2855             sendBuffer(createSendingMessage(scenario[search_index+1] -> send_scheme, (search_index+1)));
 2856             return true;
 2857           }
 2858         }
 2859       }
 2860     }
 2861   }
 2862 
 2863   /* If it is still not found, process an unexpected message */
 2864   if(!found) {
 2865     if ((L_case = checkAutomaticResponseMode(request)) == 0) {
 2866       if (!process_unexpected(msg)) {
 2867         return false; // Call aborted by unexpected message handling
 2868       }
 2869     } else {
 2870       // call aborted by automatic response mode if needed
 2871       return automaticResponseMode(L_case, msg);
 2872     }
 2873   }
 2874 
 2875   int test = (!found) ? -1 : scenario[search_index]->test;
 2876   /* test==0: No branching"
 2877    * test==-1 branching without testing"
 2878    * test>0   branching with testing
 2879    */
 2880 
 2881   /* Simulate loss of messages */
 2882   if(lost(search_index)) {
 2883     TRACE_MSG((s, "%s message lost (recv).",
 2884                TRANSPORT_TO_STRING(transport)));
 2885     if(comp_state) { comp_free(&comp_state); }
 2886     scenario[search_index] -> nb_lost++;
 2887     return true;
 2888   }
 2889 
 2890 
 2891   /* Handle counters and RTDs for this message. */
 2892   do_bookkeeping(search_index);
 2893 
 2894   /* Increment the recv counter */
 2895   scenario[search_index] -> nb_recv++;
 2896 
 2897   // Action treatment
 2898   if (found) {
 2899     //WARNING_P1("---EXECUTE_ACTION_ON_MSG---%s---", msg);
 2900 
 2901     actionResult = executeAction(msg, search_index);
 2902 
 2903     if(actionResult != call::E_AR_NO_ERROR) {
 2904       // Store last action result if it is an error
 2905       // and go on with the scenario
 2906       call::last_action_result = actionResult;
 2907       if (actionResult == E_AR_STOP_CALL) {
 2908           return rejectCall();
 2909       }
 2910     }
 2911   }
 2912 
 2913   if (request) { // update [cseq] with received CSeq
 2914     unsigned long int rcseq = get_cseq_value(msg);
 2915     if (rcseq > cseq) cseq = rcseq;
 2916   }
 2917 
 2918   /* This is an ACK/PRACK or a response, and its index is greater than the
 2919    * current active retransmission message, so we stop the retrans timer.
 2920    * True also for CANCEL and BYE that we also want to answer to */
 2921   if(((reply_code) ||
 2922       ((!strcmp(request, "ACK")) ||
 2923        (!strcmp(request, "CANCEL")) || (!strcmp(request, "BYE")) ||
 2924        (!strcmp(request, "PRACK"))))  &&
 2925      (search_index > last_send_index)) {
 2926    /*
 2927     * We should stop any retransmission timers on receipt of a provisional response only for INVITE
 2928     * transactions. Non INVITE transactions continue to retransmit at T2 until a final response is
 2929     * received
 2930     */
 2931     if ( (0 == reply_code) || // means this is a request.
 2932          (200 <= reply_code) ||  // final response
 2933          ((0 != reply_code) && (0 == strncmp (responsecseqmethod, "INVITE", strlen(responsecseqmethod)))) ) // prov for INVITE
 2934     {
 2935     next_retrans = 0;
 2936   }
 2937     else
 2938     {
 2939       /*
 2940        * We are here due to a provisional response for non INVITE. Update our next retransmit.
 2941        */
 2942       next_retrans = clock_tick + DEFAULT_T2_TIMER_VALUE;
 2943       nb_last_delay = DEFAULT_T2_TIMER_VALUE;
 2944 
 2945     }
 2946   }
 2947 
 2948   /* This is a response with 200 so set the flag indicating that an
 2949    * ACK is pending (used to prevent from release a call with CANCEL
 2950    * when an ACK+BYE should be sent instead)                         */
 2951   if (reply_code == 200) {
 2952     ack_is_pending = true;
 2953   }
 2954 
 2955   /* store the route set only once. TODO: does not support target refreshes!! */
 2956   if (scenario[search_index] -> bShouldRecordRoutes &&
 2957           NULL == dialog_route_set ) {
 2958 
 2959       next_req_url = (char*) calloc(1, MAX_HEADER_LEN);
 2960 
 2961       char rr[MAX_HEADER_LEN];
 2962       memset(rr, 0, sizeof(rr));
 2963       strcpy(rr, get_header_content(msg, (char*)"Record-Route:"));
 2964 
 2965       // WARNING_P1("rr [%s]", rr);
 2966       char ch[MAX_HEADER_LEN];
 2967       strcpy(ch, get_header_content(msg, (char*)"Contact:"));
 2968 
 2969       /* decorate the contact with '<' and '>' if it does not have it */
 2970       char* contDecorator = strchr(ch, '<');
 2971       if (NULL == contDecorator) {
 2972          char tempBuffer[MAX_HEADER_LEN];
 2973          sprintf(tempBuffer, "<%s>", ch);
 2974          strcpy(ch, tempBuffer);
 2975       }
 2976 
 2977       /* should cache the route set */
 2978       if (reply_code) {
 2979         computeRouteSetAndRemoteTargetUri (rr, ch, false);
 2980       }
 2981       else
 2982       {
 2983         computeRouteSetAndRemoteTargetUri (rr, ch, true);
 2984       }
 2985       // WARNING_P1("next_req_url is [%s]", next_req_url);
 2986   }
 2987 
 2988 #ifdef _USE_OPENSSL
 2989   /* store the authentication info */
 2990   if ((scenario[search_index] -> bShouldAuthenticate) &&
 2991           (reply_code == 401 || reply_code == 407)) {
 2992 
 2993       /* is a challenge */
 2994       char auth[MAX_HEADER_LEN];
 2995       memset(auth, 0, sizeof(auth));
 2996       strcpy(auth, get_header_content(msg, (char*)"Proxy-Authenticate:"));
 2997       if (auth[0] == 0) {
 2998         strcpy(auth, get_header_content(msg, (char*)"WWW-Authenticate:"));
 2999       }
 3000       if (auth[0] == 0) {
 3001         ERROR("Couldn't find 'Proxy-Authenticate' or 'WWW-Authenticate' in 401 or 407!");
 3002       }
 3003 
 3004       dialog_authentication = (char *) realloc(dialog_authentication, strlen(auth) + 2);
 3005       sprintf(dialog_authentication, "%s", auth);
 3006 
 3007       /* Store the code of the challenge for building the proper header */
 3008       dialog_challenge_type = reply_code;
 3009   }
 3010 #endif
 3011 
 3012   /* Store last received message information for all messages so that we can
 3013    * correctly identify retransmissions, and use its body for inclusion
 3014    * in our messages. */
 3015   last_recv_index = search_index;
 3016   last_recv_hash = cookie;
 3017   last_recv_msg = (char *) realloc(last_recv_msg, strlen(msg) + 1);
 3018   strcpy(last_recv_msg, msg);
 3019 
 3020   /* If this was a mandatory message, or if there is an explicit next label set
 3021    * we must update our state machine.  */
 3022   if (!(scenario[search_index] -> optional) ||
 3023        scenario[search_index]->next &&
 3024       ((test == -1) ||
 3025        (test <= maxVariableUsed && M_callVariableTable[test] != NULL && M_callVariableTable[test]->isSet()))
 3026      ) {
 3027     /* If we are paused, then we need to wake up so that we properly go through the state machine. */
 3028     paused_until = 0;
 3029     msg_index = search_index;
 3030     return next();
 3031   } else {
 3032     unsigned int timeout = call_wake(this);
 3033     unsigned int candidate;
 3034 
 3035     if (scenario[search_index]->next && test <= maxVariableUsed &&
 3036        M_callVariableTable[test] != NULL && M_callVariableTable[test]->isSet()) {
 3037       WARNING_P1("Last message generates an error and will not be used for next sends (for last_ variables):\r\n%s",msg);
 3038     }
 3039 
 3040     /* We are just waiting for a message to be received, if any of the
 3041      * potential messages have a timeout we set it as our timeout. We
 3042      * start from the next message and go until any non-receives. */
 3043     for(search_index++; search_index < scenario_len; search_index++) {
 3044       if(scenario[search_index] -> M_type != MSG_TYPE_RECV) {
 3045   break;
 3046       }
 3047       candidate = scenario[search_index] -> timeout;
 3048       if (candidate == 0) {
 3049   if (defl_recv_timeout == 0) {
 3050     continue;
 3051   }
 3052   candidate = defl_recv_timeout;
 3053       }
 3054       if (!timeout || (clock_tick + candidate < timeout)) {
 3055   timeout = clock_tick + candidate;
 3056       }
 3057     }
 3058 
 3059     if (!remove_running_call(this)) {
 3060       ERROR("Tried to remove a running call that wasn't running!\n");
 3061     }
 3062     paused_calls.add_paused_call(this, true);
 3063   }
 3064   return true;
 3065 }
 3066 
 3067 double call::get_rhs(CAction *currentAction) {
 3068   if (currentAction->getVarInId()) {
 3069     return M_callVariableTable[currentAction->getVarInId()]->getDouble();
 3070   } else {
 3071     return currentAction->getDoubleValue();
 3072   }
 3073 }
 3074 
 3075 call::T_ActionResult call::executeAction(char * msg, int scenarioIndex)
 3076 {
 3077   CActions*  actions;
 3078   CAction*   currentAction;
 3079   CVariable* scenVariable;
 3080   char       msgPart[MAX_SUB_MESSAGE_LENGTH];
 3081   int        currentId;
 3082 
 3083   actions = scenario[scenarioIndex]->M_actions;
 3084   // looking for action to do on this message
 3085   if(actions != NULL) {
 3086     for(int i=0; i<actions->getActionSize(); i++) {
 3087       currentAction = actions->getAction(i);
 3088       if(currentAction != NULL) {
 3089         if(currentAction->getActionType() == CAction::E_AT_ASSIGN_FROM_REGEXP) {
 3090           currentId = currentAction->getVarId();
 3091           scenVariable = scenVariableTable[currentId][scenarioIndex];
 3092           if(scenVariable != NULL) {
 3093             if(currentAction->getLookingPlace() == CAction::E_LP_HDR) {
 3094               extractSubMessage
 3095                                 (msg,
 3096                                 currentAction->getLookingChar(),
 3097                                 msgPart,
 3098                                 currentAction->getCaseIndep(),
 3099                                 currentAction->getOccurence(),
 3100                                 currentAction->getHeadersOnly());
 3101 
 3102               if(strlen(msgPart) > 0) {
 3103 
 3104                 scenVariable->executeRegExp(msgPart,
 3105                                   M_callVariableTable,
 3106           currentId,
 3107           currentAction->getNbSubVarId(),
 3108                                   currentAction->getSubVarId());
 3109 
 3110                 if( (!(M_callVariableTable[currentId]->isSet()))
 3111                 && (currentAction->getCheckIt() == true) ) {
 3112                   // the message doesn't match and the checkit
 3113                   // action say it MUST match
 3114                   // Allow easier regexp debugging
 3115                   WARNING_P2("Failed regexp match: looking "
 3116                   "in '%s', with regexp '%s'",
 3117                   msgPart,
 3118                   scenVariable->
 3119                   getRegularExpression());
 3120                   // --> Call will be marked as failed
 3121                   return(call::E_AR_REGEXP_DOESNT_MATCH);
 3122                 }
 3123               } else {// sub part of message not found
 3124                 if( currentAction->getCheckIt() == true ) {
 3125                   // the sub message is not found and the
 3126                   // checking action say it MUST match
 3127                   // --> Call will be marked as failed but
 3128                   // will go on
 3129                   WARNING_P2("Failed regexp match: header %s not found in message %s\n", currentAction->getLookingChar(), msg);
 3130                   return(call::E_AR_HDR_NOT_FOUND);
 3131                 }
 3132               }
 3133             } else {// we must look in the entire message
 3134               // WARNING_P1("LOOKING IN MSG -%s-", msg);
 3135                 scenVariable->executeRegExp(msg,
 3136                                   M_callVariableTable,
 3137           currentId,
 3138           currentAction->getNbSubVarId(),
 3139                                   currentAction->getSubVarId());
 3140               if((!(M_callVariableTable[currentId]->isSet()))
 3141               && (currentAction->getCheckIt() == true) ) {
 3142                 // the message doesn't match and the checkit
 3143                 // action say it MUST match
 3144                 // Allow easier regexp debugging
 3145                 WARNING_P2("Failed regexp match: looking in '%s'"
 3146                 ", with regexp '%s'",
 3147                 msg,
 3148                 scenVariable->getRegularExpression());
 3149                 // --> rejecting the call
 3150                 return(call::E_AR_REGEXP_DOESNT_MATCH);
 3151               }
 3152             }
 3153           } // end if scen variable != null
 3154         } else /* end action == E_AT_ASSIGN_FROM_REGEXP */
 3155             if (currentAction->getActionType() == CAction::E_AT_ASSIGN_FROM_VALUE) {
 3156         M_callVariableTable[currentAction->getVarId()]->setDouble(currentAction->getDoubleValue());
 3157         } else if (currentAction->getActionType() == CAction::E_AT_VAR_ADD) {
 3158     double value = M_callVariableTable[currentAction->getVarId()]->getDouble();
 3159     double operand = get_rhs(currentAction);
 3160     M_callVariableTable[currentAction->getVarId()]->setDouble(value + operand);
 3161         } else if (currentAction->getActionType() == CAction::E_AT_VAR_SUBTRACT) {
 3162     double value = M_callVariableTable[currentAction->getVarId()]->getDouble();
 3163     double operand = get_rhs(currentAction);
 3164     M_callVariableTable[currentAction->getVarId()]->setDouble(value - operand);
 3165         } else if (currentAction->getActionType() == CAction::E_AT_VAR_MULTIPLY) {
 3166     double value = M_callVariableTable[currentAction->getVarId()]->getDouble();
 3167     double operand = get_rhs(currentAction);
 3168     M_callVariableTable[currentAction->getVarId()]->setDouble(value * operand);
 3169         } else if (currentAction->getActionType() == CAction::E_AT_VAR_DIVIDE) {
 3170     double value = M_callVariableTable[currentAction->getVarId()]->getDouble();
 3171     double operand = get_rhs(currentAction);
 3172     if (operand == 0) {
 3173       WARNING_P2("Action failure: Can not divide by zero ($%d/$%d)!\n", currentAction->getVarId(), currentAction->getVarInId());
 3174     } else {
 3175       M_callVariableTable[currentAction->getVarId()]->setDouble(value / operand);
 3176     }
 3177         } else if (currentAction->getActionType() == CAction::E_AT_VAR_TEST) {
 3178     double value = currentAction->compare(M_callVariableTable);
 3179     M_callVariableTable[currentAction->getVarId()]->setBool(value);
 3180         } else if (currentAction->getActionType() == CAction::E_AT_VAR_STRCMP) {
 3181     char *rhs = M_callVariableTable[currentAction->getVarInId()]->getString();
 3182     char *lhs = currentAction->getStringValue();
 3183     int value = strcmp(rhs, lhs);
 3184     M_callVariableTable[currentAction->getVarId()]->setDouble((double)value);
 3185         } else if (currentAction->getActionType() == CAction::E_AT_VAR_TO_DOUBLE) {
 3186     double value;
 3187 
 3188     if (M_callVariableTable[currentAction->getVarInId()]->toDouble(&value)) {
 3189       M_callVariableTable[currentAction->getVarId()]->setDouble(value);
 3190     } else {
 3191       WARNING_P2("Invalid double conversion from $%d to $%d", currentAction->getVarInId(), currentAction->getVarId());
 3192     }
 3193   } else if (currentAction->getActionType() == CAction::E_AT_ASSIGN_FROM_SAMPLE) {
 3194     double value = currentAction->getDistribution()->sample();
 3195     M_callVariableTable[currentAction->getVarId()]->setDouble(value);
 3196   } else if (currentAction->getActionType() == CAction::E_AT_ASSIGN_FROM_STRING) {
 3197             char* x = createSendingMessage(currentAction->getMessage(), -2 /* do not add crlf*/, true /* skip sanity check */);
 3198       char *str = strdup(x);
 3199       if (!str) {
 3200     ERROR("Out of memory duplicating string for assignment!");
 3201       }
 3202       M_callVariableTable[currentAction->getVarId()]->setString(str);
 3203   } else if (currentAction->getActionType() == CAction::E_AT_LOG_TO_FILE) {
 3204             char* x = createSendingMessage(currentAction->getMessage(), -2 /* do not add crlf*/, true /* skip sanity check */);
 3205             LOG_MSG((s, "%s\n", x));
 3206         } else if (currentAction->getActionType() == CAction::E_AT_EXECUTE_CMD) {
 3207 
 3208             if (currentAction->getCmdLine()) {
 3209                 char* x = createSendingMessage(currentAction->getCmdLine(), -2 /* do not add crlf*/, true /* skip sanity check. */);
 3210                 // TRACE_MSG((s, "Trying to execute [%s]", x));
 3211                 pid_t l_pid;
 3212                 switch(l_pid = fork())
 3213                 {
 3214                     case -1:
 3215                         // error when forking !
 3216                         ERROR_NO("Forking error main");
 3217                         break;
 3218 
 3219                     case 0:
 3220                        // first child process - execute the command
 3221                        if((l_pid = fork()) < 0) {
 3222                          ERROR_NO("Forking error child");
 3223                        } else {
 3224                          if( l_pid == 0){
 3225                          int ret;
 3226                          ret = system(x); // second child runs
 3227                          if(ret == -1) {
 3228                            WARNING_P1("system call error for %s",x);
 3229                           }
 3230                         }
 3231                        exit(EXIT_OTHER);
 3232                        }
 3233                        break;
 3234                     default:
 3235                        // parent process continue
 3236                        // reap first child immediately
 3237                        pid_t ret;
 3238                        while ((ret=waitpid(l_pid, NULL, 0)) != l_pid) {
 3239                        if (ret != -1) {
 3240                           ERROR_P2("waitpid returns %1d for child %1d",ret,l_pid);
 3241                          }
 3242                        }
 3243                        break;
 3244                 }
 3245             }
 3246         } else /* end action == E_AT_EXECUTE_CMD */
 3247             if (currentAction->getActionType() == CAction::E_AT_EXEC_INTCMD) {
 3248                 switch (currentAction->getIntCmd())
 3249                 {
 3250                     case CAction::E_INTCMD_STOP_ALL:
 3251                         quitting = 1;
 3252                         break;
 3253                     case CAction::E_INTCMD_STOP_NOW:
 3254                         screen_exit(EXIT_TEST_RES_INTERNAL);
 3255                         break;
 3256                     case CAction::E_INTCMD_STOPCALL:
 3257                     default:
 3258                         return(call::E_AR_STOP_CALL);
 3259                         break;
 3260                 }
 3261 #ifdef PCAPPLAY
 3262         } else if ((currentAction->getActionType() == CAction::E_AT_PLAY_PCAP_AUDIO) ||
 3263                    (currentAction->getActionType() == CAction::E_AT_PLAY_PCAP_VIDEO)) {
 3264           play_args_t *play_args;
 3265           if (currentAction->getActionType() == CAction::E_AT_PLAY_PCAP_AUDIO) {
 3266             play_args = &(this->play_args_a);
 3267           } else if (currentAction->getActionType() == CAction::E_AT_PLAY_PCAP_VIDEO) {
 3268             play_args = &(this->play_args_v);
 3269           }
 3270           play_args->pcap = currentAction->getPcapPkts();
 3271           /* port number is set in [auto_]media_port interpolation */
 3272           if (media_ip_is_ipv6) {
 3273             struct sockaddr_in6 *from = (struct sockaddr_in6 *)(void *) &(play_args->from);
 3274             from->sin6_family = AF_INET6;
 3275             inet_pton(AF_INET6, media_ip, &(from->sin6_addr));
 3276           }
 3277           else {
 3278             struct sockaddr_in *from = (struct sockaddr_in *)(void *) &(play_args->from);
 3279             from->sin_family = AF_INET;
 3280             from->sin_addr.s_addr = inet_addr(media_ip);
 3281           }
 3282           /* Create a thread to send RTP packets */
 3283           pthread_attr_t attr;
 3284           pthread_attr_init(&attr);
 3285 #ifndef PTHREAD_STACK_MIN
 3286 #define PTHREAD_STACK_MIN 16384
 3287 #endif
 3288           //pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN);
 3289           pthread_attr_setdetachstate(&attr,
 3290         PTHREAD_CREATE_DETACHED);
 3291           int ret = pthread_create(&media_thread, &attr, send_wrapper,
 3292            (void *) play_args);
 3293           if(ret)
 3294             ERROR("Can create thread to send RTP packets");
 3295           pthread_attr_destroy(&attr);
 3296 #endif
 3297         } else {
 3298           ERROR("call::executeAction unknown action");
 3299         }
 3300       } // end if current action != null
 3301     } // end for
 3302   }
 3303   return(call::E_AR_NO_ERROR);
 3304 }
 3305 
 3306 void call::extractSubMessage(char * msg, char * matchingString, char* result, bool case_indep, int occurrence, bool headers) {
 3307 
 3308  char *ptr, *ptr1;
 3309   int sizeOf;
 3310   int i = 0;
 3311  int len = strlen(matchingString);
 3312  char mat1 = tolower(*matchingString);
 3313  char mat2 = toupper(*matchingString);
 3314 
 3315  ptr = msg;
 3316  while (*ptr) {
 3317    if (!case_indep) {
 3318      ptr = strstr(ptr, matchingString);
 3319      if (ptr == NULL) break;
 3320      if (headers == true && ptr != msg && *(ptr-1) != '\n') {
 3321        ++ptr;
 3322        continue;
 3323      }
 3324    } else {
 3325      if (headers) {
 3326        if (ptr != msg) {
 3327          ptr = strchr(ptr, '\n');
 3328          if (ptr == NULL) break;
 3329          ++ptr;
 3330          if (*ptr == 0) break;
 3331        }
 3332      } else {
 3333        ptr1 = strchr(ptr, mat1);
 3334        ptr = strchr(ptr, mat2);
 3335        if (ptr == NULL) {
 3336          if (ptr1 == NULL) break;
 3337          ptr = ptr1;
 3338        } else {
 3339          if (ptr1 != NULL && ptr1 < ptr) ptr = ptr1;
 3340        }
 3341      }
 3342      if (strncasecmp(ptr, matchingString, len) != 0) {
 3343        ++ptr;
 3344        continue;
 3345      }
 3346    }
 3347    // here with ptr pointing to a matching string
 3348    if (occurrence <= 1) break;
 3349    --occurrence;
 3350    ++ptr;
 3351  }
 3352 
 3353  if(ptr != NULL && *ptr != 0) {
 3354    strncpy(result, ptr+len, MAX_SUB_MESSAGE_LENGTH);
 3355     sizeOf = strlen(result);
 3356     if(sizeOf >= MAX_SUB_MESSAGE_LENGTH)
 3357       sizeOf = MAX_SUB_MESSAGE_LENGTH-1;
 3358     while((i<sizeOf) && (result[i] != '\n') && (result[i] != '\r'))
 3359       i++;
 3360     result[i] = '\0';
 3361   } else {
 3362     result[0] = '\0';
 3363   }
 3364 }
 3365 
 3366 void call::getFieldFromInputFile(const char *fileName, int field, char*& dest)
 3367 {
 3368   if (inFiles.find(fileName) == inFiles.end()) {
 3369     ERROR_P1("Invalid injection file: %s", fileName);
 3370   }
 3371   int line = (*m_lineNumber)[fileName];
 3372   if (line < 0) {
 3373     return;
 3374   }
 3375   dest += inFiles[fileName]->getField(line, field, dest, SIPP_MAX_MSG_SIZE);
 3376 }
 3377 
 3378 int  call::checkAutomaticResponseMode(char * P_recv) {
 3379 
 3380   int L_res = 0 ;
 3381 
 3382   if (strcmp(P_recv, "BYE")==0) {
 3383     L_res = 1 ;
 3384   } else if (strcmp(P_recv, "CANCEL") == 0) {
 3385     L_res = 2 ;
 3386   } else if (strcmp(P_recv, "PING") == 0) {
 3387     L_res = 3 ;
 3388   } else if (((strcmp(P_recv, "INFO") == 0) || (strcmp(P_recv, "NOTIFY") == 0) || (strcmp(P_recv, "UPDATE") == 0))
 3389                && (auto_answer == true)){
 3390     L_res = 4 ;
 3391   }
 3392 
 3393   return (L_res) ;
 3394 
 3395 }
 3396 
 3397 
 3398 bool call::automaticResponseMode(int P_case, char * P_recv)
 3399 {
 3400 
 3401   int res ;
 3402   char * old_last_recv_msg = NULL;
 3403   bool last_recv_msg_saved = false;
 3404 
 3405   switch (P_case) {
 3406   case 1: // response for an unexpected BYE
 3407     // usage of last_ keywords
 3408     last_recv_msg = (char *) realloc(last_recv_msg, strlen(P_recv) + 1);
 3409     strcpy(last_recv_msg, P_recv);
 3410 
 3411     // The BYE is unexpected, count it
 3412     scenario[msg_index] -> nb_unexp++;
 3413     if (default_behavior) {
 3414       WARNING_P1("Aborting call on an unexpected BYE for call: %s", (id==NULL)?"none":id);
 3415     sendBuffer(createSendingMessage(
 3416                     (char*)"SIP/2.0 200 OK\n"
 3417                     "[last_Via:]\n"
 3418                     "[last_From:]\n"
 3419                     "[last_To:]\n"
 3420                     "[last_Call-ID:]\n"
 3421                     "[last_CSeq:]\n"
 3422                     "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
 3423                     "Content-Length: 0\n\n"
 3424                     , -1)) ;
 3425 
 3426 #ifdef __3PCC__
 3427     // if twin socket call => reset the other part here
 3428     if (twinSippSocket && (msg_index > 0)) {
 3429       res = sendCmdBuffer
 3430       (createSendingMessage((char*)"call-id: [call_id]\ninternal-cmd: abort_call\n\n", -1));
 3431     }
 3432 #endif /* __3PCC__ */
 3433       CStat::instance()->computeStat(CStat::E_CALL_FAILED);
 3434       CStat::instance()->computeStat(CStat::E_FAILED_UNEXPECTED_MSG);
 3435       delete_call(id);
 3436     } else {
 3437       WARNING_P1("Continuing call on an unexpected BYE for call: %s", (id==NULL)?"none":id);
 3438     }
 3439       break ;
 3440 
 3441   case 2: // response for an unexpected cancel
 3442     // usage of last_ keywords
 3443     last_recv_msg = (char *) realloc(last_recv_msg, strlen(P_recv) + 1);
 3444     strcpy(last_recv_msg, P_recv);
 3445 
 3446     // The CANCEL is unexpected, count it
 3447     scenario[msg_index] -> nb_unexp++;
 3448     if (default_behavior) {
 3449       WARNING_P1("Aborting call on an unexpected CANCEL for call: %s", (id==NULL)?"none":id);
 3450     sendBuffer(createSendingMessage(
 3451                       (char*)"SIP/2.0 200 OK\n"
 3452                       "[last_Via:]\n"
 3453                       "[last_From:]\n"
 3454                       "[last_To:]\n"
 3455                       "[last_Call-ID:]\n"
 3456                       "[last_CSeq:]\n"
 3457                       "Contact: sip:sipp@[local_ip]:[local_port]\n"
 3458                       "Content-Length: 0\n\n"
 3459                       , -1)) ;
 3460 
 3461 #ifdef __3PCC__
 3462     // if twin socket call => reset the other part here
 3463     if (twinSippSocket && (msg_index > 0)) {
 3464       res = sendCmdBuffer
 3465       (createSendingMessage((char*)"call-id: [call_id]\ninternal-cmd: abort_call\n\n", -1));
 3466     }
 3467 #endif /* __3PCC__ */
 3468 
 3469     CStat::instance()->computeStat(CStat::E_CALL_FAILED);
 3470     CStat::instance()->computeStat(CStat::E_FAILED_UNEXPECTED_MSG);
 3471     delete_call(id);
 3472     } else {
 3473       WARNING_P1("Continuing call on unexpected CANCEL for call: %s", (id==NULL)?"none":id);
 3474     }
 3475     break ;
 3476 
 3477   case 3: // response for a random ping
 3478     // usage of last_ keywords
 3479     last_recv_msg = (char *) realloc(last_recv_msg, strlen(P_recv) + 1);
 3480     strcpy(last_recv_msg, P_recv);
 3481 
 3482    if (default_behavior) {
 3483     WARNING_P1("Automatic response mode for an unexpected PING for call: %s", (id==NULL)?"none":id);
 3484     count_in_stats = false; // Call must not be counted in statistics
 3485     sendBuffer(createSendingMessage(
 3486                     (char*)"SIP/2.0 200 OK\n"
 3487                     "[last_Via:]\n"
 3488                     "[last_Call-ID:]\n"
 3489                     "[last_To:]\n"
 3490                     "[last_From:]\n"
 3491                     "[last_CSeq:]\n"
 3492                     "Contact: sip:sipp@[local_ip]:[local_port]\n"
 3493                     "Content-Length: 0\n\n"
 3494                     , -1)) ;
 3495     // Note: the call ends here but it is not marked as bad. PING is a
 3496     //       normal message.
 3497 #ifdef __3PCC__
 3498     // if twin socket call => reset the other part here
 3499     if (twinSippSocket && (msg_index > 0)) {
 3500       res = sendCmdBuffer
 3501       (createSendingMessage((char*)"call-id: [call_id]\ninternal-cmd: abort_call\n\n",-1));
 3502     }
 3503 #endif /* __3PCC__ */
 3504 
 3505     CStat::instance()->computeStat(CStat::E_AUTO_ANSWERED);
 3506     delete_call(id);
 3507     } else {
 3508       WARNING_P1("Do not answer on an unexpected PING for call: %s", (id==NULL)?"none":id);
 3509     }
 3510     break ;
 3511 
 3512   case 4: // response for a random INFO, UPDATE or NOTIFY
 3513     // store previous last msg if msg is INFO, UPDATE or NOTIFY
 3514     // restore last_recv_msg to previous one
 3515     // after sending ok
 3516     old_last_recv_msg = NULL;
 3517     if (last_recv_msg != NULL) {
 3518       last_recv_msg_saved = true;
 3519       old_last_recv_msg = (char *) malloc(strlen(last_recv_msg)+1);
 3520       strcpy(old_last_recv_msg,last_recv_msg);
 3521     }
 3522     // usage of last_ keywords
 3523     last_recv_msg = (char *) realloc(last_recv_msg, strlen(P_recv) + 1);
 3524     strcpy(last_recv_msg, P_recv);
 3525 
 3526     WARNING_P1("Automatic response mode for an unexpected INFO, UPDATE or NOTIFY for call: %s", (id==NULL)?"none":id);
 3527     sendBuffer(createSendingMessage(
 3528                     (char*)"SIP/2.0 200 OK\n"
 3529                     "[last_Via:]\n"
 3530                     "[last_Call-ID:]\n"
 3531                     "[last_To:]\n"
 3532                     "[last_From:]\n"
 3533                     "[last_CSeq:]\n"
 3534                     "Contact: sip:sipp@[local_ip]:[local_port]\n"
 3535                     "Content-Length: 0\n\n"
 3536                     , -1)) ;
 3537 
 3538     // restore previous last msg
 3539     if (last_recv_msg_saved == true) {
 3540       last_recv_msg = (char *) realloc(last_recv_msg, strlen(old_last_recv_msg) + 1);
 3541       strcpy(last_recv_msg, old_last_recv_msg);
 3542       if (old_last_recv_msg != NULL) {
 3543         free(old_last_recv_msg);
 3544         old_last_recv_msg = NULL;
 3545       }
 3546     }
 3547     CStat::instance()->computeStat(CStat::E_AUTO_ANSWERED);
 3548     return true;
 3549     break;
 3550 
 3551     case 5: // response for an out of call message
 3552     old_last_recv_msg = NULL;
 3553     if (last_recv_msg != NULL) {
 3554       last_recv_msg_saved = true;
 3555       old_last_recv_msg = (char *) malloc(strlen(last_recv_msg)+1);
 3556       strcpy(old_last_recv_msg,last_recv_msg);
 3557     }
 3558     // usage of last_ keywords
 3559     last_recv_msg = (char *) realloc(last_recv_msg, strlen(P_recv) + 1);
 3560     strcpy(last_recv_msg, P_recv);
 3561 
 3562     WARNING("Automatic response mode for an out of call message");
 3563     sendBuffer(createSendingMessage(
 3564                     (char*)"SIP/2.0 200 OK\n"
 3565                     "[last_Via:]\n"
 3566                     "[last_Call-ID:]\n"
 3567                     "[last_To:]\n"
 3568                     "[last_From:]\n"
 3569                     "[last_CSeq:]\n"
 3570                     "Contact: sip:sipp@[local_ip]:[local_port]\n"
 3571                     "Content-Length: 0\n\n"
 3572                     , -1)) ;
 3573 
 3574     // restore previous last msg
 3575     if (last_recv_msg_saved == true) {
 3576       last_recv_msg = (char *) realloc(last_recv_msg, strlen(old_last_recv_msg) + 1);
 3577       strcpy(last_recv_msg, old_last_recv_msg);
 3578       if (old_last_recv_msg != NULL) {
 3579         free(old_last_recv_msg);
 3580         old_last_recv_msg = NULL;
 3581       }
 3582     }
 3583     CStat::instance()->computeStat(CStat::E_AUTO_ANSWERED);
 3584     return true;
 3585 
 3586     default:
 3587     ERROR_P1("Internal error for automaticResponseMode - mode %d is not implemented!", P_case);
 3588     break ;
 3589   }
 3590 
 3591   return false;
 3592 
 3593 }
 3594 
 3595 #ifdef PCAPPLAY
 3596 void *send_wrapper(void *arg)
 3597 {
 3598   play_args_t *s = (play_args_t *) arg;
 3599   //struct sched_param param;
 3600   //int ret;
 3601   //param.sched_priority = 10;
 3602   //ret = pthread_setschedparam(pthread_self(), SCHED_RR, &param);
 3603   //if(ret)
 3604   //  ERROR("Can't set RTP play thread realtime parameters");
 3605   pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
 3606   pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
 3607   send_packets(s);
 3608   pthread_exit(NULL);
 3609   return NULL;
 3610 }
 3611 #endif

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.8