📄 sipp.cpp
字号:
/* * 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 * Marc LAMBERTON * Olivier JACQUES * From Hewlett Packard Company. * F. Tarek Rogers * Peter Higginson * Vincent Luba */#define GLOBALS_FULL_DEFINITION#include "sipp.hpp"#ifdef _USE_OPENSSLSSL_CTX *sip_trp_ssl_ctx = NULL; /* For SSL cserver context */SSL_CTX *sip_trp_ssl_ctx_client = NULL; /* For SSL cserver context */SSL_CTX *twinSipp_sip_trp_ssl_ctx_client = NULL; /* For SSL cserver context */#define CALL_BACK_USER_DATA "ksgr"/*** passwd_call_back_routine implementation***/intpasswd_call_back_routine(char *buf , int size , int flag, void *passwd){ strncpy(buf, (char *)(passwd), size); buf[size - 1] = '\0'; return(strlen(buf));}#endif/***************** System Portability Features *****************/unsigned int getmilliseconds(){ struct timeval LS_system_time; unsigned long long int VI_milli; static unsigned long long int VI_milli_base = 0; gettimeofday(&LS_system_time, NULL); VI_milli = ((unsigned long long) LS_system_time.tv_sec) * 1000LL + (LS_system_time.tv_usec / 1000LL); if (!VI_milli_base) VI_milli_base = VI_milli - 1; VI_milli = VI_milli - VI_milli_base; return (unsigned int) VI_milli;}#ifdef _USE_OPENSSLint send_nowait_tls(SSL *ssl, const void *msg, int len, int flags){ int initial_fd_flags; int rc; int fd; int fd_flags; if ( (fd = SSL_get_fd(ssl)) == -1 ) { return (-1); } fd_flags = fcntl(fd, F_GETFL , NULL); initial_fd_flags = fd_flags; fd_flags |= O_NONBLOCK; fcntl(fd, F_SETFL , fd_flags); rc = SSL_write(ssl,msg,len); if ( rc <= 0 ) { return(rc); } fcntl(fd, F_SETFL , initial_fd_flags); return rc;}#endif int send_nowait(int s, const void *msg, int len, int flags){#ifdef MSG_DONTWAIT return send(s, msg, len, flags | MSG_DONTWAIT);#else int fd_flags = fcntl(s, F_GETFL , NULL); int initial_fd_flags; int rc; initial_fd_flags = fd_flags; // fd_flags &= ~O_ACCMODE; // Remove the access mode from the value fd_flags |= O_NONBLOCK; fcntl(s, F_SETFL , fd_flags); rc = send(s, msg, len, flags); fcntl(s, F_SETFL , initial_fd_flags); return rc;#endif }char * get_inet_address(struct sockaddr_storage * addr){ static char * ip_addr = NULL; int res; if (!ip_addr) { ip_addr = (char *)malloc(1024*sizeof(char)); } if (getnameinfo(_RCAST(struct sockaddr *, addr), sizeof(struct sockaddr), ip_addr, 1024, NULL, 0, NI_NUMERICHOST) != 0) { strcpy(ip_addr, "addr not supported"); } return ip_addr;}void get_host_and_port(char * addr, char * host, int * port){ /* Separate the port number (if any) from the host name. * Thing is, the separator is a colon (':'). The colon may also exist * in the host portion if the host is specified as an IPv6 address (see * RFC 2732). If that's the case, then we need to skip past the IPv6 * address, which should be contained within square brackets ('[',']'). */ char *p; p = strchr( addr, '[' ); /* Look for '['. */ if( p != NULL ) { /* If found, look for ']'. */ p = strchr( p, ']' ); } if( p == NULL ) { /* If '['..']' not found, */ p = addr; /* scan the whole string. */ } else { /* If '['..']' found, */ char *p1; /* extract the remote_host */ char *p2; p1 = strchr( addr, '[' ); p2 = strchr( addr, ']' ); *p2 = '\0'; strcpy(host, p1 + 1); } /* Starting at <p>, which is either the start of the host substring * or the end of the IPv6 address, find the last colon character. */ p = strchr( p, ':' ); if( NULL != p ) { *p = '\0'; *port = atol(p + 1); } else { *port = 0; }}char * strcasestr2(char *s, char *find) { char c, sc; size_t len; if ((c = *find++) != 0) { c = tolower((unsigned char)c); len = strlen(find); do { do { if ((sc = *s++) == 0) return (NULL); } while ((char)tolower((unsigned char)sc) != c); } while (strncasecmp(s, find, len) != 0); s--; } return ((char *)s);}/******************** Recv Poll Processing *********************/int pollnfds;struct pollfd pollfiles[SIPP_MAXFDS];call * pollcalls[SIPP_MAXFDS];#ifdef _USE_OPENSSLSSL * ssl_list[SIPP_MAXFDS];#endif/***************** Check of the message received ***************/bool sipMsgCheck (char *P_msg, int P_msgSize#ifdef __3PCC__ ,int P_pollSetIdx#endif ) { const char C_sipHeader[] = "SIP/2.0" ;#ifdef __3PCC__ if (pollfiles[P_pollSetIdx].fd == twinSippSocket) { return true ; } else {#endif // __3PCC__ if (strstr(P_msg, C_sipHeader) != NULL) { return true ; } return false ;#ifdef __3PCC__ }#endif // __3PCC__}void pollset_reset(){ pollnfds = 0; memset((void *)pollfiles,0,SIPP_MAXFDS*sizeof(struct pollfd)); pollfiles[pollnfds].fd = main_socket; pollfiles[pollnfds].events = POLLIN | POLLERR; pollfiles[pollnfds].revents = 0; pollcalls[pollnfds] = NULL; pollnfds++; if(tcp_multiplex) { /* Adds the TCP multiplex in the file descriptor array */ pollfiles[pollnfds].fd = tcp_multiplex; pollfiles[pollnfds].events = POLLIN | POLLERR; pollfiles[pollnfds].revents = 0; pollcalls[pollnfds] = NULL; pollnfds++; } #ifdef __3PCC__ if(twinSippSocket) { /* Adds the twinSippSocket */ pollfiles[pollnfds].fd = twinSippSocket; pollfiles[pollnfds].events = POLLIN | POLLERR; pollfiles[pollnfds].revents = 0; pollcalls[pollnfds] = NULL; pollnfds++; } if(localTwinSippSocket) { /* Adds the twinSippSocket */ pollfiles[pollnfds].fd = localTwinSippSocket; pollfiles[pollnfds].events = POLLIN | POLLERR; pollfiles[pollnfds].revents = 0; pollcalls[pollnfds] = NULL; pollnfds++; } #endif}int pollset_add(call * p_call, int sock){ // WARNING_P2("Adding socket %d at idx = %d", sock, pollnfds); pollfiles[pollnfds].fd = sock; pollfiles[pollnfds].events = POLLIN | POLLERR; pollfiles[pollnfds].revents = 0; pollcalls[pollnfds] = p_call; pollnfds++; return pollnfds - 1;}void pollset_remove(int idx){ if(idx >= pollnfds) { ERROR("Pollset error"); } /* Adds call sockets in the array */ if(pollnfds) { // WARNING_P2("Removing socket %d at idx = %d", pollfiles[idx].fd, idx); pollnfds--; pollfiles[idx] = pollfiles[pollnfds]; pollcalls[idx] = pollcalls[pollnfds]; if((pollcalls[idx]) && (pollcalls[idx] -> pollset_index)) { pollcalls[idx] -> pollset_index = idx; } } else { ERROR("Pollset underflow"); }}/************** Statistics display & User control *************/void print_stats_in_file(FILE * f, int last){ int index; static char temp_str[256]; int divisor;#define SIPP_ENDL "\r\n" /* Optional timestamp line for files only */ if(f != stdout) { time_t tim; time(&tim); fprintf(f, " Timestamp: %s" SIPP_ENDL, ctime(&tim)); } /* Header line with global parameters */ sprintf(temp_str, "%3.1f(%d ms)/%5.3fs", rate, duration, rate_period_s); if( toolMode == MODE_SERVER) { fprintf (f, " Port Total-time Total-calls Transport" SIPP_ENDL " %-5d %6d.%02d s %8d %s" SIPP_ENDL SIPP_ENDL, local_port, clock_tick / 1000, (clock_tick % 1000) / 10, total_calls, TRANSPORT_TO_STRING(transport)); } else { fprintf (f, " Call-rate(length) Port Total-time Total-calls Remote-host" SIPP_ENDL "%19s %-5d %6d.%02d s %8d %s:%d(%s)" SIPP_ENDL SIPP_ENDL, temp_str, local_port, clock_tick / 1000, (clock_tick % 1000) / 10, total_calls, remote_ip, remote_port, TRANSPORT_TO_STRING(transport)); } /* 1st line */ if(total_calls < stop_after) { sprintf(temp_str, "%d new calls during %d.%03d s period ", total_calls - last_report_calls, (clock_tick-last_report_time) / 1000, ((clock_tick-last_report_time) % 1000)); } else { sprintf(temp_str, "Call limit reached (-m %d), %d.%03d s period ", stop_after, (clock_tick-last_report_time) / 1000, ((clock_tick-last_report_time) % 1000)); } divisor = scheduling_loops; if(!divisor) { divisor = 1; } fprintf(f," %-38s %d ms scheduler resolution" SIPP_ENDL, temp_str, (clock_tick-last_report_time) / divisor); /* 2nd line */ if( toolMode == MODE_SERVER) { sprintf(temp_str, "%d concurrent calls", open_calls); } else { sprintf(temp_str, "%d concurrent calls (limit %d)", open_calls, open_calls_allowed); } fprintf(f," %-38s Peak was %d calls, after %d s" SIPP_ENDL, temp_str, open_calls_peak, open_calls_peak_time); /* 3rd line (optional) */ if( toolMode != MODE_SERVER) { sprintf(temp_str,"%d out-of-call msg (discarded)", nb_out_of_the_blue); fprintf(f," %-37s", temp_str); } if(compression) { fprintf(f," Comp resync: %d sent, %d recv" , resynch_send, resynch_recv); } if(compression || (toolMode != MODE_SERVER)) { fprintf(f,SIPP_ENDL); } /* 4th line , sockets and optional errors */ sprintf(temp_str,"%d open sockets", pollnfds); fprintf(f," %-38s", temp_str); if(nb_net_recv_errors || nb_net_send_errors || nb_net_cong) { fprintf(f," %d/%d/%d %s errors (send/recv/cong)" SIPP_ENDL, nb_net_send_errors, nb_net_recv_errors, nb_net_cong, TRANSPORT_TO_STRING(transport)); } else { fprintf(f,SIPP_ENDL); } /* 5th line, RTP echo statistics */ if (media_socket > 0) { sprintf(temp_str, "%d Total echo RTP pckts", rtp_pckts); // AComment: Fix for random coredump when using RTP echo if (clock_tick-last_report_time) { fprintf(f," %-38s %d.%03d last period RTP rate (kB/s)" SIPP_ENDL, temp_str, (rtp_bytes)/(clock_tick-last_report_time), (rtp_bytes)%(clock_tick-last_report_time)); } rtp_bytes = 0; } /* Scenario counters */ fprintf(f,SIPP_ENDL); if(!lose_packets) { fprintf(f," " "Messages Retrans Timeout Unexpected-Msg" SIPP_ENDL); } else { fprintf(f," " "Messages Retrans Timeout Unexp. Lost" SIPP_ENDL); } for(index = 0; index < scenario_len; index ++) { if(scenario[index] -> send_scheme) { char *dest, *src; int len; dest = temp_str; src = scenario[index] -> send_scheme; if( strncmp(src, "SIP/2.0", 7) == 0) { src += 8; } while((*src) && (*src != ' ') && (*src != '\t') && (*src != '\n')) { *dest++ = *src ++; } *dest = 0; if(toolMode == MODE_SERVER) { fprintf(f," <---------- %-10s %-8s",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -