Send connman mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        https://lists.01.org/mailman/listinfo/connman
or, via email, send a message with subject or body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of connman digest..."


Today's Topics:

   1. [PATCH 1/2] dns: support for systemd-resolved and backend
      selection. (Ismo Puustinen)
   2. [PATCH 2/2] doc: added documentation for running without DNS
      resolving. (Ismo Puustinen)


----------------------------------------------------------------------

Message: 1
Date: Tue,  3 Oct 2017 17:02:59 +0300
From: Ismo Puustinen <[email protected]>
To: [email protected]
Subject: [PATCH 1/2] dns: support for systemd-resolved and backend
        selection.
Message-ID: <[email protected]>

During configure, use --with-dns-backend to declare which DNS backend
you want to use during build. The two options available are "internal"
and "systemd-resolved".

The internal backend works as previously. The systemd-resolved backend
configures systemd-resolved over D-Bus.

The "-r" command line option for connmand still works. It means that the
DNS servers (either internal DNS proxy or systemd-resolved) aren't used,
and instead connmand just updates /etc/resolv.conf file.
---
 Makefile.am                |  15 +-
 configure.ac               |  14 ++
 src/dns-systemd-resolved.c | 378 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 405 insertions(+), 2 deletions(-)
 create mode 100644 src/dns-systemd-resolved.c

diff --git a/Makefile.am b/Makefile.am
index e67a7a55..97f1c87d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -120,11 +120,18 @@ src_connmand_SOURCES = $(gdhcp_sources) $(gweb_sources) 
$(backtrace_sources) \
                        src/storage.c src/dbus.c src/config.c \
                        src/technology.c src/counter.c src/ntp.c \
                        src/session.c src/tethering.c src/wpad.c src/wispr.c \
-                       src/stats.c src/dnsproxy.c src/6to4.c \
+                       src/stats.c src/6to4.c \
                        src/ippool.c src/bridge.c src/nat.c src/ipaddress.c \
                        src/inotify.c src/ipv6pd.c src/peer.c \
                        src/peer_service.c src/machine.c src/util.c
 
+if INTERNAL_DNS_BACKEND
+src_connmand_SOURCES += src/dnsproxy.c
+endif
+if SYSTEMD_RESOLVED_DNS_BACKEND
+src_connmand_SOURCES += src/dns-systemd-resolved.c
+endif
+
 src_connmand_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
                        @GLIB_LIBS@ @DBUS_LIBS@ @GNUTLS_LIBS@ \
                        -lresolv -ldl -lrt
@@ -178,7 +185,11 @@ vpn_connman_vpnd_LDFLAGS = -Wl,--export-dynamic \
 endif
 
 BUILT_SOURCES = $(local_headers) src/builtin.h $(service_files) \
-       scripts/connman scripts/connman_resolvconf.conf
+       scripts/connman
+
+if INTERNAL_DNS_BACKEND
+BUILT_SOURCES += scripts/connman_resolvconf.conf
+endif
 
 if VPN
 BUILT_SOURCES += vpn/builtin.h
diff --git a/configure.ac b/configure.ac
index 4baa6852..4feccc08 100644
--- a/configure.ac
+++ b/configure.ac
@@ -433,4 +433,18 @@ AM_CONDITIONAL(VPN, test "${enable_openconnect}" != "no" 
-o \
                        "${enable_l2tp}" != "no" -o \
                        "${enable_pptp}" != "no")
 
+AC_MSG_CHECKING(which DNS backend to use)
+AC_ARG_WITH(dns-backend, AC_HELP_STRING([--with-dns-backend=TYPE],
+            [specify which DNS backend to use: internal or systemd-resolved 
[default=internal]]),
+               [dns_backend=${withval}],
+               [dns_backend="internal"])
+
+if (test "${dns_backend}" != "internal" -a \
+               "${dns_backend}" != "systemd-resolved"); then
+       AC_MSG_ERROR(no suitable DNS backend defined)
+fi
+AM_CONDITIONAL(INTERNAL_DNS_BACKEND, test "${dns_backend}" = "internal")
+AM_CONDITIONAL(SYSTEMD_RESOLVED_DNS_BACKEND, test "${dns_backend}" = 
"systemd-resolved")
+AC_MSG_RESULT(${dns_backend})
+
 AC_OUTPUT(Makefile include/version.h connman.pc)
