}
static int manager_watch_hostname(Manager *m) {
- _cleanup_free_ char *h = NULL;
int r;
assert(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;
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;
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);
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);
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)
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;
}