]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: add cache-flush bit to answers in mDNS announcements
authorDmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
Fri, 2 Dec 2016 13:28:14 +0000 (15:28 +0200)
committerDmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
Thu, 19 Jan 2017 09:51:21 +0000 (11:51 +0200)
See the section 10.2 of RFC6762 for details.

Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
src/resolve/resolved-dns-answer.h
src/resolve/resolved-dns-cache.c
src/resolve/resolved-dns-packet.c
src/resolve/resolved-dns-packet.h
src/resolve/resolved-dns-rr.c
src/resolve/resolved-dns-scope.c
src/resolve/resolved-dns-stub.c
src/resolve/resolved-dns-transaction.c

index 4a92bd1150065c7ce72b3677784744f159f0738d..c0a819873a3e1ad2d958f27a3c343a86d585659e 100644 (file)
@@ -36,6 +36,7 @@ typedef enum DnsAnswerFlags {
         DNS_ANSWER_AUTHENTICATED = 1, /* Item has been authenticated */
         DNS_ANSWER_CACHEABLE     = 2, /* Item is subject to caching */
         DNS_ANSWER_SHARED_OWNER  = 4, /* For mDNS: RRset may be owner by multiple peers */
+        DNS_ANSWER_CACHE_FLUSH   = 8, /* For mDNS: sets cache-flush bit in the rrclass of response records */
 } DnsAnswerFlags;
 
 struct DnsAnswerItem {
index 9233fb0ac17b987fd783c79828c23cddcde06010..c43a7865dc3dee32265bbfd408f878195b3cbf38 100644 (file)
@@ -980,7 +980,7 @@ int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p) {
                         if (!j->shared_owner)
                                 continue;
 
-                        r = dns_packet_append_rr(p, j->rr, NULL, NULL);
+                        r = dns_packet_append_rr(p, j->rr, 0, NULL, NULL);
                         if (r == -EMSGSIZE && p->protocol == DNS_PROTOCOL_MDNS) {
                                 /* For mDNS, if we're unable to stuff all known answers into the given packet,
                                  * allocate a new one, push the RR into that one and link it to the current one.
@@ -995,7 +995,7 @@ int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p) {
 
                                 /* continue with new packet */
                                 p = p->more;
-                                r = dns_packet_append_rr(p, j->rr, NULL, NULL);
+                                r = dns_packet_append_rr(p, j->rr, 0, NULL, NULL);
                         }
 
                         if (r < 0)
index 337a8c473fb84810f60e44ce15b7d57c17ec8ac4..8231c21450b0d1e891172e75a23dfd80cf9223ab 100644 (file)
@@ -569,8 +569,9 @@ fail:
         return r;
 }
 
-int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start) {
+int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, const DnsAnswerFlags flags, size_t *start) {
         size_t saved_size;
+        uint16_t class;
         int r;
 
         assert(p);
@@ -586,7 +587,8 @@ int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start)
         if (r < 0)
                 goto fail;
 
-        r = dns_packet_append_uint16(p, k->class, NULL);
+        class = flags & DNS_ANSWER_CACHE_FLUSH ? k->class | MDNS_RR_CACHE_FLUSH : k->class;
+        r = dns_packet_append_uint16(p, class, NULL);
         if (r < 0)
                 goto fail;
 
@@ -791,7 +793,7 @@ int dns_packet_truncate_opt(DnsPacket *p) {
         return 1;
 }
 
-int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start, size_t *rdata_start) {
+int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, const DnsAnswerFlags flags, size_t *start, size_t *rdata_start) {
 
         size_t saved_size, rdlength_offset, end, rdlength, rds;
         int r;
@@ -801,7 +803,7 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *star
 
         saved_size = p->size;
 
-        r = dns_packet_append_key(p, rr->key, NULL);
+        r = dns_packet_append_key(p, rr->key, flags, NULL);
         if (r < 0)
                 goto fail;
 
@@ -1143,7 +1145,7 @@ int dns_packet_append_question(DnsPacket *p, DnsQuestion *q) {
         assert(p);
 
         DNS_QUESTION_FOREACH(key, q) {
-                r = dns_packet_append_key(p, key, NULL);
+                r = dns_packet_append_key(p, key, 0, NULL);
                 if (r < 0)
                         return r;
         }
@@ -1153,12 +1155,13 @@ int dns_packet_append_question(DnsPacket *p, DnsQuestion *q) {
 
 int dns_packet_append_answer(DnsPacket *p, DnsAnswer *a) {
         DnsResourceRecord *rr;
+        DnsAnswerFlags flags;
         int r;
 
         assert(p);
 
-        DNS_ANSWER_FOREACH(rr, a) {
-                r = dns_packet_append_rr(p, rr, NULL, NULL);
+        DNS_ANSWER_FOREACH_FLAGS(rr, flags, a) {
+                r = dns_packet_append_rr(p, rr, flags, NULL, NULL);
                 if (r < 0)
                         return r;
         }
index 054dc88a85eeac796e4a7014bfd3755d4485923d..2c92392e4d78ee93dfcb5cceeb4e672a0f4dbc8b 100644 (file)
@@ -209,8 +209,8 @@ int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start);
 int dns_packet_append_raw_string(DnsPacket *p, const void *s, size_t size, size_t *start);
 int dns_packet_append_label(DnsPacket *p, const char *s, size_t l, bool canonical_candidate, size_t *start);
 int dns_packet_append_name(DnsPacket *p, const char *name, bool allow_compression, bool canonical_candidate, size_t *start);
-int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *key, size_t *start);
-int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start, size_t *rdata_start);
+int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *key, const DnsAnswerFlags flags, size_t *start);
+int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, const DnsAnswerFlags flags, size_t *start, size_t *rdata_start);
 int dns_packet_append_opt(DnsPacket *p, uint16_t max_udp_size, bool edns0_do, int rcode, size_t *start);
 int dns_packet_append_question(DnsPacket *p, DnsQuestion *q);
 int dns_packet_append_answer(DnsPacket *p, DnsAnswer *a);
