summaryrefslogtreecommitdiffstats
path: root/tests/tcpflood.c
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2010-08-11 11:49:32 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2010-08-11 11:49:32 +0200
commit32e715929f5d946d7244db3bc0595842dd293dd9 (patch)
tree2a154cd6984690e91569feebcd6924efa0eb91b7 /tests/tcpflood.c
parent89f7dddf36d57c9261464560e3b2c0fb8ea88fd2 (diff)
parentc664adfa1683763ae503f2da9e8d4d528d6634d1 (diff)
downloadrsyslog-32e715929f5d946d7244db3bc0595842dd293dd9.tar.gz
rsyslog-32e715929f5d946d7244db3bc0595842dd293dd9.tar.xz
rsyslog-32e715929f5d946d7244db3bc0595842dd293dd9.zip
Merge branch 'v4-stable-imptcp' into tmp
Conflicts: Makefile.am configure.ac runtime/rsyslog.h tests/Makefile.am
Diffstat (limited to 'tests/tcpflood.c')
-rw-r--r--tests/tcpflood.c95
1 files changed, 37 insertions, 58 deletions
diff --git a/tests/tcpflood.c b/tests/tcpflood.c
index e92d1308..2d8be10f 100644
--- a/tests/tcpflood.c
+++ b/tests/tcpflood.c
@@ -28,6 +28,8 @@
* 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 ;))
+ * -D randomly drop and re-establish connections. Useful for stress-testing
+ * the TCP receiver.
*
* Part of the testbench for rsyslog.
*
@@ -83,11 +85,13 @@ 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 int bRandConnDrop = 0; /* randomly drop connections? */
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 */
+static long nConnDrops = 0; /* counter: number of time connection was dropped (-D option) */
/* open a single tcp connection
@@ -154,8 +158,6 @@ int openConnections(void)
if(i % 10 == 0) {
if(bShowProgress)
printf("\r%5.5d", i);
- //lenMsg = sprintf(msgBuf, "\r%5.5d", i);
- //write(1, msgBuf, lenMsg);
}
if(openConn(&(sockArray[i])) != 0) {
printf("error in trying to open connection i=%d\n", i);
@@ -180,6 +182,7 @@ void closeConnections(void)
{
int i;
size_t lenMsg;
+ struct linger ling;
char msgBuf[128];
if(bShowProgress)
@@ -191,7 +194,15 @@ void closeConnections(void)
write(1, msgBuf, lenMsg);
}
}
- close(sockArray[i]);
+ if(sockArray[i] != -1) {
+ /* we try to not overrun the receiver by trying to flush buffers
+ * *during* close(). -- rgerhards, 2010-08-10
+ */
+ ling.l_onoff = 1;
+ ling.l_linger = 1;
+ setsockopt(sockArray[i], SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));
+ close(sockArray[i]);
+ }
}
lenMsg = sprintf(msgBuf, "\r%5.5d close connections\n", i);
write(1, msgBuf, lenMsg);
@@ -288,12 +299,18 @@ int sendMessages(void)
socknum = i - (numMsgsToSend - numConnections);
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! */
+ if(sockArray[socknum] == -1) {
+ /* connection was dropped, need to re-establish */
+ if(openConn(&(sockArray[socknum])) != 0) {
+ printf("error in trying to re-open connection %d\n", socknum);
+ exit(1);
+ }
+ }
lenSend = send(sockArray[socknum], buf, lenBuf, 0);
if(lenSend != lenBuf) {
printf("\r%5.5d\n", i);
@@ -308,6 +325,16 @@ int sendMessages(void)
if(bShowProgress)
printf("\r%8.8d", i);
}
+ if(bRandConnDrop) {
+ /* if we need to randomly drop connections, see if we
+ * are a victim
+ */
+ if(rand() > (int) (RAND_MAX * 0.95)) {
+ ++nConnDrops;
+ close(sockArray[socknum]);
+ sockArray[socknum] = -1;
+ }
+ }
++msgNum;
++i;
}
@@ -317,59 +344,6 @@ int sendMessages(void)
}
-/* send a message via TCP
- * We open the connection on the initial send, and never close it
- * (let the OS do that). If a conneciton breaks, we do NOT try to
- * recover, so all test after that one will fail (and the test
- * driver probably hang. returns 0 if ok, something else otherwise.
- * We use traditional framing '\n' at EOR for this tester. It may be
- * worth considering additional framing modes.
- * rgerhards, 2009-04-08
- */
-int
-tcpSend(char *buf, int lenBuf)
-{
- static int sock = INVALID_SOCKET;
- struct sockaddr_in addr;
-
- if(sock == INVALID_SOCKET) {
- /* first time, need to connect to target */
- if((sock=socket(AF_INET, SOCK_STREAM, 0))==-1) {
- perror("socket()");
- return(1);
- }
-
- memset((char *) &addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(13514);
- if(inet_aton("127.0.0.1", &addr.sin_addr)==0) {
- fprintf(stderr, "inet_aton() failed\n");
- return(1);
- }
- if(connect(sock, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
- fprintf(stderr, "connect() failed\n");
- return(1);
- }
- }
-
- /* send test data */
- if(send(sock, buf, lenBuf, 0) != lenBuf) {
- perror("send test data");
- fprintf(stderr, "send() failed\n");
- return(1);
- }
-
- /* send record terminator */
- if(send(sock, "\n", 1, 0) != 1) {
- perror("send record terminator");
- fprintf(stderr, "send() failed\n");
- return(1);
- }
-
- return 0;
-}
-
-
/* Run the test.
* rgerhards, 2009-04-03
*/
@@ -395,7 +369,7 @@ int main(int argc, char *argv[])
if(!isatty(1))
bShowProgress = 0;
- while((opt = getopt(argc, argv, "f:t:p:c:C:m:i:I:P:d:n:M:rB")) != -1) {
+ while((opt = getopt(argc, argv, "f:t:p:c:C:m:i:I:P:d:Dn:M:rB")) != -1) {
switch (opt) {
case 't': targetIP = optarg;
break;
@@ -420,6 +394,8 @@ int main(int argc, char *argv[])
exit(1);
}
break;
+ case 'D': bRandConnDrop = 1;
+ break;
case 'r': bRandomizeExtraData = 1;
break;
case 'f': dynFileIDs = atoi(optarg);
@@ -471,7 +447,10 @@ int main(int argc, char *argv[])
exit(1);
}
+ if(nConnDrops > 0)
+ printf("-D option initiated %ld connection closures\n", nConnDrops);
printf("End of tcpflood Run\n");
+ closeConnections(); /* this is important so that we do not finish too early! */
exit(ret);
}