[PATCH v2 5/5] systemd-resolved: Proxy tethering client DNS requests to resolved

Jussi Laakkonen <[email protected]> Sat, 9 May 2026 16:47:38 +0300
Newsgroups dev.linux.lists.connman
Message-ID <[email protected]>
Proxy the DNS requests from tethering clients to resolved using the
dns.c functionality. Add an UDP listener for the tethering interface to
serve the requests from that interface and use the shared/dns.c with the
default systemd-resolved server 127.0.0.53 by binding the socket to
localhost interface. This ensures that the limitations set in the
systemd-resolved (by allowing only localhost to connect to the server)
can be circumvented by making the packets to originate from localhost
and not getting dropped as martians or by the server itself.
---
Changes since v2:
 - Use the build-time DNS_BACKEND_V4 as systemd-resolved server address
 
 src/dns-systemd-resolved.c | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/src/dns-systemd-resolved.c b/src/dns-systemd-resolved.c
index 9dd0328c..6d46de49 100644
--- a/src/dns-systemd-resolved.c
+++ b/src/dns-systemd-resolved.c
@@ -31,6 +31,7 @@
 #include <glib.h>
 #include <connman/dbus.h>
 
+#include "shared/dns.h"
 #include "connman.h"
 
 #define SYSTEMD_RESOLVED_SERVICE "org.freedesktop.resolve1"
@@ -375,14 +376,32 @@ int __connman_dnsproxy_append(int index, const char *domain,
 
 int __connman_dnsproxy_add_listener(int index)
 {
-	DBG("");
+	int lo_index;
+	int err;
+
+	DBG("index %d", index);
+
+	err = dns_add_listener(index, DNS_IPPROTO_UDP, true);
+	if (err)
+		return err;
+
+	lo_index = connman_inet_ifindex("lo");
+	err = dns_create_server(lo_index, "local", DNS_BACKEND_V4, IPPROTO_UDP);
+	if (err)
+		return err;
+
+	err = dns_enable_server(lo_index, DNS_BACKEND_V4, IPPROTO_UDP, true);
+	if (err)
+		return err;
 
-	return -ENXIO;
+	return 0;
 }
 
 void __connman_dnsproxy_remove_listener(int index)
 {
 	DBG("");
+
+	dns_remove_listener(index);
 }
 
 static int setup_resolved(void)
@@ -779,6 +798,10 @@ int __connman_dnsproxy_init(void)
 	if (!interface_hash)
 		return -ENOMEM;
 
+	ret = dns_init(NULL);
+	if (ret)
+		return ret;
+
 	ret = connman_notifier_register(&resolved_notifier);
 	if (ret < 0)
 		DBG("cannot register notifier");
@@ -821,4 +844,6 @@ void __connman_dnsproxy_cleanup(void)
 		dbus_connection_unref(connection);
 		connection = NULL;
 	}
+
+	dns_cleanup();
 }
-- 
2.47.3