Hello, this is a diff against the sipp.2006-09-07 snapshot which provides an
enhancement to allow SIPp to send to multiple remote destinations in a round
robin fashion, when acting as a UAC.
Example command:
./sipp proxy-server1 proxy-server2 proxy-server3 -sn uac -r 1
will send the first call to proxy-server1, the second to proxy-server2, etc.
A #define MAX_REMOTE_DEST 16 determines the max allowed remote servers.
Also, this code has a limitation that when using TCP, you have to use
multi-socket (-t tn) if you are using more than one remote destination. I
couldn't figure out how to make multiple destinations work with tcp_multiplex
easily. So I added a check which errors out if this combination is used. If
anyone wants to attack that last leg, please feel free.
diff -bruN sipp.2006-09-07/call.cpp sipp.2006-09-07.multidest/call.cpp
--- sipp.2006-09-07/call.cpp 2006-09-06 17:25:29.000000000 -0400
+++ sipp.2006-09-07.multidest/call.cpp 2006-09-11 17:18:26.206797409 -0400
@@ -426,6 +426,7 @@
call::InputFileUsage call::m_usage = call::InputFileSequentialOrder;
int call::m_counter = 0;
+int call::remote_dest_counter = 0;
call::call(char * p_id, bool ipv6) : use_ipv6(ipv6)
{
@@ -489,6 +490,11 @@
}
+ m_dest_index = remote_dest_counter++;
+ if (remote_dest_counter >= remote_dest_size) {
+ remote_dest_counter = 0;
+ }
+
#ifdef PCAPPLAY
memset(&(play_args_a.to), 0, sizeof(struct sockaddr_storage));
memset(&(play_args_v.to), 0, sizeof(struct sockaddr_storage));
@@ -698,7 +704,7 @@
} else { /* TCP */
int L_status = 0 ; // no new socket
- struct sockaddr_storage *L_dest = &remote_sockaddr;
+ struct sockaddr_storage *L_dest = &remote_sockaddr[m_dest_index];
if ((call_socket = new_socket(use_ipv6, SOCK_STREAM, &L_status)) == -1) {
ERROR_NO("Unable to get a TCP socket");
@@ -713,7 +719,7 @@
if(connect(call_socket,
(struct sockaddr *)(void *)L_dest,
- SOCK_ADDR_SIZE(&remote_sockaddr))) {
+ SOCK_ADDR_SIZE(&remote_sockaddr[m_dest_index]))) {
if (reset_number > 0) {
if(errno == EINVAL){
@@ -844,7 +850,7 @@
if(connect(call_remote_socket,
(struct sockaddr *)(void *)L_dest,
- SOCK_ADDR_SIZE(&remote_sockaddr))) {
+ SOCK_ADDR_SIZE(&remote_sockaddr[m_dest_index]))) {
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));
@@ -878,7 +884,7 @@
rc = send_message_tls(ssl, state, msg);
} else {
#endif
- rc = send_message(sock, state, msg);
+ rc = send_message(sock, state, msg, m_dest_index);
#ifdef _USE_OPENSSL
}
#endif
@@ -1549,7 +1555,7 @@
char * cseq;
cseq = compute_cseq(src);
if (cseq != NULL) {
- sprintf(L_param, "%s%s BYE\n", L_param, compute_cseq(src));
+ sprintf(L_param, "%s%s BYE\n", L_param, cseq);
}
sprintf(L_param, "%s%s", L_param, "Contact:
<sip:[local_ip]:[local_port];transport=[transport]>\n");
sprintf(L_param, "%s%s", L_param, "Content-Length: 0\n");
@@ -1587,7 +1593,7 @@
char * cseq;
cseq = compute_cseq(src);
if (cseq != NULL) {
- sprintf(L_param, "%s%s BYE\n", L_param, compute_cseq(src));
+ sprintf(L_param, "%s%s BYE\n", L_param, cseq);
}
sprintf(L_param, "%s%s", L_param, "Contact:
<sip:[local_ip]:[local_port];transport=[transport]>\n");
sprintf(L_param, "%s%s", L_param, "Content-Length: 0\n");
@@ -1727,9 +1733,9 @@
} else offset = 0;
if(!strcmp(keyword, "remote_ip")) {
- dest += sprintf(dest, "%s", remote_ip_escaped);
+ dest += sprintf(dest, "%s", remote_ip_escaped[m_dest_index]);
} else if(!strcmp(keyword, "remote_port")) {
- dest += sprintf(dest, "%u", remote_port + offset);
+ dest += sprintf(dest, "%u", remote_port[m_dest_index] + offset);
} else if(!strcmp(keyword, "transport")) {
dest += sprintf(dest, "%s", TRANSPORT_TO_STRING(transport));
} else if(!strcmp(keyword, "local_ip")) {
@@ -2007,7 +2013,7 @@
/* Build the auth credenticals */
char result[MAX_HEADER_LEN];
char uri[MAX_HEADER_LEN];
- sprintf (uri, "%s:%d", remote_ip, remote_port);
+ sprintf (uri, "%s:%d", remote_ip[m_dest_index],
remote_port[m_dest_index]);
if (createAuthHeader(my_auth_user, my_auth_pass, method, uri,
body, dialog_authentication, result) == 0) {
ERROR_P1("%s", result);
diff -bruN sipp.2006-09-07/call.hpp sipp.2006-09-07.multidest/call.hpp
--- sipp.2006-09-07/call.hpp 2006-08-21 17:34:21.000000000 -0400
+++ sipp.2006-09-07.multidest/call.hpp 2006-09-11 11:07:44.246990289 -0400
@@ -122,6 +122,8 @@
/* Index of the socket, only if the call locally created it
* and must delete it on call deletion */
int pollset_index;
+ /* Index of the destination array when round-robin sending */
+ int m_dest_index;
void * comp_state;
@@ -220,6 +222,7 @@
static InputFileUsage m_usage;
static int m_counter; // used for sequential access
+ static int remote_dest_counter; // index for multiple dests
int m_localLineNumber;
diff -bruN sipp.2006-09-07/sipp.cpp sipp.2006-09-07.multidest/sipp.cpp
--- sipp.2006-09-07/sipp.cpp 2006-09-07 17:00:26.000000000 -0400
+++ sipp.2006-09-07.multidest/sipp.cpp 2006-09-11 17:32:02.065221483 -0400
@@ -558,6 +558,12 @@
total_calls,
TRANSPORT_TO_STRING(transport));
} else {
+ char tmp_ip[128] = "multi-dest";
+ int tmp_port = 0;
+ if (remote_dest_size == 1) {
+ strcpy(tmp_ip, remote_ip[0]);
+ tmp_port = remote_port[0];
+ }
fprintf
(f,
" Call-rate(length) Port Total-time Total-calls Remote-host"
@@ -568,8 +574,8 @@
local_port,
clock_tick / 1000, (clock_tick % 1000) / 10,
total_calls,
- remote_ip,
- remote_port,
+ tmp_ip,
+ tmp_port,
TRANSPORT_TO_STRING(transport));
}
@@ -1680,7 +1686,7 @@
return len;
}
-int decompress_if_needed(int sock, char *buff, int len, void **st)
+int decompress_if_needed(int sock, char *buff, int len, void **st, int
sockidx)
{
if(compression && len) {
if (useMessagef == 1) {
@@ -1714,8 +1720,8 @@
buff,
len,
0,
- (sockaddr *)(void *)&remote_sockaddr,
- SOCK_ADDR_SIZE(&remote_sockaddr));
+ (sockaddr *)(void *)&remote_sockaddr[sockidx],
+ SOCK_ADDR_SIZE(&remote_sockaddr[sockidx]));
resynch_send++;
return 0;
@@ -1807,10 +1813,10 @@
}
#endif
-int send_message(int s, void ** comp_state, char * msg)
+int send_message(int s, void ** comp_state, char * msg, int sockidx)
{
- struct sockaddr_storage *L_dest = &remote_sockaddr;
+ struct sockaddr_storage *L_dest = &remote_sockaddr[sockidx];
if(transport == T_TCP) {
@@ -1993,7 +1999,14 @@
char * VP_tmp = strdup(pending_msg[(*poll_idx)]);
free(pending_msg[(*poll_idx)]);
pending_msg[(*poll_idx)] = NULL;
- send_message(pollfiles[(*poll_idx)].fd, NULL, VP_tmp);
+ if(transport == T_UDP) {
+ call * L_recv_call = pollcalls[(*poll_idx)];
+ if(L_recv_call) {
+ send_message(pollfiles[(*poll_idx)].fd, NULL, VP_tmp, L_recv_call
-> m_dest_index);
+ }
+ } else {
+ send_message(pollfiles[(*poll_idx)].fd, NULL, VP_tmp, 0);
+ }
free(VP_tmp);
}
@@ -2051,9 +2064,9 @@
if(s == main_socket) {
/* New incoming connection */
- sipp_socklen_t len = SOCK_ADDR_SIZE(&remote_sockaddr);
+ sipp_socklen_t len = SOCK_ADDR_SIZE(&remote_sockaddr[0]);
int new_sock = accept(s,
- (sockaddr *)(void *)&remote_sockaddr,
+ (sockaddr *)(void *)&remote_sockaddr[0],
&len);
#ifdef _USE_OPENSSL
@@ -2148,13 +2161,13 @@
} else { /* T_UDP */
if(toolMode == MODE_SERVER) {
- sipp_socklen_t len = SOCK_ADDR_SIZE(&remote_sockaddr);
+ sipp_socklen_t len = SOCK_ADDR_SIZE(&remote_sockaddr[0]);
size = recvfrom(s,
buffer,
buffer_size,
0,
- (sockaddr *)(void *)&remote_sockaddr,
+ (sockaddr *)(void *)&remote_sockaddr[0],
&len);
} else {
@@ -2180,12 +2193,15 @@
if (size > 0) {
+ call * L_recv_call = pollcalls[(*poll_idx)];
+ if(L_recv_call) {
size = decompress_if_needed(s,
buffer,
size,
((recv_call) ?
(&(recv_call -> comp_state)) :
- &monosocket_comp_state));
+ &monosocket_comp_state), L_recv_call ->
m_dest_index);
+ }
}
} /* else ... T_UDP */
@@ -3217,6 +3233,7 @@
int err;
int L_maxSocketPresent = 0;
unsigned int generic_count = 0;
+ int remote_dest_index = 0;
generic[0] = NULL;
@@ -3974,7 +3991,11 @@
if(!processed) {
if((argv[argi])[0] != '-') {
- strcpy(remote_host, argv[argi]);
+ if (remote_dest_index == MAX_REMOTE_DEST) {
+ ERROR_P1("Remote Destination '%s' exceeds maximum allowed
destinations", argv[argi]);
+ }
+ strcpy(remote_host[remote_dest_index], argv[argi]);
+ remote_dest_index++;
} else {
help();
ERROR_P1("Invalid argument: '%s'.\n"
@@ -3983,6 +4004,12 @@
}
}
+ remote_dest_size = remote_dest_index;
+
+ if (!multisocket && transport != T_UDP && remote_dest_size > 1) {
+ ERROR("Multiple destinations are not supported with single socket TCP or
TLS");
+ }
+
if (peripsocket) {
if (!argiInputFile) {
ERROR("You must use the -inf option when using -t ui.\n"
@@ -4138,6 +4165,7 @@
if (toolMode == MODE_SERVER) {
reset_number = 0;
+ remote_dest_size = 1; // Only one connection allowed in UAS mode
}
open_connections();
@@ -4359,55 +4387,59 @@
local_port = 0;
struct addrinfo * local_addr;
- if(!strlen(remote_host)) {
+ if(!strlen(remote_host[0])) {
if(toolMode != MODE_SERVER) {
ERROR("Missing remote host parameter. This scenario requires it");
}
} else {
- int temp_remote_port;
- get_host_and_port(remote_host, remote_host, &temp_remote_port);
+ int temp_remote_port, i;
+ for (i = 0; i < remote_dest_size; i++) {
+ get_host_and_port(remote_host[i], remote_host[i], &temp_remote_port);
if (temp_remote_port != 0) {
- remote_port = temp_remote_port;
+ remote_port[i] = temp_remote_port;
+ } else {
+ remote_port[i] = DEFAULT_PORT;
}
/* Resolving the remote IP */
{
struct addrinfo hints;
- fprintf(stderr,"Resolving remote host '%s'... ", remote_host);
+ fprintf(stderr,"Resolving remote host '%s'... ", remote_host[i]);
memset((char*)&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_family = PF_UNSPEC;
/* FIXME: add DNS SRV support using liburli? */
- if (getaddrinfo(remote_host,
+ if (getaddrinfo(remote_host[i],
NULL,
&hints,
&local_addr) != 0) {
ERROR_P1("Unknown remote host '%s'.\n"
- "Use 'sipp -h' for details", remote_host);
+ "Use 'sipp -h' for details", remote_host[i]);
}
- memset(&remote_sockaddr, 0, sizeof( remote_sockaddr ));
- memcpy(&remote_sockaddr,
+ memset(&remote_sockaddr[i], 0, sizeof( remote_sockaddr[i] ));
+ memcpy(&remote_sockaddr[i],
local_addr->ai_addr,
SOCK_ADDR_SIZE(
_RCAST(struct sockaddr_storage *,local_addr->ai_addr)));
- strcpy(remote_ip, get_inet_address(&remote_sockaddr));
- if (remote_sockaddr.ss_family == AF_INET) {
- (_RCAST(struct sockaddr_in *, &remote_sockaddr))->sin_port =
- htons((short)remote_port);
- strcpy(remote_ip_escaped, remote_ip);
- } else {
- (_RCAST(struct sockaddr_in6 *, &remote_sockaddr))->sin6_port =
- htons((short)remote_port);
- sprintf(remote_ip_escaped, "[%s]", remote_ip);
+ strcpy(remote_ip[i], get_inet_address(&remote_sockaddr[i]));
+ if (remote_sockaddr[i].ss_family == AF_INET) {
+ (_RCAST(struct sockaddr_in *, &remote_sockaddr[i]))->sin_port =
+ htons((short)remote_port[i]);
+ strcpy(remote_ip_escaped[i], remote_ip[i]);
+ } else {
+ (_RCAST(struct sockaddr_in6 *, &remote_sockaddr[i]))->sin6_port =
+ htons((short)remote_port[i]);
+ sprintf(remote_ip_escaped[i], "[%s]", remote_ip[i]);
}
fprintf(stderr,"Done.\n");
}
}
+ }
if(gethostname(hostname,64) != 0) {
ERROR_NO("Can't get local hostname in 'gethostname(hostname,64)'");
@@ -4698,12 +4730,12 @@
/* OJA FIXME: is it correct? */
if (use_remote_sending_addr) {
- remote_sockaddr = remote_sending_sockaddr ;
+ remote_sockaddr[0] = remote_sending_sockaddr ;
}
if(connect(tcp_multiplex,
- (struct sockaddr *)(void *)&remote_sockaddr,
- SOCK_ADDR_SIZE(&remote_sockaddr))) {
+ (struct sockaddr *)(void *)&remote_sockaddr[0],
+ SOCK_ADDR_SIZE(&remote_sockaddr[0]))) {
if(errno == EINVAL){
/* This occurs sometime on HPUX but is not a true INVAL */
diff -bruN sipp.2006-09-07/sipp.hpp sipp.2006-09-07.multidest/sipp.hpp
--- sipp.2006-09-07/sipp.hpp 2006-08-29 04:03:34.000000000 -0400
+++ sipp.2006-09-07.multidest/sipp.hpp 2006-09-01 14:08:08.000000000 -0400
@@ -120,6 +120,8 @@
#define MAX_PATH 250
+#define MAX_REMOTE_DEST 16
+
/******************** Default parameters ***********************/
#define DEFAULT_RATE 10.0
@@ -184,9 +186,9 @@
extern int media_port _DEFVAL(0);
extern size_t media_bufsize _DEFVAL(2048);
extern bool media_ip_is_ipv6;
-extern char remote_ip[40];
-extern char remote_ip_escaped[42];
-extern int remote_port _DEFVAL(DEFAULT_PORT);
+extern char remote_ip[MAX_REMOTE_DEST][40];
+extern char remote_ip_escaped[MAX_REMOTE_DEST][42];
+extern int remote_port[MAX_REMOTE_DEST];
extern unsigned int pid _DEFVAL(0);
extern int print_all_responses _DEFVAL(0);
extern unsigned long stop_after _DEFVAL(0xffffffff);
@@ -194,7 +196,8 @@
extern int interrupt _DEFVAL(0);
extern int paused _DEFVAL(0);
extern int lose_packets _DEFVAL(0);
-extern char remote_host[255];
+extern char remote_host[MAX_REMOTE_DEST][255];
+extern int remote_dest_size _DEFVAL(0);
#ifdef __3PCC__
extern char twinSippHost[255];
extern char twinSippIp[40];
@@ -326,7 +329,7 @@
extern struct sockaddr_storage twinSipp_sockaddr;
#endif
-extern struct sockaddr_storage remote_sockaddr;
+extern struct sockaddr_storage remote_sockaddr[MAX_REMOTE_DEST];
extern short use_remote_sending_addr _DEFVAL(0);
extern struct sockaddr_storage remote_sending_sockaddr;
@@ -387,7 +390,7 @@
/********************** Network Interfaces ********************/
void sipp_customize_socket(int socket);
-int send_message(int s, void ** comp_state, char * msg);
+int send_message(int s, void ** comp_state, char * msg, int sockidx);
#ifdef _USE_OPENSSL
int send_message_tls(SSL *s, void ** comp_state, char * msg);
#endif
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Sipp-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sipp-users