iperf icon indicating copy to clipboard operation
iperf copied to clipboard

Idle TCP connection hangs / DoSes the server

Open kathampy opened this issue 6 years ago • 8 comments

Context

  • Version of iperf3: 3.6

  • Hardware: MacBook Pro (15-inch, 2017)

  • Operating system (and distribution, if any): macOS Mojave Version 10.14 Beta (18A384a)

Bug Report

If I Telnet to the iperf3 server and leave the connection idle, the server is rendered unusable. Even if I send gibberish over the socket, it doesn't terminate the connection.

  • Expected Behavior Server should timeout and terminate empty TCP connections. Server should still accept new client tests while empty TCP connections are open. Server should instantly terminate TCP connections with invalid client protocols.

  • Actual Behavior Empty TCP connections hang the server. New clients can connect, but tests do not begin while empty TCP connections are open. TCP connections with invalid client protocols are not terminated.

  • Steps to Reproduce Telnet to an iperf3 server, and then attempt to run a test.

  • Possible Solution Detect and handle the above cases.

kathampy avatar Sep 07 '18 07:09 kathampy

This is one of a number of cases where the original design of iperf3 assumed that a single entity has control of both the client and server sides of a connection. For example, iperf3, on its own, would probably not be a good solution for a public-facing Internet bandwidth testing service...it needs some other mechanisms to handle situations like this. Within the perfSONAR world, which was the original use case for iperf3, those other mechanisms are implemented by pScheduler (and before that bwctl).

bmah888 avatar Sep 28 '18 17:09 bmah888

Using pScheduler seems excessive. Such a concept patch would be sufficient:

--- a/iperf/src/iperf_server_api.c
+++ b/iperf/src/iperf_server_api.c
@@ -118,6 +118,14 @@ iperf_accept(struct iperf_test *test)
     if (test->ctrl_sck == -1) {
         /* Server free, accept new client */
         test->ctrl_sck = s;
+
+       struct timeval timeout;
+       timeout.tv_sec = 10;
+       timeout.tv_usec = 0;
+
+       setsockopt (s, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout));
+       setsockopt (s, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout));
+
         if (Nread(test->ctrl_sck, test->cookie, COOKIE_SIZE, Ptcp) < 0) {
             i_errno = IERECVCOOKIE;
             return -1;

I'm not a practicing C-programmer, so I didn't use result checking: probably someone will do it better. It would also be good to make the timeout configurable. And incident should be logged (for using in fail2ban for example).

asy972 avatar Aug 15 '19 13:08 asy972

Has this fix suggested by asy972 been merged to iperf3 version , or has it been verified if it works fine. Please update.

LO764640 avatar Jan 31 '20 06:01 LO764640

or has it been verified if it works fine

I applied this patch to iperf3-3.7-alt2 and It's been working for me since then time

asy972 avatar Jul 22 '20 07:07 asy972

is fixed in 3.15? https://downloads.es.net/pub/iperf/esnet-secadv-2023-0002.txt.asc

asy972 avatar Oct 28 '23 20:10 asy972

is fixed in 3.15?

@asy972, I believe that the issue was fixed by PR #1282, using socket's TCP_USER_TIMEOUT option. Timeout is set using --snd-timeout and --rcv-timeout.

davidBar-On avatar Oct 29 '23 07:10 davidBar-On

No. I tested it now. --snd-timeout isn't help. Version 3.14 remained susceptible for this DoS but 3.15 canceled arbitrary connection without my patch.

asy972 avatar Oct 30 '23 08:10 asy972

No. I tested it now. --snd-timeout isn't help. Version 3.14 remained susceptible for this DoS but 3.15 canceled arbitrary connection without my patch.

Sorry for wrong answer. PR #1282 only handled waiting for TCP acks timeout, but not waiting for input (e.g. for the cookie). The fix in 3.15 is probably as described in this document from 3.15 release notes.

davidBar-On avatar Oct 31 '23 08:10 davidBar-On