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>
This commit is contained in:
Dmitry Rozhkov 2016-12-05 17:12:15 +02:00
parent d37baf4016
commit 3b991089c3
3 changed files with 53 additions and 2 deletions

View 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,

View 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);

View 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.");