From 01278ceba0d16a5259b7d21433ce1c326bd671a5 Mon Sep 17 00:00:00 2001 From: Nick Rosbrook Date: Fri, 10 Oct 2025 15:56:35 -0400 Subject: [PATCH] resolve: add DumpDNSConfiguration to varlink API Add io.systemd.Resolve.DumpDNSConfiguration. This provides the same information as io.systemd.Resolve.Monitor.SubscribeDNSConfiguration, but just returns the configuration once without the subscription logic. In order to use the same definitions for DNSConfiguration et al. between both interfaces, move the definitions to io.systemd.Resolve, and include them in io.systemd.Resolve.Monitor. This will be used to implement --json for resolvectl status. --- src/resolve/resolved-varlink.c | 40 +++++++-- .../varlink-io.systemd.Resolve.Monitor.c | 86 +++--------------- src/shared/varlink-io.systemd.Resolve.c | 89 +++++++++++++++++++ src/shared/varlink-io.systemd.Resolve.h | 4 + 4 files changed, 135 insertions(+), 84 deletions(-) diff --git a/src/resolve/resolved-varlink.c b/src/resolve/resolved-varlink.c index 0a73e419619..e4ea55b1734 100644 --- a/src/resolve/resolved-varlink.c +++ b/src/resolve/resolved-varlink.c @@ -1409,6 +1409,29 @@ fail: return log_debug_errno(r, "Failed to subscribe client to DNS configuration monitor: %m"); } +static int vl_method_dump_dns_configuration(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { + _cleanup_(sd_json_variant_unrefp) sd_json_variant *configuration = NULL; + Manager *m; + Link *l; + int r; + + assert(link); + + m = ASSERT_PTR(sd_varlink_server_get_userdata(sd_varlink_get_server(link))); + + /* Make sure the accessible flag is not stale. */ + dns_server_reset_accessible_all(m->dns_servers); + + HASHMAP_FOREACH(l, m->links) + dns_server_reset_accessible_all(l->dns_servers); + + r = manager_dump_dns_configuration_json(m, &configuration); + if (r < 0) + return r; + + return sd_varlink_reply(link, configuration); +} + static int varlink_monitor_server_init(Manager *m) { _cleanup_(sd_varlink_server_unrefp) sd_varlink_server *server = NULL; int r; @@ -1481,14 +1504,15 @@ static int varlink_main_server_init(Manager *m) { r = sd_varlink_server_bind_method_many( s, - "io.systemd.Resolve.ResolveHostname", vl_method_resolve_hostname, - "io.systemd.Resolve.ResolveAddress", vl_method_resolve_address, - "io.systemd.Resolve.ResolveService", vl_method_resolve_service, - "io.systemd.Resolve.ResolveRecord", vl_method_resolve_record, - "io.systemd.service.Ping", varlink_method_ping, - "io.systemd.service.SetLogLevel", varlink_method_set_log_level, - "io.systemd.service.GetEnvironment", varlink_method_get_environment, - "io.systemd.Resolve.BrowseServices", vl_method_browse_services); + "io.systemd.Resolve.ResolveHostname", vl_method_resolve_hostname, + "io.systemd.Resolve.ResolveAddress", vl_method_resolve_address, + "io.systemd.Resolve.ResolveService", vl_method_resolve_service, + "io.systemd.Resolve.ResolveRecord", vl_method_resolve_record, + "io.systemd.service.Ping", varlink_method_ping, + "io.systemd.service.SetLogLevel", varlink_method_set_log_level, + "io.systemd.service.GetEnvironment", varlink_method_get_environment, + "io.systemd.Resolve.BrowseServices", vl_method_browse_services, + "io.systemd.Resolve.DumpDNSConfiguration", vl_method_dump_dns_configuration); if (r < 0) return log_error_errno(r, "Failed to register varlink methods: %m"); diff --git a/src/shared/varlink-io.systemd.Resolve.Monitor.c b/src/shared/varlink-io.systemd.Resolve.Monitor.c index bd514145fc0..0fc67df221b 100644 --- a/src/shared/varlink-io.systemd.Resolve.Monitor.c +++ b/src/shared/varlink-io.systemd.Resolve.Monitor.c @@ -3,8 +3,16 @@ #include "bus-polkit.h" #include "varlink-io.systemd.Resolve.Monitor.h" -/* We want to reuse the ResourceKey and ResourceRecord structures from the io.systemd.Resolve interface, - * hence import them here. */ +/* We want to reuse several structures from the io.systemd.Resolve interface, namely: + * + * - ResourceKey + * - ResourceRecord + * - DNSServer + * - DNSScope + * - SearchDomain + * - DNSConfiguration + * + * Hence, import them here . */ #include "varlink-io.systemd.Resolve.h" static SD_VARLINK_DEFINE_STRUCT_TYPE( @@ -114,80 +122,6 @@ static SD_VARLINK_DEFINE_METHOD( ResetStatistics, VARLINK_DEFINE_POLKIT_INPUT); -static SD_VARLINK_DEFINE_STRUCT_TYPE( - DNSServer, - SD_VARLINK_FIELD_COMMENT("IPv4 or IPv6 address of the server."), - SD_VARLINK_DEFINE_FIELD(address, SD_VARLINK_INT, SD_VARLINK_ARRAY), - SD_VARLINK_FIELD_COMMENT("IPv4 or IPv6 address of the server, formatted as a human-readable string."), - SD_VARLINK_DEFINE_FIELD(addressString, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), - SD_VARLINK_FIELD_COMMENT("Address family of the server, one of AF_INET or AF_INET6."), - SD_VARLINK_DEFINE_FIELD(family, SD_VARLINK_INT, 0), - SD_VARLINK_FIELD_COMMENT("Port number of the server."), - SD_VARLINK_DEFINE_FIELD(port, SD_VARLINK_INT, 0), - SD_VARLINK_FIELD_COMMENT("Interface index for which this server is configured."), - SD_VARLINK_DEFINE_FIELD(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), - SD_VARLINK_FIELD_COMMENT("Server Name Indication (SNI) of the server."), - SD_VARLINK_DEFINE_FIELD(name, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), - SD_VARLINK_FIELD_COMMENT("Indicates if the DNS server is accessible or not."), - SD_VARLINK_DEFINE_FIELD(accessible, SD_VARLINK_BOOL, 0)); - -static SD_VARLINK_DEFINE_STRUCT_TYPE( - SearchDomain, - SD_VARLINK_FIELD_COMMENT("Domain name."), - SD_VARLINK_DEFINE_FIELD(name, SD_VARLINK_STRING, 0), - SD_VARLINK_FIELD_COMMENT("Indicates whether or not this is a routing-only domain."), - SD_VARLINK_DEFINE_FIELD(routeOnly, SD_VARLINK_BOOL, 0), - SD_VARLINK_FIELD_COMMENT("Interface index for which this search domain is configured."), - SD_VARLINK_DEFINE_FIELD(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); - -static 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_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."), - SD_VARLINK_DEFINE_FIELD(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), - SD_VARLINK_FIELD_COMMENT("Interface name associated with this scope."), - SD_VARLINK_DEFINE_FIELD(ifname, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), - 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)); - -static SD_VARLINK_DEFINE_STRUCT_TYPE( - DNSConfiguration, - SD_VARLINK_FIELD_COMMENT("Interface name, if any, associated with this configuration. Empty for global configuration."), - SD_VARLINK_DEFINE_FIELD(ifname, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), - SD_VARLINK_FIELD_COMMENT("Interface index, if any, associated with this configuration. Empty for global configuration."), - SD_VARLINK_DEFINE_FIELD(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), - SD_VARLINK_FIELD_COMMENT("Delegate name, if any, associated with this configuration. Empty for global or link configurations."), - SD_VARLINK_DEFINE_FIELD(delegate, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), - SD_VARLINK_FIELD_COMMENT("Indicates whether or not this link's DNS servers will be used for resolving domain names that do not match any link's configured domains."), - SD_VARLINK_DEFINE_FIELD(defaultRoute, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), - SD_VARLINK_FIELD_COMMENT("DNS server currently selected to use for lookups."), - SD_VARLINK_DEFINE_FIELD_BY_TYPE(currentServer, DNSServer, SD_VARLINK_NULLABLE), - SD_VARLINK_FIELD_COMMENT("Array of configured DNS servers."), - SD_VARLINK_DEFINE_FIELD_BY_TYPE(servers, DNSServer, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), - SD_VARLINK_FIELD_COMMENT("Array of configured fallback DNS servers, set for global configuration only."), - SD_VARLINK_DEFINE_FIELD_BY_TYPE(fallbackServers, DNSServer, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), - SD_VARLINK_FIELD_COMMENT("Array of configured search domains."), - SD_VARLINK_DEFINE_FIELD_BY_TYPE(searchDomains, SearchDomain, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), - SD_VARLINK_FIELD_COMMENT("Array of configured DNSSEC negative trust anchors."), - SD_VARLINK_DEFINE_FIELD(negativeTrustAnchors, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), - 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_FIELD_COMMENT("LLMNR support."), - 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_FIELD_COMMENT("resolv.conf mode, set for global configuration only."), - SD_VARLINK_DEFINE_FIELD(resolvConfMode, SD_VARLINK_STRING, 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)); - static SD_VARLINK_DEFINE_METHOD_FULL( SubscribeDNSConfiguration, SD_VARLINK_REQUIRES_MORE, diff --git a/src/shared/varlink-io.systemd.Resolve.c b/src/shared/varlink-io.systemd.Resolve.c index 80835aef4f6..bdc0d9cd076 100644 --- a/src/shared/varlink-io.systemd.Resolve.c +++ b/src/shared/varlink-io.systemd.Resolve.c @@ -170,6 +170,80 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( SD_VARLINK_DEFINE_FIELD_BY_TYPE(rr, ResourceRecord, SD_VARLINK_NULLABLE), SD_VARLINK_DEFINE_FIELD(raw, SD_VARLINK_STRING, 0)); +SD_VARLINK_DEFINE_STRUCT_TYPE( + DNSServer, + SD_VARLINK_FIELD_COMMENT("IPv4 or IPv6 address of the server."), + SD_VARLINK_DEFINE_FIELD(address, SD_VARLINK_INT, SD_VARLINK_ARRAY), + SD_VARLINK_FIELD_COMMENT("IPv4 or IPv6 address of the server, formatted as a human-readable string."), + SD_VARLINK_DEFINE_FIELD(addressString, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Address family of the server, one of AF_INET or AF_INET6."), + SD_VARLINK_DEFINE_FIELD(family, SD_VARLINK_INT, 0), + SD_VARLINK_FIELD_COMMENT("Port number of the server."), + SD_VARLINK_DEFINE_FIELD(port, SD_VARLINK_INT, 0), + SD_VARLINK_FIELD_COMMENT("Interface index for which this server is configured."), + SD_VARLINK_DEFINE_FIELD(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Server Name Indication (SNI) of the server."), + SD_VARLINK_DEFINE_FIELD(name, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Indicates if the DNS server is accessible or not."), + SD_VARLINK_DEFINE_FIELD(accessible, SD_VARLINK_BOOL, 0)); + +SD_VARLINK_DEFINE_STRUCT_TYPE( + SearchDomain, + SD_VARLINK_FIELD_COMMENT("Domain name."), + SD_VARLINK_DEFINE_FIELD(name, SD_VARLINK_STRING, 0), + SD_VARLINK_FIELD_COMMENT("Indicates whether or not this is a routing-only domain."), + SD_VARLINK_DEFINE_FIELD(routeOnly, SD_VARLINK_BOOL, 0), + SD_VARLINK_FIELD_COMMENT("Interface index for which this search domain is configured."), + SD_VARLINK_DEFINE_FIELD(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); + +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_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."), + SD_VARLINK_DEFINE_FIELD(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Interface name associated with this scope."), + SD_VARLINK_DEFINE_FIELD(ifname, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + 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_STRUCT_TYPE( + DNSConfiguration, + SD_VARLINK_FIELD_COMMENT("Interface name, if any, associated with this configuration. Empty for global configuration."), + SD_VARLINK_DEFINE_FIELD(ifname, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Interface index, if any, associated with this configuration. Empty for global configuration."), + SD_VARLINK_DEFINE_FIELD(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Delegate name, if any, associated with this configuration. Empty for global or link configurations."), + SD_VARLINK_DEFINE_FIELD(delegate, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Indicates whether or not this link's DNS servers will be used for resolving domain names that do not match any link's configured domains."), + SD_VARLINK_DEFINE_FIELD(defaultRoute, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("DNS server currently selected to use for lookups."), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(currentServer, DNSServer, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Array of configured DNS servers."), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(servers, DNSServer, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Array of configured fallback DNS servers, set for global configuration only."), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(fallbackServers, DNSServer, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Array of configured search domains."), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(searchDomains, SearchDomain, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Array of configured DNSSEC negative trust anchors."), + SD_VARLINK_DEFINE_FIELD(negativeTrustAnchors, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + 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_FIELD_COMMENT("LLMNR support."), + 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_FIELD_COMMENT("resolv.conf mode, set for global configuration only."), + SD_VARLINK_DEFINE_FIELD(resolvConfMode, SD_VARLINK_STRING, 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)); + static SD_VARLINK_DEFINE_METHOD( ResolveRecord, SD_VARLINK_DEFINE_INPUT(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), @@ -194,6 +268,11 @@ static SD_VARLINK_DEFINE_METHOD_FULL( SD_VARLINK_FIELD_COMMENT("An array of service data containing information about discovered services."), SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(browserServiceData, ServiceData, SD_VARLINK_ARRAY)); +static SD_VARLINK_DEFINE_METHOD( + DumpDNSConfiguration, + SD_VARLINK_FIELD_COMMENT("The current global and per-interface DNS configurations"), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(configuration, DNSConfiguration, SD_VARLINK_ARRAY)); + static SD_VARLINK_DEFINE_ERROR(NoNameServers); static SD_VARLINK_DEFINE_ERROR(NoSuchResourceRecord); static SD_VARLINK_DEFINE_ERROR(QueryTimedOut); @@ -236,6 +315,8 @@ SD_VARLINK_DEFINE_INTERFACE( &vl_method_ResolveRecord, SD_VARLINK_SYMBOL_COMMENT("Starts browsing for DNS-SD services of specified type."), &vl_method_BrowseServices, + SD_VARLINK_SYMBOL_COMMENT("Current global and per-link DNS configurations."), + &vl_method_DumpDNSConfiguration, SD_VARLINK_SYMBOL_COMMENT("Encapsulates a resolved address."), &vl_type_ResolvedAddress, SD_VARLINK_SYMBOL_COMMENT("Encapsulates a resolved host name."), @@ -254,6 +335,14 @@ SD_VARLINK_DEFINE_INTERFACE( &vl_type_BrowseServiceUpdateFlag, SD_VARLINK_SYMBOL_COMMENT("Encapsulates the service data obtained from browsing."), &vl_type_ServiceData, + SD_VARLINK_SYMBOL_COMMENT("Encapsulates a DNS server address specification."), + &vl_type_DNSServer, + SD_VARLINK_SYMBOL_COMMENT("Encapsulates a search domain specification."), + &vl_type_SearchDomain, + SD_VARLINK_SYMBOL_COMMENT("Encapsulates a global or per-link DNS configuration, including configured DNS servers, search domains, and more."), + &vl_type_DNSConfiguration, + SD_VARLINK_SYMBOL_COMMENT("Encapsulates a DNS scope specification."), + &vl_type_DNSScope, &vl_error_NoNameServers, &vl_error_NoSuchResourceRecord, &vl_error_QueryTimedOut, diff --git a/src/shared/varlink-io.systemd.Resolve.h b/src/shared/varlink-io.systemd.Resolve.h index b7a828530d1..48fdabe13cd 100644 --- a/src/shared/varlink-io.systemd.Resolve.h +++ b/src/shared/varlink-io.systemd.Resolve.h @@ -5,5 +5,9 @@ extern const sd_varlink_symbol vl_type_ResourceKey; extern const sd_varlink_symbol vl_type_ResourceRecord; +extern const sd_varlink_symbol vl_type_DNSServer; +extern const sd_varlink_symbol vl_type_DNSScope; +extern const sd_varlink_symbol vl_type_SearchDomain; +extern const sd_varlink_symbol vl_type_DNSConfiguration; extern const sd_varlink_interface vl_interface_io_systemd_Resolve; -- 2.47.3