From: Daniel Mack Date: Sat, 11 Jul 2015 00:44:59 +0000 (-0400) Subject: resolved: add mDNS packet dispatcher X-Git-Tag: v229~226^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=124602aea81a27dda02e898798a18f95bf03734e;p=thirdparty%2Fsystemd.git resolved: add mDNS packet dispatcher Add the packet dispatching routine for mDNS. It differs to what LLMNR and DNS dispatchers do in the way it matches incoming packets. In mDNS, we actually handle all incoming packets, regardless whether we asked for them earlier or not. --- diff --git a/src/resolve/resolved-mdns.c b/src/resolve/resolved-mdns.c index 6767706f6e2..096a4b1fe55 100644 --- a/src/resolve/resolved-mdns.c +++ b/src/resolve/resolved-mdns.c @@ -70,7 +70,64 @@ eaddrinuse: } static int on_mdns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) { - /* TODO */ + _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL; + Manager *m = userdata; + DnsScope *scope; + int r; + + r = manager_recv(m, fd, DNS_PROTOCOL_MDNS, &p); + if (r <= 0) + return r; + + scope = manager_find_scope(m, p); + if (!scope) { + log_warning("Got mDNS UDP packet on unknown scope. Ignoring."); + return 0; + } + + if (dns_packet_validate_reply(p) > 0) { + unsigned i; + + log_debug("Got mDNS reply packet"); + + /* + * mDNS is different from regular DNS and LLMNR with regard to handling responses. + * While on other protocols, we can ignore every answer that doesn't match a question + * we broadcast earlier, RFC6762, section 18.1 recommends looking at and caching all + * incoming information, regardless of the DNS packet ID. + * + * Hence, extract the packet here, and try to find a transaction for answer the we got + * and complete it. Also store the new information in scope's cache. + */ + r = dns_packet_extract(p); + if (r < 0) { + log_debug("mDNS packet extraction failed."); + return 0; + } + + dns_scope_check_conflicts(scope, p); + + for (i = 0; i < p->answer->n_rrs; i++) { + DnsResourceRecord *rr; + DnsTransaction *t; + + rr = p->answer->items[i].rr; + + t = dns_scope_find_transaction(scope, rr->key, false); + if (t) + dns_transaction_process_reply(t, p); + } + + dns_cache_put(&scope->cache, NULL, DNS_PACKET_RCODE(p), p->answer, + p->answer->n_rrs, false, 0, p->family, &p->sender); + + } else if (dns_packet_validate_query(p) > 0) { + log_debug("Got mDNS query packet for id %u", DNS_PACKET_ID(p)); + + dns_scope_process_query(scope, NULL, p); + } else + log_debug("Invalid mDNS UDP packet."); + return 0; }