This is an automated email from the ASF dual-hosted git repository. lserris pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push: new bce7b05c86 Support upstream MPTCP (#10701) bce7b05c86 is described below commit bce7b05c866f9868b71a5ebf1ed8cd0102e3c67f Author: Serris Lew <serrisn...@gmail.com> AuthorDate: Mon Nov 13 10:56:54 2023 -0800 Support upstream MPTCP (#10701) * Support upstream MPTCP * update cmake build --------- Co-authored-by: Serris Lew <lser...@apple.com> --- CMakeLists.txt | 1 + include/tscore/ink_platform.h | 14 ++++++++++++++ src/iocore/net/Connection.cc | 32 ++++++++++++++------------------ src/iocore/net/P_UnixNetVConnection.h | 27 +++++++++++++++++++++++++-- src/records/RecHttp.cc | 10 +++++++--- 5 files changed, 61 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cbd79661ee..45b72935a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -469,6 +469,7 @@ check_struct_has_member("struct sockaddr_in" sin_len "netinet/in.h" HAVE_STRUCT_ check_struct_has_member("struct sockaddr_in6" sin6_len "netinet/in.h" HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN) check_struct_has_member("struct stat" st_mtimespec "sys/stat.h" HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) check_struct_has_member("struct stat" st_mtim "sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) +check_struct_has_member("struct mptcp_info" mptcpi_subflows "linux/mptcp.h" HAVE_STRUCT_MPTCP_INFO_SUBFLOWS) # find resolv library if available find_package(resolv) diff --git a/include/tscore/ink_platform.h b/include/tscore/ink_platform.h index 9a91e7051f..7ed6cff3b2 100644 --- a/include/tscore/ink_platform.h +++ b/include/tscore/ink_platform.h @@ -198,3 +198,17 @@ using in_addr_t = unsigned int; #define MPTCP_ENABLED 0 #endif #endif + +// If kernel headers do not support IPPROTO_MPTCP definition +#ifndef IPPROTO_MPTCP +#define IPPROTO_MPTCP 262 +#endif + +#ifndef SOL_MPTCP +#define SOL_MPTCP 284 +#endif + +// Undefined in upstream until 5.16 +#ifndef MPTCP_INFO +#define MPTCP_INFO 1 +#endif diff --git a/src/iocore/net/Connection.cc b/src/iocore/net/Connection.cc index 60d47a785d..195b6eafc0 100644 --- a/src/iocore/net/Connection.cc +++ b/src/iocore/net/Connection.cc @@ -229,7 +229,7 @@ Server::setup_fd_for_listen(bool non_blocking, const NetProcessor::AcceptOptions #endif } - if ((opt.sockopt_flags & NetVCOptions::SOCK_OPT_NO_DELAY) && setsockopt_on(fd, IPPROTO_TCP, TCP_NODELAY) < 0) { + if ((opt.sockopt_flags & NetVCOptions::SOCK_OPT_NO_DELAY) && !opt.f_mptcp && setsockopt_on(fd, IPPROTO_TCP, TCP_NODELAY) < 0) { goto Lerror; } @@ -239,7 +239,7 @@ Server::setup_fd_for_listen(bool non_blocking, const NetProcessor::AcceptOptions } #ifdef TCP_FASTOPEN - if ((opt.sockopt_flags & NetVCOptions::SOCK_OPT_TCP_FAST_OPEN) && + if ((opt.sockopt_flags & NetVCOptions::SOCK_OPT_TCP_FAST_OPEN) && !opt.f_mptcp && safe_setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, (char *)&opt.tfo_queue_length, sizeof(int))) { goto Lerror; } @@ -261,28 +261,17 @@ Server::setup_fd_for_listen(bool non_blocking, const NetProcessor::AcceptOptions } #if defined(TCP_MAXSEG) - if (NetProcessor::accept_mss > 0) { + if (NetProcessor::accept_mss > 0 && !opt.f_mptcp) { if (safe_setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, reinterpret_cast<char *>(&NetProcessor::accept_mss), sizeof(int)) < 0) { goto Lerror; } } #endif - if (opt.f_mptcp) { -#if MPTCP_ENABLED - if (setsockopt_on(fd, IPPROTO_TCP, MPTCP_ENABLED) < 0) { - Error("[Server::listen] Unable to enable MPTCP socket-option [%d] %s\n", errno, strerror(errno)); - goto Lerror; - } -#else - Error("[Server::listen] Multipath TCP requested but not configured on this host\n"); -#endif - } - #ifdef TCP_DEFER_ACCEPT // set tcp defer accept timeout if it is configured, this will not trigger an accept until there is // data on the socket ready to be read - if (opt.defer_accept > 0 && setsockopt(fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &opt.defer_accept, sizeof(int)) < 0) { + if (opt.defer_accept > 0 && !opt.f_mptcp && setsockopt(fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &opt.defer_accept, sizeof(int)) < 0) { // FIXME: should we go to the error // goto error; Error("[Server::listen] Defer accept is configured but set failed: %d", errno); @@ -344,6 +333,7 @@ Server::listen(bool non_blocking, const NetProcessor::AcceptOptions &opt) ink_assert(fd == NO_FD); int res = 0; int namelen; + int prot = IPPROTO_TCP; if (!ats_is_ip(&accept_addr)) { ats_ip4_set(&addr, INADDR_ANY, 0); @@ -351,7 +341,12 @@ Server::listen(bool non_blocking, const NetProcessor::AcceptOptions &opt) ats_ip_copy(&addr, &accept_addr); } - fd = res = SocketManager::socket(addr.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); + if (opt.f_mptcp) { + Debug("connection", "Define socket with MPTCP"); + prot = IPPROTO_MPTCP; + } + + fd = res = SocketManager::socket(addr.sa.sa_family, SOCK_STREAM, prot); if (res < 0) { goto Lerror; } @@ -361,7 +356,7 @@ Server::listen(bool non_blocking, const NetProcessor::AcceptOptions &opt) goto Lerror; } - if ((res = SocketManager::ink_bind(fd, &addr.sa, ats_ip_size(&addr.sa), IPPROTO_TCP)) < 0) { + if ((res = SocketManager::ink_bind(fd, &addr.sa, ats_ip_size(&addr.sa), prot)) < 0) { goto Lerror; } @@ -388,6 +383,7 @@ Lerror: fd = NO_FD; } - Fatal("Could not bind or listen to port %d (error: %d)", ats_ip_port_host_order(&addr), res); + Fatal("Could not bind or listen to port %d, mptcp enabled: %d (error: %d) %s %d", ats_ip_port_host_order(&addr), + prot == IPPROTO_MPTCP, errno, strerror(errno), res); return res; } diff --git a/src/iocore/net/P_UnixNetVConnection.h b/src/iocore/net/P_UnixNetVConnection.h index 606e1223ed..395be61a55 100644 --- a/src/iocore/net/P_UnixNetVConnection.h +++ b/src/iocore/net/P_UnixNetVConnection.h @@ -41,6 +41,10 @@ #include "P_NetAccept.h" #include "iocore/net/NetEvent.h" +#if HAVE_STRUCT_MPTCP_INFO_SUBFLOWS +#include <linux/mptcp.h> +#endif + class UnixNetVConnection; class NetHandler; struct PollDescriptor; @@ -307,10 +311,29 @@ UnixNetVConnection::set_mptcp_state() if (0 == safe_getsockopt(con.fd, IPPROTO_TCP, MPTCP_ENABLED, (char *)&mptcp_enabled, &mptcp_enabled_size)) { Dbg(_dbg_ctl_socket_mptcp, "MPTCP socket state: %d", mptcp_enabled); - mptcp_state = mptcp_enabled > 0 ? true : false; + mptcp_state = (mptcp_enabled > 0); + return; + } else { + Dbg(_dbg_ctl_socket_mptcp, "MPTCP failed getsockopt(MPTCP_ENABLED): %s", strerror(errno)); + } + +#if defined(HAVE_STRUCT_MPTCP_INFO_SUBFLOWS) && defined(MPTCP_INFO) && MPTCP_INFO == 1 + struct mptcp_info minfo; + int minfo_len = sizeof(minfo); + + Dbg(_dbg_ctl_socket_mptcp, "MPTCP_INFO and struct mptcp_info defined"); + if (0 == safe_getsockopt(con.fd, SOL_MPTCP, MPTCP_INFO, &minfo, &minfo_len)) { + if (minfo_len > 0) { + Dbg(_dbg_ctl_socket_mptcp, "MPTCP socket state (remote key received): %d", + (minfo.mptcpi_flags & MPTCP_INFO_FLAG_REMOTE_KEY_RECEIVED)); + mptcp_state = (minfo.mptcpi_flags & MPTCP_INFO_FLAG_REMOTE_KEY_RECEIVED); + return; + } } else { - Dbg(_dbg_ctl_socket_mptcp, "MPTCP failed getsockopt(): %s", strerror(errno)); + mptcp_state = 0; + Dbg(_dbg_ctl_socket_mptcp, "MPTCP failed getsockopt(%d, MPTCP_INFO): %s", con.fd, strerror(errno)); } +#endif } inline ink_hrtime diff --git a/src/records/RecHttp.cc b/src/records/RecHttp.cc index b7ea4c7d6e..f24748176d 100644 --- a/src/records/RecHttp.cc +++ b/src/records/RecHttp.cc @@ -103,13 +103,17 @@ static bool mptcp_supported() { ats_scoped_fd fd(::open("/proc/sys/net/mptcp/mptcp_enabled", O_RDONLY)); + // Newer kernel mptcp config + ats_scoped_fd fd_new(::open("/proc/sys/net/mptcp/enabled", O_RDONLY)); int value = 0; + TextBuffer buffer(16); - if (fd) { - TextBuffer buffer(16); - + if (fd > 0) { buffer.slurp(fd.get()); value = atoi(buffer.bufPtr()); + } else if (fd_new > 0) { + buffer.slurp(fd_new.get()); + value = atoi(buffer.bufPtr()); } return value != 0;