diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-12-18 19:32:46 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-12-18 19:40:47 +0100 |
commit | d2579eec5e1b845b2cf29caddc951dc22f2abb91 (patch) | |
tree | a79b2eedd458f8f93b0bec40a40490b4098e951d /src/resolve/resolved-dns-packet.c | |
parent | ea207b639a379b2a0bb8f2cafb0893e406c6152e (diff) |
resolved: rework mDNS cache-flush bit handling
This adds a new DnsAnswer item flag "DNS_ANSWER_SHARED_OWNER" which is
set for mDNS RRs that lack the cache-flush bit. The cache-flush bit is
removed from the DnsResourceRecord object in favour of this.
This also splits out the code that removes previous entries when adding
new positive ones into a new separate call dns_cache_remove_previous().
Diffstat (limited to 'src/resolve/resolved-dns-packet.c')
-rw-r--r-- | src/resolve/resolved-dns-packet.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 2b7d634a51..14faf9e4ab 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -1455,9 +1455,9 @@ fail: return r; } -int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) { +int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, bool *ret_cache_flush, size_t *start) { _cleanup_free_ char *name = NULL; - bool cache_flush = true; + bool cache_flush = false; uint16_t class, type; DnsResourceKey *key; size_t saved_rindex; @@ -1483,10 +1483,10 @@ int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) { if (p->protocol == DNS_PROTOCOL_MDNS) { /* See RFC6762, Section 10.2 */ - if (type != DNS_TYPE_OPT && (class & MDNS_RR_CACHE_FLUSH)) + if (type != DNS_TYPE_OPT && (class & MDNS_RR_CACHE_FLUSH)) { class &= ~MDNS_RR_CACHE_FLUSH; - else - cache_flush = false; + cache_flush = true; + } } key = dns_resource_key_new_consume(class, type, name); @@ -1495,11 +1495,11 @@ int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) { goto fail; } - key->cache_flush = cache_flush; - name = NULL; *ret = key; + if (ret_cache_flush) + *ret_cache_flush = cache_flush; if (start) *start = saved_rindex; @@ -1515,11 +1515,12 @@ static bool loc_size_ok(uint8_t size) { return m <= 9 && e <= 9 && (m > 0 || e == 0); } -int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { +int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_flush, size_t *start) { _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL; _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL; size_t saved_rindex, offset; uint16_t rdlength; + bool cache_flush; int r; assert(p); @@ -1527,7 +1528,7 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { saved_rindex = p->rindex; - r = dns_packet_read_key(p, &key, NULL); + r = dns_packet_read_key(p, &key, &cache_flush, NULL); if (r < 0) goto fail; @@ -1939,6 +1940,8 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { *ret = rr; rr = NULL; + if (ret_cache_flush) + *ret_cache_flush = cache_flush; if (start) *start = saved_rindex; @@ -1971,11 +1974,17 @@ int dns_packet_extract(DnsPacket *p) { for (i = 0; i < n; i++) { _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL; + bool cache_flush; - r = dns_packet_read_key(p, &key, NULL); + r = dns_packet_read_key(p, &key, &cache_flush, NULL); if (r < 0) goto finish; + if (cache_flush) { + r = -EBADMSG; + goto finish; + } + if (!dns_type_is_valid_query(key->type)) { r = -EBADMSG; goto finish; @@ -2034,7 +2043,8 @@ int dns_packet_extract(DnsPacket *p) { * sections. */ r = dns_answer_add(answer, rr, p->ifindex, - i < DNS_PACKET_ANCOUNT(p) ? DNS_ANSWER_CACHEABLE : 0); + (i < DNS_PACKET_ANCOUNT(p) ? DNS_ANSWER_CACHEABLE : 0) | + (p->protocol == DNS_PROTOCOL_MDNS && !cache_flush ? DNS_ANSWER_SHARED_OWNER : 0)); if (r < 0) goto finish; } |