OSDN Git Service

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