mirror of
https://github.com/systemd/systemd.git
synced 2024-11-01 00:51:24 +03:00
resolved: when a server consistently returns SERVFAIL, try another one
Currently, we accept SERVFAIL after downgrading fully, cache it and move on. Let's extend this a bit: after downgrading fully, if the SERVFAIL logic continues to be an issue, then use a different DNS server if there are any. Fixes: #7147
This commit is contained in:
parent
4a0e9289bf
commit
44db02d0ef
@ -143,6 +143,26 @@ DnsServer *dns_scope_get_dns_server(DnsScope *s) {
|
||||
return manager_get_dns_server(s->manager);
|
||||
}
|
||||
|
||||
unsigned dns_scope_get_n_dns_servers(DnsScope *s) {
|
||||
unsigned n = 0;
|
||||
DnsServer *i;
|
||||
|
||||
assert(s);
|
||||
|
||||
if (s->protocol != DNS_PROTOCOL_DNS)
|
||||
return 0;
|
||||
|
||||
if (s->link)
|
||||
i = s->link->dns_servers;
|
||||
else
|
||||
i = s->manager->dns_servers;
|
||||
|
||||
for (; i; i = i->servers_next)
|
||||
n++;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void dns_scope_next_dns_server(DnsScope *s) {
|
||||
assert(s);
|
||||
|
||||
|
@ -95,6 +95,7 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, co
|
||||
bool dns_scope_good_key(DnsScope *s, const DnsResourceKey *key);
|
||||
|
||||
DnsServer *dns_scope_get_dns_server(DnsScope *s);
|
||||
unsigned dns_scope_get_n_dns_servers(DnsScope *s);
|
||||
void dns_scope_next_dns_server(DnsScope *s);
|
||||
|
||||
int dns_scope_llmnr_membership(DnsScope *s, bool b);
|
||||
|
@ -408,6 +408,8 @@ static int dns_transaction_pick_server(DnsTransaction *t) {
|
||||
dns_server_unref(t->server);
|
||||
t->server = dns_server_ref(server);
|
||||
|
||||
t->n_picked_servers ++;
|
||||
|
||||
log_debug("Using DNS server %s for transaction %u.", dns_server_string(t->server), t->id);
|
||||
|
||||
return 1;
|
||||
@ -913,12 +915,21 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
|
||||
/* Request failed, immediately try again with reduced features */
|
||||
|
||||
if (t->current_feature_level <= DNS_SERVER_FEATURE_LEVEL_UDP) {
|
||||
|
||||
/* This was already at UDP feature level? If so, it doesn't make sense to downgrade
|
||||
* this transaction anymore, hence let's process the response, and accept the
|
||||
* this transaction anymore, but let's see if it might make sense to send the request
|
||||
* to a different DNS server instead. If not let's process the response, and accept the
|
||||
* rcode. Note that we don't retry on TCP, since that's a suitable way to mitigate
|
||||
* packet loss, but is not going to give us better rcodes should we actually have
|
||||
* managed to get them already at UDP level. */
|
||||
|
||||
if (t->n_picked_servers < dns_scope_get_n_dns_servers(t->scope)) {
|
||||
/* We tried fewer servers on this transaction than we know, let's try another one then */
|
||||
dns_transaction_retry(t, true);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Give up, accept the rcode */
|
||||
log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p)));
|
||||
break;
|
||||
}
|
||||
|
@ -109,6 +109,8 @@ struct DnsTransaction {
|
||||
sd_event_source *timeout_event_source;
|
||||
unsigned n_attempts;
|
||||
|
||||
unsigned n_picked_servers;
|
||||
|
||||
/* UDP connection logic, if we need it */
|
||||
int dns_udp_fd;
|
||||
sd_event_source *dns_udp_event_source;
|
||||
|
Loading…
Reference in New Issue
Block a user