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

📄 call.cpp

📁 sipp is sip protocal testing tool.
💻 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 *           Venkatesh *           Enrico Hartung *           Nasir Khan *           Lee Ballard *           Guillaume Teissier from FTR&D *           Wolfgang Beck *           Venkatesh *           Vlad Troyanker *           Charles P Wright from IBM Research *           Amit On from Followap */#include <iterator>#include <algorithm>#include <fstream>#include <iostream>#include <sys/types.h>#include <sys/wait.h>#ifdef PCAPPLAY#include "send_packets.h"#endif#include "sipp.hpp"#include "assert.h"#define KEYWORD_SIZE 256#ifdef _USE_OPENSSLextern  SSL                 *ssl_list[];extern  struct pollfd        pollfiles[];extern  SSL_CTX             *sip_trp_ssl_ctx;#endifextern  map<string, int>     map_perip_fd;call_map calls;call_list running_calls;timewheel paused_calls;#ifdef PCAPPLAY/* send_packets pthread wrapper */void *send_wrapper(void *);#endif/************** Call map and management routines **************/call_map * get_calls(){  return & calls;}static unsigned int next_number = 1;unsigned int get_tdm_map_number(unsigned int number) {  unsigned int nb = 0;  unsigned int i=0;  unsigned int interval=0;  unsigned int random=0;  bool found = false;  /* Find a number in the tdm_map which is not in use */  interval = (tdm_map_a+1) * (tdm_map_b+1) * (tdm_map_c+1);  random = rand() % interval;  while ((i<interval) && (!found)) {    if (tdm_map[(random + i - 1) % interval] == false) {      nb = (random + i - 1) % interval;      found = true;    }     i++;  }   if (!found) {    return 0;  } else {    return nb+1;  } }call * add_call(char * call_id, bool ipv6){  call * new_call;  unsigned int nb;  if(!next_number) { next_number ++; }  if (use_tdmmap) {    nb = get_tdm_map_number(next_number);    if (nb != 0) {      /* Mark the entry in the list as busy */      tdm_map[nb - 1] = true;    } else {      /* Can't create the new call */      WARNING("Can't create new outgoing call: all tdm_map circuits busy");      return NULL;    }  }  new_call = new call(call_id, ipv6);  if(!new_call) {    ERROR("Memory Overflow");  }  /* All calls must exist in the map. */  calls[std::string(call_id)] = new_call;  /* All calls start off in the running state. */  add_running_call(new_call);  new_call -> number = next_number;  new_call -> tdm_map_number = nb - 1;  /* 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;}#ifdef _USE_OPENSSLcall * add_call(char * call_id , int P_pollset_indx, bool ipv6){  call * new_call = add_call(call_id, ipv6);  new_call -> pollset_index = P_pollset_indx;  return new_call;}#endifcall * add_call(bool ipv6){  static char call_id[MAX_HEADER_LEN];    call * new_call;  char * src = call_id_string;  int count = 0;    if(!next_number) { next_number ++; }    while (*src && count < MAX_HEADER_LEN-1) {      if (*src == '%') {          ++src;          switch(*src++) {          case 'u':              count += snprintf(&call_id[count], MAX_HEADER_LEN-count-1,"%u", next_number);              break;          case 'p':              count += snprintf(&call_id[count], MAX_HEADER_LEN-count-1,"%u", pid);              break;          case 's':              count += snprintf(&call_id[count], MAX_HEADER_LEN-count-1,"%s", local_ip);              break;          default:      // treat all unknown sequences as %%              call_id[count++] = '%';              break;          }      } else {        call_id[count++] = *src++;      }  }  call_id[count] = 0;  return add_call(call_id, ipv6);}call * get_call(char * call_id){  call * call_ptr;  call_map::iterator call_it ;  call_it = calls.find(call_map::key_type(call_id));  call_ptr = (call_it != calls.end()) ? call_it->second : NULL ;  return call_ptr;}void delete_call(char * call_id){  call * call_ptr;  call_map::iterator call_it ;  call_it = calls.find(call_map::key_type(call_id));  call_ptr = (call_it != calls.end()) ? call_it->second : NULL ;  if(call_ptr) {    if (use_tdmmap)      tdm_map[call_ptr->tdm_map_number] = false;    calls.erase(call_it);    if (call_ptr->running) {      remove_running_call(call_ptr);    } else {      paused_calls.remove_paused_call(call_ptr);    }    delete call_ptr;    open_calls--;  } else {    if (start_calls == 0) {      ERROR("Call not found");    }  }}void delete_calls(void){  call * call_ptr;    call_map::iterator call_it ;  call_it = calls.begin();  while (call_it != calls.end()) {    call_ptr = (call_it != calls.end()) ? call_it->second : NULL ;    WARNING_P1("Aborting call with Call-Id '%s'", call_ptr->id);    call_ptr->abortCall();    call_it = calls.begin();  }}/* Routines for running calls. *//* Get the overall list of running calls. */call_list * get_running_calls(){  return & running_calls;}/* Put this call in the run queue. */void add_running_call(call *call) {  call->runit = running_calls.insert(running_calls.end(), call);  call->running = true;}/* Remove this call from the run queue. */bool remove_running_call(call *call) {  if (!call->running) {    return false;    }  running_calls.erase(call->runit);  call->running = false;  return true;}/* When should this call wake up? */unsigned int call_wake(call *call) {  unsigned int wake = 0;  if (call->paused_until) {    wake = call->paused_until;  }  if (call->next_retrans && (!wake || (call->next_retrans < wake))) {    wake = call->next_retrans;  }  if (call->recv_timeout && (!wake || (call->recv_timeout < wake))) {    wake = call->recv_timeout;  }  return wake;}call_list *timewheel::call2list(call *call) {  unsigned int wake = call_wake(call);  unsigned int wake_sigbits = wake;  unsigned int base_sigbits = wheel_base;  if (wake == 0) {    return &forever_list;  }  wake_sigbits /= LEVEL_ONE_SLOTS;  base_sigbits /= LEVEL_ONE_SLOTS;  if (wake_sigbits == base_sigbits) {    return &wheel_one[wake % LEVEL_ONE_SLOTS];  }  wake_sigbits /= LEVEL_TWO_SLOTS;  base_sigbits /= LEVEL_TWO_SLOTS;  if (wake_sigbits == base_sigbits) {    return &wheel_two[(wake / LEVEL_ONE_SLOTS) % LEVEL_TWO_SLOTS];  }  assert(wake_sigbits < LEVEL_THREE_SLOTS);  return &wheel_three[wake_sigbits];}int expire_paused_calls() {  return paused_calls.expire_paused_calls();}int paused_calls_count() {  return paused_calls.size();}void remove_paused_call(call *call) {  assert(!call->running);  paused_calls.remove_paused_call(call);}/* Iterate through our sorted set of paused calls, removing those that * should no longer be paused, and adding them to the run queue. */int timewheel::expire_paused_calls() {  int found = 0;  while (wheel_base < clock_tick) {    int slot1 = wheel_base % LEVEL_ONE_SLOTS;    /* Migrate calls from slot2 when we hit 0. */    if (slot1 == 0) {      int slot2 = (wheel_base / LEVEL_ONE_SLOTS) % LEVEL_TWO_SLOTS;      /* If slot2 is also zero, we must migrate calls from slot3 into slot2. */      if (slot2 == 0) {	int slot3 = ((wheel_base / LEVEL_ONE_SLOTS) / LEVEL_TWO_SLOTS);	assert(slot3 < LEVEL_THREE_SLOTS);	for (call_list::iterator l3it = wheel_three[slot3].begin();	     l3it != wheel_three[slot3].end();	     l3it++) {	  /* Migrate this call to wheel two. */	  add_paused_call(*l3it, false);        }	wheel_three[slot3].clear();      }      for (call_list::iterator l2it = wheel_two[slot2].begin();	  l2it != wheel_two[slot2].end();	  l2it++) {	/* Migrate this call to wheel one. */	add_paused_call(*l2it, false);      }      wheel_two[slot2].clear();    }    found += wheel_one[slot1].size();    for(call_list::iterator it = wheel_one[slot1].begin();	it != wheel_one[slot1].end(); it++) {      add_running_call(*it);      count--;    }    wheel_one[slot1].clear();    wheel_base++;  }  return found;}void timewheel::add_paused_call(call *call, bool increment) {  call_list *list = call2list(call);  call->pauseit = list->insert(list->end(), call);  if (increment) {    count++;  }}void timewheel::remove_paused_call(call *call) {  call_list *list = call2list(call);  list->erase(call->pauseit);  count--;}timewheel::timewheel() {  count = 0;  wheel_base = clock_tick;}int timewheel::size() {  return count;}#ifdef PCAPPLAY/******* Media information management *************************//* * Look for "c=IN IP4 " pattern in the message and extract the following value * which should be IP address */uint32_t get_remote_ip_media(char *msg){    char pattern[] = "c=IN IP4 ";    char *begin, *end;    char ip[32];    begin = strstr(msg, pattern);    if (!begin) {      /* Can't find what we're looking at -> return no address */      return INADDR_NONE;    }    begin += sizeof("c=IN IP4 ") - 1;    end = strstr(begin, "\r\n");    if (!end)      return INADDR_NONE;    memset(ip, 0, 32);    strncpy(ip, begin, end - begin);    return inet_addr(ip);}/* * Look for "c=IN IP6 " pattern in the message and extract the following value * which should be IPv6 address */uint8_t get_remote_ipv6_media(char *msg, struct in6_addr addr){    char pattern[] = "c=IN IP6 ";    char *begin, *end;    char ip[128];    memset(&addr, 0, sizeof(addr));    memset(ip, 0, 128);

⌨️ 快捷键说明

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