1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include "alloc-util.h"
23 #include "bus-common-errors.h"
25 #include "dns-domain.h"
26 #include "resolved-bus.h"
27 #include "resolved-def.h"
28 #include "resolved-link-bus.h"
30 static int reply_query_state(DnsQuery
*q
) {
34 case DNS_TRANSACTION_NO_SERVERS
:
35 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_NAME_SERVERS
, "No appropriate name servers or networks for name found");
37 case DNS_TRANSACTION_TIMEOUT
:
38 return sd_bus_reply_method_errorf(q
->request
, SD_BUS_ERROR_TIMEOUT
, "Query timed out");
40 case DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
:
41 return sd_bus_reply_method_errorf(q
->request
, SD_BUS_ERROR_TIMEOUT
, "All attempts to contact name servers or networks failed");
43 case DNS_TRANSACTION_INVALID_REPLY
:
44 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_INVALID_REPLY
, "Received invalid reply");
46 case DNS_TRANSACTION_ERRNO
:
47 return sd_bus_reply_method_errnof(q
->request
, q
->answer_errno
, "Lookup failed due to system error: %m");
49 case DNS_TRANSACTION_ABORTED
:
50 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_ABORTED
, "Query aborted");
52 case DNS_TRANSACTION_DNSSEC_FAILED
:
53 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_DNSSEC_FAILED
, "DNSSEC validation failed: %s",
54 dnssec_result_to_string(q
->answer_dnssec_result
));
56 case DNS_TRANSACTION_NO_TRUST_ANCHOR
:
57 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_TRUST_ANCHOR
, "No suitable trust anchor known");
59 case DNS_TRANSACTION_RR_TYPE_UNSUPPORTED
:
60 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_RR_TYPE_UNSUPPORTED
, "Server does not support requested resource record type");
62 case DNS_TRANSACTION_NETWORK_DOWN
:
63 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NETWORK_DOWN
, "Network is down");
65 case DNS_TRANSACTION_NOT_FOUND
:
66 /* We return this as NXDOMAIN. This is only generated when a host doesn't implement LLMNR/TCP, and we
67 * thus quickly know that we cannot resolve an in-addr.arpa or ip6.arpa address. */
68 return sd_bus_reply_method_errorf(q
->request
, _BUS_ERROR_DNS
"NXDOMAIN", "'%s' not found", dns_query_string(q
));
70 case DNS_TRANSACTION_RCODE_FAILURE
: {
71 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
73 if (q
->answer_rcode
== DNS_RCODE_NXDOMAIN
)
74 sd_bus_error_setf(&error
, _BUS_ERROR_DNS
"NXDOMAIN", "'%s' not found", dns_query_string(q
));
77 char p
[DECIMAL_STR_MAX(q
->answer_rcode
)];
79 rc
= dns_rcode_to_string(q
->answer_rcode
);
81 sprintf(p
, "%i", q
->answer_rcode
);
85 n
= strjoina(_BUS_ERROR_DNS
, rc
);
86 sd_bus_error_setf(&error
, n
, "Could not resolve '%s', server or network returned error %s", dns_query_string(q
), rc
);
89 return sd_bus_reply_method_error(q
->request
, &error
);
92 case DNS_TRANSACTION_NULL
:
93 case DNS_TRANSACTION_PENDING
:
94 case DNS_TRANSACTION_VALIDATING
:
95 case DNS_TRANSACTION_SUCCESS
:
97 assert_not_reached("Impossible state");
101 static int append_address(sd_bus_message
*reply
, DnsResourceRecord
*rr
, int ifindex
) {
107 r
= sd_bus_message_open_container(reply
, 'r', "iiay");
111 r
= sd_bus_message_append(reply
, "i", ifindex
);
115 if (rr
->key
->type
== DNS_TYPE_A
) {
116 r
= sd_bus_message_append(reply
, "i", AF_INET
);
120 r
= sd_bus_message_append_array(reply
, 'y', &rr
->a
.in_addr
, sizeof(struct in_addr
));
122 } else if (rr
->key
->type
== DNS_TYPE_AAAA
) {
123 r
= sd_bus_message_append(reply
, "i", AF_INET6
);
127 r
= sd_bus_message_append_array(reply
, 'y', &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
));
129 return -EAFNOSUPPORT
;
134 r
= sd_bus_message_close_container(reply
);
141 static void bus_method_resolve_hostname_complete(DnsQuery
*q
) {
142 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*canonical
= NULL
;
143 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
144 DnsResourceRecord
*rr
;
150 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
151 r
= reply_query_state(q
);
155 r
= dns_query_process_cname(q
);
157 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
));
162 if (r
== DNS_QUERY_RESTARTED
) /* This was a cname, and the query was restarted. */
165 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
169 r
= sd_bus_message_open_container(reply
, 'a', "(iiay)");
173 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
174 DnsQuestion
*question
;
176 question
= dns_query_question_for_protocol(q
, q
->answer_protocol
);
178 r
= dns_question_matches_rr(question
, rr
, DNS_SEARCH_DOMAIN_NAME(q
->answer_search_domain
));
184 r
= append_address(reply
, rr
, ifindex
);
189 canonical
= dns_resource_record_ref(rr
);
195 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
));
199 r
= sd_bus_message_close_container(reply
);
203 /* Return the precise spelling and uppercasing and CNAME target reported by the server */
205 r
= sd_bus_message_append(
207 DNS_RESOURCE_KEY_NAME(canonical
->key
),
208 SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
, q
->answer_authenticated
));
212 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
216 log_error_errno(r
, "Failed to send hostname reply: %m");
217 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
223 static int check_ifindex_flags(int ifindex
, uint64_t *flags
, uint64_t ok
, sd_bus_error
*error
) {
227 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid interface index");
229 if (*flags
& ~(SD_RESOLVED_PROTOCOLS_ALL
|SD_RESOLVED_NO_CNAME
|ok
))
230 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid flags parameter");
232 if ((*flags
& SD_RESOLVED_PROTOCOLS_ALL
) == 0) /* If no protocol is enabled, enable all */
233 *flags
|= SD_RESOLVED_PROTOCOLS_ALL
;
238 static int bus_method_resolve_hostname(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
239 _cleanup_(dns_question_unrefp
) DnsQuestion
*question_idna
= NULL
, *question_utf8
= NULL
;
240 Manager
*m
= userdata
;
241 const char *hostname
;
250 assert_cc(sizeof(int) == sizeof(int32_t));
252 r
= sd_bus_message_read(message
, "isit", &ifindex
, &hostname
, &family
, &flags
);
256 if (!IN_SET(family
, AF_INET
, AF_INET6
, AF_UNSPEC
))
257 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown address family %i", family
);
259 r
= dns_name_is_valid(hostname
);
263 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid hostname '%s'", hostname
);
265 r
= check_ifindex_flags(ifindex
, &flags
, SD_RESOLVED_NO_SEARCH
, error
);
269 r
= dns_question_new_address(&question_utf8
, family
, hostname
, false);
273 r
= dns_question_new_address(&question_idna
, family
, hostname
, true);
277 r
= dns_query_new(m
, &q
, question_utf8
, question_idna
, ifindex
, flags
);
281 q
->request
= sd_bus_message_ref(message
);
282 q
->request_family
= family
;
283 q
->complete
= bus_method_resolve_hostname_complete
;
285 r
= dns_query_bus_track(q
, message
);
300 static void bus_method_resolve_address_complete(DnsQuery
*q
) {
301 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
302 DnsQuestion
*question
;
303 DnsResourceRecord
*rr
;
309 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
310 r
= reply_query_state(q
);
314 r
= dns_query_process_cname(q
);
316 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
));
321 if (r
== DNS_QUERY_RESTARTED
) /* This was a cname, and the query was restarted. */
324 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
328 r
= sd_bus_message_open_container(reply
, 'a', "(is)");
332 question
= dns_query_question_for_protocol(q
, q
->answer_protocol
);
334 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
335 r
= dns_question_matches_rr(question
, rr
, NULL
);
341 r
= sd_bus_message_append(reply
, "(is)", ifindex
, rr
->ptr
.name
);
349 _cleanup_free_
char *ip
= NULL
;
351 in_addr_to_string(q
->request_family
, &q
->request_address
, &ip
);
352 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_SUCH_RR
, "Address '%s' does not have any RR of requested type", strna(ip
));
356 r
= sd_bus_message_close_container(reply
);
360 r
= sd_bus_message_append(reply
, "t", SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
, q
->answer_authenticated
));
364 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
368 log_error_errno(r
, "Failed to send address reply: %m");
369 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
375 static int bus_method_resolve_address(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
376 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
377 Manager
*m
= userdata
;
388 assert_cc(sizeof(int) == sizeof(int32_t));
390 r
= sd_bus_message_read(message
, "ii", &ifindex
, &family
);
394 if (!IN_SET(family
, AF_INET
, AF_INET6
))
395 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown address family %i", family
);
397 r
= sd_bus_message_read_array(message
, 'y', &d
, &sz
);
401 if (sz
!= FAMILY_ADDRESS_SIZE(family
))
402 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid address size");
404 r
= sd_bus_message_read(message
, "t", &flags
);
408 r
= check_ifindex_flags(ifindex
, &flags
, 0, error
);
412 r
= dns_question_new_reverse(&question
, family
, d
);
416 r
= dns_query_new(m
, &q
, question
, question
, ifindex
, flags
|SD_RESOLVED_NO_SEARCH
);
420 q
->request
= sd_bus_message_ref(message
);
421 q
->request_family
= family
;
422 memcpy(&q
->request_address
, d
, sz
);
423 q
->complete
= bus_method_resolve_address_complete
;
425 r
= dns_query_bus_track(q
, message
);
440 static int bus_message_append_rr(sd_bus_message
*m
, DnsResourceRecord
*rr
, int ifindex
) {
446 r
= sd_bus_message_open_container(m
, 'r', "iqqay");
450 r
= sd_bus_message_append(m
, "iqq",
457 r
= dns_resource_record_to_wire_format(rr
, false);
461 r
= sd_bus_message_append_array(m
, 'y', rr
->wire_format
, rr
->wire_format_size
);
465 return sd_bus_message_close_container(m
);
468 static void bus_method_resolve_record_complete(DnsQuery
*q
) {
469 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
470 DnsResourceRecord
*rr
;
471 DnsQuestion
*question
;
478 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
479 r
= reply_query_state(q
);
483 r
= dns_query_process_cname(q
);
485 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
));
490 if (r
== DNS_QUERY_RESTARTED
) /* This was a cname, and the query was restarted. */
493 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
497 r
= sd_bus_message_open_container(reply
, 'a', "(iqqay)");
501 question
= dns_query_question_for_protocol(q
, q
->answer_protocol
);
503 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
504 r
= dns_question_matches_rr(question
, rr
, NULL
);
510 r
= bus_message_append_rr(reply
, rr
, ifindex
);
518 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
));
522 r
= sd_bus_message_close_container(reply
);
526 r
= sd_bus_message_append(reply
, "t", SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
, q
->answer_authenticated
));
530 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
534 log_error_errno(r
, "Failed to send record reply: %m");
535 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
541 static int bus_method_resolve_record(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
542 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
543 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
544 Manager
*m
= userdata
;
545 uint16_t class, type
;
554 assert_cc(sizeof(int) == sizeof(int32_t));
556 r
= sd_bus_message_read(message
, "isqqt", &ifindex
, &name
, &class, &type
, &flags
);
560 r
= dns_name_is_valid(name
);
564 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid name '%s'", name
);
566 if (!dns_type_is_valid_query(type
))
567 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Specified resource record type %" PRIu16
" may not be used in a query.", type
);
568 if (dns_type_is_obsolete(type
))
569 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Specified DNS resource record type %" PRIu16
" is obsolete.", type
);
571 r
= check_ifindex_flags(ifindex
, &flags
, 0, error
);
575 question
= dns_question_new(1);
579 key
= dns_resource_key_new(class, type
, name
);
583 r
= dns_question_add(question
, key
);
587 r
= dns_query_new(m
, &q
, question
, question
, ifindex
, flags
|SD_RESOLVED_NO_SEARCH
);
591 q
->request
= sd_bus_message_ref(message
);
592 q
->complete
= bus_method_resolve_record_complete
;
594 r
= dns_query_bus_track(q
, message
);
609 static int append_srv(DnsQuery
*q
, sd_bus_message
*reply
, DnsResourceRecord
*rr
) {
610 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*canonical
= NULL
;
619 if (rr
->key
->type
!= DNS_TYPE_SRV
)
622 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
623 /* First, let's see if we could find an appropriate A or AAAA
624 * record for the SRV record */
625 LIST_FOREACH(auxiliary_queries
, aux
, q
->auxiliary_queries
) {
626 DnsResourceRecord
*zz
;
627 DnsQuestion
*question
;
629 if (aux
->state
!= DNS_TRANSACTION_SUCCESS
)
631 if (aux
->auxiliary_result
!= 0)
634 question
= dns_query_question_for_protocol(aux
, aux
->answer_protocol
);
636 r
= dns_name_equal(dns_question_first_name(question
), rr
->srv
.name
);
642 DNS_ANSWER_FOREACH(zz
, aux
->answer
) {
644 r
= dns_question_matches_rr(question
, zz
, NULL
);
650 canonical
= dns_resource_record_ref(zz
);
658 /* Is there are successful A/AAAA lookup for this SRV RR? If not, don't add it */
663 r
= sd_bus_message_open_container(reply
, 'r', "qqqsa(iiay)s");
667 r
= sd_bus_message_append(
670 rr
->srv
.priority
, rr
->srv
.weight
, rr
->srv
.port
, rr
->srv
.name
);
674 r
= sd_bus_message_open_container(reply
, 'a', "(iiay)");
678 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
679 LIST_FOREACH(auxiliary_queries
, aux
, q
->auxiliary_queries
) {
680 DnsResourceRecord
*zz
;
681 DnsQuestion
*question
;
684 if (aux
->state
!= DNS_TRANSACTION_SUCCESS
)
686 if (aux
->auxiliary_result
!= 0)
689 question
= dns_query_question_for_protocol(aux
, aux
->answer_protocol
);
691 r
= dns_name_equal(dns_question_first_name(question
), rr
->srv
.name
);
697 DNS_ANSWER_FOREACH_IFINDEX(zz
, ifindex
, aux
->answer
) {
699 r
= dns_question_matches_rr(question
, zz
, NULL
);
705 r
= append_address(reply
, zz
, ifindex
);
712 r
= sd_bus_message_close_container(reply
);
716 /* Note that above we appended the hostname as encoded in the
717 * SRV, and here the canonical hostname this maps to. */
718 r
= sd_bus_message_append(reply
, "s", canonical
? DNS_RESOURCE_KEY_NAME(canonical
->key
) : rr
->srv
.name
);
722 r
= sd_bus_message_close_container(reply
);
729 static int append_txt(sd_bus_message
*reply
, DnsResourceRecord
*rr
) {
737 if (rr
->key
->type
!= DNS_TYPE_TXT
)
740 LIST_FOREACH(items
, i
, rr
->txt
.items
) {
745 r
= sd_bus_message_append_array(reply
, 'y', i
->data
, i
->length
);
753 static void resolve_service_all_complete(DnsQuery
*q
) {
754 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*canonical
= NULL
;
755 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
756 _cleanup_free_
char *name
= NULL
, *type
= NULL
, *domain
= NULL
;
757 DnsQuestion
*question
;
758 DnsResourceRecord
*rr
;
765 if (q
->block_all_complete
> 0)
768 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
769 DnsQuery
*bad
= NULL
;
770 bool have_success
= false;
772 LIST_FOREACH(auxiliary_queries
, aux
, q
->auxiliary_queries
) {
774 switch (aux
->state
) {
776 case DNS_TRANSACTION_PENDING
:
777 /* If an auxiliary query is still pending, let's wait */
780 case DNS_TRANSACTION_SUCCESS
:
781 if (aux
->auxiliary_result
== 0)
794 /* We can only return one error, hence pick the last error we encountered */
798 if (bad
->state
== DNS_TRANSACTION_SUCCESS
) {
799 assert(bad
->auxiliary_result
!= 0);
801 if (bad
->auxiliary_result
== -ELOOP
) {
802 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
));
806 r
= bad
->auxiliary_result
;
810 r
= reply_query_state(bad
);
815 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
819 r
= sd_bus_message_open_container(reply
, 'a', "(qqqsa(iiay)s)");
823 question
= dns_query_question_for_protocol(q
, q
->answer_protocol
);
824 DNS_ANSWER_FOREACH(rr
, q
->answer
) {
825 r
= dns_question_matches_rr(question
, rr
, NULL
);
831 r
= append_srv(q
, reply
, rr
);
834 if (r
== 0) /* not an SRV record */
838 canonical
= dns_resource_record_ref(rr
);
844 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
));
848 r
= sd_bus_message_close_container(reply
);
852 r
= sd_bus_message_open_container(reply
, 'a', "ay");
856 DNS_ANSWER_FOREACH(rr
, q
->answer
) {
857 r
= dns_question_matches_rr(question
, rr
, NULL
);
863 r
= append_txt(reply
, rr
);
868 r
= sd_bus_message_close_container(reply
);
873 r
= dns_service_split(DNS_RESOURCE_KEY_NAME(canonical
->key
), &name
, &type
, &domain
);
877 r
= sd_bus_message_append(
881 SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
, q
->answer_authenticated
));
885 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
889 log_error_errno(r
, "Failed to send service reply: %m");
890 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
896 static void resolve_service_hostname_complete(DnsQuery
*q
) {
900 assert(q
->auxiliary_for
);
902 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
903 resolve_service_all_complete(q
->auxiliary_for
);
907 r
= dns_query_process_cname(q
);
908 if (r
== DNS_QUERY_RESTARTED
) /* This was a cname, and the query was restarted. */
911 /* This auxiliary lookup is finished or failed, let's see if all are finished now. */
912 q
->auxiliary_result
= r
;
913 resolve_service_all_complete(q
->auxiliary_for
);
916 static int resolve_service_hostname(DnsQuery
*q
, DnsResourceRecord
*rr
, int ifindex
) {
917 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
924 assert(rr
->key
->type
== DNS_TYPE_SRV
);
926 /* OK, we found an SRV record for the service. Let's resolve
927 * the hostname included in it */
929 r
= dns_question_new_address(&question
, q
->request_family
, rr
->srv
.name
, false);
933 r
= dns_query_new(q
->manager
, &aux
, question
, question
, ifindex
, q
->flags
|SD_RESOLVED_NO_SEARCH
);
937 aux
->request_family
= q
->request_family
;
938 aux
->complete
= resolve_service_hostname_complete
;
940 r
= dns_query_make_auxiliary(aux
, q
);
942 /* Too many auxiliary lookups? If so, don't complain,
943 * let's just not add this one, we already have more
952 /* Note that auxiliary queries do not track the original bus
953 * client, only the primary request does that. */
955 r
= dns_query_go(aux
);
966 static void bus_method_resolve_service_complete(DnsQuery
*q
) {
967 bool has_root_domain
= false;
968 DnsResourceRecord
*rr
;
969 DnsQuestion
*question
;
975 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
976 r
= reply_query_state(q
);
980 r
= dns_query_process_cname(q
);
982 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
));
987 if (r
== DNS_QUERY_RESTARTED
) /* This was a cname, and the query was restarted. */
990 question
= dns_query_question_for_protocol(q
, q
->answer_protocol
);
992 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
993 r
= dns_question_matches_rr(question
, rr
, NULL
);
999 if (rr
->key
->type
!= DNS_TYPE_SRV
)
1002 if (dns_name_is_root(rr
->srv
.name
)) {
1003 has_root_domain
= true;
1007 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
1008 q
->block_all_complete
++;
1009 r
= resolve_service_hostname(q
, rr
, ifindex
);
1010 q
->block_all_complete
--;
1019 if (has_root_domain
&& found
<= 0) {
1020 /* If there's exactly one SRV RR and it uses
1021 * the root domain as host name, then the
1022 * service is explicitly not offered on the
1023 * domain. Report this as a recognizable
1024 * error. See RFC 2782, Section "Usage
1026 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_SUCH_SERVICE
, "'%s' does not provide the requested service", dns_query_string(q
));
1031 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
));
1035 /* Maybe we are already finished? check now... */
1036 resolve_service_all_complete(q
);
1041 log_error_errno(r
, "Failed to send service reply: %m");
1042 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
1048 static int bus_method_resolve_service(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1049 _cleanup_(dns_question_unrefp
) DnsQuestion
*question_idna
= NULL
, *question_utf8
= NULL
;
1050 const char *name
, *type
, *domain
;
1051 _cleanup_free_
char *n
= NULL
;
1052 Manager
*m
= userdata
;
1053 int family
, ifindex
;
1061 assert_cc(sizeof(int) == sizeof(int32_t));
1063 r
= sd_bus_message_read(message
, "isssit", &ifindex
, &name
, &type
, &domain
, &family
, &flags
);
1067 if (!IN_SET(family
, AF_INET
, AF_INET6
, AF_UNSPEC
))
1068 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown address family %i", family
);
1072 else if (!dns_service_name_is_valid(name
))
1073 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid service name '%s'", name
);
1077 else if (!dns_srv_type_is_valid(type
))
1078 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid SRV service type '%s'", type
);
1080 r
= dns_name_is_valid(domain
);
1084 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid domain '%s'", domain
);
1087 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Service name cannot be specified without service type.");
1089 r
= check_ifindex_flags(ifindex
, &flags
, SD_RESOLVED_NO_TXT
|SD_RESOLVED_NO_ADDRESS
, error
);
1093 r
= dns_question_new_service(&question_utf8
, name
, type
, domain
, !(flags
& SD_RESOLVED_NO_TXT
), false);
1097 r
= dns_question_new_service(&question_idna
, name
, type
, domain
, !(flags
& SD_RESOLVED_NO_TXT
), true);
1101 r
= dns_query_new(m
, &q
, question_utf8
, question_idna
, ifindex
, flags
|SD_RESOLVED_NO_SEARCH
);
1105 q
->request
= sd_bus_message_ref(message
);
1106 q
->request_family
= family
;
1107 q
->complete
= bus_method_resolve_service_complete
;
1109 r
= dns_query_bus_track(q
, message
);
1113 r
= dns_query_go(q
);
1124 int bus_dns_server_append(sd_bus_message
*reply
, DnsServer
*s
, bool with_ifindex
) {
1130 r
= sd_bus_message_open_container(reply
, 'r', with_ifindex
? "iiay" : "iay");
1135 r
= sd_bus_message_append(reply
, "i", s
->link
? s
->link
->ifindex
: 0);
1140 r
= sd_bus_message_append(reply
, "i", s
->family
);
1144 r
= sd_bus_message_append_array(reply
, 'y', &s
->address
, FAMILY_ADDRESS_SIZE(s
->family
));
1148 return sd_bus_message_close_container(reply
);
1151 static int bus_property_get_dns_servers(
1154 const char *interface
,
1155 const char *property
,
1156 sd_bus_message
*reply
,
1158 sd_bus_error
*error
) {
1160 Manager
*m
= userdata
;
1170 r
= sd_bus_message_open_container(reply
, 'a', "(iiay)");
1174 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
1175 r
= bus_dns_server_append(reply
, s
, true);
1182 HASHMAP_FOREACH(l
, m
->links
, i
) {
1183 LIST_FOREACH(servers
, s
, l
->dns_servers
) {
1184 r
= bus_dns_server_append(reply
, s
, true);
1192 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
) {
1193 r
= bus_dns_server_append(reply
, s
, true);
1199 return sd_bus_message_close_container(reply
);
1202 static int bus_property_get_search_domains(
1205 const char *interface
,
1206 const char *property
,
1207 sd_bus_message
*reply
,
1209 sd_bus_error
*error
) {
1211 Manager
*m
= userdata
;
1220 r
= sd_bus_message_open_container(reply
, 'a', "(is)");
1224 LIST_FOREACH(domains
, d
, m
->search_domains
) {
1225 r
= sd_bus_message_append(reply
, "(is)", 0, d
->name
);
1230 HASHMAP_FOREACH(l
, m
->links
, i
) {
1231 LIST_FOREACH(domains
, d
, l
->search_domains
) {
1232 r
= sd_bus_message_append(reply
, "is", l
->ifindex
, d
->name
);
1238 return sd_bus_message_close_container(reply
);
1241 static int bus_property_get_transaction_statistics(
1244 const char *interface
,
1245 const char *property
,
1246 sd_bus_message
*reply
,
1248 sd_bus_error
*error
) {
1250 Manager
*m
= userdata
;
1255 return sd_bus_message_append(reply
, "(tt)",
1256 (uint64_t) hashmap_size(m
->dns_transactions
),
1257 (uint64_t) m
->n_transactions_total
);
1260 static int bus_property_get_cache_statistics(
1263 const char *interface
,
1264 const char *property
,
1265 sd_bus_message
*reply
,
1267 sd_bus_error
*error
) {
1269 uint64_t size
= 0, hit
= 0, miss
= 0;
1270 Manager
*m
= userdata
;
1276 LIST_FOREACH(scopes
, s
, m
->dns_scopes
) {
1277 size
+= dns_cache_size(&s
->cache
);
1278 hit
+= s
->cache
.n_hit
;
1279 miss
+= s
->cache
.n_miss
;
1282 return sd_bus_message_append(reply
, "(ttt)", size
, hit
, miss
);
1285 static int bus_property_get_dnssec_statistics(
1288 const char *interface
,
1289 const char *property
,
1290 sd_bus_message
*reply
,
1292 sd_bus_error
*error
) {
1294 Manager
*m
= userdata
;
1299 return sd_bus_message_append(reply
, "(tttt)",
1300 (uint64_t) m
->n_dnssec_verdict
[DNSSEC_SECURE
],
1301 (uint64_t) m
->n_dnssec_verdict
[DNSSEC_INSECURE
],
1302 (uint64_t) m
->n_dnssec_verdict
[DNSSEC_BOGUS
],
1303 (uint64_t) m
->n_dnssec_verdict
[DNSSEC_INDETERMINATE
]);
1306 static int bus_property_get_dnssec_supported(
1309 const char *interface
,
1310 const char *property
,
1311 sd_bus_message
*reply
,
1313 sd_bus_error
*error
) {
1315 Manager
*m
= userdata
;
1320 return sd_bus_message_append(reply
, "b", manager_dnssec_supported(m
));
1323 static int bus_method_reset_statistics(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1324 Manager
*m
= userdata
;
1330 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1331 s
->cache
.n_hit
= s
->cache
.n_miss
= 0;
1333 m
->n_transactions_total
= 0;
1334 zero(m
->n_dnssec_verdict
);
1336 return sd_bus_reply_method_return(message
, NULL
);
1339 static int get_any_link(Manager
*m
, int ifindex
, Link
**ret
, sd_bus_error
*error
) {
1346 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid interface index");
1348 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
1350 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_LINK
, "Link %i not known", ifindex
);
1356 static int get_unmanaged_link(Manager
*m
, int ifindex
, Link
**ret
, sd_bus_error
*error
) {
1363 r
= get_any_link(m
, ifindex
, &l
, error
);
1367 if (l
->flags
& IFF_LOOPBACK
)
1368 return sd_bus_error_setf(error
, BUS_ERROR_LINK_BUSY
, "Link %s is loopback device.", l
->name
);
1370 return sd_bus_error_setf(error
, BUS_ERROR_LINK_BUSY
, "Link %s is managed.", l
->name
);
1376 static int call_link_method(Manager
*m
, sd_bus_message
*message
, sd_bus_message_handler_t handler
, sd_bus_error
*error
) {
1384 assert_cc(sizeof(int) == sizeof(int32_t));
1385 r
= sd_bus_message_read(message
, "i", &ifindex
);
1389 r
= get_unmanaged_link(m
, ifindex
, &l
, error
);
1393 return handler(message
, l
, error
);
1396 static int bus_method_set_link_dns_servers(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1397 return call_link_method(userdata
, message
, bus_link_method_set_dns_servers
, error
);
1400 static int bus_method_set_link_search_domains(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1401 return call_link_method(userdata
, message
, bus_link_method_set_search_domains
, error
);
1404 static int bus_method_set_link_llmnr(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1405 return call_link_method(userdata
, message
, bus_link_method_set_llmnr
, error
);
1408 static int bus_method_set_link_mdns(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1409 return call_link_method(userdata
, message
, bus_link_method_set_mdns
, error
);
1412 static int bus_method_set_link_dnssec(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1413 return call_link_method(userdata
, message
, bus_link_method_set_dnssec
, error
);
1416 static int bus_method_set_link_dnssec_negative_trust_anchors(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1417 return call_link_method(userdata
, message
, bus_link_method_set_dnssec_negative_trust_anchors
, error
);
1420 static int bus_method_revert_link(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1421 return call_link_method(userdata
, message
, bus_link_method_revert
, error
);
1424 static int bus_method_get_link(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1425 _cleanup_free_
char *p
= NULL
;
1426 Manager
*m
= userdata
;
1433 assert_cc(sizeof(int) == sizeof(int32_t));
1434 r
= sd_bus_message_read(message
, "i", &ifindex
);
1438 r
= get_any_link(m
, ifindex
, &l
, error
);
1442 p
= link_bus_path(l
);
1446 return sd_bus_reply_method_return(message
, "o", p
);
1449 static const sd_bus_vtable resolve_vtable
[] = {
1450 SD_BUS_VTABLE_START(0),
1451 SD_BUS_PROPERTY("LLMNRHostname", "s", NULL
, offsetof(Manager
, llmnr_hostname
), 0),
1452 SD_BUS_PROPERTY("DNS", "a(iiay)", bus_property_get_dns_servers
, 0, 0),
1453 SD_BUS_PROPERTY("Domains", "a(is)", bus_property_get_search_domains
, 0, 0),
1454 SD_BUS_PROPERTY("TransactionStatistics", "(tt)", bus_property_get_transaction_statistics
, 0, 0),
1455 SD_BUS_PROPERTY("CacheStatistics", "(ttt)", bus_property_get_cache_statistics
, 0, 0),
1456 SD_BUS_PROPERTY("DNSSECStatistics", "(tttt)", bus_property_get_dnssec_statistics
, 0, 0),
1457 SD_BUS_PROPERTY("DNSSECSupported", "b", bus_property_get_dnssec_supported
, 0, 0),
1459 SD_BUS_METHOD("ResolveHostname", "isit", "a(iiay)st", bus_method_resolve_hostname
, SD_BUS_VTABLE_UNPRIVILEGED
),
1460 SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address
, SD_BUS_VTABLE_UNPRIVILEGED
),
1461 SD_BUS_METHOD("ResolveRecord", "isqqt", "a(iqqay)t", bus_method_resolve_record
, SD_BUS_VTABLE_UNPRIVILEGED
),
1462 SD_BUS_METHOD("ResolveService", "isssit", "a(qqqsa(iiay)s)aayssst", bus_method_resolve_service
, SD_BUS_VTABLE_UNPRIVILEGED
),
1463 SD_BUS_METHOD("ResetStatistics", NULL
, NULL
, bus_method_reset_statistics
, 0),
1464 SD_BUS_METHOD("GetLink", "i", "o", bus_method_get_link
, SD_BUS_VTABLE_UNPRIVILEGED
),
1465 SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL
, bus_method_set_link_dns_servers
, 0),
1466 SD_BUS_METHOD("SetLinkDomains", "ias", NULL
, bus_method_set_link_search_domains
, 0),
1467 SD_BUS_METHOD("SetLinkLLMNR", "is", NULL
, bus_method_set_link_llmnr
, 0),
1468 SD_BUS_METHOD("SetLinkMulticastDNS", "is", NULL
, bus_method_set_link_mdns
, 0),
1469 SD_BUS_METHOD("SetLinkDNSSEC", "is", NULL
, bus_method_set_link_dnssec
, 0),
1470 SD_BUS_METHOD("SetLinkDNSSECNegativeTrustAnchors", "ias", NULL
, bus_method_set_link_dnssec_negative_trust_anchors
, 0),
1471 SD_BUS_METHOD("RevertLink", "i", NULL
, bus_method_revert_link
, 0),
1476 static int on_bus_retry(sd_event_source
*s
, usec_t usec
, void *userdata
) {
1477 Manager
*m
= userdata
;
1482 m
->bus_retry_event_source
= sd_event_source_unref(m
->bus_retry_event_source
);
1484 manager_connect_bus(m
);
1488 static int match_prepare_for_sleep(sd_bus_message
*message
, void *userdata
, sd_bus_error
*ret_error
) {
1489 Manager
*m
= userdata
;
1495 r
= sd_bus_message_read(message
, "b", &b
);
1497 log_debug_errno(r
, "Failed to parse PrepareForSleep signal: %m");
1504 log_debug("Coming back from suspend, verifying all RRs...");
1506 manager_verify_all(m
);
1510 int manager_connect_bus(Manager
*m
) {
1518 r
= sd_bus_default_system(&m
->bus
);
1520 /* We failed to connect? Yuck, we must be in early
1521 * boot. Let's try in 5s again. As soon as we have
1522 * kdbus we can stop doing this... */
1524 log_debug_errno(r
, "Failed to connect to bus, trying again in 5s: %m");
1526 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
);
1528 return log_error_errno(r
, "Failed to install bus reconnect time event: %m");
1530 (void) sd_event_source_set_description(m
->bus_retry_event_source
, "bus-retry");
1534 r
= sd_bus_add_object_vtable(m
->bus
, NULL
, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable
, m
);
1536 return log_error_errno(r
, "Failed to register object: %m");
1538 r
= sd_bus_add_fallback_vtable(m
->bus
, NULL
, "/org/freedesktop/resolve1/link", "org.freedesktop.resolve1.Link", link_vtable
, link_object_find
, m
);
1540 return log_error_errno(r
, "Failed to register link objects: %m");
1542 r
= sd_bus_add_node_enumerator(m
->bus
, NULL
, "/org/freedesktop/resolve1/link", link_node_enumerator
, m
);
1544 return log_error_errno(r
, "Failed to register link enumerator: %m");
1546 r
= sd_bus_request_name(m
->bus
, "org.freedesktop.resolve1", 0);
1548 return log_error_errno(r
, "Failed to register name: %m");
1550 r
= sd_bus_attach_event(m
->bus
, m
->event
, 0);
1552 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
1554 r
= sd_bus_add_match(m
->bus
, &m
->prepare_for_sleep_slot
,
1556 "sender='org.freedesktop.login1',"
1557 "interface='org.freedesktop.login1.Manager',"
1558 "member='PrepareForSleep',"
1559 "path='/org/freedesktop/login1'",
1560 match_prepare_for_sleep
,
1563 log_error_errno(r
, "Failed to add match for PrepareForSleep: %m");