diff --git a/src/dns-systemd-resolved.c b/src/dns-systemd-resolved.c
new file mode 100644
index 00000000..3cb752e6
--- /dev/null
+++ b/src/dns-systemd-resolved.c
@@ -0,0 +1,378 @@
+/*
+ *
+ *  Connection Manager
+ *
+ *  Copyright (C) 2007-2017  Intel Corporation. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <gdbus.h>
+#include <glib.h>
+#include <connman/dbus.h>
+
+#include "connman.h"
+
+#define SYSTEMD_RESOLVED_SERVICE "org.freedesktop.resolve1"
+#define SYSTEMD_RESOLVED_PATH "/org/freedesktop/resolve1"
+
+static GTree *interface_map = NULL;
+static DBusConnection *connection = NULL;
+static GDBusClient *client = NULL;
+static GDBusProxy *resolved_proxy = NULL;
+
+struct dns_interface {
+       GList *domains;
+       GList *servers;
+       int index;
+};
+
+static gint int_cmp(gconstpointer a, gconstpointer b, void *data)
+{
+       gint ai = GPOINTER_TO_UINT(a);
+       gint bi = GPOINTER_TO_UINT(b);
+
+       return ai - bi;
+}
+
+static void free_dns_interface(gpointer data)
+{
+       struct dns_interface *iface = data;
+
+       DBG("%p", data);
+
+       if (!iface)
+               return;
+
+       g_list_free_full(iface->domains, free);
+       g_list_free_full(iface->servers, free);
+
+       free(iface);
+}
+
+static void setlinkdns_append(DBusMessageIter *iter, void *user_data)
+{
+       struct dns_interface *iface = user_data;
+       int result;
+       unsigned int i;
+       int type;
+       char ipv4_bytes[4];
+       char ipv6_bytes[16];
+       GList *list;
+       DBusMessageIter address_array, struct_array, byte_array;
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &iface->index);
+
+       dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "(iay)",
+                       &address_array);
+
+       for (list = iface->servers; list; list = g_list_next(list)) {
+               char *server = list->data;
+
+               DBG("index: %d, server: %s", iface->index, server);
+
+               dbus_message_iter_open_container(&address_array,
+                               DBUS_TYPE_STRUCT, NULL, &struct_array);
+
+               type = connman_inet_check_ipaddress(server);
+
+               if (type == AF_INET) {
+
+                       result = inet_pton(type, server, ipv4_bytes);
+
+                       if (!result) {
+                               DBG("Failed to parse IPv4 address: %s",
+                                               server);
+                               return;
+                       }
+
+                       dbus_message_iter_append_basic(&struct_array,
+                                       DBUS_TYPE_INT32, &type);
+
+                       dbus_message_iter_open_container(&struct_array,
+                                       DBUS_TYPE_ARRAY, "y", &byte_array);
+
+                       for (i = 0; i < sizeof(ipv4_bytes); i++) {
+                               dbus_message_iter_append_basic(&byte_array,
+                                               DBUS_TYPE_BYTE,
+                                               &(ipv4_bytes[i]));
+                       }
+
+                       dbus_message_iter_close_container(&struct_array,
+                                       &byte_array);
+               } else if (type == AF_INET6) {
+
+                       result = inet_pton(type, server, ipv6_bytes);
+
+                       if (!result) {
+                               DBG("Failed to parse IPv6 address: %s",
+                                               server);
+                               return;
+                       }
+
+                       dbus_message_iter_append_basic(&struct_array,
+                                       DBUS_TYPE_INT32, &type);
+
+                       dbus_message_iter_open_container(&struct_array,
+                                       DBUS_TYPE_ARRAY, "y", &byte_array);
+
+                       for (i = 0; i < sizeof(ipv6_bytes); i++) {
+                               dbus_message_iter_append_basic(&byte_array,
+                                               DBUS_TYPE_BYTE,
+                                               &(ipv6_bytes[i]));
+                       }
+
+                       dbus_message_iter_close_container(&struct_array,
+                                       &byte_array);
+               }
+
+               dbus_message_iter_close_container(&address_array,
+                               &struct_array);
+       }
+
+       dbus_message_iter_close_container(iter, &address_array);
+}
+
+static void setlinkdomains_append(DBusMessageIter *iter, void *user_data)
+{
+       struct dns_interface *iface = user_data;
+       GList *list;
+       DBusMessageIter domain_array, struct_array;
+       gboolean only_routing = FALSE;
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &iface->index);
+
+       dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "(sb)",
+                       &domain_array);
+
+       for (list = iface->domains; list; list = g_list_next(list)) {
+               char *domain = list->data;
+
+               DBG("index: %d, domain: %s", iface->index, domain);
+
+               dbus_message_iter_open_container(&domain_array,
+                               DBUS_TYPE_STRUCT, NULL, &struct_array);
+
+               dbus_message_iter_append_basic(&struct_array, DBUS_TYPE_STRING,
+                               &domain);
+
+               dbus_message_iter_append_basic(&struct_array, DBUS_TYPE_BOOLEAN,
+                               &only_routing);
+
+               dbus_message_iter_close_container(&domain_array, &struct_array);
+       }
+
+       dbus_message_iter_close_container(iter, &domain_array);
+}
+
+static int set_systemd_resolved_values(struct dns_interface *iface)
+{
+       if (!resolved_proxy || !iface)
+               return -ENOENT;
+
+       /* No async error processing -- just fire and forget */
+
+       if (!g_dbus_proxy_method_call(resolved_proxy, "SetLinkDNS",
+                       setlinkdns_append, NULL, iface, NULL))
+               return -EINVAL;
+
+       if (!g_dbus_proxy_method_call(resolved_proxy, "SetLinkDomains",
+                       setlinkdomains_append, NULL, iface, NULL))
+               return -EINVAL;
+
+       return 0;
+}
+
+static void remove_values(struct dns_interface *iface, const char *domain,
+                                                       const char *server)
+{
+       if (!iface)
+               return;
+
+       if (domain)
+               iface->domains = g_list_remove(iface->domains, domain);
+
+       if (server)
+               iface->servers = g_list_remove(iface->servers, server);
+}
+
+static bool is_empty(struct dns_interface *iface)
+{
+       if (!iface)
+               return FALSE;
+
+       return (!iface->domains && !iface->servers);
+}
+
+int __connman_dnsproxy_remove(int index, const char *domain,
+                                                       const char *server)
+{
+       struct dns_interface *iface;
+       int ret = 0;
+
+       DBG("");
+
+       if (!interface_map || index < 0)
+               return -EINVAL;
+
+       iface = g_tree_lookup(interface_map, GUINT_TO_POINTER(index));
+
+       if (!iface)
+               return -EINVAL;
+
+       remove_values(iface, domain, server);
+
+       ret = set_systemd_resolved_values(iface);
+
+       if (is_empty(iface))
+               g_tree_remove(interface_map, GUINT_TO_POINTER(index));
+
+       /* freed during g_tree_remove */
+       iface = NULL;
+
+       return ret;
+}
+
+static GList *replace_to_end(GList *str_list, const char *str)
+{
+       GList *list;
+
+       for (list = str_list; list; list = g_list_next(list)) {
+               char *orig = list->data;
+
+               if (strcmp(orig, str) == 0) {
+                       str_list = g_list_remove(str_list, orig);
+                       free(orig);
+                       break;
+               }
+       }
+
+       return g_list_append(str_list, strdup(str));
+}
+
+int __connman_dnsproxy_append(int index, const char *domain,
+                                                       const char *server)
+{
+       struct dns_interface *iface;
+
+       DBG("");
+
+       if (!interface_map || index < 0)
+               return -EINVAL;
+
+       iface = g_tree_lookup(interface_map, GUINT_TO_POINTER(index));
+
+       if (!iface) {
+               iface = g_new0(struct dns_interface, 1);
+               if (!iface)
+                       return -ENOMEM;
+               g_tree_insert(interface_map, GUINT_TO_POINTER(index), iface);
+       }
+
+       if (domain)
+               iface->domains = replace_to_end(iface->domains, domain);
+
+       if (server)
+               iface->servers = replace_to_end(iface->servers, server);
+
+       iface->index = index;
+
+       return set_systemd_resolved_values(iface);
+}
+
+int __connman_dnsproxy_add_listener(int index)
+{
+       DBG("");
+
+       return -ENXIO;
+}
+
+void __connman_dnsproxy_remove_listener(int index)
+{
+       DBG("");
+}
+
+static int setup_resolved(void)
+{
+       connection = connman_dbus_get_connection();
+
+       if (!connection)
+               return -ENXIO;
+
+       client = g_dbus_client_new(connection, SYSTEMD_RESOLVED_SERVICE,
+                       SYSTEMD_RESOLVED_PATH);
+
+       if (!client)
+               return -EINVAL;
+
+       resolved_proxy = g_dbus_proxy_new(client, SYSTEMD_RESOLVED_PATH,
+                       "org.freedesktop.resolve1.Manager");
+
+       if (!resolved_proxy)
+               return -EINVAL;
+
+       return 0;
+}
+
+int __connman_dnsproxy_init(void)
+{
+       int ret;
+
+       DBG("");
+
+       if ((ret = setup_resolved()) < 0)
+               return ret;
+
+       interface_map = g_tree_new_full(int_cmp, NULL, NULL,
+                       free_dns_interface);
+
+       if (!interface_map)
+               return -ENOMEM;
+
+       return 0;
+}
+
+void __connman_dnsproxy_cleanup(void)
+{
+       DBG("");
+
+       if (interface_map) {
+               g_tree_destroy(interface_map);
+               interface_map = NULL;
+       }
+
+       if (resolved_proxy) {
+               g_dbus_proxy_unref(resolved_proxy);
+               resolved_proxy = NULL;
+       }
+
+       if (client) {
+               g_dbus_client_unref(client);
+               client = NULL;
+       }
+
+       if (connection) {
+               dbus_connection_unref(connection);
+               connection = NULL;
+       }
+}
-- 
2.13.6



