📄 call.cpp
字号:
begin = strstr(msg, pattern); if (!begin) { /* Can't find what we're looking at -> return no address */ return 0; } begin += sizeof("c=IN IP6 ") - 1; end = strstr(begin, "\r\n"); if (!end) return 0; strncpy(ip, begin, end - begin); if (!inet_pton(AF_INET6, ip, &addr)) { return 0; } return 1;}/* * Look for "m=audio " pattern in the message and extract the following value * which should be port number */uint16_t get_remote_audio_port_media(char *msg){ char pattern[] = "m=audio "; char *begin, *end; char number[5]; begin = strstr(msg, pattern); if (!begin) ERROR("get_remote_audio_port_media: No audio media port found in SDP"); begin += sizeof("m=audio ") - 1; end = strstr(begin, "\r\n"); if (!end) ERROR("get_remote_audio_port_media: no CRLF found"); memset(number, 0, 5); strncpy(number, begin, end - begin); return atoi(number);}/* * Look for "m=video " pattern in the message and extract the following value * which should be port number */uint16_t get_remote_video_port_media(char *msg){ char pattern[] = "m=video "; char *begin, *end; char number[5]; begin = strstr(msg, pattern); if (!begin) { /* m=video not found */ return 0; } begin += sizeof("m=video ") - 1; end = strstr(begin, "\r\n"); if (!end) ERROR("get_remote_video_port_media: no CRLF found"); memset(number, 0, 5); strncpy(number, begin, end - begin); return atoi(number);}/* * IPv{4,6} compliant */void call::get_remote_media_addr(char *msg) { uint16_t video_port; if (media_ip_is_ipv6) { struct in6_addr ip_media; if (get_remote_ipv6_media(msg, ip_media)) { (_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_flowinfo = 0; (_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_scope_id = 0; (_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_family = AF_INET6; (_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_port = get_remote_audio_port_media(msg); (_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_addr = ip_media; video_port = get_remote_video_port_media(msg); if (video_port) { /* We have video in the SDP: set the to_video addr */ (_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_flowinfo = 0; (_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_scope_id = 0; (_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_family = AF_INET6; (_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_port = video_port; (_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_addr = ip_media; } hasMediaInformation = 1; } } else { uint32_t ip_media; ip_media = get_remote_ip_media(msg); if (ip_media != INADDR_NONE) { (_RCAST(struct sockaddr_in *, &(play_args_a.to)))->sin_family = AF_INET; (_RCAST(struct sockaddr_in *, &(play_args_a.to)))->sin_port = get_remote_audio_port_media(msg); (_RCAST(struct sockaddr_in *, &(play_args_a.to)))->sin_addr.s_addr = ip_media; video_port = get_remote_video_port_media(msg); if (video_port) { /* We have video in the SDP: set the to_video addr */ (_RCAST(struct sockaddr_in *, &(play_args_v.to)))->sin_family = AF_INET; (_RCAST(struct sockaddr_in *, &(play_args_v.to)))->sin_port = video_port; (_RCAST(struct sockaddr_in *, &(play_args_v.to)))->sin_addr.s_addr = ip_media; } hasMediaInformation = 1; } }}#endif/******* Very simple hash for retransmission detection *******/unsigned long hash(char * msg) { unsigned long hash = 0; int c; while (c = *msg++) hash = c + (hash << 6) + (hash << 16) - hash; return hash;}/******************* Call class implementation ****************/call::InputFileUsage call::m_usage = call::InputFileSequentialOrder;int call::m_counter = 0;call::call(char * p_id, bool ipv6) : use_ipv6(ipv6){ memset(this, 0, sizeof(call)); id = strdup(p_id); start_time = clock_tick; call_established=false ; count_in_stats=true ; ack_is_pending=false ; last_recv_msg = NULL; cseq = base_cseq; nb_last_delay = 0; tdm_map_number = 0; #ifdef _USE_OPENSSL m_ctx_ssl = NULL ; m_bio = NULL ;#endif pollset_index = 0 ; poll_flag_write = false ; call_remote_socket = 0; // initialising the CallVariable with the Scenario variable bool test_var=false; int i,j; for(i=0; i<SCEN_VARIABLE_SIZE; i++) { for (j=0; j<SCEN_MAX_MESSAGES; j++) { if(scenVariableTable[i][j] != NULL) { test_var=true; break; } } if (test_var) { M_callVariableTable[i] = new CCallVariable(); if (M_callVariableTable[i] == NULL) { ERROR ("call variable allocation failed"); } } else { M_callVariableTable[i] = NULL; } } // If not updated by a message we use the start time // information to compute rtd information for (i = 0; i < MAX_RTD_INFO_LENGTH; i++) { start_time_rtd[i] = clock_tick; rtd_done[i] = false; } // by default, last action result is NO_ERROR last_action_result = call::E_AR_NO_ERROR; if (InputFileRandomOrder == m_usage) { m_localLineNumber = rand() % numLinesInFile; } else { m_localLineNumber = m_counter++; if (m_counter >= numLinesInFile) { m_counter = 0; } }#ifdef PCAPPLAY memset(&(play_args_a.to), 0, sizeof(struct sockaddr_storage)); memset(&(play_args_v.to), 0, sizeof(struct sockaddr_storage)); memset(&(play_args_a.from), 0, sizeof(struct sockaddr_storage)); memset(&(play_args_v.from), 0, sizeof(struct sockaddr_storage)); hasMediaInformation = 0; media_thread = 0;#endif peer_tag = NULL; recv_timeout = 0;}call::~call(){ 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); }#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); } } } else { if (call_remote_socket) { close(call_remote_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(peer_tag) { free(peer_tag); } 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)); memcpy(&saddr, local_addr_storage->ai_addr, SOCK_ADDR_SIZE( _RCAST(struct sockaddr_storage *,local_addr_storage->ai_addr))); 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 struct sockaddr_storage *L_dest = &remote_sockaddr; 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 (use_remote_sending_addr) { L_dest = &remote_sending_sockaddr; } if(connect(call_socket, (struct sockaddr *)(void *)L_dest, 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))){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -