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 /* We don't process CNAME for PTR lookups. */
303 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
307 r
= sd_bus_message_open_container(reply
, 'a', "(is)");
312 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
313 r
= dns_question_matches_rr(q
->question
, rr
);
319 r
= sd_bus_message_append(reply
, "(is)", ifindex
, rr
->ptr
.name
);
328 _cleanup_free_
char *ip
= NULL
;
330 in_addr_to_string(q
->request_family
, &q
->request_address
, &ip
);
331 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
));
335 r
= sd_bus_message_close_container(reply
);
339 r
= sd_bus_message_append(reply
, "t", SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
));
343 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
347 log_error_errno(r
, "Failed to send address reply: %m");
348 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
354 static int bus_method_resolve_address(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
355 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
356 Manager
*m
= userdata
;
367 assert_cc(sizeof(int) == sizeof(int32_t));
369 r
= sd_bus_message_read(message
, "ii", &ifindex
, &family
);
373 if (!IN_SET(family
, AF_INET
, AF_INET6
))
374 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown address family %i", family
);
376 r
= sd_bus_message_read_array(message
, 'y', &d
, &sz
);
380 if (sz
!= FAMILY_ADDRESS_SIZE(family
))
381 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid address size");
383 r
= sd_bus_message_read(message
, "t", &flags
);
387 r
= check_ifindex_flags(ifindex
, &flags
, 0, error
);
391 r
= dns_question_new_reverse(&question
, family
, d
);
395 r
= dns_query_new(m
, &q
, question
, ifindex
, flags
);
399 q
->request
= sd_bus_message_ref(message
);
400 q
->request_family
= family
;
401 memcpy(&q
->request_address
, d
, sz
);
402 q
->complete
= bus_method_resolve_address_complete
;
404 r
= dns_query_bus_track(q
, message
);
419 static int bus_message_append_rr(sd_bus_message
*m
, DnsResourceRecord
*rr
, int ifindex
) {
420 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
427 r
= sd_bus_message_open_container(m
, 'r', "iqqay");
431 r
= sd_bus_message_append(m
, "iqq",
438 r
= dns_packet_new(&p
, DNS_PROTOCOL_DNS
, 0);
442 p
->refuse_compression
= true;
444 r
= dns_packet_append_rr(p
, rr
, &start
);
448 r
= sd_bus_message_append_array(m
, 'y', DNS_PACKET_DATA(p
) + start
, p
->size
- start
);
452 return sd_bus_message_close_container(m
);
455 static void bus_method_resolve_record_complete(DnsQuery
*q
) {
456 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
462 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
463 r
= reply_query_state(q
);
467 r
= dns_query_process_cname(q
);
469 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
));
474 if (r
> 0) /* Following a CNAME */
477 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
481 r
= sd_bus_message_open_container(reply
, 'a', "(iqqay)");
486 DnsResourceRecord
*rr
;
489 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
490 r
= dns_question_matches_rr(q
->question
, rr
);
496 r
= bus_message_append_rr(reply
, rr
, ifindex
);
505 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
));
509 r
= sd_bus_message_close_container(reply
);
513 r
= sd_bus_message_append(reply
, "t", SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
));
517 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
521 log_error_errno(r
, "Failed to send record reply: %m");
522 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
528 static int bus_method_resolve_record(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
529 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
530 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
531 Manager
*m
= userdata
;
532 uint16_t class, type
;
541 assert_cc(sizeof(int) == sizeof(int32_t));
543 r
= sd_bus_message_read(message
, "isqqt", &ifindex
, &name
, &class, &type
, &flags
);
547 r
= dns_name_is_valid(name
);
551 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid name '%s'", name
);
553 r
= check_ifindex_flags(ifindex
, &flags
, 0, error
);
557 question
= dns_question_new(1);
561 key
= dns_resource_key_new(class, type
, name
);
565 r
= dns_question_add(question
, key
);
569 r
= dns_query_new(m
, &q
, question
, ifindex
, flags
);
573 q
->request
= sd_bus_message_ref(message
);
574 q
->complete
= bus_method_resolve_record_complete
;
576 r
= dns_query_bus_track(q
, message
);
591 static int append_srv(DnsQuery
*q
, sd_bus_message
*reply
, DnsResourceRecord
*rr
) {
592 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*canonical
= NULL
;
601 if (rr
->key
->type
!= DNS_TYPE_SRV
)
604 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
605 /* First, let's see if we could find an appropriate A or AAAA
606 * record for the SRV record */
607 LIST_FOREACH(auxiliary_queries
, aux
, q
->auxiliary_queries
) {
608 DnsResourceRecord
*zz
;
610 if (aux
->state
!= DNS_TRANSACTION_SUCCESS
)
612 if (aux
->auxiliary_result
!= 0)
615 r
= dns_name_equal(dns_question_name(aux
->question
), rr
->srv
.name
);
621 DNS_ANSWER_FOREACH(zz
, aux
->answer
) {
623 r
= dns_question_matches_rr(aux
->question
, zz
);
629 canonical
= dns_resource_record_ref(zz
);
637 /* Is there are successful A/AAAA lookup for this SRV RR? If not, don't add it */
642 r
= sd_bus_message_open_container(reply
, 'r', "qqqsa(iiay)s");
646 r
= sd_bus_message_append(
649 rr
->srv
.priority
, rr
->srv
.weight
, rr
->srv
.port
, rr
->srv
.name
);
653 r
= sd_bus_message_open_container(reply
, 'a', "(iiay)");
657 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
658 LIST_FOREACH(auxiliary_queries
, aux
, q
->auxiliary_queries
) {
659 DnsResourceRecord
*zz
;
662 if (aux
->state
!= DNS_TRANSACTION_SUCCESS
)
664 if (aux
->auxiliary_result
!= 0)
667 r
= dns_name_equal(dns_question_name(aux
->question
), rr
->srv
.name
);
673 DNS_ANSWER_FOREACH_IFINDEX(zz
, ifindex
, aux
->answer
) {
675 r
= dns_question_matches_rr(aux
->question
, zz
);
681 r
= append_address(reply
, zz
, ifindex
);
688 r
= sd_bus_message_close_container(reply
);
692 /* Note that above we appended the hostname as encoded in the
693 * SRV, and here the canonical hostname this maps to. */
694 r
= sd_bus_message_append(reply
, "s", canonical
? DNS_RESOURCE_KEY_NAME(canonical
->key
) : rr
->srv
.name
);
698 r
= sd_bus_message_close_container(reply
);
705 static int append_txt(sd_bus_message
*reply
, DnsResourceRecord
*rr
) {
713 if (rr
->key
->type
!= DNS_TYPE_TXT
)
716 LIST_FOREACH(items
, i
, rr
->txt
.items
) {
721 r
= sd_bus_message_append_array(reply
, 'y', i
->data
, i
->length
);
729 static void resolve_service_all_complete(DnsQuery
*q
) {
730 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*canonical
= NULL
;
731 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
732 _cleanup_free_
char *name
= NULL
, *type
= NULL
, *domain
= NULL
;
734 unsigned added
= false;
739 if (q
->block_all_complete
> 0)
742 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
743 DnsQuery
*bad
= NULL
;
744 bool have_success
= false;
746 LIST_FOREACH(auxiliary_queries
, aux
, q
->auxiliary_queries
) {
748 switch (aux
->state
) {
750 case DNS_TRANSACTION_PENDING
:
751 /* If an auxiliary query is still pending, let's wait */
754 case DNS_TRANSACTION_SUCCESS
:
755 if (aux
->auxiliary_result
== 0)
768 /* We can only return one error, hence pick the last error we encountered */
772 if (bad
->state
== DNS_TRANSACTION_SUCCESS
) {
773 assert(bad
->auxiliary_result
!= 0);
775 if (bad
->auxiliary_result
== -ELOOP
) {
776 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
));
780 r
= bad
->auxiliary_result
;
784 r
= reply_query_state(bad
);
789 r
= sd_bus_message_new_method_return(q
->request
, &reply
);
793 r
= sd_bus_message_open_container(reply
, 'a', "(qqqsa(iiay)s)");
798 DnsResourceRecord
*rr
;
800 DNS_ANSWER_FOREACH(rr
, q
->answer
) {
801 r
= dns_question_matches_rr(q
->question
, rr
);
807 r
= append_srv(q
, reply
, rr
);
810 if (r
== 0) /* not an SRV record */
814 canonical
= dns_resource_record_ref(rr
);
821 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
));
825 r
= sd_bus_message_close_container(reply
);
829 r
= sd_bus_message_open_container(reply
, 'a', "ay");
834 DnsResourceRecord
*rr
;
836 DNS_ANSWER_FOREACH(rr
, q
->answer
) {
837 r
= dns_question_matches_rr(q
->question
, rr
);
843 r
= append_txt(reply
, rr
);
849 r
= sd_bus_message_close_container(reply
);
854 r
= dns_service_split(DNS_RESOURCE_KEY_NAME(canonical
->key
), &name
, &type
, &domain
);
858 r
= sd_bus_message_append(
862 SD_RESOLVED_FLAGS_MAKE(q
->answer_protocol
, q
->answer_family
));
866 r
= sd_bus_send(q
->manager
->bus
, reply
, NULL
);
870 log_error_errno(r
, "Failed to send service reply: %m");
871 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
877 static void resolve_service_hostname_complete(DnsQuery
*q
) {
881 assert(q
->auxiliary_for
);
883 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
884 resolve_service_all_complete(q
->auxiliary_for
);
888 r
= dns_query_process_cname(q
);
889 if (r
> 0) /* This was a cname, and the query was restarted. */
892 /* This auxiliary lookup is finished or failed, let's see if all are finished now. */
893 q
->auxiliary_result
= r
;
894 resolve_service_all_complete(q
->auxiliary_for
);
897 static int resolve_service_hostname(DnsQuery
*q
, DnsResourceRecord
*rr
, int ifindex
) {
898 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
905 assert(rr
->key
->type
== DNS_TYPE_SRV
);
907 /* OK, we found an SRV record for the service. Let's resolve
908 * the hostname included in it */
910 r
= dns_question_new_address(&question
, q
->request_family
, rr
->srv
.name
);
914 r
= dns_query_new(q
->manager
, &aux
, question
, ifindex
, q
->flags
);
918 aux
->request_family
= q
->request_family
;
919 aux
->complete
= resolve_service_hostname_complete
;
921 r
= dns_query_make_auxiliary(aux
, q
);
923 /* Too many auxiliary lookups? If so, don't complain,
924 * let's just not add this one, we already have more
933 /* Note that auxiliary queries do not track the original bus
934 * client, only the primary request does that. */
936 r
= dns_query_go(aux
);
947 static void bus_method_resolve_service_complete(DnsQuery
*q
) {
953 if (q
->state
!= DNS_TRANSACTION_SUCCESS
) {
954 r
= reply_query_state(q
);
958 r
= dns_query_process_cname(q
);
960 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
));
965 if (r
> 0) /* This was a cname, and the query was restarted. */
969 DnsResourceRecord
*rr
;
972 DNS_ANSWER_FOREACH_IFINDEX(rr
, ifindex
, q
->answer
) {
973 r
= dns_question_matches_rr(q
->question
, rr
);
979 if (rr
->key
->type
!= DNS_TYPE_SRV
)
982 if ((q
->flags
& SD_RESOLVED_NO_ADDRESS
) == 0) {
983 q
->block_all_complete
++;
984 r
= resolve_service_hostname(q
, rr
, ifindex
);
985 q
->block_all_complete
--;
996 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
));
1000 /* Maybe we are already finished? check now... */
1001 resolve_service_all_complete(q
);
1006 log_error_errno(r
, "Failed to send service reply: %m");
1007 sd_bus_reply_method_errno(q
->request
, r
, NULL
);
1013 static int bus_method_resolve_service(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1014 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
1015 const char *name
, *type
, *domain
, *joined
;
1016 _cleanup_free_
char *n
= NULL
;
1017 Manager
*m
= userdata
;
1018 int family
, ifindex
;
1026 assert_cc(sizeof(int) == sizeof(int32_t));
1028 r
= sd_bus_message_read(message
, "isssit", &ifindex
, &name
, &type
, &domain
, &family
, &flags
);
1032 if (!IN_SET(family
, AF_INET
, AF_INET6
, AF_UNSPEC
))
1033 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown address family %i", family
);
1038 if (!dns_service_name_is_valid(name
))
1039 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid service name '%s'", name
);
1045 r
= dns_srv_type_verify(type
);
1049 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid SRV service type '%s'", type
);
1052 r
= dns_name_is_valid(domain
);
1056 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid domain '%s'", domain
);
1059 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Service name cannot be specified without service type.");
1061 r
= check_ifindex_flags(ifindex
, &flags
, SD_RESOLVED_NO_TXT
|SD_RESOLVED_NO_ADDRESS
, error
);
1066 /* If the type is specified, we generate the full domain name to look up ourselves */
1067 r
= dns_service_join(name
, type
, domain
, &n
);
1073 /* If no type is specified, we assume the domain
1074 * contains the full domain name to lookup already */
1077 r
= dns_question_new_service(&question
, joined
, !(flags
& SD_RESOLVED_NO_TXT
));
1081 r
= dns_query_new(m
, &q
, question
, ifindex
, flags
);
1085 q
->request
= sd_bus_message_ref(message
);
1086 q
->request_family
= family
;
1087 q
->complete
= bus_method_resolve_service_complete
;
1089 r
= dns_query_bus_track(q
, message
);
1093 r
= dns_query_go(q
);
1104 static const sd_bus_vtable resolve_vtable
[] = {
1105 SD_BUS_VTABLE_START(0),
1106 SD_BUS_METHOD("ResolveHostname", "isit", "a(iiay)st", bus_method_resolve_hostname
, SD_BUS_VTABLE_UNPRIVILEGED
),
1107 SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address
, SD_BUS_VTABLE_UNPRIVILEGED
),
1108 SD_BUS_METHOD("ResolveRecord", "isqqt", "a(iqqay)t", bus_method_resolve_record
, SD_BUS_VTABLE_UNPRIVILEGED
),
1109 SD_BUS_METHOD("ResolveService", "isssit", "a(qqqsa(iiay)s)aayssst", bus_method_resolve_service
, SD_BUS_VTABLE_UNPRIVILEGED
),
1113 static int on_bus_retry(sd_event_source
*s
, usec_t usec
, void *userdata
) {
1114 Manager
*m
= userdata
;
1119 m
->bus_retry_event_source
= sd_event_source_unref(m
->bus_retry_event_source
);
1121 manager_connect_bus(m
);
1125 static int match_prepare_for_sleep(sd_bus_message
*message
, void *userdata
, sd_bus_error
*ret_error
) {
1126 Manager
*m
= userdata
;
1132 r
= sd_bus_message_read(message
, "b", &b
);
1134 log_debug_errno(r
, "Failed to parse PrepareForSleep signal: %m");
1141 log_debug("Coming back from suspend, verifying all RRs...");
1143 manager_verify_all(m
);
1147 int manager_connect_bus(Manager
*m
) {
1155 r
= sd_bus_default_system(&m
->bus
);
1157 /* We failed to connect? Yuck, we must be in early
1158 * boot. Let's try in 5s again. As soon as we have
1159 * kdbus we can stop doing this... */
1161 log_debug_errno(r
, "Failed to connect to bus, trying again in 5s: %m");
1163 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
);
1165 return log_error_errno(r
, "Failed to install bus reconnect time event: %m");
1170 r
= sd_bus_add_object_vtable(m
->bus
, NULL
, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable
, m
);
1172 return log_error_errno(r
, "Failed to register object: %m");
1174 r
= sd_bus_request_name(m
->bus
, "org.freedesktop.resolve1", 0);
1176 return log_error_errno(r
, "Failed to register name: %m");
1178 r
= sd_bus_attach_event(m
->bus
, m
->event
, 0);
1180 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
1182 r
= sd_bus_add_match(m
->bus
, &m
->prepare_for_sleep_slot
,
1184 "sender='org.freedesktop.login1',"
1185 "interface='org.freedesktop.login1.Manager',"
1186 "member='PrepareForSleep',"
1187 "path='/org/freedesktop/login1'",
1188 match_prepare_for_sleep
,
1191 log_error_errno(r
, "Failed to add match for PrepareForSleep: %m");