index 209d565033c503a405843804d0b6b1780f84a554..e8c05ed0daf985f07ad799f2f631cf0f95773ca9 100644 (file)
@@ -1262,7 +1262,7 @@ int dns_resource_record_to_wire_format(DnsResourceRecord *rr, bool canonical) {
         if (rr->wire_format && rr->wire_format_canonical == canonical)
                 return 0;
 
-        r = dns_packet_append_rr(&packet, rr, &start, &rds);
+        r = dns_packet_append_rr(&packet, rr, 0, &start, &rds);
         if (r < 0)
                 return r;
 
index 6616bc4e0e54b9c98b9bae5c7921a7427917a657..b47cb7979519a23ed00dafaa8152ed99fd370cbd 100644 (file)
@@ -847,11 +847,11 @@ static int dns_scope_make_conflict_packet(
         DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
         DNS_PACKET_HEADER(p)->arcount = htobe16(1);
 
-        r = dns_packet_append_key(p, rr->key, NULL);
+        r = dns_packet_append_key(p, rr->key, 0, NULL);
         if (r < 0)
                 return r;
 
-        r = dns_packet_append_rr(p, rr, NULL, NULL);
+        r = dns_packet_append_rr(p, rr, 0, NULL, NULL);
         if (r < 0)
                 return r;
 
@@ -1086,12 +1086,12 @@ void dns_scope_announce(DnsScope *scope) {
 
         answer = dns_answer_new(4);
         LIST_FOREACH(addresses, a, scope->link->addresses) {
-                r = dns_answer_add(answer, a->mdns_address_rr, 0);
+                r = dns_answer_add(answer, a->mdns_address_rr, 0, DNS_ANSWER_CACHE_FLUSH);
                 if (r < 0) {
                         log_debug_errno(r, "Failed to add address RR to answer: %m");
                         return;
                 }
-                r = dns_answer_add(answer, a->mdns_ptr_rr, 0);
+                r = dns_answer_add(answer, a->mdns_ptr_rr, 0, DNS_ANSWER_CACHE_FLUSH);
                 if (r < 0) {
                         log_debug_errno(r, "Failed to add PTR RR to answer: %m");
                         return;
index e76de6c06a3a8939f8aead67ca13ac69d05e4d80..932e5b58a23f83c903908cdb34625b622009f550 100644 (file)
@@ -86,7 +86,7 @@ static int dns_stub_make_reply_packet(
 
                 continue;
         add:
-                r = dns_packet_append_rr(p, rr, NULL, NULL);
+                r = dns_packet_append_rr(p, rr, 0, NULL, NULL);
                 if (r < 0)
                         return r;
 
index bd36e5e1a1ad1a229459c9801d96ff13f3d17d1b..672f0e4cb2b03f32cbe116832d44fb89da2b879c 100644 (file)
@@ -1369,7 +1369,7 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
         if (r < 0)
                 return r;
 
-        r = dns_packet_append_key(p, t->key, NULL);
+        r = dns_packet_append_key(p, t->key, 0, NULL);
         if (r < 0)
                 return r;
 
@@ -1401,7 +1401,7 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
                 if (qdcount >= UINT16_MAX)
                         break;
 
-                r = dns_packet_append_key(p, other->key, NULL);
+                r = dns_packet_append_key(p, other->key, 0, NULL);
 
                 /*
                  * If we can't stuff more questions into the packet, just give up.
@@ -1470,7 +1470,7 @@ static int dns_transaction_make_packet(DnsTransaction *t) {
         if (r < 0)
                 return r;
 
-        r = dns_packet_append_key(p, t->key, NULL);
+        r = dns_packet_append_key(p, t->key, 0, NULL);
         if (r < 0)
                 return r;