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"
29 static int reply_query_state(DnsQuery
*q
) {
30 _cleanup_free_
char *ip
= NULL
;
34 if (q
->request_address_valid
) {
35 r
= in_addr_to_string(q
->request_family
, &q
->request_address
, &ip
);
41 name
= dns_question_name(q
->question
);
45 case DNS_TRANSACTION_NO_SERVERS
:
46 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_NAME_SERVERS
, "No appropriate name servers or networks for name found");
48 case DNS_TRANSACTION_TIMEOUT
:
49 return sd_bus_reply_method_errorf(q
->request
, SD_BUS_ERROR_TIMEOUT
, "Query timed out");
51 case DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
:
52 return sd_bus_reply_method_errorf(q
->request
, SD_BUS_ERROR_TIMEOUT
, "All attempts to contact name servers or networks failed");
54 case DNS_TRANSACTION_INVALID_REPLY
:
55 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_INVALID_REPLY
, "Received invalid reply");
57 case DNS_TRANSACTION_RESOURCES
:
58 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_RESOURCES
, "Not enough resources");
60 case DNS_TRANSACTION_ABORTED
:
61 return sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_ABORTED
, "Query aborted");
63 case DNS_TRANSACTION_FAILURE
: {
64 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
66 if (q
->answer_rcode
== DNS_RCODE_NXDOMAIN
)
67 sd_bus_error_setf(&error
, _BUS_ERROR_DNS
"NXDOMAIN", "'%s' not found", name
);
70 char p
[3]; /* the rcode is 4 bits long */
72 rc
= dns_rcode_to_string(q
->answer_rcode
);
74 sprintf(p
, "%i", q
->answer_rcode
);
78 n
= strjoina(_BUS_ERROR_DNS
, rc
);
79 sd_bus_error_setf(&error
, n
, "Could not resolve '%s', server or network returned error %s", name
, rc
);
82 return sd_bus_reply_method_error(q
->request
, &error
);
85 case DNS_TRANSACTION_NULL
:
86 case DNS_TRANSACTION_PENDING
:
87 case DNS_TRANSACTION_SUCCESS
:
89 assert_not_reached("Impossible state");
93 static int append_address(sd_bus_message
*reply
, DnsResourceRecord
*rr
, int ifindex
) {
99 r
= sd_bus_message_open_container(reply
, 'r', "iiay");
103 r
= sd_bus_message_append(reply
, "i", ifindex
);
107 if (rr
->key
->type
== DNS_TYPE_A
) {
108 r
= sd_bus_message_append(reply
, "i", AF_INET
);
112 r
= sd_bus_message_append_array(reply
, 'y', &rr
->a
.in_addr
, sizeof(struct in_addr
));
114 } else if (rr
->key
->type
== DNS_TYPE_AAAA
) {
115 r
= sd_bus_message_append(reply
, "i", AF_INET6
);
119 r
= sd_bus_message_append_array(reply
, 'y', &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
));
121 return -EAFNOSUPPORT
;
126 r
= sd_bus_message_close_container(reply
);
133 static void bus_method_resolve_hostname_complete(DnsQuery
*q
) {
134 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*canonical
= NULL
;
135 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
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_question_name(q
->question
));
153 if (r
> 0) /* 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)");
165 DnsResourceRecord
*rr
;
168 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
169 r
= dns_question_matches_rr(q
->question
, rr
);
175 r
= append_address(reply
, rr
, ifindex
);
180 canonical
= dns_resource_record_ref(rr
);
187 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_SUCH_RR
, "'%s' does not have any RR of the requested type", dns_question_name(q
->question
));
191 r
= sd_bus_message_close_container(reply
);
195 /* Return the precise spelling and uppercasing and CNAME target reported by the server */
197 r
= sd_bus_message_append(
199 DNS_RESOURCE_KEY_NAME(canonical
->key
),
200 SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
));
204 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
208 log_error_errno(r
, "Failed to send hostname reply: %m");
209 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
215 static int check_ifindex_flags(int ifindex
, uint64_t *flags
, uint64_t ok
, sd_bus_error
*error
) {
219 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid interface index");
221 if (*flags
& ~(SD_RESOLVED_PROTOCOLS_ALL
|SD_RESOLVED_NO_CNAME
|ok
))
222 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid flags parameter");
224 if ((*flags
& SD_RESOLVED_PROTOCOLS_ALL
) == 0) /* If no protocol is enabled, enable all */
225 *flags
|= SD_RESOLVED_PROTOCOLS_ALL
;
230 static int bus_method_resolve_hostname(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
231 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
232 Manager
*m
= userdata
;
233 const char *hostname
;
242 assert_cc(sizeof(int) == sizeof(int32_t));
244 r
= sd_bus_message_read(message
, "isit", &ifindex
, &hostname
, &family
, &flags
);
248 if (!IN_SET(family
, AF_INET
, AF_INET6
, AF_UNSPEC
))
249 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown address family %i", family
);
251 r
= dns_name_is_valid(hostname
);
255 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid hostname '%s'", hostname
);
257 r
= check_ifindex_flags(ifindex
, &flags
, 0, error
);
261 r
= dns_question_new_address(&question
, family
, hostname
);
265 r
= dns_query_new(m
, &q
, question
, ifindex
, flags
);
269 q
->request
= sd_bus_message_ref(message
);
270 q
->request_family
= family
;
271 q
->complete
= bus_method_resolve_hostname_complete
;
273 r
= dns_query_bus_track(q
, message
);
288 static void bus_method_resolve_address_complete(DnsQuery
*q
) {
289 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
290 DnsResourceRecord
*rr
;
296 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
297 r
= reply_query_state(q
);
301 r
= dns_query_process_cname(q
);
303 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_CNAME_LOOP
, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_question_name(q
->question
));
308 if (r
> 0) /* This was a cname, and the query was restarted. */
311 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
315 r
= sd_bus_message_open_container(reply
, 'a', "(is)");
320 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
321 r
= dns_question_matches_rr(q
->question
, rr
);
327 r
= sd_bus_message_append(reply
, "(is)", ifindex
, rr
->ptr
.name
);
336 _cleanup_free_
char *ip
= NULL
;
338 in_addr_to_string(q
->request_family
, &q
->request_address
, &ip
);
339 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
));
343 r
= sd_bus_message_close_container(reply
);
347 r
= sd_bus_message_append(reply
, "t", SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
));
351 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
355 log_error_errno(r
, "Failed to send address reply: %m");
356 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
362 static int bus_method_resolve_address(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
363 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
364 Manager
*m
= userdata
;
375 assert_cc(sizeof(int) == sizeof(int32_t));
377 r
= sd_bus_message_read(message
, "ii", &ifindex
, &family
);
381 if (!IN_SET(family
, AF_INET
, AF_INET6
))
382 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown address family %i", family
);
384 r
= sd_bus_message_read_array(message
, 'y', &d
, &sz
);
388 if (sz
!= FAMILY_ADDRESS_SIZE(family
))
389 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid address size");
391 r
= sd_bus_message_read(message
, "t", &flags
);
395 r
= check_ifindex_flags(ifindex
, &flags
, 0, error
);
399 r
= dns_question_new_reverse(&question
, family
, d
);
403 r
= dns_query_new(m
, &q
, question
, ifindex
, flags
);
407 q
->request
= sd_bus_message_ref(message
);
408 q
->request_family
= family
;
409 memcpy(&q
->request_address
, d
, sz
);
410 q
->complete
= bus_method_resolve_address_complete
;
412 r
= dns_query_bus_track(q
, message
);
427 static int bus_message_append_rr(sd_bus_message
*m
, DnsResourceRecord
*rr
, int ifindex
) {
428 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
435 r
= sd_bus_message_open_container(m
, 'r', "iqqay");
439 r
= sd_bus_message_append(m
, "iqq",
446 r
= dns_packet_new(&p
, DNS_PROTOCOL_DNS
, 0);
450 p
->refuse_compression
= true;
452 r
= dns_packet_append_rr(p
, rr
, &start
);
456 r
= sd_bus_message_append_array(m
, 'y', DNS_PACKET_DATA(p
) + start
, p
->size
- start
);
460 return sd_bus_message_close_container(m
);
463 static void bus_method_resolve_record_complete(DnsQuery
*q
) {
464 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
470 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
471 r
= reply_query_state(q
);
475 r
= dns_query_process_cname(q
);
477 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_CNAME_LOOP
, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_question_name(q
->question
));
482 if (r
> 0) /* Following a CNAME */
485 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
489 r
= sd_bus_message_open_container(reply
, 'a', "(iqqay)");
494 DnsResourceRecord
*rr
;
497 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
498 r
= dns_question_matches_rr(q
->question
, rr
);
504 r
= bus_message_append_rr(reply
, rr
, ifindex
);
513 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_question_name(q
->question
));
517 r
= sd_bus_message_close_container(reply
);
521 r
= sd_bus_message_append(reply
, "t", SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
));
525 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
529 log_error_errno(r
, "Failed to send record reply: %m");
530 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
536 static int bus_method_resolve_record(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
537 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
538 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
539 Manager
*m
= userdata
;
540 uint16_t class, type
;
549 assert_cc(sizeof(int) == sizeof(int32_t));
551 r
= sd_bus_message_read(message
, "isqqt", &ifindex
, &name
, &class, &type
, &flags
);
555 r
= dns_name_is_valid(name
);
559 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid name '%s'", name
);
561 r
= check_ifindex_flags(ifindex
, &flags
, 0, error
);
565 question
= dns_question_new(1);
569 key
= dns_resource_key_new(class, type
, name
);
573 r
= dns_question_add(question
, key
);
577 r
= dns_query_new(m
, &q
, question
, ifindex
, flags
);
581 q
->request
= sd_bus_message_ref(message
);
582 q
->complete
= bus_method_resolve_record_complete
;
584 r
= dns_query_bus_track(q
, message
);
599 static int append_srv(DnsQuery
*q
, sd_bus_message
*reply
, DnsResourceRecord
*rr
) {
600 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*canonical
= NULL
;
609 if (rr
->key
->type
!= DNS_TYPE_SRV
)
612 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
613 /* First, let's see if we could find an appropriate A or AAAA
614 * record for the SRV record */
615 LIST_FOREACH(auxiliary_queries
, aux
, q
->auxiliary_queries
) {
616 DnsResourceRecord
*zz
;
618 if (aux
->state
!= DNS_TRANSACTION_SUCCESS
)
620 if (aux
->auxiliary_result
!= 0)
623 r
= dns_name_equal(dns_question_name(aux
->question
), rr
->srv
.name
);
629 DNS_ANSWER_FOREACH(zz
, aux
->answer
) {
631 r
= dns_question_matches_rr(aux
->question
, zz
);
637 canonical
= dns_resource_record_ref(zz
);
645 /* Is there are successful A/AAAA lookup for this SRV RR? If not, don't add it */
650 r
= sd_bus_message_open_container(reply
, 'r', "qqqsa(iiay)s");
654 r
= sd_bus_message_append(
657 rr
->srv
.priority
, rr
->srv
.weight
, rr
->srv
.port
, rr
->srv
.name
);
661 r
= sd_bus_message_open_container(reply
, 'a', "(iiay)");
665 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
666 LIST_FOREACH(auxiliary_queries
, aux
, q
->auxiliary_queries
) {
667 DnsResourceRecord
*zz
;
670 if (aux
->state
!= DNS_TRANSACTION_SUCCESS
)
672 if (aux
->auxiliary_result
!= 0)
675 r
= dns_name_equal(dns_question_name(aux
->question
), rr
->srv
.name
);
681 DNS_ANSWER_FOREACH_IFINDEX(zz
, ifindex
, aux
->answer
) {
683 r
= dns_question_matches_rr(aux
->question
, zz
);
689 r
= append_address(reply
, zz
, ifindex
);
696 r
= sd_bus_message_close_container(reply
);
700 /* Note that above we appended the hostname as encoded in the
701 * SRV, and here the canonical hostname this maps to. */
702 r
= sd_bus_message_append(reply
, "s", canonical
? DNS_RESOURCE_KEY_NAME(canonical
->key
) : rr
->srv
.name
);
706 r
= sd_bus_message_close_container(reply
);
713 static int append_txt(sd_bus_message
*reply
, DnsResourceRecord
*rr
) {
721 if (rr
->key
->type
!= DNS_TYPE_TXT
)
724 LIST_FOREACH(items
, i
, rr
->txt
.items
) {
729 r
= sd_bus_message_append_array(reply
, 'y', i
->data
, i
->length
);
737 static void resolve_service_all_complete(DnsQuery
*q
) {
738 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*canonical
= NULL
;
739 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
740 _cleanup_free_
char *name
= NULL
, *type
= NULL
, *domain
= NULL
;
742 unsigned added
= false;
747 if (q
->block_all_complete
> 0)
750 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
751 DnsQuery
*bad
= NULL
;
752 bool have_success
= false;
754 LIST_FOREACH(auxiliary_queries
, aux
, q
->auxiliary_queries
) {
756 switch (aux
->state
) {
758 case DNS_TRANSACTION_PENDING
:
759 /* If an auxiliary query is still pending, let's wait */
762 case DNS_TRANSACTION_SUCCESS
:
763 if (aux
->auxiliary_result
== 0)
776 /* We can only return one error, hence pick the last error we encountered */
780 if (bad
->state
== DNS_TRANSACTION_SUCCESS
) {
781 assert(bad
->auxiliary_result
!= 0);
783 if (bad
->auxiliary_result
== -ELOOP
) {
784 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_CNAME_LOOP
, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_question_name(bad
->question
));
788 r
= bad
->auxiliary_result
;
792 r
= reply_query_state(bad
);
797 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
801 r
= sd_bus_message_open_container(reply
, 'a', "(qqqsa(iiay)s)");
806 DnsResourceRecord
*rr
;
808 DNS_ANSWER_FOREACH(rr
, q
->answer
) {
809 r
= dns_question_matches_rr(q
->question
, rr
);
815 r
= append_srv(q
, reply
, rr
);
818 if (r
== 0) /* not an SRV record */
822 canonical
= dns_resource_record_ref(rr
);
829 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_SUCH_RR
, "'%s' does not have any RR of the requested type", dns_question_name(q
->question
));
833 r
= sd_bus_message_close_container(reply
);
837 r
= sd_bus_message_open_container(reply
, 'a', "ay");
842 DnsResourceRecord
*rr
;
844 DNS_ANSWER_FOREACH(rr
, q
->answer
) {
845 r
= dns_question_matches_rr(q
->question
, rr
);
851 r
= append_txt(reply
, rr
);
857 r
= sd_bus_message_close_container(reply
);
862 r
= dns_service_split(DNS_RESOURCE_KEY_NAME(canonical
->key
), &name
, &type
, &domain
);
866 r
= sd_bus_message_append(
870 SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
));
874 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
878 log_error_errno(r
, "Failed to send service reply: %m");
879 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
885 static void resolve_service_hostname_complete(DnsQuery
*q
) {
889 assert(q
->auxiliary_for
);
891 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
892 resolve_service_all_complete(q
->auxiliary_for
);
896 r
= dns_query_process_cname(q
);
897 if (r
> 0) /* This was a cname, and the query was restarted. */
900 /* This auxiliary lookup is finished or failed, let's see if all are finished now. */
901 q
->auxiliary_result
= r
;
902 resolve_service_all_complete(q
->auxiliary_for
);
905 static int resolve_service_hostname(DnsQuery
*q
, DnsResourceRecord
*rr
, int ifindex
) {
906 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
913 assert(rr
->key
->type
== DNS_TYPE_SRV
);
915 /* OK, we found an SRV record for the service. Let's resolve
916 * the hostname included in it */
918 r
= dns_question_new_address(&question
, q
->request_family
, rr
->srv
.name
);
922 r
= dns_query_new(q
->manager
, &aux
, question
, ifindex
, q
->flags
);
926 aux
->request_family
= q
->request_family
;
927 aux
->complete
= resolve_service_hostname_complete
;
929 r
= dns_query_make_auxiliary(aux
, q
);
931 /* Too many auxiliary lookups? If so, don't complain,
932 * let's just not add this one, we already have more
941 /* Note that auxiliary queries do not track the original bus
942 * client, only the primary request does that. */
944 r
= dns_query_go(aux
);
955 static void bus_method_resolve_service_complete(DnsQuery
*q
) {
961 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
962 r
= reply_query_state(q
);
966 r
= dns_query_process_cname(q
);
968 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_CNAME_LOOP
, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_question_name(q
->question
));
973 if (r
> 0) /* This was a cname, and the query was restarted. */
977 DnsResourceRecord
*rr
;
980 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
981 r
= dns_question_matches_rr(q
->question
, rr
);
987 if (rr
->key
->type
!= DNS_TYPE_SRV
)
990 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
991 q
->block_all_complete
++;
992 r
= resolve_service_hostname(q
, rr
, ifindex
);
993 q
->block_all_complete
--;
1004 r
= sd_bus_reply_method_errorf(q
->request
, BUS_ERROR_NO_SUCH_RR
, "'%s' does not have any RR of the requested type", dns_question_name(q
->question
));
1008 /* Maybe we are already finished? check now... */
1009 resolve_service_all_complete(q
);
1014 log_error_errno(r
, "Failed to send service reply: %m");
1015 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
1021 static int bus_method_resolve_service(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1022 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
1023 const char *name
, *type
, *domain
, *joined
;
1024 _cleanup_free_
char *n
= NULL
;
1025 Manager
*m
= userdata
;
1026 int family
, ifindex
;
1034 assert_cc(sizeof(int) == sizeof(int32_t));
1036 r
= sd_bus_message_read(message
, "isssit", &ifindex
, &name
, &type
, &domain
, &family
, &flags
);
1040 if (!IN_SET(family
, AF_INET
, AF_INET6
, AF_UNSPEC
))
1041 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown address family %i", family
);
1046 if (!dns_service_name_is_valid(name
))
1047 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid service name '%s'", name
);
1053 r
= dns_srv_type_verify(type
);
1057 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid SRV service type '%s'", type
);
1060 r
= dns_name_is_valid(domain
);
1064 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid domain '%s'", domain
);
1067 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Service name cannot be specified without service type.");
1069 r
= check_ifindex_flags(ifindex
, &flags
, SD_RESOLVED_NO_TXT
|SD_RESOLVED_NO_ADDRESS
, error
);
1074 /* If the type is specified, we generate the full domain name to look up ourselves */
1075 r
= dns_service_join(name
, type
, domain
, &n
);
1081 /* If no type is specified, we assume the domain
1082 * contains the full domain name to lookup already */
1085 r
= dns_question_new_service(&question
, joined
, !(flags
& SD_RESOLVED_NO_TXT
));
1089 r
= dns_query_new(m
, &q
, question
, ifindex
, flags
);
1093 q
->request
= sd_bus_message_ref(message
);
1094 q
->request_family
= family
;
1095 q
->complete
= bus_method_resolve_service_complete
;
1097 r
= dns_query_bus_track(q
, message
);
1101 r
= dns_query_go(q
);
1112 static const sd_bus_vtable resolve_vtable
[] = {
1113 SD_BUS_VTABLE_START(0),
1114 SD_BUS_METHOD("ResolveHostname", "isit", "a(iiay)st", bus_method_resolve_hostname
, SD_BUS_VTABLE_UNPRIVILEGED
),
1115 SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address
, SD_BUS_VTABLE_UNPRIVILEGED
),
1116 SD_BUS_METHOD("ResolveRecord", "isqqt", "a(iqqay)t", bus_method_resolve_record
, SD_BUS_VTABLE_UNPRIVILEGED
),
1117 SD_BUS_METHOD("ResolveService", "isssit", "a(qqqsa(iiay)s)aayssst", bus_method_resolve_service
, SD_BUS_VTABLE_UNPRIVILEGED
),
1121 static int on_bus_retry(sd_event_source
*s
, usec_t usec
, void *userdata
) {
1122 Manager
*m
= userdata
;
1127 m
->bus_retry_event_source
= sd_event_source_unref(m
->bus_retry_event_source
);
1129 manager_connect_bus(m
);
1133 static int match_prepare_for_sleep(sd_bus_message
*message
, void *userdata
, sd_bus_error
*ret_error
) {
1134 Manager
*m
= userdata
;
1140 r
= sd_bus_message_read(message
, "b", &b
);
1142 log_debug_errno(r
, "Failed to parse PrepareForSleep signal: %m");
1149 log_debug("Coming back from suspend, verifying all RRs...");
1151 manager_verify_all(m
);
1155 int manager_connect_bus(Manager
*m
) {
1163 r
= sd_bus_default_system(&m
->bus
);
1165 /* We failed to connect? Yuck, we must be in early
1166 * boot. Let's try in 5s again. As soon as we have
1167 * kdbus we can stop doing this... */
1169 log_debug_errno(r
, "Failed to connect to bus, trying again in 5s: %m");
1171 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
);
1173 return log_error_errno(r
, "Failed to install bus reconnect time event: %m");
1178 r
= sd_bus_add_object_vtable(m
->bus
, NULL
, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable
, m
);
1180 return log_error_errno(r
, "Failed to register object: %m");
1182 r
= sd_bus_request_name(m
->bus
, "org.freedesktop.resolve1", 0);
1184 return log_error_errno(r
, "Failed to register name: %m");
1186 r
= sd_bus_attach_event(m
->bus
, m
->event
, 0);
1188 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
1190 r
= sd_bus_add_match(m
->bus
, &m
->prepare_for_sleep_slot
,
1192 "sender='org.freedesktop.login1',"
1193 "interface='org.freedesktop.login1.Manager',"
1194 "member='PrepareForSleep',"
1195 "path='/org/freedesktop/login1'",
1196 match_prepare_for_sleep
,
1199 log_error_errno(r
, "Failed to add match for PrepareForSleep: %m");