]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: add dns_cache_export_to_packet() 2122/head
authorDaniel Mack <daniel@zonque.org>
Mon, 30 Nov 2015 23:53:42 +0000 (00:53 +0100)
committerDaniel Mack <daniel@zonque.org>
Tue, 8 Dec 2015 15:51:41 +0000 (16:51 +0100)
This new functions exports cached records of type PTR, SRV and TXT into
an existing DnsPacket. This is used in order to fill in known records
to mDNS queries, for known answer supression.

src/resolve/resolved-dns-cache.c
src/resolve/resolved-dns-cache.h
src/resolve/resolved-dns-rr.h
src/resolve/resolved-dns-transaction.c

index 2179a61890683eb0b9aa2469711a45194b414f99..6124ff659c9679ce74e2336089d7dac1422a1b58 100644 (file)
@@ -731,6 +731,39 @@ int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_
         return 1;
 }
 
+int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p) {
+        unsigned ancount = 0;
+        Iterator iterator;
+        DnsCacheItem *i;
+        int r;
+
+        assert(cache);
+
+        HASHMAP_FOREACH(i, cache->by_key, iterator) {
+                DnsCacheItem *j;
+
+                LIST_FOREACH(by_key, j, i) {
+                        _cleanup_free_ char *t = NULL;
+
+                        if (!j->rr)
+                                continue;
+
+                        if (!dns_key_is_shared(j->rr->key))
+                                continue;
+
+                        r = dns_packet_append_rr(p, j->rr, NULL, NULL);
+                        if (r < 0)
+                                return r;
+
+                        ancount ++;
+                }
+        }
+
+        DNS_PACKET_HEADER(p)->ancount = htobe16(ancount);
+
+        return 0;
+}
+
 void dns_cache_dump(DnsCache *cache, FILE *f) {
         Iterator iterator;
         DnsCacheItem *i;
index 5f9116478585e34daa6114360f38bd1541b126ed..0f28bbe543ba581942d610b1937aabf3ec15e443 100644 (file)
@@ -32,6 +32,7 @@ typedef struct DnsCache {
 } DnsCache;
 
 #include "resolved-dns-answer.h"
+#include "resolved-dns-packet.h"
 #include "resolved-dns-question.h"
 #include "resolved-dns-rr.h"
 
@@ -45,3 +46,5 @@ int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_
 
 void dns_cache_dump(DnsCache *cache, FILE *f);
 bool dns_cache_is_empty(DnsCache *cache);
+
+int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p);
index 5cbb927681f39217abf85d4b84603ab117303ef6..5c2306ba96ae97b18f3510819da017e93b6e85f4 100644 (file)
@@ -250,6 +250,10 @@ int dns_resource_key_match_cname(const DnsResourceKey *key, const DnsResourceRec
 int dns_resource_key_to_string(const DnsResourceKey *key, char **ret);
 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceKey*, dns_resource_key_unref);
 
+static inline bool dns_key_is_shared(const DnsResourceKey *key) {
+        return IN_SET(key->type, DNS_TYPE_PTR);
+}
+
 DnsResourceRecord* dns_resource_record_new(DnsResourceKey *key);
 DnsResourceRecord* dns_resource_record_new_full(uint16_t class, uint16_t type, const char *name);
 DnsResourceRecord* dns_resource_record_ref(DnsResourceRecord *rr);
index dccb8000a23f00e9c203040d31079628cefa8833..90f07e6c4b9f6a6fb773c58f7b3398c42dfe8342 100644 (file)
@@ -24,6 +24,7 @@
 #include "dns-domain.h"
 #include "fd-util.h"
 #include "random-util.h"
+#include "resolved-dns-cache.h"
 #include "resolved-dns-transaction.h"
 #include "resolved-llmnr.h"
 #include "string-table.h"
@@ -733,6 +734,7 @@ static int dns_transaction_prepare_next_attempt(DnsTransaction *t, usec_t ts) {
 static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
 
         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+        bool add_known_answers = false;
         DnsTransaction *other;
         unsigned qdcount;
         usec_t ts;
@@ -754,6 +756,9 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
 
         qdcount = 1;
 
+        if (dns_key_is_shared(t->key))
+                add_known_answers = true;
+
         /*
          * 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
@@ -808,11 +813,21 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
                 other->next_attempt_after = ts;
 
                 qdcount ++;
+
+                if (dns_key_is_shared(other->key))
+                        add_known_answers = true;
         }
 
         DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount);
         DNS_PACKET_HEADER(p)->id = t->id;
 
+        /* Append known answer section if we're asking for any shared record */
+        if (add_known_answers) {
+                r = dns_cache_export_shared_to_packet(&t->scope->cache, p);
+                if (r < 0)
+                        return r;
+        }
+
         t->sent = p;
         p = NULL;