summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/resolve/resolved-dns-server.c10
-rw-r--r--src/resolve/resolved-dns-server.h1
-rw-r--r--src/resolve/resolved-dns-transaction.c17
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: