From ba10770d1a739ac132369198521bfcff89e959e1 Mon Sep 17 00:00:00 2001 From: Federico Ceratto Date: Wed, 27 Apr 2016 17:04:27 +0100 Subject: [PATCH] Support binding to IPv6 addresses in UDP sockets Change-Id: I9b785e101570231bbc65896b30c3c67d51c03135 --- designate/tests/test_utils.py | 6 ++++++ designate/utils.py | 15 ++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/designate/tests/test_utils.py b/designate/tests/test_utils.py index 800dc1195..d99e97b6c 100644 --- a/designate/tests/test_utils.py +++ b/designate/tests/test_utils.py @@ -140,3 +140,9 @@ class SocketListenTest(unittest.TestCase): for addr in ('', '0.0.0.0', '127.0.0.1', '::', '::1'): s = utils.bind_tcp(addr, 0, 1) s.close() + + def test_listen_udp(self): + # Test listening on UDP on IPv4 and IPv6 addrs + for addr in ('', '0.0.0.0', '127.0.0.1', '::', '::1'): + s = utils.bind_udp(addr, 0) + s.close() diff --git a/designate/utils.py b/designate/utils.py index 3d2d53da9..932ac7d12 100644 --- a/designate/utils.py +++ b/designate/utils.py @@ -506,17 +506,26 @@ def bind_tcp(host, port, tcp_backlog, tcp_keepidle=None): def bind_udp(host, port): - # Bind to the UDP port + """Bind to an UDP port and listen. + Use reuseaddr, reuseport if available + + :param host: IPv4/v6 address or "". "" binds to every IPv4 interface. + :type host: str + :param port: UDP port + :type port: int + :returns: socket + """ LOG.info(_LI('Opening UDP Listening Socket on %(host)s:%(port)d'), {'host': host, 'port': port}) - sock_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + family = socket.AF_INET6 if is_valid_ipv6(host) else socket.AF_INET + sock_udp = socket.socket(family, socket.SOCK_DGRAM) sock_udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # NOTE: Linux supports socket.SO_REUSEPORT only in 3.9 and later releases. try: sock_udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) except Exception: - pass + LOG.info(_LI('SO_REUSEPORT not available, ignoring.')) sock_udp.setblocking(True) sock_udp.bind((host, port))