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.
This commit is contained in:
parent
e58a818ce9
commit
65fdc8f2fe
|
@ -345,39 +345,30 @@ static const struct resolve_method_ops resolve_method_systemd_ops = {
|
||||||
|
|
||||||
char *resolvconf_path;
|
char *resolvconf_path;
|
||||||
|
|
||||||
struct resolvconf {
|
static bool resolvconf_invoke(const char *ifname, const char *type,
|
||||||
struct resolve super;
|
const char *content)
|
||||||
char *ifname;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void resolve_resolvconf_add_dns(struct resolve *resolve,
|
|
||||||
uint8_t type, char **dns_list)
|
|
||||||
{
|
{
|
||||||
FILE *resolvconf;
|
FILE *resolvconf;
|
||||||
struct l_string *content;
|
|
||||||
int error;
|
|
||||||
L_AUTO_FREE_VAR(char *, cmd) = NULL;
|
L_AUTO_FREE_VAR(char *, cmd) = NULL;
|
||||||
L_AUTO_FREE_VAR(char *, str) = NULL;
|
int error;
|
||||||
|
|
||||||
if (L_WARN_ON(!resolvconf_path))
|
if (content) {
|
||||||
return;
|
cmd = l_strdup_printf("%s -a %s.%s", resolvconf_path,
|
||||||
|
ifname, type);
|
||||||
cmd = l_strdup_printf("%s -a %u", resolvconf_path, resolve->ifindex);
|
resolvconf = popen(cmd, "w");
|
||||||
|
} else {
|
||||||
if (!(resolvconf = popen(cmd, "w"))) {
|
cmd = l_strdup_printf("%s -d %s.%s", resolvconf_path,
|
||||||
l_error("resolve: Failed to start %s (%s).", resolvconf_path,
|
ifname, type);
|
||||||
strerror(errno));
|
resolvconf = popen(cmd, "r");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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++)
|
if (content && fprintf(resolvconf, "%s", content) < 0)
|
||||||
l_string_append_printf(content, "nameserver %s\n", *dns_list);
|
|
||||||
|
|
||||||
str = l_string_unwrap(content);
|
|
||||||
|
|
||||||
if (fprintf(resolvconf, "%s", str) < 0)
|
|
||||||
l_error("resolve: Failed to print into %s stdin.",
|
l_error("resolve: Failed to print into %s stdin.",
|
||||||
resolvconf_path);
|
resolvconf_path);
|
||||||
|
|
||||||
|
@ -388,32 +379,47 @@ static void resolve_resolvconf_add_dns(struct resolve *resolve,
|
||||||
else if (error > 0)
|
else if (error > 0)
|
||||||
l_info("resolve: %s exited with status (%d).", resolvconf_path,
|
l_info("resolve: %s exited with status (%d).", resolvconf_path,
|
||||||
error);
|
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;
|
struct resolvconf *rc =
|
||||||
int error;
|
l_container_of(resolve, struct resolvconf, super);
|
||||||
L_AUTO_FREE_VAR(char *, cmd) = NULL;
|
struct l_string *content;
|
||||||
|
L_AUTO_FREE_VAR(char *, str) = NULL;
|
||||||
|
|
||||||
if (L_WARN_ON(!resolvconf_path))
|
if (L_WARN_ON(!resolvconf_path))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cmd = l_strdup_printf("%s -d %u", resolvconf_path, resolve->ifindex);
|
content = l_string_new(0);
|
||||||
|
|
||||||
if (!(resolvconf = popen(cmd, "r"))) {
|
for (; *dns_list; dns_list++)
|
||||||
l_error("resolve: Failed to start %s (%s).", resolvconf_path,
|
l_string_append_printf(content, "nameserver %s\n", *dns_list);
|
||||||
strerror(errno));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = pclose(resolvconf);
|
str = l_string_unwrap(content);
|
||||||
if (error < 0)
|
|
||||||
l_error("resolve: Failed to close pipe to %s (%s).",
|
if (resolvconf_invoke(rc->ifname, "dns", str))
|
||||||
resolvconf_path, strerror(errno));
|
rc->have_dns = true;
|
||||||
else if (error > 0)
|
}
|
||||||
l_info("resolve: %s exited with status (%d).", resolvconf_path,
|
|
||||||
error);
|
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)
|
static void resolve_resolvconf_destroy(struct resolve *resolve)
|
||||||
|
|
Loading…
Reference in New Issue