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 /* After how much time to repeat classic DNS requests */
28 #define DNS_TRANSACTION_TIMEOUT_USEC (5 * USEC_PER_SEC)
30 /* After how much time to repeat LLMNR requests, see RFC 4795 Section 7 */
31 #define LLMNR_TRANSACTION_TIMEOUT_USEC (1 * USEC_PER_SEC)
33 /* How long to wait for the query in total */
34 #define QUERY_TIMEOUT_USEC (30 * USEC_PER_SEC)
36 /* Maximum attempts to send DNS requests, across all DNS servers */
37 #define DNS_TRANSACTION_ATTEMPTS_MAX 8
39 /* Maximum attempts to send LLMNR requests, see RFC 4795 Section 2.7 */
40 #define LLMNR_TRANSACTION_ATTEMPTS_MAX 3
43 #define QUERIES_MAX 2048
45 #define TRANSACTION_TIMEOUT_USEC(p) ((t)->scope->protocol == DNS_PROTOCOL_LLMNR ? LLMNR_TRANSACTION_TIMEOUT_USEC : DNS_TRANSACTION_TIMEOUT_USEC)
46 #define TRANSACTION_ATTEMPTS_MAX(p) ((t)->scope->protocol == DNS_PROTOCOL_LLMNR ? LLMNR_TRANSACTION_ATTEMPTS_MAX : DNS_TRANSACTION_ATTEMPTS_MAX)
48 static int dns_query_transaction_go(DnsQueryTransaction *t);
50 DnsQueryTransaction* dns_query_transaction_free(DnsQueryTransaction *t) {
56 sd_event_source_unref(t->timeout_event_source);
58 dns_question_unref(t->question);
59 dns_packet_unref(t->sent);
60 dns_packet_unref(t->received);
61 dns_answer_unref(t->cached);
63 dns_stream_free(t->stream);
66 LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
69 hashmap_remove(t->scope->manager->dns_query_transactions, UINT_TO_PTR(t->id));
72 while ((q = set_steal_first(t->queries)))
73 set_remove(q->transactions, t);
81 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQueryTransaction*, dns_query_transaction_free);
83 static void dns_query_transaction_gc(DnsQueryTransaction *t) {
89 if (set_isempty(t->queries))
90 dns_query_transaction_free(t);
93 static int dns_query_transaction_new(DnsQueryTransaction **ret, DnsScope *s, DnsQuestion *q) {
94 _cleanup_(dns_query_transaction_freep) DnsQueryTransaction *t = NULL;
101 r = hashmap_ensure_allocated(&s->manager->dns_query_transactions, NULL, NULL);
105 t = new0(DnsQueryTransaction, 1);
109 t->question = dns_question_ref(q);
112 random_bytes(&t->id, sizeof(t->id));
114 hashmap_get(s->manager->dns_query_transactions, UINT_TO_PTR(t->id)));
116 r = hashmap_put(s->manager->dns_query_transactions, UINT_TO_PTR(t->id), t);
122 LIST_PREPEND(transactions_by_scope, s->transactions, t);
133 static void dns_query_transaction_stop(DnsQueryTransaction *t) {
136 t->timeout_event_source = sd_event_source_unref(t->timeout_event_source);
137 t->stream = dns_stream_free(t->stream);
140 void dns_query_transaction_complete(DnsQueryTransaction *t, DnsQueryState state) {
145 assert(!IN_SET(state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
146 assert(IN_SET(t->state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
148 /* Note that this call might invalidate the query. Callers
149 * should hence not attempt to access the query or transaction
150 * after calling this function. */
152 log_debug("Transaction on scope %s on %s/%s now complete with %s",
153 dns_protocol_to_string(t->scope->protocol),
154 t->scope->link ? t->scope->link->name : "*",
155 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
156 dns_query_state_to_string(state));
160 dns_query_transaction_stop(t);
162 /* Notify all queries that are interested, but make sure the
163 * transaction isn't freed while we are still looking at it */
165 SET_FOREACH(q, t->queries, i)
169 dns_query_transaction_gc(t);
172 static int on_stream_complete(DnsStream *s, int error) {
173 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
174 DnsQueryTransaction *t;
177 assert(s->transaction);
179 /* Copy the data we care about out of the stream before we
182 p = dns_packet_ref(s->read_packet);
184 t->stream = dns_stream_free(t->stream);
187 dns_query_transaction_complete(t, DNS_QUERY_RESOURCES);
192 dns_query_transaction_process_reply(t, p);
195 /* If the response wasn't useful, then complete the transition now */
196 if (t->state == DNS_QUERY_PENDING)
197 dns_query_transaction_complete(t, DNS_QUERY_INVALID_REPLY);
202 static int dns_query_transaction_open_tcp(DnsQueryTransaction *t) {
203 _cleanup_close_ int fd = -1;
211 if (t->scope->protocol == DNS_PROTOCOL_DNS)
212 fd = dns_scope_tcp_socket(t->scope, AF_UNSPEC, NULL, 53);
213 else if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
215 /* When we already received a query to this (but it was truncated), send to its sender address */
217 fd = dns_scope_tcp_socket(t->scope, t->received->family, &t->received->sender, t->received->sender_port);
219 union in_addr_union address;
222 /* Otherwise, try to talk to the owner of a
223 * the IP address, in case this is a reverse
225 r = dns_question_extract_reverse_address(t->question, &family, &address);
231 fd = dns_scope_tcp_socket(t->scope, family, &address, 5355);
234 return -EAFNOSUPPORT;
239 r = dns_stream_new(t->scope->manager, &t->stream, t->scope->protocol, fd);
245 r = dns_stream_write_packet(t->stream, t->sent);
247 t->stream = dns_stream_free(t->stream);
251 t->received = dns_packet_unref(t->received);
252 t->stream->complete = on_stream_complete;
253 t->stream->transaction = t;
255 /* The interface index is difficult to determine if we are
256 * connecting to the local host, hence fill this in right away
257 * instead of determining it from the socket */
259 t->stream->ifindex = t->scope->link->ifindex;
264 void dns_query_transaction_process_reply(DnsQueryTransaction *t, DnsPacket *p) {
269 assert(t->state == DNS_QUERY_PENDING);
271 /* Note that this call might invalidate the query. Callers
272 * should hence not attempt to access the query or transaction
273 * after calling this function. */
275 if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
276 assert(t->scope->link);
278 /* For LLMNR we will not accept any packets from other
281 if (p->ifindex != t->scope->link->ifindex)
284 if (p->family != t->scope->family)
287 /* Tentative replies shall be discarded, see RFC 4795,
294 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
296 /* For DNS we are fine with accepting packets on any
297 * interface, but the source IP address must be one of
298 * a valid DNS server */
300 if (!dns_scope_good_dns_server(t->scope, p->family, &p->sender))
303 if (p->sender_port != 53)
307 if (t->received != p) {
308 dns_packet_unref(t->received);
309 t->received = dns_packet_ref(p);
312 if (p->ipproto == IPPROTO_TCP) {
313 if (DNS_PACKET_TC(p)) {
314 /* Truncated via TCP? Somebody must be fucking with us */
315 dns_query_transaction_complete(t, DNS_QUERY_INVALID_REPLY);
319 if (DNS_PACKET_ID(p) != t->id) {
320 /* Not the reply to our query? Somebody must be fucking with us */
321 dns_query_transaction_complete(t, DNS_QUERY_INVALID_REPLY);
326 if (DNS_PACKET_TC(p)) {
327 /* Response was truncated, let's try again with good old TCP */
328 r = dns_query_transaction_open_tcp(t);
330 /* No servers found? Damn! */
331 dns_query_transaction_complete(t, DNS_QUERY_NO_SERVERS);
335 /* On LLMNR, if we cannot connect to the host,
336 * we immediately give up */
337 if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
338 dns_query_transaction_complete(t, DNS_QUERY_RESOURCES);
342 /* On DNS, couldn't send? Try immediately again, with a new server */
343 dns_scope_next_dns_server(t->scope);
345 r = dns_query_transaction_go(t);
347 dns_query_transaction_complete(t, DNS_QUERY_RESOURCES);
355 /* Parse and update the cache */
356 r = dns_packet_extract(p);
358 dns_query_transaction_complete(t, DNS_QUERY_INVALID_REPLY);
362 /* According to RFC 4795, section 2.9. only the RRs from the answer section shall be cached */
363 dns_cache_put(&t->scope->cache, p->question, DNS_PACKET_RCODE(p), p->answer, DNS_PACKET_ANCOUNT(p), 0);
365 if (DNS_PACKET_RCODE(p) == DNS_RCODE_SUCCESS)
366 dns_query_transaction_complete(t, DNS_QUERY_SUCCESS);
368 dns_query_transaction_complete(t, DNS_QUERY_FAILURE);
371 static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
372 DnsQueryTransaction *t = userdata;
378 /* Timeout reached? Try again, with a new server */
379 dns_scope_next_dns_server(t->scope);
381 r = dns_query_transaction_go(t);
383 dns_query_transaction_complete(t, DNS_QUERY_RESOURCES);
388 static int dns_query_make_packet(DnsQueryTransaction *t) {
389 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
390 unsigned n, added = 0;
398 r = dns_packet_new_query(&p, t->scope->protocol, 0);
402 for (n = 0; n < t->question->n_keys; n++) {
403 r = dns_scope_good_key(t->scope, t->question->keys[n]);
409 r = dns_packet_append_key(p, t->question->keys[n], NULL);
419 DNS_PACKET_HEADER(p)->qdcount = htobe16(added);
420 DNS_PACKET_HEADER(p)->id = t->id;
428 static int dns_query_transaction_go(DnsQueryTransaction *t) {
434 had_stream = !!t->stream;
436 dns_query_transaction_stop(t);
438 log_debug("Beginning transaction on scope %s on %s/%s",
439 dns_protocol_to_string(t->scope->protocol),
440 t->scope->link ? t->scope->link->name : "*",
441 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family));
443 if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t)) {
444 dns_query_transaction_complete(t, DNS_QUERY_ATTEMPTS_MAX);
448 if (t->scope->protocol == DNS_PROTOCOL_LLMNR && had_stream) {
449 /* If we already tried via a stream, then we don't
450 * retry on LLMNR. See RFC 4795, Section 2.7. */
451 dns_query_transaction_complete(t, DNS_QUERY_ATTEMPTS_MAX);
456 t->received = dns_packet_unref(t->received);
457 t->cached = dns_answer_unref(t->cached);
460 /* First, let's try the cache */
461 dns_cache_prune(&t->scope->cache);
462 r = dns_cache_lookup(&t->scope->cache, t->question, &t->cached_rcode, &t->cached);
466 if (t->cached_rcode == DNS_RCODE_SUCCESS)
467 dns_query_transaction_complete(t, DNS_QUERY_SUCCESS);
469 dns_query_transaction_complete(t, DNS_QUERY_FAILURE);
473 /* Otherwise, we need to ask the network */
474 r = dns_query_make_packet(t);
476 /* Not the right request to make on this network?
477 * (i.e. an A request made on IPv6 or an AAAA request
478 * made on IPv4, on LLMNR or mDNS.) */
479 dns_query_transaction_complete(t, DNS_QUERY_NO_SERVERS);
485 if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
486 (dns_question_endswith(t->question, "in-addr.arpa") > 0 ||
487 dns_question_endswith(t->question, "ip6.arpa") > 0)) {
489 /* RFC 4795, Section 2.4. says reverse lookups shall
490 * always be made via TCP on LLMNR */
491 r = dns_query_transaction_open_tcp(t);
493 /* Try via UDP, and if that fails due to large size try via TCP */
494 r = dns_scope_send(t->scope, t->sent);
496 r = dns_query_transaction_open_tcp(t);
499 /* No servers to send this to? */
500 dns_query_transaction_complete(t, DNS_QUERY_NO_SERVERS);
504 /* Couldn't send? Try immediately again, with a new server */
505 dns_scope_next_dns_server(t->scope);
507 return dns_query_transaction_go(t);
510 r = sd_event_add_time(t->scope->manager->event, &t->timeout_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + TRANSACTION_TIMEOUT_USEC(t), 0, on_transaction_timeout, t);
514 t->state = DNS_QUERY_PENDING;
518 DnsQuery *dns_query_free(DnsQuery *q) {
519 DnsQueryTransaction *t;
524 sd_bus_message_unref(q->request);
526 dns_question_unref(q->question);
527 dns_answer_unref(q->answer);
529 sd_event_source_unref(q->timeout_event_source);
531 while ((t = set_steal_first(q->transactions))) {
532 set_remove(t->queries, q);
533 dns_query_transaction_gc(t);
536 set_free(q->transactions);
539 LIST_REMOVE(queries, q->manager->dns_queries, q);
540 q->manager->n_dns_queries--;
548 int dns_query_new(Manager *m, DnsQuery **ret, DnsQuestion *question) {
549 _cleanup_(dns_query_freep) DnsQuery *q = NULL;
556 r = dns_question_is_valid(question);
560 if (m->n_dns_queries >= QUERIES_MAX)
563 q = new0(DnsQuery, 1);
567 q->question = dns_question_ref(question);
569 for (i = 0; i < question->n_keys; i++) {
570 _cleanup_free_ char *p;
572 r = dns_resource_key_to_string(question->keys[i], &p);
576 log_debug("Looking up RR for %s", p);
579 LIST_PREPEND(queries, m->dns_queries, q);
590 static void dns_query_stop(DnsQuery *q) {
591 DnsQueryTransaction *t;
595 q->timeout_event_source = sd_event_source_unref(q->timeout_event_source);
597 while ((t = set_steal_first(q->transactions))) {
598 set_remove(t->queries, q);
599 dns_query_transaction_gc(t);
603 static void dns_query_complete(DnsQuery *q, DnsQueryState state) {
605 assert(!IN_SET(state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
606 assert(IN_SET(q->state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
608 /* Note that this call might invalidate the query. Callers
609 * should hence not attempt to access the query or transaction
610 * after calling this function. */
619 static int on_query_timeout(sd_event_source *s, usec_t usec, void *userdata) {
620 DnsQuery *q = userdata;
625 dns_query_complete(q, DNS_QUERY_TIMEOUT);
629 static int dns_query_add_transaction(DnsQuery *q, DnsScope *s, DnsResourceKey *key) {
630 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
631 DnsQueryTransaction *t;
636 r = set_ensure_allocated(&q->transactions, NULL, NULL);
641 question = dns_question_new(1);
645 r = dns_question_add(question, key);
649 question = dns_question_ref(q->question);
651 LIST_FOREACH(transactions_by_scope, t, s->transactions)
652 if (dns_question_is_superset(t->question, question))
656 r = dns_query_transaction_new(&t, s, question);
661 r = set_ensure_allocated(&t->queries, NULL, NULL);
665 r = set_put(t->queries, q);
669 r = set_put(q->transactions, t);
671 set_remove(t->queries, q);
678 dns_query_transaction_gc(t);
682 static int dns_query_add_transaction_split(DnsQuery *q, DnsScope *s) {
688 if (s->protocol == DNS_PROTOCOL_MDNS) {
689 r = dns_query_add_transaction(q, s, NULL);
695 /* On DNS and LLMNR we can only send a single
696 * question per datagram, hence issue multiple
699 for (i = 0; i < q->question->n_keys; i++) {
700 r = dns_query_add_transaction(q, s, q->question->keys[i]);
709 int dns_query_go(DnsQuery *q) {
710 DnsScopeMatch found = DNS_SCOPE_NO;
711 DnsScope *s, *first = NULL;
712 DnsQueryTransaction *t;
719 if (q->state != DNS_QUERY_NULL)
723 assert(q->question->n_keys > 0);
725 name = DNS_RESOURCE_KEY_NAME(q->question->keys[0]);
727 LIST_FOREACH(scopes, s, q->manager->dns_scopes) {
730 match = dns_scope_good_domain(s, name);
734 if (match == DNS_SCOPE_NO)
739 if (match == DNS_SCOPE_YES) {
743 assert(match == DNS_SCOPE_MAYBE);
750 if (found == DNS_SCOPE_NO)
753 r = dns_query_add_transaction_split(q, first);
757 LIST_FOREACH(scopes, s, first->scopes_next) {
760 match = dns_scope_good_domain(s, name);
767 r = dns_query_add_transaction_split(q, s);
772 q->answer = dns_answer_unref(q->answer);
773 q->answer_ifindex = 0;
776 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);
780 q->state = DNS_QUERY_PENDING;
783 SET_FOREACH(t, q->transactions, i) {
784 if (t->state == DNS_QUERY_NULL) {
785 r = dns_query_transaction_go(t);
801 void dns_query_ready(DnsQuery *q) {
802 DnsQueryTransaction *t;
803 DnsQueryState state = DNS_QUERY_NO_SERVERS;
804 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
806 DnsScope *scope = NULL;
807 bool pending = false;
811 assert(IN_SET(q->state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
813 /* Note that this call might invalidate the query. Callers
814 * should hence not attempt to access the query or transaction
815 * after calling this function, unless the block_ready
816 * counter was explicitly bumped before doing so. */
818 if (q->block_ready > 0)
821 SET_FOREACH(t, q->transactions, i) {
823 /* If we found a successful answer, ignore all answers from other scopes */
824 if (state == DNS_QUERY_SUCCESS && t->scope != scope)
827 /* One of the transactions is still going on, let's maybe wait for it */
828 if (IN_SET(t->state, DNS_QUERY_PENDING, DNS_QUERY_NULL)) {
833 /* One of the transactions is successful, let's use
834 * it, and copy its data out */
835 if (t->state == DNS_QUERY_SUCCESS) {
839 rcode = DNS_PACKET_RCODE(t->received);
840 a = t->received->answer;
842 rcode = t->cached_rcode;
846 if (state == DNS_QUERY_SUCCESS) {
849 merged = dns_answer_merge(answer, a);
851 dns_query_complete(q, DNS_QUERY_RESOURCES);
855 dns_answer_unref(answer);
858 dns_answer_unref(answer);
859 answer = dns_answer_ref(a);
863 state = DNS_QUERY_SUCCESS;
867 /* One of the transactions has failed, let's see
868 * whether we find anything better, but if not, return
869 * its response data */
870 if (state != DNS_QUERY_SUCCESS && t->state == DNS_QUERY_FAILURE) {
874 rcode = DNS_PACKET_RCODE(t->received);
875 a = t->received->answer;
877 rcode = t->cached_rcode;
881 dns_answer_unref(answer);
882 answer = dns_answer_ref(a);
885 state = DNS_QUERY_FAILURE;
889 if (state == DNS_QUERY_NO_SERVERS && t->state != DNS_QUERY_NO_SERVERS)
895 /* If so far we weren't successful, and there's
896 * something still pending, then wait for it */
897 if (state != DNS_QUERY_SUCCESS)
900 /* If we already were successful, then only wait for
901 * other transactions on the same scope to finish. */
902 SET_FOREACH(t, q->transactions, i) {
903 if (t->scope == scope && IN_SET(t->state, DNS_QUERY_PENDING, DNS_QUERY_NULL))
908 if (IN_SET(state, DNS_QUERY_SUCCESS, DNS_QUERY_FAILURE)) {
909 q->answer = dns_answer_ref(answer);
910 q->answer_rcode = rcode;
911 q->answer_ifindex = (scope && scope->link) ? scope->link->ifindex : 0;
914 dns_query_complete(q, state);
917 int dns_query_cname_redirect(DnsQuery *q, const char *name) {
918 _cleanup_(dns_question_unrefp) DnsQuestion *nq = NULL;
923 if (q->n_cname_redirects > CNAME_MAX)
926 r = dns_question_cname_redirect(q->question, name, &nq);
930 dns_question_unref(q->question);
934 q->n_cname_redirects++;
937 q->state = DNS_QUERY_NULL;
942 static const char* const dns_query_state_table[_DNS_QUERY_STATE_MAX] = {
943 [DNS_QUERY_NULL] = "null",
944 [DNS_QUERY_PENDING] = "pending",
945 [DNS_QUERY_FAILURE] = "failure",
946 [DNS_QUERY_SUCCESS] = "success",
947 [DNS_QUERY_NO_SERVERS] = "no-servers",
948 [DNS_QUERY_TIMEOUT] = "timeout",
949 [DNS_QUERY_ATTEMPTS_MAX] = "attempts-max",
950 [DNS_QUERY_INVALID_REPLY] = "invalid-reply",
951 [DNS_QUERY_RESOURCES] = "resources",
952 [DNS_QUERY_ABORTED] = "aborted",
954 DEFINE_STRING_TABLE_LOOKUP(dns_query_state, DnsQueryState);