Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Time Flag For The Iperf Server Process #1684

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

manedurphy
Copy link
Contributor

@manedurphy manedurphy commented Apr 19, 2024

PLEASE NOTE the following text from the iperf3 license. Submitting a
pull request to the iperf3 repository constitutes "[making]
Enhancements available...publicly":

You are under no obligation whatsoever to provide any bug fixes, patches, or
upgrades to the features, functionality or performance of the source code
("Enhancements") to anyone; however, if you choose to make your Enhancements
available either publicly, or directly to Lawrence Berkeley National
Laboratory, without imposing a separate written license agreement for such
Enhancements, then you hereby grant the following license: a non-exclusive,
royalty-free perpetual license to install, use, modify, prepare derivative
works, incorporate into other computer software, distribute, and sublicense
such enhancements or derivative works thereof, in binary and source code form.

The complete iperf3 license is available in the LICENSE file in the
top directory of the iperf3 source tree.

  • Version of iperf3 (or development branch, such as master or
    3.1-STABLE) to which this pull request applies: master

  • Issues fixed (if any): Enable '-t X' option in server mode #354, Server-side limiting switches #615

  • Brief description of code changes (suitable for use as a commit message):
    These changes add the functionality as requested by the linked issues. Specifically, this functionality allows the server to determine the maximum duration of an iperf measurement. The implementation is similar to the --server-bitrate-limit flag, where the measurement is forcibly stopped when an interval has exceeded the server's configured bitrate. In this case, the measurement is forcibly stopped when the duration exceeds the server's configured time, which is the value of --server-time.

Example

From the dropdowns below, we can see that the server has enforced a measurement time of 3 seconds. The client attempts to run the measurement for 4 seconds. When the 3rd second is exceeded, the socket is forcibly closed.

