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.