1*2f2c4c7aSAndroid Build Coastguard Worker#!/usr/bin/python3 2*2f2c4c7aSAndroid Build Coastguard Worker# 3*2f2c4c7aSAndroid Build Coastguard Worker# Copyright 2015 The Android Open Source Project 4*2f2c4c7aSAndroid Build Coastguard Worker# 5*2f2c4c7aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*2f2c4c7aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*2f2c4c7aSAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*2f2c4c7aSAndroid Build Coastguard Worker# 9*2f2c4c7aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*2f2c4c7aSAndroid Build Coastguard Worker# 11*2f2c4c7aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*2f2c4c7aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*2f2c4c7aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*2f2c4c7aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*2f2c4c7aSAndroid Build Coastguard Worker# limitations under the License. 16*2f2c4c7aSAndroid Build Coastguard Worker 17*2f2c4c7aSAndroid Build Coastguard Worker# pylint: disable=g-bad-todo,g-bad-file-header,wildcard-import 18*2f2c4c7aSAndroid Build Coastguard Workerfrom errno import * # pylint: disable=wildcard-import 19*2f2c4c7aSAndroid Build Coastguard Workerimport binascii 20*2f2c4c7aSAndroid Build Coastguard Workerimport os 21*2f2c4c7aSAndroid Build Coastguard Workerimport random 22*2f2c4c7aSAndroid Build Coastguard Workerimport select 23*2f2c4c7aSAndroid Build Coastguard Workerfrom socket import * # pylint: disable=wildcard-import 24*2f2c4c7aSAndroid Build Coastguard Workerimport struct 25*2f2c4c7aSAndroid Build Coastguard Workerimport threading 26*2f2c4c7aSAndroid Build Coastguard Workerimport time 27*2f2c4c7aSAndroid Build Coastguard Workerimport unittest 28*2f2c4c7aSAndroid Build Coastguard Worker 29*2f2c4c7aSAndroid Build Coastguard Workerimport cstruct 30*2f2c4c7aSAndroid Build Coastguard Workerimport multinetwork_base 31*2f2c4c7aSAndroid Build Coastguard Workerimport net_test 32*2f2c4c7aSAndroid Build Coastguard Workerimport packets 33*2f2c4c7aSAndroid Build Coastguard Workerimport sock_diag 34*2f2c4c7aSAndroid Build Coastguard Workerimport tcp_test 35*2f2c4c7aSAndroid Build Coastguard Worker 36*2f2c4c7aSAndroid Build Coastguard Worker# Mostly empty structure definition containing only the fields we currently use. 37*2f2c4c7aSAndroid Build Coastguard WorkerTcpInfo = cstruct.Struct("TcpInfo", "64xI", "tcpi_rcv_ssthresh") 38*2f2c4c7aSAndroid Build Coastguard Worker 39*2f2c4c7aSAndroid Build Coastguard WorkerNUM_SOCKETS = 30 40*2f2c4c7aSAndroid Build Coastguard WorkerNO_BYTECODE = b"" 41*2f2c4c7aSAndroid Build Coastguard Worker 42*2f2c4c7aSAndroid Build Coastguard WorkerIPPROTO_SCTP = 132 43*2f2c4c7aSAndroid Build Coastguard Worker 44*2f2c4c7aSAndroid Build Coastguard Workerdef HaveSctp(): 45*2f2c4c7aSAndroid Build Coastguard Worker try: 46*2f2c4c7aSAndroid Build Coastguard Worker s = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP) 47*2f2c4c7aSAndroid Build Coastguard Worker s.close() 48*2f2c4c7aSAndroid Build Coastguard Worker return True 49*2f2c4c7aSAndroid Build Coastguard Worker except IOError: 50*2f2c4c7aSAndroid Build Coastguard Worker return False 51*2f2c4c7aSAndroid Build Coastguard Worker 52*2f2c4c7aSAndroid Build Coastguard WorkerHAVE_SCTP = HaveSctp() 53*2f2c4c7aSAndroid Build Coastguard Worker 54*2f2c4c7aSAndroid Build Coastguard Worker 55*2f2c4c7aSAndroid Build Coastguard Workerclass SockDiagBaseTest(multinetwork_base.MultiNetworkBaseTest): 56*2f2c4c7aSAndroid Build Coastguard Worker """Basic tests for SOCK_DIAG functionality. 57*2f2c4c7aSAndroid Build Coastguard Worker 58*2f2c4c7aSAndroid Build Coastguard Worker Relevant kernel commits: 59*2f2c4c7aSAndroid Build Coastguard Worker android-3.4: 60*2f2c4c7aSAndroid Build Coastguard Worker ab4a727 net: inet_diag: zero out uninitialized idiag_{src,dst} fields 61*2f2c4c7aSAndroid Build Coastguard Worker 99ee451 net: diag: support v4mapped sockets in inet_diag_find_one_icsk() 62*2f2c4c7aSAndroid Build Coastguard Worker 63*2f2c4c7aSAndroid Build Coastguard Worker android-3.10: 64*2f2c4c7aSAndroid Build Coastguard Worker 3eb409b net: inet_diag: zero out uninitialized idiag_{src,dst} fields 65*2f2c4c7aSAndroid Build Coastguard Worker f77e059 net: diag: support v4mapped sockets in inet_diag_find_one_icsk() 66*2f2c4c7aSAndroid Build Coastguard Worker 67*2f2c4c7aSAndroid Build Coastguard Worker android-3.18: 68*2f2c4c7aSAndroid Build Coastguard Worker e603010 net: diag: support v4mapped sockets in inet_diag_find_one_icsk() 69*2f2c4c7aSAndroid Build Coastguard Worker 70*2f2c4c7aSAndroid Build Coastguard Worker android-4.4: 71*2f2c4c7aSAndroid Build Coastguard Worker 525ee59 net: diag: support v4mapped sockets in inet_diag_find_one_icsk() 72*2f2c4c7aSAndroid Build Coastguard Worker """ 73*2f2c4c7aSAndroid Build Coastguard Worker @staticmethod 74*2f2c4c7aSAndroid Build Coastguard Worker def _CreateLotsOfSockets(socktype): 75*2f2c4c7aSAndroid Build Coastguard Worker # Dict mapping (addr, sport, dport) tuples to socketpairs. 76*2f2c4c7aSAndroid Build Coastguard Worker socketpairs = {} 77*2f2c4c7aSAndroid Build Coastguard Worker for _ in range(NUM_SOCKETS): 78*2f2c4c7aSAndroid Build Coastguard Worker family, addr = random.choice([ 79*2f2c4c7aSAndroid Build Coastguard Worker (AF_INET, "127.0.0.1"), 80*2f2c4c7aSAndroid Build Coastguard Worker (AF_INET6, "::1"), 81*2f2c4c7aSAndroid Build Coastguard Worker (AF_INET6, "::ffff:127.0.0.1")]) 82*2f2c4c7aSAndroid Build Coastguard Worker socketpair = net_test.CreateSocketPair(family, socktype, addr) 83*2f2c4c7aSAndroid Build Coastguard Worker sport, dport = (socketpair[0].getsockname()[1], 84*2f2c4c7aSAndroid Build Coastguard Worker socketpair[1].getsockname()[1]) 85*2f2c4c7aSAndroid Build Coastguard Worker socketpairs[(addr, sport, dport)] = socketpair 86*2f2c4c7aSAndroid Build Coastguard Worker return socketpairs 87*2f2c4c7aSAndroid Build Coastguard Worker 88*2f2c4c7aSAndroid Build Coastguard Worker def assertSocketClosed(self, sock): 89*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(ENOTCONN, sock.getpeername) 90*2f2c4c7aSAndroid Build Coastguard Worker 91*2f2c4c7aSAndroid Build Coastguard Worker def assertSocketConnected(self, sock): 92*2f2c4c7aSAndroid Build Coastguard Worker sock.getpeername() # No errors? Socket is alive and connected. 93*2f2c4c7aSAndroid Build Coastguard Worker 94*2f2c4c7aSAndroid Build Coastguard Worker def assertSocketsClosed(self, socketpair): 95*2f2c4c7aSAndroid Build Coastguard Worker for sock in socketpair: 96*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketClosed(sock) 97*2f2c4c7aSAndroid Build Coastguard Worker 98*2f2c4c7aSAndroid Build Coastguard Worker def assertMarkIs(self, mark, attrs): 99*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(mark, attrs.get("INET_DIAG_MARK", None)) 100*2f2c4c7aSAndroid Build Coastguard Worker 101*2f2c4c7aSAndroid Build Coastguard Worker def assertSockInfoMatchesSocket(self, s, info): 102*2f2c4c7aSAndroid Build Coastguard Worker diag_msg, attrs = info 103*2f2c4c7aSAndroid Build Coastguard Worker family = s.getsockopt(net_test.SOL_SOCKET, net_test.SO_DOMAIN) 104*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(diag_msg.family, family) 105*2f2c4c7aSAndroid Build Coastguard Worker 106*2f2c4c7aSAndroid Build Coastguard Worker src, sport = s.getsockname()[0:2] 107*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(diag_msg.id.src, self.sock_diag.PaddedAddress(src)) 108*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(diag_msg.id.sport, sport) 109*2f2c4c7aSAndroid Build Coastguard Worker 110*2f2c4c7aSAndroid Build Coastguard Worker if self.sock_diag.GetDestinationAddress(diag_msg) not in ["0.0.0.0", "::"]: 111*2f2c4c7aSAndroid Build Coastguard Worker dst, dport = s.getpeername()[0:2] 112*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(diag_msg.id.dst, self.sock_diag.PaddedAddress(dst)) 113*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(diag_msg.id.dport, dport) 114*2f2c4c7aSAndroid Build Coastguard Worker else: 115*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(ENOTCONN, s.getpeername) 116*2f2c4c7aSAndroid Build Coastguard Worker 117*2f2c4c7aSAndroid Build Coastguard Worker mark = s.getsockopt(SOL_SOCKET, net_test.SO_MARK) 118*2f2c4c7aSAndroid Build Coastguard Worker self.assertMarkIs(mark, attrs) 119*2f2c4c7aSAndroid Build Coastguard Worker 120*2f2c4c7aSAndroid Build Coastguard Worker def PackAndCheckBytecode(self, instructions): 121*2f2c4c7aSAndroid Build Coastguard Worker bytecode = self.sock_diag.PackBytecode(instructions) 122*2f2c4c7aSAndroid Build Coastguard Worker decoded = self.sock_diag.DecodeBytecode(bytecode) 123*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(len(instructions), len(decoded)) 124*2f2c4c7aSAndroid Build Coastguard Worker self.assertFalse("???" in decoded) 125*2f2c4c7aSAndroid Build Coastguard Worker return bytecode 126*2f2c4c7aSAndroid Build Coastguard Worker 127*2f2c4c7aSAndroid Build Coastguard Worker def _EventDuringBlockingCall(self, sock, call, expected_errno, event): 128*2f2c4c7aSAndroid Build Coastguard Worker """Simulates an external event during a blocking call on sock. 129*2f2c4c7aSAndroid Build Coastguard Worker 130*2f2c4c7aSAndroid Build Coastguard Worker Args: 131*2f2c4c7aSAndroid Build Coastguard Worker sock: The socket to use. 132*2f2c4c7aSAndroid Build Coastguard Worker call: A function, the call to make. Takes one parameter, sock. 133*2f2c4c7aSAndroid Build Coastguard Worker expected_errno: The value that call is expected to fail with, or None if 134*2f2c4c7aSAndroid Build Coastguard Worker call is expected to succeed. 135*2f2c4c7aSAndroid Build Coastguard Worker event: A function, the event that will happen during the blocking call. 136*2f2c4c7aSAndroid Build Coastguard Worker Takes one parameter, sock. 137*2f2c4c7aSAndroid Build Coastguard Worker """ 138*2f2c4c7aSAndroid Build Coastguard Worker thread = SocketExceptionThread(sock, call) 139*2f2c4c7aSAndroid Build Coastguard Worker thread.start() 140*2f2c4c7aSAndroid Build Coastguard Worker time.sleep(0.1) 141*2f2c4c7aSAndroid Build Coastguard Worker event(sock) 142*2f2c4c7aSAndroid Build Coastguard Worker thread.join(1) 143*2f2c4c7aSAndroid Build Coastguard Worker self.assertFalse(thread.is_alive()) 144*2f2c4c7aSAndroid Build Coastguard Worker if expected_errno is not None: 145*2f2c4c7aSAndroid Build Coastguard Worker self.assertIsNotNone(thread.exception) 146*2f2c4c7aSAndroid Build Coastguard Worker self.assertTrue(isinstance(thread.exception, IOError), 147*2f2c4c7aSAndroid Build Coastguard Worker "Expected IOError, got %s" % thread.exception) 148*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(expected_errno, thread.exception.errno) 149*2f2c4c7aSAndroid Build Coastguard Worker else: 150*2f2c4c7aSAndroid Build Coastguard Worker self.assertIsNone(thread.exception) 151*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketClosed(sock) 152*2f2c4c7aSAndroid Build Coastguard Worker 153*2f2c4c7aSAndroid Build Coastguard Worker def CloseDuringBlockingCall(self, sock, call, expected_errno): 154*2f2c4c7aSAndroid Build Coastguard Worker self._EventDuringBlockingCall( 155*2f2c4c7aSAndroid Build Coastguard Worker sock, call, expected_errno, 156*2f2c4c7aSAndroid Build Coastguard Worker lambda sock: self.sock_diag.CloseSocketFromFd(sock)) 157*2f2c4c7aSAndroid Build Coastguard Worker 158*2f2c4c7aSAndroid Build Coastguard Worker def setUp(self): 159*2f2c4c7aSAndroid Build Coastguard Worker super(SockDiagBaseTest, self).setUp() 160*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag = sock_diag.SockDiag() 161*2f2c4c7aSAndroid Build Coastguard Worker self.socketpairs = {} 162*2f2c4c7aSAndroid Build Coastguard Worker 163*2f2c4c7aSAndroid Build Coastguard Worker def tearDown(self): 164*2f2c4c7aSAndroid Build Coastguard Worker for socketpair in list(self.socketpairs.values()): 165*2f2c4c7aSAndroid Build Coastguard Worker for s in socketpair: 166*2f2c4c7aSAndroid Build Coastguard Worker s.close() 167*2f2c4c7aSAndroid Build Coastguard Worker super(SockDiagBaseTest, self).tearDown() 168*2f2c4c7aSAndroid Build Coastguard Worker 169*2f2c4c7aSAndroid Build Coastguard Worker 170*2f2c4c7aSAndroid Build Coastguard Workerclass SockDiagTest(SockDiagBaseTest): 171*2f2c4c7aSAndroid Build Coastguard Worker 172*2f2c4c7aSAndroid Build Coastguard Worker def testFindsMappedSockets(self): 173*2f2c4c7aSAndroid Build Coastguard Worker """Tests that inet_diag_find_one_icsk can find mapped sockets.""" 174*2f2c4c7aSAndroid Build Coastguard Worker socketpair = net_test.CreateSocketPair(AF_INET6, SOCK_STREAM, 175*2f2c4c7aSAndroid Build Coastguard Worker "::ffff:127.0.0.1") 176*2f2c4c7aSAndroid Build Coastguard Worker for sock in socketpair: 177*2f2c4c7aSAndroid Build Coastguard Worker diag_msg = self.sock_diag.FindSockDiagFromFd(sock) 178*2f2c4c7aSAndroid Build Coastguard Worker diag_req = self.sock_diag.DiagReqFromDiagMsg(diag_msg, IPPROTO_TCP) 179*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.GetSockInfo(diag_req) 180*2f2c4c7aSAndroid Build Coastguard Worker # No errors? Good. 181*2f2c4c7aSAndroid Build Coastguard Worker 182*2f2c4c7aSAndroid Build Coastguard Worker for sock in socketpair: 183*2f2c4c7aSAndroid Build Coastguard Worker sock.close() 184*2f2c4c7aSAndroid Build Coastguard Worker 185*2f2c4c7aSAndroid Build Coastguard Worker def CheckFindsAllMySockets(self, socktype, proto): 186*2f2c4c7aSAndroid Build Coastguard Worker """Tests that basic socket dumping works.""" 187*2f2c4c7aSAndroid Build Coastguard Worker self.socketpairs = self._CreateLotsOfSockets(socktype) 188*2f2c4c7aSAndroid Build Coastguard Worker sockets = self.sock_diag.DumpAllInetSockets(proto, NO_BYTECODE) 189*2f2c4c7aSAndroid Build Coastguard Worker self.assertGreaterEqual(len(sockets), NUM_SOCKETS) 190*2f2c4c7aSAndroid Build Coastguard Worker 191*2f2c4c7aSAndroid Build Coastguard Worker # Find the cookies for all of our sockets. 192*2f2c4c7aSAndroid Build Coastguard Worker cookies = {} 193*2f2c4c7aSAndroid Build Coastguard Worker for diag_msg, unused_attrs in sockets: 194*2f2c4c7aSAndroid Build Coastguard Worker addr = self.sock_diag.GetSourceAddress(diag_msg) 195*2f2c4c7aSAndroid Build Coastguard Worker sport = diag_msg.id.sport 196*2f2c4c7aSAndroid Build Coastguard Worker dport = diag_msg.id.dport 197*2f2c4c7aSAndroid Build Coastguard Worker if (addr, sport, dport) in self.socketpairs: 198*2f2c4c7aSAndroid Build Coastguard Worker cookies[(addr, sport, dport)] = diag_msg.id.cookie 199*2f2c4c7aSAndroid Build Coastguard Worker elif (addr, dport, sport) in self.socketpairs: 200*2f2c4c7aSAndroid Build Coastguard Worker cookies[(addr, sport, dport)] = diag_msg.id.cookie 201*2f2c4c7aSAndroid Build Coastguard Worker 202*2f2c4c7aSAndroid Build Coastguard Worker # Did we find all the cookies? 203*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(2 * NUM_SOCKETS, len(cookies)) 204*2f2c4c7aSAndroid Build Coastguard Worker 205*2f2c4c7aSAndroid Build Coastguard Worker socketpairs = list(self.socketpairs.values()) 206*2f2c4c7aSAndroid Build Coastguard Worker random.shuffle(socketpairs) 207*2f2c4c7aSAndroid Build Coastguard Worker for socketpair in socketpairs: 208*2f2c4c7aSAndroid Build Coastguard Worker for sock in socketpair: 209*2f2c4c7aSAndroid Build Coastguard Worker # Check that we can find a diag_msg by scanning a dump. 210*2f2c4c7aSAndroid Build Coastguard Worker self.assertSockInfoMatchesSocket( 211*2f2c4c7aSAndroid Build Coastguard Worker sock, 212*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.FindSockInfoFromFd(sock)) 213*2f2c4c7aSAndroid Build Coastguard Worker cookie = self.sock_diag.FindSockDiagFromFd(sock).id.cookie 214*2f2c4c7aSAndroid Build Coastguard Worker 215*2f2c4c7aSAndroid Build Coastguard Worker # Check that we can find a diag_msg once we know the cookie. 216*2f2c4c7aSAndroid Build Coastguard Worker req = self.sock_diag.DiagReqFromSocket(sock) 217*2f2c4c7aSAndroid Build Coastguard Worker req.id.cookie = cookie 218*2f2c4c7aSAndroid Build Coastguard Worker if proto == IPPROTO_UDP: 219*2f2c4c7aSAndroid Build Coastguard Worker # Kernel bug: for UDP sockets, the order of arguments must be swapped. 220*2f2c4c7aSAndroid Build Coastguard Worker # See testDemonstrateUdpGetSockIdBug. 221*2f2c4c7aSAndroid Build Coastguard Worker req.id.sport, req.id.dport = req.id.dport, req.id.sport 222*2f2c4c7aSAndroid Build Coastguard Worker req.id.src, req.id.dst = req.id.dst, req.id.src 223*2f2c4c7aSAndroid Build Coastguard Worker info = self.sock_diag.GetSockInfo(req) 224*2f2c4c7aSAndroid Build Coastguard Worker self.assertSockInfoMatchesSocket(sock, info) 225*2f2c4c7aSAndroid Build Coastguard Worker 226*2f2c4c7aSAndroid Build Coastguard Worker for socketpair in socketpairs: 227*2f2c4c7aSAndroid Build Coastguard Worker for sock in socketpair: 228*2f2c4c7aSAndroid Build Coastguard Worker sock.close() 229*2f2c4c7aSAndroid Build Coastguard Worker 230*2f2c4c7aSAndroid Build Coastguard Worker def assertItemsEqual(self, expected, actual): 231*2f2c4c7aSAndroid Build Coastguard Worker try: 232*2f2c4c7aSAndroid Build Coastguard Worker super(SockDiagTest, self).assertItemsEqual(expected, actual) 233*2f2c4c7aSAndroid Build Coastguard Worker except AttributeError: 234*2f2c4c7aSAndroid Build Coastguard Worker # This was renamed in python3 but has the same behaviour. 235*2f2c4c7aSAndroid Build Coastguard Worker super(SockDiagTest, self).assertCountEqual(expected, actual) 236*2f2c4c7aSAndroid Build Coastguard Worker 237*2f2c4c7aSAndroid Build Coastguard Worker def testFindsAllMySocketsTcp(self): 238*2f2c4c7aSAndroid Build Coastguard Worker self.CheckFindsAllMySockets(SOCK_STREAM, IPPROTO_TCP) 239*2f2c4c7aSAndroid Build Coastguard Worker 240*2f2c4c7aSAndroid Build Coastguard Worker def testFindsAllMySocketsUdp(self): 241*2f2c4c7aSAndroid Build Coastguard Worker self.CheckFindsAllMySockets(SOCK_DGRAM, IPPROTO_UDP) 242*2f2c4c7aSAndroid Build Coastguard Worker 243*2f2c4c7aSAndroid Build Coastguard Worker def testBytecodeCompilation(self): 244*2f2c4c7aSAndroid Build Coastguard Worker # pylint: disable=bad-whitespace 245*2f2c4c7aSAndroid Build Coastguard Worker instructions = [ 246*2f2c4c7aSAndroid Build Coastguard Worker (sock_diag.INET_DIAG_BC_S_GE, 1, 8, 0), # 0 247*2f2c4c7aSAndroid Build Coastguard Worker (sock_diag.INET_DIAG_BC_D_LE, 1, 7, 0xffff), # 8 248*2f2c4c7aSAndroid Build Coastguard Worker (sock_diag.INET_DIAG_BC_S_COND, 1, 2, ("::1", 128, -1)), # 16 249*2f2c4c7aSAndroid Build Coastguard Worker (sock_diag.INET_DIAG_BC_JMP, 1, 3, None), # 44 250*2f2c4c7aSAndroid Build Coastguard Worker (sock_diag.INET_DIAG_BC_S_COND, 2, 4, ("127.0.0.1", 32, -1)), # 48 251*2f2c4c7aSAndroid Build Coastguard Worker (sock_diag.INET_DIAG_BC_D_LE, 1, 3, 0x6665), # not used # 64 252*2f2c4c7aSAndroid Build Coastguard Worker (sock_diag.INET_DIAG_BC_NOP, 1, 1, None), # 72 253*2f2c4c7aSAndroid Build Coastguard Worker # 76 acc 254*2f2c4c7aSAndroid Build Coastguard Worker # 80 rej 255*2f2c4c7aSAndroid Build Coastguard Worker ] 256*2f2c4c7aSAndroid Build Coastguard Worker # pylint: enable=bad-whitespace 257*2f2c4c7aSAndroid Build Coastguard Worker bytecode = self.PackAndCheckBytecode(instructions) 258*2f2c4c7aSAndroid Build Coastguard Worker expected = ( 259*2f2c4c7aSAndroid Build Coastguard Worker b"0208500000000000" 260*2f2c4c7aSAndroid Build Coastguard Worker b"050848000000ffff" 261*2f2c4c7aSAndroid Build Coastguard Worker b"071c20000a800000ffffffff00000000000000000000000000000001" 262*2f2c4c7aSAndroid Build Coastguard Worker b"01041c00" 263*2f2c4c7aSAndroid Build Coastguard Worker b"0718200002200000ffffffff7f000001" 264*2f2c4c7aSAndroid Build Coastguard Worker b"0508100000006566" 265*2f2c4c7aSAndroid Build Coastguard Worker b"00040400" 266*2f2c4c7aSAndroid Build Coastguard Worker ) 267*2f2c4c7aSAndroid Build Coastguard Worker states = 1 << tcp_test.TCP_ESTABLISHED 268*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(expected, binascii.hexlify(bytecode)) 269*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(76, len(bytecode)) 270*2f2c4c7aSAndroid Build Coastguard Worker self.socketpairs = self._CreateLotsOfSockets(SOCK_STREAM) 271*2f2c4c7aSAndroid Build Coastguard Worker filteredsockets = self.sock_diag.DumpAllInetSockets(IPPROTO_TCP, bytecode, 272*2f2c4c7aSAndroid Build Coastguard Worker states=states) 273*2f2c4c7aSAndroid Build Coastguard Worker allsockets = self.sock_diag.DumpAllInetSockets(IPPROTO_TCP, NO_BYTECODE, 274*2f2c4c7aSAndroid Build Coastguard Worker states=states) 275*2f2c4c7aSAndroid Build Coastguard Worker self.assertItemsEqual(allsockets, filteredsockets) 276*2f2c4c7aSAndroid Build Coastguard Worker 277*2f2c4c7aSAndroid Build Coastguard Worker # Pick a few sockets in hash table order, and check that the bytecode we 278*2f2c4c7aSAndroid Build Coastguard Worker # compiled selects them properly. 279*2f2c4c7aSAndroid Build Coastguard Worker for socketpair in list(self.socketpairs.values())[:20]: 280*2f2c4c7aSAndroid Build Coastguard Worker for s in socketpair: 281*2f2c4c7aSAndroid Build Coastguard Worker diag_msg = self.sock_diag.FindSockDiagFromFd(s) 282*2f2c4c7aSAndroid Build Coastguard Worker instructions = [ 283*2f2c4c7aSAndroid Build Coastguard Worker (sock_diag.INET_DIAG_BC_S_GE, 1, 5, diag_msg.id.sport), 284*2f2c4c7aSAndroid Build Coastguard Worker (sock_diag.INET_DIAG_BC_S_LE, 1, 4, diag_msg.id.sport), 285*2f2c4c7aSAndroid Build Coastguard Worker (sock_diag.INET_DIAG_BC_D_GE, 1, 3, diag_msg.id.dport), 286*2f2c4c7aSAndroid Build Coastguard Worker (sock_diag.INET_DIAG_BC_D_LE, 1, 2, diag_msg.id.dport), 287*2f2c4c7aSAndroid Build Coastguard Worker ] 288*2f2c4c7aSAndroid Build Coastguard Worker bytecode = self.PackAndCheckBytecode(instructions) 289*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(32, len(bytecode)) 290*2f2c4c7aSAndroid Build Coastguard Worker sockets = self.sock_diag.DumpAllInetSockets(IPPROTO_TCP, bytecode) 291*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(1, len(sockets)) 292*2f2c4c7aSAndroid Build Coastguard Worker 293*2f2c4c7aSAndroid Build Coastguard Worker # TODO: why doesn't comparing the cstructs work? 294*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(diag_msg.Pack(), sockets[0][0].Pack()) 295*2f2c4c7aSAndroid Build Coastguard Worker 296*2f2c4c7aSAndroid Build Coastguard Worker def testCrossFamilyBytecode(self): 297*2f2c4c7aSAndroid Build Coastguard Worker """Checks for a cross-family bug in inet_diag_hostcond matching. 298*2f2c4c7aSAndroid Build Coastguard Worker 299*2f2c4c7aSAndroid Build Coastguard Worker Relevant kernel commits: 300*2f2c4c7aSAndroid Build Coastguard Worker android-3.4: 301*2f2c4c7aSAndroid Build Coastguard Worker f67caec inet_diag: avoid unsafe and nonsensical prefix matches in inet_diag_bc_run() 302*2f2c4c7aSAndroid Build Coastguard Worker """ 303*2f2c4c7aSAndroid Build Coastguard Worker # TODO: this is only here because the test fails if there are any open 304*2f2c4c7aSAndroid Build Coastguard Worker # sockets other than the ones it creates itself. Make the bytecode more 305*2f2c4c7aSAndroid Build Coastguard Worker # specific and remove it. 306*2f2c4c7aSAndroid Build Coastguard Worker states = 1 << tcp_test.TCP_ESTABLISHED 307*2f2c4c7aSAndroid Build Coastguard Worker self.assertFalse(self.sock_diag.DumpAllInetSockets(IPPROTO_TCP, NO_BYTECODE, 308*2f2c4c7aSAndroid Build Coastguard Worker states=states)) 309*2f2c4c7aSAndroid Build Coastguard Worker 310*2f2c4c7aSAndroid Build Coastguard Worker unused_pair4 = net_test.CreateSocketPair(AF_INET, SOCK_STREAM, "127.0.0.1") 311*2f2c4c7aSAndroid Build Coastguard Worker unused_pair6 = net_test.CreateSocketPair(AF_INET6, SOCK_STREAM, "::1") 312*2f2c4c7aSAndroid Build Coastguard Worker 313*2f2c4c7aSAndroid Build Coastguard Worker bytecode4 = self.PackAndCheckBytecode([ 314*2f2c4c7aSAndroid Build Coastguard Worker (sock_diag.INET_DIAG_BC_S_COND, 1, 2, ("0.0.0.0", 0, -1))]) 315*2f2c4c7aSAndroid Build Coastguard Worker bytecode6 = self.PackAndCheckBytecode([ 316*2f2c4c7aSAndroid Build Coastguard Worker (sock_diag.INET_DIAG_BC_S_COND, 1, 2, ("::", 0, -1))]) 317*2f2c4c7aSAndroid Build Coastguard Worker 318*2f2c4c7aSAndroid Build Coastguard Worker # IPv4/v6 filters must never match IPv6/IPv4 sockets... 319*2f2c4c7aSAndroid Build Coastguard Worker v4socks = self.sock_diag.DumpAllInetSockets(IPPROTO_TCP, bytecode4, 320*2f2c4c7aSAndroid Build Coastguard Worker states=states) 321*2f2c4c7aSAndroid Build Coastguard Worker self.assertTrue(v4socks) 322*2f2c4c7aSAndroid Build Coastguard Worker self.assertTrue(all(d.family == AF_INET for d, _ in v4socks)) 323*2f2c4c7aSAndroid Build Coastguard Worker 324*2f2c4c7aSAndroid Build Coastguard Worker v6socks = self.sock_diag.DumpAllInetSockets(IPPROTO_TCP, bytecode6, 325*2f2c4c7aSAndroid Build Coastguard Worker states=states) 326*2f2c4c7aSAndroid Build Coastguard Worker self.assertTrue(v6socks) 327*2f2c4c7aSAndroid Build Coastguard Worker self.assertTrue(all(d.family == AF_INET6 for d, _ in v6socks)) 328*2f2c4c7aSAndroid Build Coastguard Worker 329*2f2c4c7aSAndroid Build Coastguard Worker # Except for mapped addresses, which match both IPv4 and IPv6. 330*2f2c4c7aSAndroid Build Coastguard Worker pair5 = net_test.CreateSocketPair(AF_INET6, SOCK_STREAM, 331*2f2c4c7aSAndroid Build Coastguard Worker "::ffff:127.0.0.1") 332*2f2c4c7aSAndroid Build Coastguard Worker diag_msgs = [self.sock_diag.FindSockDiagFromFd(s) for s in pair5] 333*2f2c4c7aSAndroid Build Coastguard Worker v4socks = [d for d, _ in self.sock_diag.DumpAllInetSockets(IPPROTO_TCP, 334*2f2c4c7aSAndroid Build Coastguard Worker bytecode4, 335*2f2c4c7aSAndroid Build Coastguard Worker states=states)] 336*2f2c4c7aSAndroid Build Coastguard Worker v6socks = [d for d, _ in self.sock_diag.DumpAllInetSockets(IPPROTO_TCP, 337*2f2c4c7aSAndroid Build Coastguard Worker bytecode6, 338*2f2c4c7aSAndroid Build Coastguard Worker states=states)] 339*2f2c4c7aSAndroid Build Coastguard Worker self.assertTrue(all(d in v4socks for d in diag_msgs)) 340*2f2c4c7aSAndroid Build Coastguard Worker self.assertTrue(all(d in v6socks for d in diag_msgs)) 341*2f2c4c7aSAndroid Build Coastguard Worker 342*2f2c4c7aSAndroid Build Coastguard Worker for sock in unused_pair4: 343*2f2c4c7aSAndroid Build Coastguard Worker sock.close() 344*2f2c4c7aSAndroid Build Coastguard Worker 345*2f2c4c7aSAndroid Build Coastguard Worker for sock in unused_pair6: 346*2f2c4c7aSAndroid Build Coastguard Worker sock.close() 347*2f2c4c7aSAndroid Build Coastguard Worker 348*2f2c4c7aSAndroid Build Coastguard Worker for sock in pair5: 349*2f2c4c7aSAndroid Build Coastguard Worker sock.close() 350*2f2c4c7aSAndroid Build Coastguard Worker 351*2f2c4c7aSAndroid Build Coastguard Worker def testPortComparisonValidation(self): 352*2f2c4c7aSAndroid Build Coastguard Worker """Checks for a bug in validating port comparison bytecode. 353*2f2c4c7aSAndroid Build Coastguard Worker 354*2f2c4c7aSAndroid Build Coastguard Worker Relevant kernel commits: 355*2f2c4c7aSAndroid Build Coastguard Worker android-3.4: 356*2f2c4c7aSAndroid Build Coastguard Worker 5e1f542 inet_diag: validate port comparison byte code to prevent unsafe reads 357*2f2c4c7aSAndroid Build Coastguard Worker """ 358*2f2c4c7aSAndroid Build Coastguard Worker bytecode = sock_diag.InetDiagBcOp((sock_diag.INET_DIAG_BC_D_GE, 4, 8)) 359*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual("???", 360*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.DecodeBytecode(bytecode)) 361*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno( 362*2f2c4c7aSAndroid Build Coastguard Worker EINVAL, 363*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.DumpAllInetSockets, IPPROTO_TCP, bytecode.Pack()) 364*2f2c4c7aSAndroid Build Coastguard Worker 365*2f2c4c7aSAndroid Build Coastguard Worker def testNonSockDiagCommand(self): 366*2f2c4c7aSAndroid Build Coastguard Worker def DiagDump(code): 367*2f2c4c7aSAndroid Build Coastguard Worker sock_id = self.sock_diag._EmptyInetDiagSockId() 368*2f2c4c7aSAndroid Build Coastguard Worker req = sock_diag.InetDiagReqV2((AF_INET6, IPPROTO_TCP, 0, 0xffffffff, 369*2f2c4c7aSAndroid Build Coastguard Worker sock_id)) 370*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag._Dump(code, req, sock_diag.InetDiagMsg) 371*2f2c4c7aSAndroid Build Coastguard Worker 372*2f2c4c7aSAndroid Build Coastguard Worker op = sock_diag.SOCK_DIAG_BY_FAMILY 373*2f2c4c7aSAndroid Build Coastguard Worker DiagDump(op) # No errors? Good. 374*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(EINVAL, DiagDump, op + 17) 375*2f2c4c7aSAndroid Build Coastguard Worker 376*2f2c4c7aSAndroid Build Coastguard Worker def CheckSocketCookie(self, inet, addr): 377*2f2c4c7aSAndroid Build Coastguard Worker """Tests that getsockopt SO_COOKIE can get cookie for all sockets.""" 378*2f2c4c7aSAndroid Build Coastguard Worker socketpair = net_test.CreateSocketPair(inet, SOCK_STREAM, addr) 379*2f2c4c7aSAndroid Build Coastguard Worker for sock in socketpair: 380*2f2c4c7aSAndroid Build Coastguard Worker diag_msg = self.sock_diag.FindSockDiagFromFd(sock) 381*2f2c4c7aSAndroid Build Coastguard Worker cookie = sock.getsockopt(net_test.SOL_SOCKET, net_test.SO_COOKIE, 8) 382*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(diag_msg.id.cookie, cookie) 383*2f2c4c7aSAndroid Build Coastguard Worker 384*2f2c4c7aSAndroid Build Coastguard Worker for sock in socketpair: 385*2f2c4c7aSAndroid Build Coastguard Worker sock.close() 386*2f2c4c7aSAndroid Build Coastguard Worker 387*2f2c4c7aSAndroid Build Coastguard Worker def testGetsockoptcookie(self): 388*2f2c4c7aSAndroid Build Coastguard Worker self.CheckSocketCookie(AF_INET, "127.0.0.1") 389*2f2c4c7aSAndroid Build Coastguard Worker self.CheckSocketCookie(AF_INET6, "::1") 390*2f2c4c7aSAndroid Build Coastguard Worker 391*2f2c4c7aSAndroid Build Coastguard Worker def testDemonstrateUdpGetSockIdBug(self): 392*2f2c4c7aSAndroid Build Coastguard Worker # TODO: this is because udp_dump_one mistakenly uses __udp[46]_lib_lookup 393*2f2c4c7aSAndroid Build Coastguard Worker # by passing the source address as the source address argument. 394*2f2c4c7aSAndroid Build Coastguard Worker # Unfortunately those functions are intended to match local sockets based 395*2f2c4c7aSAndroid Build Coastguard Worker # on received packets, and the argument that ends up being compared with 396*2f2c4c7aSAndroid Build Coastguard Worker # e.g., sk_daddr is actually saddr, not daddr. udp_diag_destroy does not 397*2f2c4c7aSAndroid Build Coastguard Worker # have this bug. Upstream has confirmed that this will not be fixed: 398*2f2c4c7aSAndroid Build Coastguard Worker # https://www.mail-archive.com/[email protected]/msg248638.html 399*2f2c4c7aSAndroid Build Coastguard Worker """Documents a bug: getting UDP sockets requires swapping src and dst.""" 400*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 5, 6]: 401*2f2c4c7aSAndroid Build Coastguard Worker family = net_test.GetAddressFamily(version) 402*2f2c4c7aSAndroid Build Coastguard Worker s = socket(family, SOCK_DGRAM, 0) 403*2f2c4c7aSAndroid Build Coastguard Worker self.SelectInterface(s, self.RandomNetid(), "mark") 404*2f2c4c7aSAndroid Build Coastguard Worker s.connect((self.GetRemoteSocketAddress(version), 53)) 405*2f2c4c7aSAndroid Build Coastguard Worker 406*2f2c4c7aSAndroid Build Coastguard Worker # Create a fully-specified diag req from our socket, including cookie if 407*2f2c4c7aSAndroid Build Coastguard Worker # we can get it. 408*2f2c4c7aSAndroid Build Coastguard Worker req = self.sock_diag.DiagReqFromSocket(s) 409*2f2c4c7aSAndroid Build Coastguard Worker req.id.cookie = s.getsockopt(net_test.SOL_SOCKET, net_test.SO_COOKIE, 8) 410*2f2c4c7aSAndroid Build Coastguard Worker 411*2f2c4c7aSAndroid Build Coastguard Worker # As is, this request does not find anything. 412*2f2c4c7aSAndroid Build Coastguard Worker with self.assertRaisesErrno(ENOENT): 413*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.GetSockInfo(req) 414*2f2c4c7aSAndroid Build Coastguard Worker 415*2f2c4c7aSAndroid Build Coastguard Worker # But if we swap src and dst, the kernel finds our socket. 416*2f2c4c7aSAndroid Build Coastguard Worker req.id.sport, req.id.dport = req.id.dport, req.id.sport 417*2f2c4c7aSAndroid Build Coastguard Worker req.id.src, req.id.dst = req.id.dst, req.id.src 418*2f2c4c7aSAndroid Build Coastguard Worker 419*2f2c4c7aSAndroid Build Coastguard Worker self.assertSockInfoMatchesSocket(s, self.sock_diag.GetSockInfo(req)) 420*2f2c4c7aSAndroid Build Coastguard Worker 421*2f2c4c7aSAndroid Build Coastguard Worker s.close() 422*2f2c4c7aSAndroid Build Coastguard Worker 423*2f2c4c7aSAndroid Build Coastguard Worker 424*2f2c4c7aSAndroid Build Coastguard Workerclass SockDestroyTest(SockDiagBaseTest): 425*2f2c4c7aSAndroid Build Coastguard Worker """Tests that SOCK_DESTROY works correctly. 426*2f2c4c7aSAndroid Build Coastguard Worker 427*2f2c4c7aSAndroid Build Coastguard Worker Relevant kernel commits: 428*2f2c4c7aSAndroid Build Coastguard Worker net-next: 429*2f2c4c7aSAndroid Build Coastguard Worker b613f56 net: diag: split inet_diag_dump_one_icsk into two 430*2f2c4c7aSAndroid Build Coastguard Worker 64be0ae net: diag: Add the ability to destroy a socket. 431*2f2c4c7aSAndroid Build Coastguard Worker 6eb5d2e net: diag: Support SOCK_DESTROY for inet sockets. 432*2f2c4c7aSAndroid Build Coastguard Worker c1e64e2 net: diag: Support destroying TCP sockets. 433*2f2c4c7aSAndroid Build Coastguard Worker 2010b93 net: tcp: deal with listen sockets properly in tcp_abort. 434*2f2c4c7aSAndroid Build Coastguard Worker 435*2f2c4c7aSAndroid Build Coastguard Worker android-3.4: 436*2f2c4c7aSAndroid Build Coastguard Worker d48ec88 net: diag: split inet_diag_dump_one_icsk into two 437*2f2c4c7aSAndroid Build Coastguard Worker 2438189 net: diag: Add the ability to destroy a socket. 438*2f2c4c7aSAndroid Build Coastguard Worker 7a2ddbc net: diag: Support SOCK_DESTROY for inet sockets. 439*2f2c4c7aSAndroid Build Coastguard Worker 44047b2 net: diag: Support destroying TCP sockets. 440*2f2c4c7aSAndroid Build Coastguard Worker 200dae7 net: tcp: deal with listen sockets properly in tcp_abort. 441*2f2c4c7aSAndroid Build Coastguard Worker 442*2f2c4c7aSAndroid Build Coastguard Worker android-3.10: 443*2f2c4c7aSAndroid Build Coastguard Worker 9eaff90 net: diag: split inet_diag_dump_one_icsk into two 444*2f2c4c7aSAndroid Build Coastguard Worker d60326c net: diag: Add the ability to destroy a socket. 445*2f2c4c7aSAndroid Build Coastguard Worker 3d4ce85 net: diag: Support SOCK_DESTROY for inet sockets. 446*2f2c4c7aSAndroid Build Coastguard Worker 529dfc6 net: diag: Support destroying TCP sockets. 447*2f2c4c7aSAndroid Build Coastguard Worker 9c712fe net: tcp: deal with listen sockets properly in tcp_abort. 448*2f2c4c7aSAndroid Build Coastguard Worker 449*2f2c4c7aSAndroid Build Coastguard Worker android-3.18: 450*2f2c4c7aSAndroid Build Coastguard Worker 100263d net: diag: split inet_diag_dump_one_icsk into two 451*2f2c4c7aSAndroid Build Coastguard Worker 194c5f3 net: diag: Add the ability to destroy a socket. 452*2f2c4c7aSAndroid Build Coastguard Worker 8387ea2 net: diag: Support SOCK_DESTROY for inet sockets. 453*2f2c4c7aSAndroid Build Coastguard Worker b80585a net: diag: Support destroying TCP sockets. 454*2f2c4c7aSAndroid Build Coastguard Worker 476c6ce net: tcp: deal with listen sockets properly in tcp_abort. 455*2f2c4c7aSAndroid Build Coastguard Worker 456*2f2c4c7aSAndroid Build Coastguard Worker android-4.1: 457*2f2c4c7aSAndroid Build Coastguard Worker 56eebf8 net: diag: split inet_diag_dump_one_icsk into two 458*2f2c4c7aSAndroid Build Coastguard Worker fb486c9 net: diag: Add the ability to destroy a socket. 459*2f2c4c7aSAndroid Build Coastguard Worker 0c02b7e net: diag: Support SOCK_DESTROY for inet sockets. 460*2f2c4c7aSAndroid Build Coastguard Worker 67c71d8 net: diag: Support destroying TCP sockets. 461*2f2c4c7aSAndroid Build Coastguard Worker a76e0ec net: tcp: deal with listen sockets properly in tcp_abort. 462*2f2c4c7aSAndroid Build Coastguard Worker e6e277b net: diag: support v4mapped sockets in inet_diag_find_one_icsk() 463*2f2c4c7aSAndroid Build Coastguard Worker 464*2f2c4c7aSAndroid Build Coastguard Worker android-4.4: 465*2f2c4c7aSAndroid Build Coastguard Worker 76c83a9 net: diag: split inet_diag_dump_one_icsk into two 466*2f2c4c7aSAndroid Build Coastguard Worker f7cf791 net: diag: Add the ability to destroy a socket. 467*2f2c4c7aSAndroid Build Coastguard Worker 1c42248 net: diag: Support SOCK_DESTROY for inet sockets. 468*2f2c4c7aSAndroid Build Coastguard Worker c9e8440d net: diag: Support destroying TCP sockets. 469*2f2c4c7aSAndroid Build Coastguard Worker 3d9502c tcp: diag: add support for request sockets to tcp_abort() 470*2f2c4c7aSAndroid Build Coastguard Worker 001cf75 net: tcp: deal with listen sockets properly in tcp_abort. 471*2f2c4c7aSAndroid Build Coastguard Worker """ 472*2f2c4c7aSAndroid Build Coastguard Worker 473*2f2c4c7aSAndroid Build Coastguard Worker def testClosesSockets(self): 474*2f2c4c7aSAndroid Build Coastguard Worker self.socketpairs = self._CreateLotsOfSockets(SOCK_STREAM) 475*2f2c4c7aSAndroid Build Coastguard Worker for _, socketpair in self.socketpairs.items(): 476*2f2c4c7aSAndroid Build Coastguard Worker # Close one of the sockets. 477*2f2c4c7aSAndroid Build Coastguard Worker # This will send a RST that will close the other side as well. 478*2f2c4c7aSAndroid Build Coastguard Worker s = random.choice(socketpair) 479*2f2c4c7aSAndroid Build Coastguard Worker if random.randrange(0, 2) == 1: 480*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.CloseSocketFromFd(s) 481*2f2c4c7aSAndroid Build Coastguard Worker else: 482*2f2c4c7aSAndroid Build Coastguard Worker diag_msg = self.sock_diag.FindSockDiagFromFd(s) 483*2f2c4c7aSAndroid Build Coastguard Worker 484*2f2c4c7aSAndroid Build Coastguard Worker # Get the cookie wrong and ensure that we get an error and the socket 485*2f2c4c7aSAndroid Build Coastguard Worker # is not closed. 486*2f2c4c7aSAndroid Build Coastguard Worker real_cookie = diag_msg.id.cookie 487*2f2c4c7aSAndroid Build Coastguard Worker diag_msg.id.cookie = os.urandom(len(real_cookie)) 488*2f2c4c7aSAndroid Build Coastguard Worker req = self.sock_diag.DiagReqFromDiagMsg(diag_msg, IPPROTO_TCP) 489*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(ENOENT, self.sock_diag.CloseSocket, req) 490*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketConnected(s) 491*2f2c4c7aSAndroid Build Coastguard Worker 492*2f2c4c7aSAndroid Build Coastguard Worker # Now close it with the correct cookie. 493*2f2c4c7aSAndroid Build Coastguard Worker req.id.cookie = real_cookie 494*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.CloseSocket(req) 495*2f2c4c7aSAndroid Build Coastguard Worker 496*2f2c4c7aSAndroid Build Coastguard Worker # Check that both sockets in the pair are closed. 497*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketsClosed(socketpair) 498*2f2c4c7aSAndroid Build Coastguard Worker 499*2f2c4c7aSAndroid Build Coastguard Worker # TODO: 500*2f2c4c7aSAndroid Build Coastguard Worker # Test that killing unix sockets returns EOPNOTSUPP. 501*2f2c4c7aSAndroid Build Coastguard Worker 502*2f2c4c7aSAndroid Build Coastguard Worker 503*2f2c4c7aSAndroid Build Coastguard Workerclass SocketExceptionThread(threading.Thread): 504*2f2c4c7aSAndroid Build Coastguard Worker 505*2f2c4c7aSAndroid Build Coastguard Worker def __init__(self, sock, operation): 506*2f2c4c7aSAndroid Build Coastguard Worker self.exception = None 507*2f2c4c7aSAndroid Build Coastguard Worker super(SocketExceptionThread, self).__init__() 508*2f2c4c7aSAndroid Build Coastguard Worker self.daemon = True 509*2f2c4c7aSAndroid Build Coastguard Worker self.sock = sock 510*2f2c4c7aSAndroid Build Coastguard Worker self.operation = operation 511*2f2c4c7aSAndroid Build Coastguard Worker 512*2f2c4c7aSAndroid Build Coastguard Worker def run(self): 513*2f2c4c7aSAndroid Build Coastguard Worker try: 514*2f2c4c7aSAndroid Build Coastguard Worker self.operation(self.sock) 515*2f2c4c7aSAndroid Build Coastguard Worker except (IOError, AssertionError) as e: 516*2f2c4c7aSAndroid Build Coastguard Worker self.exception = e 517*2f2c4c7aSAndroid Build Coastguard Worker 518*2f2c4c7aSAndroid Build Coastguard Worker 519*2f2c4c7aSAndroid Build Coastguard Workerclass SockDiagTcpTest(tcp_test.TcpBaseTest, SockDiagBaseTest): 520*2f2c4c7aSAndroid Build Coastguard Worker 521*2f2c4c7aSAndroid Build Coastguard Worker def testIpv4MappedSynRecvSocket(self): 522*2f2c4c7aSAndroid Build Coastguard Worker """Tests for the absence of a bug with AF_INET6 TCP SYN-RECV sockets. 523*2f2c4c7aSAndroid Build Coastguard Worker 524*2f2c4c7aSAndroid Build Coastguard Worker Relevant kernel commits: 525*2f2c4c7aSAndroid Build Coastguard Worker android-3.4: 526*2f2c4c7aSAndroid Build Coastguard Worker 457a04b inet_diag: fix oops for IPv4 AF_INET6 TCP SYN-RECV state 527*2f2c4c7aSAndroid Build Coastguard Worker """ 528*2f2c4c7aSAndroid Build Coastguard Worker netid = random.choice(list(self.tuns.keys())) 529*2f2c4c7aSAndroid Build Coastguard Worker self.IncomingConnection(5, tcp_test.TCP_SYN_RECV, netid) 530*2f2c4c7aSAndroid Build Coastguard Worker sock_id = self.sock_diag._EmptyInetDiagSockId() 531*2f2c4c7aSAndroid Build Coastguard Worker sock_id.sport = self.port 532*2f2c4c7aSAndroid Build Coastguard Worker states = 1 << tcp_test.TCP_SYN_RECV 533*2f2c4c7aSAndroid Build Coastguard Worker req = sock_diag.InetDiagReqV2((AF_INET6, IPPROTO_TCP, 0, states, sock_id)) 534*2f2c4c7aSAndroid Build Coastguard Worker children = self.sock_diag.Dump(req, NO_BYTECODE) 535*2f2c4c7aSAndroid Build Coastguard Worker 536*2f2c4c7aSAndroid Build Coastguard Worker self.assertTrue(children) 537*2f2c4c7aSAndroid Build Coastguard Worker for child, unused_args in children: 538*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(tcp_test.TCP_SYN_RECV, child.state) 539*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(self.sock_diag.PaddedAddress(self.remotesockaddr), 540*2f2c4c7aSAndroid Build Coastguard Worker child.id.dst) 541*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(self.sock_diag.PaddedAddress(self.mysockaddr), 542*2f2c4c7aSAndroid Build Coastguard Worker child.id.src) 543*2f2c4c7aSAndroid Build Coastguard Worker 544*2f2c4c7aSAndroid Build Coastguard Worker 545*2f2c4c7aSAndroid Build Coastguard Workerclass TcpRcvWindowTest(tcp_test.TcpBaseTest, SockDiagBaseTest): 546*2f2c4c7aSAndroid Build Coastguard Worker 547*2f2c4c7aSAndroid Build Coastguard Worker RWND_SIZE = 64000 548*2f2c4c7aSAndroid Build Coastguard Worker TCP_DEFAULT_INIT_RWND = "/proc/sys/net/ipv4/tcp_default_init_rwnd" 549*2f2c4c7aSAndroid Build Coastguard Worker 550*2f2c4c7aSAndroid Build Coastguard Worker def setUp(self): 551*2f2c4c7aSAndroid Build Coastguard Worker super(TcpRcvWindowTest, self).setUp() 552*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(ENOENT, open, self.TCP_DEFAULT_INIT_RWND, "w") 553*2f2c4c7aSAndroid Build Coastguard Worker 554*2f2c4c7aSAndroid Build Coastguard Worker def checkInitRwndSize(self, version, netid): 555*2f2c4c7aSAndroid Build Coastguard Worker self.IncomingConnection(version, tcp_test.TCP_ESTABLISHED, netid) 556*2f2c4c7aSAndroid Build Coastguard Worker tcpInfo = TcpInfo(self.accepted.getsockopt(net_test.SOL_TCP, 557*2f2c4c7aSAndroid Build Coastguard Worker net_test.TCP_INFO, len(TcpInfo))) 558*2f2c4c7aSAndroid Build Coastguard Worker self.assertLess(self.RWND_SIZE, tcpInfo.tcpi_rcv_ssthresh, 559*2f2c4c7aSAndroid Build Coastguard Worker "Tcp rwnd of netid=%d, version=%d is not enough. " 560*2f2c4c7aSAndroid Build Coastguard Worker "Expect: %d, actual: %d" % (netid, version, self.RWND_SIZE, 561*2f2c4c7aSAndroid Build Coastguard Worker tcpInfo.tcpi_rcv_ssthresh)) 562*2f2c4c7aSAndroid Build Coastguard Worker self.CloseSockets() 563*2f2c4c7aSAndroid Build Coastguard Worker 564*2f2c4c7aSAndroid Build Coastguard Worker def checkSynPacketWindowSize(self, version, netid): 565*2f2c4c7aSAndroid Build Coastguard Worker s = self.BuildSocket(version, net_test.TCPSocket, netid, "mark") 566*2f2c4c7aSAndroid Build Coastguard Worker myaddr = self.MyAddress(version, netid) 567*2f2c4c7aSAndroid Build Coastguard Worker dstaddr = self.GetRemoteAddress(version) 568*2f2c4c7aSAndroid Build Coastguard Worker dstsockaddr = self.GetRemoteSocketAddress(version) 569*2f2c4c7aSAndroid Build Coastguard Worker desc, expected = packets.SYN(53, version, myaddr, dstaddr, 570*2f2c4c7aSAndroid Build Coastguard Worker sport=None, seq=None) 571*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(EINPROGRESS, s.connect, (dstsockaddr, 53)) 572*2f2c4c7aSAndroid Build Coastguard Worker msg = "IPv%s TCP connect: expected %s on %s" % ( 573*2f2c4c7aSAndroid Build Coastguard Worker version, desc, self.GetInterfaceName(netid)) 574*2f2c4c7aSAndroid Build Coastguard Worker syn = self.ExpectPacketOn(netid, msg, expected) 575*2f2c4c7aSAndroid Build Coastguard Worker self.assertLess(self.RWND_SIZE, syn.window) 576*2f2c4c7aSAndroid Build Coastguard Worker s.close() 577*2f2c4c7aSAndroid Build Coastguard Worker 578*2f2c4c7aSAndroid Build Coastguard Worker def testTcpCwndSize(self): 579*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 5, 6]: 580*2f2c4c7aSAndroid Build Coastguard Worker for netid in self.NETIDS: 581*2f2c4c7aSAndroid Build Coastguard Worker self.checkInitRwndSize(version, netid) 582*2f2c4c7aSAndroid Build Coastguard Worker self.checkSynPacketWindowSize(version, netid) 583*2f2c4c7aSAndroid Build Coastguard Worker 584*2f2c4c7aSAndroid Build Coastguard Worker 585*2f2c4c7aSAndroid Build Coastguard Workerclass SockDestroyTcpTest(tcp_test.TcpBaseTest, SockDiagBaseTest): 586*2f2c4c7aSAndroid Build Coastguard Worker 587*2f2c4c7aSAndroid Build Coastguard Worker def setUp(self): 588*2f2c4c7aSAndroid Build Coastguard Worker super(SockDestroyTcpTest, self).setUp() 589*2f2c4c7aSAndroid Build Coastguard Worker self.netid = random.choice(list(self.tuns.keys())) 590*2f2c4c7aSAndroid Build Coastguard Worker 591*2f2c4c7aSAndroid Build Coastguard Worker def ExpectRst(self, msg): 592*2f2c4c7aSAndroid Build Coastguard Worker desc, rst = self.RstPacket() 593*2f2c4c7aSAndroid Build Coastguard Worker msg = "%s: expecting %s: " % (msg, desc) 594*2f2c4c7aSAndroid Build Coastguard Worker self.ExpectPacketOn(self.netid, msg, rst) 595*2f2c4c7aSAndroid Build Coastguard Worker 596*2f2c4c7aSAndroid Build Coastguard Worker def CheckRstOnClose(self, sock, req, expect_reset, msg, do_close=True): 597*2f2c4c7aSAndroid Build Coastguard Worker """Closes the socket and checks whether a RST is sent or not.""" 598*2f2c4c7aSAndroid Build Coastguard Worker if sock is not None: 599*2f2c4c7aSAndroid Build Coastguard Worker self.assertIsNone(req, "Must specify sock or req, not both") 600*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.CloseSocketFromFd(sock) 601*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(EINVAL, sock.accept) 602*2f2c4c7aSAndroid Build Coastguard Worker else: 603*2f2c4c7aSAndroid Build Coastguard Worker self.assertIsNone(sock, "Must specify sock or req, not both") 604*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.CloseSocket(req) 605*2f2c4c7aSAndroid Build Coastguard Worker 606*2f2c4c7aSAndroid Build Coastguard Worker if expect_reset: 607*2f2c4c7aSAndroid Build Coastguard Worker self.ExpectRst(msg) 608*2f2c4c7aSAndroid Build Coastguard Worker else: 609*2f2c4c7aSAndroid Build Coastguard Worker msg = "%s: " % msg 610*2f2c4c7aSAndroid Build Coastguard Worker self.ExpectNoPacketsOn(self.netid, msg) 611*2f2c4c7aSAndroid Build Coastguard Worker 612*2f2c4c7aSAndroid Build Coastguard Worker if sock is not None and do_close: 613*2f2c4c7aSAndroid Build Coastguard Worker sock.close() 614*2f2c4c7aSAndroid Build Coastguard Worker 615*2f2c4c7aSAndroid Build Coastguard Worker def CheckTcpReset(self, state, statename): 616*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 5, 6]: 617*2f2c4c7aSAndroid Build Coastguard Worker msg = "Closing incoming IPv%d %s socket" % (version, statename) 618*2f2c4c7aSAndroid Build Coastguard Worker self.IncomingConnection(version, state, self.netid) 619*2f2c4c7aSAndroid Build Coastguard Worker self.CheckRstOnClose(self.s, None, False, msg) 620*2f2c4c7aSAndroid Build Coastguard Worker if state != tcp_test.TCP_LISTEN: 621*2f2c4c7aSAndroid Build Coastguard Worker msg = "Closing accepted IPv%d %s socket" % (version, statename) 622*2f2c4c7aSAndroid Build Coastguard Worker self.CheckRstOnClose(self.accepted, None, True, msg) 623*2f2c4c7aSAndroid Build Coastguard Worker self.CloseSockets() 624*2f2c4c7aSAndroid Build Coastguard Worker 625*2f2c4c7aSAndroid Build Coastguard Worker def testTcpResets(self): 626*2f2c4c7aSAndroid Build Coastguard Worker """Checks that closing sockets in appropriate states sends a RST.""" 627*2f2c4c7aSAndroid Build Coastguard Worker self.CheckTcpReset(tcp_test.TCP_LISTEN, "TCP_LISTEN") 628*2f2c4c7aSAndroid Build Coastguard Worker self.CheckTcpReset(tcp_test.TCP_ESTABLISHED, "TCP_ESTABLISHED") 629*2f2c4c7aSAndroid Build Coastguard Worker self.CheckTcpReset(tcp_test.TCP_CLOSE_WAIT, "TCP_CLOSE_WAIT") 630*2f2c4c7aSAndroid Build Coastguard Worker 631*2f2c4c7aSAndroid Build Coastguard Worker def testFinWait1Socket(self): 632*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 5, 6]: 633*2f2c4c7aSAndroid Build Coastguard Worker self.IncomingConnection(version, tcp_test.TCP_ESTABLISHED, self.netid) 634*2f2c4c7aSAndroid Build Coastguard Worker 635*2f2c4c7aSAndroid Build Coastguard Worker # Get the cookie so we can find this socket after we close it. 636*2f2c4c7aSAndroid Build Coastguard Worker diag_msg = self.sock_diag.FindSockDiagFromFd(self.accepted) 637*2f2c4c7aSAndroid Build Coastguard Worker diag_req = self.sock_diag.DiagReqFromDiagMsg(diag_msg, IPPROTO_TCP) 638*2f2c4c7aSAndroid Build Coastguard Worker 639*2f2c4c7aSAndroid Build Coastguard Worker # Close the socket and check that it goes into FIN_WAIT1 and sends a FIN. 640*2f2c4c7aSAndroid Build Coastguard Worker net_test.EnableFinWait(self.accepted) 641*2f2c4c7aSAndroid Build Coastguard Worker self.accepted.close() 642*2f2c4c7aSAndroid Build Coastguard Worker self.accepted = None 643*2f2c4c7aSAndroid Build Coastguard Worker diag_req.states = 1 << tcp_test.TCP_FIN_WAIT1 644*2f2c4c7aSAndroid Build Coastguard Worker diag_msg, attrs = self.sock_diag.GetSockInfo(diag_req) 645*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(tcp_test.TCP_FIN_WAIT1, diag_msg.state) 646*2f2c4c7aSAndroid Build Coastguard Worker desc, fin = self.FinPacket() 647*2f2c4c7aSAndroid Build Coastguard Worker msg = "Closing FIN_WAIT1 socket" 648*2f2c4c7aSAndroid Build Coastguard Worker self.ExpectPacketOn(self.netid, msg, fin) 649*2f2c4c7aSAndroid Build Coastguard Worker 650*2f2c4c7aSAndroid Build Coastguard Worker # Destroy the socket. 651*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.CloseSocketFromFd(self.s) 652*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(EINVAL, self.s.accept) 653*2f2c4c7aSAndroid Build Coastguard Worker try: 654*2f2c4c7aSAndroid Build Coastguard Worker diag_msg, attrs = self.sock_diag.GetSockInfo(diag_req) 655*2f2c4c7aSAndroid Build Coastguard Worker except Error as e: 656*2f2c4c7aSAndroid Build Coastguard Worker # Newer kernels will have closed the socket and sent a RST. 657*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(ENOENT, e.errno) 658*2f2c4c7aSAndroid Build Coastguard Worker self.ExpectRst(msg) 659*2f2c4c7aSAndroid Build Coastguard Worker self.CloseSockets() 660*2f2c4c7aSAndroid Build Coastguard Worker return 661*2f2c4c7aSAndroid Build Coastguard Worker 662*2f2c4c7aSAndroid Build Coastguard Worker # Older kernels don't support closing FIN_WAIT1 sockets. 663*2f2c4c7aSAndroid Build Coastguard Worker # Check that no RST is sent and that the socket is still in FIN_WAIT1, and 664*2f2c4c7aSAndroid Build Coastguard Worker # advances to FIN_WAIT2 if the FIN is ACked. 665*2f2c4c7aSAndroid Build Coastguard Worker msg = "%s: " % msg 666*2f2c4c7aSAndroid Build Coastguard Worker self.ExpectNoPacketsOn(self.netid, msg) 667*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(tcp_test.TCP_FIN_WAIT1, diag_msg.state) 668*2f2c4c7aSAndroid Build Coastguard Worker 669*2f2c4c7aSAndroid Build Coastguard Worker # ACK the FIN so we don't trip over retransmits in future tests. 670*2f2c4c7aSAndroid Build Coastguard Worker finversion = 4 if version == 5 else version 671*2f2c4c7aSAndroid Build Coastguard Worker desc, finack = packets.ACK(finversion, self.remoteaddr, self.myaddr, fin) 672*2f2c4c7aSAndroid Build Coastguard Worker diag_msg, attrs = self.sock_diag.GetSockInfo(diag_req) 673*2f2c4c7aSAndroid Build Coastguard Worker self.ReceivePacketOn(self.netid, finack) 674*2f2c4c7aSAndroid Build Coastguard Worker 675*2f2c4c7aSAndroid Build Coastguard Worker # See if we can find the resulting FIN_WAIT2 socket. 676*2f2c4c7aSAndroid Build Coastguard Worker diag_req.states = 1 << tcp_test.TCP_FIN_WAIT2 677*2f2c4c7aSAndroid Build Coastguard Worker infos = self.sock_diag.Dump(diag_req, NO_BYTECODE) 678*2f2c4c7aSAndroid Build Coastguard Worker self.assertTrue(any(diag_msg.state == tcp_test.TCP_FIN_WAIT2 679*2f2c4c7aSAndroid Build Coastguard Worker for diag_msg, attrs in infos), 680*2f2c4c7aSAndroid Build Coastguard Worker "Expected to find FIN_WAIT2 socket in %s" % infos) 681*2f2c4c7aSAndroid Build Coastguard Worker 682*2f2c4c7aSAndroid Build Coastguard Worker self.CloseSockets() 683*2f2c4c7aSAndroid Build Coastguard Worker 684*2f2c4c7aSAndroid Build Coastguard Worker def FindChildSockets(self, s): 685*2f2c4c7aSAndroid Build Coastguard Worker """Finds the SYN_RECV child sockets of a given listening socket.""" 686*2f2c4c7aSAndroid Build Coastguard Worker d = self.sock_diag.FindSockDiagFromFd(self.s) 687*2f2c4c7aSAndroid Build Coastguard Worker req = self.sock_diag.DiagReqFromDiagMsg(d, IPPROTO_TCP) 688*2f2c4c7aSAndroid Build Coastguard Worker req.states = 1 << tcp_test.TCP_SYN_RECV | 1 << tcp_test.TCP_ESTABLISHED 689*2f2c4c7aSAndroid Build Coastguard Worker req.id.cookie = b"\x00" * 8 690*2f2c4c7aSAndroid Build Coastguard Worker 691*2f2c4c7aSAndroid Build Coastguard Worker bad_bytecode = self.PackAndCheckBytecode( 692*2f2c4c7aSAndroid Build Coastguard Worker [(sock_diag.INET_DIAG_BC_MARK_COND, 1, 2, (0xffff, 0xffff))]) 693*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual([], self.sock_diag.Dump(req, bad_bytecode)) 694*2f2c4c7aSAndroid Build Coastguard Worker 695*2f2c4c7aSAndroid Build Coastguard Worker bytecode = self.PackAndCheckBytecode( 696*2f2c4c7aSAndroid Build Coastguard Worker [(sock_diag.INET_DIAG_BC_MARK_COND, 1, 2, (self.netid, 0xffff))]) 697*2f2c4c7aSAndroid Build Coastguard Worker children = self.sock_diag.Dump(req, bytecode) 698*2f2c4c7aSAndroid Build Coastguard Worker return [self.sock_diag.DiagReqFromDiagMsg(d, IPPROTO_TCP) 699*2f2c4c7aSAndroid Build Coastguard Worker for d, _ in children] 700*2f2c4c7aSAndroid Build Coastguard Worker 701*2f2c4c7aSAndroid Build Coastguard Worker def CheckChildSocket(self, version, statename, parent_first): 702*2f2c4c7aSAndroid Build Coastguard Worker state = getattr(tcp_test, statename) 703*2f2c4c7aSAndroid Build Coastguard Worker 704*2f2c4c7aSAndroid Build Coastguard Worker self.IncomingConnection(version, state, self.netid) 705*2f2c4c7aSAndroid Build Coastguard Worker 706*2f2c4c7aSAndroid Build Coastguard Worker d = self.sock_diag.FindSockDiagFromFd(self.s) 707*2f2c4c7aSAndroid Build Coastguard Worker parent = self.sock_diag.DiagReqFromDiagMsg(d, IPPROTO_TCP) 708*2f2c4c7aSAndroid Build Coastguard Worker children = self.FindChildSockets(self.s) 709*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(1, len(children)) 710*2f2c4c7aSAndroid Build Coastguard Worker 711*2f2c4c7aSAndroid Build Coastguard Worker is_established = (state == tcp_test.TCP_NOT_YET_ACCEPTED) 712*2f2c4c7aSAndroid Build Coastguard Worker expected_state = tcp_test.TCP_ESTABLISHED if is_established else state 713*2f2c4c7aSAndroid Build Coastguard Worker 714*2f2c4c7aSAndroid Build Coastguard Worker for child in children: 715*2f2c4c7aSAndroid Build Coastguard Worker diag_msg, attrs = self.sock_diag.GetSockInfo(child) 716*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(diag_msg.state, expected_state) 717*2f2c4c7aSAndroid Build Coastguard Worker self.assertMarkIs(self.netid, attrs) 718*2f2c4c7aSAndroid Build Coastguard Worker 719*2f2c4c7aSAndroid Build Coastguard Worker def CloseParent(expect_reset): 720*2f2c4c7aSAndroid Build Coastguard Worker msg = "Closing parent IPv%d %s socket %s child" % ( 721*2f2c4c7aSAndroid Build Coastguard Worker version, statename, "before" if parent_first else "after") 722*2f2c4c7aSAndroid Build Coastguard Worker self.CheckRstOnClose(self.s, None, expect_reset, msg) 723*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(ENOENT, self.sock_diag.GetSockInfo, parent) 724*2f2c4c7aSAndroid Build Coastguard Worker 725*2f2c4c7aSAndroid Build Coastguard Worker def CheckChildrenClosed(): 726*2f2c4c7aSAndroid Build Coastguard Worker for child in children: 727*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(ENOENT, self.sock_diag.GetSockInfo, child) 728*2f2c4c7aSAndroid Build Coastguard Worker 729*2f2c4c7aSAndroid Build Coastguard Worker def CloseChildren(): 730*2f2c4c7aSAndroid Build Coastguard Worker for child in children: 731*2f2c4c7aSAndroid Build Coastguard Worker msg = "Closing child IPv%d %s socket %s parent" % ( 732*2f2c4c7aSAndroid Build Coastguard Worker version, statename, "after" if parent_first else "before") 733*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.GetSockInfo(child) 734*2f2c4c7aSAndroid Build Coastguard Worker self.CheckRstOnClose(None, child, is_established, msg) 735*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(ENOENT, self.sock_diag.GetSockInfo, child) 736*2f2c4c7aSAndroid Build Coastguard Worker CheckChildrenClosed() 737*2f2c4c7aSAndroid Build Coastguard Worker 738*2f2c4c7aSAndroid Build Coastguard Worker if parent_first: 739*2f2c4c7aSAndroid Build Coastguard Worker # Closing the parent will close child sockets, which will send a RST, 740*2f2c4c7aSAndroid Build Coastguard Worker # iff they are already established. 741*2f2c4c7aSAndroid Build Coastguard Worker CloseParent(is_established) 742*2f2c4c7aSAndroid Build Coastguard Worker if is_established: 743*2f2c4c7aSAndroid Build Coastguard Worker CheckChildrenClosed() 744*2f2c4c7aSAndroid Build Coastguard Worker else: 745*2f2c4c7aSAndroid Build Coastguard Worker CloseChildren() 746*2f2c4c7aSAndroid Build Coastguard Worker CheckChildrenClosed() 747*2f2c4c7aSAndroid Build Coastguard Worker else: 748*2f2c4c7aSAndroid Build Coastguard Worker CloseChildren() 749*2f2c4c7aSAndroid Build Coastguard Worker CloseParent(False) 750*2f2c4c7aSAndroid Build Coastguard Worker 751*2f2c4c7aSAndroid Build Coastguard Worker self.CloseSockets() 752*2f2c4c7aSAndroid Build Coastguard Worker 753*2f2c4c7aSAndroid Build Coastguard Worker def testChildSockets(self): 754*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 5, 6]: 755*2f2c4c7aSAndroid Build Coastguard Worker self.CheckChildSocket(version, "TCP_SYN_RECV", False) 756*2f2c4c7aSAndroid Build Coastguard Worker self.CheckChildSocket(version, "TCP_SYN_RECV", True) 757*2f2c4c7aSAndroid Build Coastguard Worker self.CheckChildSocket(version, "TCP_NOT_YET_ACCEPTED", False) 758*2f2c4c7aSAndroid Build Coastguard Worker self.CheckChildSocket(version, "TCP_NOT_YET_ACCEPTED", True) 759*2f2c4c7aSAndroid Build Coastguard Worker 760*2f2c4c7aSAndroid Build Coastguard Worker def testAcceptInterrupted(self): 761*2f2c4c7aSAndroid Build Coastguard Worker """Tests that accept() is interrupted by SOCK_DESTROY.""" 762*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 5, 6]: 763*2f2c4c7aSAndroid Build Coastguard Worker self.IncomingConnection(version, tcp_test.TCP_LISTEN, self.netid) 764*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(ENOTCONN, self.s.recv, 4096) 765*2f2c4c7aSAndroid Build Coastguard Worker self.CloseDuringBlockingCall(self.s, lambda sock: sock.accept(), EINVAL) 766*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(ECONNABORTED, self.s.send, b"foo") 767*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(EINVAL, self.s.accept) 768*2f2c4c7aSAndroid Build Coastguard Worker # TODO: this should really return an error such as ENOTCONN... 769*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(b"", self.s.recv(4096)) 770*2f2c4c7aSAndroid Build Coastguard Worker self.CloseSockets() 771*2f2c4c7aSAndroid Build Coastguard Worker 772*2f2c4c7aSAndroid Build Coastguard Worker def testReadInterrupted(self): 773*2f2c4c7aSAndroid Build Coastguard Worker """Tests that read() is interrupted by SOCK_DESTROY.""" 774*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 5, 6]: 775*2f2c4c7aSAndroid Build Coastguard Worker self.IncomingConnection(version, tcp_test.TCP_ESTABLISHED, self.netid) 776*2f2c4c7aSAndroid Build Coastguard Worker self.CloseDuringBlockingCall(self.accepted, lambda sock: sock.recv(4096), 777*2f2c4c7aSAndroid Build Coastguard Worker ECONNABORTED) 778*2f2c4c7aSAndroid Build Coastguard Worker # Writing returns EPIPE, and reading returns EOF. 779*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(EPIPE, self.accepted.send, b"foo") 780*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(b"", self.accepted.recv(4096)) 781*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(b"", self.accepted.recv(4096)) 782*2f2c4c7aSAndroid Build Coastguard Worker self.CloseSockets() 783*2f2c4c7aSAndroid Build Coastguard Worker 784*2f2c4c7aSAndroid Build Coastguard Worker def testConnectInterrupted(self): 785*2f2c4c7aSAndroid Build Coastguard Worker """Tests that connect() is interrupted by SOCK_DESTROY.""" 786*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 5, 6]: 787*2f2c4c7aSAndroid Build Coastguard Worker family = {4: AF_INET, 5: AF_INET6, 6: AF_INET6}[version] 788*2f2c4c7aSAndroid Build Coastguard Worker s = net_test.Socket(family, SOCK_STREAM, IPPROTO_TCP) 789*2f2c4c7aSAndroid Build Coastguard Worker self.SelectInterface(s, self.netid, "mark") 790*2f2c4c7aSAndroid Build Coastguard Worker 791*2f2c4c7aSAndroid Build Coastguard Worker remotesockaddr = self.GetRemoteSocketAddress(version) 792*2f2c4c7aSAndroid Build Coastguard Worker remoteaddr = self.GetRemoteAddress(version) 793*2f2c4c7aSAndroid Build Coastguard Worker s.bind(("", 0)) 794*2f2c4c7aSAndroid Build Coastguard Worker _, sport = s.getsockname()[:2] 795*2f2c4c7aSAndroid Build Coastguard Worker self.CloseDuringBlockingCall( 796*2f2c4c7aSAndroid Build Coastguard Worker s, lambda sock: sock.connect((remotesockaddr, 53)), ECONNABORTED) 797*2f2c4c7aSAndroid Build Coastguard Worker desc, syn = packets.SYN(53, version, self.MyAddress(version, self.netid), 798*2f2c4c7aSAndroid Build Coastguard Worker remoteaddr, sport=sport, seq=None) 799*2f2c4c7aSAndroid Build Coastguard Worker self.ExpectPacketOn(self.netid, desc, syn) 800*2f2c4c7aSAndroid Build Coastguard Worker msg = "SOCK_DESTROY of socket in connect, expected no RST" 801*2f2c4c7aSAndroid Build Coastguard Worker self.ExpectNoPacketsOn(self.netid, msg) 802*2f2c4c7aSAndroid Build Coastguard Worker s.close() 803*2f2c4c7aSAndroid Build Coastguard Worker 804*2f2c4c7aSAndroid Build Coastguard Worker 805*2f2c4c7aSAndroid Build Coastguard Workerclass PollOnCloseTest(tcp_test.TcpBaseTest, SockDiagBaseTest): 806*2f2c4c7aSAndroid Build Coastguard Worker """Tests that the effect of SOCK_DESTROY on poll matches TCP RSTs. 807*2f2c4c7aSAndroid Build Coastguard Worker 808*2f2c4c7aSAndroid Build Coastguard Worker The behaviour of poll() in these cases is not what we might expect: if only 809*2f2c4c7aSAndroid Build Coastguard Worker POLLIN is specified, it will return POLLIN|POLLERR|POLLHUP, but if POLLOUT 810*2f2c4c7aSAndroid Build Coastguard Worker is (also) specified, it will only return POLLOUT. 811*2f2c4c7aSAndroid Build Coastguard Worker """ 812*2f2c4c7aSAndroid Build Coastguard Worker 813*2f2c4c7aSAndroid Build Coastguard Worker POLLIN_OUT = select.POLLIN | select.POLLOUT 814*2f2c4c7aSAndroid Build Coastguard Worker POLLIN_ERR_HUP = select.POLLIN | select.POLLERR | select.POLLHUP 815*2f2c4c7aSAndroid Build Coastguard Worker 816*2f2c4c7aSAndroid Build Coastguard Worker def setUp(self): 817*2f2c4c7aSAndroid Build Coastguard Worker super(PollOnCloseTest, self).setUp() 818*2f2c4c7aSAndroid Build Coastguard Worker self.netid = random.choice(list(self.tuns.keys())) 819*2f2c4c7aSAndroid Build Coastguard Worker 820*2f2c4c7aSAndroid Build Coastguard Worker POLL_FLAGS = [(select.POLLIN, "IN"), (select.POLLOUT, "OUT"), 821*2f2c4c7aSAndroid Build Coastguard Worker (select.POLLERR, "ERR"), (select.POLLHUP, "HUP")] 822*2f2c4c7aSAndroid Build Coastguard Worker 823*2f2c4c7aSAndroid Build Coastguard Worker def PollResultToString(self, poll_events, ignoremask): 824*2f2c4c7aSAndroid Build Coastguard Worker out = [] 825*2f2c4c7aSAndroid Build Coastguard Worker for fd, event in poll_events: 826*2f2c4c7aSAndroid Build Coastguard Worker flags = [name for (flag, name) in self.POLL_FLAGS 827*2f2c4c7aSAndroid Build Coastguard Worker if event & flag & ~ignoremask != 0] 828*2f2c4c7aSAndroid Build Coastguard Worker out.append((fd, "|".join(flags))) 829*2f2c4c7aSAndroid Build Coastguard Worker return out 830*2f2c4c7aSAndroid Build Coastguard Worker 831*2f2c4c7aSAndroid Build Coastguard Worker def BlockingPoll(self, sock, mask, expected, ignoremask): 832*2f2c4c7aSAndroid Build Coastguard Worker p = select.poll() 833*2f2c4c7aSAndroid Build Coastguard Worker p.register(sock, mask) 834*2f2c4c7aSAndroid Build Coastguard Worker expected_fds = [(sock.fileno(), expected)] 835*2f2c4c7aSAndroid Build Coastguard Worker # Don't block forever or we'll hang continuous test runs on failure. 836*2f2c4c7aSAndroid Build Coastguard Worker # A 5-second timeout should be long enough not to be flaky. 837*2f2c4c7aSAndroid Build Coastguard Worker actual_fds = p.poll(5000) 838*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(self.PollResultToString(expected_fds, ignoremask), 839*2f2c4c7aSAndroid Build Coastguard Worker self.PollResultToString(actual_fds, ignoremask)) 840*2f2c4c7aSAndroid Build Coastguard Worker 841*2f2c4c7aSAndroid Build Coastguard Worker def RstDuringBlockingCall(self, sock, call, expected_errno): 842*2f2c4c7aSAndroid Build Coastguard Worker self._EventDuringBlockingCall( 843*2f2c4c7aSAndroid Build Coastguard Worker sock, call, expected_errno, 844*2f2c4c7aSAndroid Build Coastguard Worker lambda _: self.ReceiveRstPacketOn(self.netid)) 845*2f2c4c7aSAndroid Build Coastguard Worker 846*2f2c4c7aSAndroid Build Coastguard Worker def assertSocketErrors(self, errno): 847*2f2c4c7aSAndroid Build Coastguard Worker # The first operation returns the expected errno. 848*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(errno, self.accepted.recv, 4096) 849*2f2c4c7aSAndroid Build Coastguard Worker 850*2f2c4c7aSAndroid Build Coastguard Worker # Subsequent operations behave as normal. 851*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(EPIPE, self.accepted.send, b"foo") 852*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(b"", self.accepted.recv(4096)) 853*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(b"", self.accepted.recv(4096)) 854*2f2c4c7aSAndroid Build Coastguard Worker 855*2f2c4c7aSAndroid Build Coastguard Worker def CheckPollDestroy(self, mask, expected, ignoremask): 856*2f2c4c7aSAndroid Build Coastguard Worker """Interrupts a poll() with SOCK_DESTROY.""" 857*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 5, 6]: 858*2f2c4c7aSAndroid Build Coastguard Worker self.IncomingConnection(version, tcp_test.TCP_ESTABLISHED, self.netid) 859*2f2c4c7aSAndroid Build Coastguard Worker self.CloseDuringBlockingCall( 860*2f2c4c7aSAndroid Build Coastguard Worker self.accepted, 861*2f2c4c7aSAndroid Build Coastguard Worker lambda sock: self.BlockingPoll(sock, mask, expected, ignoremask), 862*2f2c4c7aSAndroid Build Coastguard Worker None) 863*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketErrors(ECONNABORTED) 864*2f2c4c7aSAndroid Build Coastguard Worker self.CloseSockets() 865*2f2c4c7aSAndroid Build Coastguard Worker 866*2f2c4c7aSAndroid Build Coastguard Worker def CheckPollRst(self, mask, expected, ignoremask): 867*2f2c4c7aSAndroid Build Coastguard Worker """Interrupts a poll() by receiving a TCP RST.""" 868*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 5, 6]: 869*2f2c4c7aSAndroid Build Coastguard Worker self.IncomingConnection(version, tcp_test.TCP_ESTABLISHED, self.netid) 870*2f2c4c7aSAndroid Build Coastguard Worker self.RstDuringBlockingCall( 871*2f2c4c7aSAndroid Build Coastguard Worker self.accepted, 872*2f2c4c7aSAndroid Build Coastguard Worker lambda sock: self.BlockingPoll(sock, mask, expected, ignoremask), 873*2f2c4c7aSAndroid Build Coastguard Worker None) 874*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketErrors(ECONNRESET) 875*2f2c4c7aSAndroid Build Coastguard Worker self.CloseSockets() 876*2f2c4c7aSAndroid Build Coastguard Worker 877*2f2c4c7aSAndroid Build Coastguard Worker def testReadPollRst(self): 878*2f2c4c7aSAndroid Build Coastguard Worker self.CheckPollRst(select.POLLIN, self.POLLIN_ERR_HUP, 0) 879*2f2c4c7aSAndroid Build Coastguard Worker 880*2f2c4c7aSAndroid Build Coastguard Worker def testWritePollRst(self): 881*2f2c4c7aSAndroid Build Coastguard Worker self.CheckPollRst(select.POLLOUT, select.POLLOUT, 0) 882*2f2c4c7aSAndroid Build Coastguard Worker 883*2f2c4c7aSAndroid Build Coastguard Worker def testReadWritePollRst(self): 884*2f2c4c7aSAndroid Build Coastguard Worker self.CheckPollRst(self.POLLIN_OUT, select.POLLOUT, 0) 885*2f2c4c7aSAndroid Build Coastguard Worker 886*2f2c4c7aSAndroid Build Coastguard Worker def testReadPollDestroy(self): 887*2f2c4c7aSAndroid Build Coastguard Worker # tcp_abort has the same race that tcp_reset has, but it's not fixed yet. 888*2f2c4c7aSAndroid Build Coastguard Worker ignoremask = select.POLLIN | select.POLLHUP 889*2f2c4c7aSAndroid Build Coastguard Worker self.CheckPollDestroy(select.POLLIN, self.POLLIN_ERR_HUP, ignoremask) 890*2f2c4c7aSAndroid Build Coastguard Worker 891*2f2c4c7aSAndroid Build Coastguard Worker def testWritePollDestroy(self): 892*2f2c4c7aSAndroid Build Coastguard Worker self.CheckPollDestroy(select.POLLOUT, select.POLLOUT, 0) 893*2f2c4c7aSAndroid Build Coastguard Worker 894*2f2c4c7aSAndroid Build Coastguard Worker def testReadWritePollDestroy(self): 895*2f2c4c7aSAndroid Build Coastguard Worker self.CheckPollDestroy(self.POLLIN_OUT, select.POLLOUT, 0) 896*2f2c4c7aSAndroid Build Coastguard Worker 897*2f2c4c7aSAndroid Build Coastguard Worker 898*2f2c4c7aSAndroid Build Coastguard Workerclass SockDestroyUdpTest(SockDiagBaseTest): 899*2f2c4c7aSAndroid Build Coastguard Worker 900*2f2c4c7aSAndroid Build Coastguard Worker """Tests SOCK_DESTROY on UDP sockets. 901*2f2c4c7aSAndroid Build Coastguard Worker 902*2f2c4c7aSAndroid Build Coastguard Worker Relevant kernel commits: 903*2f2c4c7aSAndroid Build Coastguard Worker upstream net-next: 904*2f2c4c7aSAndroid Build Coastguard Worker 5d77dca net: diag: support SOCK_DESTROY for UDP sockets 905*2f2c4c7aSAndroid Build Coastguard Worker f95bf34 net: diag: make udp_diag_destroy work for mapped addresses. 906*2f2c4c7aSAndroid Build Coastguard Worker """ 907*2f2c4c7aSAndroid Build Coastguard Worker 908*2f2c4c7aSAndroid Build Coastguard Worker def testClosesUdpSockets(self): 909*2f2c4c7aSAndroid Build Coastguard Worker self.socketpairs = self._CreateLotsOfSockets(SOCK_DGRAM) 910*2f2c4c7aSAndroid Build Coastguard Worker for _, socketpair in self.socketpairs.items(): 911*2f2c4c7aSAndroid Build Coastguard Worker s1, s2 = socketpair 912*2f2c4c7aSAndroid Build Coastguard Worker 913*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketConnected(s1) 914*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.CloseSocketFromFd(s1) 915*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketClosed(s1) 916*2f2c4c7aSAndroid Build Coastguard Worker 917*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketConnected(s2) 918*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.CloseSocketFromFd(s2) 919*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketClosed(s2) 920*2f2c4c7aSAndroid Build Coastguard Worker 921*2f2c4c7aSAndroid Build Coastguard Worker def BindToRandomPort(self, s, addr): 922*2f2c4c7aSAndroid Build Coastguard Worker ATTEMPTS = 20 923*2f2c4c7aSAndroid Build Coastguard Worker for i in range(20): 924*2f2c4c7aSAndroid Build Coastguard Worker port = random.randrange(1024, 65535) 925*2f2c4c7aSAndroid Build Coastguard Worker try: 926*2f2c4c7aSAndroid Build Coastguard Worker s.bind((addr, port)) 927*2f2c4c7aSAndroid Build Coastguard Worker return port 928*2f2c4c7aSAndroid Build Coastguard Worker except error as e: 929*2f2c4c7aSAndroid Build Coastguard Worker if e.errno != EADDRINUSE: 930*2f2c4c7aSAndroid Build Coastguard Worker raise e 931*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Could not find a free port on %s after %d attempts" % 932*2f2c4c7aSAndroid Build Coastguard Worker (addr, ATTEMPTS)) 933*2f2c4c7aSAndroid Build Coastguard Worker 934*2f2c4c7aSAndroid Build Coastguard Worker def testSocketAddressesAfterClose(self): 935*2f2c4c7aSAndroid Build Coastguard Worker for version in 4, 5, 6: 936*2f2c4c7aSAndroid Build Coastguard Worker netid = random.choice(self.NETIDS) 937*2f2c4c7aSAndroid Build Coastguard Worker dst = self.GetRemoteSocketAddress(version) 938*2f2c4c7aSAndroid Build Coastguard Worker family = {4: AF_INET, 5: AF_INET6, 6: AF_INET6}[version] 939*2f2c4c7aSAndroid Build Coastguard Worker unspec = {4: "0.0.0.0", 5: "::", 6: "::"}[version] 940*2f2c4c7aSAndroid Build Coastguard Worker 941*2f2c4c7aSAndroid Build Coastguard Worker # Closing a socket that was not explicitly bound (i.e., bound via 942*2f2c4c7aSAndroid Build Coastguard Worker # connect(), not bind()) clears the source address and port. 943*2f2c4c7aSAndroid Build Coastguard Worker s = self.BuildSocket(version, net_test.UDPSocket, netid, "mark") 944*2f2c4c7aSAndroid Build Coastguard Worker self.SelectInterface(s, netid, "mark") 945*2f2c4c7aSAndroid Build Coastguard Worker s.connect((dst, 53)) 946*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.CloseSocketFromFd(s) 947*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual((unspec, 0), s.getsockname()[:2]) 948*2f2c4c7aSAndroid Build Coastguard Worker s.close() 949*2f2c4c7aSAndroid Build Coastguard Worker 950*2f2c4c7aSAndroid Build Coastguard Worker # Closing a socket bound to an IP address leaves the address as is. 951*2f2c4c7aSAndroid Build Coastguard Worker s = self.BuildSocket(version, net_test.UDPSocket, netid, "mark") 952*2f2c4c7aSAndroid Build Coastguard Worker src = self.MySocketAddress(version, netid) 953*2f2c4c7aSAndroid Build Coastguard Worker s.bind((src, 0)) 954*2f2c4c7aSAndroid Build Coastguard Worker s.connect((dst, 53)) 955*2f2c4c7aSAndroid Build Coastguard Worker port = s.getsockname()[1] 956*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.CloseSocketFromFd(s) 957*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual((src, 0), s.getsockname()[:2]) 958*2f2c4c7aSAndroid Build Coastguard Worker s.close() 959*2f2c4c7aSAndroid Build Coastguard Worker 960*2f2c4c7aSAndroid Build Coastguard Worker # Closing a socket bound to a port leaves the port as is. 961*2f2c4c7aSAndroid Build Coastguard Worker s = self.BuildSocket(version, net_test.UDPSocket, netid, "mark") 962*2f2c4c7aSAndroid Build Coastguard Worker port = self.BindToRandomPort(s, "") 963*2f2c4c7aSAndroid Build Coastguard Worker s.connect((dst, 53)) 964*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.CloseSocketFromFd(s) 965*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual((unspec, port), s.getsockname()[:2]) 966*2f2c4c7aSAndroid Build Coastguard Worker s.close() 967*2f2c4c7aSAndroid Build Coastguard Worker 968*2f2c4c7aSAndroid Build Coastguard Worker # Closing a socket bound to IP address and port leaves both as is. 969*2f2c4c7aSAndroid Build Coastguard Worker s = self.BuildSocket(version, net_test.UDPSocket, netid, "mark") 970*2f2c4c7aSAndroid Build Coastguard Worker src = self.MySocketAddress(version, netid) 971*2f2c4c7aSAndroid Build Coastguard Worker port = self.BindToRandomPort(s, src) 972*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.CloseSocketFromFd(s) 973*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual((src, port), s.getsockname()[:2]) 974*2f2c4c7aSAndroid Build Coastguard Worker s.close() 975*2f2c4c7aSAndroid Build Coastguard Worker 976*2f2c4c7aSAndroid Build Coastguard Worker def testReadInterrupted(self): 977*2f2c4c7aSAndroid Build Coastguard Worker """Tests that read() is interrupted by SOCK_DESTROY.""" 978*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 5, 6]: 979*2f2c4c7aSAndroid Build Coastguard Worker family = {4: AF_INET, 5: AF_INET6, 6: AF_INET6}[version] 980*2f2c4c7aSAndroid Build Coastguard Worker s = net_test.UDPSocket(family) 981*2f2c4c7aSAndroid Build Coastguard Worker self.SelectInterface(s, random.choice(self.NETIDS), "mark") 982*2f2c4c7aSAndroid Build Coastguard Worker addr = self.GetRemoteSocketAddress(version) 983*2f2c4c7aSAndroid Build Coastguard Worker 984*2f2c4c7aSAndroid Build Coastguard Worker # Check that reads on connected sockets are interrupted. 985*2f2c4c7aSAndroid Build Coastguard Worker s.connect((addr, 53)) 986*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(3, s.send(b"foo")) 987*2f2c4c7aSAndroid Build Coastguard Worker self.CloseDuringBlockingCall(s, lambda sock: sock.recv(4096), 988*2f2c4c7aSAndroid Build Coastguard Worker ECONNABORTED) 989*2f2c4c7aSAndroid Build Coastguard Worker 990*2f2c4c7aSAndroid Build Coastguard Worker # A destroyed socket is no longer connected, but still usable. 991*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(EDESTADDRREQ, s.send, b"foo") 992*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(3, s.sendto(b"foo", (addr, 53))) 993*2f2c4c7aSAndroid Build Coastguard Worker 994*2f2c4c7aSAndroid Build Coastguard Worker # Check that reads on unconnected sockets are also interrupted. 995*2f2c4c7aSAndroid Build Coastguard Worker self.CloseDuringBlockingCall(s, lambda sock: sock.recv(4096), 996*2f2c4c7aSAndroid Build Coastguard Worker ECONNABORTED) 997*2f2c4c7aSAndroid Build Coastguard Worker 998*2f2c4c7aSAndroid Build Coastguard Worker s.close() 999*2f2c4c7aSAndroid Build Coastguard Worker 1000*2f2c4c7aSAndroid Build Coastguard Workerclass SockDestroyPermissionTest(SockDiagBaseTest): 1001*2f2c4c7aSAndroid Build Coastguard Worker 1002*2f2c4c7aSAndroid Build Coastguard Worker def CheckPermissions(self, socktype): 1003*2f2c4c7aSAndroid Build Coastguard Worker s = socket(AF_INET6, socktype, 0) 1004*2f2c4c7aSAndroid Build Coastguard Worker self.SelectInterface(s, random.choice(self.NETIDS), "mark") 1005*2f2c4c7aSAndroid Build Coastguard Worker if socktype == SOCK_STREAM: 1006*2f2c4c7aSAndroid Build Coastguard Worker s.listen(1) 1007*2f2c4c7aSAndroid Build Coastguard Worker expectedstate = tcp_test.TCP_LISTEN 1008*2f2c4c7aSAndroid Build Coastguard Worker else: 1009*2f2c4c7aSAndroid Build Coastguard Worker s.connect((self.GetRemoteAddress(6), 53)) 1010*2f2c4c7aSAndroid Build Coastguard Worker expectedstate = tcp_test.TCP_ESTABLISHED 1011*2f2c4c7aSAndroid Build Coastguard Worker 1012*2f2c4c7aSAndroid Build Coastguard Worker with net_test.RunAsUid(12345): 1013*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno( 1014*2f2c4c7aSAndroid Build Coastguard Worker EPERM, self.sock_diag.CloseSocketFromFd, s) 1015*2f2c4c7aSAndroid Build Coastguard Worker 1016*2f2c4c7aSAndroid Build Coastguard Worker self.sock_diag.CloseSocketFromFd(s) 1017*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaises(ValueError, self.sock_diag.CloseSocketFromFd, s) 1018*2f2c4c7aSAndroid Build Coastguard Worker 1019*2f2c4c7aSAndroid Build Coastguard Worker s.close() 1020*2f2c4c7aSAndroid Build Coastguard Worker 1021*2f2c4c7aSAndroid Build Coastguard Worker 1022*2f2c4c7aSAndroid Build Coastguard Worker def testUdp(self): 1023*2f2c4c7aSAndroid Build Coastguard Worker self.CheckPermissions(SOCK_DGRAM) 1024*2f2c4c7aSAndroid Build Coastguard Worker 1025*2f2c4c7aSAndroid Build Coastguard Worker def testTcp(self): 1026*2f2c4c7aSAndroid Build Coastguard Worker self.CheckPermissions(SOCK_STREAM) 1027*2f2c4c7aSAndroid Build Coastguard Worker 1028*2f2c4c7aSAndroid Build Coastguard Worker 1029*2f2c4c7aSAndroid Build Coastguard Workerclass SockDiagMarkTest(tcp_test.TcpBaseTest, SockDiagBaseTest): 1030*2f2c4c7aSAndroid Build Coastguard Worker 1031*2f2c4c7aSAndroid Build Coastguard Worker """Tests SOCK_DIAG bytecode filters that use marks. 1032*2f2c4c7aSAndroid Build Coastguard Worker 1033*2f2c4c7aSAndroid Build Coastguard Worker Relevant kernel commits: 1034*2f2c4c7aSAndroid Build Coastguard Worker upstream net-next: 1035*2f2c4c7aSAndroid Build Coastguard Worker 627cc4a net: diag: slightly refactor the inet_diag_bc_audit error checks. 1036*2f2c4c7aSAndroid Build Coastguard Worker a52e95a net: diag: allow socket bytecode filters to match socket marks 1037*2f2c4c7aSAndroid Build Coastguard Worker d545cac net: inet: diag: expose the socket mark to privileged processes. 1038*2f2c4c7aSAndroid Build Coastguard Worker """ 1039*2f2c4c7aSAndroid Build Coastguard Worker 1040*2f2c4c7aSAndroid Build Coastguard Worker def FilterEstablishedSockets(self, mark, mask): 1041*2f2c4c7aSAndroid Build Coastguard Worker instructions = [(sock_diag.INET_DIAG_BC_MARK_COND, 1, 2, (mark, mask))] 1042*2f2c4c7aSAndroid Build Coastguard Worker bytecode = self.sock_diag.PackBytecode(instructions) 1043*2f2c4c7aSAndroid Build Coastguard Worker return self.sock_diag.DumpAllInetSockets( 1044*2f2c4c7aSAndroid Build Coastguard Worker IPPROTO_TCP, bytecode, states=(1 << tcp_test.TCP_ESTABLISHED)) 1045*2f2c4c7aSAndroid Build Coastguard Worker 1046*2f2c4c7aSAndroid Build Coastguard Worker def assertSamePorts(self, ports, diag_msgs): 1047*2f2c4c7aSAndroid Build Coastguard Worker expected = sorted(ports) 1048*2f2c4c7aSAndroid Build Coastguard Worker actual = sorted([msg[0].id.sport for msg in diag_msgs]) 1049*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(expected, actual) 1050*2f2c4c7aSAndroid Build Coastguard Worker 1051*2f2c4c7aSAndroid Build Coastguard Worker def SockInfoMatchesSocket(self, s, info): 1052*2f2c4c7aSAndroid Build Coastguard Worker try: 1053*2f2c4c7aSAndroid Build Coastguard Worker self.assertSockInfoMatchesSocket(s, info) 1054*2f2c4c7aSAndroid Build Coastguard Worker return True 1055*2f2c4c7aSAndroid Build Coastguard Worker except AssertionError: 1056*2f2c4c7aSAndroid Build Coastguard Worker return False 1057*2f2c4c7aSAndroid Build Coastguard Worker 1058*2f2c4c7aSAndroid Build Coastguard Worker @staticmethod 1059*2f2c4c7aSAndroid Build Coastguard Worker def SocketDescription(s): 1060*2f2c4c7aSAndroid Build Coastguard Worker return "%s -> %s" % (str(s.getsockname()), str(s.getpeername())) 1061*2f2c4c7aSAndroid Build Coastguard Worker 1062*2f2c4c7aSAndroid Build Coastguard Worker def assertFoundSockets(self, infos, sockets): 1063*2f2c4c7aSAndroid Build Coastguard Worker matches = {} 1064*2f2c4c7aSAndroid Build Coastguard Worker for s in sockets: 1065*2f2c4c7aSAndroid Build Coastguard Worker match = None 1066*2f2c4c7aSAndroid Build Coastguard Worker for info in infos: 1067*2f2c4c7aSAndroid Build Coastguard Worker if self.SockInfoMatchesSocket(s, info): 1068*2f2c4c7aSAndroid Build Coastguard Worker if match: 1069*2f2c4c7aSAndroid Build Coastguard Worker self.fail("Socket %s matched both %s and %s" % 1070*2f2c4c7aSAndroid Build Coastguard Worker (self.SocketDescription(s), match, info)) 1071*2f2c4c7aSAndroid Build Coastguard Worker matches[s] = info 1072*2f2c4c7aSAndroid Build Coastguard Worker self.assertTrue(s in matches, "Did not find socket %s in dump" % 1073*2f2c4c7aSAndroid Build Coastguard Worker self.SocketDescription(s)) 1074*2f2c4c7aSAndroid Build Coastguard Worker 1075*2f2c4c7aSAndroid Build Coastguard Worker for i in infos: 1076*2f2c4c7aSAndroid Build Coastguard Worker if i not in list(matches.values()): 1077*2f2c4c7aSAndroid Build Coastguard Worker self.fail("Too many sockets in dump, first unexpected: %s" % str(i)) 1078*2f2c4c7aSAndroid Build Coastguard Worker 1079*2f2c4c7aSAndroid Build Coastguard Worker def testMarkBytecode(self): 1080*2f2c4c7aSAndroid Build Coastguard Worker family, addr = random.choice([ 1081*2f2c4c7aSAndroid Build Coastguard Worker (AF_INET, "127.0.0.1"), 1082*2f2c4c7aSAndroid Build Coastguard Worker (AF_INET6, "::1"), 1083*2f2c4c7aSAndroid Build Coastguard Worker (AF_INET6, "::ffff:127.0.0.1")]) 1084*2f2c4c7aSAndroid Build Coastguard Worker s1, s2 = net_test.CreateSocketPair(family, SOCK_STREAM, addr) 1085*2f2c4c7aSAndroid Build Coastguard Worker s1.setsockopt(SOL_SOCKET, net_test.SO_MARK, 0xfff1234) 1086*2f2c4c7aSAndroid Build Coastguard Worker s2.setsockopt(SOL_SOCKET, net_test.SO_MARK, 0xf0f1235) 1087*2f2c4c7aSAndroid Build Coastguard Worker 1088*2f2c4c7aSAndroid Build Coastguard Worker infos = self.FilterEstablishedSockets(0x1234, 0xffff) 1089*2f2c4c7aSAndroid Build Coastguard Worker self.assertFoundSockets(infos, [s1]) 1090*2f2c4c7aSAndroid Build Coastguard Worker 1091*2f2c4c7aSAndroid Build Coastguard Worker infos = self.FilterEstablishedSockets(0x1234, 0xfffe) 1092*2f2c4c7aSAndroid Build Coastguard Worker self.assertFoundSockets(infos, [s1, s2]) 1093*2f2c4c7aSAndroid Build Coastguard Worker 1094*2f2c4c7aSAndroid Build Coastguard Worker infos = self.FilterEstablishedSockets(0x1235, 0xffff) 1095*2f2c4c7aSAndroid Build Coastguard Worker self.assertFoundSockets(infos, [s2]) 1096*2f2c4c7aSAndroid Build Coastguard Worker 1097*2f2c4c7aSAndroid Build Coastguard Worker infos = self.FilterEstablishedSockets(0x0, 0x0) 1098*2f2c4c7aSAndroid Build Coastguard Worker self.assertFoundSockets(infos, [s1, s2]) 1099*2f2c4c7aSAndroid Build Coastguard Worker 1100*2f2c4c7aSAndroid Build Coastguard Worker infos = self.FilterEstablishedSockets(0xfff0000, 0xf0fed00) 1101*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(0, len(infos)) 1102*2f2c4c7aSAndroid Build Coastguard Worker 1103*2f2c4c7aSAndroid Build Coastguard Worker with net_test.RunAsUid(12345): 1104*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(EPERM, self.FilterEstablishedSockets, 1105*2f2c4c7aSAndroid Build Coastguard Worker 0xfff0000, 0xf0fed00) 1106*2f2c4c7aSAndroid Build Coastguard Worker 1107*2f2c4c7aSAndroid Build Coastguard Worker s1.close() 1108*2f2c4c7aSAndroid Build Coastguard Worker s2.close() 1109*2f2c4c7aSAndroid Build Coastguard Worker 1110*2f2c4c7aSAndroid Build Coastguard Worker @staticmethod 1111*2f2c4c7aSAndroid Build Coastguard Worker def SetRandomMark(s): 1112*2f2c4c7aSAndroid Build Coastguard Worker # Python doesn't like marks that don't fit into a signed int. 1113*2f2c4c7aSAndroid Build Coastguard Worker mark = random.randrange(0, 2**31 - 1) 1114*2f2c4c7aSAndroid Build Coastguard Worker s.setsockopt(SOL_SOCKET, net_test.SO_MARK, mark) 1115*2f2c4c7aSAndroid Build Coastguard Worker return mark 1116*2f2c4c7aSAndroid Build Coastguard Worker 1117*2f2c4c7aSAndroid Build Coastguard Worker def assertSocketMarkIs(self, s, mark): 1118*2f2c4c7aSAndroid Build Coastguard Worker diag_msg, attrs = self.sock_diag.FindSockInfoFromFd(s) 1119*2f2c4c7aSAndroid Build Coastguard Worker self.assertMarkIs(mark, attrs) 1120*2f2c4c7aSAndroid Build Coastguard Worker with net_test.RunAsUid(12345): 1121*2f2c4c7aSAndroid Build Coastguard Worker diag_msg, attrs = self.sock_diag.FindSockInfoFromFd(s) 1122*2f2c4c7aSAndroid Build Coastguard Worker self.assertMarkIs(None, attrs) 1123*2f2c4c7aSAndroid Build Coastguard Worker 1124*2f2c4c7aSAndroid Build Coastguard Worker def testMarkInAttributes(self): 1125*2f2c4c7aSAndroid Build Coastguard Worker testcases = [(AF_INET, "127.0.0.1"), 1126*2f2c4c7aSAndroid Build Coastguard Worker (AF_INET6, "::1"), 1127*2f2c4c7aSAndroid Build Coastguard Worker (AF_INET6, "::ffff:127.0.0.1")] 1128*2f2c4c7aSAndroid Build Coastguard Worker for family, addr in testcases: 1129*2f2c4c7aSAndroid Build Coastguard Worker # TCP listen sockets. 1130*2f2c4c7aSAndroid Build Coastguard Worker server = socket(family, SOCK_STREAM, 0) 1131*2f2c4c7aSAndroid Build Coastguard Worker server.bind((addr, 0)) 1132*2f2c4c7aSAndroid Build Coastguard Worker port = server.getsockname()[1] 1133*2f2c4c7aSAndroid Build Coastguard Worker server.listen(1) # Or the socket won't be in the hashtables. 1134*2f2c4c7aSAndroid Build Coastguard Worker server_mark = self.SetRandomMark(server) 1135*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketMarkIs(server, server_mark) 1136*2f2c4c7aSAndroid Build Coastguard Worker 1137*2f2c4c7aSAndroid Build Coastguard Worker # TCP client sockets. 1138*2f2c4c7aSAndroid Build Coastguard Worker client = socket(family, SOCK_STREAM, 0) 1139*2f2c4c7aSAndroid Build Coastguard Worker client_mark = self.SetRandomMark(client) 1140*2f2c4c7aSAndroid Build Coastguard Worker client.connect((addr, port)) 1141*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketMarkIs(client, client_mark) 1142*2f2c4c7aSAndroid Build Coastguard Worker 1143*2f2c4c7aSAndroid Build Coastguard Worker # TCP server sockets. 1144*2f2c4c7aSAndroid Build Coastguard Worker accepted, _ = server.accept() 1145*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketMarkIs(accepted, server_mark) 1146*2f2c4c7aSAndroid Build Coastguard Worker 1147*2f2c4c7aSAndroid Build Coastguard Worker accepted_mark = self.SetRandomMark(accepted) 1148*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketMarkIs(accepted, accepted_mark) 1149*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketMarkIs(server, server_mark) 1150*2f2c4c7aSAndroid Build Coastguard Worker 1151*2f2c4c7aSAndroid Build Coastguard Worker accepted.close() 1152*2f2c4c7aSAndroid Build Coastguard Worker server.close() 1153*2f2c4c7aSAndroid Build Coastguard Worker client.close() 1154*2f2c4c7aSAndroid Build Coastguard Worker 1155*2f2c4c7aSAndroid Build Coastguard Worker # Other TCP states are tested in SockDestroyTcpTest. 1156*2f2c4c7aSAndroid Build Coastguard Worker 1157*2f2c4c7aSAndroid Build Coastguard Worker # UDP sockets. 1158*2f2c4c7aSAndroid Build Coastguard Worker s = socket(family, SOCK_DGRAM, 0) 1159*2f2c4c7aSAndroid Build Coastguard Worker mark = self.SetRandomMark(s) 1160*2f2c4c7aSAndroid Build Coastguard Worker s.connect(("", 53)) 1161*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketMarkIs(s, mark) 1162*2f2c4c7aSAndroid Build Coastguard Worker s.close() 1163*2f2c4c7aSAndroid Build Coastguard Worker 1164*2f2c4c7aSAndroid Build Coastguard Worker # Basic test for SCTP. sctp_diag was only added in 4.7. 1165*2f2c4c7aSAndroid Build Coastguard Worker if HAVE_SCTP: 1166*2f2c4c7aSAndroid Build Coastguard Worker s = socket(family, SOCK_STREAM, IPPROTO_SCTP) 1167*2f2c4c7aSAndroid Build Coastguard Worker s.bind((addr, 0)) 1168*2f2c4c7aSAndroid Build Coastguard Worker s.listen(1) 1169*2f2c4c7aSAndroid Build Coastguard Worker mark = self.SetRandomMark(s) 1170*2f2c4c7aSAndroid Build Coastguard Worker self.assertSocketMarkIs(s, mark) 1171*2f2c4c7aSAndroid Build Coastguard Worker sockets = self.sock_diag.DumpAllInetSockets(IPPROTO_SCTP, NO_BYTECODE) 1172*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(1, len(sockets)) 1173*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(mark, sockets[0][1].get("INET_DIAG_MARK", None)) 1174*2f2c4c7aSAndroid Build Coastguard Worker s.close() 1175*2f2c4c7aSAndroid Build Coastguard Worker 1176*2f2c4c7aSAndroid Build Coastguard Worker 1177*2f2c4c7aSAndroid Build Coastguard Workerif __name__ == "__main__": 1178*2f2c4c7aSAndroid Build Coastguard Worker unittest.main() 1179