------------------------------

Message: 2
Date: Tue,  3 Oct 2017 17:03:00 +0300
From: Ismo Puustinen <[email protected]>
To: [email protected]
Subject: [PATCH 2/2] doc: added documentation for running without DNS
        resolving.
Message-ID: <[email protected]>

If '-r' option is used, do not use either dnsproxy or systemd-resolved
backend. Instead update /etc/resolv.conf and let applications do the
resolving.
---
 README           | 10 ++++++++++
 doc/connman.8.in | 16 +++++++++-------
 src/main.c       |  2 +-
 3 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/README b/README
index cbd86a5f..f9610e13 100644
--- a/README
+++ b/README
@@ -220,6 +220,16 @@ For a working system, certain configuration options need 
to be enabled:
                        # semodule -i connman-task.pp
                in order to enable the dbus access.
 
+    --with-dns-backend=TYPE
+
+               Enable support for a DNS resolving backend
+
+               Select a DNS backend to use. Supported values are "internal"
+               and "systemd-resolved". If "internal" is selected, ConnMan
+               will be build with a caching DNS proxy. If "systemd-resolved"
+               is selected, ConnMan configures systemd-resolved to do DNS
+               resolving. The default value is "internal".
+
 
 Activating debugging
 ====================
diff --git a/doc/connman.8.in b/doc/connman.8.in
index ddfba09b..85e7c5e0 100644
--- a/doc/connman.8.in
+++ b/doc/connman.8.in
@@ -88,13 +88,15 @@ Do not daemonize. This is useful for debugging, and directs 
log output to
 the controlling terminal in addition to syslog.
 .TP
 .BR \-r ", " \-\-nodnsproxy
