diff options
-rw-r--r-- | src/resolve/resolved-dns-server.c | 10 | ||||
-rw-r--r-- | src/resolve/resolved-dns-server.h | 1 | ||||
-rw-r--r-- | src/resolve/resolved-dns-transaction.c | 17 |
3 files changed, 27 insertions, 1 deletions
diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c index 5fc7c3187f..c5396a03c8 100644 --- a/src/resolve/resolved-dns-server.c +++ b/src/resolve/resolved-dns-server.c @@ -253,6 +253,16 @@ void dns_server_packet_lost(DnsServer *s, DnsServerFeatureLevel features, usec_t s->resend_timeout = MIN(s->resend_timeout * 2, DNS_TIMEOUT_MAX_USEC); } +void dns_server_packet_failed(DnsServer *s, DnsServerFeatureLevel features) { + assert(s); + assert(s->manager); + + if (s->possible_features != features) + return; + + s->n_failed_attempts = (unsigned) -1; +} + static bool dns_server_grace_period_expired(DnsServer *s) { usec_t ts; diff --git a/src/resolve/resolved-dns-server.h b/src/resolve/resolved-dns-server.h index f82b14e8fb..a3e8cbcc52 100644 --- a/src/resolve/resolved-dns-server.h +++ b/src/resolve/resolved-dns-server.h @@ -89,6 +89,7 @@ void dns_server_move_back_and_unmark(DnsServer *s); void dns_server_packet_received(DnsServer *s, DnsServerFeatureLevel features, usec_t rtt); void dns_server_packet_lost(DnsServer *s, DnsServerFeatureLevel features, usec_t usec); +void dns_server_packet_failed(DnsServer *s, DnsServerFeatureLevel features); DnsServer *dns_server_find(DnsServer *first, int family, const union in_addr_union *in_addr); diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index 0e09a339aa..4398c2cb99 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -418,7 +418,22 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) { case DNS_PROTOCOL_DNS: assert(t->server); - dns_server_packet_received(t->server, t->current_features, ts - t->start_usec); + if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_FORMERR, DNS_RCODE_SERVFAIL, DNS_RCODE_NOTIMP)) { + + /* request failed, immediately try again with reduced features */ + log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p))); + + dns_server_packet_failed(t->server, t->current_features); + + r = dns_transaction_go(t); + if (r < 0) { + dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES); + return; + } + + return; + } else + dns_server_packet_received(t->server, t->current_features, ts - t->start_usec); break; case DNS_PROTOCOL_LLMNR: |