diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index 92171107df..2c23a0df77 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -609,7 +609,7 @@ int dns_scope_mdns_membership(DnsScope *s, bool b) { return dns_scope_multicast_membership(s, b, MDNS_MULTICAST_IPV4_ADDRESS, MDNS_MULTICAST_IPV6_ADDRESS); } -static int dns_scope_make_reply_packet( +int dns_scope_make_reply_packet( DnsScope *s, uint16_t id, int rcode, diff --git a/src/resolve/resolved-dns-scope.h b/src/resolve/resolved-dns-scope.h index 01a83a76b2..d501835e45 100644 --- a/src/resolve/resolved-dns-scope.h +++ b/src/resolve/resolved-dns-scope.h @@ -96,6 +96,7 @@ void dns_scope_next_dns_server(DnsScope *s); int dns_scope_llmnr_membership(DnsScope *s, bool b); int dns_scope_mdns_membership(DnsScope *s, bool b); +int dns_scope_make_reply_packet(DnsScope *s, uint16_t id, int rcode, DnsQuestion *q, DnsAnswer *answer, DnsAnswer *soa, bool tentative, DnsPacket **ret); void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p); DnsTransaction *dns_scope_find_transaction(DnsScope *scope, DnsResourceKey *key, bool cache_ok); diff --git a/src/resolve/resolved-mdns.c b/src/resolve/resolved-mdns.c index 48ec17f4b5..f5cae6f682 100644 --- a/src/resolve/resolved-mdns.c +++ b/src/resolve/resolved-mdns.c @@ -67,6 +67,52 @@ eaddrinuse: return 0; } +static int mdns_scope_process_query(DnsScope *s, DnsPacket *p) { + _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL; + _cleanup_(dns_packet_unrefp) DnsPacket *reply = NULL; + DnsResourceKey *key = NULL; + bool tentative = false; + int r; + + assert(s); + assert(p); + + r = dns_packet_extract(p); + if (r < 0) { + log_debug_errno(r, "Failed to extract resource records from incoming packet: %m"); + return r; + } + + /* TODO: there might be more than one question in mDNS queries. */ + assert_return((dns_question_size(p->question) > 0), -EINVAL); + key = p->question->keys[0]; + + r = dns_zone_lookup(&s->zone, key, 0, &answer, &soa, &tentative); + if (r < 0) { + log_debug_errno(r, "Failed to lookup key: %m"); + return r; + } + if (r == 0) + return 0; + + r = dns_scope_make_reply_packet(s, DNS_PACKET_ID(p), DNS_RCODE_SUCCESS, NULL, answer, NULL, false, &reply); + if (r < 0) { + log_debug_errno(r, "Failed to build reply packet: %m"); + return r; + } + + if (!ratelimit_test(&s->ratelimit)) + return 0; + + r = dns_scope_emit_udp(s, -1, reply); + if (r < 0) { + log_debug_errno(r, "Failed to send reply packet: %m"); + return r; + } + + return 0; +} + static int on_mdns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) { _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL; Manager *m = userdata; @@ -134,7 +180,11 @@ static int on_mdns_packet(sd_event_source *s, int fd, uint32_t revents, void *us } 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); + r = mdns_scope_process_query(scope, p); + if (r < 0) { + log_debug("mDNS query processing failed."); + return 0; + } } else log_debug("Invalid mDNS UDP packet.");