[httperf] More than one IP
Rivalino Matias Jr.
rivalino at eps.ufsc.br
Thu Jul 8 11:10:55 PDT 2004
Cool !
I will apply the patches and next the tests return a feedback !
Thank you....
Rivalino.
----- Original Message -----
From: "Martin Arlitt" <arlitt at granite.hpl.hp.com>
To: "Rivalino Matias Jr." <rivalino at eps.ufsc.br>
Cc: <httperf at napali.hpl.hp.com>
Sent: Thursday, July 08, 2004 1:47 PM
Subject: Re: [httperf] More than one IP
> Rivalino
>
> below is a patch to allow httperf to use more than one source IP address
> (assuming that the client machine is configured to support those
> addresses). please be sure to use this only on an isolated network.
>
> you need to patch three files to implement this:
> httperf.h
> httperf.c
> core.c
>
> the patch also contains a fix for a problem with gen/wsesslog.c. that's
> not needed for supporting multiple IP addresses, but is a good idea if you
> use sessions.
>
> the patch includes two different ways for specifying the addresses. the
> code enclosed by "MULTIPLE_SRC_ADDRS_OPTION" enables the command line
> option "--src-addrs", which allows you to specify the addresses on the
> command line. e.g., --src-addrs=192.168.1.1,192.168.1.2,192.168.1.3
>
> the code enclosed by "MULTIPLE_SRC_ADDRS_FILE_OPTION" enables the command
> line option "--src-addrs-file". this option requires a filename. in the
> file you specify one IP address per line. This is useful if you want to
> use lots of client IP addresses.
>
> to compile the patched version of httperf you will need to add the
> appropriate CPPFLAG, or remove the ifdefs corresponding to the option you
> want to use.
>
> to configure multiple IP addresses on the client's NIC, use:
>
> # /sbin/ip address add <ip_address> dev <interface>
>
> e.g.,
> # /sbin/ip address add 192.168.1.1 dev eth0
> # /sbin/ip address add 192.168.1.2 dev eth0
>
> then run httperf
>
>
./httperf --server=<server> --src-addrs=192.168.1.1,192.168.1.2 --hog --num-
conns=2
>
> note that you need to specify the --hog option (for the implementation
> below at least). also, you will need to issue at least N connections in
> order to see connections from N different client IP addresses. this
> implementation cycles through the IP addresses in round-robin fashion.
>
> the implementation below allows 16 addresses to be specified on the
> command line, or 32768 in a file.
>
> Martin
>
> ------------------------------------------------------------------
>
> diff -urN httperf-0.8/core.c httperf-0.8.mod/core.c
> --- httperf-0.8/core.c 2000-10-31 16:57:50.000000000 -0700
> +++ httperf-0.8.mod/core.c 2004-07-08 10:24:28.000000000 -0600
> @@ -881,6 +881,30 @@
>
> if (param.hog)
> {
> +#ifdef MULTIPLE_SRC_ADDRS_OPTION
> + if(param.src_addrs.num_addrs > 0)
> + {
> + /* determine client address to use */
> + myaddr.sin_addr.s_addr =
> +
param.src_addrs.src_addr[param.src_addrs.next_addr].s_addr;
> + param.src_addrs.next_addr =
> + (param.src_addrs.next_addr+1) %
param.src_addrs.num_addrs;
> + }
> +#endif /* MULTIPLE_SRC_ADDRS_OPTION */
> +#ifdef MULTIPLE_SRC_ADDRS_FILE_OPTION
> + if(param.src_addrs_file.num_addrs > 0)
> + {
> + /* determine client address to use */
> + myaddr.sin_addr.s_addr =
> + param.src_addrs_file.src_addr
> + [param.src_addrs_file.next_addr].s_addr;
> +
> + param.src_addrs_file.next_addr =
> + (param.src_addrs_file.next_addr+1)
> + % param.src_addrs_file.num_addrs;
> + }
> +#endif /* MULTIPLE_SRC_ADDRS_FILE_OPTION */
> +
> while (1)
> {
> myport = port_get ();
> diff -urN httperf-0.8/gen/wsesslog.c httperf-0.8.mod/gen/wsesslog.c
> --- httperf-0.8/gen/wsesslog.c 2000-10-11 17:40:46.000000000 -0600
> +++ httperf-0.8.mod/gen/wsesslog.c 2003-07-29 13:14:58.000000000 -0600
> @@ -312,6 +312,9 @@
> sess = session_get_sess_from_call (call);
> priv = SESS_PRIVATE_DATA (sess);
>
> + if (sess->failed)
> + return;
> +
> ++priv->num_calls_destroyed;
>
> if (priv->num_calls_destroyed >= priv->total_num_reqs)
> diff -urN httperf-0.8/httperf.c httperf-0.8.mod/httperf.c
> --- httperf-0.8/httperf.c 2000-10-31 13:20:00.000000000 -0700
> +++ httperf-0.8.mod/httperf.c 2004-07-08 10:23:55.000000000 -0600
> @@ -117,6 +117,12 @@
> {"rate", required_argument, (int *) ¶m.rate, 0},
> {"recv-buffer", required_argument, (int *) ¶m.recv_buffer_size,
0},
> {"retry-on-failure", no_argument, ¶m.retry_on_failure, 1},
> +#ifdef MULTIPLE_SRC_ADDRS_OPTION
> + {"src-addrs", required_argument, (int *) ¶m.src_addrs,
0},
> +#endif /* MULTIPLE_SRC_ADDRS_OPTION */
> +#ifdef MULTIPLE_SRC_ADDRS_FILE_OPTION
> + {"src-addrs-file",required_argument, (int *) ¶m.src_addrs_file,
0},
> +#endif /* MULTIPLE_SRC_ADDRS_FILE_OPTION */
> {"send-buffer", required_argument, (int *) ¶m.send_buffer_size,
0},
> {"server", required_argument, (int *) ¶m.server, 0},
> {"server-name", required_argument, (int *) ¶m.server_name, 0},
> @@ -151,6 +157,12 @@
> "\t[--port N] "
> "[--print-reply [header|body]] [--print-request [header|body]]\n"
> "\t[--rate X] [--recv-buffer N] [--retry-on-failure] "
> +#ifdef MULTIPLE_SRC_ADDRS_OPTION
> + "\t[--src-addrs A1,...,An]\n"
> +#endif /* MULTIPLE_SRC_ADDRS_OPTION */
> +#ifdef MULTIPLE_SRC_ADDRS_FILE_OPTION
> + "\t[--src-addrs-file file]\n"
> +#endif /* MULTIPLE_SRC_ADDRS_FILE_OPTION */
> "[--send-buffer N]\n"
> "\t[--server S] [--server-name S] [--session-cookies]\n"
> #ifdef HAVE_SSL
> @@ -220,6 +232,22 @@
> void *flag;
> Time t;
>
> +#ifdef MULTIPLE_SRC_ADDRS_OPTION
> + struct in_addr src_addr;
> + int result;
> + int numSrcs;
> +#endif /* MULTIPLE_SRC_ADDRS_OPTION */
> +
> +#ifdef MULTIPLE_SRC_ADDRS_FILE_OPTION
> + FILE *fp;
> + char line[1000];
> + char ip_addr[1000];
> +
> + struct in_addr src_addr;
> + int result;
> + int numSrcs;
> +#endif /* MULTIPLE_SRC_ADDRS_FILE_OPTION */
> +
> #ifdef __FreeBSD__
> /* This works around a bug in earlier versions of FreeBSD that cause
> non-finite IEEE arithmetic to cause SIGFPE instead of the
> @@ -359,6 +387,105 @@
> exit (1);
> }
> }
> +
> +#ifdef MULTIPLE_SRC_ADDRS_OPTION
> + else if (flag == ¶m.src_addrs)
> + {
> + name = "bad source address";
> + numSrcs=0;
> +
> + while(numSrcs < MAX_SRC_ADDRS)
> + {
> + /* determine address */
> + if((end = strchr(optarg, ',')) == NULL)
> + {
> + /* last address */
> + numSrcs = MAX_SRC_ADDRS;
> + }
> + else
> + {
> + *end++ = '\0';
> + }
> +
> + /* convert the address */
> + result = inet_aton(optarg, &src_addr);
> + if(result == 0)
> + {
> + fprintf(stderr,"%s: %s in --src-addrs arg "
> + "(rest: '%s')\n",
> + prog_name, name, end);
> + exit(1);
> + }
> +
> + /* store the address */
> + param.src_addrs.src_addr
> + [param.src_addrs.num_addrs++].s_addr =
src_addr.s_addr;
> +
> + /* advance to next address */
> + optarg = end;
> + }
> + }
> +#endif /* MULTIPLE_SRC_ADDRS_OPTION */
> +#ifdef MULTIPLE_SRC_ADDRS_FILE_OPTION
> + else if (flag == ¶m.src_addrs_file)
> + {
> + param.src_addrs_file.name = optarg;
> +
> + name = "bad source address";
> + numSrcs=0;
> +
> + /* open file with source IP addresses */
> + if((fp = fopen(param.src_addrs_file.name, "r")) == NULL)
> + {
> + fprintf(stderr, "%s: can't open %s\n",
> + prog_name, param.src_addrs_file.name);
> + exit(1);
> + }
> +
> + fgets(line, sizeof(line), fp);
> +
> + while(!feof(fp))
> + {
> + /* skip comments */
> + if (line[0] == '#')
> + continue;
> +
> + if(sscanf(line, "%s", ip_addr) == 1)
> + {
> + if(numSrcs >= MAX_SRC_FILE_ADDRS)
> + {
> + fprintf(stderr,"%s: too many ip addresses "
> + "in %s\n",
> + prog_name, param.src_addrs_file.name);
> + exit(1);
> + }
> +
> + /* convert the address */
> + result = inet_aton(ip_addr, &src_addr);
> + if(result == 0)
> + {
> + fprintf(stderr,"%s: invalid ip address %s in %s\n ",
> + prog_name, ip_addr,
> + param.src_addrs_file.name);
> + exit(1);
> + }
> +
> + /* store the address */
> + param.src_addrs_file.src_addr
> + [param.src_addrs_file.num_addrs++].s_addr =
> + src_addr.s_addr;
> +
> + numSrcs++;
> + }
> +
> + /* advance to next address */
> + fgets(line, sizeof(line), fp);
> + }
> + /* close the file of ip addresses */
> + fclose(fp);
> + }
> +#endif /* MULTIPLE_SRC_ADDRS_FILE_OPTION */
> +
> else if (flag == ¶m.print_request || flag == ¶m.print_reply)
> {
> int val;
> diff -urN httperf-0.8/httperf.h httperf-0.8.mod/httperf.h
> --- httperf-0.8/httperf.h 2000-10-31 13:32:09.000000000 -0700
> +++ httperf-0.8.mod/httperf.h 2004-07-08 09:51:53.000000000 -0600
> @@ -31,6 +31,18 @@
> #include <sys/types.h>
> #include <sys/resource.h>
>
> +#ifdef MULTIPLE_SRC_ADDRS_OPTION
> +#include <sys/socket.h>
> +#include <netinet/in.h>
> +#include <arpa/inet.h>
> +#endif /* MULTIPLE_SRC_ADDRS_OPTION */
> +
> +#ifdef MULTIPLE_SRC_ADDRS_FILE_OPTION
> +#include <sys/socket.h>
> +#include <netinet/in.h>
> +#include <arpa/inet.h>
> +#endif /* MULTIPLE_SRC_ADDRS_FILE_OPTION */
> +
> #define VERSION "0.8"
>
> typedef double Time;
> @@ -96,6 +108,14 @@
> #define PRINT_HEADER (1 << 0)
> #define PRINT_BODY (1 << 1)
>
> +#ifdef MULTIPLE_SRC_ADDRS_OPTION
> +#define MAX_SRC_ADDRS 16
> +#endif /* MULTIPLE_SRC_ADDRS_OPTION */
> +
> +#ifdef MULTIPLE_SRC_ADDRS_FILE_OPTION
> +#define MAX_SRC_FILE_ADDRS 32769
> +#endif /* MULTIPLE_SRC_ADDRS_FILE_OPTION */
> +
> typedef struct Cmdline_Params
> {
> int http_version; /* (default) HTTP protocol version */
> @@ -167,6 +187,27 @@
> double target_miss_rate;
> }
> wset;
> +
> +#ifdef MULTIPLE_SRC_ADDRS_OPTION
> + struct
> + {
> + int next_addr;
> + int num_addrs;
> + struct in_addr src_addr[MAX_SRC_ADDRS];
> + }
> + src_addrs;
> +#endif /* MULTIPLE_SRC_ADDRS_OPTION */
> +
> +#ifdef MULTIPLE_SRC_ADDRS_FILE_OPTION
> + struct
> + {
> + char *name;
> + int next_addr;
> + int num_addrs;
> + struct in_addr src_addr[MAX_SRC_FILE_ADDRS];
> + }
> + src_addrs_file;
> +#endif /* MULTIPLE_SRC_ADDRS_FILE_OPTION */
> }
> Cmdline_Params;
>
>
More information about the httperf
mailing list