diff --git a/hbd/server.py b/hbd/server.py index 3b28a93..9704b9e 100644 --- a/hbd/server.py +++ b/hbd/server.py @@ -1,7 +1,7 @@ """Server runtime: starts UDP listener, HTTP server and websocket stubs.""" import asyncio import logging -import atexit +import socket import time import signal import sys @@ -85,8 +85,20 @@ async def _run_async(config): email = notify_mod.email pushmsg = notify_mod.pushmsg_from_config + sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) + # Disable IPV6_V6ONLY option to enable dual-stack (listen on IPv4 as well) + # This option is system-dependent; on many systems, setting it to False enables + # the socket to handle both IPv4 and IPv6 traffic. + try: + sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False) + except OSError as e: + logger.error(f"Warning: Could not set IPV6_V6ONLY to False. System may not support dual-stack or option is unavailable. Error: {e}") + + # 3. Bind to all interfaces (::) on a specific port + # UDP server endpoint (handler wired to handle_datagram with context) - bind_addr = ("0.0.0.0", config.get("hb_port", 50003)) + bind_addr = ("::", config.get("hb_port", 50003)) + sock.bind(bind_addr) logger.info("Starting UDP server on %s:%s", *bind_addr) def udp_handler(msg, addr, transport): @@ -104,7 +116,7 @@ async def _run_async(config): transport, protocol = await loop.create_datagram_endpoint( lambda: udp.EchoServerProtocol(config=config, handler=udp_handler), - local_addr=bind_addr, + sock=sock, ) # HTTP server (asyncio-based via aiohttp)