From 322cced778195df26a038aa6388080fbaeeff345 Mon Sep 17 00:00:00 2001 From: Marcin Gozdalik Date: Fri, 12 Nov 2021 14:37:26 +0100 Subject: [PATCH] Allow to bind to IPv6 address specified by name, not address --- gunicorn/sock.py | 52 ++++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/gunicorn/sock.py b/gunicorn/sock.py index d45867709a..890e5ede70 100644 --- a/gunicorn/sock.py +++ b/gunicorn/sock.py @@ -176,30 +176,44 @@ def create_sockets(conf, log, fds=None): return listeners # no sockets is bound, first initialization of gunicorn in this env. + some_sock_succeeded = False for addr in laddr: - sock_type = _sock_type(addr) sock = None - for i in range(5): - try: - sock = sock_type(addr, conf, log) - except socket.error as e: - if e.args[0] == errno.EADDRINUSE: - log.error("Connection in use: %s", str(addr)) - if e.args[0] == errno.EADDRNOTAVAIL: - log.error("Invalid address: %s", str(addr)) - if i < 5: - msg = "connection to {addr} failed: {error}" - log.debug(msg.format(addr=str(addr), error=str(e))) - log.error("Retrying in 1 second.") - time.sleep(1) + try: + addrinfos = socket.getaddrinfo(addr[0], addr[1], type=socket.SOCK_STREAM) + except socket.error as e: + log.error("Failed getaddrinfo for %s: %s", str(addr), str(e)) + continue + for sock_family, _, _, _, sock_addr in addrinfos: + if sock_family == socket.AF_INET: + sock_class = TCPSocket + elif sock_family == socket.AF_INET6: + sock_class = TCP6Socket else: - break + log.warning("Ignoring unknown socket family: %s", str(sock_family)) + continue + for i in range(5): + try: + sock = sock_class(sock_addr, conf, log) + except socket.error as e: + if e.args[0] == errno.EADDRINUSE: + log.error("Connection in use: %s", str(sock_addr)) + if e.args[0] == errno.EADDRNOTAVAIL: + log.error("Invalid address: %s", str(sock_addr)) + if i < 5: + msg = "connection to {addr} failed: {error}" + log.debug(msg.format(addr=str(sock_addr), error=str(e))) + log.error("Retrying in 1 second.") + time.sleep(1) + else: + break - if sock is None: - log.error("Can't connect to %s", str(addr)) - sys.exit(1) + listeners.append(sock) + some_sock_succeeded = True - listeners.append(sock) + if not some_sock_succeeded: + log.error("Can't connect to %s", str(addr)) + sys.exit(1) return listeners