From 4e5bf5e15899de3f9d11c2ddfe9721d9f8b07a37 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Fri, 10 Jul 2015 20:44:46 -0400 Subject: resolved: add packet header details for mDNS Validate mDNS queries and responses by looking at some header fields, add mDNS flags. --- src/resolve/resolved-dns-packet.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'src/resolve/resolved-dns-packet.c') diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index ea776f7916..3a4482a1b7 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -88,6 +88,16 @@ int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu, bool 0 /* ad */, 0 /* cd */, 0 /* rcode */)); + else if (protocol == DNS_PROTOCOL_MDNS) + h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */, + 0 /* opcode */, + 0 /* aa */, + 0 /* tc */, + 0 /* rd (ask for recursion) */, + 0 /* ra */, + 0 /* ad */, + 0 /* cd */, + 0 /* rcode */)); else h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */, 0 /* opcode */, @@ -182,6 +192,13 @@ int dns_packet_validate_reply(DnsPacket *p) { break; + case DNS_PROTOCOL_MDNS: + /* RFC 6762, Section 18 */ + if (DNS_PACKET_RCODE(p) != 0) + return -EBADMSG; + + break; + default: break; } @@ -223,6 +240,18 @@ int dns_packet_validate_query(DnsPacket *p) { break; + case DNS_PROTOCOL_MDNS: + /* RFC 6762, Section 18 */ + if (DNS_PACKET_AA(p) != 0 || + DNS_PACKET_RD(p) != 0 || + DNS_PACKET_RA(p) != 0 || + DNS_PACKET_AD(p) != 0 || + DNS_PACKET_CD(p) != 0 || + DNS_PACKET_RCODE(p) != 0) + return -EBADMSG; + + break; + default: break; } -- cgit v1.2.3-54-g00ecf From 23502de3b0891455c8ce499a9eb61b69d060a829 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 24 Nov 2015 15:45:15 +0100 Subject: resolved: add cache flush flag to DnsResourceKey MDNS has a 'key cache flush' flag for records which must be masked out for the parsers to do our right thing. We will also use that flag later (in a different patch) in order to alter the cache behavior. --- src/resolve/resolved-dns-packet.c | 12 ++++++++++++ src/resolve/resolved-dns-rr.h | 4 ++++ 2 files changed, 16 insertions(+) (limited to 'src/resolve/resolved-dns-packet.c') diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 3a4482a1b7..35d1fb02be 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -1421,6 +1421,7 @@ fail: int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) { _cleanup_free_ char *name = NULL; + bool cache_flush = false; uint16_t class, type; DnsResourceKey *key; size_t saved_rindex; @@ -1443,12 +1444,23 @@ int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) { if (r < 0) goto fail; + if (p->protocol == DNS_PROTOCOL_MDNS) { + /* See RFC6762, Section 10.2 */ + + if (class & MDNS_RR_CACHE_FLUSH) { + class &= ~MDNS_RR_CACHE_FLUSH; + cache_flush = true; + } + } + key = dns_resource_key_new_consume(class, type, name); if (!key) { r = -ENOMEM; goto fail; } + key->cache_flush = cache_flush; + name = NULL; *ret = key; diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h index b82fa77562..5cbb927681 100644 --- a/src/resolve/resolved-dns-rr.h +++ b/src/resolve/resolved-dns-rr.h @@ -45,6 +45,9 @@ enum { #define DNSKEY_FLAG_ZONE_KEY (UINT16_C(1) << 8) #define DNSKEY_FLAG_SEP (UINT16_C(1) << 0) +/* mDNS RR flags */ +#define MDNS_RR_CACHE_FLUSH (UINT16_C(1) << 15) + /* DNSSEC algorithm identifiers, see * http://tools.ietf.org/html/rfc4034#appendix-A.1 and * https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */ @@ -76,6 +79,7 @@ struct DnsResourceKey { unsigned n_ref; uint16_t class, type; char *_name; /* don't access directy, use DNS_RESOURCE_KEY_NAME()! */ + bool cache_flush:1; }; /* Creates a temporary resource key. This is only useful to quickly -- cgit v1.2.3-54-g00ecf From d84e543d927926fbcc6a5eec730b4db97d9272c7 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 1 Sep 2015 17:17:27 +0200 Subject: resolved: allow name compression in NSEC records --- src/resolve/resolved-dns-packet.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/resolve/resolved-dns-packet.c') diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 35d1fb02be..9bd08eeec2 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -1819,8 +1819,16 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { break; - case DNS_TYPE_NSEC: - r = dns_packet_read_name(p, &rr->nsec.next_domain_name, false, NULL); + case DNS_TYPE_NSEC: { + + /* + * RFC6762, section 18.14 explicly states mDNS should use name compression. + * This contradicts RFC3845, section 2.1.1 + */ + + bool allow_compressed = p->protocol == DNS_PROTOCOL_MDNS; + + r = dns_packet_read_name(p, &rr->nsec.next_domain_name, allow_compressed, NULL); if (r < 0) goto fail; @@ -1833,7 +1841,7 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { * without the NSEC bit set. */ break; - + } case DNS_TYPE_NSEC3: { uint8_t size; -- cgit v1.2.3-54-g00ecf