]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: don't forget about lost OPT and RRSIG when downgrading a feature level 2358/head
authorLennart Poettering <lennart@poettering.net>
Mon, 18 Jan 2016 23:51:26 +0000 (00:51 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 18 Jan 2016 23:51:26 +0000 (00:51 +0100)
Certain Belkin routers appear to implement a broken DNS cache for A RRs and some others, but implement a pass-thru for
AAAA RRs. This has the effect that we quickly recognize the broken logic of the router when we do an A lookup, but for
AAAA everything works fine until we actually try to validate the request. Given that the validation will necessarily
fail ultimately let's make sure we remember even when downgrading a feature level that OPT or RRSIG was missing.

src/resolve/resolved-dns-server.c

index 949c0d66e11a38f762ef4907318dca4776793cc0..5a866618075f8ebc901cdcefccc9c7aa24b868a0 100644 (file)
@@ -375,9 +375,18 @@ static void dns_server_reset_counters(DnsServer *s) {
         s->n_failed_tcp = 0;
         s->packet_failed = false;
         s->packet_truncated = false;
-        s->packet_bad_opt = false;
-        s->packet_rrsig_missing = false;
         s->verified_usec = 0;
+
+        /* Note that we do not reset s->packet_bad_opt and s->packet_rrsig_missing here. We reset them only when the
+         * grace period ends, but not when lowering the possible feature level, as a lower level feature level should
+         * not make RRSIGs appear or OPT appear, but rather make them disappear. If the reappear anyway, then that's
+         * indication for a differently broken OPT/RRSIG implementation, and we really don't want to support that
+         * either.
+         *
+         * This is particularly important to deal with certain Belkin routers which break OPT for certain lookups (A),
+         * but pass traffic through for others (AAAA). If we detect the broken behaviour on one lookup we should not
+         * reenable it for another, because we cannot validate things anyway, given that the RRSIG/OPT data will be
+         * incomplete. */
 }
 
 DnsServerFeatureLevel dns_server_possible_feature_level(DnsServer *s) {
@@ -387,8 +396,12 @@ DnsServerFeatureLevel dns_server_possible_feature_level(DnsServer *s) {
             dns_server_grace_period_expired(s)) {
 
                 s->possible_feature_level = DNS_SERVER_FEATURE_LEVEL_BEST;
+
                 dns_server_reset_counters(s);
 
+                s->packet_bad_opt = false;
+                s->packet_rrsig_missing = false;
+
                 log_info("Grace period over, resuming full feature set (%s) for DNS server %s.",
                          dns_server_feature_level_to_string(s->possible_feature_level),
                          dns_server_string(s));