From 4e0b8b17a7465653f4e7b819dad5f8e30d64c0c4 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Thu, 16 Jul 2015 14:39:55 +0200 Subject: [PATCH] resolved: degrade the feature level on explicit failure Previously, we would only degrade on packet loss, but when adding EDNS0 support, we also have to handle the case where the server replies with an explicit error. --- src/resolve/resolved-dns-server.c | 10 ++++++++++ src/resolve/resolved-dns-server.h | 1 + src/resolve/resolved-dns-transaction.c | 17 ++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) 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: