summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Rozhkov <dmitry.rozhkov@linux.intel.com>2016-12-05 17:12:15 +0200
committerDmitry Rozhkov <dmitry.rozhkov@linux.intel.com>2017-01-19 11:51:21 +0200
commit3b991089c389d8ac969ce77f2606f996f3f411d0 (patch)
tree32a177dece3aaf8c44ef5f54bde70e394d89af2a
parentd37baf4016b92cf0aee7dcef77446f73a2ed47e9 (diff)
downloadsystemd-3b991089c389d8ac969ce77f2606f996f3f411d0.tar.gz
resolved: process mDNS queries
This way other hosts can resolve our hostname to its address using mDNS. Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
-rw-r--r--src/resolve/resolved-dns-scope.c2
-rw-r--r--src/resolve/resolved-dns-scope.h1
-rw-r--r--src/resolve/resolved-mdns.c52
3 files changed, 53 insertions, 2 deletions
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.");