⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 call.cpp

📁 sip终端
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * *  Author : Richard GAYRAUD - 04 Nov 2003 *           Olivier Jacques *           From Hewlett Packard Company. *           Shriram Natarajan *           Peter Higginson *           Eric Miller */#include <iterator>#include <algorithm>#include <fstream>#include <iostream>#include "sipp.hpp"#define KEYWORD_SIZE 64call_map calls;/************** Call map and management routines **************/call_map * get_calls(){  return & calls;}static unsigned int next_number = 1;call * add_call(char * call_id, bool ipv6){  call * new_call;  new_call = new call(call_id, ipv6);  if(!new_call) {    ERROR("Memory Overflow");  }  calls[std::string(call_id)] = new_call;  if(!next_number) { next_number ++; }  new_call -> number = next_number;  /* Vital counters update */  next_number++;  open_calls++;  /* Statistics update */  calls_since_last_rate_change++;  total_calls ++;  if(open_calls > open_calls_peak) {     open_calls_peak = open_calls;    open_calls_peak_time = clock_tick / 1000;  }  return new_call;}call * add_call(bool ipv6){  static char call_id[MAX_HEADER_LEN];    call * new_call;    if(!next_number) { next_number ++; }    sprintf(call_id, 	  "%u-%u@%s",          next_number, pid, local_ip);    return add_call(call_id, ipv6);}call * get_call(char * call_id){  call * call_ptr;    call_ptr = calls[std::string(call_id)];  if(!call_ptr) {    calls.erase(std::string(call_id));  }    return call_ptr;}void delete_call(char * call_id){  call * call_ptr = calls[std::string(call_id)];  if(!calls.erase(std::string(call_id))) {    ERROR("Call not erased from map");  }   if(call_ptr) {    delete call_ptr;    open_calls--;  } else {    ERROR("Call not found");  }}/******* Very simple hash for retransmission detection  *******/unsigned long hash(char * msg) {  unsigned long rv = 0;  int len = strlen(msg);  int index = 0;    if (len > 4) {    rv  = msg[0] + msg[1] + msg[2] + msg[3];  }    if (len > 12) {    rv += msg[9] + msg[10] + msg[11] + msg[12];  }  rv <<= 8;  rv += len;  rv <<= 16;    for (index = 0; index < len; index ++) {    rv += + msg[index] * index;  }    return rv;}/******************* Call class implementation ****************/call::InputFileUsage call::m_usage   = call::InputFileSequentialOrder;int                  call::m_counter = 0;call::call(char * p_id, bool ipv6) : use_ipv6(ipv6){  memset(this, 0, sizeof(call));  id = strdup(p_id);  start_time = clock_tick;  call_established=false ;  count_in_stats=true ;  ack_is_pending=false ;  last_recv_msg = NULL;    call_remote_socket = 0;    // initialising the CallVariable with the Scenario variable  for(int i=0; i<SCEN_VARIABLE_SIZE; i++)     {      if(scenVariableTable[i] != NULL) {        M_callVariableTable[i] = new CCallVariable();        if (M_callVariableTable[i] == NULL) {          ERROR ("call variable allocation failed");        }      } else {        M_callVariableTable[i] = NULL;      }    }  // If not updated by a message we use the start time   // information to compute rtd information  start_time_rtd  = clock_tick;   // by default, last action result is NO_ERROR  last_action_result = call::E_AR_NO_ERROR;  if (InputFileRandomOrder == m_usage) {      m_localLineNumber = rand() % numLinesInFile;  } else {      m_localLineNumber = m_counter++;      if (m_counter >= numLinesInFile) {          m_counter = 0;      }  }  peer_tag[0] = '\0';}call::~call(){  deleted += 1;    if(comp_state) { comp_free(&comp_state); }  if(count_in_stats) {    CStat::instance()->computeStat(CStat::E_ADD_CALL_DURATION,                                    clock_tick - start_time);  }  call_duration_sum += clock_tick - start_time;  call_duration_nb++;    if(pollset_index) {    pollset_remove(pollset_index);    shutdown(call_socket, SHUT_RDWR);    close(call_socket);  }  /* Deletion of the call variable */   for(int i=0; i<SCEN_VARIABLE_SIZE; i++) {    if(M_callVariableTable[i] != NULL) {      delete M_callVariableTable[i] ;      M_callVariableTable[i] = NULL;    }  }  if(id) { free(id); }  if(last_recv_msg) { free(last_recv_msg); }  if(last_send_msg) { free(last_send_msg); }  if(dialog_route_set) {       free(dialog_route_set);  }#ifdef _USE_OPENSSL  if(dialog_authentication) {       free(dialog_authentication);  }#endif  call_established= false ;} void call::connect_socket_if_needed(){	   if(call_socket) return;  if(!multisocket) return;  if(transport == T_UDP) {    struct sockaddr_storage saddr;    sipp_socklen_t len;        if(toolMode != MODE_CLIENT) return;    if((call_socket = socket(use_ipv6 ? AF_INET6 : AF_INET,                             SOCK_DGRAM,                             0)) == -1) {      ERROR_NO("Unable to get an UDP socket");    }        memset(&saddr, 0, sizeof(struct sockaddr_storage));    saddr.ss_family       = AF_INET;        if(bind(call_socket,            (sockaddr *)(void *)&saddr,            use_ipv6 ? sizeof(struct sockaddr_in6) :                       sizeof(struct sockaddr_in))) {      ERROR_NO("Unable to bind UDP socket");    }        if (use_ipv6) {      len = sizeof(struct sockaddr_in6);    } else {      len = sizeof(struct sockaddr_in);    }    getsockname(call_socket,                 (sockaddr *)(void *)&saddr,                &len);    if (use_ipv6) {      call_port =        ntohs((short)((_RCAST(struct sockaddr_in6 *, &saddr))->sin6_port));    } else {      call_port        = ntohs((short)((_RCAST(struct sockaddr_in *, &saddr))->sin_port));    }  } else { /* TCP */    if((call_socket= socket(use_ipv6 ? AF_INET6 : AF_INET,                            SOCK_STREAM,                            0))== -1) {      ERROR_NO("Unable to get a TCP socket");    }        sipp_customize_socket(call_socket);    /*    struct sockaddr_storage *L_dest = &remote_sockaddr;    if (use_remote_sending_addr) {        L_dest = &remote_sending_sockaddr ;     }    */              //  (struct sockaddr *)(void *)&remote_sockaddr,              //  (struct sockaddr *)(void *)L_dest,               // use_ipv6 ? sizeof(struct sockaddr_in6) :                //           sizeof(struct sockaddr_in))) {		    if(connect(call_socket,               (struct sockaddr *)(void *)&remote_sockaddr,	        SOCK_ADDR_SIZE(&remote_sockaddr))) {            if(errno == EINVAL){        /* This occurs sometime on HPUX but is not a true INVAL */        ERROR("Unable to connect a TCP socket, remote peer error");      } else {        ERROR_NO("Unable to connect a TCP socket");      }    }  }  /* Asks to receive incoming messages */  pollset_index = pollset_add(this, call_socket);}bool lost(int percent){  static int inited = 0;  if(!lose_packets) return false;  if(!percent) return false;  if(!inited) {    srand((unsigned int) time(NULL));    inited = 1;  }  if((rand() % 100) < percent) {    return true;  } else {    return false;  }}int call::send_raw(char * msg, int index) {  void ** state;  int sock;  int rc;#ifdef _USE_OPENSSL  SSL *ssl;  extern SSL *ssl_list[];#endif  struct timeval currentTime;  GET_TIME (&currentTime);  TRACE_MSG((s, "----------------------------------------------- %s\n"             "%s message sent:\n\n%s\n",             CStat::instance()->formatTime(&currentTime),             TRANSPORT_TO_STRING(transport),             msg));    if(lost(scenario[index] -> lost)) {    TRACE_MSG((s, "%s message voluntary lost (while sending).", TRANSPORT_TO_STRING(transport)));        if(comp_state) { comp_free(&comp_state); }    scenario[index] -> nb_lost++;    return 0;  }    if(call_socket) {    state = &comp_state;    sock = call_socket;    if (use_remote_sending_addr) {      if (!call_remote_socket) {        struct sockaddr_storage *L_dest = &remote_sending_sockaddr;        if((call_remote_socket= socket(use_ipv6 ? AF_INET6 : AF_INET,                            SOCK_STREAM,                            0))== -1) {          ERROR_NO("Unable to get a TCP socket");        }            sipp_customize_socket(call_remote_socket);        if(connect(call_remote_socket,               (struct sockaddr *)(void *)L_dest,	        SOCK_ADDR_SIZE(&remote_sockaddr))) {          if(errno == EINVAL){            /* This occurs sometime on HPUX but is not a true INVAL */            ERROR("Unable to connect a TCP socket, remote peer error");          } else {            ERROR_NO("Unable to connect a TCP socket");          }        }      }      sock=call_remote_socket ;    }#ifdef _USE_OPENSSL    ssl  = ssl_list[sock];#endif  } else {    state = &monosocket_comp_state;    if(transport == T_UDP) {      sock = main_socket;    } else {      sock = tcp_multiplex;#ifdef _USE_OPENSSL      ssl = ssl_tcp_multiplex;#endif    }  }#ifdef _USE_OPENSSL  if ( transport == T_TLS ) {    rc = send_message_tls(ssl, state, msg);  } else {#endif  rc = send_message(sock, state, msg);#ifdef _USE_OPENSSL  }#endif  if(rc == -1) return -1;  if(rc < -1) {    CStat::instance()->computeStat(CStat::E_CALL_FAILED);    CStat::instance()->computeStat(CStat::E_FAILED_CANNOT_SEND_MSG);    delete_call(id);  }    return rc; /* OK */}int call::sendBuffer(char * msg) {  void ** state;  int sock;  int rc;  TRACE_MSG((s, "-----------------------------------------------\n"             "%s message send:\n\n%s\n",             TRANSPORT_TO_STRING(transport),             msg));  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -