diff options
author | Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com> | 2016-12-02 11:58:00 +0200 |
---|---|---|
committer | Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com> | 2017-01-19 11:51:21 +0200 |
commit | 400cb36ec67cf47c7f445c73c03a715405e8f601 (patch) | |
tree | 58a43719f84d3c814bdba4f4f8bd43c6e030e04e /src/resolve | |
parent | 3755027c2cada70345c96787a9b5569994dd23ed (diff) |
resolved: populate mDNS scopes' zones with RRs for the host
Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
Diffstat (limited to 'src/resolve')
-rw-r--r-- | src/resolve/resolved-dns-zone.h | 3 | ||||
-rw-r--r-- | src/resolve/resolved-link.c | 123 | ||||
-rw-r--r-- | src/resolve/resolved-link.h | 2 | ||||
-rw-r--r-- | src/resolve/resolved-manager.c | 4 | ||||
-rw-r--r-- | src/resolve/resolved-manager.h | 2 |
5 files changed, 134 insertions, 0 deletions
diff --git a/src/resolve/resolved-dns-zone.h b/src/resolve/resolved-dns-zone.h index a41df37e6b..545ec958fb 100644 --- a/src/resolve/resolved-dns-zone.h +++ b/src/resolve/resolved-dns-zone.h @@ -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, diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c index 4e38e88815..4d7447b507 100644 --- a/src/resolve/resolved-link.c +++ b/src/resolve/resolved-link.c @@ -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; diff --git a/src/resolve/resolved-link.h b/src/resolve/resolved-link.h index c9b2a58c34..1e9be8ae84 100644 --- a/src/resolve/resolved-link.h +++ b/src/resolve/resolved-link.h @@ -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); }; diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 0954641c20..97c1c2389d 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -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); diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h index 6b2208ed94..0b52ca594a 100644 --- a/src/resolve/resolved-manager.h +++ b/src/resolve/resolved-manager.h @@ -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; |