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/>.
24 #include "resolved-dns-query.h"
25 #include "resolved-dns-domain.h"
27 #define TRANSACTION_TIMEOUT_USEC (5 * USEC_PER_SEC)
28 #define QUERY_TIMEOUT_USEC (30 * USEC_PER_SEC)
29 #define ATTEMPTS_MAX 8
31 #define QUERIES_MAX 2048
33 static int dns_query_transaction_go(DnsQueryTransaction *t);
35 DnsQueryTransaction* dns_query_transaction_free(DnsQueryTransaction *t) {
41 sd_event_source_unref(t->timeout_event_source);
43 dns_question_unref(t->question);
44 dns_packet_unref(t->sent);
45 dns_packet_unref(t->received);
46 dns_answer_unref(t->cached);
48 dns_stream_free(t->stream);
51 LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
54 hashmap_remove(t->scope->manager->dns_query_transactions, UINT_TO_PTR(t->id));
57 while ((q = set_steal_first(t->queries)))
58 set_remove(q->transactions, t);
66 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQueryTransaction*, dns_query_transaction_free);
68 static void dns_query_transaction_gc(DnsQueryTransaction *t) {
74 if (set_isempty(t->queries))
75 dns_query_transaction_free(t);
78 static int dns_query_transaction_new(DnsQueryTransaction **ret, DnsScope *s, DnsQuestion *q) {
79 _cleanup_(dns_query_transaction_freep) DnsQueryTransaction *t = NULL;
86 r = hashmap_ensure_allocated(&s->manager->dns_query_transactions, NULL, NULL);
90 t = new0(DnsQueryTransaction, 1);
94 t->question = dns_question_ref(q);
97 random_bytes(&t->id, sizeof(t->id));
99 hashmap_get(s->manager->dns_query_transactions, UINT_TO_PTR(t->id)));
101 r = hashmap_put(s->manager->dns_query_transactions, UINT_TO_PTR(t->id), t);
107 LIST_PREPEND(transactions_by_scope, s->transactions, t);
118 static void dns_query_transaction_stop(DnsQueryTransaction *t) {
121 t->timeout_event_source = sd_event_source_unref(t->timeout_event_source);
122 t->stream = dns_stream_free(t->stream);
125 void dns_query_transaction_complete(DnsQueryTransaction *t, DnsQueryState state) {
130 assert(!IN_SET(state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
131 assert(IN_SET(t->state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
133 /* Note that this call might invalidate the query. Callers
134 * should hence not attempt to access the query or transaction
135 * after calling this function. */
137 log_debug("Transaction on scope %s on %s/%s now complete with %s",
138 dns_protocol_to_string(t->scope->protocol),
139 t->scope->link ? t->scope->link->name : "*",
140 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
141 dns_query_state_to_string(state));
145 dns_query_transaction_stop(t);
147 /* Notify all queries that are interested, but make sure the
148 * transaction isn't freed while we are still looking at it */
150 SET_FOREACH(q, t->queries, i)
154 dns_query_transaction_gc(t);
157 static int on_stream_complete(DnsStream *s, int error) {
158 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
159 DnsQueryTransaction *t;
162 assert(s->transaction);
164 /* Copy the data we care about out of the stream before we
167 p = dns_packet_ref(s->read_packet);
169 t->stream = dns_stream_free(t->stream);
172 dns_query_transaction_complete(t, DNS_QUERY_RESOURCES);
177 dns_query_transaction_process_reply(t, p);
180 /* If the response wasn't useful, then complete the transition now */
181 if (t->state == DNS_QUERY_PENDING)
182 dns_query_transaction_complete(t, DNS_QUERY_INVALID_REPLY);
187 static int dns_query_transaction_open_tcp(DnsQueryTransaction *t) {
188 _cleanup_close_ int fd = -1;
196 if (t->scope->protocol == DNS_PROTOCOL_DNS)
197 fd = dns_scope_tcp_socket(t->scope, AF_UNSPEC, NULL, 53);
198 else if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
200 /* When we already received a query to this (but it was truncated), send to its sender address */
202 fd = dns_scope_tcp_socket(t->scope, t->received->family, &t->received->sender, t->received->sender_port);
204 union in_addr_union address;
207 /* Otherwise, try to talk to the owner of a
208 * the IP address, in case this is a reverse
210 r = dns_question_extract_reverse_address(t->question, &family, &address);
216 fd = dns_scope_tcp_socket(t->scope, family, &address, 5355);
219 return -EAFNOSUPPORT;
224 r = dns_stream_new(t->scope->manager, &t->stream, t->scope->protocol, fd);
230 r = dns_stream_write_packet(t->stream, t->sent);
232 t->stream = dns_stream_free(t->stream);
236 t->received = dns_packet_unref(t->received);
237 t->stream->complete = on_stream_complete;
238 t->stream->transaction = t;
240 /* The interface index is difficult to determine if we are
241 * connecting to the local host, hence fill this in right away
242 * instead of determining it from the socket */
244 t->stream->ifindex = t->scope->link->ifindex;
249 void dns_query_transaction_process_reply(DnsQueryTransaction *t, DnsPacket *p) {
254 assert(t->state == DNS_QUERY_PENDING);
256 /* Note that this call might invalidate the query. Callers
257 * should hence not attempt to access the query or transaction
258 * after calling this function. */
260 if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
261 assert(t->scope->link);
263 /* For LLMNR we will not accept any packets from other
266 if (p->ifindex != t->scope->link->ifindex)
269 if (p->family != t->scope->family)
272 /* Don't accept UDP packets directed to anything but
273 * the LLMNR multicast addresses. */
275 if (p->ipproto == IPPROTO_UDP) {
276 if (p->family == AF_INET && !in_addr_equal(AF_INET, &p->destination, (union in_addr_union*) &LLMNR_MULTICAST_IPV4_ADDRESS))
279 if (p->family == AF_INET6 && !in_addr_equal(AF_INET6, &p->destination, (union in_addr_union*) &LLMNR_MULTICAST_IPV6_ADDRESS))
283 /* Tentative replies shall be discarded, see RFC 4795,
290 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
292 /* For DNS we are fine with accepting packets on any
293 * interface, but the source IP address must be one of
294 * a valid DNS server */
296 if (!dns_scope_good_dns_server(t->scope, p->family, &p->sender))
299 if (p->sender_port != 53)
303 if (t->received != p) {
304 dns_packet_unref(t->received);
305 t->received = dns_packet_ref(p);
308 if (p->ipproto == IPPROTO_TCP) {
309 if (DNS_PACKET_TC(p)) {
310 /* Truncated via TCP? Somebody must be fucking with us */
311 dns_query_transaction_complete(t, DNS_QUERY_INVALID_REPLY);
315 if (DNS_PACKET_ID(p) != t->id) {
316 /* Not the reply to our query? Somebody must be fucking with us */
317 dns_query_transaction_complete(t, DNS_QUERY_INVALID_REPLY);
322 if (DNS_PACKET_TC(p)) {
323 /* Response was truncated, let's try again with good old TCP */
324 r = dns_query_transaction_open_tcp(t);
326 /* No servers found? Damn! */
327 dns_query_transaction_complete(t, DNS_QUERY_NO_SERVERS);
331 /* On LLMNR, if we cannot connect to the host,
332 * we immediately give up */
333 if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
334 dns_query_transaction_complete(t, DNS_QUERY_RESOURCES);
338 /* On DNS, couldn't send? Try immediately again, with a new server */
339 dns_scope_next_dns_server(t->scope);
341 r = dns_query_transaction_go(t);
343 dns_query_transaction_complete(t, DNS_QUERY_RESOURCES);
351 /* Parse and update the cache */
352 r = dns_packet_extract(p);
354 dns_query_transaction_complete(t, DNS_QUERY_INVALID_REPLY);
358 dns_cache_put(&t->scope->cache, p->question, DNS_PACKET_RCODE(p), p->answer, 0);
360 if (DNS_PACKET_RCODE(p) == DNS_RCODE_SUCCESS)
361 dns_query_transaction_complete(t, DNS_QUERY_SUCCESS);
363 dns_query_transaction_complete(t, DNS_QUERY_FAILURE);
366 static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
367 DnsQueryTransaction *t = userdata;
373 /* Timeout reached? Try again, with a new server */
374 dns_scope_next_dns_server(t->scope);
376 r = dns_query_transaction_go(t);
378 dns_query_transaction_complete(t, DNS_QUERY_RESOURCES);
383 static int dns_query_make_packet(DnsQueryTransaction *t) {
384 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
385 unsigned n, added = 0;
393 r = dns_packet_new_query(&p, t->scope->protocol, 0);
397 for (n = 0; n < t->question->n_keys; n++) {
398 r = dns_scope_good_key(t->scope, t->question->keys[n]);
404 r = dns_packet_append_key(p, t->question->keys[n], NULL);
414 DNS_PACKET_HEADER(p)->qdcount = htobe16(added);
415 DNS_PACKET_HEADER(p)->id = t->id;
423 static int dns_query_transaction_go(DnsQueryTransaction *t) {
428 dns_query_transaction_stop(t);
430 log_debug("Beginning transaction on scope %s on %s/%s",
431 dns_protocol_to_string(t->scope->protocol),
432 t->scope->link ? t->scope->link->name : "*",
433 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family));
435 if (t->n_attempts >= ATTEMPTS_MAX) {
436 dns_query_transaction_complete(t, DNS_QUERY_ATTEMPTS_MAX);
441 t->received = dns_packet_unref(t->received);
442 t->cached = dns_answer_unref(t->cached);
445 /* First, let's try the cache */
446 dns_cache_prune(&t->scope->cache);
447 r = dns_cache_lookup(&t->scope->cache, t->question, &t->cached_rcode, &t->cached);
451 if (t->cached_rcode == DNS_RCODE_SUCCESS)
452 dns_query_transaction_complete(t, DNS_QUERY_SUCCESS);
454 dns_query_transaction_complete(t, DNS_QUERY_FAILURE);
458 /* Otherwise, we need to ask the network */
459 r = dns_query_make_packet(t);
461 /* Not the right request to make on this network?
462 * (i.e. an A request made on IPv6 or an AAAA request
463 * made on IPv4, on LLMNR or mDNS.) */
464 dns_query_transaction_complete(t, DNS_QUERY_NO_SERVERS);
470 if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
471 (dns_question_endswith(t->question, "in-addr.arpa") > 0 ||
472 dns_question_endswith(t->question, "ip6.arpa") > 0)) {
474 /* RFC 4795, Section 2.4. says reverse lookups shall
475 * always be made via TCP on LLMNR */
476 r = dns_query_transaction_open_tcp(t);
478 /* Try via UDP, and if that fails due to large size try via TCP */
479 r = dns_scope_send(t->scope, t->sent);
481 r = dns_query_transaction_open_tcp(t);
484 /* No servers to send this to? */
485 dns_query_transaction_complete(t, DNS_QUERY_NO_SERVERS);
489 /* Couldn't send? Try immediately again, with a new server */
490 dns_scope_next_dns_server(t->scope);
492 return dns_query_transaction_go(t);
495 r = sd_event_add_time(t->scope->manager->event, &t->timeout_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + TRANSACTION_TIMEOUT_USEC, 0, on_transaction_timeout, t);
499 t->state = DNS_QUERY_PENDING;
503 DnsQuery *dns_query_free(DnsQuery *q) {
504 DnsQueryTransaction *t;
509 sd_bus_message_unref(q->request);
511 dns_question_unref(q->question);
512 dns_answer_unref(q->answer);
514 sd_event_source_unref(q->timeout_event_source);
516 while ((t = set_steal_first(q->transactions))) {
517 set_remove(t->queries, q);
518 dns_query_transaction_gc(t);
521 set_free(q->transactions);
524 LIST_REMOVE(queries, q->manager->dns_queries, q);
525 q->manager->n_dns_queries--;
533 int dns_query_new(Manager *m, DnsQuery **ret, DnsQuestion *question) {
534 _cleanup_(dns_query_freep) DnsQuery *q = NULL;
541 r = dns_question_is_valid(question);
545 if (m->n_dns_queries >= QUERIES_MAX)
548 q = new0(DnsQuery, 1);
552 q->question = dns_question_ref(question);
554 for (i = 0; i < question->n_keys; i++) {
555 log_debug("Looking up RR for %s %s %s",
556 strna(dns_class_to_string(question->keys[i]->class)),
557 strna(dns_type_to_string(question->keys[i]->type)),
558 DNS_RESOURCE_KEY_NAME(question->keys[i]));
561 LIST_PREPEND(queries, m->dns_queries, q);
572 static void dns_query_stop(DnsQuery *q) {
573 DnsQueryTransaction *t;
577 q->timeout_event_source = sd_event_source_unref(q->timeout_event_source);
579 while ((t = set_steal_first(q->transactions))) {
580 set_remove(t->queries, q);
581 dns_query_transaction_gc(t);
585 static void dns_query_complete(DnsQuery *q, DnsQueryState state) {
587 assert(!IN_SET(state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
588 assert(IN_SET(q->state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
590 /* Note that this call might invalidate the query. Callers
591 * should hence not attempt to access the query or transaction
592 * after calling this function. */
601 static int on_query_timeout(sd_event_source *s, usec_t usec, void *userdata) {
602 DnsQuery *q = userdata;
607 dns_query_complete(q, DNS_QUERY_TIMEOUT);
611 static int dns_query_add_transaction(DnsQuery *q, DnsScope *s, DnsResourceKey *key) {
612 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
613 DnsQueryTransaction *t;
618 r = set_ensure_allocated(&q->transactions, NULL, NULL);
623 question = dns_question_new(1);
627 r = dns_question_add(question, key);
631 question = dns_question_ref(q->question);
633 LIST_FOREACH(transactions_by_scope, t, s->transactions)
634 if (dns_question_is_superset(t->question, question))
638 r = dns_query_transaction_new(&t, s, question);
643 r = set_ensure_allocated(&t->queries, NULL, NULL);
647 r = set_put(t->queries, q);
651 r = set_put(q->transactions, t);
653 set_remove(t->queries, q);
660 dns_query_transaction_gc(t);
664 static int dns_query_add_transaction_split(DnsQuery *q, DnsScope *s) {
670 if (s->protocol == DNS_PROTOCOL_MDNS) {
671 r = dns_query_add_transaction(q, s, NULL);
677 /* On DNS and LLMNR we can only send a single
678 * question per datagram, hence issue multiple
681 for (i = 0; i < q->question->n_keys; i++) {
682 r = dns_query_add_transaction(q, s, q->question->keys[i]);
691 int dns_query_go(DnsQuery *q) {
692 DnsScopeMatch found = DNS_SCOPE_NO;
693 DnsScope *s, *first = NULL;
694 DnsQueryTransaction *t;
701 if (q->state != DNS_QUERY_NULL)
705 assert(q->question->n_keys > 0);
707 name = DNS_RESOURCE_KEY_NAME(q->question->keys[0]);
709 LIST_FOREACH(scopes, s, q->manager->dns_scopes) {
712 match = dns_scope_good_domain(s, name);
716 if (match == DNS_SCOPE_NO)
721 if (match == DNS_SCOPE_YES) {
725 assert(match == DNS_SCOPE_MAYBE);
732 if (found == DNS_SCOPE_NO)
735 r = dns_query_add_transaction_split(q, first);
739 LIST_FOREACH(scopes, s, first->scopes_next) {
742 match = dns_scope_good_domain(s, name);
749 r = dns_query_add_transaction_split(q, s);
754 q->answer = dns_answer_unref(q->answer);
755 q->answer_ifindex = 0;
758 r = sd_event_add_time(q->manager->event, &q->timeout_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + QUERY_TIMEOUT_USEC, 0, on_query_timeout, q);
762 q->state = DNS_QUERY_PENDING;
765 SET_FOREACH(t, q->transactions, i) {
766 if (t->state == DNS_QUERY_NULL) {
767 r = dns_query_transaction_go(t);
783 void dns_query_ready(DnsQuery *q) {
784 DnsQueryTransaction *t;
785 DnsQueryState state = DNS_QUERY_NO_SERVERS;
786 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
788 DnsScope *scope = NULL;
792 assert(IN_SET(q->state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
794 /* Note that this call might invalidate the query. Callers
795 * should hence not attempt to access the query or transaction
796 * after calling this function, unless the block_ready
797 * counter was explicitly bumped before doing so. */
799 if (q->block_ready > 0)
802 SET_FOREACH(t, q->transactions, i) {
804 /* If we found a successful answer, ignore all answers from other scopes */
805 if (state == DNS_QUERY_SUCCESS && t->scope != scope)
808 /* One of the transactions is still going on, let's wait for it */
809 if (t->state == DNS_QUERY_PENDING || t->state == DNS_QUERY_NULL)
812 /* One of the transactions is successful, let's use
813 * it, and copy its data out */
814 if (t->state == DNS_QUERY_SUCCESS) {
818 rcode = DNS_PACKET_RCODE(t->received);
819 a = t->received->answer;
821 rcode = t->cached_rcode;
825 if (state == DNS_QUERY_SUCCESS) {
828 merged = dns_answer_merge(answer, a);
830 dns_query_complete(q, DNS_QUERY_RESOURCES);
834 dns_answer_unref(answer);
837 dns_answer_unref(answer);
838 answer = dns_answer_ref(a);
842 state = DNS_QUERY_SUCCESS;
846 /* One of the transactions has failed, let's see
847 * whether we find anything better, but if not, return
848 * its response data */
849 if (state != DNS_QUERY_SUCCESS && t->state == DNS_QUERY_FAILURE) {
853 rcode = DNS_PACKET_RCODE(t->received);
854 a = t->received->answer;
856 rcode = t->cached_rcode;
860 dns_answer_unref(answer);
861 answer = dns_answer_ref(a);
864 state = DNS_QUERY_FAILURE;
868 if (state == DNS_QUERY_NO_SERVERS && t->state != DNS_QUERY_NO_SERVERS)
872 if (IN_SET(state, DNS_QUERY_SUCCESS, DNS_QUERY_FAILURE)) {
873 q->answer = dns_answer_ref(answer);
874 q->answer_rcode = rcode;
875 q->answer_ifindex = (scope && scope->link) ? scope->link->ifindex : 0;
878 dns_query_complete(q, state);
881 int dns_query_cname_redirect(DnsQuery *q, const char *name) {
882 _cleanup_(dns_question_unrefp) DnsQuestion *nq = NULL;
887 if (q->n_cname_redirects > CNAME_MAX)
890 r = dns_question_cname_redirect(q->question, name, &nq);
894 dns_question_unref(q->question);
898 q->n_cname_redirects++;
901 q->state = DNS_QUERY_NULL;
906 static const char* const dns_query_state_table[_DNS_QUERY_STATE_MAX] = {
907 [DNS_QUERY_NULL] = "null",
908 [DNS_QUERY_PENDING] = "pending",
909 [DNS_QUERY_FAILURE] = "failure",
910 [DNS_QUERY_SUCCESS] = "success",
911 [DNS_QUERY_NO_SERVERS] = "no-servers",
912 [DNS_QUERY_TIMEOUT] = "timeout",
913 [DNS_QUERY_ATTEMPTS_MAX] = "attempts-max",
914 [DNS_QUERY_INVALID_REPLY] = "invalid-reply",
915 [DNS_QUERY_RESOURCES] = "resources",
916 [DNS_QUERY_ABORTED] = "aborted",
918 DEFINE_STRING_TABLE_LOOKUP(dns_query_state, DnsQueryState);