From ecf0111898b519a9a21fd62ae14ed54ec64992eb Mon Sep 17 00:00:00 2001
From: Zsombor Welker <fedora@zdeqb.com>
Date: Fri, 9 Dec 2022 22:47:42 +0100
Subject: [PATCH] Parse ipv6 docker gateway entries correctly

---
 README.md                            | 12 +++++----
 src/systemd_resolved_docker/cli.py   |  5 ++--
 src/systemd_resolved_docker/utils.py |  9 ++++++-
 systemd-resolved-docker.sysconfig    | 40 ++++++++++++++--------------
 4 files changed, 37 insertions(+), 29 deletions(-)

diff --git a/README.md b/README.md
index 9cd5e99..78c9214 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ an exact match is required. If a generated domain address doesn't match the list
 
 1. `<container_id>.<default_domain>`
 
-   All containers will be reachable by their `container_id`:
+   All containers may be reachable by their `container_id`:
    ```sh
    docker run --rm -it alpine                                        #  d6d51528ac46.docker
    docker ps
@@ -125,15 +125,17 @@ If there are link-local, VPN or other DNS servers configured then those will als
 `systemd-resolved-docker` may be configured using environment variables. When installed using the RPM
 `/etc/sysconfig/systemd-resolved-docker` may also be modified to update the environment variables.
 
+*Note*: IPv6 addresses should be provided in square brackets (`[2001:db8:1::1]` or `[2001:db8:1::1]:1053`).
+
 | Name                              | Description                                                                                                             | Default Value                                            | Example                           |
 |-----------------------------------|-------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------|-----------------------------------|
-| DNS_SERVER                        | DNS server to use when resolving queries from docker containers.                                                        | `127.0.0.53` - systemd-resolved DNS server               | `127.0.0.53`                      |
-| SYSTEMD_RESOLVED_INTERFACE        | Dummy interface name which will be created to interface with systemd-resolved                                           | `srd-dummy`                                              | `srd-dummy`                       |
-| SYSTEMD_RESOLVED_LISTEN_ADDRESS   | IPs (+port) to listen on for queries from systemd-resolved.                                                             | `127.0.0.153`                                            | `127.0.0.153:1053`                |
-| DOCKER_LISTEN_ADDRESS             | IPs (+port) to listen on for queries from docker containers in the default network.                                     | _ip of the default docker bridge_, often `172.17.0.1`    | `172.17.0.1` or `172.17.0.1:53`   |
 | ALLOWED_DOMAINS                   | Domain which will be handled by the DNS server. If a domain starts with `.` then all subdomains will also be allowed.   | `.docker`                                                | `.docker,.local`                  |
 | DEFAULT_DOMAIN                    | Domain to append to hostnames which are not allowed by `ALLOWED_DOMAINS`.                                               | `docker`                                                 | `docker`                          |
 | DEFAULT_HOST_IP                   | IP address to use for containers on the host network if the container doesn't contain one.                              | `127.0.0.1`                                              | `127.0.0.1`                       |
+| DOCKER_LISTEN_ADDRESS             | IPs (+port) to listen on for queries from docker containers in the default network.                                     | _ip of the default docker bridge_, often `172.17.0.1`    | `172.17.0.1` or `172.17.0.1:53`   |
+| UPSTREAM_DNS_SERVER               | DNS server to use when resolving queries from docker containers.                                                        | `127.0.0.53` - systemd-resolved DNS server               | `127.0.0.53`                      |
+| SYSTEMD_RESOLVED_INTERFACE        | Dummy interface name which will be created to interface with systemd-resolved                                           | `srd-dummy`                                              | `srd-dummy`                       |
+| SYSTEMD_RESOLVED_LISTEN_ADDRESS   | IPs (+port) to listen on for queries from systemd-resolved.                                                             | `127.0.0.153`                                            | `127.0.0.153:1053`                |
 | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | --------------------------------- |
 
 ## Install
diff --git a/src/systemd_resolved_docker/cli.py b/src/systemd_resolved_docker/cli.py
index 6d289ec..c46618e 100644
--- a/src/systemd_resolved_docker/cli.py
+++ b/src/systemd_resolved_docker/cli.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python3
-
 import os
 import signal
 
@@ -9,7 +8,7 @@ from systemd import daemon
 from .dockerdnsconnector import DockerDNSConnector
 from .resolvedconnector import SystemdResolvedConnector
 from .utils import find_default_docker_bridge_gateway, parse_ip_port, parse_listen_address, remove_dummy_interface, \
-    create_dummy_interface, sanify_domain
+    create_dummy_interface, sanify_domain, parse_ip
 
 
 class Handler:
@@ -58,7 +57,7 @@ def main():
     systemd_resolved_listen_addresses = parse_listen_address(systemd_resolved_listen_address,
                                                              lambda: [parse_ip_port("127.0.0.153:53")])
     docker_listen_addresses = parse_listen_address(docker_listen_address,
-                                                   lambda: [parse_ip_port(entry['gateway']) for entry in
+                                                   lambda: [parse_ip(entry['gateway']) for entry in
                                                             docker_gateway])
 
     handler.log("Creating interface %s" % systemd_resolved_interface)
diff --git a/src/systemd_resolved_docker/utils.py b/src/systemd_resolved_docker/utils.py
index 8ecc780..e9ed3f6 100644
--- a/src/systemd_resolved_docker/utils.py
+++ b/src/systemd_resolved_docker/utils.py
@@ -13,7 +13,14 @@ class IpAndPort:
         self.port = port
 
     def __str__(self):
-        return "%s:%s" % (self.ip.compressed, self.port)
+        if isinstance(self.ip, ipaddress.IPv4Address):
+            return "%s:%s" % (self.ip.compressed, self.port)
+        else:
+            return "[%s]:%s" % (self.ip.compressed, self.port)
+
+
+def parse_ip(entry, default_port=53) -> IpAndPort:
+    return IpAndPort(ip=ipaddress.ip_address(entry), port=default_port)
 
 
 def parse_ip_port(entry, default_port=53) -> IpAndPort:
diff --git a/systemd-resolved-docker.sysconfig b/systemd-resolved-docker.sysconfig
index fde5312..e9b1ad2 100644
--- a/systemd-resolved-docker.sysconfig
+++ b/systemd-resolved-docker.sysconfig
@@ -1,6 +1,25 @@
+## Domain globs of domains which will be handled by the DNS server.
+## A container must be within one of these domains, while all non-matching requests
+## will be forwarded to the configured DNS server.
+## default: .docker
+# ALLOWED_DOMAINS=.docker
+
+## Domain to append to containers which don't have one set using `--domainname`
+## or are not part of a network
+## default: .docker
+# DEFAULT_DOMAIN=docker
+
+## IPs (+port) to listen on for queries from docker containers in the default network.
+## default: ip of the default docker bridge
+# DOCKER_LISTEN_ADDRESS=172.17.0.1:53
+
+## IP address to use with host networks when an IP is not specified
+## default: 127.0.0.1
+# DEFAULT_HOST_ip=127.0.0.1
+
 ## DNS server to use when resolving queries from docker containers.
 ## default: 127.0.0.53
-# DNS_SERVER=127.0.0.53
+# UPSTREAM_DNS_SERVER=127.0.0.53
 
 ## Dummy interface name which will be created to interface with systemd-resolved.
 ## default: srd-dummy
@@ -9,22 +28,3 @@
 ## IPs (+port) to listen on for queries from systemd-resolved.
 ## default: 127.0.0.153
 # SYSTEMD_RESOLVED_LISTEN_ADDRESS=127.0.0.153:53
-
-## IPs (+port) to listen on for queries from docker containers in the default network.
-## default: ip of the default docker bridge
-# DOCKER_LISTEN_ADDRESS=172.17.0.1:53
-
-## Domain to append to containers which don't have one set using `--domainname`
-## or are not part of a network
-## default: .docker
-# DEFAULT_DOMAIN=docker
-
-## Domain globs of domains which will be handled by the DNS server.
-## A container must be within one of these domains, while all non-matching requests
-## will be forwarded to the configured DNS server.
-## default: .docker
-# ALLOWED_DOMAINS=.docker
-
-## IP address to use with host networks when an IP is not specified
-## default: 127.0.0.1
-# DEFAULT_HOST_ip=127.0.0.1
\ No newline at end of file
-- 
GitLab