From 0d5ee47dfd225bf73a7f1c67d1c4c9b76baa6bea Mon Sep 17 00:00:00 2001 From: Dmitry Rozhkov Date: Mon, 16 Oct 2017 17:25:17 +0300 Subject: [PATCH] resolved: add authority section to mDNS probing queries According to RFC 6762 Section 8.2 "Simultaneous Probe Tiebreaking" probing queries' Authority Section is populated with proposed resource records in order to resolve possible race conditions. --- src/resolve/resolved-dns-transaction.c | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index a66d6054053..ea81056119b 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -1377,7 +1377,11 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) { _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL; bool add_known_answers = false; DnsTransaction *other; + Iterator i; + DnsResourceKey *tkey; + _cleanup_set_free_ Set *keys = NULL; unsigned qdcount; + unsigned nscount = 0; usec_t ts; int r; @@ -1400,6 +1404,16 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) { if (dns_key_is_shared(t->key)) add_known_answers = true; + if (t->key->type == DNS_TYPE_ANY) { + r = set_ensure_allocated(&keys, &dns_resource_key_hash_ops); + if (r < 0) + return r; + + r = set_put(keys, t->key); + if (r < 0) + return r; + } + /* * For mDNS, we want to coalesce as many open queries in pending transactions into one single * query packet on the wire as possible. To achieve that, we iterate through all pending transactions @@ -1459,6 +1473,16 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) { if (dns_key_is_shared(other->key)) add_known_answers = true; + + if (other->key->type == DNS_TYPE_ANY) { + r = set_ensure_allocated(&keys, &dns_resource_key_hash_ops); + if (r < 0) + return r; + + r = set_put(keys, other->key); + if (r < 0) + return r; + } } DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount); @@ -1470,6 +1494,22 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) { return r; } + SET_FOREACH(tkey, keys, i) { + _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; + bool tentative; + + r = dns_zone_lookup(&t->scope->zone, tkey, t->scope->link->ifindex, &answer, NULL, &tentative); + if (r < 0) + return r; + + r = dns_packet_append_answer(p, answer); + if (r < 0) + return r; + + nscount += dns_answer_size(answer); + } + DNS_PACKET_HEADER(p)->nscount = htobe16(nscount); + t->sent = p; p = NULL; -- 2.39.2