diff options
author | Lorenzo Colitti <lorenzo@google.com> | 2017-01-17 03:57:33 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2017-01-17 03:57:33 +0000 |
commit | 23471e471df7355e05fd61ac36f8c83293dca269 (patch) | |
tree | 4a448a0c40b399e73820981e0e6f5b2022d8ee96 | |
parent | 3c8ae064554e1b418a44bdc6fbb692df1d834ea7 (diff) | |
parent | ebe1d89525d779ba81d93c7e2a7314df930c09ee (diff) | |
download | tests-23471e471df7355e05fd61ac36f8c83293dca269.tar.gz |
Ensure SIOCKILLADDR is no longer supported. am: 2fcf8feb45
am: ebe1d89525
Change-Id: Ie41082db26f17077644ae5fe8edcd7394816a9c7
-rwxr-xr-x | net/test/tcp_nuke_addr_test.py | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/net/test/tcp_nuke_addr_test.py b/net/test/tcp_nuke_addr_test.py new file mode 100755 index 0000000..deb4012 --- /dev/null +++ b/net/test/tcp_nuke_addr_test.py @@ -0,0 +1,112 @@ +#!/usr/bin/python +# +# Copyright 2017 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import errno +import fcntl +from socket import * # pylint: disable=wildcard-import +import unittest + +import csocket +import cstruct +import net_test + +IPV4_LOOPBACK_ADDR = "127.0.0.1" +IPV6_LOOPBACK_ADDR = "::1" +LOOPBACK_DEV = "lo" +LOOPBACK_IFINDEX = 1 + +SIOCKILLADDR = 0x8939 + + +Ifreq = cstruct.Struct("Ifreq", "=16s16s", "name data") +In6Ifreq = cstruct.Struct("In6Ifreq", "=16sIi", "addr prefixlen ifindex") + +def KillAddrIoctl(addr): + """Calls the SIOCKILLADDR ioctl on the provided IP address. + + Args: + addr The IP address to pass to the ioctl. + + Raises: + ValueError: If addr is of an unsupported address family. + """ + family, _, _, _, _ = getaddrinfo(addr, None, AF_UNSPEC, SOCK_DGRAM, 0, + AI_NUMERICHOST)[0] + if family == AF_INET6: + addr = inet_pton(AF_INET6, addr) + ifreq = In6Ifreq((addr, 128, LOOPBACK_IFINDEX)).Pack() + elif family == AF_INET: + addr = inet_pton(AF_INET, addr) + sockaddr = csocket.SockaddrIn((AF_INET, 0, addr)).Pack() + ifreq = Ifreq((LOOPBACK_DEV, sockaddr)).Pack() + else: + raise ValueError('Address family %r not supported.' % family) + datagram_socket = socket(family, SOCK_DGRAM) + try: + fcntl.ioctl(datagram_socket.fileno(), SIOCKILLADDR, ifreq) + finally: + datagram_socket.close() + +# For convenience. +def CreateIPv4SocketPair(): + return net_test.CreateSocketPair(AF_INET, SOCK_STREAM, IPV4_LOOPBACK_ADDR) + +def CreateIPv6SocketPair(): + return net_test.CreateSocketPair(AF_INET6, SOCK_STREAM, IPV6_LOOPBACK_ADDR) + + +@unittest.skipUnless(net_test.LINUX_VERSION >= (4, 4, 0), "grace period") +class TcpNukeAddrTest(net_test.NetworkTest): + + """Tests that SIOCKILLADDR no longer exists. + + The out-of-tree SIOCKILLADDR was replaced by the upstream SOCK_DESTROY + operation in Linux 4.5. It was backported to common Android trees all the way + back to android-3.10 and is required by CTS from Android N onwards. + This test ensures that it no longer works in 4.4 and above kernels. + + Relevant kernel commits: + android-4.4: + 3094efd84c Revert "net: socket ioctl to reset connections matching local address" + """ + + def CheckNukeAddrUnsupported(self, socketpair, addr): + s1, s2 = socketpair + self.assertRaisesErrno(errno.ENOTTY, KillAddrIoctl, addr) + data = "foo" + try: + self.assertEquals(len(data), s1.send(data)) + self.assertEquals(data, s2.recv(4096)) + self.assertSocketsNotClosed(socketpair) + finally: + s1.close() + s2.close() + + def assertSocketsNotClosed(self, socketpair): + for sock in socketpair: + self.assertTrue(sock.getpeername()) + + def testIpv4Unsupported(self): + self.CheckNukeAddrUnsupported(CreateIPv4SocketPair(), IPV4_LOOPBACK_ADDR) + self.CheckNukeAddrUnsupported(CreateIPv4SocketPair(), "0.0.0.0") + + def testIpv6Unsupported(self): + self.CheckNukeAddrUnsupported(CreateIPv6SocketPair(), IPV6_LOOPBACK_ADDR) + self.CheckNukeAddrUnsupported(CreateIPv4SocketPair(), "::") + + +if __name__ == "__main__": + unittest.main() |