1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 #include "alloc-util.h"
4 #include "bus-common-errors.h"
6 #include "dns-domain.h"
7 #include "memory-util.h"
8 #include "missing_capability.h"
9 #include "resolved-bus.h"
10 #include "resolved-def.h"
11 #include "resolved-dns-synthesize.h"
12 #include "resolved-dnssd-bus.h"
13 #include "resolved-dnssd.h"
14 #include "resolved-link-bus.h"
15 #include "user-util.h"
18 BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_resolve_support
, resolve_support
, ResolveSupport
);
20 static int reply_query_state(DnsQuery
*q
) {
24 case DNS_TRANSACTION_NO_SERVERS
:
25 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_NAME_SERVERS
, "No appropriate name servers or networks for name found");
27 case DNS_TRANSACTION_TIMEOUT
:
28 return sd_bus_reply_method_errorf(q
->request
, SD_BUS_ERROR_TIMEOUT
, "Query timed out");
30 case DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
:
31 return sd_bus_reply_method_errorf(q
->request
, SD_BUS_ERROR_TIMEOUT
, "All attempts to contact name servers or networks failed");
33 case DNS_TRANSACTION_INVALID_REPLY
:
34 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_INVALID_REPLY
, "Received invalid reply");
36 case DNS_TRANSACTION_ERRNO
:
37 return sd_bus_reply_method_errnof(q
->request
, q
->answer_errno
, "Lookup failed due to system error: %m");
39 case DNS_TRANSACTION_ABORTED
:
40 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_ABORTED
, "Query aborted");
42 case DNS_TRANSACTION_DNSSEC_FAILED
:
43 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_DNSSEC_FAILED
, "DNSSEC validation failed: %s",
44 dnssec_result_to_string(q
->answer_dnssec_result
));
46 case DNS_TRANSACTION_NO_TRUST_ANCHOR
:
47 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_TRUST_ANCHOR
, "No suitable trust anchor known");
49 case DNS_TRANSACTION_RR_TYPE_UNSUPPORTED
:
50 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_RR_TYPE_UNSUPPORTED
, "Server does not support requested resource record type");
52 case DNS_TRANSACTION_NETWORK_DOWN
:
53 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NETWORK_DOWN
, "Network is down");
55 case DNS_TRANSACTION_NOT_FOUND
:
56 /* We return this as NXDOMAIN. This is only generated when a host doesn't implement LLMNR/TCP, and we
57 * thus quickly know that we cannot resolve an in-addr.arpa or ip6.arpa address. */
58 return sd_bus_reply_method_errorf(q
->request
, _BUS_ERROR_DNS
"NXDOMAIN", "'%s' not found", dns_query_string(q
));
60 case DNS_TRANSACTION_RCODE_FAILURE
: {
61 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
63 if (q
->answer_rcode
== DNS_RCODE_NXDOMAIN
)
64 sd_bus_error_setf(&error
, _BUS_ERROR_DNS
"NXDOMAIN", "'%s' not found", dns_query_string(q
));
67 char p
[DECIMAL_STR_MAX(q
->answer_rcode
)];
69 rc
= dns_rcode_to_string(q
->answer_rcode
);
71 sprintf(p
, "%i", q
->answer_rcode
);
75 n
= strjoina(_BUS_ERROR_DNS
, rc
);
76 sd_bus_error_setf(&error
, n
, "Could not resolve '%s', server or network returned error %s", dns_query_string(q
), rc
);
79 return sd_bus_reply_method_error(q
->request
, &error
);
82 case DNS_TRANSACTION_NULL
:
83 case DNS_TRANSACTION_PENDING
:
84 case DNS_TRANSACTION_VALIDATING
:
85 case DNS_TRANSACTION_SUCCESS
:
87 assert_not_reached("Impossible state");
91 static int append_address(sd_bus_message
*reply
, DnsResourceRecord
*rr
, int ifindex
) {
97 r
= sd_bus_message_open_container(reply
, 'r', "iiay");
101 r
= sd_bus_message_append(reply
, "i", ifindex
);
105 if (rr
->key
->type
== DNS_TYPE_A
) {
106 r
= sd_bus_message_append(reply
, "i", AF_INET
);
110 r
= sd_bus_message_append_array(reply
, 'y', &rr
->a
.in_addr
, sizeof(struct in_addr
));
112 } else if (rr
->key
->type
== DNS_TYPE_AAAA
) {
113 r
= sd_bus_message_append(reply
, "i", AF_INET6
);
117 r
= sd_bus_message_append_array(reply
, 'y', &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
));
119 return -EAFNOSUPPORT
;
124 r
= sd_bus_message_close_container(reply
);
131 static void bus_method_resolve_hostname_complete(DnsQuery
*q
) {
132 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*canonical
= NULL
;
133 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
134 _cleanup_free_
char *normalized
= NULL
;
135 DnsResourceRecord
*rr
;
141 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
142 r
= reply_query_state(q
);
146 r
= dns_query_process_cname(q
);
148 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_CNAME_LOOP
, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q
));
153 if (r
== DNS_QUERY_RESTARTED
) /* This was a cname, and the query was restarted. */
156 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
160 r
= sd_bus_message_open_container(reply
, 'a', "(iiay)");
164 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
165 DnsQuestion
*question
;
167 question
= dns_query_question_for_protocol(q
, q
->answer_protocol
);
169 r
= dns_question_matches_rr(question
, rr
, DNS_SEARCH_DOMAIN_NAME(q
->answer_search_domain
));
175 r
= append_address(reply
, rr
, ifindex
);
180 canonical
= dns_resource_record_ref(rr
);
186 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_SUCH_RR
, "'%s' does not have any RR of the requested type", dns_query_string(q
));
190 r
= sd_bus_message_close_container(reply
);
194 /* The key names are not necessarily normalized, make sure that they are when we return them to our bus
196 r
= dns_name_normalize(dns_resource_key_name(canonical
->key
), 0, &normalized
);
200 /* Return the precise spelling and uppercasing and CNAME target reported by the server */
202 r
= sd_bus_message_append(
205 SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
, dns_query_fully_authenticated(q
)));
209 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
213 log_error_errno(r
, "Failed to send hostname reply: %m");
214 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
220 static int check_ifindex_flags(int ifindex
, uint64_t *flags
, uint64_t ok
, sd_bus_error
*error
) {
224 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid interface index");
226 if (*flags
& ~(SD_RESOLVED_PROTOCOLS_ALL
|SD_RESOLVED_NO_CNAME
|ok
))
227 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid flags parameter");
229 if ((*flags
& SD_RESOLVED_PROTOCOLS_ALL
) == 0) /* If no protocol is enabled, enable all */
230 *flags
|= SD_RESOLVED_PROTOCOLS_ALL
;
235 static int parse_as_address(sd_bus_message
*m
, int ifindex
, const char *hostname
, int family
, uint64_t flags
) {
236 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
237 _cleanup_free_
char *canonical
= NULL
;
238 union in_addr_union parsed
;
239 int r
, ff
, parsed_ifindex
= 0;
241 /* Check if the hostname is actually already an IP address formatted as string. In that case just parse it,
242 * let's not attempt to look it up. */
244 r
= in_addr_ifindex_from_string_auto(hostname
, &ff
, &parsed
, &parsed_ifindex
);
245 if (r
< 0) /* not an address */
248 if (family
!= AF_UNSPEC
&& ff
!= family
)
249 return sd_bus_reply_method_errorf(m
, BUS_ERROR_NO_SUCH_RR
, "The specified address is not of the requested family.");
250 if (ifindex
> 0 && parsed_ifindex
> 0 && parsed_ifindex
!= ifindex
)
251 return sd_bus_reply_method_errorf(m
, BUS_ERROR_NO_SUCH_RR
, "The specified address interface index does not match requested interface.");
253 if (parsed_ifindex
> 0)
254 ifindex
= parsed_ifindex
;
256 r
= sd_bus_message_new_method_return(m
, &reply
);
260 r
= sd_bus_message_open_container(reply
, 'a', "(iiay)");
264 r
= sd_bus_message_open_container(reply
, 'r', "iiay");
268 r
= sd_bus_message_append(reply
, "ii", ifindex
, ff
);
272 r
= sd_bus_message_append_array(reply
, 'y', &parsed
, FAMILY_ADDRESS_SIZE(ff
));
276 r
= sd_bus_message_close_container(reply
);
280 r
= sd_bus_message_close_container(reply
);
284 /* When an IP address is specified we just return it as canonical name, in order to avoid a DNS
285 * look-up. However, we reformat it to make sure it's in a truly canonical form (i.e. on IPv6 the inner
286 * omissions are always done the same way). */
287 r
= in_addr_ifindex_to_string(ff
, &parsed
, ifindex
, &canonical
);
291 r
= sd_bus_message_append(reply
, "st", canonical
,
292 SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(flags
), ff
, true));
296 return sd_bus_send(sd_bus_message_get_bus(m
), reply
, NULL
);
299 static int bus_method_resolve_hostname(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
300 _cleanup_(dns_question_unrefp
) DnsQuestion
*question_idna
= NULL
, *question_utf8
= NULL
;
301 Manager
*m
= userdata
;
302 const char *hostname
;
311 assert_cc(sizeof(int) == sizeof(int32_t));
313 r
= sd_bus_message_read(message
, "isit", &ifindex
, &hostname
, &family
, &flags
);
317 if (!IN_SET(family
, AF_INET
, AF_INET6
, AF_UNSPEC
))
318 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown address family %i", family
);
320 r
= check_ifindex_flags(ifindex
, &flags
, SD_RESOLVED_NO_SEARCH
, error
);
324 r
= parse_as_address(message
, ifindex
, hostname
, family
, flags
);
328 r
= dns_name_is_valid(hostname
);
332 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid hostname '%s'", hostname
);
334 r
= dns_question_new_address(&question_utf8
, family
, hostname
, false);
338 r
= dns_question_new_address(&question_idna
, family
, hostname
, true);
339 if (r
< 0 && r
!= -EALREADY
)
342 r
= dns_query_new(m
, &q
, question_utf8
, question_idna
?: question_utf8
, ifindex
, flags
);
346 q
->request
= sd_bus_message_ref(message
);
347 q
->request_family
= family
;
348 q
->complete
= bus_method_resolve_hostname_complete
;
349 q
->suppress_unroutable_family
= family
== AF_UNSPEC
;
351 r
= dns_query_bus_track(q
, message
);
366 static void bus_method_resolve_address_complete(DnsQuery
*q
) {
367 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
368 DnsQuestion
*question
;
369 DnsResourceRecord
*rr
;
375 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
376 r
= reply_query_state(q
);
380 r
= dns_query_process_cname(q
);
382 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_CNAME_LOOP
, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q
));
387 if (r
== DNS_QUERY_RESTARTED
) /* This was a cname, and the query was restarted. */
390 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
394 r
= sd_bus_message_open_container(reply
, 'a', "(is)");
398 question
= dns_query_question_for_protocol(q
, q
->answer_protocol
);
400 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
401 _cleanup_free_
char *normalized
= NULL
;
403 r
= dns_question_matches_rr(question
, rr
, NULL
);
409 r
= dns_name_normalize(rr
->ptr
.name
, 0, &normalized
);
413 r
= sd_bus_message_append(reply
, "(is)", ifindex
, normalized
);
421 _cleanup_free_
char *ip
= NULL
;
423 (void) in_addr_to_string(q
->request_family
, &q
->request_address
, &ip
);
424 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_SUCH_RR
,
425 "Address '%s' does not have any RR of requested type", strnull(ip
));
429 r
= sd_bus_message_close_container(reply
);
433 r
= sd_bus_message_append(reply
, "t", SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
, dns_query_fully_authenticated(q
)));
437 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
441 log_error_errno(r
, "Failed to send address reply: %m");
442 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
448 static int bus_method_resolve_address(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
449 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
450 Manager
*m
= userdata
;
461 assert_cc(sizeof(int) == sizeof(int32_t));
463 r
= sd_bus_message_read(message
, "ii", &ifindex
, &family
);
467 if (!IN_SET(family
, AF_INET
, AF_INET6
))
468 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown address family %i", family
);
470 r
= sd_bus_message_read_array(message
, 'y', &d
, &sz
);
474 if (sz
!= FAMILY_ADDRESS_SIZE(family
))
475 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid address size");
477 r
= sd_bus_message_read(message
, "t", &flags
);
481 r
= check_ifindex_flags(ifindex
, &flags
, 0, error
);
485 r
= dns_question_new_reverse(&question
, family
, d
);
489 r
= dns_query_new(m
, &q
, question
, question
, ifindex
, flags
|SD_RESOLVED_NO_SEARCH
);
493 q
->request
= sd_bus_message_ref(message
);
494 q
->request_family
= family
;
495 memcpy(&q
->request_address
, d
, sz
);
496 q
->complete
= bus_method_resolve_address_complete
;
498 r
= dns_query_bus_track(q
, message
);
513 static int bus_message_append_rr(sd_bus_message
*m
, DnsResourceRecord
*rr
, int ifindex
) {
519 r
= sd_bus_message_open_container(m
, 'r', "iqqay");
523 r
= sd_bus_message_append(m
, "iqq",
530 r
= dns_resource_record_to_wire_format(rr
, false);
534 r
= sd_bus_message_append_array(m
, 'y', rr
->wire_format
, rr
->wire_format_size
);
538 return sd_bus_message_close_container(m
);
541 static void bus_method_resolve_record_complete(DnsQuery
*q
) {
542 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
543 DnsResourceRecord
*rr
;
544 DnsQuestion
*question
;
551 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
552 r
= reply_query_state(q
);
556 r
= dns_query_process_cname(q
);
558 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_CNAME_LOOP
, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q
));
563 if (r
== DNS_QUERY_RESTARTED
) /* This was a cname, and the query was restarted. */
566 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
570 r
= sd_bus_message_open_container(reply
, 'a', "(iqqay)");
574 question
= dns_query_question_for_protocol(q
, q
->answer_protocol
);
576 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
577 r
= dns_question_matches_rr(question
, rr
, NULL
);
583 r
= bus_message_append_rr(reply
, rr
, ifindex
);
591 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_SUCH_RR
, "Name '%s' does not have any RR of the requested type", dns_query_string(q
));
595 r
= sd_bus_message_close_container(reply
);
599 r
= sd_bus_message_append(reply
, "t", SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
, dns_query_fully_authenticated(q
)));
603 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
607 log_error_errno(r
, "Failed to send record reply: %m");
608 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
614 static int bus_method_resolve_record(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
615 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
616 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
617 Manager
*m
= userdata
;
618 uint16_t class, type
;
627 assert_cc(sizeof(int) == sizeof(int32_t));
629 r
= sd_bus_message_read(message
, "isqqt", &ifindex
, &name
, &class, &type
, &flags
);
633 r
= dns_name_is_valid(name
);
637 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid name '%s'", name
);
639 if (!dns_type_is_valid_query(type
))
640 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Specified resource record type %" PRIu16
" may not be used in a query.", type
);
641 if (dns_type_is_zone_transer(type
))
642 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Zone transfers not permitted via this programming interface.");
643 if (dns_type_is_obsolete(type
))
644 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Specified DNS resource record type %" PRIu16
" is obsolete.", type
);
646 r
= check_ifindex_flags(ifindex
, &flags
, 0, error
);
650 question
= dns_question_new(1);
654 key
= dns_resource_key_new(class, type
, name
);
658 r
= dns_question_add(question
, key
);
662 r
= dns_query_new(m
, &q
, question
, question
, ifindex
, flags
|SD_RESOLVED_NO_SEARCH
);
666 /* Let's request that the TTL is fixed up for locally cached entries, after all we return it in the wire format
670 q
->request
= sd_bus_message_ref(message
);
671 q
->complete
= bus_method_resolve_record_complete
;
673 r
= dns_query_bus_track(q
, message
);
688 static int append_srv(DnsQuery
*q
, sd_bus_message
*reply
, DnsResourceRecord
*rr
) {
689 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*canonical
= NULL
;
690 _cleanup_free_
char *normalized
= NULL
;
699 if (rr
->key
->type
!= DNS_TYPE_SRV
)
702 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
703 /* First, let's see if we could find an appropriate A or AAAA
704 * record for the SRV record */
705 LIST_FOREACH(auxiliary_queries
, aux
, q
->auxiliary_queries
) {
706 DnsResourceRecord
*zz
;
707 DnsQuestion
*question
;
709 if (aux
->state
!= DNS_TRANSACTION_SUCCESS
)
711 if (aux
->auxiliary_result
!= 0)
714 question
= dns_query_question_for_protocol(aux
, aux
->answer_protocol
);
716 r
= dns_name_equal(dns_question_first_name(question
), rr
->srv
.name
);
722 DNS_ANSWER_FOREACH(zz
, aux
->answer
) {
724 r
= dns_question_matches_rr(question
, zz
, NULL
);
730 canonical
= dns_resource_record_ref(zz
);
738 /* Is there are successful A/AAAA lookup for this SRV RR? If not, don't add it */
743 r
= sd_bus_message_open_container(reply
, 'r', "qqqsa(iiay)s");
747 r
= dns_name_normalize(rr
->srv
.name
, 0, &normalized
);
751 r
= sd_bus_message_append(
754 rr
->srv
.priority
, rr
->srv
.weight
, rr
->srv
.port
, normalized
);
758 r
= sd_bus_message_open_container(reply
, 'a', "(iiay)");
762 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
763 LIST_FOREACH(auxiliary_queries
, aux
, q
->auxiliary_queries
) {
764 DnsResourceRecord
*zz
;
765 DnsQuestion
*question
;
768 if (aux
->state
!= DNS_TRANSACTION_SUCCESS
)
770 if (aux
->auxiliary_result
!= 0)
773 question
= dns_query_question_for_protocol(aux
, aux
->answer_protocol
);
775 r
= dns_name_equal(dns_question_first_name(question
), rr
->srv
.name
);
781 DNS_ANSWER_FOREACH_IFINDEX(zz
, ifindex
, aux
->answer
) {
783 r
= dns_question_matches_rr(question
, zz
, NULL
);
789 r
= append_address(reply
, zz
, ifindex
);
796 r
= sd_bus_message_close_container(reply
);
801 normalized
= mfree(normalized
);
803 r
= dns_name_normalize(dns_resource_key_name(canonical
->key
), 0, &normalized
);
808 /* Note that above we appended the hostname as encoded in the
809 * SRV, and here the canonical hostname this maps to. */
810 r
= sd_bus_message_append(reply
, "s", normalized
);
814 r
= sd_bus_message_close_container(reply
);
821 static int append_txt(sd_bus_message
*reply
, DnsResourceRecord
*rr
) {
829 if (rr
->key
->type
!= DNS_TYPE_TXT
)
832 LIST_FOREACH(items
, i
, rr
->txt
.items
) {
837 r
= sd_bus_message_append_array(reply
, 'y', i
->data
, i
->length
);
845 static void resolve_service_all_complete(DnsQuery
*q
) {
846 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*canonical
= NULL
;
847 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
848 _cleanup_free_
char *name
= NULL
, *type
= NULL
, *domain
= NULL
;
849 DnsQuestion
*question
;
850 DnsResourceRecord
*rr
;
857 if (q
->block_all_complete
> 0)
860 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
861 DnsQuery
*bad
= NULL
;
862 bool have_success
= false;
864 LIST_FOREACH(auxiliary_queries
, aux
, q
->auxiliary_queries
) {
866 switch (aux
->state
) {
868 case DNS_TRANSACTION_PENDING
:
869 /* If an auxiliary query is still pending, let's wait */
872 case DNS_TRANSACTION_SUCCESS
:
873 if (aux
->auxiliary_result
== 0)
886 /* We can only return one error, hence pick the last error we encountered */
890 if (bad
->state
== DNS_TRANSACTION_SUCCESS
) {
891 assert(bad
->auxiliary_result
!= 0);
893 if (bad
->auxiliary_result
== -ELOOP
) {
894 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_CNAME_LOOP
, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(bad
));
898 r
= bad
->auxiliary_result
;
902 r
= reply_query_state(bad
);
907 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
911 r
= sd_bus_message_open_container(reply
, 'a', "(qqqsa(iiay)s)");
915 question
= dns_query_question_for_protocol(q
, q
->answer_protocol
);
916 DNS_ANSWER_FOREACH(rr
, q
->answer
) {
917 r
= dns_question_matches_rr(question
, rr
, NULL
);
923 r
= append_srv(q
, reply
, rr
);
926 if (r
== 0) /* not an SRV record */
930 canonical
= dns_resource_record_ref(rr
);
936 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_SUCH_RR
, "'%s' does not have any RR of the requested type", dns_query_string(q
));
940 r
= sd_bus_message_close_container(reply
);
944 r
= sd_bus_message_open_container(reply
, 'a', "ay");
948 DNS_ANSWER_FOREACH(rr
, q
->answer
) {
949 r
= dns_question_matches_rr(question
, rr
, NULL
);
955 r
= append_txt(reply
, rr
);
960 r
= sd_bus_message_close_container(reply
);
965 r
= dns_service_split(dns_resource_key_name(canonical
->key
), &name
, &type
, &domain
);
969 r
= sd_bus_message_append(
973 SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
, dns_query_fully_authenticated(q
)));
977 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
981 log_error_errno(r
, "Failed to send service reply: %m");
982 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
988 static void resolve_service_hostname_complete(DnsQuery
*q
) {
992 assert(q
->auxiliary_for
);
994 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
995 resolve_service_all_complete(q
->auxiliary_for
);
999 r
= dns_query_process_cname(q
);
1000 if (r
== DNS_QUERY_RESTARTED
) /* This was a cname, and the query was restarted. */
1003 /* This auxiliary lookup is finished or failed, let's see if all are finished now. */
1004 q
->auxiliary_result
= r
;
1005 resolve_service_all_complete(q
->auxiliary_for
);
1008 static int resolve_service_hostname(DnsQuery
*q
, DnsResourceRecord
*rr
, int ifindex
) {
1009 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
1016 assert(rr
->key
->type
== DNS_TYPE_SRV
);
1018 /* OK, we found an SRV record for the service. Let's resolve
1019 * the hostname included in it */
1021 r
= dns_question_new_address(&question
, q
->request_family
, rr
->srv
.name
, false);
1025 r
= dns_query_new(q
->manager
, &aux
, question
, question
, ifindex
, q
->flags
|SD_RESOLVED_NO_SEARCH
);
1029 aux
->request_family
= q
->request_family
;
1030 aux
->complete
= resolve_service_hostname_complete
;
1032 r
= dns_query_make_auxiliary(aux
, q
);
1034 /* Too many auxiliary lookups? If so, don't complain,
1035 * let's just not add this one, we already have more
1038 dns_query_free(aux
);
1044 /* Note that auxiliary queries do not track the original bus
1045 * client, only the primary request does that. */
1047 r
= dns_query_go(aux
);
1054 dns_query_free(aux
);
1058 static void bus_method_resolve_service_complete(DnsQuery
*q
) {
1059 bool has_root_domain
= false;
1060 DnsResourceRecord
*rr
;
1061 DnsQuestion
*question
;
1067 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
1068 r
= reply_query_state(q
);
1072 r
= dns_query_process_cname(q
);
1074 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_CNAME_LOOP
, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q
));
1079 if (r
== DNS_QUERY_RESTARTED
) /* This was a cname, and the query was restarted. */
1082 question
= dns_query_question_for_protocol(q
, q
->answer_protocol
);
1084 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
1085 r
= dns_question_matches_rr(question
, rr
, NULL
);
1091 if (rr
->key
->type
!= DNS_TYPE_SRV
)
1094 if (dns_name_is_root(rr
->srv
.name
)) {
1095 has_root_domain
= true;
1099 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
1100 q
->block_all_complete
++;
1101 r
= resolve_service_hostname(q
, rr
, ifindex
);
1102 q
->block_all_complete
--;
1111 if (has_root_domain
&& found
<= 0) {
1112 /* If there's exactly one SRV RR and it uses
1113 * the root domain as host name, then the
1114 * service is explicitly not offered on the
1115 * domain. Report this as a recognizable
1116 * error. See RFC 2782, Section "Usage
1118 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_SUCH_SERVICE
, "'%s' does not provide the requested service", dns_query_string(q
));
1123 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_SUCH_RR
, "'%s' does not have any RR of the requested type", dns_query_string(q
));
1127 /* Maybe we are already finished? check now... */
1128 resolve_service_all_complete(q
);
1133 log_error_errno(r
, "Failed to send service reply: %m");
1134 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
1140 static int bus_method_resolve_service(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1141 _cleanup_(dns_question_unrefp
) DnsQuestion
*question_idna
= NULL
, *question_utf8
= NULL
;
1142 const char *name
, *type
, *domain
;
1143 Manager
*m
= userdata
;
1144 int family
, ifindex
;
1152 assert_cc(sizeof(int) == sizeof(int32_t));
1154 r
= sd_bus_message_read(message
, "isssit", &ifindex
, &name
, &type
, &domain
, &family
, &flags
);
1158 if (!IN_SET(family
, AF_INET
, AF_INET6
, AF_UNSPEC
))
1159 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown address family %i", family
);
1163 else if (!dns_service_name_is_valid(name
))
1164 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid service name '%s'", name
);
1168 else if (!dns_srv_type_is_valid(type
))
1169 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid SRV service type '%s'", type
);
1171 r
= dns_name_is_valid(domain
);
1175 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid domain '%s'", domain
);
1178 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Service name cannot be specified without service type.");
1180 r
= check_ifindex_flags(ifindex
, &flags
, SD_RESOLVED_NO_TXT
|SD_RESOLVED_NO_ADDRESS
, error
);
1184 r
= dns_question_new_service(&question_utf8
, name
, type
, domain
, !(flags
& SD_RESOLVED_NO_TXT
), false);
1188 r
= dns_question_new_service(&question_idna
, name
, type
, domain
, !(flags
& SD_RESOLVED_NO_TXT
), true);
1192 r
= dns_query_new(m
, &q
, question_utf8
, question_idna
, ifindex
, flags
|SD_RESOLVED_NO_SEARCH
);
1196 q
->request
= sd_bus_message_ref(message
);
1197 q
->request_family
= family
;
1198 q
->complete
= bus_method_resolve_service_complete
;
1200 r
= dns_query_bus_track(q
, message
);
1204 r
= dns_query_go(q
);
1215 int bus_dns_server_append(sd_bus_message
*reply
, DnsServer
*s
, bool with_ifindex
) {
1222 return sd_bus_message_append(reply
, "(iiay)", 0, AF_UNSPEC
, 0);
1224 return sd_bus_message_append(reply
, "(iay)", AF_UNSPEC
, 0);
1227 r
= sd_bus_message_open_container(reply
, 'r', with_ifindex
? "iiay" : "iay");
1232 r
= sd_bus_message_append(reply
, "i", dns_server_ifindex(s
));
1237 r
= sd_bus_message_append(reply
, "i", s
->family
);
1241 r
= sd_bus_message_append_array(reply
, 'y', &s
->address
, FAMILY_ADDRESS_SIZE(s
->family
));
1245 return sd_bus_message_close_container(reply
);
1248 static int bus_property_get_dns_servers(
1251 const char *interface
,
1252 const char *property
,
1253 sd_bus_message
*reply
,
1255 sd_bus_error
*error
) {
1257 Manager
*m
= userdata
;
1266 r
= sd_bus_message_open_container(reply
, 'a', "(iiay)");
1270 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
1271 r
= bus_dns_server_append(reply
, s
, true);
1276 HASHMAP_FOREACH(l
, m
->links
, i
) {
1277 LIST_FOREACH(servers
, s
, l
->dns_servers
) {
1278 r
= bus_dns_server_append(reply
, s
, true);
1284 return sd_bus_message_close_container(reply
);
1287 static int bus_property_get_fallback_dns_servers(
1290 const char *interface
,
1291 const char *property
,
1292 sd_bus_message
*reply
,
1294 sd_bus_error
*error
) {
1296 DnsServer
*s
, **f
= userdata
;
1302 r
= sd_bus_message_open_container(reply
, 'a', "(iiay)");
1306 LIST_FOREACH(servers
, s
, *f
) {
1307 r
= bus_dns_server_append(reply
, s
, true);
1312 return sd_bus_message_close_container(reply
);
1315 static int bus_property_get_current_dns_server(
1318 const char *interface
,
1319 const char *property
,
1320 sd_bus_message
*reply
,
1322 sd_bus_error
*error
) {
1329 s
= *(DnsServer
**) userdata
;
1331 return bus_dns_server_append(reply
, s
, true);
1334 static int bus_property_get_domains(
1337 const char *interface
,
1338 const char *property
,
1339 sd_bus_message
*reply
,
1341 sd_bus_error
*error
) {
1343 Manager
*m
= userdata
;
1352 r
= sd_bus_message_open_container(reply
, 'a', "(isb)");
1356 LIST_FOREACH(domains
, d
, m
->search_domains
) {
1357 r
= sd_bus_message_append(reply
, "(isb)", 0, d
->name
, d
->route_only
);
1362 HASHMAP_FOREACH(l
, m
->links
, i
) {
1363 LIST_FOREACH(domains
, d
, l
->search_domains
) {
1364 r
= sd_bus_message_append(reply
, "(isb)", l
->ifindex
, d
->name
, d
->route_only
);
1370 return sd_bus_message_close_container(reply
);
1373 static int bus_property_get_transaction_statistics(
1376 const char *interface
,
1377 const char *property
,
1378 sd_bus_message
*reply
,
1380 sd_bus_error
*error
) {
1382 Manager
*m
= userdata
;
1387 return sd_bus_message_append(reply
, "(tt)",
1388 (uint64_t) hashmap_size(m
->dns_transactions
),
1389 (uint64_t) m
->n_transactions_total
);
1392 static int bus_property_get_cache_statistics(
1395 const char *interface
,
1396 const char *property
,
1397 sd_bus_message
*reply
,
1399 sd_bus_error
*error
) {
1401 uint64_t size
= 0, hit
= 0, miss
= 0;
1402 Manager
*m
= userdata
;
1408 LIST_FOREACH(scopes
, s
, m
->dns_scopes
) {
1409 size
+= dns_cache_size(&s
->cache
);
1410 hit
+= s
->cache
.n_hit
;
1411 miss
+= s
->cache
.n_miss
;
1414 return sd_bus_message_append(reply
, "(ttt)", size
, hit
, miss
);
1417 static int bus_property_get_dnssec_statistics(
1420 const char *interface
,
1421 const char *property
,
1422 sd_bus_message
*reply
,
1424 sd_bus_error
*error
) {
1426 Manager
*m
= userdata
;
1431 return sd_bus_message_append(reply
, "(tttt)",
1432 (uint64_t) m
->n_dnssec_verdict
[DNSSEC_SECURE
],
1433 (uint64_t) m
->n_dnssec_verdict
[DNSSEC_INSECURE
],
1434 (uint64_t) m
->n_dnssec_verdict
[DNSSEC_BOGUS
],
1435 (uint64_t) m
->n_dnssec_verdict
[DNSSEC_INDETERMINATE
]);
1438 static int bus_property_get_ntas(
1441 const char *interface
,
1442 const char *property
,
1443 sd_bus_message
*reply
,
1445 sd_bus_error
*error
) {
1447 Manager
*m
= userdata
;
1455 r
= sd_bus_message_open_container(reply
, 'a', "s");
1459 SET_FOREACH(domain
, m
->trust_anchor
.negative_by_name
, i
) {
1460 r
= sd_bus_message_append(reply
, "s", domain
);
1465 return sd_bus_message_close_container(reply
);
1468 static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_dns_stub_listener_mode
, dns_stub_listener_mode
, DnsStubListenerMode
);
1469 static BUS_DEFINE_PROPERTY_GET(bus_property_get_dnssec_supported
, "b", Manager
, manager_dnssec_supported
);
1470 static BUS_DEFINE_PROPERTY_GET2(bus_property_get_dnssec_mode
, "s", Manager
, manager_get_dnssec_mode
, dnssec_mode_to_string
);
1471 static BUS_DEFINE_PROPERTY_GET2(bus_property_get_dns_over_tls_mode
, "s", Manager
, manager_get_dns_over_tls_mode
, dns_over_tls_mode_to_string
);
1473 static int bus_method_reset_statistics(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1474 Manager
*m
= userdata
;
1480 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1481 s
->cache
.n_hit
= s
->cache
.n_miss
= 0;
1483 m
->n_transactions_total
= 0;
1484 zero(m
->n_dnssec_verdict
);
1486 return sd_bus_reply_method_return(message
, NULL
);
1489 static int get_any_link(Manager
*m
, int ifindex
, Link
**ret
, sd_bus_error
*error
) {
1496 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid interface index");
1498 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
1500 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_LINK
, "Link %i not known", ifindex
);
1506 static int call_link_method(Manager
*m
, sd_bus_message
*message
, sd_bus_message_handler_t handler
, sd_bus_error
*error
) {
1514 assert_cc(sizeof(int) == sizeof(int32_t));
1515 r
= sd_bus_message_read(message
, "i", &ifindex
);
1519 r
= get_any_link(m
, ifindex
, &l
, error
);
1523 return handler(message
, l
, error
);
1526 static int bus_method_set_link_dns_servers(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1527 return call_link_method(userdata
, message
, bus_link_method_set_dns_servers
, error
);
1530 static int bus_method_set_link_domains(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1531 return call_link_method(userdata
, message
, bus_link_method_set_domains
, error
);
1534 static int bus_method_set_link_default_route(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1535 return call_link_method(userdata
, message
, bus_link_method_set_default_route
, error
);
1538 static int bus_method_set_link_llmnr(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1539 return call_link_method(userdata
, message
, bus_link_method_set_llmnr
, error
);
1542 static int bus_method_set_link_mdns(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1543 return call_link_method(userdata
, message
, bus_link_method_set_mdns
, error
);
1546 static int bus_method_set_link_dns_over_tls(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1547 return call_link_method(userdata
, message
, bus_link_method_set_dns_over_tls
, error
);
1550 static int bus_method_set_link_dnssec(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1551 return call_link_method(userdata
, message
, bus_link_method_set_dnssec
, error
);
1554 static int bus_method_set_link_dnssec_negative_trust_anchors(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1555 return call_link_method(userdata
, message
, bus_link_method_set_dnssec_negative_trust_anchors
, error
);
1558 static int bus_method_revert_link(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1559 return call_link_method(userdata
, message
, bus_link_method_revert
, error
);
1562 static int bus_method_get_link(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1563 _cleanup_free_
char *p
= NULL
;
1564 Manager
*m
= userdata
;
1571 assert_cc(sizeof(int) == sizeof(int32_t));
1572 r
= sd_bus_message_read(message
, "i", &ifindex
);
1576 r
= get_any_link(m
, ifindex
, &l
, error
);
1580 p
= link_bus_path(l
);
1584 return sd_bus_reply_method_return(message
, "o", p
);
1587 static int bus_method_flush_caches(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1588 Manager
*m
= userdata
;
1593 manager_flush_caches(m
);
1595 return sd_bus_reply_method_return(message
, NULL
);
1598 static int bus_method_reset_server_features(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1599 Manager
*m
= userdata
;
1604 manager_reset_server_features(m
);
1606 return sd_bus_reply_method_return(message
, NULL
);
1609 static int on_bus_track(sd_bus_track
*t
, void *userdata
) {
1610 DnssdService
*s
= userdata
;
1615 log_debug("Client of active request vanished, destroying DNS-SD service.");
1616 dnssd_service_free(s
);
1621 static int bus_method_register_service(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1622 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
1623 _cleanup_(dnssd_service_freep
) DnssdService
*service
= NULL
;
1624 _cleanup_(sd_bus_track_unrefp
) sd_bus_track
*bus_track
= NULL
;
1625 _cleanup_free_
char *path
= NULL
;
1626 _cleanup_free_
char *instance_name
= NULL
;
1627 Manager
*m
= userdata
;
1628 DnssdService
*s
= NULL
;
1630 const char *name_template
;
1638 if (m
->mdns_support
!= RESOLVE_SUPPORT_YES
)
1639 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Support for MulticastDNS is disabled");
1641 service
= new0(DnssdService
, 1);
1645 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_EUID
, &creds
);
1649 r
= sd_bus_creds_get_euid(creds
, &euid
);
1652 service
->originator
= euid
;
1654 r
= sd_bus_message_read(message
, "sssqqq", &name
, &name_template
, &type
,
1655 &service
->port
, &service
->priority
,
1660 s
= hashmap_get(m
->dnssd_services
, name
);
1662 return sd_bus_error_setf(error
, BUS_ERROR_DNSSD_SERVICE_EXISTS
, "DNS-SD service '%s' exists already", name
);
1664 if (!dnssd_srv_type_is_valid(type
))
1665 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "DNS-SD service type '%s' is invalid", type
);
1667 service
->name
= strdup(name
);
1671 service
->name_template
= strdup(name_template
);
1672 if (!service
->name_template
)
1675 service
->type
= strdup(type
);
1679 r
= dnssd_render_instance_name(service
, &instance_name
);
1683 r
= sd_bus_message_enter_container(message
, SD_BUS_TYPE_ARRAY
, "a{say}");
1687 while ((r
= sd_bus_message_enter_container(message
, SD_BUS_TYPE_ARRAY
, "{say}")) > 0) {
1688 _cleanup_(dnssd_txtdata_freep
) DnssdTxtData
*txt_data
= NULL
;
1689 DnsTxtItem
*last
= NULL
;
1691 txt_data
= new0(DnssdTxtData
, 1);
1695 while ((r
= sd_bus_message_enter_container(message
, SD_BUS_TYPE_DICT_ENTRY
, "say")) > 0) {
1701 r
= sd_bus_message_read(message
, "s", &key
);
1706 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Keys in DNS-SD TXT RRs can't be empty");
1708 if (!ascii_is_valid(key
))
1709 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "TXT key '%s' contains non-ASCII symbols", key
);
1711 r
= sd_bus_message_read_array(message
, 'y', &value
, &size
);
1715 r
= dnssd_txt_item_new_from_data(key
, value
, size
, &i
);
1719 LIST_INSERT_AFTER(items
, txt_data
->txt
, last
, i
);
1722 r
= sd_bus_message_exit_container(message
);
1730 r
= sd_bus_message_exit_container(message
);
1734 if (txt_data
->txt
) {
1735 LIST_PREPEND(items
, service
->txt_data_items
, txt_data
);
1742 r
= sd_bus_message_exit_container(message
);
1746 if (!service
->txt_data_items
) {
1747 _cleanup_(dnssd_txtdata_freep
) DnssdTxtData
*txt_data
= NULL
;
1749 txt_data
= new0(DnssdTxtData
, 1);
1753 r
= dns_txt_item_new_empty(&txt_data
->txt
);
1757 LIST_PREPEND(items
, service
->txt_data_items
, txt_data
);
1761 r
= sd_bus_path_encode("/org/freedesktop/resolve1/dnssd", service
->name
, &path
);
1765 r
= bus_verify_polkit_async(message
, CAP_SYS_ADMIN
,
1766 "org.freedesktop.resolve1.register-service",
1767 NULL
, false, UID_INVALID
,
1768 &m
->polkit_registry
, error
);
1772 return 1; /* Polkit will call us back */
1774 r
= hashmap_ensure_allocated(&m
->dnssd_services
, &string_hash_ops
);
1778 r
= hashmap_put(m
->dnssd_services
, service
->name
, service
);
1782 r
= sd_bus_track_new(sd_bus_message_get_bus(message
), &bus_track
, on_bus_track
, service
);
1786 r
= sd_bus_track_add_sender(bus_track
, message
);
1790 service
->manager
= m
;
1794 manager_refresh_rrs(m
);
1796 return sd_bus_reply_method_return(message
, "o", path
);
1799 static int call_dnssd_method(Manager
*m
, sd_bus_message
*message
, sd_bus_message_handler_t handler
, sd_bus_error
*error
) {
1800 _cleanup_free_
char *name
= NULL
;
1801 DnssdService
*s
= NULL
;
1809 r
= sd_bus_message_read(message
, "o", &path
);
1813 r
= sd_bus_path_decode(path
, "/org/freedesktop/resolve1/dnssd", &name
);
1815 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_DNSSD_SERVICE
, "DNS-SD service with object path '%s' does not exist", path
);
1819 s
= hashmap_get(m
->dnssd_services
, name
);
1821 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_DNSSD_SERVICE
, "DNS-SD service '%s' not known", name
);
1823 return handler(message
, s
, error
);
1826 static int bus_method_unregister_service(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1827 Manager
*m
= userdata
;
1832 return call_dnssd_method(m
, message
, bus_dnssd_method_unregister
, error
);
1835 static const sd_bus_vtable resolve_vtable
[] = {
1836 SD_BUS_VTABLE_START(0),
1837 SD_BUS_PROPERTY("LLMNRHostname", "s", NULL
, offsetof(Manager
, llmnr_hostname
), 0),
1838 SD_BUS_PROPERTY("LLMNR", "s", bus_property_get_resolve_support
, offsetof(Manager
, llmnr_support
), 0),
1839 SD_BUS_PROPERTY("MulticastDNS", "s", bus_property_get_resolve_support
, offsetof(Manager
, mdns_support
), 0),
1840 SD_BUS_PROPERTY("DNSOverTLS", "s", bus_property_get_dns_over_tls_mode
, 0, 0),
1841 SD_BUS_PROPERTY("DNS", "a(iiay)", bus_property_get_dns_servers
, 0, 0),
1842 SD_BUS_PROPERTY("FallbackDNS", "a(iiay)", bus_property_get_fallback_dns_servers
, offsetof(Manager
, fallback_dns_servers
), SD_BUS_VTABLE_PROPERTY_CONST
),
1843 SD_BUS_PROPERTY("CurrentDNSServer", "(iiay)", bus_property_get_current_dns_server
, offsetof(Manager
, current_dns_server
), 0),
1844 SD_BUS_PROPERTY("Domains", "a(isb)", bus_property_get_domains
, 0, 0),
1845 SD_BUS_PROPERTY("TransactionStatistics", "(tt)", bus_property_get_transaction_statistics
, 0, 0),
1846 SD_BUS_PROPERTY("CacheStatistics", "(ttt)", bus_property_get_cache_statistics
, 0, 0),
1847 SD_BUS_PROPERTY("DNSSEC", "s", bus_property_get_dnssec_mode
, 0, 0),
1848 SD_BUS_PROPERTY("DNSSECStatistics", "(tttt)", bus_property_get_dnssec_statistics
, 0, 0),
1849 SD_BUS_PROPERTY("DNSSECSupported", "b", bus_property_get_dnssec_supported
, 0, 0),
1850 SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", bus_property_get_ntas
, 0, 0),
1851 SD_BUS_PROPERTY("DNSStubListener", "s", bus_property_get_dns_stub_listener_mode
, offsetof(Manager
, dns_stub_listener_mode
), 0),
1853 SD_BUS_METHOD("ResolveHostname", "isit", "a(iiay)st", bus_method_resolve_hostname
, SD_BUS_VTABLE_UNPRIVILEGED
),
1854 SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address
, SD_BUS_VTABLE_UNPRIVILEGED
),
1855 SD_BUS_METHOD("ResolveRecord", "isqqt", "a(iqqay)t", bus_method_resolve_record
, SD_BUS_VTABLE_UNPRIVILEGED
),
1856 SD_BUS_METHOD("ResolveService", "isssit", "a(qqqsa(iiay)s)aayssst", bus_method_resolve_service
, SD_BUS_VTABLE_UNPRIVILEGED
),
1857 SD_BUS_METHOD("ResetStatistics", NULL
, NULL
, bus_method_reset_statistics
, SD_BUS_VTABLE_UNPRIVILEGED
),
1858 SD_BUS_METHOD("FlushCaches", NULL
, NULL
, bus_method_flush_caches
, SD_BUS_VTABLE_UNPRIVILEGED
),
1859 SD_BUS_METHOD("ResetServerFeatures", NULL
, NULL
, bus_method_reset_server_features
, SD_BUS_VTABLE_UNPRIVILEGED
),
1860 SD_BUS_METHOD("GetLink", "i", "o", bus_method_get_link
, SD_BUS_VTABLE_UNPRIVILEGED
),
1861 SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL
, bus_method_set_link_dns_servers
, SD_BUS_VTABLE_UNPRIVILEGED
),
1862 SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL
, bus_method_set_link_domains
, SD_BUS_VTABLE_UNPRIVILEGED
),
1863 SD_BUS_METHOD("SetLinkDefaultRoute", "ib", NULL
, bus_method_set_link_default_route
, SD_BUS_VTABLE_UNPRIVILEGED
),
1864 SD_BUS_METHOD("SetLinkLLMNR", "is", NULL
, bus_method_set_link_llmnr
, SD_BUS_VTABLE_UNPRIVILEGED
),
1865 SD_BUS_METHOD("SetLinkMulticastDNS", "is", NULL
, bus_method_set_link_mdns
, SD_BUS_VTABLE_UNPRIVILEGED
),
1866 SD_BUS_METHOD("SetLinkDNSOverTLS", "is", NULL
, bus_method_set_link_dns_over_tls
, SD_BUS_VTABLE_UNPRIVILEGED
),
1867 SD_BUS_METHOD("SetLinkDNSSEC", "is", NULL
, bus_method_set_link_dnssec
, SD_BUS_VTABLE_UNPRIVILEGED
),
1868 SD_BUS_METHOD("SetLinkDNSSECNegativeTrustAnchors", "ias", NULL
, bus_method_set_link_dnssec_negative_trust_anchors
, SD_BUS_VTABLE_UNPRIVILEGED
),
1869 SD_BUS_METHOD("RevertLink", "i", NULL
, bus_method_revert_link
, SD_BUS_VTABLE_UNPRIVILEGED
),
1871 SD_BUS_METHOD("RegisterService", "sssqqqaa{say}", "o", bus_method_register_service
, SD_BUS_VTABLE_UNPRIVILEGED
),
1872 SD_BUS_METHOD("UnregisterService", "o", NULL
, bus_method_unregister_service
, SD_BUS_VTABLE_UNPRIVILEGED
),
1876 static int match_prepare_for_sleep(sd_bus_message
*message
, void *userdata
, sd_bus_error
*ret_error
) {
1877 Manager
*m
= userdata
;
1883 r
= sd_bus_message_read(message
, "b", &b
);
1885 log_debug_errno(r
, "Failed to parse PrepareForSleep signal: %m");
1892 log_debug("Coming back from suspend, verifying all RRs...");
1894 manager_verify_all(m
);
1898 int manager_connect_bus(Manager
*m
) {
1906 r
= bus_open_system_watch_bind_with_description(&m
->bus
, "bus-api-resolve");
1908 return log_error_errno(r
, "Failed to connect to system bus: %m");
1910 r
= sd_bus_add_object_vtable(m
->bus
, NULL
, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable
, m
);
1912 return log_error_errno(r
, "Failed to register object: %m");
1914 r
= sd_bus_add_fallback_vtable(m
->bus
, NULL
, "/org/freedesktop/resolve1/link", "org.freedesktop.resolve1.Link", link_vtable
, link_object_find
, m
);
1916 return log_error_errno(r
, "Failed to register link objects: %m");
1918 r
= sd_bus_add_node_enumerator(m
->bus
, NULL
, "/org/freedesktop/resolve1/link", link_node_enumerator
, m
);
1920 return log_error_errno(r
, "Failed to register link enumerator: %m");
1922 r
= sd_bus_add_fallback_vtable(m
->bus
, NULL
, "/org/freedesktop/resolve1/dnssd", "org.freedesktop.resolve1.DnssdService", dnssd_vtable
, dnssd_object_find
, m
);
1924 return log_error_errno(r
, "Failed to register dnssd objects: %m");
1926 r
= sd_bus_add_node_enumerator(m
->bus
, NULL
, "/org/freedesktop/resolve1/dnssd", dnssd_node_enumerator
, m
);
1928 return log_error_errno(r
, "Failed to register dnssd enumerator: %m");
1930 r
= sd_bus_request_name_async(m
->bus
, NULL
, "org.freedesktop.resolve1", 0, NULL
, NULL
);
1932 return log_error_errno(r
, "Failed to request name: %m");
1934 r
= sd_bus_attach_event(m
->bus
, m
->event
, 0);
1936 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
1938 r
= sd_bus_match_signal_async(
1941 "org.freedesktop.login1",
1942 "/org/freedesktop/login1",
1943 "org.freedesktop.login1.Manager",
1945 match_prepare_for_sleep
,
1949 log_warning_errno(r
, "Failed to request match for PrepareForSleep, ignoring: %m");