mirror of
https://github.com/Ysurac/openmptcprouter-feeds.git
synced 2025-02-12 10:31:51 +00:00
Update iperf3 with MPTCP and sock5 proxy support
This commit is contained in:
parent
f83ffd5266
commit
fff6e52ed4
5 changed files with 671 additions and 58 deletions
|
@ -8,15 +8,16 @@
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=iperf
|
PKG_NAME:=iperf
|
||||||
PKG_VERSION:=3.17.1
|
PKG_VERSION:=3.18
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=https://github.com/esnet/iperf/archive/refs/tags/
|
PKG_SOURCE_URL:=https://downloads.es.net/pub/iperf
|
||||||
PKG_HASH:=105b4fe7fbce31c9b94a3fec10c46e3b4b298adc076e1e3af52b990e1faf2db9
|
PKG_HASH:=c0618175514331e766522500e20c94bfb293b4424eb27d7207fb427b88d20bab
|
||||||
|
|
||||||
PKG_MAINTAINER:=Yannick Chabanois <ycarus@zugaina.org>
|
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||||
PKG_LICENSE:=BSD-3-Clause
|
PKG_LICENSE:=BSD-3-Clause
|
||||||
|
PKG_CPE_ID:=cpe:/a:es:iperf3
|
||||||
|
|
||||||
PKG_BUILD_PARALLEL:=1
|
PKG_BUILD_PARALLEL:=1
|
||||||
PKG_INSTALL:=1
|
PKG_INSTALL:=1
|
||||||
|
@ -37,24 +38,36 @@ endef
|
||||||
define Package/iperf3
|
define Package/iperf3
|
||||||
$(call Package/iperf3/default)
|
$(call Package/iperf3/default)
|
||||||
VARIANT:=nossl
|
VARIANT:=nossl
|
||||||
|
DEPENDS:=+libiperf3
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/iperf3-ssl
|
define Package/iperf3-ssl
|
||||||
$(call Package/iperf3/default)
|
$(call Package/iperf3/default)
|
||||||
TITLE+= with iperf_auth support
|
TITLE+= with iperf_auth support
|
||||||
VARIANT:=ssl
|
VARIANT:=ssl
|
||||||
DEPENDS:= +libopenssl
|
DEPENDS:=+libopenssl +libatomic
|
||||||
|
CONFLICTS:=iperf3
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/libiperf3
|
||||||
|
SECTION:=libs
|
||||||
|
CATEGORY:=Libraries
|
||||||
|
TITLE:=Internet Protocol bandwidth measuring library
|
||||||
|
URL:=https://github.com/esnet/iperf
|
||||||
|
DEPENDS+=+libatomic
|
||||||
endef
|
endef
|
||||||
|
|
||||||
TARGET_CFLAGS += -D_GNU_SOURCE
|
TARGET_CFLAGS += -D_GNU_SOURCE
|
||||||
CONFIGURE_ARGS += --disable-shared
|
TARGET_LDFLAGS += -latomic
|
||||||
|
|
||||||
ifeq ($(BUILD_VARIANT),ssl)
|
ifeq ($(BUILD_VARIANT),ssl)
|
||||||
CONFIGURE_ARGS += --with-openssl="$(STAGING_DIR)/usr"
|
CONFIGURE_ARGS += --with-openssl="$(STAGING_DIR)/usr" --disable-shared
|
||||||
else
|
else
|
||||||
CONFIGURE_ARGS += --without-openssl
|
CONFIGURE_ARGS += --without-openssl
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
CONFIGURE_ARGS += --without-sctp
|
||||||
|
|
||||||
MAKE_FLAGS += noinst_PROGRAMS=
|
MAKE_FLAGS += noinst_PROGRAMS=
|
||||||
|
|
||||||
define Package/iperf3/description
|
define Package/iperf3/description
|
||||||
|
@ -63,6 +76,17 @@ define Package/iperf3/description
|
||||||
characteristics.
|
characteristics.
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Package/libiperf3/description
|
||||||
|
Libiperf is a library providing an API for iperf3 functionality.
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/InstallDev
|
||||||
|
$(INSTALL_DIR) $(1)/usr/lib
|
||||||
|
$(INSTALL_DIR) $(1)/usr/include
|
||||||
|
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libiperf.* $(1)/usr/lib/
|
||||||
|
$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
|
||||||
|
endef
|
||||||
|
|
||||||
# autoreconf fails if the README file isn't present
|
# autoreconf fails if the README file isn't present
|
||||||
define Build/Prepare
|
define Build/Prepare
|
||||||
$(call Build/Prepare/Default)
|
$(call Build/Prepare/Default)
|
||||||
|
@ -79,5 +103,11 @@ define Package/iperf3-ssl/install
|
||||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/iperf3 $(1)/usr/bin/
|
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/iperf3 $(1)/usr/bin/
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Package/libiperf3/install
|
||||||
|
$(INSTALL_DIR) $(1)/usr/lib
|
||||||
|
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libiperf.so.* $(1)/usr/lib
|
||||||
|
endef
|
||||||
|
|
||||||
$(eval $(call BuildPackage,iperf3))
|
$(eval $(call BuildPackage,iperf3))
|
||||||
$(eval $(call BuildPackage,iperf3-ssl))
|
$(eval $(call BuildPackage,iperf3-ssl))
|
||||||
|
$(eval $(call BuildPackage,libiperf3))
|
||||||
|
|
21
iperf3/patches/010-big-endian.patch
Normal file
21
iperf3/patches/010-big-endian.patch
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
From fe09305eb6f907e4eb637b8edd0c8a986187d1dd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rosen Penev <rosenp@gmail.com>
|
||||||
|
Date: Sat, 8 Jun 2024 15:23:51 -0700
|
||||||
|
Subject: [PATCH] fix crash under big endian musl
|
||||||
|
|
||||||
|
iperf_printf is using an int format here but an int64_t variable. The format only needs the first 3 digits. Cast to int to fix it.
|
||||||
|
---
|
||||||
|
src/iperf_api.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/src/iperf_api.c
|
||||||
|
+++ b/src/iperf_api.c
|
||||||
|
@@ -4137,7 +4137,7 @@ iperf_print_results(struct iperf_test *t
|
||||||
|
iperf_printf(test, report_sender_not_available_summary_format, "SUM");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
- iperf_printf(test, report_sum_bw_retrans_format, mbuf, start_time, sender_time, ubuf, nbuf, total_retransmits, report_sender);
|
||||||
|
+ iperf_printf(test, report_sum_bw_retrans_format, mbuf, start_time, sender_time, ubuf, nbuf, (int)total_retransmits, report_sender);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Summary sum, TCP without retransmits. */
|
|
@ -1,4 +1,4 @@
|
||||||
From 5f71968be8e8809e4e7b876ff04b4ef3f22eb141 Mon Sep 17 00:00:00 2001
|
From cf75cf46785871330717a6d2c889abeb7bbd7bfd Mon Sep 17 00:00:00 2001
|
||||||
From: Geliang Tang <geliang@kernel.org>
|
From: Geliang Tang <geliang@kernel.org>
|
||||||
Date: Wed, 6 Mar 2024 11:23:33 +0800
|
Date: Wed, 6 Mar 2024 11:23:33 +0800
|
||||||
Subject: [PATCH] add MPTCPv1 support
|
Subject: [PATCH] add MPTCPv1 support
|
||||||
|
@ -17,10 +17,6 @@ be used like this:
|
||||||
> iperf3 -m -s
|
> iperf3 -m -s
|
||||||
> iperf3 -m -c 127.0.0.1
|
> iperf3 -m -c 127.0.0.1
|
||||||
|
|
||||||
There is no need to check for IPPROTO_MPTCP support in configure.ac
|
|
||||||
at build time, it is at runtime we will see if the kernel being use
|
|
||||||
supports or not MPTCP.
|
|
||||||
|
|
||||||
If IPPROTO_MPTCP is not supported by the kernel being tested, it is
|
If IPPROTO_MPTCP is not supported by the kernel being tested, it is
|
||||||
normal to fail because the feature is not available and the user
|
normal to fail because the feature is not available and the user
|
||||||
explicitly asked to use MPTCP.
|
explicitly asked to use MPTCP.
|
||||||
|
@ -29,20 +25,44 @@ Closes: https://github.com/esnet/iperf/pull/1659
|
||||||
Co-developed-by: Paolo Abeni <pabeni@redhat.com>
|
Co-developed-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
Signed-off-by: Geliang Tang <geliang@kernel.org>
|
Signed-off-by: Geliang Tang <geliang@kernel.org>
|
||||||
---
|
---
|
||||||
|
configure.ac | 12 ++++++++++++
|
||||||
src/iperf.h | 1 +
|
src/iperf.h | 1 +
|
||||||
src/iperf3.1 | 4 ++++
|
src/iperf3.1 | 4 ++++
|
||||||
src/iperf_api.c | 19 ++++++++++++++++++-
|
src/iperf_api.c | 19 ++++++++++++++++++-
|
||||||
src/iperf_locale.c | 3 +++
|
src/iperf_locale.c | 3 +++
|
||||||
src/iperf_tcp.c | 22 +++++++++++++++++++---
|
src/iperf_tcp.c | 18 +++++++++++++++---
|
||||||
src/net.c | 10 +++++-----
|
src/net.c | 10 +++++-----
|
||||||
src/net.h | 2 +-
|
src/net.h | 2 +-
|
||||||
7 files changed, 51 insertions(+), 10 deletions(-)
|
8 files changed, 59 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index 66c1e97a5..22c2a95cf 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -337,6 +337,18 @@ if test "x$iperf3_cv_header_tcp_info_snd_wnd" = "xyes"; then
|
||||||
|
AC_DEFINE([HAVE_TCP_INFO_SND_WND], [1], [Have tcpi_snd_wnd field in tcp_info.])
|
||||||
|
fi
|
||||||
|
|
||||||
|
+# Check for IPPROTO_MPTCP (Linux)
|
||||||
|
+AC_CACHE_CHECK([MPTCP protocol],
|
||||||
|
+[iperf3_cv_header_ipproto_mptcp],
|
||||||
|
+AC_COMPILE_IFELSE(
|
||||||
|
+ [AC_LANG_PROGRAM([[#include <netinet/in.h>]],
|
||||||
|
+ [[int foo = IPPROTO_MPTCP;]])],
|
||||||
|
+ iperf3_cv_header_ipproto_mptcp=yes,
|
||||||
|
+ iperf3_cv_header_ipproto_mptcp=no))
|
||||||
|
+if test "x$iperf3_cv_header_ipproto_mptcp" = "xyes"; then
|
||||||
|
+ AC_DEFINE([HAVE_IPPROTO_MPTCP], [1], [Have MPTCP protocol.])
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
# Check if we need -lrt for clock_gettime
|
||||||
|
AC_SEARCH_LIBS(clock_gettime, [rt posix4])
|
||||||
|
# Check for clock_gettime support
|
||||||
diff --git a/src/iperf.h b/src/iperf.h
|
diff --git a/src/iperf.h b/src/iperf.h
|
||||||
index dc3c0d1df..cb821e1f7 100644
|
index 202d3016f..4043031b3 100644
|
||||||
--- a/src/iperf.h
|
--- a/src/iperf.h
|
||||||
+++ b/src/iperf.h
|
+++ b/src/iperf.h
|
||||||
@@ -342,6 +342,7 @@ struct iperf_test
|
@@ -353,6 +353,7 @@ struct iperf_test
|
||||||
int repeating_payload; /* --repeating-payload */
|
int repeating_payload; /* --repeating-payload */
|
||||||
int timestamps; /* --timestamps */
|
int timestamps; /* --timestamps */
|
||||||
char *timestamp_format;
|
char *timestamp_format;
|
||||||
|
@ -51,12 +71,12 @@ index dc3c0d1df..cb821e1f7 100644
|
||||||
char *json_output_string; /* rendered JSON output if json_output is set */
|
char *json_output_string; /* rendered JSON output if json_output is set */
|
||||||
/* Select related parameters */
|
/* Select related parameters */
|
||||||
diff --git a/src/iperf3.1 b/src/iperf3.1
|
diff --git a/src/iperf3.1 b/src/iperf3.1
|
||||||
index 2efd53dea..ebc603408 100644
|
index f8eff48d2..9e425cabc 100644
|
||||||
--- a/src/iperf3.1
|
--- a/src/iperf3.1
|
||||||
+++ b/src/iperf3.1
|
+++ b/src/iperf3.1
|
||||||
@@ -193,6 +193,10 @@ parameter is specified in ms, and defaults to the system settings.
|
@@ -202,6 +202,10 @@ iperf-3.17, OAEP padding is used, however this is a breaking change
|
||||||
This functionality depends on the TCP_USER_TIMEOUT socket option, and
|
that is not compatible with older iperf3 versions. Use this option to
|
||||||
will not work on systems that do not support it.
|
preserve the less secure, but more compatible, behavior.
|
||||||
.TP
|
.TP
|
||||||
+.BR -m ", " --mptcp " "
|
+.BR -m ", " --mptcp " "
|
||||||
+use mptcp variant for the current protocol. This only applies to
|
+use mptcp variant for the current protocol. This only applies to
|
||||||
|
@ -66,33 +86,33 @@ index 2efd53dea..ebc603408 100644
|
||||||
emit debugging output.
|
emit debugging output.
|
||||||
Primarily (perhaps exclusively) of use to developers.
|
Primarily (perhaps exclusively) of use to developers.
|
||||||
diff --git a/src/iperf_api.c b/src/iperf_api.c
|
diff --git a/src/iperf_api.c b/src/iperf_api.c
|
||||||
index 1dcfaabf5..f7f1fbfb8 100644
|
index fa06dc830..419b48657 100644
|
||||||
--- a/src/iperf_api.c
|
--- a/src/iperf_api.c
|
||||||
+++ b/src/iperf_api.c
|
+++ b/src/iperf_api.c
|
||||||
@@ -1144,6 +1144,9 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
@@ -1149,6 +1149,9 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
||||||
{"idle-timeout", required_argument, NULL, OPT_IDLE_TIMEOUT},
|
{"idle-timeout", required_argument, NULL, OPT_IDLE_TIMEOUT},
|
||||||
{"rcv-timeout", required_argument, NULL, OPT_RCV_TIMEOUT},
|
{"rcv-timeout", required_argument, NULL, OPT_RCV_TIMEOUT},
|
||||||
{"snd-timeout", required_argument, NULL, OPT_SND_TIMEOUT},
|
{"snd-timeout", required_argument, NULL, OPT_SND_TIMEOUT},
|
||||||
+#if defined(linux)
|
+#if defined(HAVE_IPPROTO_MPTCP)
|
||||||
+ {"mptcp", no_argument, NULL, 'm'},
|
+ {"mptcp", no_argument, NULL, 'm'},
|
||||||
+#endif
|
+#endif
|
||||||
{"debug", optional_argument, NULL, 'd'},
|
{"debug", optional_argument, NULL, 'd'},
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
@@ -1169,7 +1172,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
@@ -1174,7 +1177,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
||||||
FILE *ptr_file;
|
FILE *ptr_file;
|
||||||
#endif /* HAVE_SSL */
|
#endif /* HAVE_SSL */
|
||||||
|
|
||||||
- while ((flag = getopt_long(argc, argv, "p:f:i:D1VJvsc:ub:t:n:k:l:P:Rw:B:M:N46S:L:ZO:F:A:T:C:dI:hX:", longopts, NULL)) != -1) {
|
- while ((flag = getopt_long(argc, argv, "p:f:i:D1VJvsc:ub:t:n:k:l:P:Rw:B:M:N46S:L:ZO:F:A:T:C:dI:hX:", longopts, NULL)) != -1) {
|
||||||
+ while ((flag = getopt_long(argc, argv, "p:f:i:D1VJvsc:ub:t:n:k:l:P:Rw:B:mM:N46S:L:ZO:F:A:T:C:dI:hX:", longopts, NULL)) != -1) {
|
+ while ((flag = getopt_long(argc, argv, "p:f:i:D1VJvsc:ub:t:n:k:l:P:Rw:B:M:N46S:L:ZO:F:A:T:C:dI:mhX:", longopts, NULL)) != -1) {
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
case 'p':
|
case 'p':
|
||||||
portno = atoi(optarg);
|
portno = atoi(optarg);
|
||||||
@@ -1639,6 +1642,12 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
@@ -1647,6 +1650,12 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
||||||
test->settings->connect_timeout = unit_atoi(optarg);
|
test->settings->connect_timeout = unit_atoi(optarg);
|
||||||
client_flag = 1;
|
client_flag = 1;
|
||||||
break;
|
break;
|
||||||
+#if defined(linux)
|
+#if defined(HAVE_IPPROTO_MPTCP)
|
||||||
+ case 'm':
|
+ case 'm':
|
||||||
+ set_protocol(test, Ptcp);
|
+ set_protocol(test, Ptcp);
|
||||||
+ test->mptcp = 1;
|
+ test->mptcp = 1;
|
||||||
|
@ -101,58 +121,47 @@ index 1dcfaabf5..f7f1fbfb8 100644
|
||||||
case 'h':
|
case 'h':
|
||||||
usage_long(stdout);
|
usage_long(stdout);
|
||||||
exit(0);
|
exit(0);
|
||||||
@@ -2216,6 +2225,10 @@ send_parameters(struct iperf_test *test)
|
@@ -2259,6 +2268,10 @@ send_parameters(struct iperf_test *test)
|
||||||
cJSON_AddTrueToObject(j, "reverse");
|
cJSON_AddTrueToObject(j, "reverse");
|
||||||
if (test->bidirectional)
|
if (test->bidirectional)
|
||||||
cJSON_AddTrueToObject(j, "bidirectional");
|
cJSON_AddTrueToObject(j, "bidirectional");
|
||||||
+#if defined(linux)
|
+#if defined(HAVE_IPPROTO_MPTCP)
|
||||||
+ if (test->mptcp)
|
+ if (test->mptcp)
|
||||||
+ cJSON_AddTrueToObject(j, "mptcp");
|
+ cJSON_AddTrueToObject(j, "mptcp");
|
||||||
+#endif
|
+#endif
|
||||||
if (test->settings->socket_bufsize)
|
if (test->settings->socket_bufsize)
|
||||||
cJSON_AddNumberToObject(j, "window", test->settings->socket_bufsize);
|
cJSON_AddNumberToObject(j, "window", test->settings->socket_bufsize);
|
||||||
if (test->settings->blksize)
|
if (test->settings->blksize)
|
||||||
@@ -2332,6 +2345,10 @@ get_parameters(struct iperf_test *test)
|
@@ -2375,6 +2388,10 @@ get_parameters(struct iperf_test *test)
|
||||||
iperf_set_test_reverse(test, 1);
|
iperf_set_test_reverse(test, 1);
|
||||||
if ((j_p = cJSON_GetObjectItem(j, "bidirectional")) != NULL)
|
if ((j_p = iperf_cJSON_GetObjectItemType(j, "bidirectional", cJSON_True)) != NULL)
|
||||||
iperf_set_test_bidirectional(test, 1);
|
iperf_set_test_bidirectional(test, 1);
|
||||||
+#if defined(linux)
|
+#if defined(HAVE_IPPROTO_MPTCP)
|
||||||
+ if ((j_p = cJSON_GetObjectItem(j, "mptcp")) != NULL)
|
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "mptcp", cJSON_True)) != NULL)
|
||||||
+ test->mptcp = 1;
|
+ test->mptcp = 1;
|
||||||
+#endif
|
+#endif
|
||||||
if ((j_p = cJSON_GetObjectItem(j, "window")) != NULL)
|
if ((j_p = iperf_cJSON_GetObjectItemType(j, "window", cJSON_Number)) != NULL)
|
||||||
test->settings->socket_bufsize = j_p->valueint;
|
test->settings->socket_bufsize = j_p->valueint;
|
||||||
if ((j_p = cJSON_GetObjectItem(j, "len")) != NULL)
|
if ((j_p = iperf_cJSON_GetObjectItemType(j, "len", cJSON_Number)) != NULL)
|
||||||
diff --git a/src/iperf_locale.c b/src/iperf_locale.c
|
diff --git a/src/iperf_locale.c b/src/iperf_locale.c
|
||||||
index ae0f63a41..d454af4f0 100644
|
index 32883da84..f1d89e298 100644
|
||||||
--- a/src/iperf_locale.c
|
--- a/src/iperf_locale.c
|
||||||
+++ b/src/iperf_locale.c
|
+++ b/src/iperf_locale.c
|
||||||
@@ -128,6 +128,9 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n"
|
@@ -128,6 +128,9 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n"
|
||||||
" --snd-timeout # timeout for unacknowledged TCP data\n"
|
" --snd-timeout # timeout for unacknowledged TCP data\n"
|
||||||
" (in ms, default is system settings)\n"
|
" (in ms, default is system settings)\n"
|
||||||
#endif /* HAVE_TCP_USER_TIMEOUT */
|
#endif /* HAVE_TCP_USER_TIMEOUT */
|
||||||
+#if defined(linux)
|
+#if defined(HAVE_IPPROTO_MPTCP)
|
||||||
+ " -m, --mptcp use MPTCP rather than plain TCP\n"
|
+ " -m, --mptcp use MPTCP rather than plain TCP\n"
|
||||||
+#endif
|
+#endif
|
||||||
" -d, --debug[=#] emit debugging output\n"
|
" -d, --debug[=#] emit debugging output\n"
|
||||||
" (optional optional \"=\" and debug level: 1-4. Default is 4 - all messages)\n"
|
" (optional optional \"=\" and debug level: 1-4. Default is 4 - all messages)\n"
|
||||||
" -v, --version show version information and quit\n"
|
" -v, --version show version information and quit\n"
|
||||||
diff --git a/src/iperf_tcp.c b/src/iperf_tcp.c
|
diff --git a/src/iperf_tcp.c b/src/iperf_tcp.c
|
||||||
index 184a1955e..a10322b75 100644
|
index 481c09dc8..2c10d7df5 100644
|
||||||
--- a/src/iperf_tcp.c
|
--- a/src/iperf_tcp.c
|
||||||
+++ b/src/iperf_tcp.c
|
+++ b/src/iperf_tcp.c
|
||||||
@@ -44,6 +44,10 @@
|
@@ -184,9 +184,10 @@ iperf_tcp_listen(struct iperf_test *test)
|
||||||
#include "net.h"
|
|
||||||
#include "cjson.h"
|
|
||||||
|
|
||||||
+#ifndef IPPROTO_MPTCP
|
|
||||||
+#define IPPROTO_MPTCP 262
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
#if defined(HAVE_FLOWLABEL)
|
|
||||||
#include "flowlabel.h"
|
|
||||||
#endif /* HAVE_FLOWLABEL */
|
|
||||||
@@ -182,9 +186,10 @@ iperf_tcp_listen(struct iperf_test *test)
|
|
||||||
*
|
*
|
||||||
* It's not clear whether this is a requirement or a convenience.
|
* It's not clear whether this is a requirement or a convenience.
|
||||||
*/
|
*/
|
||||||
|
@ -164,12 +173,12 @@ index 184a1955e..a10322b75 100644
|
||||||
|
|
||||||
FD_CLR(s, &test->read_set);
|
FD_CLR(s, &test->read_set);
|
||||||
close(s);
|
close(s);
|
||||||
@@ -210,7 +215,12 @@ iperf_tcp_listen(struct iperf_test *test)
|
@@ -212,7 +213,12 @@ iperf_tcp_listen(struct iperf_test *test)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
- if ((s = socket(res->ai_family, SOCK_STREAM, 0)) < 0) {
|
- if ((s = socket(res->ai_family, SOCK_STREAM, 0)) < 0) {
|
||||||
+#if defined(linux)
|
+#if defined(HAVE_IPPROTO_MPTCP)
|
||||||
+ if (test->mptcp)
|
+ if (test->mptcp)
|
||||||
+ proto = IPPROTO_MPTCP;
|
+ proto = IPPROTO_MPTCP;
|
||||||
+#endif
|
+#endif
|
||||||
|
@ -178,13 +187,13 @@ index 184a1955e..a10322b75 100644
|
||||||
freeaddrinfo(res);
|
freeaddrinfo(res);
|
||||||
i_errno = IESTREAMLISTEN;
|
i_errno = IESTREAMLISTEN;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -375,8 +385,14 @@ iperf_tcp_connect(struct iperf_test *test)
|
@@ -380,8 +386,14 @@ iperf_tcp_connect(struct iperf_test *test)
|
||||||
socklen_t optlen;
|
socklen_t optlen;
|
||||||
int saved_errno;
|
int saved_errno;
|
||||||
int rcvbuf_actual, sndbuf_actual;
|
int rcvbuf_actual, sndbuf_actual;
|
||||||
+ int proto = 0;
|
+ int proto = 0;
|
||||||
+
|
+
|
||||||
+#if defined(linux)
|
+#if defined(HAVE_IPPROTO_MPTCP)
|
||||||
+ if (test->mptcp)
|
+ if (test->mptcp)
|
||||||
+ proto = IPPROTO_MPTCP;
|
+ proto = IPPROTO_MPTCP;
|
||||||
+#endif
|
+#endif
|
||||||
|
@ -195,7 +204,7 @@ index 184a1955e..a10322b75 100644
|
||||||
i_errno = IESTREAMCONNECT;
|
i_errno = IESTREAMCONNECT;
|
||||||
return -1;
|
return -1;
|
||||||
diff --git a/src/net.c b/src/net.c
|
diff --git a/src/net.c b/src/net.c
|
||||||
index c82caff1b..849e919f2 100644
|
index b693ea7fb..febf20885 100644
|
||||||
--- a/src/net.c
|
--- a/src/net.c
|
||||||
+++ b/src/net.c
|
+++ b/src/net.c
|
||||||
@@ -124,7 +124,7 @@ timeout_connect(int s, const struct sockaddr *name, socklen_t namelen,
|
@@ -124,7 +124,7 @@ timeout_connect(int s, const struct sockaddr *name, socklen_t namelen,
|
||||||
|
@ -243,7 +252,7 @@ index c82caff1b..849e919f2 100644
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
diff --git a/src/net.h b/src/net.h
|
diff --git a/src/net.h b/src/net.h
|
||||||
index f0e1b4f98..1f5cc4d34 100644
|
index 859c52cef..fb78d289b 100644
|
||||||
--- a/src/net.h
|
--- a/src/net.h
|
||||||
+++ b/src/net.h
|
+++ b/src/net.h
|
||||||
@@ -28,7 +28,7 @@
|
@@ -28,7 +28,7 @@
|
||||||
|
|
552
iperf3/patches/add-sock5-proxy-tcp-support.patch
Normal file
552
iperf3/patches/add-sock5-proxy-tcp-support.patch
Normal file
|
@ -0,0 +1,552 @@
|
||||||
|
From 197d8ba733f0502985abb5b0a22bf9f71c2596a7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Bar-On <david.cdb004@gmail.com>
|
||||||
|
Date: Mon, 25 Mar 2024 22:11:49 +0200
|
||||||
|
Subject: [PATCH] Add SOCKS5 Proxy support for TCP
|
||||||
|
|
||||||
|
---
|
||||||
|
src/iperf.h | 8 ++
|
||||||
|
src/iperf_api.c | 250 ++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
src/iperf_api.h | 13 ++-
|
||||||
|
src/iperf_client_api.c | 27 ++++-
|
||||||
|
src/iperf_error.c | 10 ++
|
||||||
|
src/iperf_locale.c | 2 +
|
||||||
|
src/iperf_tcp.c | 22 +++-
|
||||||
|
7 files changed, 323 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/iperf.h b/src/iperf.h
|
||||||
|
index dc3c0d1df..9823dc180 100644
|
||||||
|
--- a/src/iperf.h
|
||||||
|
+++ b/src/iperf.h
|
||||||
|
@@ -343,6 +343,14 @@ struct iperf_test
|
||||||
|
int timestamps; /* --timestamps */
|
||||||
|
char *timestamp_format;
|
||||||
|
|
||||||
|
+ char *socks5_host; /* --socks5 option */
|
||||||
|
+ uint16_t socks5_port; /* --socks5 option optional value */
|
||||||
|
+ char *socks5_username; /* --socks5 option optional value */
|
||||||
|
+ char *socks5_password; /* --socks5 option optional value */
|
||||||
|
+ char socks5_bind_atyp; /* from socks5 CONNECT response ATYP */
|
||||||
|
+ char *socks5_bind_host; /* from socks5 CONNECT response BIND.ADDR*/
|
||||||
|
+ uint16_t socks5_bind_port; /* from socks5 CONNECT response BIND.PORT */
|
||||||
|
+
|
||||||
|
char *json_output_string; /* rendered JSON output if json_output is set */
|
||||||
|
/* Select related parameters */
|
||||||
|
int max_fd;
|
||||||
|
diff --git a/src/iperf_api.c b/src/iperf_api.c
|
||||||
|
index 4765d4e97..ca47f708d 100644
|
||||||
|
--- a/src/iperf_api.c
|
||||||
|
+++ b/src/iperf_api.c
|
||||||
|
@@ -115,7 +115,7 @@ usage()
|
||||||
|
void
|
||||||
|
usage_long(FILE *f)
|
||||||
|
{
|
||||||
|
- fprintf(f, usage_longstr, DEFAULT_NO_MSG_RCVD_TIMEOUT, UDP_RATE / (1024*1024), DEFAULT_PACING_TIMER, DURATION, DEFAULT_TCP_BLKSIZE / 1024, DEFAULT_UDP_BLKSIZE);
|
||||||
|
+ fprintf(f, usage_longstr, DEFAULT_NO_MSG_RCVD_TIMEOUT, UDP_RATE / (1024*1024), DEFAULT_PACING_TIMER, DURATION, DEFAULT_TCP_BLKSIZE / 1024, DEFAULT_UDP_BLKSIZE, SOCKS5_DEFAULT_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1100,6 +1100,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
||||||
|
{"version6", no_argument, NULL, '6'},
|
||||||
|
{"tos", required_argument, NULL, 'S'},
|
||||||
|
{"dscp", required_argument, NULL, OPT_DSCP},
|
||||||
|
+ {"socks5", required_argument, NULL, OPT_SOCKS5},
|
||||||
|
{"extra-data", required_argument, NULL, OPT_EXTRA_DATA},
|
||||||
|
#if defined(HAVE_FLOWLABEL)
|
||||||
|
{"flowlabel", required_argument, NULL, 'L'},
|
||||||
|
@@ -1157,7 +1158,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
||||||
|
char* comma;
|
||||||
|
#endif /* HAVE_CPU_AFFINITY */
|
||||||
|
char* slash;
|
||||||
|
- char *p, *p1;
|
||||||
|
+ char *p, *p1, *p2;
|
||||||
|
struct xbind_entry *xbe;
|
||||||
|
double farg;
|
||||||
|
int rcv_timeout_in = 0;
|
||||||
|
@@ -1433,6 +1434,47 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
||||||
|
}
|
||||||
|
client_flag = 1;
|
||||||
|
break;
|
||||||
|
+ case OPT_SOCKS5: // Format: "[username:password@]<host addr/fqdn>[:port]"
|
||||||
|
+ if (strlen(optarg) <= 0) {
|
||||||
|
+ i_errno = IESOCKS5HOST;
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ p1 = strtok(optarg, "@"); // p1 -> user:password
|
||||||
|
+ if (p1 == NULL) {
|
||||||
|
+ i_errno = IESOCKS5HOST;
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ p = strtok(NULL, "@"); // p -> host[:port]
|
||||||
|
+ if (p == NULL) {
|
||||||
|
+ p = p1;
|
||||||
|
+ p1 = NULL;
|
||||||
|
+ }
|
||||||
|
+ p2 = strtok(p, ":"); // parse host[:port]
|
||||||
|
+ if (strlen(p2) <= 0) {
|
||||||
|
+ i_errno = IESOCKS5HOST;
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ test->socks5_host = strdup(p2);
|
||||||
|
+ p2 = strtok(NULL, ":");
|
||||||
|
+ if (p2 && strlen(p2) > 0) {
|
||||||
|
+ test->socks5_port = atoi(p2);
|
||||||
|
+ }
|
||||||
|
+ if (p1) { // parse user:password
|
||||||
|
+ p2 = strtok(p1, ":");
|
||||||
|
+ if (strlen(p2) <= 0 || strlen(p2) > 255) {
|
||||||
|
+ i_errno = IESOCKS5HOST;
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ test->socks5_username = strdup(p2);
|
||||||
|
+ p2 = strtok(NULL, ":");
|
||||||
|
+ if (!p2 || strlen(p2) <= 0 || strlen(p2) > 255) {
|
||||||
|
+ i_errno = IESOCKS5HOST;
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ test->socks5_password = strdup(p2);
|
||||||
|
+ }
|
||||||
|
+ client_flag = 1;
|
||||||
|
+ break;
|
||||||
|
case OPT_EXTRA_DATA:
|
||||||
|
test->extra_data = strdup(optarg);
|
||||||
|
client_flag = 1;
|
||||||
|
@@ -1740,6 +1782,12 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // SOCKS5 Proxy is supported only for TCP
|
||||||
|
+ if(test->role == 'c' && test->socks5_host && test->protocol->id != Ptcp) {
|
||||||
|
+ i_errno = IESOCKS5RTCPONLY;
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (blksize == 0) {
|
||||||
|
if (test->protocol->id == Pudp)
|
||||||
|
blksize = 0; /* try to dynamically determine from MSS */
|
||||||
|
@@ -2943,6 +2991,12 @@ iperf_defaults(struct iperf_test *testp)
|
||||||
|
testp->stats_interval = testp->reporter_interval = 1;
|
||||||
|
testp->num_streams = 1;
|
||||||
|
|
||||||
|
+ testp->socks5_host = NULL;
|
||||||
|
+ testp->socks5_port = SOCKS5_DEFAULT_PORT;
|
||||||
|
+ testp->socks5_username = NULL;
|
||||||
|
+ testp->socks5_password = NULL;
|
||||||
|
+ testp->socks5_bind_host = NULL;
|
||||||
|
+
|
||||||
|
testp->settings->domain = AF_UNSPEC;
|
||||||
|
testp->settings->unit_format = 'a';
|
||||||
|
testp->settings->socket_bufsize = 0; /* use autotuning */
|
||||||
|
@@ -3100,6 +3154,14 @@ iperf_free_test(struct iperf_test *test)
|
||||||
|
free(test->remote_congestion_used);
|
||||||
|
if (test->timestamp_format)
|
||||||
|
free(test->timestamp_format);
|
||||||
|
+ if (test->socks5_host)
|
||||||
|
+ free(test->socks5_host);
|
||||||
|
+ if (test->socks5_username)
|
||||||
|
+ free(test->socks5_username);
|
||||||
|
+ if (test->socks5_password)
|
||||||
|
+ free(test->socks5_password);
|
||||||
|
+ if (test->socks5_bind_host)
|
||||||
|
+ free(test->socks5_bind_host);
|
||||||
|
if (test->omit_timer != NULL)
|
||||||
|
tmr_cancel(test->omit_timer);
|
||||||
|
if (test->timer != NULL)
|
||||||
|
@@ -3289,6 +3351,23 @@ iperf_reset_test(struct iperf_test *test)
|
||||||
|
free(test->extra_data);
|
||||||
|
test->extra_data = NULL;
|
||||||
|
}
|
||||||
|
+ if (test->socks5_host) {
|
||||||
|
+ free(test->socks5_host);
|
||||||
|
+ test->socks5_host = NULL;
|
||||||
|
+ }
|
||||||
|
+ test->socks5_port = SOCKS5_DEFAULT_PORT;
|
||||||
|
+ if (test->socks5_username) {
|
||||||
|
+ free(test->socks5_username);
|
||||||
|
+ test->socks5_username = NULL;
|
||||||
|
+ }
|
||||||
|
+ if (test->socks5_password) {
|
||||||
|
+ free(test->socks5_password);
|
||||||
|
+ test->socks5_password = NULL;
|
||||||
|
+ }
|
||||||
|
+ if (test->socks5_bind_host) {
|
||||||
|
+ free(test->socks5_bind_host);
|
||||||
|
+ test->socks5_bind_host = NULL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* Free output line buffers, if any (on the server only) */
|
||||||
|
struct iperf_textline *t;
|
||||||
|
@@ -4614,6 +4693,173 @@ iperf_add_stream(struct iperf_test *test, struct iperf_stream *sp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**************************************************************************/
|
||||||
|
+
|
||||||
|
+/* iperf_socks5_handshake
|
||||||
|
+ *
|
||||||
|
+ * Handshake with a SOCKS5 Proxy per RFC1928, RFC1929
|
||||||
|
+ */
|
||||||
|
+int
|
||||||
|
+iperf_socks5_handshake(struct iperf_test *test, int s) {
|
||||||
|
+ char req[1024];
|
||||||
|
+ char res[1024];
|
||||||
|
+ char selected_mthod;
|
||||||
|
+ char *p, *p1;
|
||||||
|
+ size_t len;
|
||||||
|
+ int ret;
|
||||||
|
+ uint16_t net_order_short;
|
||||||
|
+
|
||||||
|
+ // Send method selection request [RFC1928]
|
||||||
|
+ p = req;
|
||||||
|
+ *p++ = 5; // VERSION
|
||||||
|
+ if (test->socks5_username) // Number of METHODs supported
|
||||||
|
+ *p++ = 2;
|
||||||
|
+ else
|
||||||
|
+ *p++ = 1;
|
||||||
|
+ *p++ = 0; // NO AUTHENTICATION REQUIRED
|
||||||
|
+ if (test->socks5_username) *p++ = 2; // USERNAME/PASSWORD
|
||||||
|
+ if (Nwrite(s, req, p - req, Ptcp) < 0) {
|
||||||
|
+ i_errno = IESOCKS5HANDSHAKE;
|
||||||
|
+ iperf_err(test, "Writing SOCKS5 auth methods message failed\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Receive selected method
|
||||||
|
+ if (Nread(s, res, 2, Ptcp) != 2) {
|
||||||
|
+ i_errno = IESOCKS5HANDSHAKE;
|
||||||
|
+ iperf_err(test, "Reading selected SOCKS5 method message failed\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ selected_mthod = res[1];
|
||||||
|
+ if (res[0] != 5 || (selected_mthod != 0 && selected_mthod != 2)) {
|
||||||
|
+ i_errno = IESOCKS5HANDSHAKE;
|
||||||
|
+ iperf_err(test, "Ilegal SOCKS5 method selection response: version=%d, auth method=%d\n", res[0], selected_mthod);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ if (test->debug) {
|
||||||
|
+ iperf_printf(test, "SOCKS5 server selected authentication method %d\n", selected_mthod);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Send Username/Password request and receive the auth response [RFC1929]
|
||||||
|
+ if (selected_mthod == 2) {
|
||||||
|
+ p = req;
|
||||||
|
+ *p++ = 1; // VERSION
|
||||||
|
+ len = strlen(test->socks5_username);
|
||||||
|
+ *p++ = len;
|
||||||
|
+ memcpy(p, test->socks5_username, len); // USERNAME
|
||||||
|
+ p += len;
|
||||||
|
+ len = strlen(test->socks5_password);
|
||||||
|
+ *p++ = len;
|
||||||
|
+ memcpy(p, test->socks5_password, len); // PASSWORD
|
||||||
|
+ p += len;
|
||||||
|
+
|
||||||
|
+ if (Nwrite(s, req, p - req, Ptcp) < 0) {
|
||||||
|
+ i_errno = IESOCKS5HANDSHAKE;
|
||||||
|
+ iperf_err(test, "Writing SOCKS5 Username/Password request message failed\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((ret = Nread(s, res, 2, Ptcp)) != 2) {
|
||||||
|
+ i_errno = IESOCKS5HANDSHAKE;
|
||||||
|
+ iperf_err(test, "Reading SOCKS5 Username/Password response failed; Returned %d\n", ret);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ if (res[1] != 0) {
|
||||||
|
+ i_errno = IESOCKS5HANDSHAKE;
|
||||||
|
+ iperf_err(test, "SOCKS5 Username/Password failed with error %d\n", res[1]);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Send CONNECT request [RFC1928]
|
||||||
|
+ p = req;
|
||||||
|
+ *p++ = 5; // VERSION
|
||||||
|
+ *p++ = 1; // CMD = CONNECT
|
||||||
|
+ *p++ = 0; // RESERVED
|
||||||
|
+ *p++ = 3; // ATYPE = DOMAINNAME:
|
||||||
|
+ len = strlen(test->server_hostname);
|
||||||
|
+ if (len > 255) {
|
||||||
|
+ i_errno = IESOCKS5HANDSHAKE;
|
||||||
|
+ iperf_err(test, "iperf3 host option length is limited to 255 chars when SOCKS5 is used\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ *p++ = len;
|
||||||
|
+ memcpy(p, test->server_hostname, len); // ADDR
|
||||||
|
+ p += len;
|
||||||
|
+ net_order_short = htons(test->server_port);
|
||||||
|
+ p1 = (char *)&net_order_short;
|
||||||
|
+ *p++ = *p1++; // PORT
|
||||||
|
+ *p++ = *p1;
|
||||||
|
+ if (Nwrite(s, req, p - req, Ptcp) < 0) {
|
||||||
|
+ i_errno = IESOCKS5HANDSHAKE;
|
||||||
|
+ iperf_err(test, "Writing SOCKS5 CONNECT message failed\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Read CONNECT response [RFC1928]
|
||||||
|
+ if ((ret = Nread(s, res, 4, Ptcp)) != 4) {
|
||||||
|
+ i_errno = IESOCKS5HANDSHAKE;
|
||||||
|
+ iperf_err(test, "Reading SOCKS5 CONNECT response failed; Returned %d\n", ret);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (res[0] != 5 || res[1] != 0 || res[2] != 0) {
|
||||||
|
+ i_errno = IESOCKS5HANDSHAKE;
|
||||||
|
+ iperf_err(test, "SOCKS5 CONNECT failed with error %d\n", res[1]);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Get BND.ADDR length
|
||||||
|
+ test->socks5_bind_atyp = res[3]; // ATYP
|
||||||
|
+ switch (test->socks5_bind_atyp) {
|
||||||
|
+ case 1: // IP V4 address
|
||||||
|
+ len = 4;
|
||||||
|
+ break;
|
||||||
|
+ case 3: // DOMAINNAME:
|
||||||
|
+ if ((ret = read(s, res, 1)) != 1) {
|
||||||
|
+ i_errno = IESOCKS5HANDSHAKE;
|
||||||
|
+ iperf_err(test, "Failed to read SOCKS5 CONNECT response BND.ADDR length; Returned %d\n", ret);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ len = (unsigned char)res[0];
|
||||||
|
+ break;
|
||||||
|
+ case 4: // IP V6 address
|
||||||
|
+ len = 16;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ i_errno = IESOCKS5HANDSHAKE;
|
||||||
|
+ iperf_err(test, "Illegal SOCKS5 CONNECT response ATYP %d\n", res[3]);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ // Read BND.ADDR
|
||||||
|
+ if ((ret = Nread(s, res, len, Ptcp)) != len) {
|
||||||
|
+ i_errno = IESOCKS5HANDSHAKE;
|
||||||
|
+ iperf_err(test, "Failed to read SOCKS5 detailes BND.ADDR; Returned %d\n", ret);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ res[len] = '\0';
|
||||||
|
+ test->socks5_bind_host = strdup(res);
|
||||||
|
+ // Read BND.PORT
|
||||||
|
+ if ((ret = Nread(s, res, 2, Ptcp)) != 2) {
|
||||||
|
+ i_errno = IESOCKS5HANDSHAKE;
|
||||||
|
+ iperf_err(test, "Failed to read SOCKS5 detailes BND.PORT; Returned %d\n", ret);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ p1 = (char *)&net_order_short;
|
||||||
|
+ *p1++ = res[0];
|
||||||
|
+ *p1 = res[1];
|
||||||
|
+ test->socks5_bind_port = ntohs(net_order_short);
|
||||||
|
+ if (test->debug) {
|
||||||
|
+ iperf_printf(test, "SOCKS5 server BIND ADDR type=%d, PORT=%d\n", test->socks5_bind_atyp, test->socks5_bind_port);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**************************************************************************/
|
||||||
|
+
|
||||||
|
+
|
||||||
|
/* This pair of routines gets inserted into the snd/rcv function pointers
|
||||||
|
** when there's a -F flag. They handle the file stuff and call the real
|
||||||
|
** snd/rcv functions, which have been saved in snd2/rcv2.
|
||||||
|
diff --git a/src/iperf_api.h b/src/iperf_api.h
|
||||||
|
index d2bbdfe96..01d63bf5e 100644
|
||||||
|
--- a/src/iperf_api.h
|
||||||
|
+++ b/src/iperf_api.h
|
||||||
|
@@ -68,6 +68,7 @@ typedef atomic_uint_fast64_t atomic_iperf_size_t;
|
||||||
|
#define DEFAULT_PACING_TIMER 1000
|
||||||
|
#define DEFAULT_NO_MSG_RCVD_TIMEOUT 120000
|
||||||
|
#define MIN_NO_MSG_RCVD_TIMEOUT 100
|
||||||
|
+#define SOCKS5_DEFAULT_PORT 1080
|
||||||
|
|
||||||
|
#define WARN_STR_LEN 128
|
||||||
|
|
||||||
|
@@ -100,7 +101,8 @@ typedef atomic_uint_fast64_t atomic_iperf_size_t;
|
||||||
|
#define OPT_RCV_TIMEOUT 27
|
||||||
|
#define OPT_JSON_STREAM 28
|
||||||
|
#define OPT_SND_TIMEOUT 29
|
||||||
|
#define OPT_USE_PKCS1_PADDING 30
|
||||||
|
+#define OPT_SOCKS5 31
|
||||||
|
|
||||||
|
/* states */
|
||||||
|
#define TEST_START 1
|
||||||
|
@@ -308,6 +310,12 @@ void iperf_free_stream(struct iperf_stream * sp);
|
||||||
|
*/
|
||||||
|
int iperf_common_sockopts(struct iperf_test *, int s);
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * iperf_socks5_handshake - handshake with a SOCKS5 Proxy per RFC1928, RFC1929
|
||||||
|
+ *
|
||||||
|
+ */
|
||||||
|
+int iperf_socks5_handshake(struct iperf_test *test, int s);
|
||||||
|
+
|
||||||
|
int has_tcpinfo(void);
|
||||||
|
int has_tcpinfo_retransmits(void);
|
||||||
|
void save_tcpinfo(struct iperf_stream *sp, struct iperf_interval_results *irp);
|
||||||
|
@@ -419,6 +427,8 @@ enum {
|
||||||
|
IESNDTIMEOUT = 33, // Illegal message send timeout
|
||||||
|
IEUDPFILETRANSFER = 34, // Cannot transfer file using UDP
|
||||||
|
IESERVERAUTHUSERS = 35, // Cannot access authorized users file
|
||||||
|
+ IESOCKS5HOST = 36, // Illegal SOCKS5 host / creadentials
|
||||||
|
+ IESOCKS5RTCPONLY = 37, // SOCKS5 Proxy is supported only for TCP
|
||||||
|
/* Test errors */
|
||||||
|
IENEWTEST = 100, // Unable to create a new test (check perror)
|
||||||
|
IEINITTEST = 101, // Test initialization failed (check perror)
|
||||||
|
@@ -473,8 +483,9 @@ enum {
|
||||||
|
IEPTHREADCANCEL=151, // Unable to cancel thread (check perror)
|
||||||
|
IEPTHREADJOIN=152, // Unable to join thread (check perror)
|
||||||
|
IEPTHREADATTRINIT=153, // Unable to initialize thread attribute (check perror)
|
||||||
|
IEPTHREADATTRDESTROY=154, // Unable to destroy thread attribute (check perror)
|
||||||
|
IEPTHREADSIGMASK=155, // Unable to initialize sub thread signal mask (check perror)
|
||||||
|
+ IESOCKS5HANDSHAKE = 156, // SOCKS5 Handshake with the server failed
|
||||||
|
/* 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_client_api.c b/src/iperf_client_api.c
|
||||||
|
index 7ad4c939b..670e3521d 100644
|
||||||
|
--- a/src/iperf_client_api.c
|
||||||
|
+++ b/src/iperf_client_api.c
|
||||||
|
@@ -385,6 +385,8 @@ iperf_connect(struct iperf_test *test)
|
||||||
|
{
|
||||||
|
int opt;
|
||||||
|
socklen_t len;
|
||||||
|
+ const char *connect_server;
|
||||||
|
+ int connect_port;
|
||||||
|
|
||||||
|
if (NULL == test)
|
||||||
|
{
|
||||||
|
@@ -397,12 +399,20 @@ iperf_connect(struct iperf_test *test)
|
||||||
|
make_cookie(test->cookie);
|
||||||
|
|
||||||
|
/* Create and connect the control channel */
|
||||||
|
- if (test->ctrl_sck < 0)
|
||||||
|
- // Create the control channel using an ephemeral port
|
||||||
|
- test->ctrl_sck = netdial(test->settings->domain, Ptcp, test->bind_address, test->bind_dev, 0, test->server_hostname, test->server_port, test->settings->connect_timeout);
|
||||||
|
if (test->ctrl_sck < 0) {
|
||||||
|
- i_errno = IECONNECT;
|
||||||
|
- return -1;
|
||||||
|
+ if (test->socks5_host) {
|
||||||
|
+ connect_server = test->socks5_host;
|
||||||
|
+ connect_port = test->socks5_port;
|
||||||
|
+ } else {
|
||||||
|
+ connect_server = test->server_hostname;
|
||||||
|
+ connect_port = test->server_port;
|
||||||
|
+ }
|
||||||
|
+ // Create the control channel using an ephemeral port
|
||||||
|
+ test->ctrl_sck = netdial(test->settings->domain, Ptcp, test->bind_address, test->bind_dev, 0, connect_server, connect_port, test->settings->connect_timeout);
|
||||||
|
+ if (test->ctrl_sck < 0) {
|
||||||
|
+ i_errno = IECONNECT;
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
// set TCP_NODELAY for lower latency on control messages
|
||||||
|
@@ -421,6 +431,13 @@ iperf_connect(struct iperf_test *test)
|
||||||
|
}
|
||||||
|
#endif /* HAVE_TCP_USER_TIMEOUT */
|
||||||
|
|
||||||
|
+ /* socks5 proxy handshake */
|
||||||
|
+ if (test->socks5_host) {
|
||||||
|
+ if (0 != iperf_socks5_handshake(test, test->ctrl_sck)) {
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (Nwrite(test->ctrl_sck, test->cookie, COOKIE_SIZE, Ptcp) < 0) {
|
||||||
|
i_errno = IESENDCOOKIE;
|
||||||
|
return -1;
|
||||||
|
diff --git a/src/iperf_error.c b/src/iperf_error.c
|
||||||
|
index 6426554cf..a0bbb6844 100644
|
||||||
|
--- a/src/iperf_error.c
|
||||||
|
+++ b/src/iperf_error.c
|
||||||
|
@@ -216,6 +216,9 @@ iperf_strerror(int int_errno)
|
||||||
|
case IEUNIMP:
|
||||||
|
snprintf(errstr, len, "an option you are trying to set is not implemented yet");
|
||||||
|
break;
|
||||||
|
+ case IESOCKS5HOST:
|
||||||
|
+ snprintf(errstr, len, "ilegal SOCKS5 host / creadentials");
|
||||||
|
+ break;
|
||||||
|
case IEFILE:
|
||||||
|
snprintf(errstr, len, "unable to open -F file");
|
||||||
|
perr = 1;
|
||||||
|
@@ -375,6 +378,9 @@ iperf_strerror(int int_errno)
|
||||||
|
case IEUDPFILETRANSFER:
|
||||||
|
snprintf(errstr, len, "cannot transfer file using UDP");
|
||||||
|
break;
|
||||||
|
+ case IESOCKS5RTCPONLY:
|
||||||
|
+ snprintf(errstr, len, "SOCKS5 Proxy is supported only for TCP");
|
||||||
|
+ break;
|
||||||
|
case IERVRSONLYRCVTIMEOUT:
|
||||||
|
snprintf(errstr, len, "client receive timeout is valid only in receiving mode");
|
||||||
|
perr = 1;
|
||||||
|
@@ -507,6 +513,10 @@ iperf_strerror(int int_errno)
|
||||||
|
snprintf(errstr, len, "unable to destroy thread attributes");
|
||||||
|
perr = 1;
|
||||||
|
break;
|
||||||
|
+ case IESOCKS5HANDSHAKE:
|
||||||
|
+ snprintf(errstr, len, "socks5 Handshake with the server failed");
|
||||||
|
+ perr = 1;
|
||||||
|
+ 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 ae0f63a41..c8b9a71d1 100644
|
||||||
|
--- a/src/iperf_locale.c
|
||||||
|
+++ b/src/iperf_locale.c
|
||||||
|
@@ -194,6 +194,8 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n"
|
||||||
|
" --dscp N or --dscp val set the IP dscp value, either 0-63 or symbolic.\n"
|
||||||
|
" Numeric values can be specified in decimal,\n"
|
||||||
|
" octal and hex (see --tos above).\n"
|
||||||
|
+ " --socks5 [user:password@]<proxy-host>[:port] use SOCKS5 Proxy for TCP connections,\n"
|
||||||
|
+ " using no auth or user:password. Default Proxy port is %d \n"
|
||||||
|
#if defined(HAVE_FLOWLABEL)
|
||||||
|
" -L, --flowlabel N set the IPv6 flow label (only supported on Linux)\n"
|
||||||
|
#endif /* HAVE_FLOWLABEL */
|
||||||
|
diff --git a/src/iperf_tcp.c b/src/iperf_tcp.c
|
||||||
|
index 184a1955e..515913581 100644
|
||||||
|
--- a/src/iperf_tcp.c
|
||||||
|
+++ b/src/iperf_tcp.c
|
||||||
|
@@ -375,14 +375,24 @@ iperf_tcp_connect(struct iperf_test *test)
|
||||||
|
socklen_t optlen;
|
||||||
|
int saved_errno;
|
||||||
|
int rcvbuf_actual, sndbuf_actual;
|
||||||
|
int proto = 0;
|
||||||
|
+ const char *connect_server;
|
||||||
|
+ int connect_port;
|
||||||
|
|
||||||
|
#if defined(HAVE_IPPROTO_MPTCP)
|
||||||
|
if (test->mptcp)
|
||||||
|
proto = IPPROTO_MPTCP;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- s = create_socket(test->settings->domain, SOCK_STREAM, proto, test->bind_address, test->bind_dev, test->bind_port, test->server_hostname, test->server_port, &server_res);
|
||||||
|
+ if (test->socks5_host) {
|
||||||
|
+ connect_server = test->socks5_host;
|
||||||
|
+ connect_port = test->socks5_port;
|
||||||
|
+ } else {
|
||||||
|
+ connect_server = test->server_hostname;
|
||||||
|
+ connect_port = test->server_port;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ s = create_socket(test->settings->domain, SOCK_STREAM, proto, test->bind_address, test->bind_dev, test->bind_port, connect_server, connect_port, &server_res);
|
||||||
|
if (s < 0) {
|
||||||
|
i_errno = IESTREAMCONNECT;
|
||||||
|
return -1;
|
||||||
|
@@ -571,6 +581,16 @@ iperf_tcp_connect(struct iperf_test *test)
|
||||||
|
|
||||||
|
freeaddrinfo(server_res);
|
||||||
|
|
||||||
|
+ /* socks5 proxy handshake */
|
||||||
|
+ if (test->socks5_host) {
|
||||||
|
+ if (0 != iperf_socks5_handshake(test, s)) {
|
||||||
|
+ saved_errno = errno;
|
||||||
|
+ close(s);
|
||||||
|
+ errno = saved_errno;
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Send cookie for verification */
|
||||||
|
if (Nwrite(s, test->cookie, COOKIE_SIZE, Ptcp) < 0) {
|
||||||
|
saved_errno = errno;
|
|
@ -10,7 +10,8 @@ PORTS=$(uci -q get iperf.$SERVER.ports | sed 's/,/ /g')
|
||||||
PORT="${PORTS%% *}"
|
PORT="${PORTS%% *}"
|
||||||
echo $KEY | base64 -d > /tmp/iperf.pem
|
echo $KEY | base64 -d > /tmp/iperf.pem
|
||||||
if [ -n "$PASSWORD" ] && [ -n "$USER" ] && [ -n "$KEY" ]; then
|
if [ -n "$PASSWORD" ] && [ -n "$USER" ] && [ -n "$KEY" ]; then
|
||||||
IPERF3_PASSWORD=$PASSWORD iperf3 --username $USER --rsa-public-key-path /tmp/iperf.pem --use-pkcs1-padding -c $HOST -p $PORT ${@}
|
#IPERF3_PASSWORD=$PASSWORD iperf3 --username $USER --rsa-public-key-path /tmp/iperf.pem --use-pkcs1-padding -c $HOST -p $PORT ${@}
|
||||||
|
IPERF3_PASSWORD=$PASSWORD iperf3 --username $USER --rsa-public-key-path /tmp/iperf.pem -c $HOST -p $PORT ${@}
|
||||||
else
|
else
|
||||||
iperf3 -c $HOST -p $PORT ${@}
|
iperf3 -c $HOST -p $PORT ${@}
|
||||||
fi
|
fi
|
||||||
|
|
Loading…
Reference in a new issue