From 6882134e9c697ec1ae3ff2dd4e70db93e216fc33 Mon Sep 17 00:00:00 2001 From: David Bar-On Date: Sat, 16 May 2020 10:57:18 +0300 Subject: [PATCH 01/10] temporary changes to undef congestion control --- configure | 4 +++- src/tcp_info.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 6ad79b056..6424fb937 100755 --- a/configure +++ b/configure @@ -12983,7 +12983,9 @@ fi $as_echo "$iperf3_cv_header_tcp_congestion" >&6; } if test "x$iperf3_cv_header_tcp_congestion" = "xyes"; then -$as_echo "#define HAVE_TCP_CONGESTION 1" >>confdefs.h +# DBO >>> $as_echo "#define HAVE_TCP_CONGESTION 1" >>confdefs.h +$as_echo "#undef HAVE_TCP_CONGESTION 1" >>confdefs.h +# <<< DBO */ fi diff --git a/src/tcp_info.c b/src/tcp_info.c index d63e5b424..06c253ac7 100644 --- a/src/tcp_info.c +++ b/src/tcp_info.c @@ -95,7 +95,7 @@ void save_tcpinfo(struct iperf_stream *sp, struct iperf_interval_results *irp) { #if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)) && \ - defined(TCP_INFO) + defined(TCP_INFO)/*DBO >>> */ && 0 /*<<socket, IPPROTO_TCP, TCP_INFO, (void *)&irp->tcpInfo, &tcp_info_length) < 0) From a5b2c1a6d25fcbbae50c63d280e65db375f0e57d Mon Sep 17 00:00:00 2001 From: David Bar-On Date: Wed, 3 Feb 2021 10:35:30 +0200 Subject: [PATCH 02/10] issue-1107 add support for Do-Not_Fragment IP flag --- configure | 4 +--- src/iperf.h | 1 + src/iperf_api.c | 36 ++++++++++++++++++++++++++++++++++++ src/iperf_api.h | 4 ++++ src/iperf_error.c | 3 +++ src/iperf_locale.c | 1 + src/tcp_info.c | 2 +- 7 files changed, 47 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 10b3d35d1..098bce198 100755 --- a/configure +++ b/configure @@ -13813,9 +13813,7 @@ fi $as_echo "$iperf3_cv_header_tcp_congestion" >&6; } if test "x$iperf3_cv_header_tcp_congestion" = "xyes"; then -# DBO >>> $as_echo "#define HAVE_TCP_CONGESTION 1" >>confdefs.h -$as_echo "#undef HAVE_TCP_CONGESTION 1" >>confdefs.h -# <<< DBO */ +$as_echo "#define HAVE_TCP_CONGESTION 1" >>confdefs.h fi diff --git a/src/iperf.h b/src/iperf.h index c46001def..8a5427306 100644 --- a/src/iperf.h +++ b/src/iperf.h @@ -153,6 +153,7 @@ struct iperf_settings iperf_size_t blocks; /* number of blocks (packets) to send */ char unit_format; /* -f */ int num_ostreams; /* SCTP initmsg settings */ + int dont_fragment; /* Whether to set IP flag Do-Not_Fragment */ #if defined(HAVE_SSL) char *authtoken; /* Authentication token */ char *client_username; diff --git a/src/iperf_api.c b/src/iperf_api.c index e1a0e9da3..fc5fa1f29 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -394,6 +394,12 @@ iperf_get_test_idle_timeout(struct iperf_test *ipt) return ipt->settings->idle_timeout; } +int +iperf_get_dont_fragment(struct iperf_test *ipt) +{ + return ipt->settings->dont_fragment; +} + /************** Setter routines for some fields inside iperf_test *************/ void @@ -731,6 +737,12 @@ iperf_set_test_idle_timeout(struct iperf_test* ipt, int to) ipt->settings->idle_timeout = to; } +void +iperf_set_dont_fragment(struct iperf_test* ipt, int dnf) +{ + ipt->settings->dont_fragment = dnf; +} + /********************** Get/set test protocol structure ***********************/ @@ -962,6 +974,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) {"rsa-private-key-path", required_argument, NULL, OPT_SERVER_RSA_PRIVATE_KEY}, {"authorized-users-path", required_argument, NULL, OPT_SERVER_AUTHORIZED_USERS}, {"time-skew-threshold", required_argument, NULL, OPT_SERVER_SKEW_THRESHOLD}, + {"dont-fragment", no_argument, NULL, OPT_DONT_FRAGMENT}, #endif /* HAVE_SSL */ {"fq-rate", required_argument, NULL, OPT_FQ_RATE}, {"pacing-timer", required_argument, NULL, OPT_PACING_TIMER}, @@ -1390,6 +1403,10 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) return -1; } break; + case OPT_DONT_FRAGMENT: + test->settings->dont_fragment = 1; + client_flag = 1; + break; #endif /* HAVE_SSL */ case OPT_PACING_TIMER: test->settings->pacing_timer = unit_atoi(optarg); @@ -1968,6 +1985,8 @@ send_parameters(struct iperf_test *test) cJSON_AddNumberToObject(j, "udp_counters_64bit", iperf_get_test_udp_counters_64bit(test)); if (test->repeating_payload) cJSON_AddNumberToObject(j, "repeating_payload", test->repeating_payload); + if (test->settings->dont_fragment) + cJSON_AddNumberToObject(j, "DONT_FRAGMENT", test->settings->dont_fragment); #if defined(HAVE_SSL) /* Send authentication parameters */ if (test->settings->client_username && test->settings->client_password && test->settings->client_rsa_pubkey){ @@ -2076,6 +2095,8 @@ get_parameters(struct iperf_test *test) iperf_set_test_udp_counters_64bit(test, 1); if ((j_p = cJSON_GetObjectItem(j, "repeating_payload")) != NULL) test->repeating_payload = 1; + if ((j_p = cJSON_GetObjectItem(j, "DONT_FRAGMENT")) != NULL) + test->settings->dont_fragment = j_p->valueint; #if defined(HAVE_SSL) if ((j_p = cJSON_GetObjectItem(j, "authtoken")) != NULL) test->settings->authtoken = strdup(j_p->valuestring); @@ -2871,6 +2892,7 @@ iperf_reset_test(struct iperf_test *test) test->settings->burst = 0; test->settings->mss = 0; test->settings->tos = 0; + test->settings->dont_fragment = 0; #if defined(HAVE_SSL) if (test->settings->authtoken) { @@ -4051,6 +4073,20 @@ iperf_init_stream(struct iperf_stream *sp, struct iperf_test *test) } } + /* Set Do-Not-Fragment */ + if (test->settings->dont_fragment) { +#if defined(linux) + opt = IP_PMTUDISC_DO; + if (setsockopt(sp->socket, IPPROTO_IP, IP_MTU_DISCOVER, &opt, sizeof(opt)) < 0) { +#else // Unix / Windows + opt = 1; + if (setsockopt(sp->socket, IPPROTO_IP, IP_DONTFRAGMENT, &opt, sizeof(opt)) < 0) { +#endif + i_errno = IESETDONTFRAGMENT; + return -1; + } + } + return 0; } diff --git a/src/iperf_api.h b/src/iperf_api.h index 8d55c52ae..4d2dcde39 100644 --- a/src/iperf_api.h +++ b/src/iperf_api.h @@ -82,6 +82,7 @@ typedef uint64_t iperf_size_t; #define OPT_SERVER_SKEW_THRESHOLD 23 #define OPT_BIND_DEV 24 #define OPT_IDLE_TIMEOUT 25 +#define OPT_DONT_FRAGMENT 26 /* states */ #define TEST_START 1 @@ -140,6 +141,7 @@ char* iperf_get_extra_data( struct iperf_test* ipt ); char* iperf_get_iperf_version(void); int iperf_get_test_no_delay( struct iperf_test* ipt ); int iperf_get_test_connect_timeout( struct iperf_test* ipt ); +int iperf_get_dont_fragment( struct iperf_test* ipt ); /* Setter routines for some fields inside iperf_test. */ void iperf_set_verbose( struct iperf_test* ipt, int verbose ); @@ -177,6 +179,7 @@ void iperf_set_test_tos( struct iperf_test* ipt, int tos ); void iperf_set_test_extra_data( struct iperf_test* ipt, const char *dat ); void iperf_set_test_bidirectional( struct iperf_test* ipt, int bidirectional); void iperf_set_test_no_delay( struct iperf_test* ipt, int no_delay); +void iperf_set_dont_fragment( struct iperf_test* ipt, int dont_fragment ); #if defined(HAVE_SSL) void iperf_set_test_client_username(struct iperf_test *ipt, const char *client_username); @@ -413,6 +416,7 @@ enum { IEAUTHTEST = 142, // Test authorization failed IEBINDDEV = 143, // Unable to bind-to-device (check perror, maybe permissions?) IENOMSG = 144, // No message was received for NO_MSG_RCVD_TIMEOUT time period + IESETDONTFRAGMENT = 145, // Unable to set IP Do-Not-Fragment /* Stream errors */ IECREATESTREAM = 200, // Unable to create a new stream (check herror/perror) IEINITSTREAM = 201, // Unable to initialize stream (check herror/perror) diff --git a/src/iperf_error.c b/src/iperf_error.c index 1769a7f54..0775ba2c3 100644 --- a/src/iperf_error.c +++ b/src/iperf_error.c @@ -433,6 +433,9 @@ iperf_strerror(int int_errno) case IENOMSG: snprintf(errstr, len, "no message was received for %d seconds", NO_MSG_RCVD_TIMEOUT); break; + case IESETDONTFRAGMENT: + snprintf(errstr, len, "unable to set IP Do-Not-Fragment flag"); + break; default: snprintf(errstr, len, "int_errno=%d", int_errno); perr = 1; diff --git a/src/iperf_locale.c b/src/iperf_locale.c index f47e65754..87ddd64e6 100644 --- a/src/iperf_locale.c +++ b/src/iperf_locale.c @@ -189,6 +189,7 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n" " --udp-counters-64bit use 64-bit counters in UDP test packets\n" " --repeating-payload use repeating pattern in payload, instead of\n" " randomized payload (like in iperf2)\n" + " --dont-fragment set IP Do-Not-fragment flag\n" #if defined(HAVE_SSL) " --username username for authentication\n" " --rsa-public-key-path path to the RSA public key used to encrypt\n" diff --git a/src/tcp_info.c b/src/tcp_info.c index 06c253ac7..d63e5b424 100644 --- a/src/tcp_info.c +++ b/src/tcp_info.c @@ -95,7 +95,7 @@ void save_tcpinfo(struct iperf_stream *sp, struct iperf_interval_results *irp) { #if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)) && \ - defined(TCP_INFO)/*DBO >>> */ && 0 /*<<socket, IPPROTO_TCP, TCP_INFO, (void *)&irp->tcpInfo, &tcp_info_length) < 0) From 6a29d0bc83a300f5bc1bdec9377da6f4bd8dc2b9 Mon Sep 17 00:00:00 2001 From: "Bruce A. Mah" Date: Fri, 5 Feb 2021 10:17:27 -0800 Subject: [PATCH 03/10] chore: Test for IP DF socket option support. --- configure.ac | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/configure.ac b/configure.ac index 7e2b62fbb..4876a835a 100644 --- a/configure.ac +++ b/configure.ac @@ -237,6 +237,23 @@ if test "x$iperf3_cv_header_so_bindtodevice" = "xyes"; then AC_DEFINE([HAVE_SO_BINDTODEVICE], [1], [Have SO_BINDTODEVICE sockopt.]) fi +# Check for IP DF support +AC_CACHE_CHECK([IP_MTU_DISCOVER or IP_DONTFRAG socket option], +[iperf3_cv_header_dontfragment], +AC_EGREP_CPP(yes, +[#include +#include +#ifdef IP_MTU_DISCOVER + yes +#endif +#ifdef IP_DONTFRAG + yes +#endif +],iperf3_cv_header_dontfragment=yes,iperf3_cv_header_dontfragment=no)) +if test "x$iperf3_cv_header_dontfragment" = "xyes"; then + AC_DEFINE([HAVE_DONT_FRAGMENT], [1], [Have IP_MTU_DISCOVER/IP_DONTFRAG sockopt.]) +fi + # Check if we need -lrt for clock_gettime AC_SEARCH_LIBS(clock_gettime, [rt posix4]) # Check for clock_gettime support From ea2aefc0cd0c91da2fbe61b910d019485f12e3fb Mon Sep 17 00:00:00 2001 From: "Bruce A. Mah" Date: Fri, 5 Feb 2021 10:18:40 -0800 Subject: [PATCH 04/10] chore: Regen. --- configure | 35 +++++++++++++++++++++++++++++++++++ src/iperf_config.h.in | 3 +++ 2 files changed, 38 insertions(+) diff --git a/configure b/configure index 098bce198..c6be0c4c8 100755 --- a/configure +++ b/configure @@ -13976,6 +13976,41 @@ $as_echo "#define HAVE_SO_BINDTODEVICE 1" >>confdefs.h fi +# Check for IP DF support +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking IP_MTU_DISCOVER or IP_DONTFRAG socket option" >&5 +$as_echo_n "checking IP_MTU_DISCOVER or IP_DONTFRAG socket option... " >&6; } +if ${iperf3_cv_header_dontfragment+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#ifdef IP_MTU_DISCOVER + yes +#endif +#ifdef IP_DONTFRAG + yes +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "yes" >/dev/null 2>&1; then : + iperf3_cv_header_dontfragment=yes +else + iperf3_cv_header_dontfragment=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $iperf3_cv_header_dontfragment" >&5 +$as_echo "$iperf3_cv_header_dontfragment" >&6; } +if test "x$iperf3_cv_header_dontfragment" = "xyes"; then + +$as_echo "#define HAVE_DONT_FRAGMENT 1" >>confdefs.h + +fi + # Check if we need -lrt for clock_gettime { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 $as_echo_n "checking for library containing clock_gettime... " >&6; } diff --git a/src/iperf_config.h.in b/src/iperf_config.h.in index a8aec642a..d78af669a 100644 --- a/src/iperf_config.h.in +++ b/src/iperf_config.h.in @@ -15,6 +15,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H +/* Have IP_MTU_DISCOVER/IP_DONTFRAG sockopt. */ +#undef HAVE_DONT_FRAGMENT + /* Define to 1 if you have the header file. */ #undef HAVE_ENDIAN_H From 80a05caf1aa7b49f6108aa6327312d66b4b0f559 Mon Sep 17 00:00:00 2001 From: "Bruce A. Mah" Date: Fri, 5 Feb 2021 10:48:43 -0800 Subject: [PATCH 05/10] fix: Various fixes and enhancements related to portability. * Make all functionality dependent on HAVE_DONT_FRAGMENT. This unbreaks iperf3 on macOS, which apparently doesn't have support for anything like this. * Test for the presence of socket options, not OS, when deciding how to enable don't-fragment functionality. * Normalize/tweak some terminology and variable names. --- src/iperf_api.c | 43 ++++++++++++++++++++++++++++++------------- src/iperf_locale.c | 4 +++- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/iperf_api.c b/src/iperf_api.c index 2ba8c043c..f325d9341 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -980,13 +980,15 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) {"get-server-output", no_argument, NULL, OPT_GET_SERVER_OUTPUT}, {"udp-counters-64bit", no_argument, NULL, OPT_UDP_COUNTERS_64BIT}, {"no-fq-socket-pacing", no_argument, NULL, OPT_NO_FQ_SOCKET_PACING}, +#if defined(HAVE_DONT_FRAGMENT) + {"dont-fragment", no_argument, NULL, OPT_DONT_FRAGMENT}, +#endif /* HAVE_DONT_FRAGMENT */ #if defined(HAVE_SSL) {"username", required_argument, NULL, OPT_CLIENT_USERNAME}, {"rsa-public-key-path", required_argument, NULL, OPT_CLIENT_RSA_PUBLIC_KEY}, {"rsa-private-key-path", required_argument, NULL, OPT_SERVER_RSA_PRIVATE_KEY}, {"authorized-users-path", required_argument, NULL, OPT_SERVER_AUTHORIZED_USERS}, {"time-skew-threshold", required_argument, NULL, OPT_SERVER_SKEW_THRESHOLD}, - {"dont-fragment", no_argument, NULL, OPT_DONT_FRAGMENT}, #endif /* HAVE_SSL */ {"fq-rate", required_argument, NULL, OPT_FQ_RATE}, {"pacing-timer", required_argument, NULL, OPT_PACING_TIMER}, @@ -1394,6 +1396,12 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) return -1; #endif break; +#if defined(HAVE_DONT_FRAGMENT) + case OPT_DONT_FRAGMENT: + test->settings->dont_fragment = 1; + client_flag = 1; + break; +#endif /* HAVE_DONT_FRAGMENT */ #if defined(HAVE_SSL) case OPT_CLIENT_USERNAME: client_username = strdup(optarg); @@ -1414,10 +1422,6 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) return -1; } break; - case OPT_DONT_FRAGMENT: - test->settings->dont_fragment = 1; - client_flag = 1; - break; #endif /* HAVE_SSL */ case OPT_PACING_TIMER: test->settings->pacing_timer = unit_atoi(optarg); @@ -1996,8 +2000,10 @@ send_parameters(struct iperf_test *test) cJSON_AddNumberToObject(j, "udp_counters_64bit", iperf_get_test_udp_counters_64bit(test)); if (test->repeating_payload) cJSON_AddNumberToObject(j, "repeating_payload", test->repeating_payload); +#if defined(HAVE_DONT_FRAGMENT) if (test->settings->dont_fragment) - cJSON_AddNumberToObject(j, "DONT_FRAGMENT", test->settings->dont_fragment); + cJSON_AddNumberToObject(j, "dont_fragment", test->settings->dont_fragment); +#endif /* HAVE_DONT_FRAGMENT */ #if defined(HAVE_SSL) /* Send authentication parameters */ if (test->settings->client_username && test->settings->client_password && test->settings->client_rsa_pubkey){ @@ -2106,8 +2112,10 @@ get_parameters(struct iperf_test *test) iperf_set_test_udp_counters_64bit(test, 1); if ((j_p = cJSON_GetObjectItem(j, "repeating_payload")) != NULL) test->repeating_payload = 1; - if ((j_p = cJSON_GetObjectItem(j, "DONT_FRAGMENT")) != NULL) +#if defined(HAVE_DONT_FRAGMENT) + if ((j_p = cJSON_GetObjectItem(j, "dont_fragment")) != NULL) test->settings->dont_fragment = j_p->valueint; +#endif /* HAVE_DONT_FRAGMENT */ #if defined(HAVE_SSL) if ((j_p = cJSON_GetObjectItem(j, "authtoken")) != NULL) test->settings->authtoken = strdup(j_p->valuestring); @@ -4084,20 +4092,29 @@ iperf_init_stream(struct iperf_stream *sp, struct iperf_test *test) } } - /* Set Do-Not-Fragment */ +#if defined(HAVE_DONT_FRAGMENT) + /* Set Don't Fragment */ if (test->settings->dont_fragment) { -#if defined(linux) +#if defined(IP_MTU_DISCOVER) /* Linux version of IP_DONTFRAG */ opt = IP_PMTUDISC_DO; if (setsockopt(sp->socket, IPPROTO_IP, IP_MTU_DISCOVER, &opt, sizeof(opt)) < 0) { -#else // Unix / Windows + i_errno = IESETDONTFRAGMENT; + return -1; + } +#else +#if defined(IP_DONTFRAG) /* UNIX and Windows do IP_DONTFRAG */ opt = 1; - if (setsockopt(sp->socket, IPPROTO_IP, IP_DONTFRAGMENT, &opt, sizeof(opt)) < 0) { -#endif + if (setsockopt(sp->socket, IPPROTO_IP, IP_DONTFRAG, &opt, sizeof(opt)) < 0) { i_errno = IESETDONTFRAGMENT; return -1; } +#else + i_errno = IESETDONTFRAGMENT; + return -1; +#endif /* IP_DONTFRAG */ +#endif /* IP_MTU_DISCOVER */ } - +#endif /* HAVE_DONT_FRAGMENT */ return 0; } diff --git a/src/iperf_locale.c b/src/iperf_locale.c index ccd96e7df..9a74fc498 100644 --- a/src/iperf_locale.c +++ b/src/iperf_locale.c @@ -189,7 +189,9 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n" " --udp-counters-64bit use 64-bit counters in UDP test packets\n" " --repeating-payload use repeating pattern in payload, instead of\n" " randomized payload (like in iperf2)\n" - " --dont-fragment set IP Do-Not-fragment flag\n" +#if defined(HAVE_DONT_FRAGMENT) + " --dont-fragment set IPv4 Don't Fragment flag\n" +#endif /* HAVE_DONT_FRAGMENT */ #if defined(HAVE_SSL) " --username username for authentication\n" " --rsa-public-key-path path to the RSA public key used to encrypt\n" From 906a53a27d7ef7c6f1fe5baad236893d1e3529fb Mon Sep 17 00:00:00 2001 From: "Bruce A. Mah" Date: Fri, 5 Feb 2021 11:10:45 -0800 Subject: [PATCH 06/10] docs: Manpage update for --dont-fragment. --- src/iperf3.1 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/iperf3.1 b/src/iperf3.1 index aec3c0754..15b7640c7 100644 --- a/src/iperf3.1 +++ b/src/iperf3.1 @@ -1,4 +1,4 @@ -.TH IPERF3 1 "September 2020" ESnet "User Manuals" +.TH IPERF3 1 "February 2021" ESnet "User Manuals" .SH NAME iperf3 \- perform network throughput tests .SH SYNOPSIS @@ -397,6 +397,10 @@ It might help to test and reveal problems in networking gear with hardware compression (including some WiFi access points), where iperf2 and iperf3 perform differently, just based on payload entropy. .TP +.BR --dont-fragment +Set the IPv4 Don't Fragment (DF) bit on outgoing packets. +Only applicable to tests doing UDP over IPv4. +.TP .BR --username " \fIusername\fR" username to use for authentication to the iperf server (if built with OpenSSL support). From e5fc9bcdba9c772ab53e5faa368ee44cbe99f6fb Mon Sep 17 00:00:00 2001 From: "Bruce A. Mah" Date: Fri, 5 Feb 2021 21:28:33 +0000 Subject: [PATCH 07/10] fix: Fix detection of IP_DONTFRAG on FreeBSD (probably other UNIX also). --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 4876a835a..8950f812a 100644 --- a/configure.ac +++ b/configure.ac @@ -243,6 +243,7 @@ AC_CACHE_CHECK([IP_MTU_DISCOVER or IP_DONTFRAG socket option], AC_EGREP_CPP(yes, [#include #include +#include #ifdef IP_MTU_DISCOVER yes #endif From 1a432c1c660d232ea9ed5519f71aa034e5c7b27d Mon Sep 17 00:00:00 2001 From: "Bruce A. Mah" Date: Fri, 5 Feb 2021 21:29:28 +0000 Subject: [PATCH 08/10] chore: Regen. --- aclocal.m4 | 13 +++++++++---- configure | 14 ++++++++++---- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/aclocal.m4 b/aclocal.m4 index 0b6f3d443..8f8528efe 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1081,11 +1081,16 @@ _LT_EOF _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - darwin*) - case ${MACOSX_DEPLOYMENT_TARGET},$host in - 10.[[012]],*|,*powerpc*) + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[[012]][[,.]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - *) + 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; diff --git a/configure b/configure index c6be0c4c8..dd945d867 100755 --- a/configure +++ b/configure @@ -7431,11 +7431,16 @@ $as_echo "$lt_cv_ld_force_load" >&6; } _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - darwin*) - case ${MACOSX_DEPLOYMENT_TARGET},$host in - 10.[012],*|,*powerpc*) + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[012][,.]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - *) + 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; @@ -13986,6 +13991,7 @@ else /* end confdefs.h. */ #include #include +#include #ifdef IP_MTU_DISCOVER yes #endif From 98d9c05d4efae333f5a7bcb9d969bc75f53252f3 Mon Sep 17 00:00:00 2001 From: "Bruce A. Mah" Date: Fri, 5 Feb 2021 21:36:29 +0000 Subject: [PATCH 09/10] enh: Show don't-fragment functionality in version feature list. --- src/iperf_util.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/iperf_util.c b/src/iperf_util.c index d54cdf284..8155270ba 100644 --- a/src/iperf_util.c +++ b/src/iperf_util.c @@ -327,6 +327,16 @@ get_optional_features(void) numfeatures++; #endif /* HAVE_SO_BINDTODEVICE */ +#if defined(HAVE_DONT_FRAGMENT) + if (numfeatures > 0) { + strncat(features, ", ", + sizeof(features) - strlen(features) - 1); + } + strncat(features, "support IPv4 don't fragment", + sizeof(features) - strlen(features) - 1); + numfeatures++; +#endif /* HAVE_DONT_FRAGMENT */ + if (numfeatures == 0) { strncat(features, "None", sizeof(features) - strlen(features) - 1); From 7a0d9971d621255089d5eae0bcee2b03d794547c Mon Sep 17 00:00:00 2001 From: "Bruce A. Mah" Date: Mon, 8 Feb 2021 16:42:41 +0000 Subject: [PATCH 10/10] fix: Unbreak on Windows, it uses IP_DONT_FRAGMENT. Also add some checks to be sure we really on try to set this on UDP/IPv4 tests. There is an outstanding issue where --dont-fragment --reverse doesn't work. --- configure | 3 +++ configure.ac | 5 ++++- src/iperf_api.c | 22 +++++++++++++++++++--- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/configure b/configure index dd945d867..468276f36 100755 --- a/configure +++ b/configure @@ -13998,6 +13998,9 @@ else #ifdef IP_DONTFRAG yes #endif +#ifdef IP_DONTFRAGMENT + yes +#endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | diff --git a/configure.ac b/configure.ac index 8950f812a..596444aa7 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# iperf, Copyright (c) 2014-2020, The Regents of the University of +# iperf, Copyright (c) 2014-2021, The Regents of the University of # California, through Lawrence Berkeley National Laboratory (subject # to receipt of any required approvals from the U.S. Dept. of # Energy). All rights reserved. @@ -250,6 +250,9 @@ AC_EGREP_CPP(yes, #ifdef IP_DONTFRAG yes #endif +#ifdef IP_DONTFRAGMENT + yes +#endif ],iperf3_cv_header_dontfragment=yes,iperf3_cv_header_dontfragment=no)) if test "x$iperf3_cv_header_dontfragment" = "xyes"; then AC_DEFINE([HAVE_DONT_FRAGMENT], [1], [Have IP_MTU_DISCOVER/IP_DONTFRAG sockopt.]) diff --git a/src/iperf_api.c b/src/iperf_api.c index f325d9341..f52c93061 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -4093,8 +4093,16 @@ iperf_init_stream(struct iperf_stream *sp, struct iperf_test *test) } #if defined(HAVE_DONT_FRAGMENT) - /* Set Don't Fragment */ - if (test->settings->dont_fragment) { + /* Set Don't Fragment (DF). Only applicable to IPv4/UDP tests. */ + if (iperf_get_test_protocol_id(test) == Pudp && + getsockdomain(sp->socket) == AF_INET && + iperf_get_dont_fragment(test)) { + + /* + * There are multiple implementations of this feature depending on the OS. + * We need to handle separately Linux, UNIX, and Windows, as well as + * the case that DF isn't supported at all (such as on macOS). + */ #if defined(IP_MTU_DISCOVER) /* Linux version of IP_DONTFRAG */ opt = IP_PMTUDISC_DO; if (setsockopt(sp->socket, IPPROTO_IP, IP_MTU_DISCOVER, &opt, sizeof(opt)) < 0) { @@ -4102,15 +4110,23 @@ iperf_init_stream(struct iperf_stream *sp, struct iperf_test *test) return -1; } #else -#if defined(IP_DONTFRAG) /* UNIX and Windows do IP_DONTFRAG */ +#if defined(IP_DONTFRAG) /* UNIX does IP_DONTFRAG */ opt = 1; if (setsockopt(sp->socket, IPPROTO_IP, IP_DONTFRAG, &opt, sizeof(opt)) < 0) { i_errno = IESETDONTFRAGMENT; return -1; } +#else +#if defined(IP_DONTFRAGMENT) /* Windows does IP_DONTFRAGMENT */ + opt = 1; + if (setsockopt(sp->socket, IPPROTO_IP, IP_DONTFRAGMENT, &opt, sizeof(opt)) < 0) { + i_errno = IESETDONTFRAGMENT; + return -1; + } #else i_errno = IESETDONTFRAGMENT; return -1; +#endif /* IP_DONTFRAGMENT */ #endif /* IP_DONTFRAG */ #endif /* IP_MTU_DISCOVER */ }