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: a7a4c60a25
This commit is contained in:
dongshengyuan
2026-08-13 17:40:49 +08:00
parent 32ac7af788
commit e021a64391
2 changed files with 21 additions and 10 deletions
+15 -7
View File
@@ -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)"):
+6 -3
View File
@@ -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"