From b7ac92cd43afe7bbde0d2155de6172f5fa255158 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 1 May 2018 15:58:42 +0900 Subject: [PATCH 1/5] resolve: expose CurrentDNSServer= property on Bus --- src/resolve/resolved-bus.c | 28 +++++++++++++++++++++++++++- src/resolve/resolved-link-bus.c | 20 ++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index fda43b84cf..bea0f2a06f 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -1219,7 +1219,13 @@ int bus_dns_server_append(sd_bus_message *reply, DnsServer *s, bool with_ifindex int r; assert(reply); - assert(s); + + if (!s) { + if (with_ifindex) + return sd_bus_message_append(reply, "(iiay)", 0, AF_UNSPEC, 0); + else + return sd_bus_message_append(reply, "(iay)", AF_UNSPEC, 0); + } r = sd_bus_message_open_container(reply, 'r', with_ifindex ? "iiay" : "iay"); if (r < 0) @@ -1293,6 +1299,25 @@ static int bus_property_get_dns_servers( return sd_bus_message_close_container(reply); } +static int bus_property_get_current_dns_server( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + DnsServer *s; + + assert(reply); + assert(userdata); + + s = *(DnsServer **) userdata; + + return bus_dns_server_append(reply, s, true); +} + static int bus_property_get_domains( sd_bus *bus, const char *path, @@ -1823,6 +1848,7 @@ static const sd_bus_vtable resolve_vtable[] = { SD_BUS_PROPERTY("LLMNR", "s", bus_property_get_resolve_support, offsetof(Manager, llmnr_support), 0), SD_BUS_PROPERTY("MulticastDNS", "s", bus_property_get_resolve_support, offsetof(Manager, mdns_support), 0), SD_BUS_PROPERTY("DNS", "a(iiay)", bus_property_get_dns_servers, 0, 0), + SD_BUS_PROPERTY("CurrentDNSServer", "(iiay)", bus_property_get_current_dns_server, offsetof(Manager, current_dns_server), 0), SD_BUS_PROPERTY("Domains", "a(isb)", bus_property_get_domains, 0, 0), SD_BUS_PROPERTY("TransactionStatistics", "(tt)", bus_property_get_transaction_statistics, 0, 0), SD_BUS_PROPERTY("CacheStatistics", "(ttt)", bus_property_get_cache_statistics, 0, 0), diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c index 8200765edb..ceaf71a71d 100644 --- a/src/resolve/resolved-link-bus.c +++ b/src/resolve/resolved-link-bus.c @@ -61,6 +61,25 @@ static int property_get_dns( return sd_bus_message_close_container(reply); } +static int property_get_current_dns_server( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + DnsServer *s; + + assert(reply); + assert(userdata); + + s = *(DnsServer **) userdata; + + return bus_dns_server_append(reply, s, false); +} + static int property_get_domains( sd_bus *bus, const char *path, @@ -516,6 +535,7 @@ const sd_bus_vtable link_vtable[] = { SD_BUS_PROPERTY("ScopesMask", "t", property_get_scopes_mask, 0, 0), SD_BUS_PROPERTY("DNS", "a(iay)", property_get_dns, 0, 0), + SD_BUS_PROPERTY("CurrentDNSServer", "(iay)", property_get_current_dns_server, offsetof(Link, current_dns_server), 0), SD_BUS_PROPERTY("Domains", "a(sb)", property_get_domains, 0, 0), SD_BUS_PROPERTY("LLMNR", "s", bus_property_get_resolve_support, offsetof(Link, llmnr_support), 0), SD_BUS_PROPERTY("MulticastDNS", "s", bus_property_get_resolve_support, offsetof(Link, mdns_support), 0), From 58f48a568aba8129070d18b8ca87a91a8fde4cde Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 3 May 2018 17:06:06 +0900 Subject: [PATCH 2/5] resolvectl: simplify map_{link,global}_dns_servers() --- src/resolve/resolvectl.c | 128 ++++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 61 deletions(-) diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index 0b58e9b57f..af2792efac 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -1169,6 +1169,66 @@ static int reset_server_features(int argc, char **argv, void *userdata) { return 0; } +static int read_dns_server_one(sd_bus_message *m, bool with_ifindex, char **ret) { + _cleanup_free_ char *pretty = NULL; + int ifindex, family, r; + const void *a; + size_t sz; + + assert(m); + assert(ret); + + r = sd_bus_message_enter_container(m, 'r', with_ifindex ? "iiay" : "iay"); + if (r <= 0) + return r; + + if (with_ifindex) { + r = sd_bus_message_read(m, "i", &ifindex); + if (r < 0) + return r; + } + + r = sd_bus_message_read(m, "i", &family); + if (r < 0) + return r; + + r = sd_bus_message_read_array(m, 'y', &a, &sz); + if (r < 0) + return r; + + r = sd_bus_message_exit_container(m); + if (r < 0) + return r; + + if (with_ifindex && ifindex != 0) { + /* only show the global ones here */ + *ret = NULL; + return 1; + } + + if (!IN_SET(family, AF_INET, AF_INET6)) { + log_debug("Unexpected family, ignoring: %i", family); + + *ret = NULL; + return 1; + } + + if (sz != FAMILY_ADDRESS_SIZE(family)) { + log_debug("Address size mismatch, ignoring."); + + *ret = NULL; + return 1; + } + + r = in_addr_to_string(family, a, &pretty); + if (r < 0) + return r; + + *ret = TAKE_PTR(pretty); + + return 1; +} + static int map_link_dns_servers(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) { char ***l = userdata; int r; @@ -1183,42 +1243,16 @@ static int map_link_dns_servers(sd_bus *bus, const char *member, sd_bus_message return r; for (;;) { - const void *a; - char *pretty; - int family; - size_t sz; + char *pretty = NULL; - r = sd_bus_message_enter_container(m, 'r', "iay"); + r = read_dns_server_one(m, false, &pretty); if (r < 0) return r; if (r == 0) break; - r = sd_bus_message_read(m, "i", &family); - if (r < 0) - return r; - - r = sd_bus_message_read_array(m, 'y', &a, &sz); - if (r < 0) - return r; - - r = sd_bus_message_exit_container(m); - if (r < 0) - return r; - - if (!IN_SET(family, AF_INET, AF_INET6)) { - log_debug("Unexpected family, ignoring."); + if (isempty(pretty)) continue; - } - - if (sz != FAMILY_ADDRESS_SIZE(family)) { - log_debug("Address size mismatch, ignoring."); - continue; - } - - r = in_addr_to_string(family, a, &pretty); - if (r < 0) - return r; r = strv_consume(l, pretty); if (r < 0) @@ -1464,46 +1498,17 @@ static int map_global_dns_servers(sd_bus *bus, const char *member, sd_bus_messag return r; for (;;) { - const void *a; - char *pretty; - int family, ifindex; - size_t sz; + char *pretty = NULL; - r = sd_bus_message_enter_container(m, 'r', "iiay"); + r = read_dns_server_one(m, true, &pretty); if (r < 0) return r; if (r == 0) break; - r = sd_bus_message_read(m, "ii", &ifindex, &family); - if (r < 0) - return r; - - r = sd_bus_message_read_array(m, 'y', &a, &sz); - if (r < 0) - return r; - - r = sd_bus_message_exit_container(m); - if (r < 0) - return r; - - if (ifindex != 0) /* only show the global ones here */ + if (isempty(pretty)) continue; - if (!IN_SET(family, AF_INET, AF_INET6)) { - log_debug("Unexpected family, ignoring."); - continue; - } - - if (sz != FAMILY_ADDRESS_SIZE(family)) { - log_debug("Address size mismatch, ignoring."); - continue; - } - - r = in_addr_to_string(family, a, &pretty); - if (r < 0) - return r; - r = strv_consume(l, pretty); if (r < 0) return r; @@ -1578,6 +1583,7 @@ static int status_print_strv_global(char **p) { static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) { struct global_info { + char *current_dns; char **dns; char **domains; char **ntas; From 446c641516f7b5e6f60213c4d050afca9901e80d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 1 May 2018 22:17:22 +0900 Subject: [PATCH 3/5] resolvectl: show current DNS server `systemd-resolved` rotate the DNS servers. So, it may by useful to show the current DNS server for diagnosing `systemd-resolved`. --- src/resolve/resolvectl.c | 61 +++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index af2792efac..32e4fc972c 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -1266,6 +1266,13 @@ static int map_link_dns_servers(sd_bus *bus, const char *member, sd_bus_message return 0; } +static int map_link_current_dns_server(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) { + assert(m); + assert(userdata); + + return read_dns_server_one(m, false, userdata); +} + static int map_link_domains(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) { char ***l = userdata; int r; @@ -1330,6 +1337,7 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode const char *llmnr; const char *mdns; const char *dnssec; + char *current_dns; char **dns; char **domains; char **ntas; @@ -1337,14 +1345,15 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode } link_info = {}; static const struct bus_properties_map property_map[] = { - { "ScopesMask", "t", NULL, offsetof(struct link_info, scopes_mask) }, - { "DNS", "a(iay)", map_link_dns_servers, offsetof(struct link_info, dns) }, - { "Domains", "a(sb)", map_link_domains, offsetof(struct link_info, domains) }, - { "LLMNR", "s", NULL, offsetof(struct link_info, llmnr) }, - { "MulticastDNS", "s", NULL, offsetof(struct link_info, mdns) }, - { "DNSSEC", "s", NULL, offsetof(struct link_info, dnssec) }, - { "DNSSECNegativeTrustAnchors", "as", NULL, offsetof(struct link_info, ntas) }, - { "DNSSECSupported", "b", NULL, offsetof(struct link_info, dnssec_supported) }, + { "ScopesMask", "t", NULL, offsetof(struct link_info, scopes_mask) }, + { "DNS", "a(iay)", map_link_dns_servers, offsetof(struct link_info, dns) }, + { "CurrentDNSServer", "(iay)", map_link_current_dns_server, offsetof(struct link_info, current_dns) }, + { "Domains", "a(sb)", map_link_domains, offsetof(struct link_info, domains) }, + { "LLMNR", "s", NULL, offsetof(struct link_info, llmnr) }, + { "MulticastDNS", "s", NULL, offsetof(struct link_info, mdns) }, + { "DNSSEC", "s", NULL, offsetof(struct link_info, dnssec) }, + { "DNSSECNegativeTrustAnchors", "as", NULL, offsetof(struct link_info, ntas) }, + { "DNSSECSupported", "b", NULL, offsetof(struct link_info, dnssec_supported) }, {} }; @@ -1448,11 +1457,13 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode printf(" LLMNR setting: %s\n" "MulticastDNS setting: %s\n" " DNSSEC setting: %s\n" - " DNSSEC supported: %s\n", + " DNSSEC supported: %s\n" + " Current DNS Server: %s\n", strna(link_info.llmnr), strna(link_info.mdns), strna(link_info.dnssec), - yes_no(link_info.dnssec_supported)); + yes_no(link_info.dnssec_supported), + strna(link_info.current_dns)); STRV_FOREACH(i, link_info.dns) { printf(" %s %s\n", @@ -1478,6 +1489,7 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode r = 0; finish: + free(link_info.current_dns); strv_free(link_info.dns); strv_free(link_info.domains); strv_free(link_info.ntas); @@ -1521,6 +1533,13 @@ static int map_global_dns_servers(sd_bus *bus, const char *member, sd_bus_messag return 0; } +static int map_global_current_dns_server(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) { + assert(m); + assert(userdata); + + return read_dns_server_one(m, true, userdata); +} + static int map_global_domains(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) { char ***l = userdata; int r; @@ -1594,13 +1613,14 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) { } global_info = {}; static const struct bus_properties_map property_map[] = { - { "DNS", "a(iiay)", map_global_dns_servers, offsetof(struct global_info, dns) }, - { "Domains", "a(isb)", map_global_domains, offsetof(struct global_info, domains) }, - { "DNSSECNegativeTrustAnchors", "as", NULL, offsetof(struct global_info, ntas) }, - { "LLMNR", "s", NULL, offsetof(struct global_info, llmnr) }, - { "MulticastDNS", "s", NULL, offsetof(struct global_info, mdns) }, - { "DNSSEC", "s", NULL, offsetof(struct global_info, dnssec) }, - { "DNSSECSupported", "b", NULL, offsetof(struct global_info, dnssec_supported) }, + { "DNS", "a(iiay)", map_global_dns_servers, offsetof(struct global_info, dns) }, + { "CurrentDNSServer", "(iiay)", map_global_current_dns_server, offsetof(struct global_info, current_dns) }, + { "Domains", "a(isb)", map_global_domains, offsetof(struct global_info, domains) }, + { "DNSSECNegativeTrustAnchors", "as", NULL, offsetof(struct global_info, ntas) }, + { "LLMNR", "s", NULL, offsetof(struct global_info, llmnr) }, + { "MulticastDNS", "s", NULL, offsetof(struct global_info, mdns) }, + { "DNSSEC", "s", NULL, offsetof(struct global_info, dnssec) }, + { "DNSSECSupported", "b", NULL, offsetof(struct global_info, dnssec_supported) }, {} }; @@ -1671,11 +1691,13 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) { printf(" LLMNR setting: %s\n" "MulticastDNS setting: %s\n" " DNSSEC setting: %s\n" - " DNSSEC supported: %s\n", + " DNSSEC supported: %s\n" + " Current DNS Server: %s\n", strna(global_info.llmnr), strna(global_info.mdns), strna(global_info.dnssec), - yes_no(global_info.dnssec_supported)); + yes_no(global_info.dnssec_supported), + strna(global_info.current_dns)); STRV_FOREACH(i, global_info.dns) { printf(" %s %s\n", @@ -1701,6 +1723,7 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) { r = 0; finish: + free(global_info.current_dns); strv_free(global_info.dns); strv_free(global_info.domains); strv_free(global_info.ntas); From 5bc53feeace7007ebdaef21294d82291de301e2e Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 1 May 2018 16:39:36 +0900 Subject: [PATCH 4/5] resolve: update comments to mention resolvectl --- src/resolve/resolv.conf | 2 +- src/resolve/resolvconf-compat.c | 2 +- src/resolve/resolved-resolv-conf.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/resolve/resolv.conf b/src/resolve/resolv.conf index 34a6b9257f..ffc460dbf2 100644 --- a/src/resolve/resolv.conf +++ b/src/resolve/resolv.conf @@ -4,7 +4,7 @@ # internal DNS stub resolver of systemd-resolved. This file lists no search # domains. # -# Run "systemd-resolve --status" to see details about the uplink DNS servers +# Run "resolvectl status" to see details about the uplink DNS servers # currently in use. # # Third party programs must not access this file directly, but only through the diff --git a/src/resolve/resolvconf-compat.c b/src/resolve/resolvconf-compat.c index a6b327e2f0..d7e68003e6 100644 --- a/src/resolve/resolvconf-compat.c +++ b/src/resolve/resolvconf-compat.c @@ -27,7 +27,7 @@ static void resolvconf_help(void) { " -f Ignore if specified interface does not exist\n" " -x Send DNS traffic preferably over this interface\n" "\n" - "This is a compatibility alias for the systemd-resolve(1) tool, providing native\n" + "This is a compatibility alias for the resolvectl(1) tool, providing native\n" "command line compatibility with the resolvconf(8) tool of various Linux\n" "distributions and BSD systems. Some options supported by other implementations\n" "are not supported and are ignored: -m, -p. Various options supported by other\n" diff --git a/src/resolve/resolved-resolv-conf.c b/src/resolve/resolved-resolv-conf.c index 4626eb4da7..b0942b701c 100644 --- a/src/resolve/resolved-resolv-conf.c +++ b/src/resolve/resolved-resolv-conf.c @@ -268,7 +268,7 @@ static int write_stub_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet "# internal DNS stub resolver of systemd-resolved. This file lists all\n" "# configured search domains.\n" "#\n" - "# Run \"systemd-resolve --status\" to see details about the uplink DNS servers\n" + "# Run \"resolvectl status\" to see details about the uplink DNS servers\n" "# currently in use.\n" "#\n" "# Third party programs must not access this file directly, but only through the\n" From c513bb6ea47bb049d33a72748a22efe990a7c367 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 3 May 2018 17:10:02 +0900 Subject: [PATCH 5/5] resolvectl: simplify map_{link,global}_domains() --- src/resolve/resolvectl.c | 62 ++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index 32e4fc972c..10c8fb5fb6 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -1273,6 +1273,39 @@ static int map_link_current_dns_server(sd_bus *bus, const char *member, sd_bus_m return read_dns_server_one(m, false, userdata); } +static int read_domain_one(sd_bus_message *m, bool with_ifindex, char **ret) { + _cleanup_free_ char *str = NULL; + int ifindex, route_only, r; + const char *domain; + + assert(m); + assert(ret); + + if (with_ifindex) + r = sd_bus_message_read(m, "(isb)", &ifindex, &domain, &route_only); + else + r = sd_bus_message_read(m, "(sb)", &domain, &route_only); + if (r <= 0) + return r; + + if (with_ifindex && ifindex != 0) { + /* only show the global ones here */ + *ret = NULL; + return 1; + } + + if (route_only) + str = strappend("~", domain); + else + str = strdup(domain); + if (!str) + return -ENOMEM; + + *ret = TAKE_PTR(str); + + return 1; +} + static int map_link_domains(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) { char ***l = userdata; int r; @@ -1287,22 +1320,16 @@ static int map_link_domains(sd_bus *bus, const char *member, sd_bus_message *m, return r; for (;;) { - const char *domain; - int route_only; - char *pretty; + char *pretty = NULL; - r = sd_bus_message_read(m, "(sb)", &domain, &route_only); + r = read_domain_one(m, false, &pretty); if (r < 0) return r; if (r == 0) break; - if (route_only) - pretty = strappend("~", domain); - else - pretty = strdup(domain); - if (!pretty) - return -ENOMEM; + if (isempty(pretty)) + continue; r = strv_consume(l, pretty); if (r < 0) @@ -1554,26 +1581,17 @@ static int map_global_domains(sd_bus *bus, const char *member, sd_bus_message *m return r; for (;;) { - const char *domain; - int route_only, ifindex; - char *pretty; + char *pretty = NULL; - r = sd_bus_message_read(m, "(isb)", &ifindex, &domain, &route_only); + r = read_domain_one(m, true, &pretty); if (r < 0) return r; if (r == 0) break; - if (ifindex != 0) /* only show the global ones here */ + if (isempty(pretty)) continue; - if (route_only) - pretty = strappend("~", domain); - else - pretty = strdup(domain); - if (!pretty) - return -ENOMEM; - r = strv_consume(l, pretty); if (r < 0) return r;