summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/resolve/resolved-dns-server.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c
index 6732030d65..949c0d66e1 100644
--- a/src/resolve/resolved-dns-server.c
+++ b/src/resolve/resolved-dns-server.c
@@ -248,13 +248,18 @@ void dns_server_packet_received(DnsServer *s, int protocol, DnsServerFeatureLeve
if (s->possible_feature_level == level)
s->n_failed_udp = 0;
+ /* If the RRSIG data is missing, then we can only validate EDNS0 at max */
+ if (s->packet_rrsig_missing && level >= DNS_SERVER_FEATURE_LEVEL_DO)
+ level = DNS_SERVER_FEATURE_LEVEL_DO - 1;
+
+ /* If the OPT RR got lost, then we can only validate UDP at max */
+ if (s->packet_bad_opt && level >= DNS_SERVER_FEATURE_LEVEL_EDNS0)
+ level = DNS_SERVER_FEATURE_LEVEL_EDNS0 - 1;
+
+ /* Even if we successfully receive a reply to a request announcing support for large packets,
+ that does not mean we can necessarily receive large packets. */
if (level == DNS_SERVER_FEATURE_LEVEL_LARGE)
- /* Even if we successfully receive a reply to a request announcing support for large packets,
- that does not mean we can necessarily receive large packets. */
- dns_server_verified(s, DNS_SERVER_FEATURE_LEVEL_LARGE - 1);
- else
- /* A successful UDP reply, verifies UDP, ENDS0 and DO levels */
- dns_server_verified(s, level);
+ level = DNS_SERVER_FEATURE_LEVEL_LARGE - 1;
} else if (protocol == IPPROTO_TCP) {
@@ -262,9 +267,11 @@ void dns_server_packet_received(DnsServer *s, int protocol, DnsServerFeatureLeve
s->n_failed_tcp = 0;
/* Successful TCP connections are only useful to verify the TCP feature level. */
- dns_server_verified(s, DNS_SERVER_FEATURE_LEVEL_TCP);
+ level = DNS_SERVER_FEATURE_LEVEL_TCP;
}
+ dns_server_verified(s, level);
+
/* Remember the size of the largest UDP packet we received from a server,
we know that we can always announce support for packets with at least
this size. */
@@ -322,6 +329,10 @@ void dns_server_packet_rrsig_missing(DnsServer *s, DnsServerFeatureLevel level)
if (level < DNS_SERVER_FEATURE_LEVEL_DO)
return;
+ /* If the RRSIG RRs are missing, we have to downgrade what we previously verified */
+ if (s->verified_feature_level >= DNS_SERVER_FEATURE_LEVEL_DO)
+ s->verified_feature_level = DNS_SERVER_FEATURE_LEVEL_DO-1;
+
s->packet_rrsig_missing = true;
}
@@ -331,6 +342,10 @@ void dns_server_packet_bad_opt(DnsServer *s, DnsServerFeatureLevel level) {
if (level < DNS_SERVER_FEATURE_LEVEL_EDNS0)
return;
+ /* If the OPT RR got lost, we have to downgrade what we previously verified */
+ if (s->verified_feature_level >= DNS_SERVER_FEATURE_LEVEL_EDNS0)
+ s->verified_feature_level = DNS_SERVER_FEATURE_LEVEL_EDNS0-1;
+
s->packet_bad_opt = true;
}