1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2014 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 #include "alloc-util.h"
22 #include "bus-common-errors.h"
24 #include "dns-domain.h"
25 #include "resolved-bus.h"
26 #include "resolved-def.h"
27 #include "resolved-dns-synthesize.h"
28 #include "resolved-dnssd.h"
29 #include "resolved-dnssd-bus.h"
30 #include "resolved-link-bus.h"
31 #include "user-util.h"
34 static int reply_query_state(DnsQuery
*q
) {
38 case DNS_TRANSACTION_NO_SERVERS
:
39 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_NAME_SERVERS
, "No appropriate name servers or networks for name found");
41 case DNS_TRANSACTION_TIMEOUT
:
42 return sd_bus_reply_method_errorf(q
->request
, SD_BUS_ERROR_TIMEOUT
, "Query timed out");
44 case DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
:
45 return sd_bus_reply_method_errorf(q
->request
, SD_BUS_ERROR_TIMEOUT
, "All attempts to contact name servers or networks failed");
47 case DNS_TRANSACTION_INVALID_REPLY
:
48 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_INVALID_REPLY
, "Received invalid reply");
50 case DNS_TRANSACTION_ERRNO
:
51 return sd_bus_reply_method_errnof(q
->request
, q
->answer_errno
, "Lookup failed due to system error: %m");
53 case DNS_TRANSACTION_ABORTED
:
54 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_ABORTED
, "Query aborted");
56 case DNS_TRANSACTION_DNSSEC_FAILED
:
57 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_DNSSEC_FAILED
, "DNSSEC validation failed: %s",
58 dnssec_result_to_string(q
->answer_dnssec_result
));
60 case DNS_TRANSACTION_NO_TRUST_ANCHOR
:
61 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_TRUST_ANCHOR
, "No suitable trust anchor known");
63 case DNS_TRANSACTION_RR_TYPE_UNSUPPORTED
:
64 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_RR_TYPE_UNSUPPORTED
, "Server does not support requested resource record type");
66 case DNS_TRANSACTION_NETWORK_DOWN
:
67 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NETWORK_DOWN
, "Network is down");
69 case DNS_TRANSACTION_NOT_FOUND
:
70 /* We return this as NXDOMAIN. This is only generated when a host doesn't implement LLMNR/TCP, and we
71 * thus quickly know that we cannot resolve an in-addr.arpa or ip6.arpa address. */
72 return sd_bus_reply_method_errorf(q
->request
, _BUS_ERROR_DNS
"NXDOMAIN", "'%s' not found", dns_query_string(q
));
74 case DNS_TRANSACTION_RCODE_FAILURE
: {
75 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
77 if (q
->answer_rcode
== DNS_RCODE_NXDOMAIN
)
78 sd_bus_error_setf(&error
, _BUS_ERROR_DNS
"NXDOMAIN", "'%s' not found", dns_query_string(q
));
81 char p
[DECIMAL_STR_MAX(q
->answer_rcode
)];
83 rc
= dns_rcode_to_string(q
->answer_rcode
);
85 sprintf(p
, "%i", q
->answer_rcode
);
89 n
= strjoina(_BUS_ERROR_DNS
, rc
);
90 sd_bus_error_setf(&error
, n
, "Could not resolve '%s', server or network returned error %s", dns_query_string(q
), rc
);
93 return sd_bus_reply_method_error(q
->request
, &error
);
96 case DNS_TRANSACTION_NULL
:
97 case DNS_TRANSACTION_PENDING
:
98 case DNS_TRANSACTION_VALIDATING
:
99 case DNS_TRANSACTION_SUCCESS
:
101 assert_not_reached("Impossible state");
105 static int append_address(sd_bus_message
*reply
, DnsResourceRecord
*rr
, int ifindex
) {
111 r
= sd_bus_message_open_container(reply
, 'r', "iiay");
115 r
= sd_bus_message_append(reply
, "i", ifindex
);
119 if (rr
->key
->type
== DNS_TYPE_A
) {
120 r
= sd_bus_message_append(reply
, "i", AF_INET
);
124 r
= sd_bus_message_append_array(reply
, 'y', &rr
->a
.in_addr
, sizeof(struct in_addr
));
126 } else if (rr
->key
->type
== DNS_TYPE_AAAA
) {
127 r
= sd_bus_message_append(reply
, "i", AF_INET6
);
131 r
= sd_bus_message_append_array(reply
, 'y', &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
));
133 return -EAFNOSUPPORT
;
138 r
= sd_bus_message_close_container(reply
);
145 static void bus_method_resolve_hostname_complete(DnsQuery
*q
) {
146 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*canonical
= NULL
;
147 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
148 _cleanup_free_
char *normalized
= NULL
;
149 DnsResourceRecord
*rr
;
155 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
156 r
= reply_query_state(q
);
160 r
= dns_query_process_cname(q
);
162 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
));
167 if (r
== DNS_QUERY_RESTARTED
) /* This was a cname, and the query was restarted. */
170 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
174 r
= sd_bus_message_open_container(reply
, 'a', "(iiay)");
178 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
179 DnsQuestion
*question
;
181 question
= dns_query_question_for_protocol(q
, q
->answer_protocol
);
183 r
= dns_question_matches_rr(question
, rr
, DNS_SEARCH_DOMAIN_NAME(q
->answer_search_domain
));
189 r
= append_address(reply
, rr
, ifindex
);
194 canonical
= dns_resource_record_ref(rr
);
200 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
));
204 r
= sd_bus_message_close_container(reply
);
208 /* The key names are not necessarily normalized, make sure that they are when we return them to our bus
210 r
= dns_name_normalize(dns_resource_key_name(canonical
->key
), &normalized
);
214 /* Return the precise spelling and uppercasing and CNAME target reported by the server */
216 r
= sd_bus_message_append(
219 SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
, dns_query_fully_authenticated(q
)));
223 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
227 log_error_errno(r
, "Failed to send hostname reply: %m");
228 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
234 static int check_ifindex_flags(int ifindex
, uint64_t *flags
, uint64_t ok
, sd_bus_error
*error
) {
238 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid interface index");
240 if (*flags
& ~(SD_RESOLVED_PROTOCOLS_ALL
|SD_RESOLVED_NO_CNAME
|ok
))
241 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid flags parameter");
243 if ((*flags
& SD_RESOLVED_PROTOCOLS_ALL
) == 0) /* If no protocol is enabled, enable all */
244 *flags
|= SD_RESOLVED_PROTOCOLS_ALL
;
249 static int parse_as_address(sd_bus_message
*m
, int ifindex
, const char *hostname
, int family
, uint64_t flags
) {
250 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
251 _cleanup_free_
char *canonical
= NULL
;
252 union in_addr_union parsed
;
253 int r
, ff
, parsed_ifindex
= 0;
255 /* Check if the hostname is actually already an IP address formatted as string. In that case just parse it,
256 * let's not attempt to look it up. */
258 r
= in_addr_ifindex_from_string_auto(hostname
, &ff
, &parsed
, &parsed_ifindex
);
259 if (r
< 0) /* not an address */
262 if (family
!= AF_UNSPEC
&& ff
!= family
)
263 return sd_bus_reply_method_errorf(m
, BUS_ERROR_NO_SUCH_RR
, "The specified address is not of the requested family.");
264 if (ifindex
> 0 && parsed_ifindex
> 0 && parsed_ifindex
!= ifindex
)
265 return sd_bus_reply_method_errorf(m
, BUS_ERROR_NO_SUCH_RR
, "The specified address interface index does not match requested interface.");
267 if (parsed_ifindex
> 0)
268 ifindex
= parsed_ifindex
;
270 r
= sd_bus_message_new_method_return(m
, &reply
);
274 r
= sd_bus_message_open_container(reply
, 'a', "(iiay)");
278 r
= sd_bus_message_open_container(reply
, 'r', "iiay");
282 r
= sd_bus_message_append(reply
, "ii", ifindex
, ff
);
286 r
= sd_bus_message_append_array(reply
, 'y', &parsed
, FAMILY_ADDRESS_SIZE(ff
));
290 r
= sd_bus_message_close_container(reply
);
294 r
= sd_bus_message_close_container(reply
);
298 /* When an IP address is specified we just return it as canonical name, in order to avoid a DNS
299 * look-up. However, we reformat it to make sure it's in a truly canonical form (i.e. on IPv6 the inner
300 * omissions are always done the same way). */
301 r
= in_addr_ifindex_to_string(ff
, &parsed
, ifindex
, &canonical
);
305 r
= sd_bus_message_append(reply
, "st", canonical
,
306 SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(flags
), ff
, true));
310 return sd_bus_send(sd_bus_message_get_bus(m
), reply
, NULL
);
313 static int bus_method_resolve_hostname(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
314 _cleanup_(dns_question_unrefp
) DnsQuestion
*question_idna
= NULL
, *question_utf8
= NULL
;
315 Manager
*m
= userdata
;
316 const char *hostname
;
325 assert_cc(sizeof(int) == sizeof(int32_t));
327 r
= sd_bus_message_read(message
, "isit", &ifindex
, &hostname
, &family
, &flags
);
331 if (!IN_SET(family
, AF_INET
, AF_INET6
, AF_UNSPEC
))
332 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown address family %i", family
);
334 r
= check_ifindex_flags(ifindex
, &flags
, SD_RESOLVED_NO_SEARCH
, error
);
338 r
= parse_as_address(message
, ifindex
, hostname
, family
, flags
);
342 r
= dns_name_is_valid(hostname
);
346 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid hostname '%s'", hostname
);
348 r
= dns_question_new_address(&question_utf8
, family
, hostname
, false);
352 r
= dns_question_new_address(&question_idna
, family
, hostname
, true);
353 if (r
< 0 && r
!= -EALREADY
)
356 r
= dns_query_new(m
, &q
, question_utf8
, question_idna
?: question_utf8
, ifindex
, flags
);
360 q
->request
= sd_bus_message_ref(message
);
361 q
->request_family
= family
;
362 q
->complete
= bus_method_resolve_hostname_complete
;
363 q
->suppress_unroutable_family
= family
== AF_UNSPEC
;
365 r
= dns_query_bus_track(q
, message
);
380 static void bus_method_resolve_address_complete(DnsQuery
*q
) {
381 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
382 DnsQuestion
*question
;
383 DnsResourceRecord
*rr
;
389 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
390 r
= reply_query_state(q
);
394 r
= dns_query_process_cname(q
);
396 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
));
401 if (r
== DNS_QUERY_RESTARTED
) /* This was a cname, and the query was restarted. */
404 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
408 r
= sd_bus_message_open_container(reply
, 'a', "(is)");
412 question
= dns_query_question_for_protocol(q
, q
->answer_protocol
);
414 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
415 _cleanup_free_
char *normalized
= NULL
;
417 r
= dns_question_matches_rr(question
, rr
, NULL
);
423 r
= dns_name_normalize(rr
->ptr
.name
, &normalized
);
427 r
= sd_bus_message_append(reply
, "(is)", ifindex
, normalized
);
435 _cleanup_free_
char *ip
= NULL
;
437 (void) in_addr_to_string(q
->request_family
, &q
->request_address
, &ip
);
438 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_SUCH_RR
,
439 "Address '%s' does not have any RR of requested type", strnull(ip
));
443 r
= sd_bus_message_close_container(reply
);
447 r
= sd_bus_message_append(reply
, "t", SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
, dns_query_fully_authenticated(q
)));
451 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
455 log_error_errno(r
, "Failed to send address reply: %m");
456 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
462 static int bus_method_resolve_address(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
463 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
464 Manager
*m
= userdata
;
475 assert_cc(sizeof(int) == sizeof(int32_t));
477 r
= sd_bus_message_read(message
, "ii", &ifindex
, &family
);
481 if (!IN_SET(family
, AF_INET
, AF_INET6
))
482 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown address family %i", family
);
484 r
= sd_bus_message_read_array(message
, 'y', &d
, &sz
);
488 if (sz
!= FAMILY_ADDRESS_SIZE(family
))
489 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid address size");
491 r
= sd_bus_message_read(message
, "t", &flags
);
495 r
= check_ifindex_flags(ifindex
, &flags
, 0, error
);
499 r
= dns_question_new_reverse(&question
, family
, d
);
503 r
= dns_query_new(m
, &q
, question
, question
, ifindex
, flags
|SD_RESOLVED_NO_SEARCH
);
507 q
->request
= sd_bus_message_ref(message
);
508 q
->request_family
= family
;
509 memcpy(&q
->request_address
, d
, sz
);
510 q
->complete
= bus_method_resolve_address_complete
;
512 r
= dns_query_bus_track(q
, message
);
527 static int bus_message_append_rr(sd_bus_message
*m
, DnsResourceRecord
*rr
, int ifindex
) {
533 r
= sd_bus_message_open_container(m
, 'r', "iqqay");
537 r
= sd_bus_message_append(m
, "iqq",
544 r
= dns_resource_record_to_wire_format(rr
, false);
548 r
= sd_bus_message_append_array(m
, 'y', rr
->wire_format
, rr
->wire_format_size
);
552 return sd_bus_message_close_container(m
);
555 static void bus_method_resolve_record_complete(DnsQuery
*q
) {
556 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
557 DnsResourceRecord
*rr
;
558 DnsQuestion
*question
;
565 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
566 r
= reply_query_state(q
);
570 r
= dns_query_process_cname(q
);
572 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
));
577 if (r
== DNS_QUERY_RESTARTED
) /* This was a cname, and the query was restarted. */
580 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
584 r
= sd_bus_message_open_container(reply
, 'a', "(iqqay)");
588 question
= dns_query_question_for_protocol(q
, q
->answer_protocol
);
590 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
591 r
= dns_question_matches_rr(question
, rr
, NULL
);
597 r
= bus_message_append_rr(reply
, rr
, ifindex
);
605 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
));
609 r
= sd_bus_message_close_container(reply
);
613 r
= sd_bus_message_append(reply
, "t", SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
, dns_query_fully_authenticated(q
)));
617 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
621 log_error_errno(r
, "Failed to send record reply: %m");
622 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
628 static int bus_method_resolve_record(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
629 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
630 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
631 Manager
*m
= userdata
;
632 uint16_t class, type
;
641 assert_cc(sizeof(int) == sizeof(int32_t));
643 r
= sd_bus_message_read(message
, "isqqt", &ifindex
, &name
, &class, &type
, &flags
);
647 r
= dns_name_is_valid(name
);
651 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid name '%s'", name
);
653 if (!dns_type_is_valid_query(type
))
654 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Specified resource record type %" PRIu16
" may not be used in a query.", type
);
655 if (dns_type_is_zone_transer(type
))
656 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Zone transfers not permitted via this programming interface.");
657 if (dns_type_is_obsolete(type
))
658 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Specified DNS resource record type %" PRIu16
" is obsolete.", type
);
660 r
= check_ifindex_flags(ifindex
, &flags
, 0, error
);
664 question
= dns_question_new(1);
668 key
= dns_resource_key_new(class, type
, name
);
672 r
= dns_question_add(question
, key
);
676 r
= dns_query_new(m
, &q
, question
, question
, ifindex
, flags
|SD_RESOLVED_NO_SEARCH
);
680 /* Let's request that the TTL is fixed up for locally cached entries, after all we return it in the wire format
684 q
->request
= sd_bus_message_ref(message
);
685 q
->complete
= bus_method_resolve_record_complete
;
687 r
= dns_query_bus_track(q
, message
);
702 static int append_srv(DnsQuery
*q
, sd_bus_message
*reply
, DnsResourceRecord
*rr
) {
703 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*canonical
= NULL
;
704 _cleanup_free_
char *normalized
= NULL
;
713 if (rr
->key
->type
!= DNS_TYPE_SRV
)
716 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
717 /* First, let's see if we could find an appropriate A or AAAA
718 * record for the SRV record */
719 LIST_FOREACH(auxiliary_queries
, aux
, q
->auxiliary_queries
) {
720 DnsResourceRecord
*zz
;
721 DnsQuestion
*question
;
723 if (aux
->state
!= DNS_TRANSACTION_SUCCESS
)
725 if (aux
->auxiliary_result
!= 0)
728 question
= dns_query_question_for_protocol(aux
, aux
->answer_protocol
);
730 r
= dns_name_equal(dns_question_first_name(question
), rr
->srv
.name
);
736 DNS_ANSWER_FOREACH(zz
, aux
->answer
) {
738 r
= dns_question_matches_rr(question
, zz
, NULL
);
744 canonical
= dns_resource_record_ref(zz
);
752 /* Is there are successful A/AAAA lookup for this SRV RR? If not, don't add it */
757 r
= sd_bus_message_open_container(reply
, 'r', "qqqsa(iiay)s");
761 r
= dns_name_normalize(rr
->srv
.name
, &normalized
);
765 r
= sd_bus_message_append(
768 rr
->srv
.priority
, rr
->srv
.weight
, rr
->srv
.port
, normalized
);
772 r
= sd_bus_message_open_container(reply
, 'a', "(iiay)");
776 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
777 LIST_FOREACH(auxiliary_queries
, aux
, q
->auxiliary_queries
) {
778 DnsResourceRecord
*zz
;
779 DnsQuestion
*question
;
782 if (aux
->state
!= DNS_TRANSACTION_SUCCESS
)
784 if (aux
->auxiliary_result
!= 0)
787 question
= dns_query_question_for_protocol(aux
, aux
->answer_protocol
);
789 r
= dns_name_equal(dns_question_first_name(question
), rr
->srv
.name
);
795 DNS_ANSWER_FOREACH_IFINDEX(zz
, ifindex
, aux
->answer
) {
797 r
= dns_question_matches_rr(question
, zz
, NULL
);
803 r
= append_address(reply
, zz
, ifindex
);
810 r
= sd_bus_message_close_container(reply
);
815 normalized
= mfree(normalized
);
817 r
= dns_name_normalize(dns_resource_key_name(canonical
->key
), &normalized
);
822 /* Note that above we appended the hostname as encoded in the
823 * SRV, and here the canonical hostname this maps to. */
824 r
= sd_bus_message_append(reply
, "s", normalized
);
828 r
= sd_bus_message_close_container(reply
);
835 static int append_txt(sd_bus_message
*reply
, DnsResourceRecord
*rr
) {
843 if (rr
->key
->type
!= DNS_TYPE_TXT
)
846 LIST_FOREACH(items
, i
, rr
->txt
.items
) {
851 r
= sd_bus_message_append_array(reply
, 'y', i
->data
, i
->length
);
859 static void resolve_service_all_complete(DnsQuery
*q
) {
860 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*canonical
= NULL
;
861 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
862 _cleanup_free_
char *name
= NULL
, *type
= NULL
, *domain
= NULL
;
863 DnsQuestion
*question
;
864 DnsResourceRecord
*rr
;
871 if (q
->block_all_complete
> 0)
874 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
875 DnsQuery
*bad
= NULL
;
876 bool have_success
= false;
878 LIST_FOREACH(auxiliary_queries
, aux
, q
->auxiliary_queries
) {
880 switch (aux
->state
) {
882 case DNS_TRANSACTION_PENDING
:
883 /* If an auxiliary query is still pending, let's wait */
886 case DNS_TRANSACTION_SUCCESS
:
887 if (aux
->auxiliary_result
== 0)
900 /* We can only return one error, hence pick the last error we encountered */
904 if (bad
->state
== DNS_TRANSACTION_SUCCESS
) {
905 assert(bad
->auxiliary_result
!= 0);
907 if (bad
->auxiliary_result
== -ELOOP
) {
908 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
));
912 r
= bad
->auxiliary_result
;
916 r
= reply_query_state(bad
);
921 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
925 r
= sd_bus_message_open_container(reply
, 'a', "(qqqsa(iiay)s)");
929 question
= dns_query_question_for_protocol(q
, q
->answer_protocol
);
930 DNS_ANSWER_FOREACH(rr
, q
->answer
) {
931 r
= dns_question_matches_rr(question
, rr
, NULL
);
937 r
= append_srv(q
, reply
, rr
);
940 if (r
== 0) /* not an SRV record */
944 canonical
= dns_resource_record_ref(rr
);
950 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
));
954 r
= sd_bus_message_close_container(reply
);
958 r
= sd_bus_message_open_container(reply
, 'a', "ay");
962 DNS_ANSWER_FOREACH(rr
, q
->answer
) {
963 r
= dns_question_matches_rr(question
, rr
, NULL
);
969 r
= append_txt(reply
, rr
);
974 r
= sd_bus_message_close_container(reply
);
979 r
= dns_service_split(dns_resource_key_name(canonical
->key
), &name
, &type
, &domain
);
983 r
= sd_bus_message_append(
987 SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
, dns_query_fully_authenticated(q
)));
991 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
995 log_error_errno(r
, "Failed to send service reply: %m");
996 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
1002 static void resolve_service_hostname_complete(DnsQuery
*q
) {
1006 assert(q
->auxiliary_for
);
1008 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
1009 resolve_service_all_complete(q
->auxiliary_for
);
1013 r
= dns_query_process_cname(q
);
1014 if (r
== DNS_QUERY_RESTARTED
) /* This was a cname, and the query was restarted. */
1017 /* This auxiliary lookup is finished or failed, let's see if all are finished now. */
1018 q
->auxiliary_result
= r
;
1019 resolve_service_all_complete(q
->auxiliary_for
);
1022 static int resolve_service_hostname(DnsQuery
*q
, DnsResourceRecord
*rr
, int ifindex
) {
1023 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
1030 assert(rr
->key
->type
== DNS_TYPE_SRV
);
1032 /* OK, we found an SRV record for the service. Let's resolve
1033 * the hostname included in it */
1035 r
= dns_question_new_address(&question
, q
->request_family
, rr
->srv
.name
, false);
1039 r
= dns_query_new(q
->manager
, &aux
, question
, question
, ifindex
, q
->flags
|SD_RESOLVED_NO_SEARCH
);
1043 aux
->request_family
= q
->request_family
;
1044 aux
->complete
= resolve_service_hostname_complete
;
1046 r
= dns_query_make_auxiliary(aux
, q
);
1048 /* Too many auxiliary lookups? If so, don't complain,
1049 * let's just not add this one, we already have more
1052 dns_query_free(aux
);
1058 /* Note that auxiliary queries do not track the original bus
1059 * client, only the primary request does that. */
1061 r
= dns_query_go(aux
);
1068 dns_query_free(aux
);
1072 static void bus_method_resolve_service_complete(DnsQuery
*q
) {
1073 bool has_root_domain
= false;
1074 DnsResourceRecord
*rr
;
1075 DnsQuestion
*question
;
1081 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
1082 r
= reply_query_state(q
);
1086 r
= dns_query_process_cname(q
);
1088 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
));
1093 if (r
== DNS_QUERY_RESTARTED
) /* This was a cname, and the query was restarted. */
1096 question
= dns_query_question_for_protocol(q
, q
->answer_protocol
);
1098 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
1099 r
= dns_question_matches_rr(question
, rr
, NULL
);
1105 if (rr
->key
->type
!= DNS_TYPE_SRV
)
1108 if (dns_name_is_root(rr
->srv
.name
)) {
1109 has_root_domain
= true;
1113 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
1114 q
->block_all_complete
++;
1115 r
= resolve_service_hostname(q
, rr
, ifindex
);
1116 q
->block_all_complete
--;
1125 if (has_root_domain
&& found
<= 0) {
1126 /* If there's exactly one SRV RR and it uses
1127 * the root domain as host name, then the
1128 * service is explicitly not offered on the
1129 * domain. Report this as a recognizable
1130 * error. See RFC 2782, Section "Usage
1132 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_SUCH_SERVICE
, "'%s' does not provide the requested service", dns_query_string(q
));
1137 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
));
1141 /* Maybe we are already finished? check now... */
1142 resolve_service_all_complete(q
);
1147 log_error_errno(r
, "Failed to send service reply: %m");
1148 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
1154 static int bus_method_resolve_service(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1155 _cleanup_(dns_question_unrefp
) DnsQuestion
*question_idna
= NULL
, *question_utf8
= NULL
;
1156 const char *name
, *type
, *domain
;
1157 Manager
*m
= userdata
;
1158 int family
, ifindex
;
1166 assert_cc(sizeof(int) == sizeof(int32_t));
1168 r
= sd_bus_message_read(message
, "isssit", &ifindex
, &name
, &type
, &domain
, &family
, &flags
);
1172 if (!IN_SET(family
, AF_INET
, AF_INET6
, AF_UNSPEC
))
1173 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown address family %i", family
);
1177 else if (!dns_service_name_is_valid(name
))
1178 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid service name '%s'", name
);
1182 else if (!dns_srv_type_is_valid(type
))
1183 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid SRV service type '%s'", type
);
1185 r
= dns_name_is_valid(domain
);
1189 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid domain '%s'", domain
);
1192 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Service name cannot be specified without service type.");
1194 r
= check_ifindex_flags(ifindex
, &flags
, SD_RESOLVED_NO_TXT
|SD_RESOLVED_NO_ADDRESS
, error
);
1198 r
= dns_question_new_service(&question_utf8
, name
, type
, domain
, !(flags
& SD_RESOLVED_NO_TXT
), false);
1202 r
= dns_question_new_service(&question_idna
, name
, type
, domain
, !(flags
& SD_RESOLVED_NO_TXT
), true);
1206 r
= dns_query_new(m
, &q
, question_utf8
, question_idna
, ifindex
, flags
|SD_RESOLVED_NO_SEARCH
);
1210 q
->request
= sd_bus_message_ref(message
);
1211 q
->request_family
= family
;
1212 q
->complete
= bus_method_resolve_service_complete
;
1214 r
= dns_query_bus_track(q
, message
);
1218 r
= dns_query_go(q
);
1229 int bus_dns_server_append(sd_bus_message
*reply
, DnsServer
*s
, bool with_ifindex
) {
1235 r
= sd_bus_message_open_container(reply
, 'r', with_ifindex
? "iiay" : "iay");
1240 r
= sd_bus_message_append(reply
, "i", dns_server_ifindex(s
));
1245 r
= sd_bus_message_append(reply
, "i", s
->family
);
1249 r
= sd_bus_message_append_array(reply
, 'y', &s
->address
, FAMILY_ADDRESS_SIZE(s
->family
));
1253 return sd_bus_message_close_container(reply
);
1256 static int bus_property_get_dns_servers(
1259 const char *interface
,
1260 const char *property
,
1261 sd_bus_message
*reply
,
1263 sd_bus_error
*error
) {
1265 Manager
*m
= userdata
;
1275 r
= sd_bus_message_open_container(reply
, 'a', "(iiay)");
1279 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
1280 r
= bus_dns_server_append(reply
, s
, true);
1287 HASHMAP_FOREACH(l
, m
->links
, i
) {
1288 LIST_FOREACH(servers
, s
, l
->dns_servers
) {
1289 r
= bus_dns_server_append(reply
, s
, true);
1297 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
) {
1298 r
= bus_dns_server_append(reply
, s
, true);
1304 return sd_bus_message_close_container(reply
);
1307 static int bus_property_get_domains(
1310 const char *interface
,
1311 const char *property
,
1312 sd_bus_message
*reply
,
1314 sd_bus_error
*error
) {
1316 Manager
*m
= userdata
;
1325 r
= sd_bus_message_open_container(reply
, 'a', "(isb)");
1329 LIST_FOREACH(domains
, d
, m
->search_domains
) {
1330 r
= sd_bus_message_append(reply
, "(isb)", 0, d
->name
, d
->route_only
);
1335 HASHMAP_FOREACH(l
, m
->links
, i
) {
1336 LIST_FOREACH(domains
, d
, l
->search_domains
) {
1337 r
= sd_bus_message_append(reply
, "(isb)", l
->ifindex
, d
->name
, d
->route_only
);
1343 return sd_bus_message_close_container(reply
);
1346 static int bus_property_get_transaction_statistics(
1349 const char *interface
,
1350 const char *property
,
1351 sd_bus_message
*reply
,
1353 sd_bus_error
*error
) {
1355 Manager
*m
= userdata
;
1360 return sd_bus_message_append(reply
, "(tt)",
1361 (uint64_t) hashmap_size(m
->dns_transactions
),
1362 (uint64_t) m
->n_transactions_total
);
1365 static int bus_property_get_cache_statistics(
1368 const char *interface
,
1369 const char *property
,
1370 sd_bus_message
*reply
,
1372 sd_bus_error
*error
) {
1374 uint64_t size
= 0, hit
= 0, miss
= 0;
1375 Manager
*m
= userdata
;
1381 LIST_FOREACH(scopes
, s
, m
->dns_scopes
) {
1382 size
+= dns_cache_size(&s
->cache
);
1383 hit
+= s
->cache
.n_hit
;
1384 miss
+= s
->cache
.n_miss
;
1387 return sd_bus_message_append(reply
, "(ttt)", size
, hit
, miss
);
1390 static int bus_property_get_dnssec_statistics(
1393 const char *interface
,
1394 const char *property
,
1395 sd_bus_message
*reply
,
1397 sd_bus_error
*error
) {
1399 Manager
*m
= userdata
;
1404 return sd_bus_message_append(reply
, "(tttt)",
1405 (uint64_t) m
->n_dnssec_verdict
[DNSSEC_SECURE
],
1406 (uint64_t) m
->n_dnssec_verdict
[DNSSEC_INSECURE
],
1407 (uint64_t) m
->n_dnssec_verdict
[DNSSEC_BOGUS
],
1408 (uint64_t) m
->n_dnssec_verdict
[DNSSEC_INDETERMINATE
]);
1411 static int bus_property_get_dnssec_supported(
1414 const char *interface
,
1415 const char *property
,
1416 sd_bus_message
*reply
,
1418 sd_bus_error
*error
) {
1420 Manager
*m
= userdata
;
1425 return sd_bus_message_append(reply
, "b", manager_dnssec_supported(m
));
1428 static int bus_property_get_ntas(
1431 const char *interface
,
1432 const char *property
,
1433 sd_bus_message
*reply
,
1435 sd_bus_error
*error
) {
1437 Manager
*m
= userdata
;
1445 r
= sd_bus_message_open_container(reply
, 'a', "s");
1449 SET_FOREACH(domain
, m
->trust_anchor
.negative_by_name
, i
) {
1450 r
= sd_bus_message_append(reply
, "s", domain
);
1455 return sd_bus_message_close_container(reply
);
1458 static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_dns_stub_listener_mode
, dns_stub_listener_mode
, DnsStubListenerMode
);
1460 static int bus_method_reset_statistics(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1461 Manager
*m
= userdata
;
1467 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1468 s
->cache
.n_hit
= s
->cache
.n_miss
= 0;
1470 m
->n_transactions_total
= 0;
1471 zero(m
->n_dnssec_verdict
);
1473 return sd_bus_reply_method_return(message
, NULL
);
1476 static int get_any_link(Manager
*m
, int ifindex
, Link
**ret
, sd_bus_error
*error
) {
1483 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid interface index");
1485 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
1487 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_LINK
, "Link %i not known", ifindex
);
1493 static int call_link_method(Manager
*m
, sd_bus_message
*message
, sd_bus_message_handler_t handler
, sd_bus_error
*error
) {
1501 assert_cc(sizeof(int) == sizeof(int32_t));
1502 r
= sd_bus_message_read(message
, "i", &ifindex
);
1506 r
= get_any_link(m
, ifindex
, &l
, error
);
1510 return handler(message
, l
, error
);
1513 static int bus_method_set_link_dns_servers(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1514 return call_link_method(userdata
, message
, bus_link_method_set_dns_servers
, error
);
1517 static int bus_method_set_link_domains(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1518 return call_link_method(userdata
, message
, bus_link_method_set_domains
, error
);
1521 static int bus_method_set_link_llmnr(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1522 return call_link_method(userdata
, message
, bus_link_method_set_llmnr
, error
);
1525 static int bus_method_set_link_mdns(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1526 return call_link_method(userdata
, message
, bus_link_method_set_mdns
, error
);
1529 static int bus_method_set_link_dnssec(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1530 return call_link_method(userdata
, message
, bus_link_method_set_dnssec
, error
);
1533 static int bus_method_set_link_dnssec_negative_trust_anchors(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1534 return call_link_method(userdata
, message
, bus_link_method_set_dnssec_negative_trust_anchors
, error
);
1537 static int bus_method_revert_link(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1538 return call_link_method(userdata
, message
, bus_link_method_revert
, error
);
1541 static int bus_method_get_link(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1542 _cleanup_free_
char *p
= NULL
;
1543 Manager
*m
= userdata
;
1550 assert_cc(sizeof(int) == sizeof(int32_t));
1551 r
= sd_bus_message_read(message
, "i", &ifindex
);
1555 r
= get_any_link(m
, ifindex
, &l
, error
);
1559 p
= link_bus_path(l
);
1563 return sd_bus_reply_method_return(message
, "o", p
);
1566 static int bus_method_flush_caches(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1567 Manager
*m
= userdata
;
1572 manager_flush_caches(m
);
1574 return sd_bus_reply_method_return(message
, NULL
);
1577 static int bus_method_reset_server_features(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1578 Manager
*m
= userdata
;
1583 manager_reset_server_features(m
);
1585 return sd_bus_reply_method_return(message
, NULL
);
1588 static int on_bus_track(sd_bus_track
*t
, void *userdata
) {
1589 DnssdService
*s
= userdata
;
1594 log_debug("Client of active request vanished, destroying DNS-SD service.");
1595 dnssd_service_free(s
);
1600 static int bus_method_register_service(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1601 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
1602 _cleanup_(dnssd_service_freep
) DnssdService
*service
= NULL
;
1603 _cleanup_(sd_bus_track_unrefp
) sd_bus_track
*bus_track
= NULL
;
1604 _cleanup_free_
char *path
= NULL
;
1605 _cleanup_free_
char *instance_name
= NULL
;
1606 Manager
*m
= userdata
;
1607 DnssdService
*s
= NULL
;
1609 const char *name_template
;
1617 if (m
->mdns_support
!= RESOLVE_SUPPORT_YES
)
1618 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Support for MulticastDNS is disabled");
1620 r
= bus_verify_polkit_async(message
, CAP_SYS_ADMIN
,
1621 "org.freedesktop.resolve1.register-service",
1622 NULL
, false, UID_INVALID
,
1623 &m
->polkit_registry
, error
);
1627 return 1; /* Polkit will call us back */
1629 service
= new0(DnssdService
, 1);
1633 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_EUID
, &creds
);
1637 r
= sd_bus_creds_get_euid(creds
, &euid
);
1640 service
->originator
= euid
;
1642 r
= sd_bus_message_read(message
, "sssqqq", &name
, &name_template
, &type
,
1643 &service
->port
, &service
->priority
,
1648 s
= hashmap_get(m
->dnssd_services
, name
);
1650 return sd_bus_error_setf(error
, BUS_ERROR_DNSSD_SERVICE_EXISTS
, "DNS-SD service '%s' exists already", name
);
1652 if (!dnssd_srv_type_is_valid(type
))
1653 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "DNS-SD service type '%s' is invalid", type
);
1655 service
->name
= strdup(name
);
1659 service
->name_template
= strdup(name_template
);
1660 if (!service
->name_template
)
1663 service
->type
= strdup(type
);
1667 r
= dnssd_render_instance_name(service
, &instance_name
);
1671 r
= sd_bus_message_enter_container(message
, SD_BUS_TYPE_ARRAY
, "a{say}");
1675 while ((r
= sd_bus_message_enter_container(message
, SD_BUS_TYPE_ARRAY
, "{say}")) > 0) {
1676 _cleanup_(dnssd_txtdata_freep
) DnssdTxtData
*txt_data
= NULL
;
1677 DnsTxtItem
*last
= NULL
;
1679 txt_data
= new0(DnssdTxtData
, 1);
1683 while ((r
= sd_bus_message_enter_container(message
, SD_BUS_TYPE_DICT_ENTRY
, "say")) > 0) {
1689 r
= sd_bus_message_read(message
, "s", &key
);
1694 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Keys in DNS-SD TXT RRs can't be empty");
1696 if (!ascii_is_valid(key
))
1697 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "TXT key '%s' contains non-ASCII symbols", key
);
1699 r
= sd_bus_message_read_array(message
, 'y', &value
, &size
);
1703 r
= dnssd_txt_item_new_from_data(key
, value
, size
, &i
);
1707 LIST_INSERT_AFTER(items
, txt_data
->txt
, last
, i
);
1710 r
= sd_bus_message_exit_container(message
);
1718 r
= sd_bus_message_exit_container(message
);
1722 if (txt_data
->txt
) {
1723 LIST_PREPEND(items
, service
->txt_data_items
, txt_data
);
1730 r
= sd_bus_message_exit_container(message
);
1734 if (!service
->txt_data_items
) {
1735 _cleanup_(dnssd_txtdata_freep
) DnssdTxtData
*txt_data
= NULL
;
1737 txt_data
= new0(DnssdTxtData
, 1);
1741 r
= dns_txt_item_new_empty(&txt_data
->txt
);
1745 LIST_PREPEND(items
, service
->txt_data_items
, txt_data
);
1749 r
= sd_bus_path_encode("/org/freedesktop/resolve1/dnssd", service
->name
, &path
);
1753 r
= hashmap_ensure_allocated(&m
->dnssd_services
, &string_hash_ops
);
1757 r
= hashmap_put(m
->dnssd_services
, service
->name
, service
);
1761 r
= sd_bus_track_new(sd_bus_message_get_bus(message
), &bus_track
, on_bus_track
, service
);
1765 r
= sd_bus_track_add_sender(bus_track
, message
);
1769 service
->manager
= m
;
1773 manager_refresh_rrs(m
);
1775 return sd_bus_reply_method_return(message
, "o", path
);
1778 static int call_dnssd_method(Manager
*m
, sd_bus_message
*message
, sd_bus_message_handler_t handler
, sd_bus_error
*error
) {
1779 _cleanup_free_
char *name
= NULL
;
1780 DnssdService
*s
= NULL
;
1788 r
= sd_bus_message_read(message
, "o", &path
);
1792 r
= sd_bus_path_decode(path
, "/org/freedesktop/resolve1/dnssd", &name
);
1794 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_DNSSD_SERVICE
, "DNS-SD service with object path '%s' does not exist", path
);
1798 s
= hashmap_get(m
->dnssd_services
, name
);
1800 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_DNSSD_SERVICE
, "DNS-SD service '%s' not known", name
);
1802 return handler(message
, s
, error
);
1805 static int bus_method_unregister_service(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1806 Manager
*m
= userdata
;
1811 return call_dnssd_method(m
, message
, bus_dnssd_method_unregister
, error
);
1814 static const sd_bus_vtable resolve_vtable
[] = {
1815 SD_BUS_VTABLE_START(0),
1816 SD_BUS_PROPERTY("LLMNRHostname", "s", NULL
, offsetof(Manager
, llmnr_hostname
), 0),
1817 SD_BUS_PROPERTY("DNS", "a(iiay)", bus_property_get_dns_servers
, 0, 0),
1818 SD_BUS_PROPERTY("Domains", "a(isb)", bus_property_get_domains
, 0, 0),
1819 SD_BUS_PROPERTY("TransactionStatistics", "(tt)", bus_property_get_transaction_statistics
, 0, 0),
1820 SD_BUS_PROPERTY("CacheStatistics", "(ttt)", bus_property_get_cache_statistics
, 0, 0),
1821 SD_BUS_PROPERTY("DNSSECStatistics", "(tttt)", bus_property_get_dnssec_statistics
, 0, 0),
1822 SD_BUS_PROPERTY("DNSSECSupported", "b", bus_property_get_dnssec_supported
, 0, 0),
1823 SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", bus_property_get_ntas
, 0, 0),
1824 SD_BUS_PROPERTY("DNSStubListener", "s", bus_property_get_dns_stub_listener_mode
, offsetof(Manager
, dns_stub_listener_mode
), 0),
1826 SD_BUS_METHOD("ResolveHostname", "isit", "a(iiay)st", bus_method_resolve_hostname
, SD_BUS_VTABLE_UNPRIVILEGED
),
1827 SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address
, SD_BUS_VTABLE_UNPRIVILEGED
),
1828 SD_BUS_METHOD("ResolveRecord", "isqqt", "a(iqqay)t", bus_method_resolve_record
, SD_BUS_VTABLE_UNPRIVILEGED
),
1829 SD_BUS_METHOD("ResolveService", "isssit", "a(qqqsa(iiay)s)aayssst", bus_method_resolve_service
, SD_BUS_VTABLE_UNPRIVILEGED
),
1830 SD_BUS_METHOD("ResetStatistics", NULL
, NULL
, bus_method_reset_statistics
, 0),
1831 SD_BUS_METHOD("FlushCaches", NULL
, NULL
, bus_method_flush_caches
, 0),
1832 SD_BUS_METHOD("ResetServerFeatures", NULL
, NULL
, bus_method_reset_server_features
, 0),
1833 SD_BUS_METHOD("GetLink", "i", "o", bus_method_get_link
, SD_BUS_VTABLE_UNPRIVILEGED
),
1834 SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL
, bus_method_set_link_dns_servers
, 0),
1835 SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL
, bus_method_set_link_domains
, 0),
1836 SD_BUS_METHOD("SetLinkLLMNR", "is", NULL
, bus_method_set_link_llmnr
, 0),
1837 SD_BUS_METHOD("SetLinkMulticastDNS", "is", NULL
, bus_method_set_link_mdns
, 0),
1838 SD_BUS_METHOD("SetLinkDNSSEC", "is", NULL
, bus_method_set_link_dnssec
, 0),
1839 SD_BUS_METHOD("SetLinkDNSSECNegativeTrustAnchors", "ias", NULL
, bus_method_set_link_dnssec_negative_trust_anchors
, 0),
1840 SD_BUS_METHOD("RevertLink", "i", NULL
, bus_method_revert_link
, 0),
1842 SD_BUS_METHOD("RegisterService", "sssqqqaa{say}", "o", bus_method_register_service
, SD_BUS_VTABLE_UNPRIVILEGED
),
1843 SD_BUS_METHOD("UnregisterService", "o", NULL
, bus_method_unregister_service
, SD_BUS_VTABLE_UNPRIVILEGED
),
1847 static int on_bus_retry(sd_event_source
*s
, usec_t usec
, void *userdata
) {
1848 Manager
*m
= userdata
;
1853 m
->bus_retry_event_source
= sd_event_source_unref(m
->bus_retry_event_source
);
1855 manager_connect_bus(m
);
1859 static int match_prepare_for_sleep(sd_bus_message
*message
, void *userdata
, sd_bus_error
*ret_error
) {
1860 Manager
*m
= userdata
;
1866 r
= sd_bus_message_read(message
, "b", &b
);
1868 log_debug_errno(r
, "Failed to parse PrepareForSleep signal: %m");
1875 log_debug("Coming back from suspend, verifying all RRs...");
1877 manager_verify_all(m
);
1881 int manager_connect_bus(Manager
*m
) {
1889 r
= sd_bus_default_system(&m
->bus
);
1891 /* We failed to connect? Yuck, we must be in early
1892 * boot. Let's try in 5s again. */
1894 log_debug_errno(r
, "Failed to connect to bus, trying again in 5s: %m");
1896 r
= sd_event_add_time(m
->event
, &m
->bus_retry_event_source
, CLOCK_MONOTONIC
, now(CLOCK_MONOTONIC
) + 5*USEC_PER_SEC
, 0, on_bus_retry
, m
);
1898 return log_error_errno(r
, "Failed to install bus reconnect time event: %m");
1900 (void) sd_event_source_set_description(m
->bus_retry_event_source
, "bus-retry");
1904 r
= sd_bus_add_object_vtable(m
->bus
, NULL
, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable
, m
);
1906 return log_error_errno(r
, "Failed to register object: %m");
1908 r
= sd_bus_add_fallback_vtable(m
->bus
, NULL
, "/org/freedesktop/resolve1/link", "org.freedesktop.resolve1.Link", link_vtable
, link_object_find
, m
);
1910 return log_error_errno(r
, "Failed to register link objects: %m");
1912 r
= sd_bus_add_node_enumerator(m
->bus
, NULL
, "/org/freedesktop/resolve1/link", link_node_enumerator
, m
);
1914 return log_error_errno(r
, "Failed to register link enumerator: %m");
1916 r
= sd_bus_add_fallback_vtable(m
->bus
, NULL
, "/org/freedesktop/resolve1/dnssd", "org.freedesktop.resolve1.DnssdService", dnssd_vtable
, dnssd_object_find
, m
);
1918 return log_error_errno(r
, "Failed to register dnssd objects: %m");
1920 r
= sd_bus_add_node_enumerator(m
->bus
, NULL
, "/org/freedesktop/resolve1/dnssd", dnssd_node_enumerator
, m
);
1922 return log_error_errno(r
, "Failed to register dnssd enumerator: %m");
1924 r
= sd_bus_request_name(m
->bus
, "org.freedesktop.resolve1", 0);
1926 return log_error_errno(r
, "Failed to register name: %m");
1928 r
= sd_bus_attach_event(m
->bus
, m
->event
, 0);
1930 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
1932 r
= sd_bus_add_match(m
->bus
, &m
->prepare_for_sleep_slot
,
1934 "sender='org.freedesktop.login1',"
1935 "interface='org.freedesktop.login1.Manager',"
1936 "member='PrepareForSleep',"
1937 "path='/org/freedesktop/login1'",
1938 match_prepare_for_sleep
,
1941 log_error_errno(r
, "Failed to add match for PrepareForSleep: %m");