networkd: store DNS servers configured per-network as parsed addresses
DNS servers must be specified as IP addresses, hence let's store them as that internally, so that they are guaranteed to be fully normalized always, and invalid data cannot be stored.
This commit is contained in:
parent
fa105ce6b7
commit
5512a96316
|
@ -854,28 +854,26 @@ static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userda
|
|||
static int link_push_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
|
||||
_cleanup_free_ struct in_addr *addresses = NULL;
|
||||
size_t n_addresses = 0, n_allocated = 0;
|
||||
char **a;
|
||||
unsigned i;
|
||||
|
||||
log_debug("Copying DNS server information from %s", link->ifname);
|
||||
|
||||
if (!link->network)
|
||||
return 0;
|
||||
|
||||
STRV_FOREACH(a, link->network->dns) {
|
||||
struct in_addr ia;
|
||||
for (i = 0; i < link->network->n_dns; i++) {
|
||||
|
||||
/* Only look for IPv4 addresses */
|
||||
if (inet_pton(AF_INET, *a, &ia) <= 0)
|
||||
if (link->network->dns[i].family != AF_INET)
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
|
||||
return log_oom();
|
||||
|
||||
addresses[n_addresses++] = ia;
|
||||
addresses[n_addresses++] = link->network->dns[i].address.in;
|
||||
}
|
||||
|
||||
if (link->network->dhcp_use_dns &&
|
||||
link->dhcp_lease) {
|
||||
if (link->network->dhcp_use_dns && link->dhcp_lease) {
|
||||
const struct in_addr *da = NULL;
|
||||
int n;
|
||||
|
||||
|
@ -919,8 +917,7 @@ static int link_push_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
|
|||
addresses[n_addresses++] = ia;
|
||||
}
|
||||
|
||||
if (link->network->dhcp_use_ntp &&
|
||||
link->dhcp_lease) {
|
||||
if (link->network->dhcp_use_ntp && link->dhcp_lease) {
|
||||
const struct in_addr *da = NULL;
|
||||
int n;
|
||||
|
||||
|
@ -3235,7 +3232,7 @@ int link_save(Link *link) {
|
|||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
fchmod(fileno(f), 0644);
|
||||
(void) fchmod(fileno(f), 0644);
|
||||
|
||||
fprintf(f,
|
||||
"# This is private data. Do not parse.\n"
|
||||
|
@ -3248,6 +3245,7 @@ int link_save(Link *link) {
|
|||
sd_dhcp6_lease *dhcp6_lease = NULL;
|
||||
const char *dhcp_domainname = NULL;
|
||||
char **dhcp6_domains = NULL;
|
||||
unsigned j;
|
||||
|
||||
if (link->dhcp6_client) {
|
||||
r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
|
||||
|
@ -3259,7 +3257,22 @@ int link_save(Link *link) {
|
|||
|
||||
fputs("DNS=", f);
|
||||
space = false;
|
||||
fputstrv(f, link->network->dns, NULL, &space);
|
||||
|
||||
for (j = 0; j < link->network->n_dns; j++) {
|
||||
_cleanup_free_ char *b = NULL;
|
||||
|
||||
r = in_addr_to_string(link->network->dns[j].family,
|
||||
&link->network->dns[j].address, &b);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to format address, ignoring: %m");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (space)
|
||||
fputc(' ', f);
|
||||
fputs(b, f);
|
||||
space = true;
|
||||
}
|
||||
|
||||
if (link->network->dhcp_use_dns &&
|
||||
link->dhcp_lease) {
|
||||
|
|
|
@ -774,11 +774,48 @@ static int manager_connect_rtnl(Manager *m) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ordered_set_put_in_addr(OrderedSet *s, const struct in_addr *address) {
|
||||
static int ordered_set_put_in_addr_data(OrderedSet *s, const struct in_addr_data *address) {
|
||||
char *p;
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
assert(address);
|
||||
|
||||
r = in_addr_to_string(address->family, &address->address, &p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ordered_set_consume(s, p);
|
||||
if (r == -EEXIST)
|
||||
return 0;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int ordered_set_put_in_addr_datav(OrderedSet *s, const struct in_addr_data *addresses, unsigned n) {
|
||||
int r, c = 0;
|
||||
unsigned i;
|
||||
|
||||
assert(s);
|
||||
assert(addresses || n == 0);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
r = ordered_set_put_in_addr_data(s, addresses+i);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c += r;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static int ordered_set_put_in4_addr(OrderedSet *s, const struct in_addr *address) {
|
||||
char *p;
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
assert(address);
|
||||
|
||||
r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
|
||||
if (r < 0)
|
||||
|
@ -791,14 +828,15 @@ static int ordered_set_put_in_addr(OrderedSet *s, const struct in_addr *address)
|
|||
return r;
|
||||
}
|
||||
|
||||
static int ordered_set_put_in_addrv(OrderedSet *s, const struct in_addr *addresses, int n) {
|
||||
int r, i, c = 0;
|
||||
static int ordered_set_put_in4_addrv(OrderedSet *s, const struct in_addr *addresses, unsigned n) {
|
||||
int r, c = 0;
|
||||
unsigned i;
|
||||
|
||||
assert(s);
|
||||
assert(n <= 0 || addresses);
|
||||
assert(n == 0 || addresses);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
r = ordered_set_put_in_addr(s, addresses+i);
|
||||
r = ordered_set_put_in4_addr(s, addresses+i);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -865,7 +903,7 @@ static int manager_save(Manager *m) {
|
|||
continue;
|
||||
|
||||
/* First add the static configured entries */
|
||||
r = ordered_set_put_strdupv(dns, link->network->dns);
|
||||
r = ordered_set_put_in_addr_datav(dns, link->network->dns, link->network->n_dns);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -890,7 +928,7 @@ static int manager_save(Manager *m) {
|
|||
|
||||
r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
|
||||
if (r > 0) {
|
||||
r = ordered_set_put_in_addrv(dns, addresses, r);
|
||||
r = ordered_set_put_in4_addrv(dns, addresses, r);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if (r < 0 && r != -ENODATA)
|
||||
|
@ -902,7 +940,7 @@ static int manager_save(Manager *m) {
|
|||
|
||||
r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
|
||||
if (r > 0) {
|
||||
r = ordered_set_put_in_addrv(ntp, addresses, r);
|
||||
r = ordered_set_put_in4_addrv(ntp, addresses, r);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if (r < 0 && r != -ENODATA)
|
||||
|
@ -934,7 +972,7 @@ static int manager_save(Manager *m) {
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
fchmod(fileno(f), 0644);
|
||||
(void) fchmod(fileno(f), 0644);
|
||||
|
||||
fprintf(f,
|
||||
"# This is private data. Do not parse.\n"
|
||||
|
|
|
@ -244,7 +244,7 @@ void network_free(Network *network) {
|
|||
free(network->mac);
|
||||
|
||||
strv_free(network->ntp);
|
||||
strv_free(network->dns);
|
||||
free(network->dns);
|
||||
strv_free(network->search_domains);
|
||||
strv_free(network->route_domains);
|
||||
strv_free(network->bind_carrier);
|
||||
|
@ -396,7 +396,7 @@ int network_apply(Network *network, Link *link) {
|
|||
route->protocol = RTPROT_STATIC;
|
||||
}
|
||||
|
||||
if (!strv_isempty(network->dns) ||
|
||||
if (network->n_dns > 0 ||
|
||||
!strv_isempty(network->ntp) ||
|
||||
!strv_isempty(network->search_domains) ||
|
||||
!strv_isempty(network->route_domains))
|
||||
|
@ -1004,29 +1004,35 @@ int config_parse_dns(
|
|||
for (;;) {
|
||||
_cleanup_free_ char *w = NULL;
|
||||
union in_addr_union a;
|
||||
struct in_addr_data *m;
|
||||
int family;
|
||||
|
||||
r = extract_first_word(&rvalue, &w, NULL, EXTRACT_QUOTES|EXTRACT_RETAIN_ESCAPE);
|
||||
if (r == 0)
|
||||
break;
|
||||
r = extract_first_word(&rvalue, &w, NULL, 0);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
|
||||
break;
|
||||
}
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
r = in_addr_from_string_auto(w, &family, &a);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse dns server address, ignoring: %s", w);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse dns server address, ignoring: %s", w);
|
||||
continue;
|
||||
}
|
||||
|
||||
r = strv_consume(&n->dns, w);
|
||||
if (r < 0)
|
||||
m = realloc(n->dns, (n->n_dns + 1) * sizeof(struct in_addr_data));
|
||||
if (!m)
|
||||
return log_oom();
|
||||
|
||||
w = NULL;
|
||||
m[n->n_dns++] = (struct in_addr_data) {
|
||||
.family = family,
|
||||
.address = a,
|
||||
};
|
||||
|
||||
n->dns = m;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -194,7 +194,10 @@ struct Network {
|
|||
Hashmap *routes_by_section;
|
||||
Hashmap *fdb_entries_by_section;
|
||||
|
||||
char **search_domains, **route_domains, **dns, **ntp, **bind_carrier;
|
||||
struct in_addr_data *dns;
|
||||
unsigned n_dns;
|
||||
|
||||
char **search_domains, **route_domains, **ntp, **bind_carrier;
|
||||
|
||||
ResolveSupport llmnr;
|
||||
ResolveSupport mdns;
|
||||
|
|
Loading…
Reference in New Issue