diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index e412576654..13f70e3b1c 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -102,11 +102,27 @@ typedef enum StatusMode { STATUS_DEFAULT_ROUTE, STATUS_LLMNR, STATUS_MDNS, - STATUS_PRIVATE, + STATUS_DNS_OVER_TLS, STATUS_DNSSEC, STATUS_NTA, + _STATUS_MAX, + _STATUS_INVALID = -EINVAL, } StatusMode; +static const char* const status_mode_json_field_table[_STATUS_MAX] = { + [STATUS_ALL] = NULL, + [STATUS_DNS] = "servers", + [STATUS_DOMAIN] = "searchDomains", + [STATUS_DEFAULT_ROUTE] = "defaultRoute", + [STATUS_LLMNR] = "llmnr", + [STATUS_MDNS] = "mDNS", + [STATUS_DNS_OVER_TLS] = "dnsOverTLS", + [STATUS_DNSSEC] = "dnssec", + [STATUS_NTA] = "negativeTrustAnchors", +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(status_mode_json_field, StatusMode); + typedef struct InterfaceInfo { int index; const char *name; @@ -1793,41 +1809,6 @@ static char** global_protocol_status(const GlobalInfo *info) { return TAKE_PTR(s); } -static const char* status_mode_to_json_field(StatusMode mode) { - switch (mode) { - - case STATUS_ALL: - return NULL; - - case STATUS_DNS: - return "servers"; - - case STATUS_DOMAIN: - return "searchDomains"; - - case STATUS_DEFAULT_ROUTE: - return "defaultRoute"; - - case STATUS_LLMNR: - return "llmnr"; - - case STATUS_MDNS: - return "mDNS"; - - case STATUS_PRIVATE: - return "dnsOverTLS"; - - case STATUS_DNSSEC: - return "dnssec"; - - case STATUS_NTA: - return "negativeTrustAnchors"; - - default: - assert_not_reached(); - } -} - static int status_json_filter_fields(sd_json_variant **configuration, StatusMode mode) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; sd_json_variant *w; @@ -1836,7 +1817,7 @@ static int status_json_filter_fields(sd_json_variant **configuration, StatusMode assert(configuration); - field = status_mode_to_json_field(mode); + field = status_mode_json_field_to_string(mode); if (!field) /* Nothing to filter for this mode. */ return 0; @@ -1869,7 +1850,6 @@ static int status_json_filter_links(sd_json_variant **configuration, char **link if (links) STRV_FOREACH(ifname, links) { int ifindex = rtnl_resolve_interface_or_warn(/* rtnl= */ NULL, *ifname); - if (ifindex < 0) return ifindex; @@ -2037,7 +2017,7 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode return 0; - case STATUS_PRIVATE: + case STATUS_DNS_OVER_TLS: printf("%sLink %i (%s)%s: %s\n", ansi_highlight(), ifindex, name, ansi_normal(), strna(link_info.dns_over_tls)); @@ -2265,7 +2245,7 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) { return 0; - case STATUS_PRIVATE: + case STATUS_DNS_OVER_TLS: printf("%sGlobal%s: %s\n", ansi_highlight(), ansi_normal(), strna(global_info.dns_over_tls)); @@ -3010,10 +2990,10 @@ static int verb_dns_over_tls(int argc, char **argv, void *userdata) { } if (arg_ifindex <= 0) - return status_all(bus, STATUS_PRIVATE); + return status_all(bus, STATUS_DNS_OVER_TLS); if (argc < 3) - return status_ifindex(bus, arg_ifindex, NULL, STATUS_PRIVATE, NULL); + return status_ifindex(bus, arg_ifindex, NULL, STATUS_DNS_OVER_TLS, NULL); (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password); diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index 6f8d0fdcfe..c6c6bdc866 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -1793,16 +1793,18 @@ bool dns_scope_is_default_route(DnsScope *scope) { return true; } -int dns_scope_dump_cache_to_json(DnsScope *scope, sd_json_variant **ret) { +int dns_scope_to_json(DnsScope *scope, bool with_cache, sd_json_variant **ret) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *cache = NULL; int r; assert(scope); assert(ret); - r = dns_cache_dump_to_json(&scope->cache, &cache); - if (r < 0) - return r; + if (with_cache) { + r = dns_cache_dump_to_json(&scope->cache, &cache); + if (r < 0) + return r; + } return sd_json_buildo( ret, @@ -1810,7 +1812,7 @@ int dns_scope_dump_cache_to_json(DnsScope *scope, sd_json_variant **ret) { SD_JSON_BUILD_PAIR_CONDITION(scope->family != AF_UNSPEC, "family", SD_JSON_BUILD_INTEGER(scope->family)), SD_JSON_BUILD_PAIR_CONDITION(!!scope->link, "ifindex", SD_JSON_BUILD_INTEGER(dns_scope_ifindex(scope))), SD_JSON_BUILD_PAIR_CONDITION(!!scope->link, "ifname", SD_JSON_BUILD_STRING(dns_scope_ifname(scope))), - SD_JSON_BUILD_PAIR_VARIANT("cache", cache), + SD_JSON_BUILD_PAIR_CONDITION(with_cache, "cache", SD_JSON_BUILD_VARIANT(cache)), SD_JSON_BUILD_PAIR_CONDITION(scope->protocol == DNS_PROTOCOL_DNS, "dnssec", SD_JSON_BUILD_STRING(dnssec_mode_to_string(scope->dnssec_mode))), diff --git a/src/resolve/resolved-dns-scope.h b/src/resolve/resolved-dns-scope.h index 16c28eb9a3..b492d7d4bd 100644 --- a/src/resolve/resolved-dns-scope.h +++ b/src/resolve/resolved-dns-scope.h @@ -120,7 +120,7 @@ int dns_scope_remove_dnssd_registered_services(DnsScope *scope); bool dns_scope_is_default_route(DnsScope *scope); -int dns_scope_dump_cache_to_json(DnsScope *scope, sd_json_variant **ret); +int dns_scope_to_json(DnsScope *scope, bool with_cache, sd_json_variant **ret); int dns_type_suitable_for_protocol(uint16_t type, DnsProtocol protocol); int dns_question_types_suitable_for_protocol(DnsQuestion *q, DnsProtocol protocol); diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 29c5f4488e..fe4807685a 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -2068,39 +2068,10 @@ static int dns_configuration_json_append( assert(configuration); - if (dns_servers) { - r = sd_json_variant_new_array(&dns_servers_json, NULL, 0); - if (r < 0) - return r; - } - - if (search_domains) { - r = sd_json_variant_new_array(&search_domains_json, NULL, 0); - if (r < 0) - return r; - } - - if (current_dns_server) { - r = dns_server_dump_configuration_to_json(current_dns_server, ¤t_dns_server_json); - if (r < 0) - return r; - } - - if (fallback_dns_servers) { - r = sd_json_variant_new_array(&fallback_dns_servers_json, NULL, 0); - if (r < 0) - return r; - } - SET_FOREACH(scope, dns_scopes) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; - r = dns_scope_dump_cache_to_json(scope, &v); - if (r < 0) - return r; - - /* The cache is not relevant to the configuration of the scope. */ - r = sd_json_variant_filter(&v, STRV_MAKE("cache")); + r = dns_scope_to_json(scope, /* with_cache= */ false, &v); if (r < 0) return r; @@ -2112,8 +2083,6 @@ static int dns_configuration_json_append( LIST_FOREACH(servers, s, dns_servers) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; - assert(dns_servers_json); - r = dns_server_dump_configuration_to_json(s, &v); if (r < 0) return r; @@ -2126,8 +2095,6 @@ static int dns_configuration_json_append( LIST_FOREACH(domains, d, search_domains) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; - assert(search_domains_json); - r = dns_search_domain_dump_to_json(d, &v); if (r < 0) return r; @@ -2140,8 +2107,6 @@ static int dns_configuration_json_append( LIST_FOREACH(servers, s, fallback_dns_servers) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; - assert(fallback_dns_servers_json); - r = dns_server_dump_configuration_to_json(s, &v); if (r < 0) return r; @@ -2156,9 +2121,7 @@ static int dns_configuration_json_append( JSON_BUILD_PAIR_STRING_NON_EMPTY("ifname", ifname), SD_JSON_BUILD_PAIR_CONDITION(ifindex > 0, "ifindex", SD_JSON_BUILD_UNSIGNED(ifindex)), JSON_BUILD_PAIR_STRING_NON_EMPTY("delegate", delegate), - JSON_BUILD_PAIR_CONDITION_BOOLEAN(ifindex > 0 || !!delegate, - "defaultRoute", - default_route > 0), + JSON_BUILD_PAIR_TRISTATE_NON_NULL("defaultRoute", default_route), JSON_BUILD_PAIR_VARIANT_NON_NULL("currentServer", current_dns_server_json), JSON_BUILD_PAIR_VARIANT_NON_NULL("servers", dns_servers_json), JSON_BUILD_PAIR_VARIANT_NON_NULL("fallbackServers", fallback_dns_servers_json), @@ -2189,7 +2152,7 @@ static int global_dns_configuration_json_append(Manager *m, sd_json_variant **co /* ifname = */ NULL, /* ifindex = */ 0, /* delegate = */ NULL, - /* default_route = */ 0, + /* default_route = */ -1, manager_get_dns_server(m), m->dns_servers, m->fallback_dns_servers, @@ -2275,7 +2238,7 @@ static int delegate_dns_configuration_json_append(DnsDelegate *d, sd_json_varian /* ifname = */ NULL, /* ifindex = */ 0, d->id, - d->default_route, + d->default_route > 0, /* Defaults to false. See dns_scope_is_default_route(). */ dns_delegate_get_dns_server(d), d->dns_servers, /* fallback_dns_servers = */ NULL, diff --git a/src/resolve/resolved-varlink.c b/src/resolve/resolved-varlink.c index e4ea55b173..a4723176a8 100644 --- a/src/resolve/resolved-varlink.c +++ b/src/resolve/resolved-varlink.c @@ -1270,7 +1270,7 @@ static int vl_method_dump_cache(sd_varlink *link, sd_json_variant *parameters, s LIST_FOREACH(scopes, s, m->dns_scopes) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *j = NULL; - r = dns_scope_dump_cache_to_json(s, &j); + r = dns_scope_to_json(s, /* with_cache= */ true, &j); if (r < 0) return r; diff --git a/src/shared/varlink-io.systemd.Resolve.Monitor.c b/src/shared/varlink-io.systemd.Resolve.Monitor.c index 0fc67df221..abff022b18 100644 --- a/src/shared/varlink-io.systemd.Resolve.Monitor.c +++ b/src/shared/varlink-io.systemd.Resolve.Monitor.c @@ -5,6 +5,10 @@ /* We want to reuse several structures from the io.systemd.Resolve interface, namely: * + * - DNSProtocol + * - DNSOverTLSMode + * - ResolveSupport + * - ResolvConfMode * - ResourceKey * - ResourceRecord * - DNSServer @@ -52,13 +56,13 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( static SD_VARLINK_DEFINE_STRUCT_TYPE( ScopeCache, - SD_VARLINK_DEFINE_FIELD(protocol, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(protocol, DNSProtocol, 0), SD_VARLINK_DEFINE_FIELD(family, SD_VARLINK_INT, SD_VARLINK_NULLABLE), SD_VARLINK_DEFINE_FIELD(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), SD_VARLINK_DEFINE_FIELD(ifname, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), SD_VARLINK_DEFINE_FIELD_BY_TYPE(cache, CacheEntry, SD_VARLINK_ARRAY), SD_VARLINK_DEFINE_FIELD(dnssec, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), - SD_VARLINK_DEFINE_FIELD(dnsOverTLS, SD_VARLINK_STRING, SD_VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_FIELD_BY_TYPE(dnsOverTLS, DNSOverTLSMode, SD_VARLINK_NULLABLE)); static SD_VARLINK_DEFINE_METHOD( DumpCache, @@ -137,6 +141,10 @@ SD_VARLINK_DEFINE_INTERFACE( &vl_method_DumpServerState, &vl_method_DumpStatistics, &vl_method_ResetStatistics, + &vl_type_DNSProtocol, + &vl_type_DNSOverTLSMode, + &vl_type_ResolveSupport, + &vl_type_ResolvConfMode, &vl_type_ResourceKey, &vl_type_ResourceRecord, &vl_type_ResourceRecordArray, diff --git a/src/shared/varlink-io.systemd.Resolve.c b/src/shared/varlink-io.systemd.Resolve.c index bdc0d9cd07..3f20c9f6cc 100644 --- a/src/shared/varlink-io.systemd.Resolve.c +++ b/src/shared/varlink-io.systemd.Resolve.c @@ -1,7 +1,48 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include "resolve-util.h" #include "varlink-io.systemd.Resolve.h" +SD_VARLINK_DEFINE_ENUM_TYPE( + DNSProtocol, + SD_VARLINK_FIELD_COMMENT("DNS"), + SD_VARLINK_DEFINE_ENUM_VALUE(dns), + SD_VARLINK_FIELD_COMMENT("Multicast DNS"), + SD_VARLINK_DEFINE_ENUM_VALUE(mdns), + SD_VARLINK_FIELD_COMMENT("LLMNR"), + SD_VARLINK_DEFINE_ENUM_VALUE(llmnr)); + +SD_VARLINK_DEFINE_ENUM_TYPE( + DNSOverTLSMode, + SD_VARLINK_FIELD_COMMENT("DNSOverTLS is disabled."), + SD_VARLINK_DEFINE_ENUM_VALUE(no), + SD_VARLINK_FIELD_COMMENT("DNSOverTLS is enabled."), + SD_VARLINK_DEFINE_ENUM_VALUE(yes), + SD_VARLINK_FIELD_COMMENT("Try to use DNSOverTLS, but disabled when the server does not support it."), + SD_VARLINK_DEFINE_ENUM_VALUE(opportunistic)); + +SD_VARLINK_DEFINE_ENUM_TYPE( + ResolveSupport, + SD_VARLINK_FIELD_COMMENT("The protocol is disabled."), + SD_VARLINK_DEFINE_ENUM_VALUE(no), + SD_VARLINK_FIELD_COMMENT("The protocol is enabled."), + SD_VARLINK_DEFINE_ENUM_VALUE(yes), + SD_VARLINK_FIELD_COMMENT("The protocol is used only for resolving."), + SD_VARLINK_DEFINE_ENUM_VALUE(resolve)); + +SD_VARLINK_DEFINE_ENUM_TYPE( + ResolvConfMode, + SD_VARLINK_FIELD_COMMENT("/etc/resolv.conf is a symbolic link to "PRIVATE_UPLINK_RESOLV_CONF"."), + SD_VARLINK_DEFINE_ENUM_VALUE(uplink), + SD_VARLINK_FIELD_COMMENT("/etc/resolv.conf is a symbolic link to "PRIVATE_STUB_RESOLV_CONF"."), + SD_VARLINK_DEFINE_ENUM_VALUE(stub), + SD_VARLINK_FIELD_COMMENT("/etc/resolv.conf is a symbolic link to "PRIVATE_STATIC_RESOLV_CONF"."), + SD_VARLINK_DEFINE_ENUM_VALUE(static), + SD_VARLINK_FIELD_COMMENT("/etc/resolv.conf does not exist."), + SD_VARLINK_DEFINE_ENUM_VALUE(missing), + SD_VARLINK_FIELD_COMMENT("/etc/resolv.conf is not managed by systemd-resolved."), + SD_VARLINK_DEFINE_ENUM_VALUE(foreign)); + SD_VARLINK_DEFINE_STRUCT_TYPE( ResourceKey, SD_VARLINK_FIELD_COMMENT("The RR class, almost always IN, i.e 0x01. If unspecified defaults to IN."), @@ -199,7 +240,7 @@ SD_VARLINK_DEFINE_STRUCT_TYPE( SD_VARLINK_DEFINE_STRUCT_TYPE( DNSScope, SD_VARLINK_FIELD_COMMENT("Protocol associated with this scope."), - SD_VARLINK_DEFINE_FIELD(protocol, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(protocol, DNSProtocol, 0), SD_VARLINK_FIELD_COMMENT("Address family associated with this scope."), SD_VARLINK_DEFINE_FIELD(family, SD_VARLINK_INT, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("Interface index associated with this scope."), @@ -209,7 +250,7 @@ SD_VARLINK_DEFINE_STRUCT_TYPE( SD_VARLINK_FIELD_COMMENT("DNSSEC mode associated with this scope."), SD_VARLINK_DEFINE_FIELD(dnssec, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("DNSOverTLS mode associated with this scope."), - SD_VARLINK_DEFINE_FIELD(dnsOverTLS, SD_VARLINK_STRING, SD_VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_FIELD_BY_TYPE(dnsOverTLS, DNSOverTLSMode, SD_VARLINK_NULLABLE)); SD_VARLINK_DEFINE_STRUCT_TYPE( DNSConfiguration, @@ -234,13 +275,14 @@ SD_VARLINK_DEFINE_STRUCT_TYPE( SD_VARLINK_FIELD_COMMENT("DNSSEC mode."), SD_VARLINK_DEFINE_FIELD(dnssec, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("DNSOverTLS mode."), - SD_VARLINK_DEFINE_FIELD(dnsOverTLS, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(dnsOverTLS, DNSOverTLSMode, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("LLMNR support."), + //SD_VARLINK_DEFINE_FIELD_BY_TYPE(llmnr, ResolveSupport, SD_VARLINK_NULLABLE), SD_VARLINK_DEFINE_FIELD(llmnr, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("mDNS support."), - SD_VARLINK_DEFINE_FIELD(mDNS, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(mDNS, ResolveSupport, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("resolv.conf mode, set for global configuration only."), - SD_VARLINK_DEFINE_FIELD(resolvConfMode, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(resolvConfMode, ResolvConfMode, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("Array of current DNS scopes."), SD_VARLINK_DEFINE_FIELD_BY_TYPE(scopes, DNSScope, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE)); @@ -317,6 +359,14 @@ SD_VARLINK_DEFINE_INTERFACE( &vl_method_BrowseServices, SD_VARLINK_SYMBOL_COMMENT("Current global and per-link DNS configurations."), &vl_method_DumpDNSConfiguration, + SD_VARLINK_SYMBOL_COMMENT("The type of protocol."), + &vl_type_DNSProtocol, + SD_VARLINK_SYMBOL_COMMENT("The mode of DNSOverTLS."), + &vl_type_DNSOverTLSMode, + SD_VARLINK_SYMBOL_COMMENT("Whether the protocol is enabled."), + &vl_type_ResolveSupport, + SD_VARLINK_SYMBOL_COMMENT("The management mode of /etc/resolve.conf file."), + &vl_type_ResolvConfMode, SD_VARLINK_SYMBOL_COMMENT("Encapsulates a resolved address."), &vl_type_ResolvedAddress, SD_VARLINK_SYMBOL_COMMENT("Encapsulates a resolved host name."), diff --git a/src/shared/varlink-io.systemd.Resolve.h b/src/shared/varlink-io.systemd.Resolve.h index 48fdabe13c..c8322cd66a 100644 --- a/src/shared/varlink-io.systemd.Resolve.h +++ b/src/shared/varlink-io.systemd.Resolve.h @@ -3,6 +3,10 @@ #include "sd-varlink-idl.h" +extern const sd_varlink_symbol vl_type_DNSProtocol; +extern const sd_varlink_symbol vl_type_DNSOverTLSMode; +extern const sd_varlink_symbol vl_type_ResolveSupport; +extern const sd_varlink_symbol vl_type_ResolvConfMode; extern const sd_varlink_symbol vl_type_ResourceKey; extern const sd_varlink_symbol vl_type_ResourceRecord; extern const sd_varlink_symbol vl_type_DNSServer; diff --git a/src/test/test-varlink-idl.c b/src/test/test-varlink-idl.c index cc2481a084..cecc64b3fd 100644 --- a/src/test/test-varlink-idl.c +++ b/src/test/test-varlink-idl.c @@ -13,6 +13,7 @@ #include "json-util.h" #include "network-util.h" #include "pretty-print.h" +#include "resolve-util.h" #include "tests.h" #include "varlink-idl-util.h" #include "varlink-io.systemd.h" @@ -512,13 +513,18 @@ static void test_enum_to_string_name(const char *n, const sd_varlink_symbol *sym TEST(enums_idl) { TEST_IDL_ENUM(BootEntryType, boot_entry_type, vl_type_BootEntryType); TEST_IDL_ENUM_TO_STRING(BootEntrySource, boot_entry_source, vl_type_BootEntrySource); + TEST_IDL_ENUM(PartitionDesignator, partition_designator, vl_type_PartitionDesignator); + TEST_IDL_ENUM(LinkAddressState, link_address_state, vl_type_LinkAddressState); TEST_IDL_ENUM_TO_STRING(LinkAddressState, link_address_state, vl_type_LinkAddressState); TEST_IDL_ENUM(LinkOnlineState, link_online_state, vl_type_LinkOnlineState); TEST_IDL_ENUM_TO_STRING(LinkOnlineState, link_online_state, vl_type_LinkOnlineState); TEST_IDL_ENUM(AddressFamily, link_required_address_family, vl_type_LinkRequiredAddressFamily); TEST_IDL_ENUM_TO_STRING(AddressFamily, link_required_address_family, vl_type_LinkRequiredAddressFamily); + + TEST_IDL_ENUM(DnsOverTlsMode, dns_over_tls_mode, vl_type_DNSOverTLSMode); + TEST_IDL_ENUM(ResolveSupport, resolve_support, vl_type_ResolveSupport); } DEFINE_TEST_MAIN(LOG_DEBUG);