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;

Reply via email to