control: tags -1 patch

I have a fix for this issue that allows calypso to listen on addresses
from addressing families other than AF_INET. This means that by default,
not specifying anything, the server will typically listen on :: and
service IPv4 addresses too.

I could not clone the specified upstream repo but did add a merge
request to the maintainer repo so please use that or the following patch
at your convenience!

Thank you,

Andrew


From 8c161af0febb99bfb956ff5793ac378581230129 Mon Sep 17 00:00:00 2001
From: Andrew Bower <and...@bower.uk>
Date: Tue, 22 Oct 2024 23:15:43 +0100
Subject: [PATCH] Listen on appropriate addressing family

Rather than only listening on AF_INET, regardless of the addressing
family needed to support the supplied hostname, listen on the addressing
family of the first result from getaddrinfo() after re-ordering to make
sure AF_INET6 addresses come first.

This enables dual-stack listening by default with no hostname specified.
---
 calypso/__init__.py | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/calypso/__init__.py b/calypso/__init__.py
index 7c9a81b..d3285c9 100644
--- a/calypso/__init__.py
+++ b/calypso/__init__.py
@@ -99,6 +99,22 @@ def _check(request, function):
     # pylint: enable=W0212
 
 
+def resolve_server_address(address):
+    """Get server address details from string."""
+    (host, port) = address
+    addrs = socket.getaddrinfo(None if host == '' else host, port,
+                               type=socket.SOCK_STREAM,
+                               flags=socket.AI_PASSIVE)
+
+    # Put IPv6 addresses first, resulting in dual stack listener by default,
+    # otherwise preserving ordering.
+    inorder      = [a for a in addrs if a[0] == socket.AF_INET6]
+    inorder.extend([a for a in addrs if a[0] != socket.AF_INET6])
+
+    # Ideally we would listen on each returned address separately.
+    return inorder[0] if inorder else None
+
+
 class HTTPServer(server.HTTPServer):
     """HTTP server."""
     PROTOCOL = "http"
@@ -107,6 +123,9 @@ class HTTPServer(server.HTTPServer):
     # pylint: disable=W0231
     def __init__(self, address, handler):
         """Create server."""
+        addrinfo = resolve_server_address(address)
+        self.address_family = addrinfo[0]
+        self.socket_type = addrinfo[1]
         http_server.__init__(self, address, handler)
         self.acl = acl.load()
     # pylint: enable=W0231
-- 
2.45.2

Attachment: signature.asc
Description: PGP signature

Reply via email to