server
./src/iperf3 -s --server-time 3
-----------------------------------------------------------
Server listening on 5201 (test #1)
-----------------------------------------------------------
Accepted connection from 127.0.0.1, port 44938
[  6] local 127.0.0.1 port 5201 connected to 127.0.0.1 port 44946
[ ID] Interval           Transfer     Bitrate
[  6]   0.00-1.00   sec  3.08 GBytes  26.5 Gbits/sec                  (omitted)
[  6]   1.00-2.00   sec  3.35 GBytes  28.8 Gbits/sec                  (omitted)
[  6]   2.00-3.00   sec  3.18 GBytes  27.3 Gbits/sec                  (omitted)
[  6]   0.00-1.00   sec  3.20 GBytes  27.5 Gbits/sec
[  6]   1.00-2.00   sec  3.34 GBytes  28.7 Gbits/sec
iperf3: error - select failed: Bad file descriptor
-----------------------------------------------------------
Server listening on 5201 (test #2)
-----------------------------------------------------------
client
./src/iperf3 --client 127.0.0.1 --port 5201 -t 4 --omit 3
Connecting to host 127.0.0.1, port 5201
[  5] local 127.0.0.1 port 44946 connected to 127.0.0.1 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  3.08 GBytes  26.5 Gbits/sec    0   1.06 MBytes       (omitted)
[  5]   1.00-2.00   sec  3.35 GBytes  28.8 Gbits/sec    0   1.06 MBytes       (omitted)
[  5]   2.00-3.00   sec  3.15 GBytes  27.1 Gbits/sec    0   1.06 MBytes       (omitted)
[  5]   0.00-1.00   sec  3.20 GBytes  27.5 Gbits/sec    0   1.12 MBytes
[  5]   1.00-2.00   sec  3.34 GBytes  28.7 Gbits/sec    0   1.25 MBytes
[  5]   1.00-2.00   sec  3.34 GBytes  28.7 Gbits/sec    0   1.25 MBytes
iperf3: error - control socket has closed unexpectedly
client_json
{
        "start":        {
                "connected":    [{
                                "socket":       5,
                                "local_host":   "127.0.0.1",
                                "local_port":   53314,
                                "remote_host":  "127.0.0.1",
                                "remote_port":  5201
                        }],
                "version":      "iperf 3.16+",
                "system_info":  "Linux windows-nexus 5.15.146.1-microsoft-standard-WSL2 #1 SMP Thu Jan 11 04:09:03 UTC 2024 x86_64",
                "timestamp":    {
                        "time": "Thu, 18 Apr 2024 04:38:09 GMT",
                        "timesecs":     1713415089
                },
                "connecting_to":        {
                        "host": "127.0.0.1",
                        "port": 5201
                },
                "cookie":       "wtuhwwetnqayseccmqno6dutzjf3zly3op5p",
                "tcp_mss_default":      32768,
                "target_bitrate":       0,
                "fq_rate":      0,
                "sock_bufsize": 0,
                "sndbuf_actual":        16384,
                "rcvbuf_actual":        131072,
                "test_start":   {
                        "protocol":     "TCP",
                        "num_streams":  1,
                        "blksize":      131072,
                        "omit": 3,
                        "duration":     4,
                        "bytes":        0,
                        "blocks":       0,
                        "reverse":      0,
                        "tos":  0,
                        "target_bitrate":       0,
                        "bidir":        0,
                        "fqrate":       0,
                        "interval":     1
                }
        },
        "intervals":    [{
                        "streams":      [{
                                        "socket":       5,
                                        "start":        0,
                                        "end":  1.001066,
                                        "seconds":      1.0010659694671631,
                                        "bytes":        3578265600,
                                        "bits_per_second":      28595642717.968742,
                                        "retransmits":  0,
                                        "snd_cwnd":     2029973,
                                        "snd_wnd":      3145088,
                                        "rtt":  51,
                                        "rttvar":       5,
                                        "pmtu": 65535,
                                        "omitted":      true,
                                        "sender":       true
                                }],
                        "sum":  {
                                "start":        0,
                                "end":  1.001066,
                                "seconds":      1.0010659694671631,
                                "bytes":        3578265600,
                                "bits_per_second":      28595642717.968742,
                                "retransmits":  0,
                                "omitted":      true,
                                "sender":       true
                        }
                }, {
                        "streams":      [{
                                        "socket":       5,
                                        "start":        1.001066,
                                        "end":  2.001046,
                                        "seconds":      0.99997997283935547,
                                        "bytes":        3452698624,
                                        "bits_per_second":      27622142185.078888,
                                        "retransmits":  0,
                                        "snd_cwnd":     2029973,
                                        "snd_wnd":      3145088,
                                        "rtt":  88,
                                        "rttvar":       67,
                                        "pmtu": 65535,
                                        "omitted":      true,
                                        "sender":       true
                                }],
                        "sum":  {
                                "start":        1.001066,
                                "end":  2.001046,
                                "seconds":      0.99997997283935547,
                                "bytes":        3452698624,
                                "bits_per_second":      27622142185.078888,
                                "retransmits":  0,
                                "omitted":      true,
                                "sender":       true
                        }
                }, {
                        "streams":      [{
                                        "socket":       5,
                                        "start":        2.001046,
                                        "end":  3.001049,
                                        "seconds":      1.0000029802322388,
                                        "bytes":        3500015616,
                                        "bits_per_second":      28000041481.373692,
                                        "retransmits":  0,
                                        "snd_cwnd":     2029973,
                                        "snd_wnd":      3145088,
                                        "rtt":  63,
                                        "rttvar":       17,
                                        "pmtu": 65535,
                                        "omitted":      true,
                                        "sender":       true
                                }],
                        "sum":  {
                                "start":        2.001046,
                                "end":  3.001049,
                                "seconds":      1.0000029802322388,
                                "bytes":        3500015616,
                                "bits_per_second":      28000041481.373692,
                                "retransmits":  0,
                                "omitted":      true,
                                "sender":       true
                        }
                }, {
                        "streams":      [{
                                        "socket":       5,
                                        "start":        0.012641,
                                        "end":  0.988366,
                                        "seconds":      1.0010069608688354,
                                        "bytes":        3449421824,
                                        "bits_per_second":      27567615082.364941,
                                        "retransmits":  0,
                                        "snd_cwnd":     2029973,
                                        "snd_wnd":      3145088,
                                        "rtt":  58,
                                        "rttvar":       7,
                                        "pmtu": 65535,
                                        "omitted":      false,
                                        "sender":       true
                                }],
                        "sum":  {
                                "start":        0.012641,
                                "end":  0.988366,
                                "seconds":      1.0010069608688354,
                                "bytes":        3449421824,
                                "bits_per_second":      27567615082.364941,
                                "retransmits":  0,
                                "omitted":      false,
                                "sender":       true
                        }
                }, {
                        "streams":      [{
                                        "socket":       5,
                                        "start":        0.988366,
                                        "end":  1.988398,
                                        "seconds":      1.0000319480895996,
                                        "bytes":        3414818816,
                                        "bits_per_second":      27317677780.382618,
                                        "retransmits":  0,
                                        "snd_cwnd":     2029973,
                                        "snd_wnd":      3145088,
                                        "rtt":  61,
                                        "rttvar":       9,
                                        "pmtu": 65535,
                                        "omitted":      false,
                                        "sender":       true
                                }],
                        "sum":  {
                                "start":        0.988366,
                                "end":  1.988398,
                                "seconds":      1.0000319480895996,
                                "bytes":        3414818816,
                                "bits_per_second":      27317677780.382618,
                                "retransmits":  0,
                                "omitted":      false,
                                "sender":       true
                        }
                }, {
                        "streams":      [{
                                        "socket":       5,
                                        "start":        0.988366,
                                        "end":  1.988398,
                                        "seconds":      1.0000319480895996,
                                        "bytes":        3414818816,
                                        "bits_per_second":      27317677780.382618,
                                        "retransmits":  0,
                                        "snd_cwnd":     2029973,
                                        "snd_wnd":      3145088,
                                        "rtt":  61,
                                        "rttvar":       9,
                                        "pmtu": 65535,
                                        "omitted":      false,
                                        "sender":       true
                                }],
                        "sum":  {
                                "start":        0.988366,
                                "end":  1.988398,
                                "seconds":      1.0000319480895996,
                                "bytes":        3414818816,
                                "bits_per_second":      27317677780.382618,
                                "retransmits":  0,
                                "omitted":      false,
                                "sender":       true
                        }
                }],
        "end":  {
        },
        "error":        "control socket has closed unexpectedly"
}

Implementation Details

With this implementation, the server overrides the value of test->duration with the value that was passed in via the --server-time flag. We can see from the drop downs that the client's experience is similar to when the bitrate limit is exceeded with the error: iperf3: error - control socket has closed unexpectedly. However, the server side is less friendly, with an error of iperf3: error - select failed: Bad file descriptor. I can already envision myself encountering this error and not knowing why I am getting it, as well as forgetting that I had set the --server-time flag to begin with.

Another thing to note is that nothing is stopping the user from setting a high value for --omit. Given that this feature is meant to protect the server, is it reasonable to include a --server-omit option to enforce a maximum value?

Update (04/18/2024)

Since the first commit, I've introduced a solution for the error iperf3: error - select failed: Bad file descriptor which provides a more friendly experience. Let's consider the scenario where the --server-time flag has been set on the server to a value of 3:

  1. The client connects to the server
  2. The server accepts the connection, receives the client's cookie, and sends the client that value of 3 for the server time
  3. When the client's timers are created, it compares its duration to the server's duration of 3. If the client's duration is greater than the server's, then the server's value is selected for the timer.
  4. The same process occurs when the server's timers are created.

The JSON output also has a new field which specifies the server's value for duration: server_duration

client_json
{
        "start":        {
                "connected":    [{
                                "socket":       5,
                                "local_host":   "127.0.0.1",
                                "local_port":   36906,
                                "remote_host":  "127.0.0.1",
                                "remote_port":  5201
                        }],
                "version":      "iperf 3.16+",
                "system_info":  "Linux windows-nexus 5.15.146.1-microsoft-standard-WSL2 #1 SMP Thu Jan 11 04:09:03 UTC 2024 x86_64",
                "timestamp":    {
                        "time": "Mon, 22 Apr 2024 02:23:53 GMT",
                        "timesecs":     1713752633
                },
                "connecting_to":        {
                        "host": "127.0.0.1",
                        "port": 5201
                },
                "cookie":       "m4n5p26auofjvyda2x2ba56kexzsly7mz5k7",
                "tcp_mss_default":      32768,
                "target_bitrate":       5000000,
                "fq_rate":      0,
                "sock_bufsize": 0,
                "sndbuf_actual":        16384,
                "rcvbuf_actual":        131072,
                "test_start":   {
                        "protocol":     "TCP",
                        "num_streams":  1,
                        "blksize":      131072,
                        "omit": 0,
                        "duration":     6,
                        "server_duration":      3,
                        "bytes":        0,
                        "blocks":       0,
                        "reverse":      0,
                        "tos":  0,
                        "target_bitrate":       5000000,
                        "bidir":        0,
                        "fqrate":       0,
                        "interval":     1
                }
        },
        "intervals":    [{
                        "streams":      [{
                                        "socket":       5,
                                        "start":        0,
                                        "end":  1.000087,
                                        "seconds":      1.0000870227813721,
                                        "bytes":        655360,
                                        "bits_per_second":      5242423.78970069,
                                        "retransmits":  0,
                                        "snd_cwnd":     654830,
                                        "snd_wnd":      1375232,
                                        "rtt":  38,
                                        "rttvar":       24,
                                        "pmtu": 65535,
                                        "omitted":      false,
                                        "sender":       true
                                }],
                        "sum":  {
                                "start":        0,
                                "end":  1.000087,
                                "seconds":      1.0000870227813721,
                                "bytes":        655360,
                                "bits_per_second":      5242423.78970069,
                                "retransmits":  0,
                                "omitted":      false,
                                "sender":       true
                        }
                }, {
                        "streams":      [{
                                        "socket":       5,
                                        "start":        1.000087,
                                        "end":  2.000084,
                                        "seconds":      0.99999701976776123,
                                        "bytes":        655360,
                                        "bits_per_second":      5242895.6250465661,
                                        "retransmits":  0,
                                        "snd_cwnd":     654830,
                                        "snd_wnd":      2684928,
                                        "rtt":  45,
                                        "rttvar":       22,
                                        "pmtu": 65535,
                                        "omitted":      false,
                                        "sender":       true
                                }],
                        "sum":  {
                                "start":        1.000087,
                                "end":  2.000084,
                                "seconds":      0.99999701976776123,
                                "bytes":        655360,
                                "bits_per_second":      5242895.6250465661,
                                "retransmits":  0,
                                "omitted":      false,
                                "sender":       true
                        }
                }, {
                        "streams":      [{
                                        "socket":       5,
                                        "start":        2.000084,
                                        "end":  3.000148,
                                        "seconds":      1.0000640153884888,
                                        "bytes":        655360,
                                        "bits_per_second":      5242544.39648379,
                                        "retransmits":  0,
                                        "snd_cwnd":     654830,
                                        "snd_wnd":      3112448,
                                        "rtt":  62,
                                        "rttvar":       44,
                                        "pmtu": 65535,
                                        "omitted":      false,
                                        "sender":       true
                                }],
                        "sum":  {
                                "start":        2.000084,
                                "end":  3.000148,
                                "seconds":      1.0000640153884888,
                                "bytes":        655360,
                                "bits_per_second":      5242544.39648379,
                                "retransmits":  0,
                                "omitted":      false,
                                "sender":       true
                        }
                }],
        "end":  {
                "streams":      [{
                                "sender":       {
                                        "socket":       5,
                                        "start":        0,
                                        "end":  3.000148,
                                        "seconds":      3.000148,
                                        "bytes":        1966080,
                                        "bits_per_second":      5242621.36401271,
                                        "retransmits":  0,
                                        "max_snd_cwnd": 654830,
                                        "max_snd_wnd":  3112448,
                                        "max_rtt":      62,
                                        "min_rtt":      38,
                                        "mean_rtt":     48,
                                        "sender":       true
                                },
                                "receiver":     {
                                        "socket":       5,
                                        "start":        0,
                                        "end":  3.000258,
                                        "seconds":      3.000148,
                                        "bytes":        1966080,
                                        "bits_per_second":      5242429.1510930061,
                                        "sender":       true
                                }
                        }],
                "sum_sent":     {
                        "start":        0,
                        "end":  3.000148,
                        "seconds":      3.000148,
                        "bytes":        1966080,
                        "bits_per_second":      5242621.36401271,
                        "retransmits":  0,
                        "sender":       true
                },
                "sum_received": {
                        "start":        0,
                        "end":  3.000258,
                        "seconds":      3.000258,
                        "bytes":        1966080,
                        "bits_per_second":      5242429.1510930061,
                        "sender":       true
                },
                "cpu_utilization_percent":      {
                        "host_total":   100.87966904530634,
                        "host_user":    100.8797023673657,
                        "host_system":  0,
                        "remote_total": 0.037496475331318856,
                        "remote_user":  0.037496475331318856,
                        "remote_system":        0
                },
                "sender_tcp_congestion":        "cubic",
                "receiver_tcp_congestion":      "cubic"
        }
}

Update (06/05/2024)

A valid question was brought up by @TheRealDJ: What happens when the server has this feature but the client doesn't?. With the current implementation, there is no backwards compatability. Further discussions will need to be had in order to handle this case properly.

@manedurphy manedurphy marked this pull request as draft April 19, 2024 00:16
@manedurphy manedurphy marked this pull request as ready for review April 19, 2024 00:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant