From 4408d4137acfacef57bd2e088a0da83d25e34918 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 10 Mar 2010 11:07:26 +0100 Subject: testbench: new calling interface for tcpflood this is a perquisite to support more flexible testing modes, which could not intelligently be implemented with the old interface --- tests/tcpflood.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'tests/tcpflood.c') diff --git a/tests/tcpflood.c b/tests/tcpflood.c index 0439e33e..308495a5 100644 --- a/tests/tcpflood.c +++ b/tests/tcpflood.c @@ -2,11 +2,11 @@ * messages over them. This is used for stress-testing. * * Params - * argv[1] target address - * argv[2] target port - * argv[3] number of connections - * argv[4] number of messages to send (connection is random) - * argv[5] initial message number (optional) + * -t target address (default 127.0.0.1) + * -p target port (default 13514) + * -c number of connections (default 1) + * -m number of messages to send (connection is random) + * -i initial message number (optional) * * Part of the testbench for rsyslog. * @@ -47,10 +47,10 @@ /* Name of input file, must match $IncludeConfig in test suite .conf files */ #define NETTEST_INPUT_CONF_FILE "nettest.input.conf" /* name of input file, must match $IncludeConfig in .conf files */ -static char *targetIP; -static int targetPort; +static char *targetIP = "127.0.0.1"; +static int targetPort = 13514; static int numMsgsToSend; /* number of messages to send */ -static int numConnections; /* number of connections to create */ +static int numConnections = 1; /* number of connections to create */ static int *sockArray; /* array of sockets to use */ static int msgNum = 0; /* initial message number to start with */ @@ -259,6 +259,7 @@ tcpSend(char *buf, int lenBuf) int main(int argc, char *argv[]) { int ret = 0; + int opt; struct sigaction sigAct; static char buf[1024]; @@ -272,18 +273,20 @@ int main(int argc, char *argv[]) setvbuf(stdout, buf, _IONBF, 48); - if(argc != 5 && argc != 6) { - printf("Invalid call of tcpflood\n"); - printf("Usage: tcpflood target-host target-port num-connections num-messages [initial msgnum]\n"); - exit(1); + while((opt = getopt(argc, argv, "t:p:c:m:i:")) != -1) { + switch (opt) { + case 't': targetIP = optarg; + break; + case 'p': targetPort = atoi(optarg); + break; + case 'c': numConnections = atoi(optarg); + break; + case 'm': numMsgsToSend = atoi(optarg); + break; + case 'i': msgNum = atoi(optarg); + break; + } } - - targetIP = argv[1]; - targetPort = atoi(argv[2]); - numConnections = atoi(argv[3]); - numMsgsToSend = atoi(argv[4]); - if(argc == 6) - msgNum = atoi(argv[5]); if(openConnections() != 0) { printf("error opening connections\n"); -- cgit From 5106cbe466781e824846742a036d36ba5f884ad6 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 10 Mar 2010 12:19:51 +0100 Subject: added ability to work with larger message sizes to testbench tools --- tests/tcpflood.c | 48 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) (limited to 'tests/tcpflood.c') diff --git a/tests/tcpflood.c b/tests/tcpflood.c index 308495a5..fcfc30a7 100644 --- a/tests/tcpflood.c +++ b/tests/tcpflood.c @@ -7,6 +7,13 @@ * -c number of connections (default 1) * -m number of messages to send (connection is random) * -i initial message number (optional) + * -P PRI to be used for generated messages (default is 167). + * Specify the plain number without leading zeros + * -d amount of extra data to add to message. If present, the + * number itself will be added as third field, and the data + * bytes as forth. Add -r to randomize the amount of extra + * data included in the range 1..(value of -d). + * -r randomize amount of extra data added (-d must be > 0) * * Part of the testbench for rsyslog. * @@ -47,8 +54,13 @@ /* Name of input file, must match $IncludeConfig in test suite .conf files */ #define NETTEST_INPUT_CONF_FILE "nettest.input.conf" /* name of input file, must match $IncludeConfig in .conf files */ +#define MAX_EXTRADATA_LEN 100*1024 + static char *targetIP = "127.0.0.1"; +static char *msgPRI = "167"; static int targetPort = 13514; +static int extraDataLen = 0; /* amount of extra data to add to message */ +static int bRandomizeExtraData = 0; /* randomize amount of extra data added */ static int numMsgsToSend; /* number of messages to send */ static int numConnections = 1; /* number of connections to create */ static int *sockArray; /* array of sockets to use */ @@ -164,7 +176,9 @@ int sendMessages(void) int socknum; int lenBuf; int lenSend; - char buf[2048]; + int edLen; /* actual extra data length to use */ + char buf[MAX_EXTRADATA_LEN + 1024]; + char extraData[MAX_EXTRADATA_LEN + 1]; srand(time(NULL)); /* seed is good enough for our needs */ @@ -177,7 +191,19 @@ int sendMessages(void) socknum = i - (numMsgsToSend - numConnections); else socknum = rand() % numConnections; - lenBuf = sprintf(buf, "<167>Mar 1 01:00:00 172.20.245.8 tag msgnum:%8.8d:\n", msgNum); + if(extraDataLen == 0) { + lenBuf = sprintf(buf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%8.8d:\n", + msgPRI, msgNum); + } else { + if(bRandomizeExtraData) + edLen = ((long) rand() + extraDataLen) % extraDataLen + 1; + else + edLen = extraDataLen; + memset(extraData, 'X', edLen); + extraData[edLen] = '\0'; + lenBuf = sprintf(buf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%8.8d:%d:%s\n", + msgPRI, msgNum, edLen, extraData); + } lenSend = send(sockArray[socknum], buf, lenBuf, 0); if(lenSend != lenBuf) { printf("\r%5.5d\n", i); @@ -251,9 +277,7 @@ tcpSend(char *buf, int lenBuf) } -/* Run the test suite. This must be called with exactly one parameter, the - * name of the test suite. For details, see file header comment at the top - * of this file. +/* Run the test. * rgerhards, 2009-04-03 */ int main(int argc, char *argv[]) @@ -273,7 +297,7 @@ int main(int argc, char *argv[]) setvbuf(stdout, buf, _IONBF, 48); - while((opt = getopt(argc, argv, "t:p:c:m:i:")) != -1) { + while((opt = getopt(argc, argv, "t:p:c:m:i:P:d:r")) != -1) { switch (opt) { case 't': targetIP = optarg; break; @@ -285,6 +309,17 @@ int main(int argc, char *argv[]) break; case 'i': msgNum = atoi(optarg); break; + case 'P': msgPRI = optarg; + break; + case 'd': extraDataLen = atoi(optarg); + if(extraDataLen > MAX_EXTRADATA_LEN) { + fprintf(stderr, "-d max is %d!\n", + MAX_EXTRADATA_LEN); + exit(1); + } + break; + case 'r': bRandomizeExtraData = 1; + break; } } @@ -298,7 +333,6 @@ int main(int argc, char *argv[]) exit(1); } - //closeConnections(); printf("End of tcpflood Run\n"); exit(ret); -- cgit From 83c15bb0a004ee348228217861c0eab7c5573952 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 11 Mar 2010 12:36:21 +0100 Subject: added more tests to testbench and improved testing tools --- tests/tcpflood.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'tests/tcpflood.c') diff --git a/tests/tcpflood.c b/tests/tcpflood.c index fcfc30a7..0f9f21f2 100644 --- a/tests/tcpflood.c +++ b/tests/tcpflood.c @@ -14,6 +14,9 @@ * bytes as forth. Add -r to randomize the amount of extra * data included in the range 1..(value of -d). * -r randomize amount of extra data added (-d must be > 0) + * -f support for testing dynafiles. If given, include a dynafile ID + * in the range 0..(f-1) as the SECOND field, shifting all field values + * one field to the right. Zero (default) disables this functionality. * * Part of the testbench for rsyslog. * @@ -59,6 +62,7 @@ static char *targetIP = "127.0.0.1"; static char *msgPRI = "167"; static int targetPort = 13514; +static int dynFileIDs = 0; static int extraDataLen = 0; /* amount of extra data to add to message */ static int bRandomizeExtraData = 0; /* randomize amount of extra data added */ static int numMsgsToSend; /* number of messages to send */ @@ -177,6 +181,7 @@ int sendMessages(void) int lenBuf; int lenSend; int edLen; /* actual extra data length to use */ + char dynFileIDBuf[128] = ""; char buf[MAX_EXTRADATA_LEN + 1024]; char extraData[MAX_EXTRADATA_LEN + 1]; @@ -191,9 +196,12 @@ int sendMessages(void) socknum = i - (numMsgsToSend - numConnections); else socknum = rand() % numConnections; + if(dynFileIDs > 0) { + sprintf(dynFileIDBuf, "%d:", rand() % dynFileIDs); + } if(extraDataLen == 0) { - lenBuf = sprintf(buf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%8.8d:\n", - msgPRI, msgNum); + lenBuf = sprintf(buf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%s%8.8d:\n", + msgPRI, dynFileIDBuf, msgNum); } else { if(bRandomizeExtraData) edLen = ((long) rand() + extraDataLen) % extraDataLen + 1; @@ -201,8 +209,8 @@ int sendMessages(void) edLen = extraDataLen; memset(extraData, 'X', edLen); extraData[edLen] = '\0'; - lenBuf = sprintf(buf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%8.8d:%d:%s\n", - msgPRI, msgNum, edLen, extraData); + lenBuf = sprintf(buf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%s%8.8d:%d:%s\n", + msgPRI, dynFileIDBuf, msgNum, edLen, extraData); } lenSend = send(sockArray[socknum], buf, lenBuf, 0); if(lenSend != lenBuf) { @@ -297,7 +305,7 @@ int main(int argc, char *argv[]) setvbuf(stdout, buf, _IONBF, 48); - while((opt = getopt(argc, argv, "t:p:c:m:i:P:d:r")) != -1) { + while((opt = getopt(argc, argv, "f:t:p:c:m:i:P:d:r")) != -1) { switch (opt) { case 't': targetIP = optarg; break; @@ -320,6 +328,11 @@ int main(int argc, char *argv[]) break; case 'r': bRandomizeExtraData = 1; break; + case 'f': dynFileIDs = atoi(optarg); + break; + default: printf("invalid option '%c' or value missing - terminating...\n", opt); + exit (1); + break; } } -- cgit From 4cb3e80152ed4674ed370915f7c02889b5bfb6f3 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 16 Mar 2010 14:23:13 +0100 Subject: added new, complex testcase to testbench this is an excerpt from some of the more intensen manual tests I am doing, stripped down to be useful inside the testbench. --- tests/tcpflood.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'tests/tcpflood.c') diff --git a/tests/tcpflood.c b/tests/tcpflood.c index 0f9f21f2..0d819d1d 100644 --- a/tests/tcpflood.c +++ b/tests/tcpflood.c @@ -4,6 +4,7 @@ * Params * -t target address (default 127.0.0.1) * -p target port (default 13514) + * -n number of target ports (targets are in range -p..(-p+-n-1) * -c number of connections (default 1) * -m number of messages to send (connection is random) * -i initial message number (optional) @@ -62,6 +63,7 @@ static char *targetIP = "127.0.0.1"; static char *msgPRI = "167"; static int targetPort = 13514; +static int numTargetPorts = 1; static int dynFileIDs = 0; static int extraDataLen = 0; /* amount of extra data to add to message */ static int bRandomizeExtraData = 0; /* randomize amount of extra data added */ @@ -77,16 +79,25 @@ int openConn(int *fd) { int sock; struct sockaddr_in addr; + int port; int retries = 0; + int rnd; if((sock=socket(AF_INET, SOCK_STREAM, 0))==-1) { perror("socket()"); return(1); } + /* randomize port if required */ + if(numTargetPorts > 1) { + rnd = rand(); /* easier if we need value for debug messages ;) */ + port = targetPort + (rnd % numTargetPorts); + } else { + port = targetPort; + } memset((char *) &addr, 0, sizeof(addr)); addr.sin_family = AF_INET; - addr.sin_port = htons(targetPort); + addr.sin_port = htons(port); if(inet_aton(targetIP, &addr.sin_addr)==0) { fprintf(stderr, "inet_aton() failed\n"); return(1); @@ -185,10 +196,8 @@ int sendMessages(void) char buf[MAX_EXTRADATA_LEN + 1024]; char extraData[MAX_EXTRADATA_LEN + 1]; - srand(time(NULL)); /* seed is good enough for our needs */ - printf("Sending %d messages.\n", numMsgsToSend); - printf("\r%5.5d messages sent", 0); + printf("\r%8.8d messages sent", 0); for(i = 0 ; i < numMsgsToSend ; ++i) { if(i < numConnections) socknum = i; @@ -222,11 +231,11 @@ int sendMessages(void) return(1); } if(i % 100 == 0) { - printf("\r%5.5d", i); + printf("\r%8.8d", i); } ++msgNum; } - printf("\r%5.5d messages sent\n", i); + printf("\r%8.8d messages sent\n", i); return 0; } @@ -295,6 +304,8 @@ int main(int argc, char *argv[]) struct sigaction sigAct; static char buf[1024]; + srand(time(NULL)); /* seed is good enough for our needs */ + /* on Solaris, we do not HAVE MSG_NOSIGNAL, so for this reason * we block SIGPIPE (not an issue for this program) */ @@ -305,12 +316,14 @@ int main(int argc, char *argv[]) setvbuf(stdout, buf, _IONBF, 48); - while((opt = getopt(argc, argv, "f:t:p:c:m:i:P:d:r")) != -1) { + while((opt = getopt(argc, argv, "f:t:p:c:m:i:P:d:n:r")) != -1) { switch (opt) { case 't': targetIP = optarg; break; case 'p': targetPort = atoi(optarg); break; + case 'n': numTargetPorts = atoi(optarg); + break; case 'c': numConnections = atoi(optarg); break; case 'm': numMsgsToSend = atoi(optarg); -- cgit From 970383f2199e177453bc13a40c3ccf04aeb647e1 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 19 Mar 2010 12:20:58 +0100 Subject: slight improvement to testing tools --- tests/tcpflood.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'tests/tcpflood.c') diff --git a/tests/tcpflood.c b/tests/tcpflood.c index 0d819d1d..d4955447 100644 --- a/tests/tcpflood.c +++ b/tests/tcpflood.c @@ -71,6 +71,7 @@ static int numMsgsToSend; /* number of messages to send */ static int numConnections = 1; /* number of connections to create */ static int *sockArray; /* array of sockets to use */ static int msgNum = 0; /* initial message number to start with */ +static int bShowProgress = 1; /* show progress messages */ /* open a single tcp connection @@ -130,11 +131,13 @@ int openConnections(void) char msgBuf[128]; size_t lenMsg; - write(1, " open connections", sizeof(" open connections")-1); + if(bShowProgress) + write(1, " open connections", sizeof(" open connections")-1); sockArray = calloc(numConnections, sizeof(int)); for(i = 0 ; i < numConnections ; ++i) { if(i % 10 == 0) { - printf("\r%5.5d", i); + if(bShowProgress) + printf("\r%5.5d", i); //lenMsg = sprintf(msgBuf, "\r%5.5d", i); //write(1, msgBuf, lenMsg); } @@ -163,11 +166,14 @@ void closeConnections(void) char msgBuf[128]; size_t lenMsg; - write(1, " close connections", sizeof(" close connections")-1); + if(bShowProgress) + write(1, " close connections", sizeof(" close connections")-1); for(i = 0 ; i < numConnections ; ++i) { if(i % 10 == 0) { - lenMsg = sprintf(msgBuf, "\r%5.5d", i); - write(1, msgBuf, lenMsg); + if(bShowProgress) { + lenMsg = sprintf(msgBuf, "\r%5.5d", i); + write(1, msgBuf, lenMsg); + } } close(sockArray[i]); } @@ -197,7 +203,8 @@ int sendMessages(void) char extraData[MAX_EXTRADATA_LEN + 1]; printf("Sending %d messages.\n", numMsgsToSend); - printf("\r%8.8d messages sent", 0); + if(bShowProgress) + printf("\r%8.8d messages sent", 0); for(i = 0 ; i < numMsgsToSend ; ++i) { if(i < numConnections) socknum = i; @@ -231,7 +238,8 @@ int sendMessages(void) return(1); } if(i % 100 == 0) { - printf("\r%8.8d", i); + if(bShowProgress) + printf("\r%8.8d", i); } ++msgNum; } @@ -315,6 +323,9 @@ int main(int argc, char *argv[]) sigaction(SIGPIPE, &sigAct, NULL); setvbuf(stdout, buf, _IONBF, 48); + + if(!isatty(1)) + bShowProgress = 0; while((opt = getopt(argc, argv, "f:t:p:c:m:i:P:d:n:r")) != -1) { switch (opt) { -- cgit From 1ddb082cfa1ca6bb7b8c44ce760ccd4200e1f2f7 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 22 Mar 2010 14:06:05 +0100 Subject: added testcase showcasing problems when dynafile can not be opened note that so far no patch is provided. This has not yet been made part of "make check" --- tests/tcpflood.c | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) (limited to 'tests/tcpflood.c') diff --git a/tests/tcpflood.c b/tests/tcpflood.c index d4955447..2bb7ba2c 100644 --- a/tests/tcpflood.c +++ b/tests/tcpflood.c @@ -18,10 +18,12 @@ * -f support for testing dynafiles. If given, include a dynafile ID * in the range 0..(f-1) as the SECOND field, shifting all field values * one field to the right. Zero (default) disables this functionality. + * -M the message to be sent. Disables all message format options, as + * only that exact same message is sent. * * Part of the testbench for rsyslog. * - * Copyright 2009 Rainer Gerhards and Adiscon GmbH. + * Copyright 2009, 2010 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * @@ -72,6 +74,7 @@ static int numConnections = 1; /* number of connections to create */ static int *sockArray; /* array of sockets to use */ static int msgNum = 0; /* initial message number to start with */ static int bShowProgress = 1; /* show progress messages */ +static char *MsgToSend = NULL; /* if non-null, this is the actual message to send */ /* open a single tcp connection @@ -212,21 +215,26 @@ int sendMessages(void) socknum = i - (numMsgsToSend - numConnections); else socknum = rand() % numConnections; - if(dynFileIDs > 0) { - sprintf(dynFileIDBuf, "%d:", rand() % dynFileIDs); - } - if(extraDataLen == 0) { - lenBuf = sprintf(buf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%s%8.8d:\n", - msgPRI, dynFileIDBuf, msgNum); + if(MsgToSend == NULL) { + if(dynFileIDs > 0) { + sprintf(dynFileIDBuf, "%d:", rand() % dynFileIDs); + } + if(extraDataLen == 0) { + lenBuf = sprintf(buf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%s%8.8d:\n", + msgPRI, dynFileIDBuf, msgNum); + } else { + if(bRandomizeExtraData) + edLen = ((long) rand() + extraDataLen) % extraDataLen + 1; + else + edLen = extraDataLen; + memset(extraData, 'X', edLen); + extraData[edLen] = '\0'; + lenBuf = sprintf(buf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%s%8.8d:%d:%s\n", + msgPRI, dynFileIDBuf, msgNum, edLen, extraData); + } } else { - if(bRandomizeExtraData) - edLen = ((long) rand() + extraDataLen) % extraDataLen + 1; - else - edLen = extraDataLen; - memset(extraData, 'X', edLen); - extraData[edLen] = '\0'; - lenBuf = sprintf(buf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%s%8.8d:%d:%s\n", - msgPRI, dynFileIDBuf, msgNum, edLen, extraData); + /* use fixed message format from command line */ + lenBuf = sprintf(buf, "%s\n", MsgToSend); } lenSend = send(sockArray[socknum], buf, lenBuf, 0); if(lenSend != lenBuf) { @@ -327,7 +335,7 @@ int main(int argc, char *argv[]) if(!isatty(1)) bShowProgress = 0; - while((opt = getopt(argc, argv, "f:t:p:c:m:i:P:d:n:r")) != -1) { + while((opt = getopt(argc, argv, "f:t:p:c:m:i:P:d:n:M:r")) != -1) { switch (opt) { case 't': targetIP = optarg; break; @@ -354,6 +362,9 @@ int main(int argc, char *argv[]) break; case 'f': dynFileIDs = atoi(optarg); break; + case 'M': MsgToSend = optarg; +fprintf(stderr, "msg to send: '%s'\n", MsgToSend); + break; default: printf("invalid option '%c' or value missing - terminating...\n", opt); exit (1); break; -- cgit From 42d2c13072734a41114b502cf77f378a51cf3431 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 22 Mar 2010 14:37:36 +0100 Subject: cleanup of debug message in testbench --- tests/tcpflood.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tests/tcpflood.c') diff --git a/tests/tcpflood.c b/tests/tcpflood.c index 2bb7ba2c..32bf959d 100644 --- a/tests/tcpflood.c +++ b/tests/tcpflood.c @@ -363,7 +363,6 @@ int main(int argc, char *argv[]) case 'f': dynFileIDs = atoi(optarg); break; case 'M': MsgToSend = optarg; -fprintf(stderr, "msg to send: '%s'\n", MsgToSend); break; default: printf("invalid option '%c' or value missing - terminating...\n", opt); exit (1); -- cgit From 7e1060295a63242bc22394b6873de6e6db2b4765 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 25 Mar 2010 11:21:10 +0100 Subject: manytcp test tool must tell OS to provide enough file handles On some platforms, the default is too low to carry out all test cases --- tests/tcpflood.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'tests/tcpflood.c') diff --git a/tests/tcpflood.c b/tests/tcpflood.c index 32bf959d..259b84b3 100644 --- a/tests/tcpflood.c +++ b/tests/tcpflood.c @@ -370,6 +370,20 @@ int main(int argc, char *argv[]) } } + if(numConnections > 20) { + /* if we use many (whatever this means, 20 is randomly picked) + * connections, we need to make sure we have a high enough + * limit. -- rgerhards, 2010-03-25 + */ + struct rlimit maxFiles; + maxFiles.rlim_cur = numConnections + 20; + maxFiles.rlim_max = numConnections + 20; + if(setrlimit(RLIMIT_NOFILE, &maxFiles) < 0) { + perror("setrlimit to increase file handles failed"); + exit(1); + } + } + if(openConnections() != 0) { printf("error opening connections\n"); exit(1); -- cgit From b628ec633ebd8bdf2e1ddb168b7b63ea2c1bb87c Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 25 Mar 2010 17:21:36 +0100 Subject: added missing header --- tests/tcpflood.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tests/tcpflood.c') diff --git a/tests/tcpflood.c b/tests/tcpflood.c index 259b84b3..68c1c097 100644 --- a/tests/tcpflood.c +++ b/tests/tcpflood.c @@ -54,6 +54,7 @@ #include #include #include +#include #define EXIT_FAILURE 1 #define INVALID_SOCKET -1 -- cgit From 2cd132eebb84dbcffcf0c20b9354c14f797c29cd Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 7 Apr 2010 12:42:41 +0200 Subject: enhanced nettester tool so that it re-uses it's callers environment this enables us to work with the "usual" environment tweaks (for debugging and other purposes), without the need for any special handling in nettester itself --- tests/tcpflood.c | 142 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 109 insertions(+), 33 deletions(-) (limited to 'tests/tcpflood.c') diff --git a/tests/tcpflood.c b/tests/tcpflood.c index 68c1c097..e92d1308 100644 --- a/tests/tcpflood.c +++ b/tests/tcpflood.c @@ -20,6 +20,14 @@ * one field to the right. Zero (default) disables this functionality. * -M the message to be sent. Disables all message format options, as * only that exact same message is sent. + * -I read specified input file, do NOT generate own test data. The test + * completes when eof is reached. + * -B The specified file (-I) is binary. No data processing is done by + * tcpflood. If multiple connections are specified, data is read in + * chunks and spread across the connections without taking any record + * delemiters into account. + * -C when input from a file is read, this file is transmitted -C times + * (C like cycle, running out of meaningful option switches ;)) * * Part of the testbench for rsyslog. * @@ -76,6 +84,10 @@ static int *sockArray; /* array of sockets to use */ static int msgNum = 0; /* initial message number to start with */ static int bShowProgress = 1; /* show progress messages */ static char *MsgToSend = NULL; /* if non-null, this is the actual message to send */ +static int bBinaryFile = 0; /* is -I file binary */ +static char *dataFile = NULL; /* name of data file, if NULL, generate own data */ +static int numFileIterations = 1;/* how often is file data to be sent? */ +FILE *dataFP = NULL; /* file pointer for data file, if used */ /* open a single tcp connection @@ -167,8 +179,8 @@ int openConnections(void) void closeConnections(void) { int i; - char msgBuf[128]; size_t lenMsg; + char msgBuf[128]; if(bShowProgress) write(1, " close connections", sizeof(" close connections")-1); @@ -187,6 +199,62 @@ void closeConnections(void) } +/* generate the message to be sent according to program command line parameters. + * this has been moved to its own function as we now have various different ways + * of constructing test messages. -- rgerhards, 2010-03-31 + */ +static inline void +genMsg(char *buf, size_t maxBuf, int *pLenBuf) +{ + int edLen; /* actual extra data length to use */ + char extraData[MAX_EXTRADATA_LEN + 1]; + char dynFileIDBuf[128] = ""; + static int numMsgsGen = 0; + int done; + + if(dataFP != NULL) { + /* get message from file */ + do { + done = 1; + *pLenBuf = fread(buf, 1, 1024, dataFP); + if(feof(dataFP)) { + if(--numFileIterations > 0) { + rewind(dataFP); + done = 0; /* need new iteration */ + } else { + *pLenBuf = 0; + goto finalize_it; + } + } + } while(!done); /* Attention: do..while()! */ + } else if(MsgToSend == NULL) { + if(dynFileIDs > 0) { + snprintf(dynFileIDBuf, maxBuf, "%d:", rand() % dynFileIDs); + } + if(extraDataLen == 0) { + *pLenBuf = snprintf(buf, maxBuf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%s%8.8d:\n", + msgPRI, dynFileIDBuf, msgNum); + } else { + if(bRandomizeExtraData) + edLen = ((long) rand() + extraDataLen) % extraDataLen + 1; + else + edLen = extraDataLen; + memset(extraData, 'X', edLen); + extraData[edLen] = '\0'; + *pLenBuf = snprintf(buf, maxBuf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%s%8.8d:%d:%s\n", + msgPRI, dynFileIDBuf, msgNum, edLen, extraData); + } + } else { + /* use fixed message format from command line */ + *pLenBuf = snprintf(buf, maxBuf, "%s\n", MsgToSend); + } + + if(numMsgsGen++ >= numMsgsToSend) + *pLenBuf = 0; /* indicate end of run */ + +finalize_it: ; +} + /* send messages to the tcp connections we keep open. We use * a very basic format that helps identify the message * (via msgnum:: e.g. msgnum:00000001:). This format is suitable @@ -197,52 +265,42 @@ void closeConnections(void) */ int sendMessages(void) { - int i; + int i = 0; int socknum; int lenBuf; int lenSend; - int edLen; /* actual extra data length to use */ - char dynFileIDBuf[128] = ""; + char *statusText; char buf[MAX_EXTRADATA_LEN + 1024]; - char extraData[MAX_EXTRADATA_LEN + 1]; - printf("Sending %d messages.\n", numMsgsToSend); + if(dataFile == NULL) { + printf("Sending %d messages.\n", numMsgsToSend); + statusText = "messages"; + } else { + printf("Sending file '%s' %d times.\n", dataFile, numFileIterations); + statusText = "kb"; + } if(bShowProgress) - printf("\r%8.8d messages sent", 0); - for(i = 0 ; i < numMsgsToSend ; ++i) { + printf("\r%8.8d %s sent", 0, statusText); + while(1) { /* broken inside loop! */ if(i < numConnections) socknum = i; else if(i >= numMsgsToSend - numConnections) socknum = i - (numMsgsToSend - numConnections); - else - socknum = rand() % numConnections; - if(MsgToSend == NULL) { - if(dynFileIDs > 0) { - sprintf(dynFileIDBuf, "%d:", rand() % dynFileIDs); - } - if(extraDataLen == 0) { - lenBuf = sprintf(buf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%s%8.8d:\n", - msgPRI, dynFileIDBuf, msgNum); - } else { - if(bRandomizeExtraData) - edLen = ((long) rand() + extraDataLen) % extraDataLen + 1; - else - edLen = extraDataLen; - memset(extraData, 'X', edLen); - extraData[edLen] = '\0'; - lenBuf = sprintf(buf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%s%8.8d:%d:%s\n", - msgPRI, dynFileIDBuf, msgNum, edLen, extraData); - } - } else { - /* use fixed message format from command line */ - lenBuf = sprintf(buf, "%s\n", MsgToSend); + else { + int rnd = rand(); + //socknum = rand() % numConnections; + socknum = rnd % numConnections; } + genMsg(buf, sizeof(buf), &lenBuf); /* generate the message to send according to params */ + if(lenBuf == 0) + break; /* end of processing! */ lenSend = send(sockArray[socknum], buf, lenBuf, 0); if(lenSend != lenBuf) { printf("\r%5.5d\n", i); fflush(stdout); perror("send test data"); - printf("send() failed at socket %d, index %d, msgNum %d\n", socknum, i, msgNum); + printf("send() failed at socket %d, index %d, msgNum %d\n", + sockArray[socknum], i, msgNum); fflush(stderr); return(1); } @@ -251,8 +309,9 @@ int sendMessages(void) printf("\r%8.8d", i); } ++msgNum; + ++i; } - printf("\r%8.8d messages sent\n", i); + printf("\r%8.8d %s sent\n", i, statusText); return 0; } @@ -336,7 +395,7 @@ int main(int argc, char *argv[]) if(!isatty(1)) bShowProgress = 0; - while((opt = getopt(argc, argv, "f:t:p:c:m:i:P:d:n:M:r")) != -1) { + while((opt = getopt(argc, argv, "f:t:p:c:C:m:i:I:P:d:n:M:rB")) != -1) { switch (opt) { case 't': targetIP = optarg; break; @@ -346,6 +405,8 @@ int main(int argc, char *argv[]) break; case 'c': numConnections = atoi(optarg); break; + case 'C': numFileIterations = atoi(optarg); + break; case 'm': numMsgsToSend = atoi(optarg); break; case 'i': msgNum = atoi(optarg); @@ -365,6 +426,14 @@ int main(int argc, char *argv[]) break; case 'M': MsgToSend = optarg; break; + case 'I': dataFile = optarg; + /* in this mode, we do not know the num messages to send, so + * we set a (high) number to keep the code happy. + */ + numMsgsToSend = 1000000; + break; + case 'B': bBinaryFile = 1; + break; default: printf("invalid option '%c' or value missing - terminating...\n", opt); exit (1); break; @@ -385,6 +454,13 @@ int main(int argc, char *argv[]) } } + if(dataFile != NULL) { + if((dataFP = fopen(dataFile, "r")) == NULL) { + perror(dataFile); + exit(1); + } + } + if(openConnections() != 0) { printf("error opening connections\n"); exit(1); -- cgit