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 "dns-domain.h"
24 #include "hostname-util.h"
25 #include "local-addresses.h"
26 #include "resolved-dns-query.h"
28 /* How long to wait for the query in total */
29 #define QUERY_TIMEOUT_USEC (30 * USEC_PER_SEC)
32 #define QUERIES_MAX 2048
34 static void dns_query_stop(DnsQuery
*q
) {
39 q
->timeout_event_source
= sd_event_source_unref(q
->timeout_event_source
);
41 while ((t
= set_steal_first(q
->transactions
))) {
42 set_remove(t
->queries
, q
);
43 dns_transaction_gc(t
);
47 DnsQuery
*dns_query_free(DnsQuery
*q
) {
52 set_free(q
->transactions
);
54 dns_question_unref(q
->question
);
55 dns_answer_unref(q
->answer
);
57 sd_bus_message_unref(q
->request
);
58 sd_bus_track_unref(q
->bus_track
);
61 LIST_REMOVE(queries
, q
->manager
->dns_queries
, q
);
62 q
->manager
->n_dns_queries
--;
70 int dns_query_new(Manager
*m
, DnsQuery
**ret
, DnsQuestion
*question
, int ifindex
, uint64_t flags
) {
71 _cleanup_(dns_query_freep
) DnsQuery
*q
= NULL
;
78 r
= dns_question_is_valid(question
);
82 if (m
->n_dns_queries
>= QUERIES_MAX
)
85 q
= new0(DnsQuery
, 1);
89 q
->question
= dns_question_ref(question
);
93 for (i
= 0; i
< question
->n_keys
; i
++) {
94 _cleanup_free_
char *p
;
96 r
= dns_resource_key_to_string(question
->keys
[i
], &p
);
100 log_debug("Looking up RR for %s", p
);
103 LIST_PREPEND(queries
, m
->dns_queries
, q
);
114 static void dns_query_complete(DnsQuery
*q
, DnsTransactionState state
) {
116 assert(!IN_SET(state
, DNS_TRANSACTION_NULL
, DNS_TRANSACTION_PENDING
));
117 assert(IN_SET(q
->state
, DNS_TRANSACTION_NULL
, DNS_TRANSACTION_PENDING
));
119 /* Note that this call might invalidate the query. Callers
120 * should hence not attempt to access the query or transaction
121 * after calling this function. */
130 static int on_query_timeout(sd_event_source
*s
, usec_t usec
, void *userdata
) {
131 DnsQuery
*q
= userdata
;
136 dns_query_complete(q
, DNS_TRANSACTION_TIMEOUT
);
140 static int dns_query_add_transaction(DnsQuery
*q
, DnsScope
*s
, DnsResourceKey
*key
) {
148 r
= set_ensure_allocated(&q
->transactions
, NULL
);
152 t
= dns_scope_find_transaction(s
, key
, true);
154 r
= dns_transaction_new(&t
, s
, key
);
159 r
= set_ensure_allocated(&t
->queries
, NULL
);
163 r
= set_put(t
->queries
, q
);
167 r
= set_put(q
->transactions
, t
);
169 set_remove(t
->queries
, q
);
176 dns_transaction_gc(t
);
180 static int dns_query_add_transaction_split(DnsQuery
*q
, DnsScope
*s
) {
187 /* Create one transaction per question key */
189 for (i
= 0; i
< q
->question
->n_keys
; i
++) {
190 r
= dns_query_add_transaction(q
, s
, q
->question
->keys
[i
]);
198 static int SYNTHESIZE_IFINDEX(int ifindex
) {
200 /* When the caller asked for resolving on a specific
201 * interface, we synthesize the answer for that
202 * interface. However, if nothing specific was claimed and we
203 * only return localhost RRs, we synthesize the answer for
209 return LOOPBACK_IFINDEX
;
212 static int SYNTHESIZE_FAMILY(uint64_t flags
) {
214 /* Picks an address family depending on set flags. This is
215 * purely for synthesized answers, where the family we return
216 * for the reply should match what was requested in the
217 * question, even though we are synthesizing the answer
220 if (!(flags
& SD_RESOLVED_DNS
)) {
221 if (flags
& SD_RESOLVED_LLMNR_IPV4
)
223 if (flags
& SD_RESOLVED_LLMNR_IPV6
)
230 static DnsProtocol
SYNTHESIZE_PROTOCOL(uint64_t flags
) {
232 /* Similar as SYNTHESIZE_FAMILY() but does this for the
233 * protocol. If resolving via DNS was requested, we claim it
234 * was DNS. Similar, if nothing specific was
235 * requested. However, if only resolving via LLMNR was
236 * requested we return that. */
238 if (flags
& SD_RESOLVED_DNS
)
239 return DNS_PROTOCOL_DNS
;
240 if (flags
& SD_RESOLVED_LLMNR
)
241 return DNS_PROTOCOL_LLMNR
;
243 return DNS_PROTOCOL_DNS
;
246 static int dns_type_to_af(uint16_t t
) {
263 static int synthesize_localhost_rr(DnsQuery
*q
, DnsResourceKey
*key
, DnsAnswer
**answer
) {
270 r
= dns_answer_reserve(answer
, 2);
274 if (IN_SET(key
->type
, DNS_TYPE_A
, DNS_TYPE_ANY
)) {
275 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
277 rr
= dns_resource_record_new_full(DNS_CLASS_IN
, DNS_TYPE_A
, DNS_RESOURCE_KEY_NAME(key
));
281 rr
->a
.in_addr
.s_addr
= htobe32(INADDR_LOOPBACK
);
283 r
= dns_answer_add(*answer
, rr
, SYNTHESIZE_IFINDEX(q
->ifindex
));
288 if (IN_SET(key
->type
, DNS_TYPE_AAAA
, DNS_TYPE_ANY
)) {
289 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
291 rr
= dns_resource_record_new_full(DNS_CLASS_IN
, DNS_TYPE_AAAA
, DNS_RESOURCE_KEY_NAME(key
));
295 rr
->aaaa
.in6_addr
= in6addr_loopback
;
297 r
= dns_answer_add(*answer
, rr
, SYNTHESIZE_IFINDEX(q
->ifindex
));
305 static int answer_add_ptr(DnsAnswer
**answer
, const char *from
, const char *to
, int ifindex
) {
306 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
308 rr
= dns_resource_record_new_full(DNS_CLASS_IN
, DNS_TYPE_PTR
, from
);
312 rr
->ptr
.name
= strdup(to
);
316 return dns_answer_add(*answer
, rr
, ifindex
);
319 static int synthesize_localhost_ptr(DnsQuery
*q
, DnsResourceKey
*key
, DnsAnswer
**answer
) {
326 r
= dns_answer_reserve(answer
, 1);
330 if (IN_SET(key
->type
, DNS_TYPE_PTR
, DNS_TYPE_ANY
)) {
331 r
= answer_add_ptr(answer
, DNS_RESOURCE_KEY_NAME(key
), "localhost", SYNTHESIZE_IFINDEX(q
->ifindex
));
339 static int answer_add_addresses_rr(
342 struct local_address
*addresses
,
343 unsigned n_addresses
) {
351 r
= dns_answer_reserve(answer
, n_addresses
);
355 for (j
= 0; j
< n_addresses
; j
++) {
356 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
358 r
= dns_resource_record_new_address(&rr
, addresses
[j
].family
, &addresses
[j
].address
, name
);
362 r
= dns_answer_add(*answer
, rr
, addresses
[j
].ifindex
);
370 static int answer_add_addresses_ptr(
373 struct local_address
*addresses
,
374 unsigned n_addresses
,
375 int af
, const union in_addr_union
*match
) {
383 for (j
= 0; j
< n_addresses
; j
++) {
384 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
386 if (af
!= AF_UNSPEC
) {
388 if (addresses
[j
].family
!= af
)
391 if (match
&& !in_addr_equal(af
, match
, &addresses
[j
].address
))
395 r
= dns_answer_reserve(answer
, 1);
399 r
= dns_resource_record_new_reverse(&rr
, addresses
[j
].family
, &addresses
[j
].address
, name
);
403 r
= dns_answer_add(*answer
, rr
, addresses
[j
].ifindex
);
411 static int synthesize_system_hostname_rr(DnsQuery
*q
, DnsResourceKey
*key
, DnsAnswer
**answer
) {
412 _cleanup_free_
struct local_address
*addresses
= NULL
;
419 af
= dns_type_to_af(key
->type
);
421 n
= local_addresses(q
->manager
->rtnl
, q
->ifindex
, af
, &addresses
);
426 struct local_address buffer
[2];
428 /* If we have no local addresses then use ::1
429 * and 127.0.0.2 as local ones. */
431 if (af
== AF_INET
|| af
== AF_UNSPEC
)
432 buffer
[n
++] = (struct local_address
) {
434 .ifindex
= SYNTHESIZE_IFINDEX(q
->ifindex
),
435 .address
.in
.s_addr
= htobe32(0x7F000002),
438 if (af
== AF_INET6
|| af
== AF_UNSPEC
)
439 buffer
[n
++] = (struct local_address
) {
441 .ifindex
= SYNTHESIZE_IFINDEX(q
->ifindex
),
442 .address
.in6
= in6addr_loopback
,
445 return answer_add_addresses_rr(answer
, DNS_RESOURCE_KEY_NAME(key
), buffer
, n
);
449 return answer_add_addresses_rr(answer
, DNS_RESOURCE_KEY_NAME(key
), addresses
, n
);
452 static int synthesize_system_hostname_ptr(DnsQuery
*q
, int af
, const union in_addr_union
*address
, DnsAnswer
**answer
) {
453 _cleanup_free_
struct local_address
*addresses
= NULL
;
460 if (af
== AF_INET
&& address
->in
.s_addr
== htobe32(0x7F000002)) {
462 /* Always map the IPv4 address 127.0.0.2 to the local
463 * hostname, in addition to "localhost": */
465 r
= dns_answer_reserve(answer
, 3);
469 r
= answer_add_ptr(answer
, "2.0.0.127.in-addr.arpa", q
->manager
->llmnr_hostname
, SYNTHESIZE_IFINDEX(q
->ifindex
));
473 r
= answer_add_ptr(answer
, "2.0.0.127.in-addr.arpa", q
->manager
->mdns_hostname
, SYNTHESIZE_IFINDEX(q
->ifindex
));
477 r
= answer_add_ptr(answer
, "2.0.0.127.in-addr.arpa", "localhost", SYNTHESIZE_IFINDEX(q
->ifindex
));
484 n
= local_addresses(q
->manager
->rtnl
, q
->ifindex
, af
, &addresses
);
488 r
= answer_add_addresses_ptr(answer
, q
->manager
->llmnr_hostname
, addresses
, n
, af
, address
);
492 return answer_add_addresses_ptr(answer
, q
->manager
->mdns_hostname
, addresses
, n
, af
, address
);
495 static int synthesize_gateway_rr(DnsQuery
*q
, DnsResourceKey
*key
, DnsAnswer
**answer
) {
496 _cleanup_free_
struct local_address
*addresses
= NULL
;
503 af
= dns_type_to_af(key
->type
);
505 n
= local_gateways(q
->manager
->rtnl
, q
->ifindex
, af
, &addresses
);
510 return answer_add_addresses_rr(answer
, DNS_RESOURCE_KEY_NAME(key
), addresses
, n
);
513 static int synthesize_gateway_ptr(DnsQuery
*q
, int af
, const union in_addr_union
*address
, DnsAnswer
**answer
) {
514 _cleanup_free_
struct local_address
*addresses
= NULL
;
521 n
= local_gateways(q
->manager
->rtnl
, q
->ifindex
, af
, &addresses
);
525 return answer_add_addresses_ptr(answer
, "gateway", addresses
, n
, af
, address
);
528 static int dns_query_synthesize_reply(DnsQuery
*q
, DnsTransactionState
*state
) {
529 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
536 /* Tries to synthesize localhost RR replies where appropriate */
539 DNS_TRANSACTION_FAILURE
,
540 DNS_TRANSACTION_NO_SERVERS
,
541 DNS_TRANSACTION_TIMEOUT
,
542 DNS_TRANSACTION_ATTEMPTS_MAX_REACHED
))
545 for (i
= 0; i
< q
->question
->n_keys
; i
++) {
546 union in_addr_union address
;
550 if (q
->question
->keys
[i
]->class != DNS_CLASS_IN
&&
551 q
->question
->keys
[i
]->class != DNS_CLASS_ANY
)
554 name
= DNS_RESOURCE_KEY_NAME(q
->question
->keys
[i
]);
556 if (is_localhost(name
)) {
558 r
= synthesize_localhost_rr(q
, q
->question
->keys
[i
], &answer
);
560 return log_error_errno(r
, "Failed to synthesize localhost RRs: %m");
562 } else if (manager_is_own_hostname(q
->manager
, name
)) {
564 r
= synthesize_system_hostname_rr(q
, q
->question
->keys
[i
], &answer
);
566 return log_error_errno(r
, "Failed to synthesize system hostname RRs: %m");
568 } else if (is_gateway_hostname(name
)) {
570 r
= synthesize_gateway_rr(q
, q
->question
->keys
[i
], &answer
);
572 return log_error_errno(r
, "Failed to synthesize gateway RRs: %m");
574 } else if ((dns_name_endswith(name
, "127.in-addr.arpa") > 0 && dns_name_equal(name
, "2.0.0.127.in-addr.arpa") == 0) ||
575 dns_name_equal(name
, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa") > 0) {
577 r
= synthesize_localhost_ptr(q
, q
->question
->keys
[i
], &answer
);
579 return log_error_errno(r
, "Failed to synthesize localhost PTR RRs: %m");
581 } else if (dns_name_address(name
, &af
, &address
) > 0) {
583 r
= synthesize_system_hostname_ptr(q
, af
, &address
, &answer
);
585 return log_error_errno(r
, "Failed to synthesize system hostname PTR RR: %m");
587 r
= synthesize_gateway_ptr(q
, af
, &address
, &answer
);
589 return log_error_errno(r
, "Failed to synthesize gateway hostname PTR RR: %m");
596 dns_answer_unref(q
->answer
);
600 q
->answer_family
= SYNTHESIZE_FAMILY(q
->flags
);
601 q
->answer_protocol
= SYNTHESIZE_PROTOCOL(q
->flags
);
602 q
->answer_rcode
= DNS_RCODE_SUCCESS
;
604 *state
= DNS_TRANSACTION_SUCCESS
;
609 int dns_query_go(DnsQuery
*q
) {
610 DnsScopeMatch found
= DNS_SCOPE_NO
;
611 DnsScope
*s
, *first
= NULL
;
619 if (q
->state
!= DNS_TRANSACTION_NULL
)
623 assert(q
->question
->n_keys
> 0);
625 name
= DNS_RESOURCE_KEY_NAME(q
->question
->keys
[0]);
627 LIST_FOREACH(scopes
, s
, q
->manager
->dns_scopes
) {
630 match
= dns_scope_good_domain(s
, q
->ifindex
, q
->flags
, name
);
634 if (match
== DNS_SCOPE_NO
)
639 if (match
== DNS_SCOPE_YES
) {
643 assert(match
== DNS_SCOPE_MAYBE
);
650 if (found
== DNS_SCOPE_NO
) {
651 DnsTransactionState state
= DNS_TRANSACTION_NO_SERVERS
;
653 dns_query_synthesize_reply(q
, &state
);
654 dns_query_complete(q
, state
);
658 r
= dns_query_add_transaction_split(q
, first
);
662 LIST_FOREACH(scopes
, s
, first
->scopes_next
) {
665 match
= dns_scope_good_domain(s
, q
->ifindex
, q
->flags
, name
);
672 r
= dns_query_add_transaction_split(q
, s
);
677 q
->answer
= dns_answer_unref(q
->answer
);
679 q
->answer_family
= AF_UNSPEC
;
680 q
->answer_protocol
= _DNS_PROTOCOL_INVALID
;
682 r
= sd_event_add_time(
684 &q
->timeout_event_source
,
685 clock_boottime_or_monotonic(),
686 now(clock_boottime_or_monotonic()) + QUERY_TIMEOUT_USEC
, 0,
687 on_query_timeout
, q
);
691 q
->state
= DNS_TRANSACTION_PENDING
;
694 /* Start the transactions that are not started yet */
695 SET_FOREACH(t
, q
->transactions
, i
) {
696 if (t
->state
!= DNS_TRANSACTION_NULL
)
699 r
= dns_transaction_go(t
);
714 void dns_query_ready(DnsQuery
*q
) {
716 DnsTransactionState state
= DNS_TRANSACTION_NO_SERVERS
;
717 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
719 DnsScope
*scope
= NULL
;
720 bool pending
= false;
724 assert(IN_SET(q
->state
, DNS_TRANSACTION_NULL
, DNS_TRANSACTION_PENDING
));
726 /* Note that this call might invalidate the query. Callers
727 * should hence not attempt to access the query or transaction
728 * after calling this function, unless the block_ready
729 * counter was explicitly bumped before doing so. */
731 if (q
->block_ready
> 0)
734 SET_FOREACH(t
, q
->transactions
, i
) {
736 /* If we found a successful answer, ignore all answers from other scopes */
737 if (state
== DNS_TRANSACTION_SUCCESS
&& t
->scope
!= scope
)
740 /* One of the transactions is still going on, let's maybe wait for it */
741 if (IN_SET(t
->state
, DNS_TRANSACTION_PENDING
, DNS_TRANSACTION_NULL
)) {
746 /* One of the transactions is successful, let's use
747 * it, and copy its data out */
748 if (t
->state
== DNS_TRANSACTION_SUCCESS
) {
752 rcode
= DNS_PACKET_RCODE(t
->received
);
753 a
= t
->received
->answer
;
755 rcode
= t
->cached_rcode
;
759 if (state
== DNS_TRANSACTION_SUCCESS
) {
762 merged
= dns_answer_merge(answer
, a
);
764 dns_query_complete(q
, DNS_TRANSACTION_RESOURCES
);
768 dns_answer_unref(answer
);
771 dns_answer_unref(answer
);
772 answer
= dns_answer_ref(a
);
776 state
= DNS_TRANSACTION_SUCCESS
;
780 /* One of the transactions has failed, let's see
781 * whether we find anything better, but if not, return
782 * its response data */
783 if (state
!= DNS_TRANSACTION_SUCCESS
&& t
->state
== DNS_TRANSACTION_FAILURE
) {
787 rcode
= DNS_PACKET_RCODE(t
->received
);
788 a
= t
->received
->answer
;
790 rcode
= t
->cached_rcode
;
794 dns_answer_unref(answer
);
795 answer
= dns_answer_ref(a
);
798 state
= DNS_TRANSACTION_FAILURE
;
802 if (state
== DNS_TRANSACTION_NO_SERVERS
&& t
->state
!= DNS_TRANSACTION_NO_SERVERS
)
808 /* If so far we weren't successful, and there's
809 * something still pending, then wait for it */
810 if (state
!= DNS_TRANSACTION_SUCCESS
)
813 /* If we already were successful, then only wait for
814 * other transactions on the same scope to finish. */
815 SET_FOREACH(t
, q
->transactions
, i
) {
816 if (t
->scope
== scope
&& IN_SET(t
->state
, DNS_TRANSACTION_PENDING
, DNS_TRANSACTION_NULL
))
821 if (IN_SET(state
, DNS_TRANSACTION_SUCCESS
, DNS_TRANSACTION_FAILURE
)) {
822 q
->answer
= dns_answer_ref(answer
);
823 q
->answer_rcode
= rcode
;
824 q
->answer_protocol
= scope
? scope
->protocol
: _DNS_PROTOCOL_INVALID
;
825 q
->answer_family
= scope
? scope
->family
: AF_UNSPEC
;
828 /* Try to synthesize a reply if we couldn't resolve something. */
829 dns_query_synthesize_reply(q
, &state
);
831 dns_query_complete(q
, state
);
834 int dns_query_cname_redirect(DnsQuery
*q
, const DnsResourceRecord
*cname
) {
835 _cleanup_(dns_question_unrefp
) DnsQuestion
*nq
= NULL
;
840 if (q
->n_cname_redirects
> CNAME_MAX
)
843 r
= dns_question_cname_redirect(q
->question
, cname
, &nq
);
847 dns_question_unref(q
->question
);
851 q
->n_cname_redirects
++;
854 q
->state
= DNS_TRANSACTION_NULL
;
859 static int on_bus_track(sd_bus_track
*t
, void *userdata
) {
860 DnsQuery
*q
= userdata
;
865 log_debug("Client of active query vanished, aborting query.");
866 dns_query_complete(q
, DNS_TRANSACTION_ABORTED
);
870 int dns_query_bus_track(DnsQuery
*q
, sd_bus_message
*m
) {
877 r
= sd_bus_track_new(sd_bus_message_get_bus(m
), &q
->bus_track
, on_bus_track
, q
);
882 r
= sd_bus_track_add_sender(q
->bus_track
, m
);