summaryrefslogtreecommitdiff
path: root/src/resolve/resolved-mdns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/resolve/resolved-mdns.c')
-rw-r--r--src/resolve/resolved-mdns.c59
1 files changed, 58 insertions, 1 deletions
diff --git a/src/resolve/resolved-mdns.c b/src/resolve/resolved-mdns.c
index 6767706f6e..096a4b1fe5 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;
}