From e021a64391c29d28b06bd2090ef6e6758db51a2b Mon Sep 17 00:00:00 2001 From: dongshengyuan <545258830@qq.com> Date: Thu, 13 Aug 2026 10:07:52 +0800 Subject: [PATCH] resolvectl: avoid TXT lookup for plain SRV service queries The service verb documents the one- and two-argument forms as SRV lookups. They should not request TXT records by default. Only the three-argument DNS-SD form should request TXT metadata. Reproducer: Run resolvectl service _mysvc._tcp signed.test in the TEST-75-RESOLVED environment, where signed.test contains: _mysvc._tcp SRV 10 5 1234 myservice _mysvc._tcp TXT "This is TXT for myservice" myservice A 10.0.0.20 Before: resolvectl service _mysvc._tcp signed.test printed TXT data for the plain SRV form: _mysvc._tcp/signed.test: myservice.signed.test:1234 [priority=10, weight=5] 10.0.0.20 fd00:dead:beef:cafe::17 This is TXT for myservice After: The plain SRV form suppresses TXT data. The DNS-SD form still shows it: resolvectl service '' _mysvc._tcp signed.test Follow-up for: a7a4c60a253a181385764bcb542906a312b68fe9 --- src/resolve/resolvectl.c | 22 +++++++++++++++------- test/units/TEST-75-RESOLVED.sh | 9 ++++++--- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index 9af5626059..d77ae3d631 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -71,6 +71,7 @@ static sd_json_format_flags_t arg_json_format_flags = SD_JSON_FORMAT_OFF; static PagerFlags arg_pager_flags = 0; bool arg_ifindex_permissive = false; /* If true, don't generate an error if the specified interface index doesn't exist */ static const char *arg_service_family = NULL; +static bool arg_service_txt_set = false; static bool arg_ask_password = true; typedef enum RawType { @@ -904,7 +905,7 @@ static int verb_query(int argc, char *argv[], uintptr_t _data, void *userdata) { return ret; } -static int resolve_service(const char *name, const char *type, const char *domain) { +static int resolve_service(const char *name, const char *type, const char *domain, uint64_t flags) { int r; assert(domain); @@ -938,7 +939,7 @@ static int resolve_service(const char *name, const char *type, const char *domai JSON_BUILD_PAIR_STRING_NON_EMPTY("type", type), JSON_BUILD_PAIR_CONDITION_UNSIGNED(arg_ifindex > 0, "ifindex", arg_ifindex), JSON_BUILD_PAIR_CONDITION_UNSIGNED(arg_family != AF_UNSPEC, "family", arg_family), - JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("flags", arg_flags)); + JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("flags", flags)); if (r < 0) return log_error_errno(r, "Failed to issue varlink call: %m"); @@ -1019,15 +1020,20 @@ static int resolve_service(const char *name, const char *type, const char *domai VERB(verb_service, "service", "[[NAME] TYPE] DOMAIN", 2, 4, 0, "Resolve service (SRV)"); static int verb_service(int argc, char *argv[], uintptr_t _data, void *userdata) { + uint64_t flags = arg_flags; + if (sd_json_format_enabled(arg_json_format_flags)) return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Use --json=pretty with --type= to acquire resource record information in JSON format."); + if (argc < 4 && !arg_service_txt_set) + flags |= SD_RESOLVED_NO_TXT; + if (argc == 2) - return resolve_service(NULL, NULL, argv[1]); - else if (argc == 3) - return resolve_service(NULL, argv[1], argv[2]); - else - return resolve_service(argv[1], argv[2], argv[3]); + return resolve_service(NULL, NULL, argv[1], flags); + if (argc == 3) + return resolve_service(NULL, argv[1], argv[2], flags); + + return resolve_service(argv[1], argv[2], argv[3], flags); } #if HAVE_OPENSSL @@ -3360,6 +3366,7 @@ static int compat_parse_argv(int argc, char *argv[], char ***remaining_args) { if (r < 0) return r; SET_FLAG(arg_flags, SD_RESOLVED_NO_TXT, r == 0); + arg_service_txt_set = true; break; OPTION_LONG("openpgp", NULL, "Query OpenPGP public key"): @@ -3594,6 +3601,7 @@ static int native_parse_argv(int argc, char *argv[], char ***remaining_args) { if (r < 0) return r; SET_FLAG(arg_flags, SD_RESOLVED_NO_TXT, r == 0); + arg_service_txt_set = true; break; OPTION_LONG("cname", "BOOL", "Follow CNAME redirects (default: yes)"): diff --git a/test/units/TEST-75-RESOLVED.sh b/test/units/TEST-75-RESOLVED.sh index 85e9e4cc84..9f18f3dcf3 100755 --- a/test/units/TEST-75-RESOLVED.sh +++ b/test/units/TEST-75-RESOLVED.sh @@ -579,10 +579,13 @@ testcase_08_resolved() { # Check SRV support run resolvectl service _mysvc._tcp signed.test grep -qF "myservice.signed.test:1234" "$RUN_OUT" - grep -qF "This is TXT for myservice" "$RUN_OUT" + (! grep -qF "This is TXT for myservice" "$RUN_OUT") grep -qF "10.0.0.20" "$RUN_OUT" grep -qF "fd00:dead:beef:cafe::17" "$RUN_OUT" grep -qF "authenticated: yes" "$RUN_OUT" + run resolvectl service "" _mysvc._tcp signed.test + grep -qF "myservice.signed.test:1234" "$RUN_OUT" + grep -qF "This is TXT for myservice" "$RUN_OUT" # Test service resolve over Varlink run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveService '{"name":"","type":"_mysvc._tcp","domain":"signed.test"}' @@ -1338,7 +1341,7 @@ testcase_14_refuse_record_types() { run resolvectl service _mysvc._tcp signed.test grep -qF "myservice.signed.test:1234" "$RUN_OUT" - grep -qF "This is TXT for myservice" "$RUN_OUT" + (! grep -qF "This is TXT for myservice" "$RUN_OUT") grep -qF "10.0.0.20" "$RUN_OUT" (! grep -qF "fd00:dead:beef:cafe::17" "$RUN_OUT") grep -qF "authenticated: yes" "$RUN_OUT" @@ -1360,7 +1363,7 @@ testcase_14_refuse_record_types() { run resolvectl service _mysvc._tcp signed.test grep -qF "myservice.signed.test:1234" "$RUN_OUT" - grep -qF "This is TXT for myservice" "$RUN_OUT" + (! grep -qF "This is TXT for myservice" "$RUN_OUT") (! grep -qF "10.0.0.20" "$RUN_OUT") (! grep -qF "fd00:dead:beef:cafe::17" "$RUN_OUT") grep -qF "authenticated: yes" "$RUN_OUT"