]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: process mDNS queries
authorDmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
Mon, 5 Dec 2016 15:12:15 +0000 (17:12 +0200)
committerDmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
Thu, 19 Jan 2017 09:51:21 +0000 (11:51 +0200)
This way other hosts can resolve our hostname to its address
using mDNS.

Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
src/resolve/resolved-dns-scope.c
src/resolve/resolved-dns-scope.h
src/resolve/resolved-mdns.c

index 92171107dfd162b1ebfd37ffb936dcd789571fd8..2c23a0df7718a1aca88dcab014fcf28137da2f40 100644 (file)
@@ -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,
index 01a83a76b2cc61c952395b8a31d4564a688e43d7..d501835e459af3cae648f720aff857daf5f4a7dc 100644 (file)
@@ -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);
index 48ec17f4b5eb5ad76f93f17d176d14ea442b9346..f5cae6f68293452aafa4536ce116e555a9293136 100644 (file)
@@ -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.");