You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2018/09/12 15:56:37 UTC

[trafficserver] branch master updated: Allow enabling MPTCP on a listening socket through the records.config

This is an automated email from the ASF dual-hosted git repository.

zwoop 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 2755a80  Allow enabling MPTCP on a listening socket through the records.config
2755a80 is described below

commit 2755a80a8c55866591f20345ea5e275084fc4e03
Author: Christoph Paasch <cp...@apple.com>
AuthorDate: Tue Aug 28 15:52:20 2018 -0700

    Allow enabling MPTCP on a listening socket through the records.config
---
 doc/admin-guide/files/records.config.en.rst |  6 ++++++
 lib/records/I_RecHttp.h                     |  3 +++
 lib/records/RecHttp.cc                      | 31 ++++++++++++++++++++++++++++-
 mgmt/LocalManager.cc                        | 23 +++++++++++++++++++++
 4 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/doc/admin-guide/files/records.config.en.rst b/doc/admin-guide/files/records.config.en.rst
index 9d14ccb..e873d53 100644
--- a/doc/admin-guide/files/records.config.en.rst
+++ b/doc/admin-guide/files/records.config.en.rst
@@ -609,6 +609,7 @@ HTTP Engine
    tr-in                       Inbound transparent.
    tr-out                      Outbound transparent.
    tr-pass                     Pass through enabled.
+   mptcp                       Multipath TCP.
    =========== =============== ========================================
 
 *number*
@@ -674,6 +675,11 @@ ip-resolve
 
    Not compatible with: ``tr-out`` - this option requires a value of ``client;none`` which is forced and should not be explicitly specified.
 
+mptcp
+   Enable Multipath TCP on this proxy port.
+
+   Requires custom Linux kernel available at https://multipath-tcp.org.
+
 .. topic:: Example
 
    Listen on port 80 on any address for IPv4 and IPv6.::
diff --git a/lib/records/I_RecHttp.h b/lib/records/I_RecHttp.h
index d69204d..7e831fc 100644
--- a/lib/records/I_RecHttp.h
+++ b/lib/records/I_RecHttp.h
@@ -245,6 +245,8 @@ public:
   bool m_outbound_transparent_p;
   // True if transparent pass-through is enabled on this port.
   bool m_transparent_passthrough;
+  /// True if MPTCP is enabled on this port.
+  bool m_mptcp;
   /// Local address for inbound connections (listen address).
   IpAddr m_inbound_ip;
   /// Local address for outbound connections (to origin server).
@@ -395,6 +397,7 @@ public:
   static const char *const OPT_COMPRESSED;              ///< Compressed.
   static const char *const OPT_HOST_RES_PREFIX;         ///< Set DNS family preference.
   static const char *const OPT_PROTO_PREFIX;            ///< Transport layer protocols.
+  static const char *const OPT_MPTCP;                   ///< MPTCP.
 
   static std::vector<self> &m_global; ///< Global ("default") data.
 
diff --git a/lib/records/RecHttp.cc b/lib/records/RecHttp.cc
index f7873fc..c4b997c 100644
--- a/lib/records/RecHttp.cc
+++ b/lib/records/RecHttp.cc
@@ -25,6 +25,7 @@
 #include <records/I_RecHttp.h>
 #include "tscore/ink_defs.h"
 #include "tscore/ink_hash_table.h"
+#include "tscore/TextBuffer.h"
 #include "tscore/Tokenizer.h"
 #include <strings.h>
 #include "tscore/ink_inet.h"
@@ -70,6 +71,22 @@ SessionProtocolSet HTTP2_PROTOCOL_SET;
 SessionProtocolSet DEFAULT_NON_TLS_SESSION_PROTOCOL_SET;
 SessionProtocolSet DEFAULT_TLS_SESSION_PROTOCOL_SET;
 
