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
|
||||
|
||||
PKG_NAME:=iperf
|
||||
PKG_VERSION:=3.17.1
|
||||
PKG_VERSION:=3.18
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/esnet/iperf/archive/refs/tags/
|
||||
PKG_HASH:=105b4fe7fbce31c9b94a3fec10c46e3b4b298adc076e1e3af52b990e1faf2db9
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://downloads.es.net/pub/iperf
|
||||
PKG_HASH:=c0618175514331e766522500e20c94bfb293b4424eb27d7207fb427b88d20bab
|
||||
|
||||
PKG_MAINTAINER:=Yannick Chabanois <ycarus@zugaina.org>
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
PKG_LICENSE:=BSD-3-Clause
|
||||
PKG_CPE_ID:=cpe:/a:es:iperf3
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_INSTALL:=1
|
||||
|
@ -37,24 +38,36 @@ endef
|
|||
define Package/iperf3
|
||||
$(call Package/iperf3/default)
|
||||
VARIANT:=nossl
|
||||
DEPENDS:=+libiperf3
|
||||
endef
|
||||
|
||||
define Package/iperf3-ssl
|
||||
$(call Package/iperf3/default)
|
||||
TITLE+= with iperf_auth support
|
||||
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
|
||||
|
||||
TARGET_CFLAGS += -D_GNU_SOURCE
|
||||
CONFIGURE_ARGS += --disable-shared
|
||||
TARGET_LDFLAGS += -latomic
|
||||
|
||||
ifeq ($(BUILD_VARIANT),ssl)
|
||||
CONFIGURE_ARGS += --with-openssl="$(STAGING_DIR)/usr"
|
||||
CONFIGURE_ARGS += --with-openssl="$(STAGING_DIR)/usr" --disable-shared
|
||||
else
|
||||
CONFIGURE_ARGS += --without-openssl
|
||||
endif
|
||||
|
||||
CONFIGURE_ARGS += --without-sctp
|
||||
|
||||
MAKE_FLAGS += noinst_PROGRAMS=
|
||||
|
||||
define Package/iperf3/description
|
||||
|
@ -63,6 +76,17 @@ define Package/iperf3/description
|
|||
characteristics.
|
||||
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
|
||||
define Build/Prepare
|
||||
$(call Build/Prepare/Default)
|
||||
|
@ -79,5 +103,11 @@ define Package/iperf3-ssl/install
|
|||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/iperf3 $(1)/usr/bin/
|
||||
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-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>
|
||||
Date: Wed, 6 Mar 2024 11:23:33 +0800
|
||||
Subject: [PATCH] add MPTCPv1 support
|
||||
|
@ -17,10 +17,6 @@ be used like this:
|
|||
> iperf3 -m -s
|
||||
> 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
|
||||
normal to fail because the feature is not available and the user
|
||||
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>
|
||||
Signed-off-by: Geliang Tang <geliang@kernel.org>
|
||||
---
|
||||
configure.ac | 12 ++++++++++++
|
||||
src/iperf.h | 1 +
|
||||
src/iperf3.1 | 4 ++++
|
||||
src/iperf_api.c | 19 ++++++++++++++++++-
|
||||
src/iperf_locale.c | 3 +++
|
||||
src/iperf_tcp.c | 22 +++++++++++++++++++---
|
||||
src/iperf_tcp.c | 18 +++++++++++++++---
|
||||
src/net.c | 10 +++++-----
|
||||
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
|
||||
index dc3c0d1df..cb821e1f7 100644
|
||||
index 202d3016f..4043031b3 100644
|
||||
--- a/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 timestamps; /* --timestamps */
|
||||
char *timestamp_format;
|
||||
|
@ -51,12 +71,12 @@ index dc3c0d1df..cb821e1f7 100644
|
|||
char *json_output_string; /* rendered JSON output if json_output is set */
|
||||
/* Select related parameters */
|
||||
diff --git a/src/iperf3.1 b/src/iperf3.1
|
||||
index 2efd53dea..ebc603408 100644
|
||||
index f8eff48d2..9e425cabc 100644
|
||||
--- a/src/iperf3.1
|
||||
+++ b/src/iperf3.1
|
||||
@@ -193,6 +193,10 @@ parameter is specified in ms, and defaults to the system settings.
|
||||
This functionality depends on the TCP_USER_TIMEOUT socket option, and
|
||||
will not work on systems that do not support it.
|
||||
@@ -202,6 +202,10 @@ iperf-3.17, OAEP padding is used, however this is a breaking change
|
||||
that is not compatible with older iperf3 versions. Use this option to
|
||||
preserve the less secure, but more compatible, behavior.
|
||||
.TP
|
||||
+.BR -m ", " --mptcp " "
|
||||
+use mptcp variant for the current protocol. This only applies to
|
||||
|
@ -66,33 +86,33 @@ index 2efd53dea..ebc603408 100644
|
|||
emit debugging output.
|
||||
Primarily (perhaps exclusively) of use to developers.
|
||||
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
|
||||
+++ 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},
|
||||
{"rcv-timeout", required_argument, NULL, OPT_RCV_TIMEOUT},
|
||||
{"snd-timeout", required_argument, NULL, OPT_SND_TIMEOUT},
|
||||
+#if defined(linux)
|
||||
+#if defined(HAVE_IPPROTO_MPTCP)
|
||||
+ {"mptcp", no_argument, NULL, 'm'},
|
||||
+#endif
|
||||
{"debug", optional_argument, NULL, 'd'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{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;
|
||||
#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: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) {
|
||||
case 'p':
|
||||
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);
|
||||
client_flag = 1;
|
||||
break;
|
||||
+#if defined(linux)
|
||||
+#if defined(HAVE_IPPROTO_MPTCP)
|
||||
+ case 'm':
|
||||
+ set_protocol(test, Ptcp);
|
||||
+ test->mptcp = 1;
|
||||
|
@ -101,58 +121,47 @@ index 1dcfaabf5..f7f1fbfb8 100644
|
|||
case 'h':
|
||||
usage_long(stdout);
|
||||
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");
|
||||
if (test->bidirectional)
|
||||
cJSON_AddTrueToObject(j, "bidirectional");
|
||||
+#if defined(linux)
|
||||
+#if defined(HAVE_IPPROTO_MPTCP)
|
||||
+ if (test->mptcp)
|
||||
+ cJSON_AddTrueToObject(j, "mptcp");
|
||||
+#endif
|
||||
if (test->settings->socket_bufsize)
|
||||
cJSON_AddNumberToObject(j, "window", test->settings->socket_bufsize);
|
||||
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);
|
||||
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);
|
||||
+#if defined(linux)
|
||||
+ if ((j_p = cJSON_GetObjectItem(j, "mptcp")) != NULL)
|
||||
+#if defined(HAVE_IPPROTO_MPTCP)
|
||||
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "mptcp", cJSON_True)) != NULL)
|
||||
+ test->mptcp = 1;
|
||||
+#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;
|
||||
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
|
||||
index ae0f63a41..d454af4f0 100644
|
||||
index 32883da84..f1d89e298 100644
|
||||
--- a/src/iperf_locale.c
|
||||
+++ b/src/iperf_locale.c
|
||||
@@ -128,6 +128,9 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n"
|
||||
" --snd-timeout # timeout for unacknowledged TCP data\n"
|
||||
" (in ms, default is system settings)\n"
|
||||
#endif /* HAVE_TCP_USER_TIMEOUT */
|
||||
+#if defined(linux)
|
||||
+#if defined(HAVE_IPPROTO_MPTCP)
|
||||
+ " -m, --mptcp use MPTCP rather than plain TCP\n"
|
||||
+#endif
|
||||
" -d, --debug[=#] emit debugging output\n"
|
||||
" (optional optional \"=\" and debug level: 1-4. Default is 4 - all messages)\n"
|
||||
" -v, --version show version information and quit\n"
|
||||
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
|
||||
+++ b/src/iperf_tcp.c
|
||||
@@ -44,6 +44,10 @@
|
||||
#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)
|
||||
@@ -184,9 +184,10 @@ iperf_tcp_listen(struct iperf_test *test)
|
||||
*
|
||||
* 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);
|
||||
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;
|
||||
}
|
||||
|
||||
- if ((s = socket(res->ai_family, SOCK_STREAM, 0)) < 0) {
|
||||
+#if defined(linux)
|
||||
+#if defined(HAVE_IPPROTO_MPTCP)
|
||||
+ if (test->mptcp)
|
||||
+ proto = IPPROTO_MPTCP;
|
||||
+#endif
|
||||
|
@ -178,13 +187,13 @@ index 184a1955e..a10322b75 100644
|
|||
freeaddrinfo(res);
|
||||
i_errno = IESTREAMLISTEN;
|
||||
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;
|
||||
int saved_errno;
|
||||
int rcvbuf_actual, sndbuf_actual;
|
||||
+ int proto = 0;
|
||||
+
|
||||
+#if defined(linux)
|
||||
+#if defined(HAVE_IPPROTO_MPTCP)
|
||||
+ if (test->mptcp)
|
||||
+ proto = IPPROTO_MPTCP;
|
||||
+#endif
|
||||
|
@ -195,7 +204,7 @@ index 184a1955e..a10322b75 100644
|
|||
i_errno = IESTREAMCONNECT;
|
||||
return -1;
|
||||
diff --git a/src/net.c b/src/net.c
|
||||
index c82caff1b..849e919f2 100644
|
||||
index b693ea7fb..febf20885 100644
|
||||
--- a/src/net.c
|
||||
+++ b/src/net.c
|
||||
@@ -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;
|
||||
}
|
||||
diff --git a/src/net.h b/src/net.h
|
||||
index f0e1b4f98..1f5cc4d34 100644
|
||||
index 859c52cef..fb78d289b 100644
|
||||
--- a/src/net.h
|
||||
+++ b/src/net.h
|
||||
@@ -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%% *}"
|
||||
echo $KEY | base64 -d > /tmp/iperf.pem
|
||||
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
|
||||
iperf3 -c $HOST -p $PORT ${@}
|
||||
fi
|
||||
|
|
Loading…
Reference in a new issue