📄 call.cpp
字号:
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) && (toolMode == MODE_SERVER)) { 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_header_field_code(char *msg, char * name){ static char code[MAX_HEADER_LEN]; char * last_header; int i; last_header = NULL; i = 0; /* If we find the field in msg */ last_header = get_header_content(msg, name); if(last_header) { /* Extract the integer value of the field */ while(isspace(*last_header)) last_header++; sscanf(last_header,"%d", &i); sprintf(code, "%s %d", name, i); } return code;}char * call::get_last_header(char * name){ static char last_header[MAX_HEADER_LEN * 10]; char * src, *dest, *ptr; /* Gcc will zero extend this using memset, if we do a default initializer. We don't need this behavior, because we can just use sprintf. */ char src_tmp[MAX_HEADER_LEN+1]; if((!last_recv_msg) || (!strlen(last_recv_msg))) { return NULL; } src = last_recv_msg; dest = last_header; snprintf(src_tmp, MAX_HEADER_LEN, "\n%s", name); /* Ideally this check should be moved to the XML parser so that it is not * along a critical path. We could also handle lowercasing there. */ 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); if(ptr) { *ptr = '\n'; } src++; } if(dest == last_header) { return NULL; } *(dest--) = 0; /* Remove trailing whitespaces, tabs, and CRs */ while ((dest > last_header) && ((*dest == ' ') || (*dest == '\r')|| (*dest == '\t'))) { *(dest--) = 0; } /* remove enclosed CRs in multilines */ /* don't remove enclosed CRs for multiple headers (e.g. Via) (Rhys) */ while((ptr = strstr(last_header, "\r\n")) != NULL && ( *(ptr + 2) == ' ' || *(ptr + 2) == '\r' || *(ptr + 2) == '\t') ) { /* Use strlen(ptr) to include trailing zero */ memmove(ptr, ptr+1, strlen(ptr)); } /* Remove illegal double CR characters */ while((ptr = strstr(last_header, "\r\r")) != NULL) { memmove(ptr, ptr+1, strlen(ptr)); } /* Remove illegal double Newline characters */ while((ptr = strstr(last_header, "\n\n")) != NULL) { memmove(ptr, ptr+1, strlen(ptr)); } return last_header;}char * call::get_header_content(char* message, char * name){ /* non reentrant. consider accepting char buffer as param */ static char last_header[MAX_HEADER_LEN * 10]; char * src, *dest, *start, *ptr; /* returns empty string in case of error */ last_header[0] = '\0'; if((!message) || (!strlen(message))) { return last_header; } src = message; dest = last_header; /* for safety's sake */ if (NULL == name || NULL == strrchr(name, ':')) { return last_header; } while(src = strcasestr2(src, name)) { /* just want the header's content */ src += strlen(name); 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 "," when several headers are present if (dest != last_header) { dest += sprintf(dest, ","); } dest += sprintf(dest, "%s", src); if(ptr) { *ptr = '\n'; } src++; } if(dest == last_header) { return last_header; } *(dest--) = 0; /* Remove trailing whitespaces, tabs, and CRs */ while ((dest > last_header) && ((*dest == ' ') || (*dest == '\r')|| (*dest == '\t'))) { *(dest--) = 0; } /* Remove leading whitespaces */ for (start = last_header; *start == ' '; start++); /* remove enclosed CRs in multilines */ while(ptr = strchr(start, '\r')) { /* Use strlen(ptr) to include trailing zero */ memmove(ptr, ptr+1, strlen(ptr)); } return start;}char * call::send_scene(int index, int *send_status){ static char msg_buffer[SIPP_MAX_MSG_SIZE];#define MAX_MSG_NAME_SIZE 30 static char msg_name[MAX_MSG_NAME_SIZE]; char *L_ptr1 ; char *L_ptr2 ; /* Socket port must be known before string substitution */ connect_socket_if_needed(); if(scenario[index] -> send_scheme) { char * dest; dest = createSendingMessage(scenario[index] -> send_scheme, index); strcpy(msg_buffer, dest); if (dest) { L_ptr1=msg_name ; L_ptr2=msg_buffer ; while ((*L_ptr2 != ' ') && (*L_ptr2 != '\n') && (*L_ptr2 != '\t')) { *L_ptr1 = *L_ptr2; L_ptr1 ++; L_ptr2 ++; } *L_ptr1 = '\0' ; } if (strcmp(msg_name,"ACK") == 0) { call_established = true ; ack_is_pending = false ; } if(send_status) { *send_status = send_raw(msg_buffer, index); } else { send_raw(msg_buffer, index); } } else { ERROR("Unsupported 'send' message in scenario"); } return msg_buffer;}void call::do_bookkeeping(int index) { /* If this message increments a counter, do it now. */ if(int counter = scenario[index] -> counter) { CStat::instance()->computeStat(CStat::E_ADD_GENERIC_COUNTER, 1, counter - 1); } /* If this message can be used to compute RTD, do it now */ if(int rtd = scenario[index] -> start_rtd) { start_time_rtd[rtd - 1] = clock_tick; } if(int rtd = scenario[index] -> stop_rtd) { if (!rtd_done[rtd - 1]) { int start = start_time_rtd[rtd - 1]; struct timeval L_currentTime; double L_stop_time; if(dumpInRtt) { GET_TIME (&L_currentTime); L_stop_time = (double)L_currentTime.tv_sec*1000.0 + (double)(L_currentTime.tv_usec)/(double)1000.0 ; CStat::instance()->computeRtt(start, L_stop_time) ; } CStat::instance()->computeStat(CStat::E_ADD_RESPONSE_TIME_DURATION, clock_tick - start, rtd - 1); rtd_done[rtd - 1] = true; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -