From: Charles-François Natali Date: Mon, 2 Jan 2012 14:57:30 +0000 (+0100) Subject: Issue #9975: socket: Fix incorrect use of flowinfo and scope_id. Patch by X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=42663334cd9ef3348732e6a229478e67730b4ecb;p=python Issue #9975: socket: Fix incorrect use of flowinfo and scope_id. Patch by Vilmos Nebehaj. --- 42663334cd9ef3348732e6a229478e67730b4ecb diff --cc Lib/test/test_socket.py index a7cee59910,d77b7dc9ed..b5c16ca512 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@@ -1248,223 -846,14 +1248,230 @@@ class GeneralModuleTests(unittest.TestC srv.listen(0) srv.close() - @unittest.skipUnless(SUPPORTS_IPV6, 'IPv6 required for this test.') ++ @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.') + def test_flowinfo(self): + self.assertRaises(OverflowError, socket.getnameinfo, + ('::1',0, 0xffffffff), 0) + with socket.socket(socket.AF_INET6, socket.SOCK_STREAM) as s: + self.assertRaises(OverflowError, s.bind, ('::1', 0, -10)) + +@unittest.skipUnless(HAVE_SOCKET_CAN, 'SocketCan required for this test.') +class BasicCANTest(unittest.TestCase): + + def testCrucialConstants(self): + socket.AF_CAN + socket.PF_CAN + socket.CAN_RAW + + def testCreateSocket(self): + with socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW) as s: + pass + + def testBindAny(self): + with socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW) as s: + s.bind(('', )) + + def testTooLongInterfaceName(self): + # most systems limit IFNAMSIZ to 16, take 1024 to be sure + with socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW) as s: + self.assertRaisesRegex(socket.error, 'interface name too long', + s.bind, ('x' * 1024,)) + + @unittest.skipUnless(hasattr(socket, "CAN_RAW_LOOPBACK"), + 'socket.CAN_RAW_LOOPBACK required for this test.') + def testLoopback(self): + with socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW) as s: + for loopback in (0, 1): + s.setsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_LOOPBACK, + loopback) + self.assertEqual(loopback, + s.getsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_LOOPBACK)) + + @unittest.skipUnless(hasattr(socket, "CAN_RAW_FILTER"), + 'socket.CAN_RAW_FILTER required for this test.') + def testFilter(self): + can_id, can_mask = 0x200, 0x700 + can_filter = struct.pack("=II", can_id, can_mask) + with socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW) as s: + s.setsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_FILTER, can_filter) + self.assertEqual(can_filter, + s.getsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_FILTER, 8)) + + +@unittest.skipUnless(HAVE_SOCKET_CAN, 'SocketCan required for this test.') +@unittest.skipUnless(thread, 'Threading required for this test.') +class CANTest(ThreadedCANSocketTest): + + """The CAN frame structure is defined in : + + struct can_frame { + canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ + __u8 can_dlc; /* data length code: 0 .. 8 */ + __u8 data[8] __attribute__((aligned(8))); + }; + """ + can_frame_fmt = "=IB3x8s" + + def __init__(self, methodName='runTest'): + ThreadedCANSocketTest.__init__(self, methodName=methodName) + + @classmethod + def build_can_frame(cls, can_id, data): + """Build a CAN frame.""" + can_dlc = len(data) + data = data.ljust(8, b'\x00') + return struct.pack(cls.can_frame_fmt, can_id, can_dlc, data) + + @classmethod + def dissect_can_frame(cls, frame): + """Dissect a CAN frame.""" + can_id, can_dlc, data = struct.unpack(cls.can_frame_fmt, frame) + return (can_id, can_dlc, data[:can_dlc]) + + def testSendFrame(self): + cf, addr = self.s.recvfrom(self.bufsize) + self.assertEqual(self.cf, cf) + self.assertEqual(addr[0], self.interface) + self.assertEqual(addr[1], socket.AF_CAN) + + def _testSendFrame(self): + self.cf = self.build_can_frame(0x00, b'\x01\x02\x03\x04\x05') + self.cli.send(self.cf) + + def testSendMaxFrame(self): + cf, addr = self.s.recvfrom(self.bufsize) + self.assertEqual(self.cf, cf) + + def _testSendMaxFrame(self): + self.cf = self.build_can_frame(0x00, b'\x07' * 8) + self.cli.send(self.cf) + + def testSendMultiFrames(self): + cf, addr = self.s.recvfrom(self.bufsize) + self.assertEqual(self.cf1, cf) + + cf, addr = self.s.recvfrom(self.bufsize) + self.assertEqual(self.cf2, cf) + + def _testSendMultiFrames(self): + self.cf1 = self.build_can_frame(0x07, b'\x44\x33\x22\x11') + self.cli.send(self.cf1) + + self.cf2 = self.build_can_frame(0x12, b'\x99\x22\x33') + self.cli.send(self.cf2) + + +@unittest.skipUnless(HAVE_SOCKET_RDS, 'RDS sockets required for this test.') +class BasicRDSTest(unittest.TestCase): + + def testCrucialConstants(self): + socket.AF_RDS + socket.PF_RDS + + def testCreateSocket(self): + with socket.socket(socket.PF_RDS, socket.SOCK_SEQPACKET, 0) as s: + pass + + def testSocketBufferSize(self): + bufsize = 16384 + with socket.socket(socket.PF_RDS, socket.SOCK_SEQPACKET, 0) as s: + s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, bufsize) + s.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, bufsize) + + +@unittest.skipUnless(HAVE_SOCKET_RDS, 'RDS sockets required for this test.') +@unittest.skipUnless(thread, 'Threading required for this test.') +class RDSTest(ThreadedRDSSocketTest): + + def __init__(self, methodName='runTest'): + ThreadedRDSSocketTest.__init__(self, methodName=methodName) + + def setUp(self): + super().setUp() + self.evt = threading.Event() + + def testSendAndRecv(self): + data, addr = self.serv.recvfrom(self.bufsize) + self.assertEqual(self.data, data) + self.assertEqual(self.cli_addr, addr) + + def _testSendAndRecv(self): + self.data = b'spam' + self.cli.sendto(self.data, 0, (HOST, self.port)) + + def testPeek(self): + data, addr = self.serv.recvfrom(self.bufsize, socket.MSG_PEEK) + self.assertEqual(self.data, data) + data, addr = self.serv.recvfrom(self.bufsize) + self.assertEqual(self.data, data) + + def _testPeek(self): + self.data = b'spam' + self.cli.sendto(self.data, 0, (HOST, self.port)) + + @requireAttrs(socket.socket, 'recvmsg') + def testSendAndRecvMsg(self): + data, ancdata, msg_flags, addr = self.serv.recvmsg(self.bufsize) + self.assertEqual(self.data, data) + + @requireAttrs(socket.socket, 'sendmsg') + def _testSendAndRecvMsg(self): + self.data = b'hello ' * 10 + self.cli.sendmsg([self.data], (), 0, (HOST, self.port)) + + def testSendAndRecvMulti(self): + data, addr = self.serv.recvfrom(self.bufsize) + self.assertEqual(self.data1, data) + + data, addr = self.serv.recvfrom(self.bufsize) + self.assertEqual(self.data2, data) + + def _testSendAndRecvMulti(self): + self.data1 = b'bacon' + self.cli.sendto(self.data1, 0, (HOST, self.port)) + + self.data2 = b'egg' + self.cli.sendto(self.data2, 0, (HOST, self.port)) + + def testSelect(self): + r, w, x = select.select([self.serv], [], [], 3.0) + self.assertIn(self.serv, r) + data, addr = self.serv.recvfrom(self.bufsize) + self.assertEqual(self.data, data) + + def _testSelect(self): + self.data = b'select' + self.cli.sendto(self.data, 0, (HOST, self.port)) + + def testCongestion(self): + # wait until the sender is done + self.evt.wait() + + def _testCongestion(self): + # test the behavior in case of congestion + self.data = b'fill' + self.cli.setblocking(False) + try: + # try to lower the receiver's socket buffer size + self.cli.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 16384) + except OSError: + pass + with self.assertRaises(OSError) as cm: + try: + # fill the receiver's socket buffer + while True: + self.cli.sendto(self.data, 0, (HOST, self.port)) + finally: + # signal the receiver we're done + self.evt.set() + # sendto() should have failed with ENOBUFS + self.assertEqual(cm.exception.errno, errno.ENOBUFS) + # and we should have received a congestion notification through poll + r, w, x = select.select([self.serv], [], [], 3.0) + self.assertIn(self.serv, r) + + @unittest.skipUnless(thread, 'Threading required for this test.') class BasicTCPTest(SocketConnectedTest): diff --cc Misc/ACKS index 88b67e014e,6ad3f8cbb0..12f4b49d8a --- a/Misc/ACKS +++ b/Misc/ACKS @@@ -698,9 -643,10 +698,10 @@@ John Nagl Takahiro Nakayama Travers Naran Charles-François Natali + Vilmos Nebehaj Fredrik Nehr -Trent Nelson Tony Nelson +Trent Nelson Chad Netzer Max Neunhöffer George Neville-Neil diff --cc Misc/NEWS index ba151e646c,da9e9de1b6..827aa4e32a --- a/Misc/NEWS +++ b/Misc/NEWS @@@ -1744,50 -1234,6 +1744,53 @@@ Tools/Demo Extension Modules ----------------- ++- Issue #9975: socket: Fix incorrect use of flowinfo and scope_id. Patch by ++ Vilmos Nebehaj. ++ +- Issue #7777: socket: Add Reliable Datagram Sockets (PF_RDS) support. + +- Issue #13159: FileIO and BZ2Compressor/BZ2Decompressor now use a linear-time + buffer growth strategy instead of a quadratic-time one. + +- Issue #10141: socket: Add SocketCAN (PF_CAN) support. Initial patch by + Matthias Fuchs, updated by Tiago Gonçalves. + +- Issue #13070: Fix a crash when a TextIOWrapper caught in a reference cycle + would be finalized after the reference to its underlying BufferedRWPair's + writer got cleared by the GC. + +- Issue #12881: ctypes: Fix segfault with large structure field names. + +- Issue #13058: ossaudiodev: fix a file descriptor leak on error. Patch by + Thomas Jarosch. + +- Issue #13013: ctypes: Fix a reference leak in PyCArrayType_from_ctype. + Thanks to Suman Saha for finding the bug and providing a patch. + +- Issue #13022: Fix: _multiprocessing.recvfd() doesn't check that + file descriptor was actually received. + +- Issue #1172711: Add 'long long' support to the array module. + Initial patch by Oren Tirosh and Hirokazu Yamamoto. + +- Issue #12483: ctypes: Fix a crash when the destruction of a callback + object triggers the garbage collector. + +- Issue #12950: Fix passing file descriptors in multiprocessing, under + OpenIndiana/Illumos. + +- Issue #12764: Fix a crash in ctypes when the name of a Structure field is not + a string. + +- Issue #11241: subclasses of ctypes.Array can now be subclassed. + +- Issue #9651: Fix a crash when ctypes.create_string_buffer(0) was passed to + some functions like file.write(). + +- Issue #10309: Define _GNU_SOURCE so that mremap() gets the proper + signature. Without this, architectures where sizeof void* != sizeof int are + broken. Patch given by Hallvard B Furuseth. + - Issue #12051: Fix segfault in json.dumps() while encoding highly-nested objects using the C accelerations.