OSDN Git Service

ANRdaemon: move trace result from /sdcard to /data am: d93aa41807
[android-x86/system-extras.git] / tests / net_test / sock_diag_test.py
1 #!/usr/bin/python
2 #
3 # Copyright 2015 The Android Open Source Project
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # pylint: disable=g-bad-todo,g-bad-file-header,wildcard-import
18 from errno import *  # pylint: disable=wildcard-import
19 import os
20 import random
21 import re
22 from socket import *  # pylint: disable=wildcard-import
23 import threading
24 import time
25 import unittest
26
27 import multinetwork_base
28 import net_test
29 import packets
30 import sock_diag
31 import tcp_test
32
33
34 NUM_SOCKETS = 30
35 NO_BYTECODE = ""
36
37
38 class SockDiagBaseTest(multinetwork_base.MultiNetworkBaseTest):
39
40   @staticmethod
41   def _CreateLotsOfSockets():
42     # Dict mapping (addr, sport, dport) tuples to socketpairs.
43     socketpairs = {}
44     for _ in xrange(NUM_SOCKETS):
45       family, addr = random.choice([
46           (AF_INET, "127.0.0.1"),
47           (AF_INET6, "::1"),
48           (AF_INET6, "::ffff:127.0.0.1")])
49       socketpair = net_test.CreateSocketPair(family, SOCK_STREAM, addr)
50       sport, dport = (socketpair[0].getsockname()[1],
51                       socketpair[1].getsockname()[1])
52       socketpairs[(addr, sport, dport)] = socketpair
53     return socketpairs
54
55   def assertSocketClosed(self, sock):
56     self.assertRaisesErrno(ENOTCONN, sock.getpeername)
57
58   def assertSocketConnected(self, sock):
59     sock.getpeername()  # No errors? Socket is alive and connected.
60
61   def assertSocketsClosed(self, socketpair):
62     for sock in socketpair:
63       self.assertSocketClosed(sock)
64
65   def setUp(self):
66     super(SockDiagBaseTest, self).setUp()
67     self.sock_diag = sock_diag.SockDiag()
68     self.socketpairs = {}
69
70   def tearDown(self):
71     for socketpair in self.socketpairs.values():
72       for s in socketpair:
73         s.close()
74     super(SockDiagBaseTest, self).tearDown()
75
76
77 class SockDiagTest(SockDiagBaseTest):
78
79   def assertSockDiagMatchesSocket(self, s, diag_msg):
80     family = s.getsockopt(net_test.SOL_SOCKET, net_test.SO_DOMAIN)
81     self.assertEqual(diag_msg.family, family)
82
83     src, sport = s.getsockname()[0:2]
84     self.assertEqual(diag_msg.id.src, self.sock_diag.PaddedAddress(src))
85     self.assertEqual(diag_msg.id.sport, sport)
86
87     if self.sock_diag.GetDestinationAddress(diag_msg) not in ["0.0.0.0", "::"]:
88       dst, dport = s.getpeername()[0:2]
89       self.assertEqual(diag_msg.id.dst, self.sock_diag.PaddedAddress(dst))
90       self.assertEqual(diag_msg.id.dport, dport)
91     else:
92       self.assertRaisesErrno(ENOTCONN, s.getpeername)
93
94   def testFindsMappedSockets(self):
95     """Tests that inet_diag_find_one_icsk can find mapped sockets.
96
97     Relevant kernel commits:
98       android-3.10:
99         f77e059 net: diag: support v4mapped sockets in inet_diag_find_one_icsk()
100     """
101     socketpair = net_test.CreateSocketPair(AF_INET6, SOCK_STREAM,
102                                            "::ffff:127.0.0.1")
103     for sock in socketpair:
104       diag_msg = self.sock_diag.FindSockDiagFromFd(sock)
105       diag_req = self.sock_diag.DiagReqFromDiagMsg(diag_msg, IPPROTO_TCP)
106       self.sock_diag.GetSockDiag(diag_req)
107       # No errors? Good.
108
109   def testFindsAllMySockets(self):
110     """Tests that basic socket dumping works.
111
112     Relevant commits:
113       android-3.4:
114         ab4a727 net: inet_diag: zero out uninitialized idiag_{src,dst} fields
115       android-3.10
116         3eb409b net: inet_diag: zero out uninitialized idiag_{src,dst} fields
117     """
118     self.socketpairs = self._CreateLotsOfSockets()
119     sockets = self.sock_diag.DumpAllInetSockets(IPPROTO_TCP, NO_BYTECODE)
120     self.assertGreaterEqual(len(sockets), NUM_SOCKETS)
121
122     # Find the cookies for all of our sockets.
123     cookies = {}
124     for diag_msg, unused_attrs in sockets:
125       addr = self.sock_diag.GetSourceAddress(diag_msg)
126       sport = diag_msg.id.sport
127       dport = diag_msg.id.dport
128       if (addr, sport, dport) in self.socketpairs:
129         cookies[(addr, sport, dport)] = diag_msg.id.cookie
130       elif (addr, dport, sport) in self.socketpairs:
131         cookies[(addr, sport, dport)] = diag_msg.id.cookie
132
133     # Did we find all the cookies?
134     self.assertEquals(2 * NUM_SOCKETS, len(cookies))
135
136     socketpairs = self.socketpairs.values()
137     random.shuffle(socketpairs)
138     for socketpair in socketpairs:
139       for sock in socketpair:
140         # Check that we can find a diag_msg by scanning a dump.
141         self.assertSockDiagMatchesSocket(
142             sock,
143             self.sock_diag.FindSockDiagFromFd(sock))
144         cookie = self.sock_diag.FindSockDiagFromFd(sock).id.cookie
145
146         # Check that we can find a diag_msg once we know the cookie.
147         req = self.sock_diag.DiagReqFromSocket(sock)
148         req.id.cookie = cookie
149         diag_msg = self.sock_diag.GetSockDiag(req)
150         req.states = 1 << diag_msg.state
151         self.assertSockDiagMatchesSocket(sock, diag_msg)
152
153   def testBytecodeCompilation(self):
154     # pylint: disable=bad-whitespace
155     instructions = [
156         (sock_diag.INET_DIAG_BC_S_GE,   1, 8, 0),                      # 0
157         (sock_diag.INET_DIAG_BC_D_LE,   1, 7, 0xffff),                 # 8
158         (sock_diag.INET_DIAG_BC_S_COND, 1, 2, ("::1", 128, -1)),       # 16
159         (sock_diag.INET_DIAG_BC_JMP,    1, 3, None),                   # 44
160         (sock_diag.INET_DIAG_BC_S_COND, 2, 4, ("127.0.0.1", 32, -1)),  # 48
161         (sock_diag.INET_DIAG_BC_D_LE,   1, 3, 0x6665),  # not used     # 64
162         (sock_diag.INET_DIAG_BC_NOP,    1, 1, None),                   # 72
163                                                                        # 76 acc
164                                                                        # 80 rej
165     ]
166     # pylint: enable=bad-whitespace
167     bytecode = self.sock_diag.PackBytecode(instructions)
168     expected = (
169         "0208500000000000"
170         "050848000000ffff"
171         "071c20000a800000ffffffff00000000000000000000000000000001"
172         "01041c00"
173         "0718200002200000ffffffff7f000001"
174         "0508100000006566"
175         "00040400"
176     )
177     self.assertMultiLineEqual(expected, bytecode.encode("hex"))
178     self.assertEquals(76, len(bytecode))
179     self.socketpairs = self._CreateLotsOfSockets()
180     filteredsockets = self.sock_diag.DumpAllInetSockets(IPPROTO_TCP, bytecode)
181     allsockets = self.sock_diag.DumpAllInetSockets(IPPROTO_TCP, NO_BYTECODE)
182     self.assertItemsEqual(allsockets, filteredsockets)
183
184     # Pick a few sockets in hash table order, and check that the bytecode we
185     # compiled selects them properly.
186     for socketpair in self.socketpairs.values()[:20]:
187       for s in socketpair:
188         diag_msg = self.sock_diag.FindSockDiagFromFd(s)
189         instructions = [
190             (sock_diag.INET_DIAG_BC_S_GE, 1, 5, diag_msg.id.sport),
191             (sock_diag.INET_DIAG_BC_S_LE, 1, 4, diag_msg.id.sport),
192             (sock_diag.INET_DIAG_BC_D_GE, 1, 3, diag_msg.id.dport),
193             (sock_diag.INET_DIAG_BC_D_LE, 1, 2, diag_msg.id.dport),
194         ]
195         bytecode = self.sock_diag.PackBytecode(instructions)
196         self.assertEquals(32, len(bytecode))
197         sockets = self.sock_diag.DumpAllInetSockets(IPPROTO_TCP, bytecode)
198         self.assertEquals(1, len(sockets))
199
200         # TODO: why doesn't comparing the cstructs work?
201         self.assertEquals(diag_msg.Pack(), sockets[0][0].Pack())
202
203   def testCrossFamilyBytecode(self):
204     """Checks for a cross-family bug in inet_diag_hostcond matching.
205
206     Relevant kernel commits:
207       android-3.4:
208         f67caec inet_diag: avoid unsafe and nonsensical prefix matches in inet_diag_bc_run()
209     """
210     # TODO: this is only here because the test fails if there are any open
211     # sockets other than the ones it creates itself. Make the bytecode more
212     # specific and remove it.
213     self.assertFalse(self.sock_diag.DumpAllInetSockets(IPPROTO_TCP, ""))
214
215     unused_pair4 = net_test.CreateSocketPair(AF_INET, SOCK_STREAM, "127.0.0.1")
216     unused_pair6 = net_test.CreateSocketPair(AF_INET6, SOCK_STREAM, "::1")
217
218     bytecode4 = self.sock_diag.PackBytecode([
219         (sock_diag.INET_DIAG_BC_S_COND, 1, 2, ("0.0.0.0", 0, -1))])
220     bytecode6 = self.sock_diag.PackBytecode([
221         (sock_diag.INET_DIAG_BC_S_COND, 1, 2, ("::", 0, -1))])
222
223     # IPv4/v6 filters must never match IPv6/IPv4 sockets...
224     v4sockets = self.sock_diag.DumpAllInetSockets(IPPROTO_TCP, bytecode4)
225     self.assertTrue(v4sockets)
226     self.assertTrue(all(d.family == AF_INET for d, _ in v4sockets))
227
228     v6sockets = self.sock_diag.DumpAllInetSockets(IPPROTO_TCP, bytecode6)
229     self.assertTrue(v6sockets)
230     self.assertTrue(all(d.family == AF_INET6 for d, _ in v6sockets))
231
232     # Except for mapped addresses, which match both IPv4 and IPv6.
233     pair5 = net_test.CreateSocketPair(AF_INET6, SOCK_STREAM,
234                                       "::ffff:127.0.0.1")
235     diag_msgs = [self.sock_diag.FindSockDiagFromFd(s) for s in pair5]
236     v4sockets = [d for d, _ in self.sock_diag.DumpAllInetSockets(IPPROTO_TCP,
237                                                                  bytecode4)]
238     v6sockets = [d for d, _ in self.sock_diag.DumpAllInetSockets(IPPROTO_TCP,
239                                                                  bytecode6)]
240     self.assertTrue(all(d in v4sockets for d in diag_msgs))
241     self.assertTrue(all(d in v6sockets for d in diag_msgs))
242
243   def testPortComparisonValidation(self):
244     """Checks for a bug in validating port comparison bytecode.
245
246     Relevant kernel commits:
247       android-3.4:
248         5e1f542 inet_diag: validate port comparison byte code to prevent unsafe reads
249     """
250     bytecode = sock_diag.InetDiagBcOp((sock_diag.INET_DIAG_BC_D_GE, 4, 8))
251     self.assertRaisesErrno(
252         EINVAL,
253         self.sock_diag.DumpAllInetSockets, IPPROTO_TCP, bytecode.Pack())
254
255   def testNonSockDiagCommand(self):
256     def DiagDump(code):
257       sock_id = self.sock_diag._EmptyInetDiagSockId()
258       req = sock_diag.InetDiagReqV2((AF_INET6, IPPROTO_TCP, 0, 0xffffffff,
259                                      sock_id))
260       self.sock_diag._Dump(code, req, sock_diag.InetDiagMsg, "")
261
262     op = sock_diag.SOCK_DIAG_BY_FAMILY
263     DiagDump(op)  # No errors? Good.
264     self.assertRaisesErrno(EINVAL, DiagDump, op + 17)
265
266
267 class SockDestroyTest(SockDiagBaseTest):
268   """Tests that SOCK_DESTROY works correctly.
269
270   Relevant kernel commits:
271     net-next:
272       b613f56 net: diag: split inet_diag_dump_one_icsk into two
273       64be0ae net: diag: Add the ability to destroy a socket.
274       6eb5d2e net: diag: Support SOCK_DESTROY for inet sockets.
275       c1e64e2 net: diag: Support destroying TCP sockets.
276       2010b93 net: tcp: deal with listen sockets properly in tcp_abort.
277
278     android-3.4:
279       d48ec88 net: diag: split inet_diag_dump_one_icsk into two
280       2438189 net: diag: Add the ability to destroy a socket.
281       7a2ddbc net: diag: Support SOCK_DESTROY for inet sockets.
282       44047b2 net: diag: Support destroying TCP sockets.
283       200dae7 net: tcp: deal with listen sockets properly in tcp_abort.
284
285     android-3.10:
286       9eaff90 net: diag: split inet_diag_dump_one_icsk into two
287       d60326c net: diag: Add the ability to destroy a socket.
288       3d4ce85 net: diag: Support SOCK_DESTROY for inet sockets.
289       529dfc6 net: diag: Support destroying TCP sockets.
290       9c712fe net: tcp: deal with listen sockets properly in tcp_abort.
291
292     android-3.18:
293       100263d net: diag: split inet_diag_dump_one_icsk into two
294       194c5f3 net: diag: Add the ability to destroy a socket.
295       8387ea2 net: diag: Support SOCK_DESTROY for inet sockets.
296       b80585a net: diag: Support destroying TCP sockets.
297       476c6ce net: tcp: deal with listen sockets properly in tcp_abort.
298   """
299
300   def testClosesSockets(self):
301     self.socketpairs = self._CreateLotsOfSockets()
302     for _, socketpair in self.socketpairs.iteritems():
303       # Close one of the sockets.
304       # This will send a RST that will close the other side as well.
305       s = random.choice(socketpair)
306       if random.randrange(0, 2) == 1:
307         self.sock_diag.CloseSocketFromFd(s)
308       else:
309         diag_msg = self.sock_diag.FindSockDiagFromFd(s)
310
311         # Get the cookie wrong and ensure that we get an error and the socket
312         # is not closed.
313         real_cookie = diag_msg.id.cookie
314         diag_msg.id.cookie = os.urandom(len(real_cookie))
315         req = self.sock_diag.DiagReqFromDiagMsg(diag_msg, IPPROTO_TCP)
316         self.assertRaisesErrno(ENOENT, self.sock_diag.CloseSocket, req)
317         self.assertSocketConnected(s)
318
319         # Now close it with the correct cookie.
320         req.id.cookie = real_cookie
321         self.sock_diag.CloseSocket(req)
322
323       # Check that both sockets in the pair are closed.
324       self.assertSocketsClosed(socketpair)
325
326   def testNonTcpSockets(self):
327     s = socket(AF_INET6, SOCK_DGRAM, 0)
328     s.connect(("::1", 53))
329     self.sock_diag.FindSockDiagFromFd(s)  # No exceptions? Good.
330     self.assertRaisesErrno(EOPNOTSUPP, self.sock_diag.CloseSocketFromFd, s)
331
332   # TODO:
333   # Test that killing unix sockets returns EOPNOTSUPP.
334
335
336 class SocketExceptionThread(threading.Thread):
337
338   def __init__(self, sock, operation):
339     self.exception = None
340     super(SocketExceptionThread, self).__init__()
341     self.daemon = True
342     self.sock = sock
343     self.operation = operation
344
345   def run(self):
346     try:
347       self.operation(self.sock)
348     except IOError, e:
349       self.exception = e
350
351
352 class SockDiagTcpTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
353
354   def testIpv4MappedSynRecvSocket(self):
355     """Tests for the absence of a bug with AF_INET6 TCP SYN-RECV sockets.
356
357     Relevant kernel commits:
358          android-3.4:
359            457a04b inet_diag: fix oops for IPv4 AF_INET6 TCP SYN-RECV state
360     """
361     netid = random.choice(self.tuns.keys())
362     self.IncomingConnection(5, tcp_test.TCP_SYN_RECV, netid)
363     sock_id = self.sock_diag._EmptyInetDiagSockId()
364     sock_id.sport = self.port
365     states = 1 << tcp_test.TCP_SYN_RECV
366     req = sock_diag.InetDiagReqV2((AF_INET6, IPPROTO_TCP, 0, states, sock_id))
367     children = self.sock_diag.Dump(req, NO_BYTECODE)
368
369     self.assertTrue(children)
370     for child, unused_args in children:
371       self.assertEqual(tcp_test.TCP_SYN_RECV, child.state)
372       self.assertEqual(self.sock_diag.PaddedAddress(self.remoteaddr),
373                        child.id.dst)
374       self.assertEqual(self.sock_diag.PaddedAddress(self.myaddr),
375                        child.id.src)
376
377
378 class SockDestroyTcpTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
379
380   def setUp(self):
381     super(SockDestroyTcpTest, self).setUp()
382     self.netid = random.choice(self.tuns.keys())
383
384   def CheckRstOnClose(self, sock, req, expect_reset, msg, do_close=True):
385     """Closes the socket and checks whether a RST is sent or not."""
386     if sock is not None:
387       self.assertIsNone(req, "Must specify sock or req, not both")
388       self.sock_diag.CloseSocketFromFd(sock)
389       self.assertRaisesErrno(EINVAL, sock.accept)
390     else:
391       self.assertIsNone(sock, "Must specify sock or req, not both")
392       self.sock_diag.CloseSocket(req)
393
394     if expect_reset:
395       desc, rst = self.RstPacket()
396       msg = "%s: expecting %s: " % (msg, desc)
397       self.ExpectPacketOn(self.netid, msg, rst)
398     else:
399       msg = "%s: " % msg
400       self.ExpectNoPacketsOn(self.netid, msg)
401
402     if sock is not None and do_close:
403       sock.close()
404
405   def CheckTcpReset(self, state, statename):
406     for version in [4, 5, 6]:
407       msg = "Closing incoming IPv%d %s socket" % (version, statename)
408       self.IncomingConnection(version, state, self.netid)
409       self.CheckRstOnClose(self.s, None, False, msg)
410       if state != tcp_test.TCP_LISTEN:
411         msg = "Closing accepted IPv%d %s socket" % (version, statename)
412         self.CheckRstOnClose(self.accepted, None, True, msg)
413
414   def testTcpResets(self):
415     """Checks that closing sockets in appropriate states sends a RST."""
416     self.CheckTcpReset(tcp_test.TCP_LISTEN, "TCP_LISTEN")
417     self.CheckTcpReset(tcp_test.TCP_ESTABLISHED, "TCP_ESTABLISHED")
418     self.CheckTcpReset(tcp_test.TCP_CLOSE_WAIT, "TCP_CLOSE_WAIT")
419
420   def FindChildSockets(self, s):
421     """Finds the SYN_RECV child sockets of a given listening socket."""
422     d = self.sock_diag.FindSockDiagFromFd(self.s)
423     req = self.sock_diag.DiagReqFromDiagMsg(d, IPPROTO_TCP)
424     req.states = 1 << tcp_test.TCP_SYN_RECV | 1 << tcp_test.TCP_ESTABLISHED
425     req.id.cookie = "\x00" * 8
426     children = self.sock_diag.Dump(req, NO_BYTECODE)
427     return [self.sock_diag.DiagReqFromDiagMsg(d, IPPROTO_TCP)
428             for d, _ in children]
429
430   def CheckChildSocket(self, version, statename, parent_first):
431     state = getattr(tcp_test, statename)
432
433     self.IncomingConnection(version, state, self.netid)
434
435     d = self.sock_diag.FindSockDiagFromFd(self.s)
436     parent = self.sock_diag.DiagReqFromDiagMsg(d, IPPROTO_TCP)
437     children = self.FindChildSockets(self.s)
438     self.assertEquals(1, len(children))
439
440     is_established = (state == tcp_test.TCP_NOT_YET_ACCEPTED)
441
442     # The new TCP listener code in 4.4 makes SYN_RECV sockets live in the
443     # regular TCP hash tables, and inet_diag_find_one_icsk can find them.
444     # Before 4.4, we can see those sockets in dumps, but we can't fetch
445     # or close them.
446     can_close_children = is_established or net_test.LINUX_VERSION >= (4, 4)
447
448     for child in children:
449       if can_close_children:
450         self.sock_diag.GetSockDiag(child)  # No errors? Good, child found.
451       else:
452         self.assertRaisesErrno(ENOENT, self.sock_diag.GetSockDiag, child)
453
454     def CloseParent(expect_reset):
455       msg = "Closing parent IPv%d %s socket %s child" % (
456           version, statename, "before" if parent_first else "after")
457       self.CheckRstOnClose(self.s, None, expect_reset, msg)
458       self.assertRaisesErrno(ENOENT, self.sock_diag.GetSockDiag, parent)
459
460     def CheckChildrenClosed():
461       for child in children:
462         self.assertRaisesErrno(ENOENT, self.sock_diag.GetSockDiag, child)
463
464     def CloseChildren():
465       for child in children:
466         msg = "Closing child IPv%d %s socket %s parent" % (
467             version, statename, "after" if parent_first else "before")
468         self.sock_diag.GetSockDiag(child)
469         self.CheckRstOnClose(None, child, is_established, msg)
470         self.assertRaisesErrno(ENOENT, self.sock_diag.GetSockDiag, child)
471       CheckChildrenClosed()
472
473     if parent_first:
474       # Closing the parent will close child sockets, which will send a RST,
475       # iff they are already established.
476       CloseParent(is_established)
477       if is_established:
478         CheckChildrenClosed()
479       elif can_close_children:
480         CloseChildren()
481         CheckChildrenClosed()
482       self.s.close()
483     else:
484       if can_close_children:
485         CloseChildren()
486       CloseParent(False)
487       self.s.close()
488
489   def testChildSockets(self):
490     for version in [4, 5, 6]:
491       self.CheckChildSocket(version, "TCP_SYN_RECV", False)
492       self.CheckChildSocket(version, "TCP_SYN_RECV", True)
493       self.CheckChildSocket(version, "TCP_NOT_YET_ACCEPTED", False)
494       self.CheckChildSocket(version, "TCP_NOT_YET_ACCEPTED", True)
495
496   def CloseDuringBlockingCall(self, sock, call, expected_errno):
497     thread = SocketExceptionThread(sock, call)
498     thread.start()
499     time.sleep(0.1)
500     self.sock_diag.CloseSocketFromFd(sock)
501     thread.join(1)
502     self.assertFalse(thread.is_alive())
503     self.assertIsNotNone(thread.exception)
504     self.assertTrue(isinstance(thread.exception, IOError),
505                     "Expected IOError, got %s" % thread.exception)
506     self.assertEqual(expected_errno, thread.exception.errno)
507     self.assertSocketClosed(sock)
508
509   def testAcceptInterrupted(self):
510     """Tests that accept() is interrupted by SOCK_DESTROY."""
511     for version in [4, 5, 6]:
512       self.IncomingConnection(version, tcp_test.TCP_LISTEN, self.netid)
513       self.CloseDuringBlockingCall(self.s, lambda sock: sock.accept(), EINVAL)
514       self.assertRaisesErrno(ECONNABORTED, self.s.send, "foo")
515       self.assertRaisesErrno(EINVAL, self.s.accept)
516
517   def testReadInterrupted(self):
518     """Tests that read() is interrupted by SOCK_DESTROY."""
519     for version in [4, 5, 6]:
520       self.IncomingConnection(version, tcp_test.TCP_ESTABLISHED, self.netid)
521       self.CloseDuringBlockingCall(self.accepted, lambda sock: sock.recv(4096),
522                                    ECONNABORTED)
523       self.assertRaisesErrno(EPIPE, self.accepted.send, "foo")
524
525   def testConnectInterrupted(self):
526     """Tests that connect() is interrupted by SOCK_DESTROY."""
527     for version in [4, 5, 6]:
528       family = {4: AF_INET, 5: AF_INET6, 6: AF_INET6}[version]
529       s = net_test.Socket(family, SOCK_STREAM, IPPROTO_TCP)
530       self.SelectInterface(s, self.netid, "mark")
531       if version == 5:
532         remoteaddr = "::ffff:" + self.GetRemoteAddress(4)
533         version = 4
534       else:
535         remoteaddr = self.GetRemoteAddress(version)
536       s.bind(("", 0))
537       _, sport = s.getsockname()[:2]
538       self.CloseDuringBlockingCall(
539           s, lambda sock: sock.connect((remoteaddr, 53)), ECONNABORTED)
540       desc, syn = packets.SYN(53, version, self.MyAddress(version, self.netid),
541                               remoteaddr, sport=sport, seq=None)
542       self.ExpectPacketOn(self.netid, desc, syn)
543       msg = "SOCK_DESTROY of socket in connect, expected no RST"
544       self.ExpectNoPacketsOn(self.netid, msg)
545
546
547 if __name__ == "__main__":
548   unittest.main()