Peter Bieringer пре 1 година
родитељ
комит
0e1d502d0a
1 измењених фајлова са 14 додато и 36 уклоњено
  1. 14 36
      radicale/server.py

+ 14 - 36
radicale/server.py

@@ -3,6 +3,7 @@
 # Copyright © 2008 Pascal Halter
 # Copyright © 2008-2017 Guillaume Ayoub
 # Copyright © 2017-2019 Unrud <unrud@outlook.com>
+# Copyright © 2024-2024 Peter Bieringer <pb@bieringer.de>
 #
 # This library is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -283,45 +284,22 @@ def serve(configuration: config.Configuration,
     servers = {}
     try:
         hosts: List[Tuple[str, int]] = configuration.get("server", "hosts")
-        for address in hosts:
-            # Try to bind sockets for IPv4 and IPv6
-            possible_families = (socket.AF_INET, socket.AF_INET6)
-            bind_ok = False
-            for i, family in enumerate(possible_families):
-                is_last = i == len(possible_families) - 1
+        for AddressPort in hosts:
+            # retrieve IPv4/IPv6 address of address
+            try:
+                getaddrinfo = socket.getaddrinfo(AddressPort[0], AddressPort[1], 0, socket.SOCK_STREAM, socket.IPPROTO_TCP);
+            except OSError as e:
+                logger.warn("cannot retrieve IPv4 or IPv6 address of: %s" % (format_address(AddressPort)))
+                continue
+            logger.debug("getaddrinfo of '%s': %s" % (format_address(AddressPort), getaddrinfo))
+            for (AddressFamily, SocketKind, SocketProto, SocketFlags, SocketAddress) in getaddrinfo:
+                logger.debug("try to create server socket on '%s'" % (format_address(SocketAddress)))
                 try:
-                    server = server_class(configuration, family, address,
-                                          RequestHandler)
+                    server = server_class(configuration, AddressFamily, (SocketAddress[0], SocketAddress[1]), RequestHandler)
                 except OSError as e:
-                    # Ignore unsupported families (only one must work)
-                    if ((bind_ok or not is_last) and (
-                            isinstance(e, socket.gaierror) and (
-                                # Hostname does not exist or doesn't have
-                                # address for address family
-                                # Linux: temporary failure in name resolution (-3)
-                                e.errno == socket.EAI_AGAIN or
-                                # macOS: IPv6 address for INET address family
-                                e.errno == socket.EAI_NONAME or
-                                # Address not for address family
-                                e.errno == COMPAT_EAI_ADDRFAMILY or
-                                e.errno == COMPAT_EAI_NODATA) or
-                            # Workaround for PyPy
-                            str(e) == "address family mismatched" or
-                            # Address family not available (e.g. IPv6 disabled)
-                            # macOS: IPv4 address for INET6 address family with
-                            #        IPV6_V6ONLY set
-                            e.errno == errno.EADDRNOTAVAIL or
-                            # Device or resource busy (16)
-                            e.errno == errno.EBUSY or
-                            # Address family not supported
-                            e.errno == errno.EAFNOSUPPORT or
-                            # Protocol not supported
-                            e.errno == errno.EPROTONOSUPPORT)):
-                        continue
-                    raise RuntimeError("Failed to start server %r: %s" % (
-                                           format_address(address), e)) from e
+                    logger.warn("cannot create server socket on '%s': %s" % (format_address(SocketAddress), e))
+                    continue
                 servers[server.socket] = server
-                bind_ok = True
                 server.set_app(application)
                 logger.info("Listening on %r%s",
                             format_address(server.server_address),