From 7782be8580d98c463a69f4fb86ece43e45e0ba88 Mon Sep 17 00:00:00 2001
From: Sistason <c3infra@sistason.de>
Date: Wed, 29 Nov 2023 21:02:20 +0100
Subject: [PATCH] Add support for AF_INET(6) sockets via
 --socket-address=IP:PORT

Signed-off-by: Sistason <c3infra@sistason.de>
---
 uffd-socketmapd | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/uffd-socketmapd b/uffd-socketmapd
index 63672a8..5ff20aa 100755
--- a/uffd-socketmapd
+++ b/uffd-socketmapd
@@ -235,15 +235,16 @@ class StdoutFilter(logging.Filter):
 		return record.levelno <= logging.INFO
 
 @click.command(help='Socketmap proxy for integrating Postfix and other compatible MTAs with uffd SSO. Supports virtual alias lookups (request name "virtual").')
-@click.option('--socket-path', type=click.Path(), help='Path for UNIX domain socket')
-@click.option('--socket-fd', type=int, help='Use fd number as server socket (alternative to --socket-path)')
+@click.option('--socket-path', type=click.Path(), help='Path for UNIX domain socket (alternative to --socket-fd/--socket-address)')
+@click.option('--socket-fd', type=int, help='Use fd number as server socket')
+@click.option('--socket-address', type=str, help='Use IP:PORT as server socket TCP address (alternative to --socket-path/--socket-fd)')
 @click.option('--api-url', required=True, help='Uffd base URL without API prefix or trailing slash (e.g. https://example.com)')
 @click.option('--api-user', required=True, help='API user/client id')
 @click.option('--api-secret', required=True, help='API secret, do not set this on the command-line, use environment variable SERVER_API_SECRET instead')
-def main(socket_path, socket_fd, api_url, api_user, api_secret):
-	if (socket_path is None and socket_fd is None) or \
-	   (socket_path is not None and socket_fd is not None):
-		raise click.ClickException('Either --socket-path or --socket-fd must be specified')
+def main(socket_path, socket_fd, socket_address, api_url, api_user, api_secret):
+	if (len([arg for arg in [socket_path, socket_fd, socket_address] if arg is None]) == 3 or
+			len([arg for arg in [socket_path, socket_fd, socket_address] if arg is not None]) != 1):
+		raise click.ClickException('Either --socket-path, --socket-fd or --socket-address must be specified')
 
 	stdout_handler = logging.StreamHandler(sys.stdout)
 	stdout_handler.setLevel(logging.DEBUG)
@@ -259,6 +260,14 @@ def main(socket_path, socket_fd, api_url, api_user, api_secret):
 	if socket_path is not None:
 		cleanup_unix_socket(socket_path)
 		socketserver.ThreadingUnixStreamServer(socket_path, RequestHandler).serve_forever()
+	elif socket_address is not None:
+		address, port = socket_address.rsplit(':', 1)
+		if ':' in address:
+			class ThreadingTCP6Server(socketserver.ThreadingTCPServer):
+				address_family = socket.AF_INET6
+			ThreadingTCP6Server((address, int(port)), RequestHandler).serve_forever()
+		else:
+			socketserver.ThreadingTCPServer((address, int(port)), RequestHandler).serve_forever()
 	else:
 		ThreadingFilenoUnixStreamServer(socket_fd, RequestHandler).serve_forever()
 
-- 
GitLab