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

📄 call.cpp

📁 sipp is sip protocal testing tool.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
bool call::next(){  int test = scenario[msg_index]->test;  /* What is the next message index? */  if ( scenario[msg_index]->next &&        ((test == -1) ||        (test < SCEN_VARIABLE_SIZE && M_callVariableTable[test] != NULL && M_callVariableTable[test]->isSet()))     ) {    /* For branching, use the 'next' attribute value */         msg_index = labelArray[scenario[msg_index]->next];  } else {    /* Without branching, use the next message */    msg_index++;  }  recv_timeout = 0;  if(msg_index >= scenario_len) {    // Call end -> was it successful?    if(call::last_action_result != call::E_AR_NO_ERROR) {      switch(call::last_action_result) {        case call::E_AR_REGEXP_DOESNT_MATCH:          CStat::instance()->computeStat(CStat::E_CALL_FAILED);          CStat::instance()->computeStat(CStat::E_FAILED_REGEXP_DOESNT_MATCH);          break;        case call::E_AR_HDR_NOT_FOUND:          CStat::instance()->computeStat(CStat::E_CALL_FAILED);          CStat::instance()->computeStat(CStat::E_FAILED_REGEXP_HDR_NOT_FOUND);          break;      }    } else {      CStat::instance()->computeStat(CStat::E_CALL_SUCCESSFULLY_ENDED);    }    delete_call(id);    return false;  }  return run();}bool call::run(){  bool            bInviteTransaction = false;  int             actionResult = 0;  assert(running);  if(msg_index >= scenario_len) {    ERROR_P3("Scenario overrun for call %s (%08x) (index = %d)\n",              id, this, msg_index);  }  /* Manages retransmissions or delete if max retrans reached */  if(next_retrans && (next_retrans < clock_tick)) {    nb_retrans++;    if ( (0 == strncmp (last_send_msg, "INVITE", 6)) )    {      bInviteTransaction = true;    }    if((nb_retrans > (bInviteTransaction ? max_invite_retrans : max_non_invite_retrans)) ||       (nb_retrans > max_udp_retrans)) {      scenario[last_send_index] -> nb_timeout ++;      if (scenario[last_send_index]->on_timeout) {  // action on timeout          WARNING_P3("Call-Id: %s, timeout on max UDP retrans for message %d, jumping to label %d ",                       id, msg_index, scenario[last_send_index]->on_timeout);          msg_index = labelArray[scenario[last_send_index]->on_timeout];          next_retrans = 0;          recv_timeout = 0;          if (msg_index < scenario_len) return true;          // here if asked to go to the last label  delete the call          CStat::instance()->computeStat(CStat::E_CALL_FAILED);          CStat::instance()->computeStat(CStat::E_FAILED_MAX_UDP_RETRANS);          if (default_behavior) {            // Abort the call by sending proper SIP message            return(abortCall());          } else {            // Just delete existing call            delete_call(id);            return false;          }      }      CStat::instance()->computeStat(CStat::E_CALL_FAILED);      CStat::instance()->computeStat(CStat::E_FAILED_MAX_UDP_RETRANS);      if (default_behavior) {        // Abort the call by sending proper SIP message        WARNING_P1("Aborting call on UDP retransmission timeout for Call-ID '%s'", id);        return(abortCall());      } else {        // Just delete existing call        delete_call(id);        return false;      }    } else {      nb_last_delay *= 2;      if (DEFAULT_T2_TIMER_VALUE < nb_last_delay)      {        if (!bInviteTransaction)        {          nb_last_delay = DEFAULT_T2_TIMER_VALUE;      }      }      if(send_raw(last_send_msg, last_send_index) < -1) {        return false;      }      scenario[last_send_index] -> nb_sent_retrans++;      CStat::instance()->computeStat(CStat::E_RETRANSMISSION);      next_retrans = clock_tick + nb_last_delay;    }  }  if(paused_until) {    /* Process a pending pause instruction until delay expiration */    if(paused_until > clock_tick) {      if (!remove_running_call(this)) {	ERROR("Tried to remove a running call that wasn't running!\n");      }      paused_calls.add_paused_call(this, true);      return true;    }    /* Our pause is over. */    paused_until = 0;    return next();  } else if(scenario[msg_index] -> pause_function) {    unsigned int pause;    pause  = scenario[msg_index] -> pause_function(scenario[msg_index]);    if (pause > INT_MAX) {      pause = INT_MAX;    }    paused_until = clock_tick + pause;    /* Increment the number of sessions in pause state */    ++scenario[msg_index]->sessions;    return run(); /* In case delay is 0 */  } #ifdef __3PCC__  else if(scenario[msg_index] -> M_type == MSG_TYPE_SENDCMD) {    int send_status;    if(next_retrans) {      return true;    }    send_status = sendCmdMessage(msg_index);    if(send_status != 0) { /* Send error */      return false; /* call deleted */    }    scenario[msg_index] -> M_nbCmdSent++;    next_retrans = 0;    return(next());  }#endif  else if(scenario[msg_index] -> M_type == MSG_TYPE_NOP) {    do_bookkeeping(msg_index);    actionResult = executeAction(NULL, msg_index);    return(next());  }  else if(scenario[msg_index] -> send_scheme) {    char * msg_snd;    int send_status;    /* Do not send a new message until the previous one which had     * retransmission enabled is acknowledged */    if(next_retrans) {      if (!remove_running_call(this)) {	ERROR("Tried to remove a running call that wasn't running!\n");      }      paused_calls.add_paused_call(this, true);      return true;    }    /* Handle counters and RTDs for this message. */    do_bookkeeping(msg_index);    /* decide whether to increment cseq or not      * basically increment for anything except response, ACK or CANCEL      * Note that cseq is only used by the [cseq] keyword, and     * not by default     */    int incr_cseq = 0;    if (strncmp(::scenario[msg_index]->send_scheme,"ACK",3) &&       strncmp(::scenario[msg_index]->send_scheme,"CANCEL",6) &&       strncmp(::scenario[msg_index]->send_scheme,"SIP/2.0",7)) {          ++cseq;          incr_cseq = 1;    }        if ((ctrlEW) || (poll_flag_write)) {      send_status = -1;    } else {    msg_snd = send_scene(msg_index, &send_status);    }    if(send_status == -1) { /* Would Block on TCP */      if (incr_cseq) --cseq;      return true; /* No step, nothing done, retry later */    } else if(send_status <-1) { /* Send error */      return false; /* call deleted */    }        last_send_index = msg_index;    last_send_msg = (char *) realloc(last_send_msg, strlen(msg_snd) + 1);    strcpy(last_send_msg, msg_snd);    if(last_recv_hash) {      /* We are sending just after msg reception. There is a great       * chance that we will be asked to retransmit this message */      recv_retrans_hash       = last_recv_hash;      recv_retrans_recv_index = last_recv_index;      recv_retrans_send_index = msg_index;          /* Prevent from detecting the cause relation between send and recv        * in the next valid send */      last_recv_hash = 0;    }    /* Update retransmission information */    if(scenario[msg_index] -> retrans_delay) {      if((transport == T_UDP) && (retrans_enabled)) {        next_retrans = clock_tick + scenario[msg_index] -> retrans_delay;        nb_retrans = 0;        nb_last_delay = scenario[msg_index]->retrans_delay;      }    } else {      next_retrans = 0;    }    #ifdef PCAPPLAY    actionResult = executeAction(msg_snd, msg_index);#endif        /* Update scenario statistics */    scenario[msg_index] -> nb_sent++;    return next();  } else if (scenario[msg_index]->M_type == MSG_TYPE_RECV#ifdef __3PCC__         || scenario[msg_index]->M_type == MSG_TYPE_RECVCMD#endif                                                 ) {    if (recv_timeout) {      if(recv_timeout > clock_tick || recv_timeout > getmilliseconds()) {	if (!remove_running_call(this)) {	  ERROR("Tried to remove a running call that wasn't running!\n");	}	paused_calls.add_paused_call(this, true);	return true;      }      recv_timeout = 0;      ++scenario[msg_index]->nb_timeout;      if (scenario[msg_index]->on_timeout == 0) {        // if you set a timeout but not a label, the call is aborted         WARNING_P2("Call-Id: %s, receive timeout on message %d without label to jump to (ontimeout attribute): aborting call",                    id, msg_index);        CStat::instance()->computeStat(CStat::E_CALL_FAILED);        CStat::instance()->computeStat(CStat::E_FAILED_TIMEOUT_ON_RECV);        if (default_behavior) {          return (abortCall());        } else {          delete_call(id);          return false;        }      }      WARNING_P3("Call-Id: %s, receive timeout on message %d, jumping to label %d",                   id, msg_index, scenario[msg_index]->on_timeout);      msg_index = labelArray[scenario[msg_index]->on_timeout];      recv_timeout = 0;      if (msg_index < scenario_len) return true;      // special case - the label points to the end - finish the call      CStat::instance()->computeStat(CStat::E_CALL_FAILED);      CStat::instance()->computeStat(CStat::E_FAILED_TIMEOUT_ON_RECV);      if (default_behavior) {        return (abortCall());      } else {        delete_call(id);        return false;      }    } else if ((scenario[msg_index]->retrans_delay) || (defl_recv_timeout)) {      if (scenario[msg_index]->retrans_delay)        // If timeout is specified on message receive, use it        recv_timeout = getmilliseconds() + scenario[msg_index]->retrans_delay;      else        // Else use the default timeout if specified        recv_timeout = getmilliseconds() + defl_recv_timeout;      return true;    } else {	/* We are going to wait forever. */	if (!remove_running_call(this)) {	  ERROR("Tried to remove a running call that wasn't running!\n");	}	paused_calls.add_paused_call(this, true);    }  }  return true;}bool call::process_unexpected(char * msg){  int search_index;  static int first = 1;  int res ;    scenario[msg_index] -> nb_unexp++;    if (scenario[msg_index] -> recv_request) {    if (default_behavior) {      WARNING_P3("Aborting call on unexpected message for Call-ID '%s': while expecting '%s', received '%s' ",                id, scenario[msg_index] -> recv_request, msg);  } else {      WARNING_P3("Continuing call on unexpected message for Call-ID '%s': while expecting '%s', received '%s' ",                  id, scenario[msg_index] -> recv_request, msg);    }  } else {    if (default_behavior) {      WARNING_P3("Aborting call on unexpected message for Call-ID '%s': while expecting '%d' response, received '%s' ",                   id, scenario[msg_index] -> recv_response, msg);    } else {      WARNING_P3("Continuing call on unexpected message for Call-ID '%s': while expecting '%d' response, received '%s' ",                 id, scenario[msg_index] -> recv_response, msg);  }  }    TRACE_MSG((s, "-----------------------------------------------\n"             "Unexpected %s message received:\n\n%s\n",             TRANSPORT_TO_STRING(transport),             msg));    if (default_behavior) {#ifdef __3PCC__  // if twin socket call => reset the other part here   if (twinSippSocket && (msg_index > 0)) {    //WARNING_P2("call-ID '%s', internal-cmd: abort_call %s",id, "");    res = sendCmdBuffer      (createSendingMessage((char*)"call-id: [call_id]\ninternal-cmd: abort_call\n", -1));  }#endif /* __3PCC__ */  // usage of last_ keywords => for call aborting  last_recv_msg = (char *) realloc(last_recv_msg, strlen(msg) + 1);  strcpy(last_recv_msg, msg);    CStat::instance()->computeStat(CStat::E_CALL_FAILED);    CStat::instance()->computeStat(CStat::E_FAILED_UNEXPECTED_MSG);  return (abortCall());  } else {    // Do not abort call nor send anything in reply if default behavior is disabled    return false;  }}bool call::abortCall(){  int res ;  int is_inv;  char * src_send = NULL ;  char * src_recv = NULL ;  if (last_send_msg != NULL) {    is_inv = !strncmp(last_send_msg, "INVITE", 6);  } else {    is_inv = false;  }    if ((toolMode != MODE_SERVER) && (msg_index > 0)) {    if ((call_established == false) && (is_inv)) {      src_recv = last_recv_msg ;      char * dest   ;      char   L_msg_buffer[SIPP_MAX_MSG_SIZE];      L_msg_buffer[0] = '\0';      char * L_param = L_msg_buffer;      // Answer unexpected errors (4XX, 5XX and beyond) with an ACK       // Contributed by F. Tarek Rogers      if((src_recv) && (get_reply_code(src_recv) >= 400)) {        strcpy(L_param, "ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n");        sprintf(L_param, "%s%s", L_param, "Via: SIP/2.0/[transport] [local_ip]:[local_port]\n");        sprintf(L_param, "%s%s", L_param, "From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]\n");        sprintf(L_param, "%s%s", L_param, "To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n");        sprintf(L_param, "%s%s", L_param, "Call-ID: [call_id]\n");        char * cseq;        cseq = get_header_field_code(src_recv,(char *) "CSeq:");        if (cseq != NULL) {          sprintf(L_param, "%s%s ACK\n", L_param, cseq);        }        sprintf(L_param, "%s%s", L_param, "Contact: <sip:sipp@[local_ip]:[local_port];transport=[transport]>\n");        sprintf(L_param, "%s%s", L_param, "Max-Forwards: 70\n");        sprintf(L_param, "%s%s", L_param, "Subject: Performance Test\n");        sprintf(L_param, "%s%s", L_param, "Content-Length: 0\n");        res = sendBuffer(createSendingMessage((char*)(L_param),-1));      } else if (src_recv) {        /* Call is not established and the reply is not a 4XX, 5XX */        /* And we already received a message. */        if (ack_is_pending == true) {          char * cseq = NULL;          /* If an ACK is expected from the other side, send it           * and send a BYE afterwards                           */          ack_is_pending = false;          /* Send an ACK */          strcpy(L_param, "ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n");          sprintf(L_param, "%s%s", L_param, "Via: SIP/2.0/[transport] [local_ip]:[local_port]\n");          sprintf(L_param, "%s%s", L_param, "From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]\n");          sprintf(L_param, "%s%s", L_param, "To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n");          sprintf(L_param, "%s%s", L_param, "Call-ID: [call_id]\n");          src_send = last_send_msg ;          cseq = get_header_field_code(src_recv,"CSeq:");          if (cseq != NULL) {            sprintf(L_param, "%s%s ACK\n", L_param, cseq);          }          sprintf(L_param, "%s%s", L_param, "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n");          sprintf(L_param, "%s%s", L_param,  "Content-Length: 0\n");          res = sendBuffer(createSendingMessage((char*)(L_param),-1));                    /* Send the BYE */          cseq = NULL;          strcpy(L_param, "BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n");          sprintf(L_param, "%s%s", L_param, "Via: SIP/2.0/[transport] [local_ip]:[local_port]\n");          sprintf(L_param, "%s%s", L_param, "From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]\n");          sprintf(L_param, "%s%s", L_param, "To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n");          sprintf(L_param, "%s%s", L_param, "Call-ID: [call_id]\n");          cseq = compute_cseq(src_recv);          if (cseq != NULL) {            sprintf(L_param, "%s%s BYE\n", L_param, compute_cseq(src_recv));          }          sprintf(L_param, "%s%s", L_param, "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n");          sprintf(L_param, "%s%s", L_param,  "Content-Length: 0\n");          res = sendBuffer(createSendingMessage((char*)(L_param),-1));

⌨️ 快捷键说明

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