Test to check tcp initial rwnd size
The backport for 4.19 kernel sets the initial receive window size to a
new value greater then 64k. Use a connected TCP socket to check the
patch is properly applied.
Test: ./sock_diag_test.py
Bug: 118591209
Change-Id: If21c6e951aede70c22699d1794dbc09ce91ba5e4
diff --git a/net/test/sock_diag_test.py b/net/test/sock_diag_test.py
index b195fe3..daa2fa4 100755
--- a/net/test/sock_diag_test.py
+++ b/net/test/sock_diag_test.py
@@ -25,16 +25,20 @@
import time
import unittest
+import cstruct
import multinetwork_base
import net_test
import packets
import sock_diag
import tcp_test
+# Mostly empty structure definition containing only the fields we currently use.
+TcpInfo = cstruct.Struct("TcpInfo", "64xI", "tcpi_rcv_ssthresh")
NUM_SOCKETS = 30
NO_BYTECODE = ""
-HAVE_SO_COOKIE_SUPPORT = net_test.LINUX_VERSION >= (4, 9, 0)
+LINUX_4_9_OR_ABOVE = net_test.LINUX_VERSION >= (4, 9, 0)
+LINUX_4_19_OR_ABOVE = net_test.LINUX_VERSION >= (4, 19, 0)
IPPROTO_SCTP = 132
@@ -55,7 +59,7 @@
True if the kernel is 4.9 or above, or the CONFIG_INET_UDP_DIAG is enabled.
False otherwise.
"""
- if HAVE_SO_COOKIE_SUPPORT:
+ if LINUX_4_9_OR_ABOVE:
return True;
s = socket(AF_INET6, SOCK_DGRAM, 0)
s.bind(("::", 0))
@@ -386,7 +390,7 @@
cookie = sock.getsockopt(net_test.SOL_SOCKET, net_test.SO_COOKIE, 8)
self.assertEqual(diag_msg.id.cookie, cookie)
- @unittest.skipUnless(HAVE_SO_COOKIE_SUPPORT, "SO_COOKIE not supported")
+ @unittest.skipUnless(LINUX_4_9_OR_ABOVE, "SO_COOKIE not supported")
def testGetsockoptcookie(self):
self.CheckSocketCookie(AF_INET, "127.0.0.1")
self.CheckSocketCookie(AF_INET6, "::1")
@@ -410,7 +414,7 @@
# Create a fully-specified diag req from our socket, including cookie if
# we can get it.
req = self.sock_diag.DiagReqFromSocket(s)
- if HAVE_SO_COOKIE_SUPPORT:
+ if LINUX_4_9_OR_ABOVE:
req.id.cookie = s.getsockopt(net_test.SOL_SOCKET, net_test.SO_COOKIE, 8)
else:
req.id.cookie = "\xff" * 16 # INET_DIAG_NOCOOKIE[2]
@@ -547,6 +551,50 @@
child.id.src)
+class TcpRcvWindowTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
+
+ RWND_SIZE = 64000 if LINUX_4_19_OR_ABOVE else 42000
+ TCP_DEFAULT_INIT_RWND = "/proc/sys/net/ipv4/tcp_default_init_rwnd"
+
+ def setUp(self):
+ super(TcpRcvWindowTest, self).setUp()
+ if LINUX_4_19_OR_ABOVE:
+ self.assertRaisesErrno(ENOENT, open, self.TCP_DEFAULT_INIT_RWND, "w")
+ return
+
+ f = open(self.TCP_DEFAULT_INIT_RWND, "w")
+ f.write("60")
+
+ def checkInitRwndSize(self, version, netid):
+ self.IncomingConnection(version, tcp_test.TCP_ESTABLISHED, netid)
+ tcpInfo = TcpInfo(self.accepted.getsockopt(net_test.SOL_TCP,
+ net_test.TCP_INFO, len(TcpInfo)))
+ self.assertLess(self.RWND_SIZE, tcpInfo.tcpi_rcv_ssthresh,
+ "Tcp rwnd of netid=%d, version=%d is not enough. "
+ "Expect: %d, actual: %d" % (netid, version, self.RWND_SIZE,
+ tcpInfo.tcpi_rcv_ssthresh))
+
+ def checkSynPacketWindowSize(self, version, netid):
+ s = self.BuildSocket(version, net_test.TCPSocket, netid, "mark")
+ myaddr = self.MyAddress(version, netid)
+ dstaddr = self.GetRemoteAddress(version)
+ dstsockaddr = self.GetRemoteSocketAddress(version)
+ desc, expected = packets.SYN(53, version, myaddr, dstaddr,
+ sport=None, seq=None)
+ self.assertRaisesErrno(EINPROGRESS, s.connect, (dstsockaddr, 53))
+ msg = "IPv%s TCP connect: expected %s on %s" % (
+ version, desc, self.GetInterfaceName(netid))
+ syn = self.ExpectPacketOn(netid, msg, expected)
+ self.assertLess(self.RWND_SIZE, syn.window)
+ s.close()
+
+ def testTcpCwndSize(self):
+ for version in [4, 5, 6]:
+ for netid in self.NETIDS:
+ self.checkInitRwndSize(version, netid)
+ self.checkSynPacketWindowSize(version, netid)
+
+
class SockDestroyTcpTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
def setUp(self):