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 /* Tentative replies shall be discarded, see RFC 4795,
279 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
281 /* For DNS we are fine with accepting packets on any
282 * interface, but the source IP address must be one of
283 * a valid DNS server */
285 if (!dns_scope_good_dns_server(t->scope, p->family, &p->sender))
288 if (p->sender_port != 53)
292 if (t->received != p) {
293 dns_packet_unref(t->received);
294 t->received = dns_packet_ref(p);
297 if (p->ipproto == IPPROTO_TCP) {
298 if (DNS_PACKET_TC(p)) {
299 /* Truncated via TCP? Somebody must be fucking with us */
300 dns_query_transaction_complete(t, DNS_QUERY_INVALID_REPLY);
304 if (DNS_PACKET_ID(p) != t->id) {
305 /* Not the reply to our query? Somebody must be fucking with us */
306 dns_query_transaction_complete(t, DNS_QUERY_INVALID_REPLY);
311 if (DNS_PACKET_TC(p)) {
312 /* Response was truncated, let's try again with good old TCP */
313 r = dns_query_transaction_open_tcp(t);
315 /* No servers found? Damn! */
316 dns_query_transaction_complete(t, DNS_QUERY_NO_SERVERS);
320 /* On LLMNR, if we cannot connect to the host,
321 * we immediately give up */
322 if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
323 dns_query_transaction_complete(t, DNS_QUERY_RESOURCES);
327 /* On DNS, couldn't send? Try immediately again, with a new server */
328 dns_scope_next_dns_server(t->scope);
330 r = dns_query_transaction_go(t);
332 dns_query_transaction_complete(t, DNS_QUERY_RESOURCES);
340 /* Parse and update the cache */
341 r = dns_packet_extract(p);
343 dns_query_transaction_complete(t, DNS_QUERY_INVALID_REPLY);
347 /* According to RFC 4795, section 2.9. only the RRs from the answer section shall be cached */
348 dns_cache_put(&t->scope->cache, p->question, DNS_PACKET_RCODE(p), p->answer, DNS_PACKET_ANCOUNT(p), 0);
350 if (DNS_PACKET_RCODE(p) == DNS_RCODE_SUCCESS)
351 dns_query_transaction_complete(t, DNS_QUERY_SUCCESS);
353 dns_query_transaction_complete(t, DNS_QUERY_FAILURE);
356 static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
357 DnsQueryTransaction *t = userdata;
363 /* Timeout reached? Try again, with a new server */
364 dns_scope_next_dns_server(t->scope);
366 r = dns_query_transaction_go(t);
368 dns_query_transaction_complete(t, DNS_QUERY_RESOURCES);
373 static int dns_query_make_packet(DnsQueryTransaction *t) {
374 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
375 unsigned n, added = 0;
383 r = dns_packet_new_query(&p, t->scope->protocol, 0);
387 for (n = 0; n < t->question->n_keys; n++) {
388 r = dns_scope_good_key(t->scope, t->question->keys[n]);
394 r = dns_packet_append_key(p, t->question->keys[n], NULL);
404 DNS_PACKET_HEADER(p)->qdcount = htobe16(added);
405 DNS_PACKET_HEADER(p)->id = t->id;
413 static int dns_query_transaction_go(DnsQueryTransaction *t) {
418 dns_query_transaction_stop(t);
420 log_debug("Beginning transaction on scope %s on %s/%s",
421 dns_protocol_to_string(t->scope->protocol),
422 t->scope->link ? t->scope->link->name : "*",
423 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family));
425 if (t->n_attempts >= ATTEMPTS_MAX) {
426 dns_query_transaction_complete(t, DNS_QUERY_ATTEMPTS_MAX);
431 t->received = dns_packet_unref(t->received);
432 t->cached = dns_answer_unref(t->cached);
435 /* First, let's try the cache */
436 dns_cache_prune(&t->scope->cache);
437 r = dns_cache_lookup(&t->scope->cache, t->question, &t->cached_rcode, &t->cached);
441 if (t->cached_rcode == DNS_RCODE_SUCCESS)
442 dns_query_transaction_complete(t, DNS_QUERY_SUCCESS);
444 dns_query_transaction_complete(t, DNS_QUERY_FAILURE);
448 /* Otherwise, we need to ask the network */
449 r = dns_query_make_packet(t);
451 /* Not the right request to make on this network?
452 * (i.e. an A request made on IPv6 or an AAAA request
453 * made on IPv4, on LLMNR or mDNS.) */
454 dns_query_transaction_complete(t, DNS_QUERY_NO_SERVERS);
460 if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
461 (dns_question_endswith(t->question, "in-addr.arpa") > 0 ||
462 dns_question_endswith(t->question, "ip6.arpa") > 0)) {
464 /* RFC 4795, Section 2.4. says reverse lookups shall
465 * always be made via TCP on LLMNR */
466 r = dns_query_transaction_open_tcp(t);
468 /* Try via UDP, and if that fails due to large size try via TCP */
469 r = dns_scope_send(t->scope, t->sent);
471 r = dns_query_transaction_open_tcp(t);
474 /* No servers to send this to? */
475 dns_query_transaction_complete(t, DNS_QUERY_NO_SERVERS);
479 /* Couldn't send? Try immediately again, with a new server */
480 dns_scope_next_dns_server(t->scope);
482 return dns_query_transaction_go(t);
485 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);
489 t->state = DNS_QUERY_PENDING;
493 DnsQuery *dns_query_free(DnsQuery *q) {
494 DnsQueryTransaction *t;
499 sd_bus_message_unref(q->request);
501 dns_question_unref(q->question);
502 dns_answer_unref(q->answer);
504 sd_event_source_unref(q->timeout_event_source);
506 while ((t = set_steal_first(q->transactions))) {
507 set_remove(t->queries, q);
508 dns_query_transaction_gc(t);
511 set_free(q->transactions);
514 LIST_REMOVE(queries, q->manager->dns_queries, q);
515 q->manager->n_dns_queries--;
523 int dns_query_new(Manager *m, DnsQuery **ret, DnsQuestion *question) {
524 _cleanup_(dns_query_freep) DnsQuery *q = NULL;
531 r = dns_question_is_valid(question);
535 if (m->n_dns_queries >= QUERIES_MAX)
538 q = new0(DnsQuery, 1);
542 q->question = dns_question_ref(question);
544 for (i = 0; i < question->n_keys; i++) {
545 log_debug("Looking up RR for %s %s %s",
546 strna(dns_class_to_string(question->keys[i]->class)),
547 strna(dns_type_to_string(question->keys[i]->type)),
548 DNS_RESOURCE_KEY_NAME(question->keys[i]));
551 LIST_PREPEND(queries, m->dns_queries, q);
562 static void dns_query_stop(DnsQuery *q) {
563 DnsQueryTransaction *t;
567 q->timeout_event_source = sd_event_source_unref(q->timeout_event_source);
569 while ((t = set_steal_first(q->transactions))) {
570 set_remove(t->queries, q);
571 dns_query_transaction_gc(t);
575 static void dns_query_complete(DnsQuery *q, DnsQueryState state) {
577 assert(!IN_SET(state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
578 assert(IN_SET(q->state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
580 /* Note that this call might invalidate the query. Callers
581 * should hence not attempt to access the query or transaction
582 * after calling this function. */
591 static int on_query_timeout(sd_event_source *s, usec_t usec, void *userdata) {
592 DnsQuery *q = userdata;
597 dns_query_complete(q, DNS_QUERY_TIMEOUT);
601 static int dns_query_add_transaction(DnsQuery *q, DnsScope *s, DnsResourceKey *key) {
602 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
603 DnsQueryTransaction *t;
608 r = set_ensure_allocated(&q->transactions, NULL, NULL);
613 question = dns_question_new(1);
617 r = dns_question_add(question, key);
621 question = dns_question_ref(q->question);
623 LIST_FOREACH(transactions_by_scope, t, s->transactions)
624 if (dns_question_is_superset(t->question, question))
628 r = dns_query_transaction_new(&t, s, question);
633 r = set_ensure_allocated(&t->queries, NULL, NULL);
637 r = set_put(t->queries, q);
641 r = set_put(q->transactions, t);
643 set_remove(t->queries, q);
650 dns_query_transaction_gc(t);
654 static int dns_query_add_transaction_split(DnsQuery *q, DnsScope *s) {
660 if (s->protocol == DNS_PROTOCOL_MDNS) {
661 r = dns_query_add_transaction(q, s, NULL);
667 /* On DNS and LLMNR we can only send a single
668 * question per datagram, hence issue multiple
671 for (i = 0; i < q->question->n_keys; i++) {
672 r = dns_query_add_transaction(q, s, q->question->keys[i]);
681 int dns_query_go(DnsQuery *q) {
682 DnsScopeMatch found = DNS_SCOPE_NO;
683 DnsScope *s, *first = NULL;
684 DnsQueryTransaction *t;
691 if (q->state != DNS_QUERY_NULL)
695 assert(q->question->n_keys > 0);
697 name = DNS_RESOURCE_KEY_NAME(q->question->keys[0]);
699 LIST_FOREACH(scopes, s, q->manager->dns_scopes) {
702 match = dns_scope_good_domain(s, name);
706 if (match == DNS_SCOPE_NO)
711 if (match == DNS_SCOPE_YES) {
715 assert(match == DNS_SCOPE_MAYBE);
722 if (found == DNS_SCOPE_NO)
725 r = dns_query_add_transaction_split(q, first);
729 LIST_FOREACH(scopes, s, first->scopes_next) {
732 match = dns_scope_good_domain(s, name);
739 r = dns_query_add_transaction_split(q, s);
744 q->answer = dns_answer_unref(q->answer);
745 q->answer_ifindex = 0;
748 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);
752 q->state = DNS_QUERY_PENDING;
755 SET_FOREACH(t, q->transactions, i) {
756 if (t->state == DNS_QUERY_NULL) {
757 r = dns_query_transaction_go(t);
773 void dns_query_ready(DnsQuery *q) {
774 DnsQueryTransaction *t;
775 DnsQueryState state = DNS_QUERY_NO_SERVERS;
776 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
778 DnsScope *scope = NULL;
782 assert(IN_SET(q->state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
784 /* Note that this call might invalidate the query. Callers
785 * should hence not attempt to access the query or transaction
786 * after calling this function, unless the block_ready
787 * counter was explicitly bumped before doing so. */
789 if (q->block_ready > 0)
792 SET_FOREACH(t, q->transactions, i) {
794 /* If we found a successful answer, ignore all answers from other scopes */
795 if (state == DNS_QUERY_SUCCESS && t->scope != scope)
798 /* One of the transactions is still going on, let's wait for it */
799 if (t->state == DNS_QUERY_PENDING || t->state == DNS_QUERY_NULL)
802 /* One of the transactions is successful, let's use
803 * it, and copy its data out */
804 if (t->state == DNS_QUERY_SUCCESS) {
808 rcode = DNS_PACKET_RCODE(t->received);
809 a = t->received->answer;
811 rcode = t->cached_rcode;
815 if (state == DNS_QUERY_SUCCESS) {
818 merged = dns_answer_merge(answer, a);
820 dns_query_complete(q, DNS_QUERY_RESOURCES);
824 dns_answer_unref(answer);
827 dns_answer_unref(answer);
828 answer = dns_answer_ref(a);
832 state = DNS_QUERY_SUCCESS;
836 /* One of the transactions has failed, let's see
837 * whether we find anything better, but if not, return
838 * its response data */
839 if (state != DNS_QUERY_SUCCESS && t->state == DNS_QUERY_FAILURE) {
843 rcode = DNS_PACKET_RCODE(t->received);
844 a = t->received->answer;
846 rcode = t->cached_rcode;
850 dns_answer_unref(answer);
851 answer = dns_answer_ref(a);
854 state = DNS_QUERY_FAILURE;
858 if (state == DNS_QUERY_NO_SERVERS && t->state != DNS_QUERY_NO_SERVERS)
862 if (IN_SET(state, DNS_QUERY_SUCCESS, DNS_QUERY_FAILURE)) {
863 q->answer = dns_answer_ref(answer);
864 q->answer_rcode = rcode;
865 q->answer_ifindex = (scope && scope->link) ? scope->link->ifindex : 0;
868 dns_query_complete(q, state);
871 int dns_query_cname_redirect(DnsQuery *q, const char *name) {
872 _cleanup_(dns_question_unrefp) DnsQuestion *nq = NULL;
877 if (q->n_cname_redirects > CNAME_MAX)
880 r = dns_question_cname_redirect(q->question, name, &nq);
884 dns_question_unref(q->question);
888 q->n_cname_redirects++;
891 q->state = DNS_QUERY_NULL;
896 static const char* const dns_query_state_table[_DNS_QUERY_STATE_MAX] = {
897 [DNS_QUERY_NULL] = "null",
898 [DNS_QUERY_PENDING] = "pending",
899 [DNS_QUERY_FAILURE] = "failure",
900 [DNS_QUERY_SUCCESS] = "success",
901 [DNS_QUERY_NO_SERVERS] = "no-servers",
902 [DNS_QUERY_TIMEOUT] = "timeout",
903 [DNS_QUERY_ATTEMPTS_MAX] = "attempts-max",
904 [DNS_QUERY_INVALID_REPLY] = "invalid-reply",
905 [DNS_QUERY_RESOURCES] = "resources",
906 [DNS_QUERY_ABORTED] = "aborted",
908 DEFINE_STRING_TABLE_LOOKUP(dns_query_state, DnsQueryState);