Parent Directory
|
Revision Log
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 (¤tTime); 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(¤tTime),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, ¶m); 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 |