SecondaryTableController: force the MSS to match pmtu on TCP SYN

Without this change, the VPN sets up a tun/ppp that needs a small
MTU, and during TCP SYN the MSS will end up matching the outgoing iface
MTU which is potentially too big.
This leads to connection flakiness. The wrong MSS is visible by
tcpdump-ing on the tun/ppp device.

With this change, the MSS now is correct.
It requires the kernel to be configured with
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
If kernel is not configured, it silently fails.

Bug: 11579326
Change-Id: I254d8c39435b92dff91931e461e1efb8b35f6b1e
diff --git a/CommandListener.cpp b/CommandListener.cpp
index f1bec15..0ca5d8f 100644
--- a/CommandListener.cpp
+++ b/CommandListener.cpp
@@ -90,6 +90,7 @@
 static const char* MANGLE_POSTROUTING[] = {
         BandwidthController::LOCAL_MANGLE_POSTROUTING,
         IdletimerController::LOCAL_MANGLE_POSTROUTING,
+        SecondaryTableController::LOCAL_MANGLE_POSTROUTING,
         NULL,
 };
 
diff --git a/SecondaryTableController.cpp b/SecondaryTableController.cpp
index d12f4c8..736b5fe 100644
--- a/SecondaryTableController.cpp
+++ b/SecondaryTableController.cpp
@@ -37,6 +37,7 @@
 #include "SecondaryTableController.h"
 
 const char* SecondaryTableController::LOCAL_MANGLE_OUTPUT = "st_mangle_OUTPUT";
+const char* SecondaryTableController::LOCAL_MANGLE_POSTROUTING = "st_mangle_POSTROUTING";
 const char* SecondaryTableController::LOCAL_MANGLE_EXEMPT = "st_mangle_EXEMPT";
 const char* SecondaryTableController::LOCAL_MANGLE_IFACE_FORMAT = "st_mangle_%s_OUTPUT";
 const char* SecondaryTableController::LOCAL_NAT_POSTROUTING = "st_nat_POSTROUTING";
@@ -422,6 +423,18 @@
                 "0",
                 NULL);
 
+        /* Best effort, because some kernels might not have the needed TCPMSS */
+        execIptables(V4V6,
+                "-t",
+                "mangle",
+                "-A",
+                LOCAL_MANGLE_POSTROUTING,
+                "-p", "tcp", "-o", iface, "--tcp-flags", "SYN,RST", "SYN",
+                "-j",
+                "TCPMSS",
+                "--clamp-mss-to-pmtu",
+                NULL);
+
     } else {
         ret = execIptables(V4V6,
                 "-t",
@@ -450,6 +463,18 @@
                 "-X",
                 chain_str,
                 NULL);
+
+        /* Best effort, because some kernels might not have the needed TCPMSS */
+        execIptables(V4V6,
+                "-t",
+                "mangle",
+                "-D",
+                LOCAL_MANGLE_POSTROUTING,
+                "-p", "tcp", "-o", iface, "--tcp-flags", "SYN,RST", "SYN",
+                "-j",
+                "TCPMSS",
+                "--clamp-mss-to-pmtu",
+                NULL);
     }
 
     //set up the needed source IP rewriting
diff --git a/SecondaryTableController.h b/SecondaryTableController.h
index 81bb863..a153685 100644
--- a/SecondaryTableController.h
+++ b/SecondaryTableController.h
@@ -59,6 +59,7 @@
     int setupIptablesHooks();
 
     static const char* LOCAL_MANGLE_OUTPUT;
+    static const char* LOCAL_MANGLE_POSTROUTING;
     static const char* LOCAL_MANGLE_EXEMPT;
     static const char* LOCAL_MANGLE_IFACE_FORMAT;
     static const char* LOCAL_NAT_POSTROUTING;