-Do not act as a DNS proxy. By default ConnMan will direct all DNS traffic
-to itself by setting nameserver to 127.0.0.1 in \fBresolv.conf\fP(5) file.
-If this is not desired and you want that all programs call directly some
-DNS server, then you can use the \fB--nodnsproxy\fP option.
-If this option is used, then ConnMan is not able to cache the DNS queries
-because the DNS traffic is not going through ConnMan and that can cause
-some extra network traffic.
+Do not act as a DNS proxy or support external DNS resolving. Depending
+on how ConnMan is compiled, it will by default direct all DNS traffic
+to itself by setting nameserver to 127.0.0.1 in \fBresolv.conf\fP(5)
+file or leave DNS management to an external entity, such as
+systemd-resolved. If this is not desired and you want that all programs
+call directly some DNS server, then you can use the \fB--nodnsproxy\fP
+option. If this option is used, then ConnMan is not able to cache the
+DNS queries because the DNS traffic is not going through ConnMan and that
+can cause some extra network traffic.
 .SH SEE ALSO
 .BR connmanctl (1), \ connman.conf (5), \ connman-service.config (5), \c
 .BR \ connman-vpn (8)
diff --git a/src/main.c b/src/main.c
index b78a0461..7b00eb3e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -571,7 +571,7 @@ static GOptionEntry options[] = {
                                "Don't fork daemon to background" },
        { "nodnsproxy", 'r', G_OPTION_FLAG_REVERSE,
                                G_OPTION_ARG_NONE, &option_dnsproxy,
-                               "Don't enable DNS Proxy" },
+                               "Don't support DNS resolving" },
        { "nobacktrace", 0, G_OPTION_FLAG_REVERSE,
                                G_OPTION_ARG_NONE, &option_backtrace,
                                "Don't print out backtrace information" },
-- 
2.13.6



------------------------------

Subject: Digest Footer

_______________________________________________
connman mailing list
[email protected]
https://lists.01.org/mailman/listinfo/connman


------------------------------

End of connman Digest, Vol 24, Issue 6
**************************************

Reply via email to