[systemd-devel] [PATCH] resolved: re-add support for getting local domain from DHCP

Michael Marineau michael.marineau at coreos.com
Mon Aug 4 10:05:46 PDT 2014


When the code for generating resolv.conf was moved from networkd to
resolved the DHCP domain name code was dropped.
---

This is a refresh of the patch on recent master with a little bit of
cleanup from the last. Regarding the robustness/correctness/etc of
setting the "domain" resolv.conf attribute from DNS, I don't think that
is practical to address in this patch. The implementation is already
clearly incomplete because networkd doesn't handle "search" domains
which is actually an entirely different option. My goal here is to just
fix the regression from when resolved was first introduced.

The most common setup is for "domain" to correspond to the domain suffix
for the local host name. If you are concerned about which interface's
domain attribute wins and lands in resolv.conf, there is a related issue
of which interface's host name winds up being applied as the host's
transient host name. What ever interface wins the two should probably
match but this is complicated significantly by the two being handled by
different daemons, resolved vs hostnamed, with two different
integration points with networkd, reading state files in /run vs dbus
method calls. I don't have a good recommendation to make sense of any of
this right now.

 src/network/networkd-link.c    |  9 +++++++++
 src/network/sd-network.c       | 24 ++++++++++++++++++++++++
 src/resolve/resolved-link.c    | 20 ++++++++++++++++++++
 src/resolve/resolved-link.h    |  2 ++
 src/resolve/resolved-manager.c | 10 +++++++++-
 src/systemd/sd-network.h       |  3 +++
 6 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 172be64..42d528f 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -2385,6 +2385,15 @@ int link_save(Link *link) {
                                 (address + 1 ? " " : ""));
 
                 fputs("\n", f);
+
+                if (link->network->dhcp_domainname &&
+                    link->dhcp_lease) {
+                        const char *domainname;
+
+                        r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
+                        if (r >= 0)
+                                fprintf(f, "DOMAINNAME=%s\n", domainname);
+                }
         }
 
         if (link->dhcp_lease) {
diff --git a/src/network/sd-network.c b/src/network/sd-network.c
index bfb8321..a427a27 100644
--- a/src/network/sd-network.c
+++ b/src/network/sd-network.c
@@ -175,6 +175,30 @@ _public_ int sd_network_get_ntp(int ifindex, char ***ret) {
         return network_get_strv("NTP", ifindex, ret);
 }
 
+_public_ int sd_network_get_domainname(int ifindex, char **domainname) {
+        _cleanup_free_ char *s = NULL, *p = NULL;
+        int r;
+
+        assert_return(ifindex > 0, -EINVAL);
+        assert_return(domainname, -EINVAL);
+
+        if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
+                return -ENOMEM;
+
+        r = parse_env_file(p, NEWLINE, "DOMAINNAME", &s, NULL);
+        if (r == -ENOENT)
+                return -ENODATA;
+        else if (r < 0)
+                return r;
+        else if (!s)
+                return -EIO;
+
+        *domainname = s;
+        s = NULL;
+
+        return 0;
+}
+
 static inline int MONITOR_TO_FD(sd_network_monitor *m) {
         return (int) (unsigned long) m - 1;
 }
diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c
index 2c02f09..9d582e4 100644
--- a/src/resolve/resolved-link.c
+++ b/src/resolve/resolved-link.c
@@ -74,6 +74,7 @@ Link *link_free(Link *l) {
         while (l->dns_servers)
                 dns_server_free(l->dns_servers);
 
+        free(l->domainname);
         free(l);
         return NULL;
 }
@@ -188,10 +189,29 @@ clear:
         return r;
 }
 
+static int link_update_domainname(Link *l) {
+        char *domainname = NULL;
+        int r;
+
+        assert(l);
+
+        free(l->domainname);
+        l->domainname = NULL;
+
+        r = sd_network_get_domainname(l->ifindex, &domainname);
+        if (r < 0)
+                return r;
+
+        l->domainname = domainname;
+
+        return 0;
+}
+
 int link_update_monitor(Link *l) {
         assert(l);
 
         link_update_dns_servers(l);
+        link_update_domainname(l);
         link_allocate_scopes(l);
         link_add_rrs(l, false);
 
diff --git a/src/resolve/resolved-link.h b/src/resolve/resolved-link.h
index 38bb392..eed9f42 100644
--- a/src/resolve/resolved-link.h
+++ b/src/resolve/resolved-link.h
@@ -68,6 +68,8 @@ struct Link {
 
         RateLimit mdns_ratelimit;
         RateLimit llmnr_ratelimit;
+
+        char *domainname;
 };
 
 int link_new(Manager *m, Link **ret, int ifindex);
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
index 1b6dc8a..8f28eaf 100644
--- a/src/resolve/resolved-manager.c
+++ b/src/resolve/resolved-manager.c
@@ -648,6 +648,7 @@ int manager_write_resolv_conf(Manager *m) {
         static const char path[] = "/run/systemd/resolve/resolv.conf";
         _cleanup_free_ char *temp_path = NULL;
         _cleanup_fclose_ FILE *f = NULL;
+        const char *domainname = NULL;
         unsigned count = 0;
         DnsServer *s;
         Iterator i;
@@ -674,15 +675,22 @@ int manager_write_resolv_conf(Manager *m) {
         LIST_FOREACH(servers, s, m->dns_servers)
                 write_resolve_conf_server(s, f, &count);
 
-        HASHMAP_FOREACH(l, m->links, i)
+        HASHMAP_FOREACH(l, m->links, i) {
                 LIST_FOREACH(servers, s, l->dns_servers)
                         write_resolve_conf_server(s, f, &count);
 
+                if (!domainname && l->domainname)
+                        domainname = l->domainname;
+        }
+
         if (count == 0) {
                 LIST_FOREACH(servers, s, m->fallback_dns_servers)
                         write_resolve_conf_server(s, f, &count);
         }
 
+        if (domainname)
+                fprintf(f, "domain %s\n", domainname);
+
         r = fflush_and_check(f);
         if (r < 0)
                 goto fail;
diff --git a/src/systemd/sd-network.h b/src/systemd/sd-network.h
index ec01e07..06f147d 100644
--- a/src/systemd/sd-network.h
+++ b/src/systemd/sd-network.h
@@ -84,6 +84,9 @@ int sd_network_get_dns(int ifindex, char ***addr);
  * reperesentations of IP addresses */
 int sd_network_get_ntp(int ifindex, char ***addr);
 
+/* Get the DNS domain name for a given link. */
+int sd_network_get_domainname(int ifindex, char **domainname);
+
 /* Monitor object */
 typedef struct sd_network_monitor sd_network_monitor;
 
-- 
1.8.5.5



More information about the systemd-devel mailing list