📄 sipp.cpp
字号:
SSL_CTX_set_verify(sip_trp_ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, sip_tls_verify_callback); SSL_CTX_set_verify(sip_trp_ssl_ctx_client, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, sip_tls_verify_callback); } /* Selection Cipher suits - load the application specified ciphers */ SSL_CTX_set_default_passwd_cb_userdata(sip_trp_ssl_ctx, (void *)CALL_BACK_USER_DATA ); SSL_CTX_set_default_passwd_cb_userdata(sip_trp_ssl_ctx_client, (void *)CALL_BACK_USER_DATA ); SSL_CTX_set_default_passwd_cb( sip_trp_ssl_ctx, passwd_call_back_routine ); SSL_CTX_set_default_passwd_cb( sip_trp_ssl_ctx_client, passwd_call_back_routine ); if ( SSL_CTX_use_certificate_file(sip_trp_ssl_ctx, tls_cert_name, SSL_FILETYPE_PEM ) != 1 ) { ERROR("FI_init_ssl_context: SSL_CTX_use_certificate_file failed"); return SSL_INIT_ERROR; } if ( SSL_CTX_use_certificate_file(sip_trp_ssl_ctx_client, tls_cert_name, SSL_FILETYPE_PEM ) != 1 ) { ERROR("FI_init_ssl_context: SSL_CTX_use_certificate_file (client) failed"); return SSL_INIT_ERROR; } if ( SSL_CTX_use_PrivateKey_file(sip_trp_ssl_ctx, tls_key_name, SSL_FILETYPE_PEM ) != 1 ) { ERROR("FI_init_ssl_context: SSL_CTX_use_PrivateKey_file failed"); return SSL_INIT_ERROR; } if ( SSL_CTX_use_PrivateKey_file(sip_trp_ssl_ctx_client, tls_key_name, SSL_FILETYPE_PEM ) != 1 ) { ERROR("FI_init_ssl_context: SSL_CTX_use_PrivateKey_file (client) failed"); return SSL_INIT_ERROR; } return SSL_INIT_NORMAL;}int 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; if (!ip_addr) { ip_addr = (char *)malloc(1024*sizeof(char)); } if (getnameinfo(_RCAST(struct sockaddr *, addr), SOCK_ADDR_SIZE(addr), 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); *p2 = ']'; } /* 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; }}static unsigned char tolower_table[256];void init_tolower_table() { for (int i = 0; i < 256; i++) { tolower_table[i] = tolower(i); }}/* This is simpler than doing a regular tolower, because there are no branches. * We also inline it, so that we don't have function call overheads. * * An alternative to a table would be to do (c | 0x20), but that only works if * we are sure that we are searching for characters (or don't care if they are * not characters. */unsigned char inline mytolower(unsigned char c) { return tolower_table[c];}char * strcasestr2(char *s, char *find) { char c, sc; size_t len; if ((c = *find++) != 0) { c = mytolower((unsigned char)c); len = strlen(find); do { do { if ((sc = *s++) == 0) return (NULL); } while ((char)mytolower((unsigned char)sc) != c); } while (strncasecmp(s, find, len) != 0); s--; } return ((char *)s);}int get_decimal_from_hex(char hex) { if (isdigit(hex)) return hex - '0'; else return tolower(hex) - 'a' + 10;}/******************** Recv Poll Processing *********************/int pollnfds;struct pollfd pollfiles[SIPP_MAXFDS];call * pollcalls[SIPP_MAXFDS];/* These buffers lets us read past the end of the message, and then split it if * required. This eliminates the need for reading a message octet by octet and * performing a second read for the content length. */struct pollbuf { char *buf; int len; int offset; struct pollbuf *next;};struct pollbuf *pollbuffers[SIPP_MAXFDS];int outstanding_poll_msgs = 0;/* Polling management. */void free_pollbuf(struct pollbuf *pollbuf);map<string, int> map_perip_fd;#ifdef _USE_OPENSSLSSL * ssl_list[SIPP_MAXFDS];#endifchar * pending_msg[SIPP_MAXFDS];/***************** 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 *)pending_msg,0,SIPP_MAXFDS*sizeof(char *)); 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 // Add additional server sockets for socket per IP address if (peripsocket && toolMode == MODE_SERVER) { for (map<string, int>::iterator i = map_perip_fd.begin(); i != map_perip_fd.end(); i++) { // main_socket is already in pollfiles if (i->second != main_socket) { pollset_add(0, i->second); } } }}int pollset_find(int sock) { int idx; for(idx = 0; idx < pollnfds; idx++) { if (pollfiles[idx].fd == sock) { return idx; } } return -1;}int pollset_add(call * p_call, int sock){ pollfiles[pollnfds].fd = sock; pollfiles[pollnfds].events = POLLIN | POLLERR; pollfiles[pollnfds].revents = 0; pollcalls[pollnfds] = p_call; pollbuffers[pollnfds] = NULL; pollnfds++; /* int L_i ; TRACE_MSG((s,"Adding socket : %d at idx = %d\n", sock, (pollnfds-1))); for (L_i = 0; L_i < pollnfds ; L_i++) { TRACE_MSG((s,"Adding socket : L_i %d and socket = %d\n", L_i , pollfiles[L_i].fd)); } TRACE_MSG((s,"Adding socket :\n")); */ return pollnfds - 1;}void pollset_attached(call * p_call, int P_pollset_idx){ pollcalls[P_pollset_idx] = p_call;}void pollset_remove(int idx){ // TRACE_MSG((s,"remove socket : idx %d\n", idx)); if(idx >= pollnfds) { ERROR("Pollset error"); } /* int L_i ; TRACE_MSG((s,"remove socket : idx %d\n", idx)); for (L_i = 0; L_i < pollnfds ; L_i++) { TRACE_MSG((s,"remove socket : L_i %d and socket = %d\n", L_i , pollfiles[L_i].fd)); } TRACE_MSG((s,"remove socket :\n")); */ /* 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; } if (pollbuffers[idx]) { free_pollbuf(pollbuffers[idx]); } pollbuffers[idx] = pollbuffers[pollnfds]; } 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -