X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fresolve%2Fresolved-manager.c;h=5061d39c4630b6ac9f1994adc492e708182eef53;hb=edc501d4674dadc304d45a7e1c5b69e207eb8cd4;hp=ba2380d68287dd9c1df085fef52b40cecb6f6015;hpb=5cb36f41f01cf4b1f4395abfffd1b33116591e58;p=elogind.git diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index ba2380d68..5061d39c4 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -359,7 +359,6 @@ static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, voi } static int manager_watch_hostname(Manager *m) { - _cleanup_free_ char *h = NULL; int r; assert(m); @@ -393,6 +392,63 @@ static int manager_watch_hostname(Manager *m) { return 0; } +static void manager_llmnr_stop(Manager *m) { + assert(m); + + m->llmnr_ipv4_udp_event_source = sd_event_source_unref(m->llmnr_ipv4_udp_event_source); + m->llmnr_ipv4_udp_fd = safe_close(m->llmnr_ipv4_udp_fd); + + m->llmnr_ipv6_udp_event_source = sd_event_source_unref(m->llmnr_ipv6_udp_event_source); + m->llmnr_ipv6_udp_fd = safe_close(m->llmnr_ipv6_udp_fd); + + m->llmnr_ipv4_tcp_event_source = sd_event_source_unref(m->llmnr_ipv4_tcp_event_source); + m->llmnr_ipv4_tcp_fd = safe_close(m->llmnr_ipv4_tcp_fd); + + m->llmnr_ipv6_tcp_event_source = sd_event_source_unref(m->llmnr_ipv6_tcp_event_source); + m->llmnr_ipv6_tcp_fd = safe_close(m->llmnr_ipv6_tcp_fd); +} + +static int manager_llmnr_start(Manager *m) { + int r; + + assert(m); + + if (m->llmnr_support == SUPPORT_NO) + return 0; + + r = manager_llmnr_ipv4_udp_fd(m); + if (r == -EADDRINUSE) + goto eaddrinuse; + if (r < 0) + return r; + + r = manager_llmnr_ipv6_udp_fd(m); + if (r == -EADDRINUSE) + goto eaddrinuse; + if (r < 0) + return r; + + r = manager_llmnr_ipv4_tcp_fd(m); + if (r == -EADDRINUSE) + goto eaddrinuse; + if (r < 0) + return r; + + r = manager_llmnr_ipv6_tcp_fd(m); + if (r == -EADDRINUSE) + goto eaddrinuse; + if (r < 0) + return r; + + return 0; + +eaddrinuse: + log_warning("There appears to be another LLMNR respondering running. Turning off LLMNR support."); + m->llmnr_support = SUPPORT_NO; + manager_llmnr_stop(m); + return 0; +} + int manager_new(Manager **ret) { _cleanup_(manager_freep) Manager *m = NULL; int r; @@ -444,25 +500,24 @@ int manager_new(Manager **ret) { if (r < 0) return r; - r = manager_llmnr_ipv4_udp_fd(m); - if (r < 0) - return r; - r = manager_llmnr_ipv6_udp_fd(m); - if (r < 0) - return r; - r = manager_llmnr_ipv4_tcp_fd(m); - if (r < 0) - return r; - r = manager_llmnr_ipv6_tcp_fd(m); - if (r < 0) - return r; - *ret = m; m = NULL; return 0; } +int manager_start(Manager *m) { + int r; + + assert(m); + + r = manager_llmnr_start(m); + if (r < 0) + return r; + + return 0; +} + Manager *manager_free(Manager *m) { Link *l; @@ -493,15 +548,7 @@ Manager *manager_free(Manager *m) { safe_close(m->dns_ipv4_fd); safe_close(m->dns_ipv6_fd); - sd_event_source_unref(m->llmnr_ipv4_udp_event_source); - sd_event_source_unref(m->llmnr_ipv6_udp_event_source); - safe_close(m->llmnr_ipv4_udp_fd); - safe_close(m->llmnr_ipv6_udp_fd); - - sd_event_source_unref(m->llmnr_ipv4_tcp_event_source); - sd_event_source_unref(m->llmnr_ipv6_tcp_event_source); - safe_close(m->llmnr_ipv4_tcp_fd); - safe_close(m->llmnr_ipv6_tcp_fd); + manager_llmnr_stop(m); sd_event_source_unref(m->bus_retry_event_source); sd_bus_unref(m->bus); @@ -1053,7 +1100,7 @@ int manager_send(Manager *m, int fd, int ifindex, int family, const union in_add return -EAFNOSUPPORT; } -bool manager_known_dns_server(Manager *m, int family, const union in_addr_union *in_addr) { +DnsServer* manager_find_dns_server(Manager *m, int family, const union in_addr_union *in_addr) { DnsServer *s; assert(m); @@ -1061,16 +1108,16 @@ bool manager_known_dns_server(Manager *m, int family, const union in_addr_union LIST_FOREACH(servers, s, m->dns_servers) if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0) - return true; + return s; LIST_FOREACH(servers, s, m->fallback_dns_servers) if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0) - return true; + return s; - return false; + return NULL; } -static DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) { +DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) { assert(m); if (m->current_dns_server == s) @@ -1081,10 +1128,13 @@ static DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) { in_addr_to_string(s->family, &s->address, &ip); log_info("Switching to system DNS server %s.", strna(ip)); - } else - log_info("No system DNS server set."); + } m->current_dns_server = s; + + if (m->unicast_scope) + dns_cache_flush(&m->unicast_scope->cache); + return s; }