resolved: populate mDNS scopes' zones with RRs for the host

Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
This commit is contained in:
Dmitry Rozhkov 2016-12-02 11:58:00 +02:00
parent 3755027c2c
commit 400cb36ec6
5 changed files with 134 additions and 0 deletions

View File

@ -37,6 +37,9 @@ typedef enum DnsZoneItemState DnsZoneItemState;
/* RFC 4795 Section 2.8. suggests a TTL of 30s by default */
#define LLMNR_DEFAULT_TTL (30)
/* RFC 6762 Section 10. suggests a TTL of 120s by default */
#define MDNS_DEFAULT_TTL (120)
enum DnsZoneItemState {
DNS_ZONE_ITEM_PROBING,
DNS_ZONE_ITEM_ESTABLISHED,

View File

@ -692,10 +692,26 @@ LinkAddress *link_address_free(LinkAddress *a) {
else if (a->family == AF_INET6 && a->link->llmnr_ipv6_scope)
dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_ptr_rr);
}
if (a->mdns_address_rr) {
if (a->family == AF_INET && a->link->mdns_ipv4_scope)
dns_zone_remove_rr(&a->link->mdns_ipv4_scope->zone, a->mdns_address_rr);
else if (a->family == AF_INET6 && a->link->mdns_ipv6_scope)
dns_zone_remove_rr(&a->link->mdns_ipv6_scope->zone, a->mdns_address_rr);
}
if (a->mdns_ptr_rr) {
if (a->family == AF_INET && a->link->mdns_ipv4_scope)
dns_zone_remove_rr(&a->link->mdns_ipv4_scope->zone, a->mdns_ptr_rr);
else if (a->family == AF_INET6 && a->link->mdns_ipv6_scope)
dns_zone_remove_rr(&a->link->mdns_ipv6_scope->zone, a->mdns_ptr_rr);
}
}
dns_resource_record_unref(a->llmnr_address_rr);
dns_resource_record_unref(a->llmnr_ptr_rr);
dns_resource_record_unref(a->mdns_address_rr);
dns_resource_record_unref(a->mdns_ptr_rr);
return mfree(a);
}
@ -760,6 +776,59 @@ void link_address_add_rrs(LinkAddress *a, bool force_remove) {
a->llmnr_ptr_rr = dns_resource_record_unref(a->llmnr_ptr_rr);
}
}
if (!force_remove &&
link_address_relevant(a, true) &&
a->link->mdns_ipv4_scope &&
a->link->mdns_support == RESOLVE_SUPPORT_YES &&
a->link->manager->mdns_support == RESOLVE_SUPPORT_YES) {
if (!a->link->manager->mdns_host_ipv4_key) {
a->link->manager->mdns_host_ipv4_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, a->link->manager->mdns_hostname);
if (!a->link->manager->mdns_host_ipv4_key) {
r = -ENOMEM;
goto fail;
}
}
if (!a->mdns_address_rr) {
a->mdns_address_rr = dns_resource_record_new(a->link->manager->mdns_host_ipv4_key);
if (!a->mdns_address_rr) {
r = -ENOMEM;
goto fail;
}
a->mdns_address_rr->a.in_addr = a->in_addr.in;
a->mdns_address_rr->ttl = MDNS_DEFAULT_TTL;
}
if (!a->mdns_ptr_rr) {
r = dns_resource_record_new_reverse(&a->mdns_ptr_rr, a->family, &a->in_addr, a->link->manager->mdns_hostname);
if (r < 0)
goto fail;
a->mdns_ptr_rr->ttl = MDNS_DEFAULT_TTL;
}
r = dns_zone_put(&a->link->mdns_ipv4_scope->zone, a->link->mdns_ipv4_scope, a->mdns_address_rr, true);
if (r < 0)
log_warning_errno(r, "Failed to add A record to MDNS zone: %m");
r = dns_zone_put(&a->link->mdns_ipv4_scope->zone, a->link->mdns_ipv4_scope, a->mdns_ptr_rr, false);
if (r < 0)
log_warning_errno(r, "Failed to add IPv4 PTR record to MDNS zone: %m");
} else {
if (a->mdns_address_rr) {
if (a->link->mdns_ipv4_scope)
dns_zone_remove_rr(&a->link->mdns_ipv4_scope->zone, a->mdns_address_rr);
a->mdns_address_rr = dns_resource_record_unref(a->mdns_address_rr);
}
if (a->mdns_ptr_rr) {
if (a->link->mdns_ipv4_scope)
dns_zone_remove_rr(&a->link->mdns_ipv4_scope->zone, a->mdns_ptr_rr);
a->mdns_ptr_rr = dns_resource_record_unref(a->mdns_ptr_rr);
}
}
}
if (a->family == AF_INET6) {
@ -817,6 +886,60 @@ void link_address_add_rrs(LinkAddress *a, bool force_remove) {
a->llmnr_ptr_rr = dns_resource_record_unref(a->llmnr_ptr_rr);
}
}
if (!force_remove &&
link_address_relevant(a, true) &&
a->link->mdns_ipv6_scope &&
a->link->mdns_support == RESOLVE_SUPPORT_YES &&
a->link->manager->mdns_support == RESOLVE_SUPPORT_YES) {
if (!a->link->manager->mdns_host_ipv6_key) {
a->link->manager->mdns_host_ipv6_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, a->link->manager->mdns_hostname);
if (!a->link->manager->mdns_host_ipv6_key) {
r = -ENOMEM;
goto fail;
}
}
if (!a->mdns_address_rr) {
a->mdns_address_rr = dns_resource_record_new(a->link->manager->mdns_host_ipv6_key);
if (!a->mdns_address_rr) {
r = -ENOMEM;
goto fail;
}
a->mdns_address_rr->aaaa.in6_addr = a->in_addr.in6;
a->mdns_address_rr->ttl = MDNS_DEFAULT_TTL;
}
if (!a->mdns_ptr_rr) {
r = dns_resource_record_new_reverse(&a->mdns_ptr_rr, a->family, &a->in_addr, a->link->manager->mdns_hostname);
if (r < 0)
goto fail;
a->mdns_ptr_rr->ttl = MDNS_DEFAULT_TTL;
}
r = dns_zone_put(&a->link->mdns_ipv6_scope->zone, a->link->mdns_ipv6_scope, a->mdns_address_rr, true);
if (r < 0)
log_warning_errno(r, "Failed to add AAAA record to MDNS zone: %m");
r = dns_zone_put(&a->link->mdns_ipv6_scope->zone, a->link->mdns_ipv6_scope, a->mdns_ptr_rr, false);
if (r < 0)
log_warning_errno(r, "Failed to add IPv6 PTR record to MDNS zone: %m");
} else {
if (a->mdns_address_rr) {
if (a->link->mdns_ipv6_scope)
dns_zone_remove_rr(&a->link->mdns_ipv6_scope->zone, a->mdns_address_rr);
a->mdns_address_rr = dns_resource_record_unref(a->mdns_address_rr);
}
if (a->mdns_ptr_rr) {
if (a->link->mdns_ipv6_scope)
dns_zone_remove_rr(&a->link->mdns_ipv6_scope->zone, a->mdns_ptr_rr);
a->mdns_ptr_rr = dns_resource_record_unref(a->mdns_ptr_rr);
}
}
}
return;

View File

@ -47,6 +47,8 @@ struct LinkAddress {
DnsResourceRecord *llmnr_address_rr;
DnsResourceRecord *llmnr_ptr_rr;
DnsResourceRecord *mdns_address_rr;
DnsResourceRecord *mdns_ptr_rr;
LIST_FIELDS(LinkAddress, addresses);
};

View File

@ -621,6 +621,8 @@ Manager *manager_free(Manager *m) {
dns_resource_key_unref(m->llmnr_host_ipv4_key);
dns_resource_key_unref(m->llmnr_host_ipv6_key);
dns_resource_key_unref(m->mdns_host_ipv4_key);
dns_resource_key_unref(m->mdns_host_ipv6_key);
sd_event_source_unref(m->hostname_event_source);
safe_close(m->hostname_fd);
@ -1007,6 +1009,8 @@ void manager_refresh_rrs(Manager *m) {
m->llmnr_host_ipv4_key = dns_resource_key_unref(m->llmnr_host_ipv4_key);
m->llmnr_host_ipv6_key = dns_resource_key_unref(m->llmnr_host_ipv6_key);
m->mdns_host_ipv4_key = dns_resource_key_unref(m->mdns_host_ipv4_key);
m->mdns_host_ipv6_key = dns_resource_key_unref(m->mdns_host_ipv6_key);
HASHMAP_FOREACH(l, m->links, i) {
link_add_rrs(l, true);

View File

@ -113,6 +113,8 @@ struct Manager {
char *mdns_hostname;
DnsResourceKey *llmnr_host_ipv4_key;
DnsResourceKey *llmnr_host_ipv6_key;
DnsResourceKey *mdns_host_ipv4_key;
DnsResourceKey *mdns_host_ipv6_key;
/* Watch the system hostname */
int hostname_fd;