Merge pull request #6949 from poettering/restart-servers
Automatically forget learnt DNS server information when network config changes
This commit is contained in:
commit
1e5284bda3
11
NEWS
11
NEWS
|
@ -209,6 +209,17 @@ CHANGES WITH 235:
|
||||||
too. Note that while the other databases are world-readable
|
too. Note that while the other databases are world-readable
|
||||||
(i.e. 0644), btmp is not and remains more restrictive.
|
(i.e. 0644), btmp is not and remains more restrictive.
|
||||||
|
|
||||||
|
* The systemd-resolve tool gained a new --reset-server-features
|
||||||
|
switch. When invoked like this systemd-resolved will forget
|
||||||
|
everything it learnt about the features supported by the configured
|
||||||
|
upstream DNS servers, and restarts the feature probing logic on the
|
||||||
|
next resolver look-up for them at the highest feature level
|
||||||
|
again.
|
||||||
|
|
||||||
|
* The status dump systemd-resolved sends to the logs upon receiving
|
||||||
|
SIGUSR1 now also includes information about all DNS servers it is
|
||||||
|
configured to use, and the features levels it probed for them.
|
||||||
|
|
||||||
Contributions from: Abdó Roig-Maranges, Alan Jenkins, Alexander
|
Contributions from: Abdó Roig-Maranges, Alan Jenkins, Alexander
|
||||||
Kuleshov, Andreas Rammhold, Andrew Jeddeloh, Andrew Soutar, Ansgar
|
Kuleshov, Andreas Rammhold, Andrew Jeddeloh, Andrew Soutar, Ansgar
|
||||||
Burchardt, b1tninja, bengal, Benjamin Berg, Benjamin Robin, Charles
|
Burchardt, b1tninja, bengal, Benjamin Berg, Benjamin Robin, Charles
|
||||||
|
|
|
@ -299,7 +299,18 @@
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--flush-caches</option></term>
|
<term><option>--flush-caches</option></term>
|
||||||
|
|
||||||
<listitem><para>Flushes all DNS resource record caches the service maintains locally.</para></listitem>
|
<listitem><para>Flushes all DNS resource record caches the service maintains locally. This is mostly equivalent
|
||||||
|
to sending the <constant>SIGUSR2</constant> to the <command>systemd-resolved</command>
|
||||||
|
service.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--reset-server-features</option></term>
|
||||||
|
|
||||||
|
<listitem><para>Flushes all feature level information the resolver learnt about specific servers, and ensures
|
||||||
|
that the server feature probing logic is started from the beginning with the next look-up request. This is
|
||||||
|
mostly equivalent to sending the <constant>SIGRTMIN+1</constant> to the <command>systemd-resolved</command>
|
||||||
|
service.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
|
|
@ -202,19 +202,38 @@
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><constant>SIGUSR1</constant></term>
|
<term><constant>SIGUSR1</constant></term>
|
||||||
|
|
||||||
<listitem><para>Upon reception of the SIGUSR1 process signal <command>systemd-resolved</command> will dump the
|
<listitem><para>Upon reception of the <constant>SIGUSR1</constant> process signal
|
||||||
contents of all DNS resource record caches it maintains into the system logs.</para></listitem>
|
<command>systemd-resolved</command> will dump the contents of all DNS resource record caches it maintains, as
|
||||||
|
well as all feature level information it learnt about configured DNS servers into the system
|
||||||
|
logs.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><constant>SIGUSR2</constant></term>
|
<term><constant>SIGUSR2</constant></term>
|
||||||
|
|
||||||
<listitem><para>Upon reception of the SIGUSR2 process signal <command>systemd-resolved</command> will flush all
|
<listitem><para>Upon reception of the <constant>SIGUSR2</constant> process signal
|
||||||
caches it maintains. Note that it should normally not be necessary to request this explicitly – except for
|
<command>systemd-resolved</command> will flush all caches it maintains. Note that it should normally not be
|
||||||
debugging purposes – as <command>systemd-resolved</command> flushes the caches automatically anyway any time
|
necessary to request this explicitly – except for debugging purposes – as <command>systemd-resolved</command>
|
||||||
the host's network configuration changes.</para></listitem>
|
flushes the caches automatically anyway any time the host's network configuration changes. Sending this signal
|
||||||
|
to <command>systemd-resolved</command> is equivalent to the <command>systemd-resolve --flush-caches</command>
|
||||||
|
command, however the latter is recommended since it operates in a synchronous way.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><constant>SIGRTMIN+1</constant></term>
|
||||||
|
|
||||||
|
<listitem><para>Upon reception of the <constant>SIGRTMIN+1</constant> process signal
|
||||||
|
<command>systemd-resolved</command> will forget everything it learnt about the configured DNS
|
||||||
|
servers. Specifically any information about server feature support is flushed out, and the server feature
|
||||||
|
probing logic is restarted on the next request, starting with the most fully featured level. Note that it
|
||||||
|
should normally not be necessary to request this explicitly – except for debugging purposes – as
|
||||||
|
<command>systemd-resolved</command> automatically forgets learnt information any time the DNS server
|
||||||
|
configuration changes. Sending this signal to <command>systemd-resolved</command> is equivalent to the
|
||||||
|
<command>systemd-resolve --reset-server-features</command> command, however the latter is recommended since it
|
||||||
|
operates in a synchronous way.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
|
|
|
@ -72,6 +72,7 @@ static enum {
|
||||||
MODE_STATISTICS,
|
MODE_STATISTICS,
|
||||||
MODE_RESET_STATISTICS,
|
MODE_RESET_STATISTICS,
|
||||||
MODE_FLUSH_CACHES,
|
MODE_FLUSH_CACHES,
|
||||||
|
MODE_RESET_SERVER_FEATURES,
|
||||||
MODE_STATUS,
|
MODE_STATUS,
|
||||||
} arg_mode = MODE_RESOLVE_HOST;
|
} arg_mode = MODE_RESOLVE_HOST;
|
||||||
|
|
||||||
|
@ -1055,6 +1056,24 @@ static int flush_caches(sd_bus *bus) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int reset_server_features(sd_bus *bus) {
|
||||||
|
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = sd_bus_call_method(bus,
|
||||||
|
"org.freedesktop.resolve1",
|
||||||
|
"/org/freedesktop/resolve1",
|
||||||
|
"org.freedesktop.resolve1.Manager",
|
||||||
|
"ResetServerFeatures",
|
||||||
|
&error,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to reset server features: %s", bus_error_message(&error, r));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int map_link_dns_servers(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
|
static int map_link_dns_servers(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
|
||||||
char ***l = userdata;
|
char ***l = userdata;
|
||||||
int r;
|
int r;
|
||||||
|
@ -1588,6 +1607,8 @@ static void help(void) {
|
||||||
" --reset-statistics Reset resolver statistics\n"
|
" --reset-statistics Reset resolver statistics\n"
|
||||||
" --status Show link and server status\n"
|
" --status Show link and server status\n"
|
||||||
" --flush-caches Flush all local DNS caches\n"
|
" --flush-caches Flush all local DNS caches\n"
|
||||||
|
" --reset-server-features\n"
|
||||||
|
" Forget learnt DNS server feature levels\n"
|
||||||
, program_invocation_short_name);
|
, program_invocation_short_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1607,30 +1628,32 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
ARG_RESET_STATISTICS,
|
ARG_RESET_STATISTICS,
|
||||||
ARG_STATUS,
|
ARG_STATUS,
|
||||||
ARG_FLUSH_CACHES,
|
ARG_FLUSH_CACHES,
|
||||||
|
ARG_RESET_SERVER_FEATURES,
|
||||||
ARG_NO_PAGER,
|
ARG_NO_PAGER,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct option options[] = {
|
static const struct option options[] = {
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{ "version", no_argument, NULL, ARG_VERSION },
|
{ "version", no_argument, NULL, ARG_VERSION },
|
||||||
{ "type", required_argument, NULL, 't' },
|
{ "type", required_argument, NULL, 't' },
|
||||||
{ "class", required_argument, NULL, 'c' },
|
{ "class", required_argument, NULL, 'c' },
|
||||||
{ "legend", required_argument, NULL, ARG_LEGEND },
|
{ "legend", required_argument, NULL, ARG_LEGEND },
|
||||||
{ "interface", required_argument, NULL, 'i' },
|
{ "interface", required_argument, NULL, 'i' },
|
||||||
{ "protocol", required_argument, NULL, 'p' },
|
{ "protocol", required_argument, NULL, 'p' },
|
||||||
{ "cname", required_argument, NULL, ARG_CNAME },
|
{ "cname", required_argument, NULL, ARG_CNAME },
|
||||||
{ "service", no_argument, NULL, ARG_SERVICE },
|
{ "service", no_argument, NULL, ARG_SERVICE },
|
||||||
{ "service-address", required_argument, NULL, ARG_SERVICE_ADDRESS },
|
{ "service-address", required_argument, NULL, ARG_SERVICE_ADDRESS },
|
||||||
{ "service-txt", required_argument, NULL, ARG_SERVICE_TXT },
|
{ "service-txt", required_argument, NULL, ARG_SERVICE_TXT },
|
||||||
{ "openpgp", no_argument, NULL, ARG_OPENPGP },
|
{ "openpgp", no_argument, NULL, ARG_OPENPGP },
|
||||||
{ "tlsa", optional_argument, NULL, ARG_TLSA },
|
{ "tlsa", optional_argument, NULL, ARG_TLSA },
|
||||||
{ "raw", optional_argument, NULL, ARG_RAW },
|
{ "raw", optional_argument, NULL, ARG_RAW },
|
||||||
{ "search", required_argument, NULL, ARG_SEARCH },
|
{ "search", required_argument, NULL, ARG_SEARCH },
|
||||||
{ "statistics", no_argument, NULL, ARG_STATISTICS, },
|
{ "statistics", no_argument, NULL, ARG_STATISTICS, },
|
||||||
{ "reset-statistics", no_argument, NULL, ARG_RESET_STATISTICS },
|
{ "reset-statistics", no_argument, NULL, ARG_RESET_STATISTICS },
|
||||||
{ "status", no_argument, NULL, ARG_STATUS },
|
{ "status", no_argument, NULL, ARG_STATUS },
|
||||||
{ "flush-caches", no_argument, NULL, ARG_FLUSH_CACHES },
|
{ "flush-caches", no_argument, NULL, ARG_FLUSH_CACHES },
|
||||||
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
{ "reset-server-features", no_argument, NULL, ARG_RESET_SERVER_FEATURES },
|
||||||
|
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1814,6 +1837,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
arg_mode = MODE_FLUSH_CACHES;
|
arg_mode = MODE_FLUSH_CACHES;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ARG_RESET_SERVER_FEATURES:
|
||||||
|
arg_mode = MODE_RESET_SERVER_FEATURES;
|
||||||
|
break;
|
||||||
|
|
||||||
case ARG_STATUS:
|
case ARG_STATUS:
|
||||||
arg_mode = MODE_STATUS;
|
arg_mode = MODE_STATUS;
|
||||||
break;
|
break;
|
||||||
|
@ -1999,6 +2026,16 @@ int main(int argc, char **argv) {
|
||||||
r = flush_caches(bus);
|
r = flush_caches(bus);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MODE_RESET_SERVER_FEATURES:
|
||||||
|
if (argc > optind) {
|
||||||
|
log_error("Too many arguments.");
|
||||||
|
r = -EINVAL;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = reset_server_features(bus);
|
||||||
|
break;
|
||||||
|
|
||||||
case MODE_STATUS:
|
case MODE_STATUS:
|
||||||
|
|
||||||
if (argc > optind) {
|
if (argc > optind) {
|
||||||
|
|
|
@ -1569,6 +1569,17 @@ static int bus_method_flush_caches(sd_bus_message *message, void *userdata, sd_b
|
||||||
return sd_bus_reply_method_return(message, NULL);
|
return sd_bus_reply_method_return(message, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bus_method_reset_server_features(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
|
Manager *m = userdata;
|
||||||
|
|
||||||
|
assert(message);
|
||||||
|
assert(m);
|
||||||
|
|
||||||
|
manager_reset_server_features(m);
|
||||||
|
|
||||||
|
return sd_bus_reply_method_return(message, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static const sd_bus_vtable resolve_vtable[] = {
|
static const sd_bus_vtable resolve_vtable[] = {
|
||||||
SD_BUS_VTABLE_START(0),
|
SD_BUS_VTABLE_START(0),
|
||||||
SD_BUS_PROPERTY("LLMNRHostname", "s", NULL, offsetof(Manager, llmnr_hostname), 0),
|
SD_BUS_PROPERTY("LLMNRHostname", "s", NULL, offsetof(Manager, llmnr_hostname), 0),
|
||||||
|
@ -1587,6 +1598,7 @@ static const sd_bus_vtable resolve_vtable[] = {
|
||||||
SD_BUS_METHOD("ResolveService", "isssit", "a(qqqsa(iiay)s)aayssst", bus_method_resolve_service, SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_METHOD("ResolveService", "isssit", "a(qqqsa(iiay)s)aayssst", bus_method_resolve_service, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD("ResetStatistics", NULL, NULL, bus_method_reset_statistics, 0),
|
SD_BUS_METHOD("ResetStatistics", NULL, NULL, bus_method_reset_statistics, 0),
|
||||||
SD_BUS_METHOD("FlushCaches", NULL, NULL, bus_method_flush_caches, 0),
|
SD_BUS_METHOD("FlushCaches", NULL, NULL, bus_method_flush_caches, 0),
|
||||||
|
SD_BUS_METHOD("ResetServerFeatures", NULL, NULL, bus_method_reset_server_features, 0),
|
||||||
SD_BUS_METHOD("GetLink", "i", "o", bus_method_get_link, SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_METHOD("GetLink", "i", "o", bus_method_get_link, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL, bus_method_set_link_dns_servers, 0),
|
SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL, bus_method_set_link_dns_servers, 0),
|
||||||
SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL, bus_method_set_link_domains, 0),
|
SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL, bus_method_set_link_domains, 0),
|
||||||
|
|
|
@ -70,15 +70,12 @@ int dns_server_new(
|
||||||
|
|
||||||
s->n_ref = 1;
|
s->n_ref = 1;
|
||||||
s->manager = m;
|
s->manager = m;
|
||||||
s->verified_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID;
|
|
||||||
s->possible_feature_level = DNS_SERVER_FEATURE_LEVEL_BEST;
|
|
||||||
s->features_grace_period_usec = DNS_SERVER_FEATURE_GRACE_PERIOD_MIN_USEC;
|
|
||||||
s->received_udp_packet_max = DNS_PACKET_UNICAST_SIZE_MAX;
|
|
||||||
s->type = type;
|
s->type = type;
|
||||||
s->family = family;
|
s->family = family;
|
||||||
s->address = *in_addr;
|
s->address = *in_addr;
|
||||||
s->ifindex = ifindex;
|
s->ifindex = ifindex;
|
||||||
s->resend_timeout = DNS_TIMEOUT_MIN_USEC;
|
|
||||||
|
dns_server_reset_features(s);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
||||||
|
@ -828,6 +825,85 @@ void dns_server_flush_cache(DnsServer *s) {
|
||||||
dns_cache_flush(&scope->cache);
|
dns_cache_flush(&scope->cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dns_server_reset_features(DnsServer *s) {
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
s->max_rtt = 0;
|
||||||
|
s->resend_timeout = DNS_TIMEOUT_MIN_USEC;
|
||||||
|
|
||||||
|
s->verified_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID;
|
||||||
|
s->possible_feature_level = DNS_SERVER_FEATURE_LEVEL_BEST;
|
||||||
|
|
||||||
|
s->received_udp_packet_max = DNS_PACKET_UNICAST_SIZE_MAX;
|
||||||
|
|
||||||
|
s->packet_bad_opt = false;
|
||||||
|
s->packet_rrsig_missing = false;
|
||||||
|
|
||||||
|
s->features_grace_period_usec = DNS_SERVER_FEATURE_GRACE_PERIOD_MIN_USEC;
|
||||||
|
|
||||||
|
s->warned_downgrade = false;
|
||||||
|
|
||||||
|
dns_server_reset_counters(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dns_server_reset_features_all(DnsServer *s) {
|
||||||
|
DnsServer *i;
|
||||||
|
|
||||||
|
LIST_FOREACH(servers, i, s)
|
||||||
|
dns_server_reset_features(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dns_server_dump(DnsServer *s, FILE *f) {
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
if (!f)
|
||||||
|
f = stdout;
|
||||||
|
|
||||||
|
fputs("[Server ", f);
|
||||||
|
fputs(dns_server_string(s), f);
|
||||||
|
fputs(" type=", f);
|
||||||
|
fputs(dns_server_type_to_string(s->type), f);
|
||||||
|
|
||||||
|
if (s->type == DNS_SERVER_LINK) {
|
||||||
|
assert(s->link);
|
||||||
|
|
||||||
|
fputs(" interface=", f);
|
||||||
|
fputs(s->link->name, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs("]\n", f);
|
||||||
|
|
||||||
|
fputs("\tVerified feature level: ", f);
|
||||||
|
fputs(strna(dns_server_feature_level_to_string(s->verified_feature_level)), f);
|
||||||
|
fputc('\n', f);
|
||||||
|
|
||||||
|
fputs("\tPossible feature level: ", f);
|
||||||
|
fputs(strna(dns_server_feature_level_to_string(s->possible_feature_level)), f);
|
||||||
|
fputc('\n', f);
|
||||||
|
|
||||||
|
fputs("\tDNSSEC Mode: ", f);
|
||||||
|
fputs(strna(dnssec_mode_to_string(dns_server_get_dnssec_mode(s))), f);
|
||||||
|
fputc('\n', f);
|
||||||
|
|
||||||
|
fputs("\tCan do DNSSEC: ", f);
|
||||||
|
fputs(yes_no(dns_server_dnssec_supported(s)), f);
|
||||||
|
fputc('\n', f);
|
||||||
|
|
||||||
|
fprintf(f,
|
||||||
|
"\tMaximum UDP packet size received: %zu\n"
|
||||||
|
"\tFailed UDP attempts: %u\n"
|
||||||
|
"\tFailed TCP attempts: %u\n"
|
||||||
|
"\tSeen truncated packet: %s\n"
|
||||||
|
"\tSeen OPT RR getting lost: %s\n"
|
||||||
|
"\tSeen RRSIG RR missing: %s\n",
|
||||||
|
s->received_udp_packet_max,
|
||||||
|
s->n_failed_udp,
|
||||||
|
s->n_failed_tcp,
|
||||||
|
yes_no(s->packet_truncated),
|
||||||
|
yes_no(s->packet_bad_opt),
|
||||||
|
yes_no(s->packet_rrsig_missing));
|
||||||
|
}
|
||||||
|
|
||||||
static const char* const dns_server_type_table[_DNS_SERVER_TYPE_MAX] = {
|
static const char* const dns_server_type_table[_DNS_SERVER_TYPE_MAX] = {
|
||||||
[DNS_SERVER_SYSTEM] = "system",
|
[DNS_SERVER_SYSTEM] = "system",
|
||||||
[DNS_SERVER_FALLBACK] = "fallback",
|
[DNS_SERVER_FALLBACK] = "fallback",
|
||||||
|
|
|
@ -151,3 +151,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(DnsServer*, dns_server_unref);
|
||||||
extern const struct hash_ops dns_server_hash_ops;
|
extern const struct hash_ops dns_server_hash_ops;
|
||||||
|
|
||||||
void dns_server_flush_cache(DnsServer *s);
|
void dns_server_flush_cache(DnsServer *s);
|
||||||
|
|
||||||
|
void dns_server_reset_features(DnsServer *s);
|
||||||
|
void dns_server_reset_features_all(DnsServer *s);
|
||||||
|
|
||||||
|
void dns_server_dump(DnsServer *s, FILE *f);
|
||||||
|
|
|
@ -111,13 +111,30 @@ Link *link_free(Link *l) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void link_allocate_scopes(Link *l) {
|
void link_allocate_scopes(Link *l) {
|
||||||
|
bool unicast_relevant;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(l);
|
assert(l);
|
||||||
|
|
||||||
if (link_relevant(l, AF_UNSPEC, false) &&
|
/* If a link that used to be relevant is no longer, or a link that did not use to be relevant now becomes
|
||||||
l->dns_servers) {
|
* relevant, let's reinit the learnt global DNS server information, since we might talk to different servers
|
||||||
|
* now, even if they have the same addresses as before. */
|
||||||
|
|
||||||
|
unicast_relevant = link_relevant(l, AF_UNSPEC, false);
|
||||||
|
if (unicast_relevant != l->unicast_relevant) {
|
||||||
|
l->unicast_relevant = unicast_relevant;
|
||||||
|
|
||||||
|
dns_server_reset_features_all(l->manager->fallback_dns_servers);
|
||||||
|
dns_server_reset_features_all(l->manager->dns_servers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And now, allocate all scopes that makes sense now if we didn't have them yet, and drop those which we don't
|
||||||
|
* need anymore */
|
||||||
|
|
||||||
|
if (unicast_relevant && l->dns_servers) {
|
||||||
if (!l->unicast_scope) {
|
if (!l->unicast_scope) {
|
||||||
|
dns_server_reset_features_all(l->dns_servers);
|
||||||
|
|
||||||
r = dns_scope_new(l->manager, &l->unicast_scope, l, DNS_PROTOCOL_DNS, AF_UNSPEC);
|
r = dns_scope_new(l->manager, &l->unicast_scope, l, DNS_PROTOCOL_DNS, AF_UNSPEC);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Failed to allocate DNS scope: %m");
|
log_warning_errno(r, "Failed to allocate DNS scope: %m");
|
||||||
|
|
|
@ -88,6 +88,8 @@ struct Link {
|
||||||
|
|
||||||
bool loaded;
|
bool loaded;
|
||||||
char *state_file;
|
char *state_file;
|
||||||
|
|
||||||
|
bool unicast_relevant;
|
||||||
};
|
};
|
||||||
|
|
||||||
int link_new(Manager *m, Link **ret, int ifindex);
|
int link_new(Manager *m, Link **ret, int ifindex);
|
||||||
|
|
|
@ -519,8 +519,11 @@ static int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si
|
||||||
_cleanup_free_ char *buffer = NULL;
|
_cleanup_free_ char *buffer = NULL;
|
||||||
_cleanup_fclose_ FILE *f = NULL;
|
_cleanup_fclose_ FILE *f = NULL;
|
||||||
Manager *m = userdata;
|
Manager *m = userdata;
|
||||||
|
DnsServer *server;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
DnsScope *scope;
|
DnsScope *scope;
|
||||||
|
Iterator i;
|
||||||
|
Link *l;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
assert(si);
|
assert(si);
|
||||||
|
@ -533,6 +536,14 @@ static int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si
|
||||||
LIST_FOREACH(scopes, scope, m->dns_scopes)
|
LIST_FOREACH(scopes, scope, m->dns_scopes)
|
||||||
dns_scope_dump(scope, f);
|
dns_scope_dump(scope, f);
|
||||||
|
|
||||||
|
LIST_FOREACH(servers, server, m->dns_servers)
|
||||||
|
dns_server_dump(server, f);
|
||||||
|
LIST_FOREACH(servers, server, m->fallback_dns_servers)
|
||||||
|
dns_server_dump(server, f);
|
||||||
|
HASHMAP_FOREACH(l, m->links, i)
|
||||||
|
LIST_FOREACH(servers, server, l->dns_servers)
|
||||||
|
dns_server_dump(server, f);
|
||||||
|
|
||||||
if (fflush_and_check(f) < 0)
|
if (fflush_and_check(f) < 0)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
|
@ -552,6 +563,17 @@ static int manager_sigusr2(sd_event_source *s, const struct signalfd_siginfo *si
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int manager_sigrtmin1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
|
||||||
|
Manager *m = userdata;
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
assert(si);
|
||||||
|
assert(m);
|
||||||
|
|
||||||
|
manager_reset_server_features(m);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int manager_new(Manager **ret) {
|
int manager_new(Manager **ret) {
|
||||||
_cleanup_(manager_freep) Manager *m = NULL;
|
_cleanup_(manager_freep) Manager *m = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
@ -616,6 +638,7 @@ int manager_new(Manager **ret) {
|
||||||
|
|
||||||
(void) sd_event_add_signal(m->event, &m->sigusr1_event_source, SIGUSR1, manager_sigusr1, m);
|
(void) sd_event_add_signal(m->event, &m->sigusr1_event_source, SIGUSR1, manager_sigusr1, m);
|
||||||
(void) sd_event_add_signal(m->event, &m->sigusr2_event_source, SIGUSR2, manager_sigusr2, m);
|
(void) sd_event_add_signal(m->event, &m->sigusr2_event_source, SIGUSR2, manager_sigusr2, m);
|
||||||
|
(void) sd_event_add_signal(m->event, &m->sigrtmin1_event_source, SIGRTMIN+1, manager_sigrtmin1, m);
|
||||||
|
|
||||||
manager_cleanup_saved_user(m);
|
manager_cleanup_saved_user(m);
|
||||||
|
|
||||||
|
@ -679,6 +702,7 @@ Manager *manager_free(Manager *m) {
|
||||||
|
|
||||||
sd_event_source_unref(m->sigusr1_event_source);
|
sd_event_source_unref(m->sigusr1_event_source);
|
||||||
sd_event_source_unref(m->sigusr2_event_source);
|
sd_event_source_unref(m->sigusr2_event_source);
|
||||||
|
sd_event_source_unref(m->sigrtmin1_event_source);
|
||||||
|
|
||||||
sd_event_unref(m->event);
|
sd_event_unref(m->event);
|
||||||
|
|
||||||
|
@ -1396,6 +1420,19 @@ void manager_flush_caches(Manager *m) {
|
||||||
log_info("Flushed all caches.");
|
log_info("Flushed all caches.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void manager_reset_server_features(Manager *m) {
|
||||||
|
Iterator i;
|
||||||
|
Link *l;
|
||||||
|
|
||||||
|
dns_server_reset_features_all(m->dns_servers);
|
||||||
|
dns_server_reset_features_all(m->fallback_dns_servers);
|
||||||
|
|
||||||
|
HASHMAP_FOREACH(l, m->links, i)
|
||||||
|
dns_server_reset_features_all(l->dns_servers);
|
||||||
|
|
||||||
|
log_info("Resetting learnt feature levels on all servers.");
|
||||||
|
}
|
||||||
|
|
||||||
void manager_cleanup_saved_user(Manager *m) {
|
void manager_cleanup_saved_user(Manager *m) {
|
||||||
_cleanup_closedir_ DIR *d = NULL;
|
_cleanup_closedir_ DIR *d = NULL;
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
|
|
|
@ -126,6 +126,7 @@ struct Manager {
|
||||||
|
|
||||||
sd_event_source *sigusr1_event_source;
|
sd_event_source *sigusr1_event_source;
|
||||||
sd_event_source *sigusr2_event_source;
|
sd_event_source *sigusr2_event_source;
|
||||||
|
sd_event_source *sigrtmin1_event_source;
|
||||||
|
|
||||||
unsigned n_transactions_total;
|
unsigned n_transactions_total;
|
||||||
unsigned n_dnssec_verdict[_DNSSEC_VERDICT_MAX];
|
unsigned n_dnssec_verdict[_DNSSEC_VERDICT_MAX];
|
||||||
|
@ -184,5 +185,6 @@ void manager_dnssec_verdict(Manager *m, DnssecVerdict verdict, const DnsResource
|
||||||
bool manager_routable(Manager *m, int family);
|
bool manager_routable(Manager *m, int family);
|
||||||
|
|
||||||
void manager_flush_caches(Manager *m);
|
void manager_flush_caches(Manager *m);
|
||||||
|
void manager_reset_server_features(Manager *m);
|
||||||
|
|
||||||
void manager_cleanup_saved_user(Manager *m);
|
void manager_cleanup_saved_user(Manager *m);
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include "ordered-set.h"
|
#include "ordered-set.h"
|
||||||
#include "resolved-conf.h"
|
#include "resolved-conf.h"
|
||||||
|
#include "resolved-dns-server.h"
|
||||||
#include "resolved-resolv-conf.h"
|
#include "resolved-resolv-conf.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
|
@ -136,6 +137,11 @@ int manager_read_resolv_conf(Manager *m) {
|
||||||
if (m->unicast_scope)
|
if (m->unicast_scope)
|
||||||
dns_cache_flush(&m->unicast_scope->cache);
|
dns_cache_flush(&m->unicast_scope->cache);
|
||||||
|
|
||||||
|
/* If /etc/resolv.conf changed, make sure to forget everything we learned about the DNS servers. After all we
|
||||||
|
* might now talk to a very different DNS server that just happens to have the same IP address as an old one
|
||||||
|
* (think 192.168.1.1). */
|
||||||
|
dns_server_reset_features_all(m->dns_servers);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
clear:
|
clear:
|
||||||
|
|
|
@ -80,7 +80,7 @@ int main(int argc, char *argv[]) {
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, SIGUSR1, SIGUSR2, -1) >= 0);
|
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, SIGUSR1, SIGUSR2, SIGRTMIN+1, -1) >= 0);
|
||||||
|
|
||||||
r = manager_new(&m);
|
r = manager_new(&m);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
|
Loading…
Reference in a new issue