From: <obo...@us...> - 2007-01-23 17:31:00
|
Revision: 152 http://svn.sourceforge.net/sipp/?rev=152&view=rev Author: oboulkroune Date: 2007-01-23 09:30:51 -0800 (Tue, 23 Jan 2007) Log Message: ----------- Enh: 3pcc extended mode added Modified Paths: -------------- sipp/trunk/call.cpp sipp/trunk/call.hpp sipp/trunk/scenario.cpp sipp/trunk/scenario.hpp sipp/trunk/sipp.cpp sipp/trunk/sipp.hpp Modified: sipp/trunk/call.cpp =================================================================== --- sipp/trunk/call.cpp 2007-01-23 17:17:19 UTC (rev 151) +++ sipp/trunk/call.cpp 2007-01-23 17:30:51 UTC (rev 152) @@ -1812,6 +1812,10 @@ delimitor[0]=27; delimitor[1]=0; + /* 3pcc extended mode */ + char * peer_dest; + int * peer_socket; + if(scenario[index] -> M_sendCmdData) { // WARNING_P1("---PREPARING_TWIN_CMD---%s---", scenario[index] -> M_sendCmdData); dest = createSendingMessage(scenario[index] -> M_sendCmdData, -1); @@ -1820,10 +1824,21 @@ int rc; + /* 3pcc extended mode */ + peer_dest = scenario[index]->peer_dest; + if(peer_dest){ + peer_socket = get_peer_socket(peer_dest); + rc = send(* peer_socket, + dest, + strlen(dest), + 0); + + }else { rc = send(twinSippSocket, dest, strlen(dest), 0); + } if(rc < 0) { CStat::instance()->computeStat(CStat::E_CALL_FAILED); CStat::instance()->computeStat(CStat::E_FAILED_CMD_NOT_SENT); @@ -2362,23 +2377,32 @@ /* The received message is different from the expected one */ return rejectCall(); } else { + if(extendedTwinSippMode){ // 3pcc extended mode + if(check_peer_src(msg, search_index)){ + found = true; + break; + } else{ + WARNING_P1("Unexpected sender for the received peer message \n%s\n", msg); + return rejectCall(); + } + } + else { found = true; break; } } + } if (found) { scenario[search_index]->M_nbCmdRecv ++; // variable treatment - // WARNING_P1("---RECVD_TWIN_CMD---%s---", msg); // Remove \r, \n at the end of a received command // (necessary for transport, to be removed for usage) while ( (msg[strlen(msg)-1] == '\n') && (msg[strlen(msg)-2] == '\r') ) { msg[strlen(msg)-2] = 0; } - // WARNING_P1("---RECVD_TWIN_CMD AFTER---%s---", msg); actionResult = executeAction(msg, search_index); if(actionResult != call::E_AR_NO_ERROR) { @@ -2431,6 +2455,35 @@ *L_ptr2 = L_backup; return (false); } + +bool call::check_peer_src(char * msg, int search_index) +{ + char * L_ptr1, * L_ptr2, L_backup ; + + L_ptr1 = strstr(msg, "From:"); + if (!L_ptr1) {return (false);} + L_ptr1 += 5 ; + while((*L_ptr1 == ' ') || (*L_ptr1 == '\t')) { L_ptr1++; } + if (!(*L_ptr1)) {return (false);} + L_ptr2 = L_ptr1; + while((*L_ptr2) && + (*L_ptr2 != ' ') && + (*L_ptr2 != '\t') && + (*L_ptr2 != '\r') && + (*L_ptr2 != '\n')) { + L_ptr2 ++; + } + if(!*L_ptr2) { return (false); } + L_backup = *L_ptr2; + *L_ptr2 = 0; + if (strcmp(L_ptr1, scenario[search_index] -> peer_src) == 0) { + *L_ptr2 = L_backup; + return(true); + } + + *L_ptr2 = L_backup; + return (false); +} #endif Modified: sipp/trunk/call.hpp =================================================================== --- sipp/trunk/call.hpp 2007-01-23 17:17:19 UTC (rev 151) +++ sipp/trunk/call.hpp 2007-01-23 17:30:51 UTC (rev 152) @@ -231,6 +231,10 @@ // received from the twin socket // used for example to cancel the call // of the third party + bool check_peer_src(char* msg, + int search_index); // 3pcc extended mode:check if + // the twin message received + // comes from the expected sender int sendBuffer(char *buf); // send a message out of a scenario // execution int checkAutomaticResponseMode(char * P_recv); Modified: sipp/trunk/scenario.cpp =================================================================== --- sipp/trunk/scenario.cpp 2007-01-23 17:17:19 UTC (rev 151) +++ sipp/trunk/scenario.cpp 2007-01-23 17:30:51 UTC (rev 152) @@ -66,6 +66,10 @@ next = 0; on_timeout = 0; +/* 3pcc extended mode */ + peer_dest = NULL; + peer_src = NULL; + /* Statistics */ nb_sent = 0; nb_recv = 0; @@ -108,6 +112,14 @@ free(regexp_compile); regexp_compile = NULL; + if(peer_dest != NULL) + free (peer_dest); + peer_dest = NULL; + + if(peer_src != NULL) + delete (peer_src); + peer_src = NULL; + #ifdef __3PCC__ if(M_sendCmdData != NULL) delete(M_sendCmdData); @@ -354,7 +366,7 @@ int L_content_length = 0 ; unsigned int recv_count = 0; unsigned int recv_opt_count = 0; - + char * peer; memset (method_list, 0, sizeof (method_list)); if(filename) { @@ -806,6 +818,11 @@ } } scenario[scenario_len]->M_type = MSG_TYPE_RECVCMD; + + /* 3pcc extended mode */ + if(ptr = xp_get_value((char *)"src")) { + scenario[scenario_len] ->peer_src = strdup(ptr) ; + } getActionForThisMessage(); } else if(!strcmp(elem, "sendCmd")) { @@ -819,6 +836,24 @@ } scenario[scenario_len]->M_type = MSG_TYPE_SENDCMD; /* Sent messages descriptions */ + + /* 3pcc extended mode */ + if(ptr = xp_get_value((char *)"dest")) { + peer = strdup(ptr) ; + scenario[scenario_len] ->peer_dest = peer ; + peer_map::iterator peer_it; + peer_it = peers.find(peer_map::key_type(peer)); + if(peer_it == peers.end()) /* the peer (slave or master) + has not been added in the map + (first occurence in the scenario) */ + { + T_peer_infos infos; + infos.peer_socket = 0; + strcpy(infos.peer_host, get_peer_addr(peer)); + peers[std::string(peer)] = infos; + } + } + if(ptr = xp_get_cdata()) { char * msg; @@ -900,9 +935,34 @@ } // end while } +/* 3pcc extended mode: + get the correspondances between + slave and master names and their + addresses */ +void parse_slave_cfg() +{ + FILE * f; + char line[MAX_PEER_SIZE]; + char * temp_peer; + char * peer_host; + + f = fopen(slave_cfg_file, "r"); + if(f){ + while (fgets(line, MAX_PEER_SIZE, f) != NULL) + { + temp_peer = strtok(line, ";"); + peer_host = (char *) malloc(MAX_PEER_SIZE); + strcpy(peer_host, strtok(NULL, ";")); + peer_addrs[std::string(temp_peer)] = peer_host; + } + }else{ + ERROR_P1("Can not open slave_cfg file %s\n", slave_cfg_file); + } +} + // Determine in which mode the sipp tool has been -// launched (client, server, 3pcc client, 3pcc server) +// launched (client, server, 3pcc client, 3pcc server, 3pcc extended master or slave) void computeSippMode() { bool isRecvCmdFound = false; @@ -938,13 +998,24 @@ * If it is a server already, then start it in * 3PCC A passive mode */ + if(twinSippMode){ toolMode = MODE_3PCC_A_PASSIVE; + }else if (extendedTwinSippMode){ + toolMode = MODE_MASTER_PASSIVE; + } } else { + if(twinSippMode){ toolMode = MODE_3PCC_CONTROLLER_A; + }else if (extendedTwinSippMode){ + toolMode = MODE_MASTER; + } } - if(!twinSippMode) + if((toolMode == MODE_MASTER_PASSIVE || toolMode == MODE_MASTER) && !master_name){ + ERROR("Inconsistency between command line and scenario: master scenario but -master option not set\n"); + } + if(!twinSippMode && !extendedTwinSippMode) ERROR("sendCmd message found in scenario but no twin sipp" - " address has been passed! Use -3pcc option.\n"); + " address has been passed! Use -3pcc option or 3pcc extended mode.\n"); return; } isFirstMessageFound = false; @@ -954,8 +1025,17 @@ isRecvCmdFound = true; if(!isSendCmdFound) { + if(twinSippMode){ toolMode = MODE_3PCC_CONTROLLER_B; - if(!twinSippMode) + } else if(extendedTwinSippMode){ + toolMode = MODE_SLAVE; + if(!slave_number) { + ERROR("Inconsistency between command line and scenario: slave scenario but -slave option not set\n"); + }else{ + toolMode = MODE_SLAVE; + } + } + if(!twinSippMode && !extendedTwinSippMode) ERROR("sendCmd message found in scenario but no " "twin sipp address has been passed! Use " "-3pcc option\n"); Modified: sipp/trunk/scenario.hpp =================================================================== --- sipp/trunk/scenario.hpp 2007-01-23 17:17:19 UTC (rev 151) +++ sipp/trunk/scenario.hpp 2007-01-23 17:30:51 UTC (rev 152) @@ -24,6 +24,8 @@ #ifndef __SCENARIO__ #define __SCENARIO__ +#include <map> +#include <sys/socket.h> #include "actions.hpp" #include "variables.hpp" @@ -55,6 +57,11 @@ #define MODE_3PCC_CONTROLLER_A 2 #define MODE_3PCC_CONTROLLER_B 3 #define MODE_3PCC_A_PASSIVE 4 + +/* 3pcc extended mode*/ +#define MODE_MASTER 5 +#define MODE_MASTER_PASSIVE 6 +#define MODE_SLAVE 7 #endif #define OPTIONAL_TRUE 1 @@ -98,6 +105,12 @@ char * send_scheme; unsigned int retrans_delay; + /* 3pcc extended mode: if this is a sendCmd */ + char * peer_dest; + + /* 3pcc extended mode: if this is a recvCmd */ + char * peer_src; + /* If this is a recv */ unsigned int recv_response; char * recv_request; @@ -156,6 +169,8 @@ extern int scenario_len; extern char scenario_name[255]; extern int toolMode; + + extern unsigned long scenario_duration; /* include -d option if used */ extern message::ContentLengthFlag content_length_flag; @@ -163,6 +178,9 @@ void load_scenario(char * filename, int deflt); +/* 3pcc extended mode */ +void parse_slave_cfg(); + void computeSippMode(); void getActionForThisMessage(); int createIntegerTable(char * P_listeStr, Modified: sipp/trunk/sipp.cpp =================================================================== --- sipp/trunk/sipp.cpp 2007-01-23 17:17:19 UTC (rev 151) +++ sipp/trunk/sipp.cpp 2007-01-23 17:30:51 UTC (rev 152) @@ -68,30 +68,31 @@ void *data; }; -#define SIPP_OPTION_HELP 1 -#define SIPP_OPTION_INT 2 -#define SIPP_OPTION_SETFLAG 3 -#define SIPP_OPTION_UNSETFLAG 4 -#define SIPP_OPTION_STRING 5 -#define SIPP_OPTION_ARGI 6 -#define SIPP_OPTION_TIME_SEC 7 -#define SIPP_OPTION_FLOAT 8 -#define SIPP_OPTION_BOOL 10 -#define SIPP_OPTION_VERSION 11 -#define SIPP_OPTION_TRANSPORT 12 -#define SIPP_OPTION_NEED_SSL 13 -#define SIPP_OPTION_IP 14 -#define SIPP_OPTION_MAX_SOCKET 15 -#define SIPP_OPTION_CSEQ 16 -#define SIPP_OPTION_SCENARIO 17 -#define SIPP_OPTION_RSA 18 -#define SIPP_OPTION_LIMIT 19 -#define SIPP_OPTION_USERS 20 -#define SIPP_OPTION_KEY 21 -#define SIPP_OPTION_3PCC 22 -#define SIPP_OPTION_TDMMAP 23 -#define SIPP_OPTION_TIME_MS 24 - +#define SIPP_OPTION_HELP 1 +#define SIPP_OPTION_INT 2 +#define SIPP_OPTION_SETFLAG 3 +#define SIPP_OPTION_UNSETFLAG 4 +#define SIPP_OPTION_STRING 5 +#define SIPP_OPTION_ARGI 6 +#define SIPP_OPTION_TIME_SEC 7 +#define SIPP_OPTION_FLOAT 8 +#define SIPP_OPTION_BOOL 10 +#define SIPP_OPTION_VERSION 11 +#define SIPP_OPTION_TRANSPORT 12 +#define SIPP_OPTION_NEED_SSL 13 +#define SIPP_OPTION_IP 14 +#define SIPP_OPTION_MAX_SOCKET 15 +#define SIPP_OPTION_CSEQ 16 +#define SIPP_OPTION_SCENARIO 17 +#define SIPP_OPTION_RSA 18 +#define SIPP_OPTION_LIMIT 19 +#define SIPP_OPTION_USERS 20 +#define SIPP_OPTION_KEY 21 +#define SIPP_OPTION_3PCC 22 +#define SIPP_OPTION_TDMMAP 23 +#define SIPP_OPTION_TIME_MS 24 +#define SIPP_OPTION_SLAVE_CFG 25 +#define SIPP_OPTION_3PCC_EXTENDED 26 /* Put Each option, its help text, and type in this table. */ struct sipp_option options_table[] = { {"v", "Display version and copyright information.", SIPP_OPTION_VERSION, NULL}, @@ -132,6 +133,7 @@ {"m", "Stop the test and exit when 'calls' calls are processed", SIPP_OPTION_INT, &stop_after}, {"mi", "Set the local media IP address", SIPP_OPTION_IP, media_ip}, + {"master","3pcc extended mode: indicates the master number", SIPP_OPTION_3PCC_EXTENDED, &master_name}, {"max_recv_loops", "Set the maximum number of messages received read per cycle. Increase this value for high traffic level. The default value is 1000.", SIPP_OPTION_INT, &max_recv_loops}, {"max_reconnect", "Set the the maximum number of reconnection.", SIPP_OPTION_INT, &reset_number}, {"max_retrans", "Maximum number of UDP retransmissions before call ends on timeout. Default is 5 for INVITE transactions and 7 for others.", SIPP_OPTION_INT, &max_udp_retrans}, @@ -182,6 +184,8 @@ {"s", "Set the username part of the resquest URI. Default is 'service'.", SIPP_OPTION_STRING, &service}, {"sd", "Dumps a default scenario (embeded in the sipp executable)", SIPP_OPTION_SCENARIO, NULL}, {"sf", "Loads an alternate xml scenario file. To learn more about XML scenario syntax, use the -sd option to dump embedded scenarios. They contain all the necessary help.", SIPP_OPTION_SCENARIO, NULL}, + {"slave", "3pcc extended mode: indicates the slave number", SIPP_OPTION_3PCC_EXTENDED, &slave_number}, + {"slave_cfg", "3pcc extended mode: indicates the file where the master and slave addresses are stored", SIPP_OPTION_SLAVE_CFG, NULL}, {"sn", "Use a default scenario (embedded in the sipp executable). If this option is omitted, the Standard SipStone UAC scenario is loaded.\n" "Available values in this version:\n\n" "- 'uac' : Standard SipStone UAC (default).\n" @@ -645,9 +649,10 @@ const char C_sipHeader[] = "SIP/2.0" ; #ifdef __3PCC__ - if (pollfiles[P_pollSetIdx].fd == twinSippSocket) { - return true ; - } else { + if (pollfiles[P_pollSetIdx].fd == twinSippSocket || + pollfiles[P_pollSetIdx].fd == localTwinSippSocket || + is_a_peer_socket(pollfiles[P_pollSetIdx].fd) || + is_a_local_socket(pollfiles[P_pollSetIdx].fd)) return true ; #endif // __3PCC__ if (strstr(P_msg, C_sipHeader) != NULL) { @@ -656,9 +661,6 @@ return false ; -#ifdef __3PCC__ - } -#endif // __3PCC__ } void pollset_reset() @@ -701,6 +703,18 @@ pollcalls[pollnfds] = NULL; pollnfds++; } + +/* 3pcc extended mode: adds the local sockets (used for reading the messages from + others twin sipp instances, master or slaves) */ + for (int i = 0; i< local_nb ; i++){ + pollfiles[pollnfds].fd = local_sockets[i]; + pollfiles[pollnfds].events = POLLIN | POLLERR; + pollfiles[pollnfds].revents = 0; + pollcalls[pollnfds] = NULL; + pollnfds++; + } + + #endif @@ -748,7 +762,6 @@ } TRACE_MSG((s,"Adding socket :\n")); */ - return pollnfds - 1; } @@ -776,7 +789,6 @@ /* 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]; @@ -1159,6 +1171,15 @@ case MODE_3PCC_CONTROLLER_A : fprintf(f,"----------------------- 3PCC Mode - Controller A side -------------------------" SIPP_ENDL); break; + case MODE_MASTER : + fprintf(f,"-----------------------3PCC extended mode - Master side -------------------------" SIPP_ENDL); + break; + case MODE_MASTER_PASSIVE : + fprintf(f,"------------------ 3PCC extended mode - Master side (passive) --------------------" SIPP_ENDL); + break; + case MODE_SLAVE : + fprintf(f,"----------------------- 3PCC extended mode - Slave side -------------------------" SIPP_ENDL); + break; #endif case MODE_CLIENT : default: @@ -1834,6 +1855,15 @@ return; } + /* 3pcc extended mode */ + if (extendedTwinSippMode) { + close(localTwinSippSocket); + close_peer_sockets(); + close_local_sockets(); + free_peer_addr_map(); + ERROR("Master has ended -> exiting"); + } + #ifdef __3PCC__ if (toolMode == MODE_3PCC_CONTROLLER_B) { /* In 3PCC controller B mode, twin socket is closed at peer closing. @@ -1854,7 +1884,7 @@ trace_id, sock); #ifdef __3PCC__ - if(sock == twinSippSocket || sock == localTwinSippSocket) { + if(sock == twinSippSocket || sock == localTwinSippSocket ) { int L_poll_idx = 0 ; quitting = 1; for((L_poll_idx) = 0; @@ -2337,19 +2367,31 @@ pollfiles[(*poll_idx)].revents = 0; #ifdef __3PCC__ - if(s == localTwinSippSocket) - { + if(s == localTwinSippSocket){ sipp_socklen_t len = sizeof(twinSipp_sockaddr); + if(toolMode == MODE_3PCC_CONTROLLER_B){ twinSippSocket = accept(s, (sockaddr *)(void *)&twinSipp_sockaddr, &len); - pollset_add(0, twinSippSocket); + }else{ + /*3pcc extended mode: open a local socket + which will be used for reading the infos sent by this remote + twin sipp instance (slave or master) */ + + int localSocket = accept(s, + (sockaddr *)(void *)&twinSipp_sockaddr, + &len); + pollset_add(0, localSocket); + local_sockets[local_nb] = localSocket; + local_nb++; + if(!peers_connected){ + connect_to_all_peers(); + } + } return(-2); - } - else if (s == twinSippSocket) - { + } else if (s == twinSippSocket || is_a_local_socket(s)){ size = recv_tcp_message(s, *poll_idx, buffer, @@ -2358,12 +2400,11 @@ E_ALTER_YES); if(size >= 0) { buffer[size] = 0; - } - else + }else { buffer[0] = 0; + } return size; - } - else + }else { #endif @@ -2429,6 +2470,7 @@ E_ALTER_YES); } else { #endif + size = recv_tcp_message(s, *poll_idx, buffer, @@ -2587,10 +2629,8 @@ ,pollset_index #endif // __3PCC__ ) == true) { - call_id = get_call_id(msg); call_ptr = get_call(call_id); - if(!call_ptr) { if(toolMode == MODE_SERVER) @@ -2626,7 +2666,8 @@ } } #ifdef __3PCC__ - else if(toolMode == MODE_3PCC_CONTROLLER_B || toolMode == MODE_3PCC_A_PASSIVE) + else if(toolMode == MODE_3PCC_CONTROLLER_B || toolMode == MODE_3PCC_A_PASSIVE + || toolMode == MODE_MASTER_PASSIVE || toolMode == MODE_SLAVE) { // Adding a new OUTGOING call ! CStat::instance()->computeStat @@ -2642,8 +2683,10 @@ (pollfiles[pollset_index].fd != main_socket) && (pollfiles[pollset_index].fd != tcp_multiplex) && (pollfiles[pollset_index].fd != localTwinSippSocket) && - (pollfiles[pollset_index].fd != twinSippSocket)) { + (pollfiles[pollset_index].fd != twinSippSocket) && + (!is_a_local_socket(pollfiles[pollset_index].fd))) { call_ptr -> call_socket = pollfiles[pollset_index].fd; + } } } @@ -2683,7 +2726,8 @@ { #ifdef __3PCC__ if( (pollfiles[pollset_index].fd == localTwinSippSocket) || - (pollfiles[pollset_index].fd == twinSippSocket)) + (pollfiles[pollset_index].fd == twinSippSocket) || + (is_a_local_socket(pollfiles[pollset_index].fd))) { if(!call_ptr -> process_twinSippCom(msg)) { @@ -2803,6 +2847,7 @@ if( (toolMode == MODE_CLIENT) #ifdef __3PCC__ || (toolMode == MODE_3PCC_CONTROLLER_A) + || (toolMode == MODE_MASTER) #endif ) { @@ -3405,6 +3450,7 @@ int err; int L_maxSocketPresent = 0; unsigned int generic_count = 0; + bool slave_masterSet = false; generic[0] = NULL; @@ -3413,7 +3459,6 @@ help(); exit(EXIT_OTHER); } - /* Ignore the SIGPIPE signal */ { struct sigaction action_pipe; @@ -3453,7 +3498,6 @@ for(argi = 1; argi < argc; argi++) { struct sipp_option *option = find_option(argv[argi]); - if (!option) { if((argv[argi])[0] != '-') { strcpy(remote_host, argv[argi]); @@ -3634,6 +3678,12 @@ break; case SIPP_OPTION_3PCC: #ifdef __3PCC__ + if(slave_masterSet){ + ERROR("-3PCC option is not compatible with -master and -slave options\n"); + } + if(extendedTwinSippMode){ + ERROR("-3pcc and -slave_cfg options are not compatible\n"); + } REQUIRE_ARG(); twinSippMode = true; strcpy(twinSippHost, argv[argi]); @@ -3672,6 +3722,27 @@ ERROR_P1("Internal error, I don't recognize %s as a scenario option\n", argv[argi] - 1); } break; + case SIPP_OPTION_SLAVE_CFG: + if(twinSippMode){ + ERROR("-slave_cfg and -3pcc options are not compatible\n"); + } + REQUIRE_ARG(); + extendedTwinSippMode = true; + slave_cfg_file = new char [strlen(argv[argi])+1] ; + sprintf(slave_cfg_file,"%s", argv[argi]); + parse_slave_cfg(); + break; + case SIPP_OPTION_3PCC_EXTENDED: + if(slave_masterSet){ + ERROR("-slave and -master options are not compatible\n"); + } + if(twinSippMode){ + ERROR("-master and -slave options are not compatible with -3PCC option\n"); + } + REQUIRE_ARG(); + *((char **)option->data) = argv[argi]; + slave_masterSet = true; + break; case SIPP_OPTION_RSA: { REQUIRE_ARG(); char *remote_s_address ; @@ -3742,6 +3813,10 @@ } } + if((extendedTwinSippMode && !slave_masterSet) || (!extendedTwinSippMode && slave_masterSet)){ + ERROR("-slave_cfg option must be used with -slave or -master option\n"); + } + if (peripsocket) { if (!argiInputFile) { ERROR("You must use the -inf option when using -t ui.\n" @@ -3788,7 +3863,7 @@ if(!screenf) { ERROR_P1("Unable to create '%s'", L_file_name); } - } + } if (useTimeoutf == 1) { char L_file_name [MAX_PATH]; @@ -3909,6 +3984,7 @@ open_connections(); + /* Defaults for media sockets */ if (media_ip[0] == '\0') { strcpy(media_ip, local_ip); @@ -4541,13 +4617,41 @@ /* Trying to connect to Twin Sipp in 3PCC mode */ if(twinSippMode) { if(toolMode == MODE_3PCC_CONTROLLER_A || toolMode == MODE_3PCC_A_PASSIVE) { - if(strstr(twinSippHost, ":")) { - twinSippPort = atol(strstr(twinSippHost, ":")+1); - *(strstr(twinSippHost, ":")) = 0; + connect_to_peer(twinSippHost, &twinSippPort, &twinSipp_sockaddr, twinSippIp, &twinSippSocket); + }else if(toolMode == MODE_3PCC_CONTROLLER_B){ + connect_local_twin_socket(twinSippHost); + }else{ + ERROR("TwinSipp Mode enabled but toolMode is different " + "from 3PCC_CONTROLLER_B and 3PCC_CONTROLLER_A\n"); + } + }else if (extendedTwinSippMode){ + if (toolMode == MODE_MASTER || toolMode == MODE_MASTER_PASSIVE) { + strcpy(twinSippHost,get_peer_addr(master_name)); + connect_local_twin_socket(twinSippHost); + connect_to_all_peers(); + }else if(toolMode == MODE_SLAVE) { + strcpy(twinSippHost,get_peer_addr(slave_number)); + connect_local_twin_socket(twinSippHost); + }else{ + ERROR("extendedTwinSipp Mode enabled but toolMode is different " + "from MASTER and SLAVE\n"); + } + } +#endif + + return status; } - /* Resolving the twin IP */ - printf("Resolving twin address : %s...\n", twinSippHost); + +void connect_to_peer(char *peer_host, int *peer_port, struct sockaddr_storage *peer_sockaddr, char *peer_ip, int *peer_socket){ + + if(strstr(peer_host, ":")) { + *peer_port = atol(strstr(peer_host, ":")+1); + *(strstr(peer_host, ":")) = 0; + } + + /* Resolving the peer IP */ + printf("Resolving peer address : %s...\n",peer_host); struct addrinfo hints; struct addrinfo * local_addr; memset((char*)&hints, 0, sizeof(hints)); @@ -4555,53 +4659,98 @@ hints.ai_family = PF_UNSPEC; is_ipv6 = false; /* Resolving twin IP */ - if (getaddrinfo(twinSippHost, + if (getaddrinfo(peer_host, NULL, &hints, &local_addr) != 0) { - ERROR_P1("Unknown twin host '%s'.\n" - "Use 'sipp -h' for details", twinSippHost); + +ERROR_P1("Unknown peer host '%s'.\n" + "Use 'sipp -h' for details", peer_host); } - memcpy(&twinSipp_sockaddr, + memcpy(peer_sockaddr, local_addr->ai_addr, SOCK_ADDR_SIZE( _RCAST(struct sockaddr_storage *,local_addr->ai_addr))); freeaddrinfo(local_addr); - if (twinSipp_sockaddr.ss_family == AF_INET) { - (_RCAST(struct sockaddr_in *,&twinSipp_sockaddr))->sin_port = - htons((short)twinSippPort); + if (peer_sockaddr->ss_family == AF_INET) { + (_RCAST(struct sockaddr_in *,peer_sockaddr))->sin_port = + htons((short)*peer_port); } else { - (_RCAST(struct sockaddr_in6 *,&twinSipp_sockaddr))->sin6_port = - htons((short)twinSippPort); + (_RCAST(struct sockaddr_in6 *,peer_sockaddr))->sin6_port = + htons((short)*peer_port); is_ipv6 = true; } - strcpy(twinSippIp, get_inet_address(&twinSipp_sockaddr)); - if((twinSippSocket = socket(is_ipv6 ? AF_INET6 : AF_INET, + strcpy(peer_ip, get_inet_address(peer_sockaddr)); + if((*peer_socket = socket(is_ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM, 0))== -1) { - ERROR_NO("Unable to get a TCP socket in 3PCC controller A mode"); + ERROR_NO("Unable to get a twin sipp TCP socket"); } - if(connect(twinSippSocket, - (struct sockaddr *)(void *)&twinSipp_sockaddr, - SOCK_ADDR_SIZE(&twinSipp_sockaddr))) { + if(connect(*peer_socket, + (struct sockaddr *)(void *)peer_sockaddr, + SOCK_ADDR_SIZE(peer_sockaddr))) { if(errno == EINVAL) { /* This occurs sometime on HPUX but is not a true INVAL */ - ERROR_NO("Unable to connect a TCP socket in 3PCC controller " - "A mode, remote peer error.\n" + ERROR_NO("Unable to connect a twin sipp TCP socket\n " + ", remote peer error.\n" "Use 'sipp -h' for details"); } else { - ERROR_NO("Unable to connect a TCP socket in 3PCC controller " - "A mode.\n" + ERROR_NO("Unable to connect a twin sipp socket " + "\n" "Use 'sipp -h' for details"); } } - sipp_customize_socket(twinSippSocket); - } else if(toolMode == MODE_3PCC_CONTROLLER_B) { - if(strstr(twinSippHost, ":")) { + sipp_customize_socket(*peer_socket); +} + +int * get_peer_socket(char * peer) +{ + int * peer_socket; + T_peer_infos infos; + peer_map::iterator peer_it; + peer_it = peers.find(peer_map::key_type(peer)); + if(peer_it != peers.end()) { + infos = peer_it->second; + peer_socket = &(infos.peer_socket); + return peer_socket; + } + else { + ERROR_P1("get_peer_socket: Peer %s not found\n", peer); + } +} + +char * get_peer_addr(char * peer) +{ + char * addr; + peer_addr_map::iterator peer_addr_it; + peer_addr_it = peer_addrs.find(peer_addr_map::key_type(peer)); + if(peer_addr_it != peer_addrs.end()){ + addr = peer_addr_it->second; + return addr; + } + else{ + ERROR_P1("get_peer_addr: Peer %s not found\n", peer); + } +} + +bool is_a_peer_socket(int peer_socket) +{ + peer_socket_map::iterator peer_socket_it; + peer_socket_it = peer_sockets.find(peer_socket_map::key_type(peer_socket)); + if(peer_socket_it == peer_sockets.end()){ + return false; + }else{ + return true; + } +} + +void connect_local_twin_socket(char * twinSippHost) +{ + if(strstr(twinSippHost, ":")) { twinSippPort = atol(strstr(twinSippHost, ":")+1); *(strstr(twinSippHost, ":")) = 0; } @@ -4614,7 +4763,7 @@ hints.ai_flags = AI_PASSIVE; hints.ai_family = PF_UNSPEC; is_ipv6 = false; - + /* Resolving twin IP */ if (getaddrinfo(twinSippHost, NULL, @@ -4622,12 +4771,12 @@ &local_addr) != 0) { ERROR_P1("Unknown twin host '%s'.\n" "Use 'sipp -h' for details", twinSippHost); - } + } memcpy(&twinSipp_sockaddr, local_addr->ai_addr, SOCK_ADDR_SIZE( _RCAST(struct sockaddr_storage *,local_addr->ai_addr))); - + if (twinSipp_sockaddr.ss_family == AF_INET) { (_RCAST(struct sockaddr_in *,&twinSipp_sockaddr))->sin_port = htons((short)twinSippPort); @@ -4637,47 +4786,100 @@ is_ipv6 = true; } strcpy(twinSippIp, get_inet_address(&twinSipp_sockaddr)); - + if((localTwinSippSocket = socket(is_ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM, 0))== -1) { - ERROR_NO("Unable to get a TCP socket in 3PCC controller B mode"); + ERROR_NO("Unable to get a listener TCP socket "); } memset(&localTwin_sockaddr, 0, sizeof(struct sockaddr_storage)); if (!is_ipv6) { - localTwin_sockaddr.ss_family = AF_INET; + localTwin_sockaddr.ss_family = AF_INET; (_RCAST(struct sockaddr_in *,&localTwin_sockaddr))->sin_port = - htons((short)twinSippPort); + htons((short)twinSippPort); } else { localTwin_sockaddr.ss_family = AF_INET6; (_RCAST(struct sockaddr_in6 *,&localTwin_sockaddr))->sin6_port = htons((short)twinSippPort); } - - // add socket option to allow the use of it without the TCP timeout - // This allows to re-start the B controller without timeout after its exit + + // add socket option to allow the use of it without the TCP timeout + // This allows to re-start the controller B (or slave) without timeout after its exit int reuse = 1; setsockopt(localTwinSippSocket,SOL_SOCKET,SO_REUSEADDR,(int *)&reuse,sizeof(reuse)); sipp_customize_socket(localTwinSippSocket); - if(bind(localTwinSippSocket, + if(bind(localTwinSippSocket, (sockaddr *)(void *)&localTwin_sockaddr, SOCK_ADDR_SIZE(&localTwin_sockaddr))) { - ERROR_NO("Unable to bind twin sipp socket in " - "3PCC_CONTROLLER_B mode"); + ERROR_NO("Unable to bind twin sipp socket "); } - if(listen(localTwinSippSocket, 100)) - ERROR_NO("Unable to listen twin sipp socket in " - "3PCC_CONTROLLER_B mode"); - } else { - ERROR("TwinSipp Mode enabled but toolMode is different " - "from 3PCC_CONTROLLER_B and 3PCC_CONTROLLER_A\n"); - } - } /* end if(twinSippMode) */ -#endif + if(listen(localTwinSippSocket, 100)) + ERROR_NO("Unable to listen twin sipp socket in "); - return status; +} +void close_peer_sockets() +{ + peer_map::iterator peer_it; + T_peer_infos infos; + for(peer_it = peers.begin(); peer_it != peers.end(); peer_it++){ + infos = peer_it->second; + shutdown(infos.peer_socket, SHUT_RDWR); + close(infos.peer_socket); + infos.peer_socket = 0 ; + peers[std::string(peer_it->first)] = infos; + } + peers_connected = 0; } +void close_local_sockets(){ + for (int i = 0; i< local_nb; i++){ + shutdown(local_sockets[i], SHUT_RDWR); + close(local_sockets[i]); + local_sockets[i] = 0; + } +} + +void connect_to_all_peers(){ + peer_map::iterator peer_it; + T_peer_infos infos; + for (peer_it = peers.begin(); peer_it != peers.end(); peer_it++){ + infos = peer_it->second; + connect_to_peer(infos.peer_host, &(infos.peer_port),&(infos.peer_sockaddr), infos.peer_ip, &(infos.peer_socket)); + peer_sockets[int(infos.peer_socket)] = peer_it->first; + peers[std::string(peer_it->first)] = infos; + pollset_add(0, infos.peer_socket); + + } + peers_connected = 1; +} +bool is_a_local_socket(int s){ + for (int i = 0; i< local_nb + 1; i++){ + if(local_sockets[i] == s) return true; + } + return (false); +} + +void free_peer_addr_map(){ + peer_addr_map::iterator peer_addr_it; + for (peer_addr_it = peer_addrs.begin(); peer_addr_it != peer_addrs.end(); peer_addr_it++){ + free(peer_addr_it->second); + } +} + + + + + + + + + + + + + + + Modified: sipp/trunk/sipp.hpp =================================================================== --- sipp/trunk/sipp.hpp 2007-01-23 17:17:19 UTC (rev 151) +++ sipp/trunk/sipp.hpp 2007-01-23 17:30:51 UTC (rev 152) @@ -1,4 +1,5 @@ /* + * 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 @@ -43,6 +44,7 @@ #include <time.h> #include <vector> #include <string> +#include <map> #include <math.h> #if defined(__HPUX) || defined(__SUNOS) @@ -121,6 +123,10 @@ #define MAX_PATH 250 +#define MAX_PEER_SIZE 4096 /* 3pcc extended mode: max size of peer names */ +#define MAX_LOCAL_TWIN_SOCKETS 10 /*3pcc extended mode:max number of peers from which + cmd messages are received */ + /******************** Default parameters ***********************/ #define DEFAULT_RATE 10.0 @@ -213,9 +219,13 @@ #ifdef __3PCC__ extern char twinSippHost[255]; extern char twinSippIp[40]; +extern char * master_name; +extern char * slave_number; extern int twinSippPort _DEFVAL(DEFAULT_3PCC_PORT); extern bool twinSippMode _DEFVAL(false); +extern bool extendedTwinSippMode _DEFVAL(false); #endif + extern bool backgroundMode _DEFVAL(false); extern bool signalDump _DEFVAL(false); @@ -339,6 +349,25 @@ extern int twinSippSocket _DEFVAL(0); extern int localTwinSippSocket _DEFVAL(0); extern struct sockaddr_storage twinSipp_sockaddr; + +/* 3pcc extended mode */ +typedef struct _T_peer_infos { + char peer_host[40]; + int peer_port; + struct sockaddr_storage peer_sockaddr; + char peer_ip[40]; + int peer_socket ; + } T_peer_infos; + +typedef std::map<std::string, char * > peer_addr_map; +extern peer_addr_map peer_addrs; +typedef std::map<std::string, T_peer_infos> peer_map; +extern peer_map peers; +typedef std::map<int, std::string > peer_socket_map; +extern peer_socket_map peer_sockets; +extern int local_sockets[MAX_LOCAL_TWIN_SOCKETS]; +extern int local_nb _DEFVAL(0); +extern int peers_connected _DEFVAL(0); #endif extern struct sockaddr_storage remote_sockaddr; @@ -365,6 +394,7 @@ extern bool dumpInFile _DEFVAL(0); extern bool dumpInRtt _DEFVAL(0); extern char * scenario_file; +extern char * slave_cfg_file; #define TRACE_MSG(arg) \ { \ @@ -430,6 +460,7 @@ /********************* Utilities functions *******************/ char *strcasestr2 ( char *__haystack, char *__needle); +char *get_peer_addr(char *); int get_decimal_from_hex(char hex); int reset_connections() ; @@ -438,6 +469,17 @@ int open_connections(); void timeout_alarm(int); +/* extended 3PCC mode */ +int * get_peer_socket(char *); +bool is_a_peer_socket(int); +bool is_a_local_socket(int); +void connect_to_peer (char *, int *, sockaddr_storage *, char *, int *); +void connect_to_all_peers (); +void connect_local_twin_socket(char *); +void close_peer_sockets(); +void close_local_sockets(); +void free_peer_addr_map(); + /********************* Reset global kludge *******************/ #ifdef GLOBALS_FULL_DEFINITION This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |