diff options
author | Joe Orton <jorton@apache.org> | 2024-09-12 09:59:22 +0200 |
---|---|---|
committer | Joe Orton <jorton@apache.org> | 2024-09-12 09:59:22 +0200 |
commit | 4915c21524e7ed2cf0dcfcf93d8be9139337497d (patch) | |
tree | 80ce4ce71a07c0e5e572f7962e3da96dbb28f070 /modules | |
parent | * Mention the additional bug [skip ci] (diff) | |
download | apache2-4915c21524e7ed2cf0dcfcf93d8be9139337497d.tar.xz apache2-4915c21524e7ed2cf0dcfcf93d8be9139337497d.zip |
Add Multipath TCP (MPTCP) support (Proxy)
Multipath TCP (MPTCP), standardized in RFC8684 [1],
is a TCP extension that enables a TCP connection to
use different paths.
Multipath TCP has been used for several use cases.
On smartphones, MPTCP enables seamless handovers between
cellular and Wi-Fi networks while preserving established
connections. This use-case is what pushed Apple to use
MPTCP since 2013 in multiple applications [2]. On dual-stack
hosts, Multipath TCP enables the TCP connection to
automatically use the best performing path, either IPv4
or IPv6. If one path fails, MPTCP automatically uses
the other path.
To benefit from MPTCP, both the client and the server
have to support it. Multipath TCP is a backward-compatible
TCP extension that is enabled by default on recent
Linux distributions (Debian, Ubuntu, Redhat, ...). Multipath
TCP is included in the Linux kernel since version 5.6 [3].
To use it on Linux, an application must explicitly enable
it when creating the socket. No need to change anything
else in the application.
Adding the possibility to create MPTCP sockets would thus
be a really fine addition to httpd, by allowing clients
to make use of their different interfaces.
This patch introduces the possibilty to connect to backend
servers using MPTCP. Note however that these changes are
only available on Linux, as IPPROTO_MPTCP is Linux specific
for the time being.
For proxies, we can connect using MPTCP by passing the
\"multipathtcp\" parameter:
ProxyPass \"/example\" \"http://backend.example.com\" multipathtcp=On
We then store this information in the worker and create sockets
appropriately according to this value.
Link: https://www.rfc-editor.org/rfc/rfc8684.html [1]
Link: https://www.tessares.net/apples-mptcp-story-so-far/ [2]
Link: https://www.mptcp.dev [3]
Add Multipath TCP (MPTCP) support (Core)
Multipath TCP (MPTCP), standardized in RFC8684 [1],
is a TCP extension that enables a TCP connection to
use different paths.
Multipath TCP has been used for several use cases.
On smartphones, MPTCP enables seamless handovers between
cellular and Wi-Fi networks while preserving established
connections. This use-case is what pushed Apple to use
MPTCP since 2013 in multiple applications [2]. On dual-stack
hosts, Multipath TCP enables the TCP connection to
automatically use the best performing path, either IPv4
or IPv6. If one path fails, MPTCP automatically uses
the other path.
To benefit from MPTCP, both the client and the server
have to support it. Multipath TCP is a backward-compatible
TCP extension that is enabled by default on recent
Linux distributions (Debian, Ubuntu, Redhat, ...). Multipath
TCP is included in the Linux kernel since version 5.6 [3].
To use it on Linux, an application must explicitly enable
it when creating the socket. No need to change anything
else in the application.
Adding the possibility to create MPTCP sockets would thus
be a really fine addition to httpd, by allowing clients
to make use of their different interfaces.
This patch introduces the possibility to listen with MPTCP
sockets. Note however that these changes are only available
on Linux, as IPPROTO_MPTCP is Linux specific for the time being.
To do so, we extended the Listen directive to include
a \"multipathtcp\" option, allowing to create MPTCP sockets
instead of regular TCP ones:
Listen 80 options=multipathtcp
We then store this information in flags for the listen directive
and create sockets appropriately according to this value.
Link: https://www.rfc-editor.org/rfc/rfc8684.html [1]
Link: https://www.tessares.net/apples-mptcp-story-so-far/ [2]
Link: https://www.mptcp.dev [3]
Submitted by: Aperence <anthony.doeraene hotmail.com>
Github: closes #476
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1920586 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules')
-rw-r--r-- | modules/proxy/mod_proxy.c | 12 | ||||
-rw-r--r-- | modules/proxy/mod_proxy.h | 1 | ||||
-rw-r--r-- | modules/proxy/proxy_util.c | 2 |
3 files changed, 14 insertions, 1 deletions
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 0cce98ddf1..46d3b07145 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -356,6 +356,18 @@ static const char *set_worker_param(apr_pool_t *p, worker->s->response_field_size = (s ? s : HUGE_STRING_LEN); worker->s->response_field_size_set = 1; } + else if (!strcasecmp(key, "multipathtcp")) { +#ifdef IPPROTO_MPTCP + if (!strcasecmp(val, "On")) + worker->s->sock_proto = IPPROTO_MPTCP; + else if (!strcasecmp(val, "Off")) + worker->s->sock_proto = APR_PROTO_TCP; + else + return "multipathtcp must be On|Off"; +#else + return "multipathtcp is not supported on your platform"; +#endif + } else { if (set_worker_hc_param_f) { return set_worker_hc_param_f(p, s, worker, key, val, NULL); diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 6594159e98..d51510fc02 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -497,6 +497,7 @@ typedef struct { unsigned int address_ttl_set:1; apr_int32_t address_ttl; /* backend address' TTL (seconds) */ apr_uint32_t address_expiry; /* backend address' next expiry time */ + int sock_proto; /* The protocol to use to create the socket */ } proxy_worker_shared; #define ALIGNED_PROXY_WORKER_SHARED_SIZE (APR_ALIGN_DEFAULT(sizeof(proxy_worker_shared))) diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index 1a11498f5d..546398da14 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -3858,7 +3858,7 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, #endif { if ((rv = apr_socket_create(&newsock, backend_addr->family, - SOCK_STREAM, APR_PROTO_TCP, + SOCK_STREAM, worker->s->sock_proto, conn->scpool)) != APR_SUCCESS) { loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR; ap_log_error(APLOG_MARK, loglevel, rv, s, APLOGNO(00952) |