From 65fdc8f2fe973d9d4cf0c2772ec19243b3a53d0f Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Fri, 21 Aug 2020 15:34:29 -0500 Subject: [PATCH] resolve: Refactor resolvconf implementation Introduce a new resolvconf_invoke function that takes care of all the details of invoking resolvconf and simplify the code a bit. Introduce have_dns that tracks whether DNS servers were actually provided. If no DNS info was provided, do not invoke resolvconf to remove it. Instead of interface index, resolvconf is now invoked with the printable name of the interface and the dns entries are placed in the "dns" protocol. This makes it a bit simpler to add additional info to resolvconf instead of trying to generate a monolithic entry. --- src/resolve.c | 92 +++++++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/src/resolve.c b/src/resolve.c index d7fa78d5..eca21d0e 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -345,39 +345,30 @@ static const struct resolve_method_ops resolve_method_systemd_ops = { char *resolvconf_path; -struct resolvconf { - struct resolve super; - char *ifname; -}; - -static void resolve_resolvconf_add_dns(struct resolve *resolve, - uint8_t type, char **dns_list) +static bool resolvconf_invoke(const char *ifname, const char *type, + const char *content) { FILE *resolvconf; - struct l_string *content; - int error; L_AUTO_FREE_VAR(char *, cmd) = NULL; - L_AUTO_FREE_VAR(char *, str) = NULL; + int error; - if (L_WARN_ON(!resolvconf_path)) - return; - - cmd = l_strdup_printf("%s -a %u", resolvconf_path, resolve->ifindex); - - if (!(resolvconf = popen(cmd, "w"))) { - l_error("resolve: Failed to start %s (%s).", resolvconf_path, - strerror(errno)); - return; + if (content) { + cmd = l_strdup_printf("%s -a %s.%s", resolvconf_path, + ifname, type); + resolvconf = popen(cmd, "w"); + } else { + cmd = l_strdup_printf("%s -d %s.%s", resolvconf_path, + ifname, type); + resolvconf = popen(cmd, "r"); } - content = l_string_new(0); + if (!resolvconf) { + l_error("resolve: Failed to start %s (%s).", resolvconf_path, + strerror(errno)); + return false; + } - for (; *dns_list; dns_list++) - l_string_append_printf(content, "nameserver %s\n", *dns_list); - - str = l_string_unwrap(content); - - if (fprintf(resolvconf, "%s", str) < 0) + if (content && fprintf(resolvconf, "%s", content) < 0) l_error("resolve: Failed to print into %s stdin.", resolvconf_path); @@ -388,32 +379,47 @@ static void resolve_resolvconf_add_dns(struct resolve *resolve, else if (error > 0) l_info("resolve: %s exited with status (%d).", resolvconf_path, error); + + return !error; } -static void resolve_resolvconf_revert(struct resolve *resolve) +struct resolvconf { + struct resolve super; + bool have_dns : 1; + char *ifname; +}; + +static void resolve_resolvconf_add_dns(struct resolve *resolve, + uint8_t type, char **dns_list) { - FILE *resolvconf; - int error; - L_AUTO_FREE_VAR(char *, cmd) = NULL; + struct resolvconf *rc = + l_container_of(resolve, struct resolvconf, super); + struct l_string *content; + L_AUTO_FREE_VAR(char *, str) = NULL; if (L_WARN_ON(!resolvconf_path)) return; - cmd = l_strdup_printf("%s -d %u", resolvconf_path, resolve->ifindex); + content = l_string_new(0); - if (!(resolvconf = popen(cmd, "r"))) { - l_error("resolve: Failed to start %s (%s).", resolvconf_path, - strerror(errno)); - return; - } + for (; *dns_list; dns_list++) + l_string_append_printf(content, "nameserver %s\n", *dns_list); - error = pclose(resolvconf); - if (error < 0) - l_error("resolve: Failed to close pipe to %s (%s).", - resolvconf_path, strerror(errno)); - else if (error > 0) - l_info("resolve: %s exited with status (%d).", resolvconf_path, - error); + str = l_string_unwrap(content); + + if (resolvconf_invoke(rc->ifname, "dns", str)) + rc->have_dns = true; +} + +static void resolve_resolvconf_revert(struct resolve *resolve) +{ + struct resolvconf *rc = + l_container_of(resolve, struct resolvconf, super); + + if (rc->have_dns) + resolvconf_invoke(rc->ifname, "dns", NULL); + + rc->have_dns = false; } static void resolve_resolvconf_destroy(struct resolve *resolve)