From 5050249a1ea69ed6ac6b953a7bd722a71b09f9f7 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 27 Jul 2023 18:15:07 +0200 Subject: [PATCH] tcpflood bugfix: TCP sending was not implemented properly Note: tcpflood is a testbench tool. This bug could lead to testbench false positives. No way it can affect production deployments. The tcpflood tool did improperly assume that a TCP sendto() call would send messages of any size in a single shot. This is not the case. It has now been corrected to proper behavior. As a side-activity, some int variables which acutally needed to be size_t have been fixed as well. --- tests/tcpflood.c | 52 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/tests/tcpflood.c b/tests/tcpflood.c index 7dce5c99a..ea91b4623 100644 --- a/tests/tcpflood.c +++ b/tests/tcpflood.c @@ -266,7 +266,7 @@ static enum { TP_UDP, TP_TCP, TP_TLS, TP_RELP_PLAIN, TP_RELP_TLS } transport = T /* forward definitions */ static void initTLSSess(int); -static int sendTLS(int i, char *buf, int lenBuf); +static int sendTLS(int i, char *buf, size_t lenBuf); static void closeTLSSess(int __attribute__((unused)) i); #ifdef ENABLE_RELP @@ -579,7 +579,7 @@ void closeConnections(void) * of constructing test messages. -- rgerhards, 2010-03-31 */ static void -genMsg(char *buf, size_t maxBuf, int *pLenBuf, struct instdata *inst) +genMsg(char *buf, size_t maxBuf, size_t *pLenBuf, struct instdata *inst) { int edLen; /* actual extra data length to use */ char extraData[MAX_EXTRADATA_LEN + 1]; @@ -650,7 +650,7 @@ genMsg(char *buf, size_t maxBuf, int *pLenBuf, struct instdata *inst) *pLenBuf = snprintf(buf, maxBuf, "%s%c", MsgToSend, frameDelim); } if (octateCountFramed == 1) { - snprintf(payloadLen, sizeof(payloadLen), "%d ", *pLenBuf); + snprintf(payloadLen, sizeof(payloadLen), "%zd ", *pLenBuf); payloadStringLen = strlen(payloadLen); memmove(buf + payloadStringLen, buf, *pLenBuf); memcpy(buf, payloadLen, payloadStringLen); @@ -661,6 +661,29 @@ genMsg(char *buf, size_t maxBuf, int *pLenBuf, struct instdata *inst) finalize_it: /*EMPTY to keep the compiler happy */; } + +static int +sendPlainTCP(int socknum, char *buf, size_t lenBuf, int *ret_errno) +{ + size_t lenSent; + int r, err; + + lenSent = 0; + while(lenSent != lenBuf) { + r = send(sockArray[socknum], buf, lenBuf, 0); + if(r > 0) { + lenSent += r; + } else { + err = errno; + goto finalize_it; + } + } + +finalize_it: + return lenSent; +} + + /* 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 @@ -673,8 +696,8 @@ int sendMessages(struct instdata *inst) { unsigned i = 0; int socknum; - int lenBuf; - int lenSend = 0; + size_t lenBuf; + size_t lenSend = 0; char *statusText = ""; char buf[MAX_EXTRADATA_LEN + 1024]; char sendBuf[MAX_SENDBUF]; @@ -722,8 +745,7 @@ int sendMessages(struct instdata *inst) exit(1); } } - lenSend = send(sockArray[socknum], buf, lenBuf, 0); - error_number = errno; + lenSend = sendPlainTCP(socknum, buf, lenBuf, &error_number); } else if(transport == TP_UDP) { lenSend = sendto(udpsock, buf, lenBuf, 0, &udpRcvr, sizeof(udpRcvr)); error_number = errno; @@ -771,8 +793,10 @@ int sendMessages(struct instdata *inst) printf("\r%5.5u\n", i); fflush(stdout); test_rs_strerror_r(error_number, errStr, sizeof(errStr)); - printf("send() failed \"%s\" at socket %d, index %u, msgNum %lld\n", - errStr, sockArray[socknum], i, inst->numSent); + printf("send() failed \"%s\" at socket %d, index %u, msgNum %lld, " + "lenSend %zd, lenBuf %zd\n", + errStr, sockArray[socknum], i, inst->numSent, lenSend, + lenBuf); fflush(stderr); return(1); @@ -792,7 +816,7 @@ int sendMessages(struct instdata *inst) lenSend = sendTLS(socknum, sendBuf, offsSendBuf); if(lenSend != offsSendBuf) { fprintf(stderr, "tcpflood: error in send function causes potential " - "data loss lenSend %d, offsSendBuf %d\n", + "data loss lenSend %zd, offsSendBuf %d\n", lenSend, offsSendBuf); } offsSendBuf = 0; @@ -1375,9 +1399,9 @@ initTLSSess(int i) static int -sendTLS(int i, char *buf, int lenBuf) +sendTLS(int i, char *buf, size_t lenBuf) { - int lenSent; + size_t lenSent; int r, err; lenSent = 0; @@ -1525,7 +1549,7 @@ initTLSSess(int i) static int -sendTLS(int i, char *buf, int lenBuf) +sendTLS(int i, char *buf, size_t lenBuf) { int lenSent; int r; @@ -1552,7 +1576,7 @@ static void initTLS(void) {} static void exitTLS(void) {} static void initTLSSess(int __attribute__((unused)) i) {} static int sendTLS(int __attribute__((unused)) i, char __attribute__((unused)) *buf, - int __attribute__((unused)) lenBuf) { return 0; } + size_t __attribute__((unused)) lenBuf) { return 0; } static void closeTLSSess(int __attribute__((unused)) i) {} # endif