📄 sipp.cpp
字号:
TRANSPORT_TO_STRING(transport), size, buffer)); return size;}void pollset_process(){ int rs; int loops = MAX_RECV_LOOPS; while((loops-- > 0) && /* Ensure some minimal statistics display sometime */ (rs = poll(pollfiles, pollnfds, 1)) > 0) { if((rs < 0) && (errno == EINTR)) { return; } if(rs < 0) { ERROR_NO("poll() error"); } while(rs > 0) { char msg[SIPP_MAX_MSG_SIZE]; int msg_size; char * call_id; call * call_ptr; int pollset_index = 0; memset(msg,0,sizeof(msg)); msg_size = recv_message(msg, SIPP_MAX_MSG_SIZE, &pollset_index); if(msg_size > 0) { if (sipMsgCheck(msg, msg_size#ifdef __3PCC__ ,pollset_index#endif // __3PCC__ ) == true) { call_id = get_call_id(msg); call_ptr = get_call(call_id); if(!call_ptr) { if(toolMode == MODE_SERVER) { // Adding a new INCOMING call ! CStat::instance()->computeStat (CStat::E_CREATE_INCOMING_CALL); call_ptr = add_call(call_id); if((pollset_index) && (pollfiles[pollset_index].fd != main_socket) && (pollfiles[pollset_index].fd != tcp_multiplex) ) { call_ptr -> call_socket = pollfiles[pollset_index].fd; } }#ifdef __3PCC__ else if(toolMode == MODE_3PCC_CONTROLLER_B || toolMode == MODE_3PCC_A_PASSIVE) { // Adding a new OUTGOING call ! CStat::instance()->computeStat (CStat::E_CREATE_OUTGOING_CALL); call_ptr = add_call(call_id); if((pollset_index) && (pollfiles[pollset_index].fd != main_socket) && (pollfiles[pollset_index].fd != tcp_multiplex) && (pollfiles[pollset_index].fd != localTwinSippSocket) && (pollfiles[pollset_index].fd != twinSippSocket)) { call_ptr -> call_socket = pollfiles[pollset_index].fd; } }#endif else // mode != from SERVER and 3PCC Controller B { nb_out_of_the_blue++; CStat::instance()->computeStat (CStat::E_OUT_OF_CALL_MSGS); // This is a message that is not relating to any call } } if(call_ptr) {#ifdef __3PCC__ if( (pollfiles[pollset_index].fd == localTwinSippSocket) || (pollfiles[pollset_index].fd == twinSippSocket)) { if(!call_ptr -> process_twinSippCom(msg)) { return; } } else#endif { if(!call_ptr -> process_incomming(msg)) { /* Needs to rebuild the pollset (socket removed, * call deleted, etc... Cause pollcalls is now * invalid and will alway lead poll() to return * an error.*/ return; } } } } else { // sipMsgCheck == false // unrecognized message => discard it WARNING("non SIP message discarded"); } } // end if msg >=0 rs--; } } cpu_max = loops <= 0;}/* Send loop & trafic generation*/void traffic_thread(){ unsigned int calls_to_open = 0; unsigned int new_time; unsigned int last_time; int timer_resolution = DEFAULT_TIMER_RESOLUTION; bool firstPass; firstPass = true; last_time = getmilliseconds(); /* Prepare pollset with basic sockets */ pollset_reset(); while(1) { scheduling_loops ++; /* update local time, except if resetted*/ new_time = getmilliseconds(); clock_tick += (new_time - last_time); last_time = new_time; if ((!quitting) && (!paused)) { calls_to_open = (unsigned int) (((clock_tick - last_rate_change_time) * rate/rate_period_s) / 1000) - calls_since_last_rate_change; if( (toolMode == MODE_CLIENT)#ifdef __3PCC__ || (toolMode == MODE_3PCC_CONTROLLER_A)#endif ) { while((calls_to_open--) && (open_calls < open_calls_allowed) && (total_calls < stop_after)) { // adding a new OUTGOING CALL CStat::instance()->computeStat(CStat::E_CREATE_OUTGOING_CALL); call * call_ptr = add_call(); call_ptr -> run(); } if(open_calls >= open_calls_allowed) { set_rate(rate); } } // Quit after asked number of calls is reached if(total_calls >= stop_after) { quitting = 1; } } else if (quitting) { /* Quitting and no more openned calls, close all */ if(!open_calls) { // Dump the latest statistics if necessary if(dumpInFile) { CStat::instance()->dumpData(); } /* Screen dumping in a file if asked */ if(screenf) { print_screens(); } screen_exit(EXIT_TEST_RES_UNKNOWN); } } if(compression) { timer_resolution = 50; } /* Schedule all pending calls and process their timers */ if((clock_tick - last_timer_cycle) > timer_resolution) { call_map * calls = get_calls(); call_map::iterator iter; /* Workaround hpux problem with iterators. Deleting the * current object when iterating breaks the iterator and * leads to iterate again on the destroyed (deleted) * object. Thus, we have to wait ont step befere actual * deletion of the object*/ call * last = NULL; for(iter = calls->begin(); iter != calls->end(); iter++) { if(last) { last -> run(); } last = iter -> second; } if(last) { last -> run(); } last_timer_cycle = clock_tick; } /* Receive incomming messages */ pollset_process(); if(firstPass) { // dumping (to create file on disk) and showing // screen at the beginning even if the report // period is not reach firstPass = false; print_statistics(0); /* Dumping once to create the file on disk */ if(dumpInFile) { CStat::instance()->dumpData(); } } if((clock_tick - last_report_time) >= report_freq) { print_statistics(0); CStat::instance()->computeStat(CStat::E_RESET_PD_COUNTERS); last_report_time = clock_tick; last_report_calls = total_calls; rtd_sum = 0; rtd_nb = 0; call_duration_sum = 0; call_duration_nb = 0; scheduling_loops = 0; } // FIXME - Should we recompute time ? print stat take // a lot of time, so the clock_time is no more // the current time ! if(dumpInFile) { if((clock_tick - last_dump_time) >= report_freq_dumpLog) { CStat::instance()->dumpData(); CStat::instance()->computeStat(CStat::E_RESET_PL_COUNTERS); last_dump_time = clock_tick; } } }}/*************** RTP ECHO THREAD ***********************/void rtp_echo_thread (void * param){ char msg[2048]; size_t nr, ns; sipp_socklen_t len; int rc; sigset_t mask; sigfillset(&mask); /* Mask all allowed signals */ rc = pthread_sigmask(SIG_BLOCK, &mask, NULL); for (;;) { len = sizeof(remote_rtp_addr); nr = recvfrom(media_socket, msg, sizeof(msg), 0, (sockaddr *)(void *) &remote_rtp_addr, &len); if (((long)nr) < 0) { WARNING_P2("%s %i", "Error on RTP echo reception - stopping echo - errno=", errno); return; } ns = sendto(media_socket, msg, nr, 0, (sockaddr *)(void *) &remote_rtp_addr, len); if (ns != nr) { WARNING_P2("%s %i", "Error on RTP echo transmission - stopping echo - errno=", errno); return; } rtp_pckts++; rtp_bytes += ns; }}/* Help screen */void help() { printf ("\n" "Usage:\n" "\n" " sipp remote_host[:remote_port] [options]\n" "\n" " Available options:\n" "\n" " -v : Display version and copyright information.\n" "\n" " -bg : Launch the tool in background mode.\n" "\n" " -p local_port : Set the local port number. Default is a\n" " random free port chosen by the system.\n" "\n" " -i local_ip : Set the local IP address for 'Contact:',\n" " 'Via:', and 'From:' headers. Default is\n" " primary host IP address.\n" "\n" " -inf file_name : Inject values from an external CSV file during calls\n" " into the scenarios.\n" " First line of this file say whether the data is \n" " to be read in sequence (SEQUENTIAL) or random \n" " (RANDOM) order.\n" " Each line corresponds to one call and has one or \n" " more ';' delimited data fields. Those fields can be \n" " referred as [field0], [field1], ... in the xml \n" " scenario file.\n" "\n" " -d duration : Controls the length (in milliseconds) of\n" " calls. More precisely, this controls\n" " the duration of 'pause' instructions in\n" " the scenario, if they do not have a\n" " 'milliseconds' section. Default value is 0.\n" "\n" " -r rate (cps) : Set the call rate (in calls per seconds).\n" " This value can be changed during test by\n" " pressing '+','_','*' or '/'. Default is 10.\n" " pressing '+' key to increase call rate by 1,\n" " pressing '-' key to decrease call rate by 1,\n" " pressing '*' key to increase call rate by 10,\n" " pressing '/' key to decrease call rate by 10.\n" " If the -rp option is used, the call rate is\n" " calculated with the period in ms given \n" " by the user.\n" "\n" " -rp period (ms) : Specify the rate period in milliseconds for the call\n" " rate.\n" " Default is 1 second.\n" " This allows you to have n calls every m milliseconds \n" " (by using -r n -rp m).\n" " Example: -r 7 -rp 2000 ==> 7 calls every 2 seconds.\n" "\n" " -sf filename : Loads an alternate xml scenario file.\n" " To learn more about XML scenario syntax,\n" " use the -sd option to dump embedded \n" " scenarios. They contain all the necessary\n" " help.\n" "\n" " -sn name : Use a default scenario (embedded in\n" " the sipp executable). If this option is omitted,\n" " the Standard SipStone UAC scenario is loaded.\n" " Available values in this version:\n" "\n" " 'uac' : Standard SipStone UAC (default).\n" " 'uas' : Simple UAS responder (UDP only).\n" " 'regexp' : Standard SipStone UAC - with\n" " regexp and variables.\n"#ifdef __3PCC__ "\n" " Default 3pcc scanerios (see -3pcc option):\n" "\n" " '3pcc-C-A' : Controller A side (must be started\n" " after all other 3pcc scenarios)\n" " '3pcc-C-B' : Controller B side.\n" " '3pcc-A' : A side.\n" " '3pcc-B' : B side.\n"#endif "\n" " -sd name : Dumps a default scenario (embeded in\n" " the sipp executable)\n" "\n" " -t [u1|un|t1|tn] : Set the transport mode:\n" "\n" " u1: UDP with one socket (default),\n" " un: UDP with one socket per call,\n" " t1: TCP with one socket,\n" " tn: TCP with one socket per call.\n" "\n"); if(!strlen(comp_error)) { printf (" It appears that you installed the\n" " " COMP_PLUGGIN " pluggin. 2 additionnal\n" " transport modes are available:\n" "\n" " c1: u1 + compression,\n" " cn: un + compression.\n" "\n"); } printf (" -trace_msg : Displays sent and received SIP messages in\n" " <scenario file name>_<ppid>_messages.log\n" "\n" " -trace_screen : Dump statistic screens in the \n" " <scenario_name>_<ppid>_screens.log file when\n" " quitting SIPp. Useful to get a final status report\n" " in background mode (-bg option).\n" "\n" " -trace_timeout : Displays call ids for calls with timeouts in\n" " <scenario file name>_<ppid>_timeout.log\n" "\n" " -trace_stat : Dumps all statistics in <scenario_name>_<ppid>.csv>\n" " file. Use the '-h stat' option for a detailed\n" " description of the statistics file content.\n" "\n" " -stf file_name : Set the file name to use to dump statistics\n" "\n" " -trace_err : Trace all unexpected messages in\n" " <scenario file name>_<ppid>_errors.log.\n" "\n" " -s service_name : Set the username part of the resquest URI.\n" " Default is 'service'.\n" "\n" " -f frequency : Set the statistics report frequency on screen\n" " (in seconds). Default is 1.\n" "\n" " -fd frequency : Set the statistics dump log report frequency\n" " (in seconds). Default is 60.\n" "\n" " -l calls_limit : Set the maximum number of simultaneous\n" " calls. Once this limit is reached, traffic\n" " is decreased until the number of open calls\n" " goes down. Default:\n" "\n" " (3 * call_duration (s) * rate).\n" "\n" " -m calls : Stop the test and exit when 'calls' calls are\n" " processed.\n" "\n" " -mp local_port : Set the local RTP echo port number. Default\n" " is none. RTP/UDP packets received on that\n" " port are echoed to their sender.\n" "\n" " -mi local_rtp_ip : Set the local IP address for RTP echo.\n" "\n"#ifdef __3PCC__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -