summaryrefslogtreecommitdiff
path: root/src/resolve/resolved-manager.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-08-04 19:48:03 +0200
committerLennart Poettering <lennart@poettering.net>2014-08-04 19:48:03 +0200
commitedc501d4674dadc304d45a7e1c5b69e207eb8cd4 (patch)
treeaf6a11f1a59a2d5802db6052a2483284328ee201 /src/resolve/resolved-manager.c
parent4f758c23981342f1fb838f4b2630812eb89a3faa (diff)
resolved: when there's already somebody listening on the LLMNR ports, simple disable LLMNR and warn, but continue
This allows us to run resolved inside an nspawn container that shares the network namespace with the host, if there's already an instance running.
Diffstat (limited to 'src/resolve/resolved-manager.c')
-rw-r--r--src/resolve/resolved-manager.c92
1 files changed, 70 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);