diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/resolve/resolved-manager.c | 92 | ||||
-rw-r--r-- | src/resolve/resolved-manager.h | 1 | ||||
-rw-r--r-- | src/resolve/resolved.c | 6 |
3 files changed, 77 insertions, 22 deletions
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 1b6dc8a4a3..5061d39c46 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -392,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; @@ -443,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; @@ -492,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); diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h index 31d670da44..1fd4be41a4 100644 --- a/src/resolve/resolved-manager.h +++ b/src/resolve/resolved-manager.h @@ -114,6 +114,7 @@ struct Manager { int manager_new(Manager **ret); Manager* manager_free(Manager *m); +int manager_start(Manager *m); int manager_read_resolv_conf(Manager *m); int manager_write_resolv_conf(Manager *m); diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c index 900a36d8f0..892bb51386 100644 --- a/src/resolve/resolved.c +++ b/src/resolve/resolved.c @@ -75,6 +75,12 @@ int main(int argc, char *argv[]) { if (r < 0) log_warning("Failed to parse configuration file: %s", strerror(-r)); + r = manager_start(m); + if (r < 0) { + log_error("Failed to start manager: %s", strerror(-r)); + goto finish; + } + /* Write finish default resolv.conf to avoid a dangling * symlink */ r = manager_write_resolv_conf(m); |