Support kernels that make SOCK_DESTROY work on FIN_WAIT sockets. A change has been sent to net to support destroying FIN_WAIT sockets: https://lore.kernel.org/netdev/20240814084622.555672-1-kuro@kuroa.me/T/#t If applied, this change will cause sock_diag_test to fail, because it expects that SOCK_DESTROY on FIN_WAIT1 sockets does nothing. Fix the test to handle the newly-proposed behaviour as well as the current behaviour. Bug: 402346034 Test: test-only change (cherry picked from https://android-review.googlesource.com/q/commit:56f489f85bae5dee5dd3a1d1447bb8bdfe39e483) Merged-In: If40089365027b4ef98fdcf695aec9404a4c32fd9 Change-Id: If40089365027b4ef98fdcf695aec9404a4c32fd9
diff --git a/net/test/sock_diag_test.py b/net/test/sock_diag_test.py index 58e8f01..fee9d0b 100755 --- a/net/test/sock_diag_test.py +++ b/net/test/sock_diag_test.py
@@ -588,6 +588,11 @@ super(SockDestroyTcpTest, self).setUp() self.netid = random.choice(list(self.tuns.keys())) + def ExpectRst(self, msg): + desc, rst = self.RstPacket() + msg = "%s: expecting %s: " % (msg, desc) + self.ExpectPacketOn(self.netid, msg, rst) + def CheckRstOnClose(self, sock, req, expect_reset, msg, do_close=True): """Closes the socket and checks whether a RST is sent or not.""" if sock is not None: @@ -599,9 +604,7 @@ self.sock_diag.CloseSocket(req) if expect_reset: - desc, rst = self.RstPacket() - msg = "%s: expecting %s: " % (msg, desc) - self.ExpectPacketOn(self.netid, msg, rst) + self.ExpectRst(msg) else: msg = "%s: " % msg self.ExpectNoPacketsOn(self.netid, msg) @@ -641,14 +644,26 @@ diag_msg, attrs = self.sock_diag.GetSockInfo(diag_req) self.assertEqual(tcp_test.TCP_FIN_WAIT1, diag_msg.state) desc, fin = self.FinPacket() - self.ExpectPacketOn(self.netid, "Closing FIN_WAIT1 socket", fin) + msg = "Closing FIN_WAIT1 socket" + self.ExpectPacketOn(self.netid, msg, fin) - # Destroy the socket and expect no RST. - self.CheckRstOnClose(None, diag_req, False, "Closing FIN_WAIT1 socket") - diag_msg, attrs = self.sock_diag.GetSockInfo(diag_req) + # Destroy the socket. + self.sock_diag.CloseSocketFromFd(self.s) + self.assertRaisesErrno(EINVAL, self.s.accept) + try: + diag_msg, attrs = self.sock_diag.GetSockInfo(diag_req) + except Error as e: + # Newer kernels will have closed the socket and sent a RST. + self.assertEqual(ENOENT, e.errno) + self.ExpectRst(msg) + self.CloseSockets() + return - # The socket is still there in FIN_WAIT1: SOCK_DESTROY did nothing - # because userspace had already closed it. + # Older kernels don't support closing FIN_WAIT1 sockets. + # Check that no RST is sent and that the socket is still in FIN_WAIT1, and + # advances to FIN_WAIT2 if the FIN is ACked. + msg = "%s: " % msg + self.ExpectNoPacketsOn(self.netid, msg) self.assertEqual(tcp_test.TCP_FIN_WAIT1, diag_msg.state) # ACK the FIN so we don't trip over retransmits in future tests.