summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO1
-rw-r--r--src/resolve/resolved-dns-transaction.c16
2 files changed, 13 insertions, 4 deletions
diff --git a/TODO b/TODO
index 2904e2b445..c1b57beeb9 100644
--- a/TODO
+++ b/TODO
@@ -354,7 +354,6 @@ Features:
- dname
- cname on PTR (?)
- maybe randomize DNS UDP source ports
- - maybe compare query section of DNS replies
* Allow multiple ExecStart= for all Type= settings, so that we can cover rescue.service nicely
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index 7fa73cd01a..3260ded424 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -338,10 +338,15 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
if (t->scope->protocol == DNS_PROTOCOL_DNS) {
/* For DNS we are fine with accepting packets on any
- * interface, but the source IP address must be one of
- * a valid DNS server */
+ * interface, but the source IP address must be the
+ * one of the DNS server we queried */
- if (!dns_scope_good_dns_server(t->scope, p->family, &p->sender))
+ assert(t->server);
+
+ if (t->server->family != p->family)
+ return;
+
+ if (!in_addr_equal(p->family, &p->sender, &t->server->address))
return;
if (p->sender_port != 53)
@@ -403,6 +408,11 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
return;
}
+ /* Only consider responses with equivalent query section to the request */
+ if (!dns_question_is_superset(p->question, t->question) ||
+ !dns_question_is_superset(t->question, p->question))
+ dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
+
/* According to RFC 4795, section 2.9. only the RRs from the answer section shall be cached */
dns_cache_put(&t->scope->cache, p->question, DNS_PACKET_RCODE(p), p->answer, DNS_PACKET_ANCOUNT(p), 0, p->family, &p->sender);