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

Reply via email to