📄 call.cpp
字号:
deleted += 1; if(comp_state) { comp_free(&comp_state); } if(count_in_stats) { CStat::instance()->computeStat(CStat::E_ADD_CALL_DURATION, clock_tick - start_time); } call_duration_sum += clock_tick - start_time; call_duration_nb++; #ifdef _USE_OPENSSL if ((toolMode == MODE_SERVER) && (multisocket)) { if (ssl_list[call_socket] != NULL) { if((pollset_index) && (pollfiles[pollset_index].fd == call_socket)) { SSL_set_shutdown(ssl_list[call_socket],SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); SSL_free(ssl_list[call_socket]); ssl_list[call_socket] = NULL ; pollset_remove(pollset_index); shutdown(call_socket, SHUT_RDWR); close(call_socket); } } } if ((toolMode != MODE_SERVER) && (multisocket)) { if(pollset_index ) { if (ssl_list[call_socket] != NULL) { // SSL_shutdown(ssl_list[call_socket]); SSL_set_shutdown(ssl_list[call_socket],SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); SSL_free(ssl_list[call_socket]); // BIO_free(m_bio); // m_bio = NULL ; m_ctx_ssl = NULL ; } } }#endif if (toolMode != MODE_SERVER) { // TRACE_MSG((s,"socket close %d at idx = %d\n", socket_close, pollset_index)); if(pollset_index) { if (socket_close) { pollset_remove(pollset_index); shutdown(call_socket, SHUT_RDWR); close(call_socket); } } } /* Deletion of the call variable */ for(int i=0; i<SCEN_VARIABLE_SIZE; i++) { if(M_callVariableTable[i] != NULL) { delete M_callVariableTable[i] ; M_callVariableTable[i] = NULL; } } if(id) { free(id); } if(last_recv_msg) { free(last_recv_msg); } if(last_send_msg) { free(last_send_msg); } if(dialog_route_set) { free(dialog_route_set); } if(next_req_url) { free(next_req_url); }#ifdef _USE_OPENSSL if(dialog_authentication) { free(dialog_authentication); }#endif call_established= false ;} void call::connect_socket_if_needed(){#ifdef _USE_OPENSSL int err; SSL *L_ssl_tcp_multiplex=NULL ;#endif if(call_socket) return; if(!multisocket) return; if(transport == T_UDP) { struct sockaddr_storage saddr; sipp_socklen_t len; int L_status = 0 ; // no new socket if(toolMode != MODE_CLIENT) return; char peripaddr[256]; if (!peripsocket) { if ((call_socket = new_socket(use_ipv6, SOCK_DGRAM, &L_status)) == -1) { ERROR_NO("Unable to get a UDP socket"); } } else { getIpFieldFromInputFile(peripfield, m_localLineNumber, peripaddr); map<string, int>::iterator i; i = map_perip_fd.find(peripaddr); if (i == map_perip_fd.end()) { // Socket does not exist if ((call_socket = new_socket(use_ipv6, SOCK_DGRAM, &L_status)) == -1) { ERROR_NO("Unable to get a UDP socket"); } else { map_perip_fd[peripaddr] = call_socket; } } else { // Socket exists already call_socket = i->second; } } if (L_status) { memset(&saddr, 0, sizeof(struct sockaddr_storage)); if (use_ipv6) { saddr.ss_family = AF_INET; } else { saddr.ss_family = AF_INET6; } if (peripsocket) { struct addrinfo * h ; struct addrinfo hints; memset((char*)&hints, 0, sizeof(hints)); hints.ai_flags = AI_PASSIVE; hints.ai_family = PF_UNSPEC; getaddrinfo(peripaddr, NULL, &hints, &h); memcpy(&saddr, h->ai_addr, SOCK_ADDR_SIZE( _RCAST(struct sockaddr_storage *,h->ai_addr))); if (use_ipv6) { (_RCAST(struct sockaddr_in6 *, &saddr))->sin6_port = htons(local_port); } else { (_RCAST(struct sockaddr_in *, &saddr))->sin_port = htons(local_port); } } if(bind(call_socket, (sockaddr *)(void *)&saddr, use_ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))) { ERROR_NO("Unable to bind UDP socket"); } } if (use_ipv6) { len = sizeof(struct sockaddr_in6); } else { len = sizeof(struct sockaddr_in); } getsockname(call_socket, (sockaddr *)(void *)&saddr, &len); if (use_ipv6) { call_port = ntohs((short)((_RCAST(struct sockaddr_in6 *, &saddr))->sin6_port)); } else { call_port = ntohs((short)((_RCAST(struct sockaddr_in *, &saddr))->sin_port)); } /* Asks to receive incoming messages */ if (L_status) { pollset_index = pollset_add(this, call_socket); } } else { /* TCP */ int L_status = 0 ; // no new socket if ((call_socket = new_socket(use_ipv6, SOCK_STREAM, &L_status)) == -1) { ERROR_NO("Unable to get a TCP socket"); } if (L_status) { sipp_customize_socket(call_socket); if(connect(call_socket, (struct sockaddr *)(void *)&remote_sockaddr, SOCK_ADDR_SIZE(&remote_sockaddr))) { if (reset_number > 0) { if(errno == EINVAL){ /* This occurs sometime on HPUX but is not a true INVAL */ WARNING("Unable to connect a TCP socket, remote peer error"); } else { WARNING("Unable to connect a TCP socket"); } start_calls = 1; } else { if(errno == EINVAL){ /* This occurs sometime on HPUX but is not a true INVAL */ ERROR("Unable to connect a TCP socket, remote peer error"); } else { ERROR_NO("Unable to connect a TCP socket"); } } } else {#ifdef _USE_OPENSSL if ( transport == T_TLS ) { m_ctx_ssl = sip_trp_ssl_ctx ; if (!(L_ssl_tcp_multiplex = SSL_new(m_ctx_ssl))){ ERROR("Unable to create SSL object : Problem with SSL_new() \n"); } // if ( (m_bio = BIO_new_socket(call_socket,BIO_NOCLOSE)) == NULL) { if ( (m_bio = BIO_new_socket(call_socket,BIO_CLOSE)) == NULL) { ERROR("Unable to create BIO object:Problem with BIO_new_socket()\n"); } // SSL_set_fd(L_ssl_tcp_multiplex, call_socket); SSL_set_bio(L_ssl_tcp_multiplex,m_bio,m_bio); // SSL_set_bio(L_ssl_tcp_multiplex,bio,bio); if ( (err = SSL_connect(L_ssl_tcp_multiplex)) < 0 ) { ERROR("Error in SSL connection \n"); } ssl_list[call_socket] = L_ssl_tcp_multiplex; }#endif /* Asks to receive incoming messages */ pollset_index = pollset_add(this, call_socket); } } }}bool lost(int percent){ static int inited = 0; if(!lose_packets) return false; if(!percent) return false; if(!inited) { srand((unsigned int) time(NULL)); inited = 1; } if((rand() % 100) < percent) { return true; } else { return false; }}int call::send_raw(char * msg, int index) { void ** state; int sock; int rc;#ifdef _USE_OPENSSL SSL *ssl; // extern SSL *ssl_list[];#endif if (useMessagef == 1) { struct timeval currentTime; GET_TIME (¤tTime); TRACE_MSG((s, "----------------------------------------------- %s\n" "%s message sent:\n\n%s\n", CStat::instance()->formatTime(¤tTime), TRANSPORT_TO_STRING(transport), msg)); } if((index!=-1) && (lost(scenario[index] -> lost))) { TRACE_MSG((s, "%s message voluntary lost (while sending).", TRANSPORT_TO_STRING(transport))); if(comp_state) { comp_free(&comp_state); } scenario[index] -> nb_lost++; return 0; } if(call_socket) { state = &comp_state; sock = call_socket; if (use_remote_sending_addr) { if (!call_remote_socket) { struct sockaddr_storage *L_dest = &remote_sending_sockaddr; if(transport == T_UDP) { if((call_remote_socket= socket(use_ipv6 ? AF_INET6 : AF_INET, SOCK_DGRAM, 0))== -1) { ERROR_NO("Unable to get a socket for rsa option"); } if(bind(call_remote_socket, (sockaddr *)(void *)L_dest, use_ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))) { ERROR_NO("Unable to bind UDP socket for rsa option"); } } else { if((call_remote_socket= socket(use_ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM, 0))== -1) { ERROR_NO("Unable to get a socket for rsa option"); } sipp_customize_socket(call_remote_socket); if(connect(call_remote_socket, (struct sockaddr *)(void *)L_dest, SOCK_ADDR_SIZE(&remote_sockaddr))) { if(errno == EINVAL){ /* This occurs sometime on HPUX but is not a true INVAL */ ERROR_P1("Unable to connect a %s socket for rsa option, remote peer error", TRANSPORT_TO_STRING(transport)); } else { ERROR_NO("Unable to connect a socket for rsa option"); } } } } sock=call_remote_socket ; }#ifdef _USE_OPENSSL ssl = ssl_list[sock]; // ssl = m_ssl;#endif } else { state = &monosocket_comp_state; if(transport == T_UDP) { sock = main_socket; } else { sock = tcp_multiplex;#ifdef _USE_OPENSSL ssl = ssl_tcp_multiplex;#endif } }#ifdef _USE_OPENSSL if ( transport == T_TLS ) { rc = send_message_tls(ssl, state, msg); } else {#endif rc = send_message(sock, state, msg);#ifdef _USE_OPENSSL }#endif if(rc == -1) return -1; if(rc < -1) { CStat::instance()->computeStat(CStat::E_CALL_FAILED); CStat::instance()->computeStat(CStat::E_FAILED_CANNOT_SEND_MSG); delete_call(id); } return rc; /* OK */}/* This method is used to send messages that are not *//* part of the XML scenario */int call::sendBuffer(char * msg) { int rc; /* call send_raw but with a special scenario index */ rc=send_raw(msg, -1); return rc;}char * call::compute_cseq(char * src){ char *dest; static char cseq[MAX_HEADER_LEN]; /* If we find a CSeq in incoming msg */ char * last_header = get_last_header("CSeq:"); if(last_header) { int i; /* Extract the integer value of the last CSeq */ last_header = strstr(last_header, ":"); last_header++; while(isspace(*last_header)) last_header++; sscanf(last_header,"%d", &i); /* Add 1 to the last CSeq value */ sprintf(cseq, "%s%d", "CSeq: ", (i+1)); } else { sprintf(cseq, "%s", "CSeq: 2"); } return cseq;}char * call::get_last_header(char * name){ static char last_header[MAX_HEADER_LEN * 10]; char * src, *dest, *ptr; char src_tmp[MAX_HEADER_LEN+1] = "\n"; if((!last_recv_msg) || (!strlen(last_recv_msg))) { return NULL; } src = last_recv_msg; dest = last_header; strncpy(src_tmp+1, name, MAX_HEADER_LEN); if (strlen(name) > MAX_HEADER_LEN) { ERROR_P2("call::get_last_header: Header to parse bigger than %d (%d)", MAX_HEADER_LEN, strlen(name)); } while(src = strcasestr2(src, src_tmp)) { src++; ptr = strchr(src, '\n'); /* Multiline headers always begin with a tab or a space * on the subsequent lines */ while((ptr) && ((*(ptr+1) == ' ' ) || (*(ptr+1) == '\t') )) { ptr = strchr(ptr + 1, '\n'); } if(ptr) { *ptr = 0; } // Add \r\n when several Via header are present (AgM) if (dest != last_header) { dest += sprintf(dest, "\r\n"); } dest += sprintf(dest, "%s", src);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -