1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter-feeds.git synced 2025-03-09 15:40:03 +00:00

Add OpenVPN with MPTCP upstream support

This commit is contained in:
Ycarus (Yannick Chabanois) 2023-08-17 11:31:53 +02:00
parent 04e1c1cd1b
commit 363f07142f
19 changed files with 2026 additions and 0 deletions

View file

@ -0,0 +1,10 @@
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -105,7 +105,6 @@ const char title_string[] =
#endif
#endif
" [AEAD]"
- " built on " __DATE__
;
#ifndef ENABLE_SMALL

View file

@ -0,0 +1,190 @@
From: Gert Doering <gert@greenie.muc.de>
Support for wolfSSL in OpenVPN
This patch adds support for wolfSSL in OpenVPN. Support is added by using
wolfSSL's OpenSSL compatibility layer. Function calls are left unchanged
and instead the OpenSSL includes point to wolfSSL headers and OpenVPN is
linked against the wolfSSL library. The wolfSSL installation directory is
detected using pkg-config.
As requested by OpenVPN maintainers, this patch does not include
wolfssl/options.h on its own. By defining the macro EXTERNAL_OPTS_OPENVPN
in the configure script wolfSSL will include wolfssl/options.h on its own
(change added in wolfSSL/wolfssl#2825). The patch
adds an option '--disable-wolfssl-options-h' in case the user would like
to supply their own settings file for wolfSSL.
wolfSSL:
Support added in: wolfSSL/wolfssl#2503
git clone https://github.com/wolfSSL/wolfssl.git
cd wolfssl
./autogen.sh
./configure --enable-openvpn
make
sudo make install
OpenVPN:
autoreconf -i -v -f
./configure --with-crypto-library=wolfssl
make
make check
sudo make install
Signed-off-by: Juliusz Sosinowicz <juliusz@wolfssl.com>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <20210317181153.83716-1-juliusz@wolfssl.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg21686.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
---
configure.ac | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/openvpn/syshead.h | 3 ++-
2 files changed, 110 insertions(+), 3 deletions(-)
--- a/configure.ac
+++ b/configure.ac
@@ -271,16 +271,23 @@ AC_ARG_WITH(
AC_ARG_WITH(
[crypto-library],
- [AS_HELP_STRING([--with-crypto-library=library], [build with the given crypto library, TYPE=openssl|mbedtls @<:@default=openssl@:>@])],
+ [AS_HELP_STRING([--with-crypto-library=library], [build with the given crypto library, TYPE=openssl|mbedtls|wolfssl @<:@default=openssl@:>@])],
[
case "${withval}" in
- openssl|mbedtls) ;;
+ openssl|mbedtls|wolfssl) ;;
*) AC_MSG_ERROR([bad value ${withval} for --with-crypto-library]) ;;
esac
],
[with_crypto_library="openssl"]
)
+AC_ARG_ENABLE(
+ [wolfssl-options-h],
+ [AS_HELP_STRING([--disable-wolfssl-options-h], [Disable including options.h in wolfSSL @<:@default=yes@:>@])],
+ ,
+ [enable_wolfssl_options_h="yes"]
+)
+
AC_ARG_WITH(
[openssl-engine],
[AS_HELP_STRING([--with-openssl-engine], [enable engine support with OpenSSL. Default enabled for OpenSSL < 3.0, auto,yes,no @<:@default=auto@:>@])],
@@ -1054,6 +1061,105 @@ elif test "${with_crypto_library}" = "mb
AC_DEFINE([ENABLE_CRYPTO_MBEDTLS], [1], [Use mbed TLS library])
CRYPTO_CFLAGS="${MBEDTLS_CFLAGS}"
CRYPTO_LIBS="${MBEDTLS_LIBS}"
+
+elif test "${with_crypto_library}" = "wolfssl"; then
+ AC_ARG_VAR([WOLFSSL_CFLAGS], [C compiler flags for wolfssl. The include directory should
+ contain the regular wolfSSL header files but also the
+ wolfSSL OpenSSL header files. Ex: -I/usr/local/include
+ -I/usr/local/include/wolfssl])
+ AC_ARG_VAR([WOLFSSL_LIBS], [linker flags for wolfssl])
+
+ saved_CFLAGS="${CFLAGS}"
+ saved_LIBS="${LIBS}"
+
+ if test -z "${WOLFSSL_CFLAGS}" -a -z "${WOLFSSL_LIBS}"; then
+ # if the user did not explicitly specify flags, try to autodetect
+ PKG_CHECK_MODULES(
+ [WOLFSSL],
+ [wolfssl],
+ [],
+ [AC_MSG_ERROR([Could not find wolfSSL.])]
+ )
+ PKG_CHECK_VAR(
+ [WOLFSSL_INCLUDEDIR],
+ [wolfssl],
+ [includedir],
+ [],
+ [AC_MSG_ERROR([Could not find wolfSSL includedir variable.])]
+ )
+ WOLFSSL_CFLAGS="${WOLFSSL_CFLAGS} -I${WOLFSSL_INCLUDEDIR}/wolfssl"
+ fi
+ saved_CFLAGS="${CFLAGS}"
+ saved_LIBS="${LIBS}"
+ CFLAGS="${CFLAGS} ${WOLFSSL_CFLAGS}"
+ LIBS="${LIBS} ${WOLFSSL_LIBS}"
+
+ AC_CHECK_LIB(
+ [wolfssl],
+ [wolfSSL_Init],
+ [],
+ [AC_MSG_ERROR([Could not link wolfSSL library.])]
+ )
+ AC_CHECK_HEADER([wolfssl/options.h],,[AC_MSG_ERROR([wolfSSL header wolfssl/options.h not found!])])
+
+ # wolfSSL signal EKM support
+ have_export_keying_material="yes"
+
+ AC_DEFINE([HAVE_HMAC_CTX_NEW], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_HMAC_CTX_FREE], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_HMAC_CTX_RESET], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_EVP_MD_CTX_NEW], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_EVP_MD_CTX_FREE], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_EVP_MD_CTX_RESET], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_EVP_CIPHER_CTX_RESET], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_OPENSSL_VERSION], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_SSL_CTX_GET_DEFAULT_PASSWD_CB], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_SSL_CTX_GET_DEFAULT_PASSWD_CB_USERDATA], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_SSL_CTX_SET_SECURITY_LEVEL], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_X509_GET0_NOTBEFORE], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_X509_GET0_NOTAFTER], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_X509_GET0_PUBKEY], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_X509_STORE_GET0_OBJECTS], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_X509_OBJECT_FREE], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_X509_OBJECT_GET_TYPE], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_EVP_PKEY_ID], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_EVP_PKEY_GET0_RSA], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_EVP_PKEY_GET0_DSA], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_EVP_PKEY_GET0_EC_KEY], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_RSA_SET_FLAGS], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_RSA_BITS], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_RSA_GET0_KEY], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_RSA_SET0_KEY], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_DSA_GET0_PQG], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_DSA_BITS], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_RSA_METH_NEW], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_RSA_METH_FREE], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_RSA_METH_SET_PUB_ENC], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_RSA_METH_SET_PUB_DEC], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_RSA_METH_SET_PRIV_ENC], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_RSA_METH_SET_PRIV_DEC], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_RSA_METH_SET_INIT], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_RSA_METH_SET_SIGN], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_RSA_METH_SET_FINISH], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_RSA_METH_SET0_APP_DATA], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_RSA_METH_GET0_APP_DATA], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+ AC_DEFINE([HAVE_EC_GROUP_ORDER_BITS], [1], [Emulate AC_CHECK_FUNCS since these are defined as macros])
+
+ if test "${enable_wolfssl_options_h}" = "yes"; then
+ AC_DEFINE([EXTERNAL_OPTS_OPENVPN], [1], [Include options.h from wolfSSL library])
+ else
+ AC_DEFINE([WOLFSSL_USER_SETTINGS], [1], [Use custom user_settings.h file for wolfSSL library])
+ fi
+
+ have_export_keying_material="yes"
+
+ CFLAGS="${saved_CFLAGS}"
+ LIBS="${saved_LIBS}"
+
+ AC_DEFINE([ENABLE_CRYPTO_WOLFSSL], [1], [Use wolfSSL crypto library])
+ AC_DEFINE([ENABLE_CRYPTO_OPENSSL], [1], [Use wolfSSL openssl compatibility layer])
+ CRYPTO_CFLAGS="${WOLFSSL_CFLAGS}"
+ CRYPTO_LIBS="${WOLFSSL_LIBS}"
else
AC_MSG_ERROR([Invalid crypto library: ${with_crypto_library}])
fi
--- a/src/openvpn/syshead.h
+++ b/src/openvpn/syshead.h
@@ -582,7 +582,8 @@ socket_defined(const socket_descriptor_t
/*
* Do we have CryptoAPI capability?
*/
-#if defined(_WIN32) && defined(ENABLE_CRYPTO_OPENSSL)
+#if defined(_WIN32) && defined(ENABLE_CRYPTO_OPENSSL) && \
+ !defined(ENABLE_CRYPTO_WOLFSSL)
#define ENABLE_CRYPTOAPI
#endif

View file

@ -0,0 +1,11 @@
--- a/src/openvpn/ssl_mbedtls.c
+++ b/src/openvpn/ssl_mbedtls.c
@@ -1539,7 +1539,7 @@ const char *
get_ssl_library_version(void)
{
static char mbedtls_version[30];
- unsigned int pv = mbedtls_version_get_number();
+ unsigned int pv = MBEDTLS_VERSION_NUMBER;
sprintf( mbedtls_version, "mbed TLS %d.%d.%d",
(pv>>24)&0xff, (pv>>16)&0xff, (pv>>8)&0xff );
return mbedtls_version;

View file

@ -0,0 +1,74 @@
--- a/configure.ac
+++ b/configure.ac
@@ -1211,68 +1211,15 @@ dnl
AC_ARG_VAR([LZ4_CFLAGS], [C compiler flags for lz4])
AC_ARG_VAR([LZ4_LIBS], [linker flags for lz4])
if test "$enable_lz4" = "yes" && test "$enable_comp_stub" = "no"; then
- if test -z "${LZ4_CFLAGS}" -a -z "${LZ4_LIBS}"; then
- # if the user did not explicitly specify flags, try to autodetect
- PKG_CHECK_MODULES([LZ4],
- [liblz4 >= 1.7.1 liblz4 < 100],
- [have_lz4="yes"],
- [LZ4_LIBS="-llz4"] # If this fails, we will do another test next.
- # We also add set LZ4_LIBS otherwise the
- # linker will not know about the lz4 library
- )
- fi
saved_CFLAGS="${CFLAGS}"
saved_LIBS="${LIBS}"
CFLAGS="${CFLAGS} ${LZ4_CFLAGS}"
LIBS="${LIBS} ${LZ4_LIBS}"
- # If pkgconfig check failed or LZ4_CFLAGS/LZ4_LIBS env vars
- # are used, check the version directly in the LZ4 include file
- if test "${have_lz4}" != "yes"; then
- AC_CHECK_HEADERS([lz4.h],
- [have_lz4h="yes"],
- [])
-
- if test "${have_lz4h}" = "yes" ; then
- AC_MSG_CHECKING([additionally if system LZ4 version >= 1.7.1])
- AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM([[
-#include <lz4.h>
- ]],
- [[
-/* Version encoding: MMNNPP (Major miNor Patch) - see lz4.h for details */
-#if LZ4_VERSION_NUMBER < 10701L
-#error LZ4 is too old
-#endif
- ]]
- )],
- [
- AC_MSG_RESULT([ok])
- have_lz4="yes"
- ],
- [AC_MSG_RESULT([system LZ4 library is too old])]
- )
- fi
- fi
-
- # Double check we have a few needed functions
- if test "${have_lz4}" = "yes" ; then
- AC_CHECK_LIB([lz4],
- [LZ4_compress_default],
- [],
- [have_lz4="no"])
- AC_CHECK_LIB([lz4],
- [LZ4_decompress_safe],
- [],
- [have_lz4="no"])
- fi
-
- if test "${have_lz4}" != "yes" ; then
- AC_MSG_RESULT([ usable LZ4 library or header not found, using version in src/compat/compat-lz4.*])
- AC_DEFINE([NEED_COMPAT_LZ4], [1], [use copy of LZ4 source in compat/])
- LZ4_LIBS=""
- fi
+ AC_MSG_RESULT([ usable LZ4 library or header not found, using version in src/compat/compat-lz4.*])
+ AC_DEFINE([NEED_COMPAT_LZ4], [1], [use copy of LZ4 source in compat/])
+ LZ4_LIBS=""
OPTIONAL_LZ4_CFLAGS="${LZ4_CFLAGS}"
OPTIONAL_LZ4_LIBS="${LZ4_LIBS}"
AC_DEFINE(ENABLE_LZ4, [1], [Enable LZ4 compression library])

View file

@ -0,0 +1,74 @@
--- a/src/openvpn/syshead.h
+++ b/src/openvpn/syshead.h
@@ -572,7 +572,7 @@ socket_defined(const socket_descriptor_t
/*
* Should we include NTLM proxy functionality
*/
-#define NTLM 1
+//#define NTLM 1
/*
* Should we include proxy digest auth functionality
--- a/src/openvpn/crypto_mbedtls.c
+++ b/src/openvpn/crypto_mbedtls.c
@@ -396,6 +396,7 @@ int
key_des_num_cblocks(const mbedtls_cipher_info_t *kt)
{
int ret = 0;
+#ifdef MBEDTLS_DES_C
if (kt->type == MBEDTLS_CIPHER_DES_CBC)
{
ret = 1;
@@ -408,6 +409,7 @@ key_des_num_cblocks(const mbedtls_cipher
{
ret = 3;
}
+#endif
dmsg(D_CRYPTO_DEBUG, "CRYPTO INFO: n_DES_cblocks=%d", ret);
return ret;
@@ -416,6 +418,7 @@ key_des_num_cblocks(const mbedtls_cipher
bool
key_des_check(uint8_t *key, int key_len, int ndc)
{
+#ifdef MBEDTLS_DES_C
int i;
struct buffer b;
@@ -444,11 +447,15 @@ key_des_check(uint8_t *key, int key_len,
err:
return false;
+#else
+ return true;
+#endif
}
void
key_des_fixup(uint8_t *key, int key_len, int ndc)
{
+#ifdef MBEDTLS_DES_C
int i;
struct buffer b;
@@ -463,6 +470,7 @@ key_des_fixup(uint8_t *key, int key_len,
}
mbedtls_des_key_set_parity(key);
}
+#endif
}
/*
@@ -783,10 +791,12 @@ cipher_des_encrypt_ecb(const unsigned ch
unsigned char *src,
unsigned char *dst)
{
+#ifdef MBEDTLS_DES_C
mbedtls_des_context ctx;
ASSERT(mbed_ok(mbedtls_des_setkey_enc(&ctx, key)));
ASSERT(mbed_ok(mbedtls_des_crypt_ecb(&ctx, src, dst)));
+#endif
}

View file

@ -0,0 +1,290 @@
diff --git a/configure.ac b/configure.ac
index 2f5f6bc7..d15c0910 100644
--- a/configure.ac
+++ b/configure.ac
@@ -293,6 +293,12 @@ AC_ARG_WITH(
[with_openssl_engine="auto"]
)
+AC_ARG_WITH(mptcp,
+ [AS_HELP_STRING([--without-mptcp],[Disable Multipath TCP support])],
+ [enable_mptcp=no],
+ [enable_mptcp=yes]
+)
+
AC_ARG_VAR([PLUGINDIR], [Path of plug-in directory @<:@default=LIBDIR/openvpn/plugins@:>@])
if test -n "${PLUGINDIR}"; then
plugindir="${PLUGINDIR}"
@@ -846,6 +852,22 @@ PKG_CHECK_MODULES(
[]
)
+dnl
+dnl Checking Multipath TCP support on Linux
+dnl
+case "$host" in
+ *-*-linux*)
+ AC_MSG_CHECKING([Multipath TCP support ])
+ AS_IF([test "x$enable_mptcp" != xno],
+ [AC_DEFINE([ENABLE_MPTCP], [1],
+ [AC_MSG_RESULT([Multipath TCP is enabled on this system])] )],
+ [ AC_MSG_RESULT([Multipath TCP is not enabled. On Linux, you need a kernel >= 5.15 and ensure that sysctl.net.mptcp_enabled is set to 1]) ],
+ )
+ ;;
+esac
+
+
+
if test "${with_crypto_library}" = "openssl"; then
AC_ARG_VAR([OPENSSL_CFLAGS], [C compiler flags for OpenSSL])
AC_ARG_VAR([OPENSSL_LIBS], [linker flags for OpenSSL])
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index be8ff80f..b4fe11e2 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -3449,6 +3449,9 @@ do_init_socket_1(struct context *c, const int mode)
c->c1.socks_proxy,
#ifdef ENABLE_DEBUG
c->options.gremlin,
+#endif
+#if defined(TARGET_LINUX) && defined(ENABLE_MPTCP)
+ c->options.enable_mptcp,
#endif
c->options.ce.bind_local,
c->options.ce.remote_float,
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 20d1273f..3222fda6 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -130,6 +130,9 @@ static const char usage_message[] =
" udp6, tcp6-server, tcp6-client\n"
"--proto-force p : only consider protocol p in list of connection profiles.\n"
" p = udp or tcp\n"
+#if defined(TARGET_LINUX) && defined(ENABLE_MPTCP)
+ "--mptcp : Enable Multipath TCP on the TCP connections.\n"
+#endif
"--connect-retry n [m] : For client, number of seconds to wait between\n"
" connection retries (default=%d). On repeated retries\n"
" the wait time is exponentially increased to a maximum of m\n"
@@ -903,6 +906,11 @@ init_options(struct options *o, const bool init_gc)
}
#endif /* _WIN32 */
o->allow_recursive_routing = false;
+
+#if defined(TARGET_LINUX) && defined(ENABLE_MPTCP)
+ o->enable_mptcp = false;
+#endif
+
}
void
@@ -8834,6 +8842,18 @@ add_option(struct options *options,
goto err;
}
}
+#if defined(TARGET_LINUX) && defined(ENABLE_MPTCP)
+ else if (streq(p[0], "mptcp"))
+ {
+ VERIFY_PERMISSION(OPT_P_GENERAL);
+ if (p[1])
+ {
+ msg(msglevel, "--mptcp does not accept any parameters");
+ goto err;
+ }
+ options->enable_mptcp = true;
+ }
+#endif
else
{
int i;
diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index 37220904..465eff52 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -430,6 +430,9 @@ struct options
#define SF_NO_PUSH_ROUTE_GATEWAY (1<<2)
unsigned int server_flags;
+#ifdef ENABLE_MPTCP
+ bool enable_mptcp;
+#endif
bool server_bridge_proxy_dhcp;
bool server_bridge_defined;
diff --git a/src/openvpn/ps.c b/src/openvpn/ps.c
index e79cb0d3..754cdfc5 100644
--- a/src/openvpn/ps.c
+++ b/src/openvpn/ps.c
@@ -39,6 +39,14 @@
#include "memdbg.h"
+
+#if defined(TARGET_LINUX) && defined(ENABLE_MPTCP)
+#ifndef IPPROTO_MPTCP
+#define IPPROTO_MPTCP 262
+#endif
+#endif
+
+
struct port_share *port_share = NULL; /* GLOBAL */
/* size of i/o buffers */
@@ -427,7 +435,11 @@ proxy_entry_new(struct proxy_connection **list,
struct proxy_connection *cp;
/* connect to port share server */
+#if defined(TARGET_LINUX) && defined(ENABLE_MPTCP)
+ if ((sd_server = socket(PF_INET, SOCK_STREAM, IPPROTO_MPTCP)) < 0)
+#else
if ((sd_server = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
+#endif
{
msg(M_WARN|M_ERRNO, "PORT SHARE PROXY: cannot create socket");
return false;
diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c
index 28fabe76..e7242020 100644
--- a/src/openvpn/socket.c
+++ b/src/openvpn/socket.c
@@ -55,6 +55,12 @@ const int proto_overhead[] = { /* indexed by PROTO_x */
IPv6_TCP_HEADER_SIZE,
};
+#if defined(TARGET_LINUX) && defined(ENABLE_MPTCP)
+#ifndef IPPROTO_MPTCP
+#define IPPROTO_MPTCP 262
+#endif
+#endif
+
/*
* Convert sockflags/getaddr_flags into getaddr_flags
*/
@@ -1093,6 +1099,39 @@ create_socket_udp(struct addrinfo *addrinfo, const unsigned int flags)
return sd;
}
+#if defined(TARGET_LINUX) && defined(ENABLE_MPTCP)
+socket_descriptor_t
+create_socket_mptcp(struct addrinfo *addrinfo)
+{
+ socket_descriptor_t sd;
+
+ ASSERT(addrinfo);
+ ASSERT(addrinfo->ai_socktype == SOCK_STREAM);
+ addrinfo->ai_protocol = IPPROTO_MPTCP;
+ if ((sd = socket(addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol)) < 0)
+ {
+ msg(M_ERR, "Cannot create MPTCP socket");
+ }
+
+ {
+ int on = 1;
+ if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR,
+ (void *) &on, sizeof(on)) < 0)
+ {
+ msg(M_ERR, "TCP: Cannot setsockopt SO_REUSEADDR on TCP socket");
+ }
+ }
+
+ /* set socket file descriptor to not pass across execs, so that
+ * scripts don't have access to it */
+ set_cloexec(sd);
+
+ return sd;
+}
+
+#endif
+
+
static void
bind_local(struct link_socket *sock, const sa_family_t ai_family)
{
@@ -1136,6 +1175,21 @@ create_socket(struct link_socket *sock, struct addrinfo *addr)
}
else if (addr->ai_protocol == IPPROTO_TCP || addr->ai_socktype == SOCK_STREAM)
{
+#if defined(TARGET_LINUX) && defined(ENABLE_MPTCP)
+ if(sock->info.multipath)
+ {
+ sock->sd = create_socket_mptcp(addr);
+ // Multipath TCP could fail because it is not enabled on this host
+ // Try regular TCP
+ if(sock->sd == -1)
+ {
+
+ msg(M_NONFATAL, "Can't resolve MPTCP socket, fallback to TCP !");
+ sock->sd = create_socket_tcp(addr);
+ }
+ }
+ else
+#endif
sock->sd = create_socket_tcp(addr);
}
else
@@ -1891,6 +1945,9 @@ link_socket_init_phase1(struct link_socket *sock,
struct socks_proxy_info *socks_proxy,
#ifdef ENABLE_DEBUG
int gremlin,
+#endif
+#if defined(TARGET_LINUX) && defined(ENABLE_MPTCP)
+ bool enable_mptcp,
#endif
bool bind_local,
bool remote_float,
@@ -1920,7 +1977,11 @@ link_socket_init_phase1(struct link_socket *sock,
sock->inetd = inetd;
sock->resolve_retry_seconds = resolve_retry_seconds;
sock->mtu_discover_type = mtu_discover_type;
-
+
+#if defined(TARGET_LINUX) && defined(ENABLE_MPTCP)
+ sock->info.multipath = enable_mptcp;
+#endif
+
#ifdef ENABLE_DEBUG
sock->gremlin = gremlin;
#endif
@@ -2305,7 +2366,7 @@ link_socket_init_phase2(struct link_socket *sock,
/* If a valid remote has been found, create the socket with its addrinfo */
if (sock->info.lsa->current_remote)
{
- create_socket(sock, sock->info.lsa->current_remote);
+ create_socket(sock, sock->info.lsa->current_remote);
}
/* If socket has not already been created create it now */
diff --git a/src/openvpn/socket.h b/src/openvpn/socket.h
index 2ad6155f..0dcb0655 100644
--- a/src/openvpn/socket.h
+++ b/src/openvpn/socket.h
@@ -120,6 +120,9 @@ struct link_socket_info
sa_family_t af; /* Address family like AF_INET, AF_INET6 or AF_UNSPEC*/
bool bind_ipv6_only;
int mtu_changed; /* Set to true when mtu value is changed */
+#if defined(TARGET_LINUX) && defined(ENABLE_MPTCP)
+ bool multipath;
+#endif
};
/*
@@ -315,6 +318,9 @@ link_socket_init_phase1(struct link_socket *sock,
struct socks_proxy_info *socks_proxy,
#ifdef ENABLE_DEBUG
int gremlin,
+#endif
+#if defined(TARGET_LINUX) && defined(ENABLE_MPTCP)
+ bool enable_mptcp,
#endif
bool bind_local,
bool remote_float,
@@ -476,6 +482,10 @@ bool ipv6_addr_safe(const char *ipv6_text_addr);
socket_descriptor_t create_socket_tcp(struct addrinfo *);
+#ifdef ENABLE_MPTCP
+socket_descriptor_t create_socket_mptcp(struct addrinfo *);
+#endif
+
socket_descriptor_t socket_do_accept(socket_descriptor_t sd,
struct link_socket_actual *act,
const bool nowait);