+static bool
+mptcp_supported()
+{
+  ats_scoped_fd fd(::open("/proc/sys/net/mptcp/mptcp_enabled", O_RDONLY));
+  int value = 0;
+
+  if (fd) {
+    TextBuffer buffer(16);
+
+    buffer.slurp(fd.get());
+    value = atoi(buffer.bufPtr());
+  }
+
+  return value != 0;
+}
+
 void
 RecHttpLoadIp(const char *value_name, IpAddr &ip4, IpAddr &ip6)
 {
@@ -130,6 +147,7 @@ const char *const HttpProxyPort::OPT_SSL                     = "ssl";
 const char *const HttpProxyPort::OPT_PLUGIN                  = "plugin";
 const char *const HttpProxyPort::OPT_BLIND_TUNNEL            = "blind";
 const char *const HttpProxyPort::OPT_COMPRESSED              = "compressed";
+const char *const HttpProxyPort::OPT_MPTCP                   = "mptcp";
 
 // File local constants.
 namespace
@@ -160,7 +178,8 @@ HttpProxyPort::HttpProxyPort()
     m_family(AF_INET),
     m_inbound_transparent_p(false),
     m_outbound_transparent_p(false),
-    m_transparent_passthrough(false)
+    m_transparent_passthrough(false),
+    m_mptcp(false)
 {
   memcpy(m_host_res_preference, host_res_default_preference_order, sizeof(m_host_res_preference));
 }
@@ -364,6 +383,12 @@ HttpProxyPort::processOptions(const char *opts)
 #else
       Warning("Transparent pass-through requested [%s] in port descriptor '%s' but TPROXY was not configured.", item, opts);
 #endif
+    } else if (0 == strcasecmp(OPT_MPTCP, item)) {
+      if (mptcp_supported()) {
+        m_mptcp = true;
+      } else {
+        Warning("Multipath TCP requested [%s] in port descriptor '%s' but it is not supported by this host.", item, opts);
+      }
     } else if (nullptr != (value = this->checkPrefix(item, OPT_HOST_RES_PREFIX, OPT_HOST_RES_PREFIX_LEN))) {
       this->processFamilyPreference(value);
       host_res_set_p = true;
@@ -541,6 +566,10 @@ HttpProxyPort::print(char *out, size_t n)
     zret += snprintf(out + zret, n - zret, ":%s", OPT_TRANSPARENT_OUTBOUND);
   }
 
+  if (m_mptcp) {
+    zret += snprintf(out + zret, n - zret, ":%s", OPT_MPTCP);
+  }
+
   if (m_transparent_passthrough) {
     zret += snprintf(out + zret, n - zret, ":%s", OPT_TRANSPARENT_PASSTHROUGH);
   }
diff --git a/mgmt/LocalManager.cc b/mgmt/LocalManager.cc
index 6c1089c..4b94d9c 100644
--- a/mgmt/LocalManager.cc
+++ b/mgmt/LocalManager.cc
@@ -47,6 +47,14 @@ using namespace std::literals;
 static const std::string_view MGMT_OPT{"-M"};
 static const std::string_view RUNROOT_OPT{"--run-root="};
 
+#ifndef MPTCP_ENABLED
+#if defined(linux)
+#define MPTCP_ENABLED 42
+#else
+#define MPTCP_ENABLED 0
+#endif
+#endif
+
 void
 LocalManager::mgmtCleanup()
 {
@@ -1025,6 +1033,21 @@ LocalManager::bindProxyPort(HttpProxyPort &port)
     }
   }
 
+  if (port.m_mptcp) {
+#if MPTCP_ENABLED
+    int err;
+
+    err = setsockopt(port.m_fd, IPPROTO_TCP, MPTCP_ENABLED, &one, sizeof(one));
+    if (err < 0) {
+      mgmt_log("[bindProxyPort] Unable to enable MPTCP: %s\n", strerror(errno));
+    } else {
+      mgmt_log("[bindProxyPort] Successfully enabled MPTCP on %d\n", port.m_port);
+    }
+#else
+    Debug("lm", "[bindProxyPort] Multipath TCP requested but not configured on this host");
+#endif
+  }
+
   if (port.m_family == AF_INET6) {
     if (setsockopt(port.m_fd, IPPROTO_IPV6, IPV6_V6ONLY, SOCKOPT_ON, sizeof(int)) < 0) {
       mgmt_log("[bindProxyPort] Unable to set socket options: %d : %s\n", port.m_port, strerror(errno));