From cc450722a02ab9c59bca1d9a5b5012f356336a8c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 19 Jan 2016 00:51:26 +0100 Subject: resolved: don't forget about lost OPT and RRSIG when downgrading a feature level 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 | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src/resolve/resolved-dns-server.c') diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c index 949c0d66e1..5a86661807 100644 --- a/src/resolve/resolved-dns-server.c +++ b/src/resolve/resolved-dns-server.c @@ -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)); -- cgit v1.2.3-54-g00ecf