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() 549