]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-query.c
resolved: end log messages in a full stop
[thirdparty/systemd.git] / src / resolve / resolved-dns-query.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2014 Lennart Poettering
7
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.
12
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.
17
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/>.
20 ***/
21
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"
27 #include "string-util.h"
28
29 /* How long to wait for the query in total */
30 #define QUERY_TIMEOUT_USEC (30 * USEC_PER_SEC)
31
32 #define CNAME_MAX 8
33 #define QUERIES_MAX 2048
34 #define AUXILIARY_QUERIES_MAX 64
35
36 static int dns_query_candidate_new(DnsQueryCandidate **ret, DnsQuery *q, DnsScope *s) {
37 DnsQueryCandidate *c;
38
39 assert(ret);
40 assert(q);
41 assert(s);
42
43 c = new0(DnsQueryCandidate, 1);
44 if (!c)
45 return -ENOMEM;
46
47 c->query = q;
48 c->scope = s;
49
50 LIST_PREPEND(candidates_by_query, q->candidates, c);
51 LIST_PREPEND(candidates_by_scope, s->query_candidates, c);
52
53 *ret = c;
54 return 0;
55 }
56
57 static void dns_query_candidate_stop(DnsQueryCandidate *c) {
58 DnsTransaction *t;
59
60 assert(c);
61
62 while ((t = set_steal_first(c->transactions))) {
63 set_remove(t->notify_query_candidates, c);
64 dns_transaction_gc(t);
65 }
66 }
67
68 DnsQueryCandidate* dns_query_candidate_free(DnsQueryCandidate *c) {
69
70 if (!c)
71 return NULL;
72
73 dns_query_candidate_stop(c);
74
75 set_free(c->transactions);
76 dns_search_domain_unref(c->search_domain);
77
78 if (c->query)
79 LIST_REMOVE(candidates_by_query, c->query->candidates, c);
80
81 if (c->scope)
82 LIST_REMOVE(candidates_by_scope, c->scope->query_candidates, c);
83
84 free(c);
85
86 return NULL;
87 }
88
89 static int dns_query_candidate_next_search_domain(DnsQueryCandidate *c) {
90 DnsSearchDomain *next = NULL;
91
92 assert(c);
93
94 if (c->search_domain && c->search_domain->linked) {
95 next = c->search_domain->domains_next;
96
97 if (!next) /* We hit the end of the list */
98 return 0;
99
100 } else {
101 next = dns_scope_get_search_domains(c->scope);
102
103 if (!next) /* OK, there's nothing. */
104 return 0;
105 }
106
107 dns_search_domain_unref(c->search_domain);
108 c->search_domain = dns_search_domain_ref(next);
109
110 return 1;
111 }
112
113 static int dns_query_candidate_add_transaction(DnsQueryCandidate *c, DnsResourceKey *key) {
114 DnsTransaction *t;
115 int r;
116
117 assert(c);
118 assert(key);
119
120 t = dns_scope_find_transaction(c->scope, key, true);
121 if (!t) {
122 r = dns_transaction_new(&t, c->scope, key);
123 if (r < 0)
124 return r;
125 } else {
126 if (set_contains(c->transactions, t))
127 return 0;
128 }
129
130 r = set_ensure_allocated(&c->transactions, NULL);
131 if (r < 0)
132 goto gc;
133
134 r = set_ensure_allocated(&t->notify_query_candidates, NULL);
135 if (r < 0)
136 goto gc;
137
138 r = set_put(t->notify_query_candidates, c);
139 if (r < 0)
140 goto gc;
141
142 r = set_put(c->transactions, t);
143 if (r < 0) {
144 (void) set_remove(t->notify_query_candidates, c);
145 goto gc;
146 }
147
148 return 1;
149
150 gc:
151 dns_transaction_gc(t);
152 return r;
153 }
154
155 static int dns_query_candidate_go(DnsQueryCandidate *c) {
156 DnsTransaction *t;
157 Iterator i;
158 int r;
159
160 assert(c);
161
162 /* Start the transactions that are not started yet */
163 SET_FOREACH(t, c->transactions, i) {
164 if (t->state != DNS_TRANSACTION_NULL)
165 continue;
166
167 r = dns_transaction_go(t);
168 if (r < 0)
169 return r;
170 }
171
172 return 0;
173 }
174
175 static DnsTransactionState dns_query_candidate_state(DnsQueryCandidate *c) {
176 DnsTransactionState state = DNS_TRANSACTION_NO_SERVERS;
177 DnsTransaction *t;
178 Iterator i;
179
180 assert(c);
181
182 if (c->error_code != 0)
183 return DNS_TRANSACTION_RESOURCES;
184
185 SET_FOREACH(t, c->transactions, i) {
186
187 switch (t->state) {
188
189 case DNS_TRANSACTION_NULL:
190 /* If there's a NULL transaction pending, then
191 * this means not all transactions where
192 * started yet, and we were called from within
193 * the stackframe that is supposed to start
194 * remaining transactions. In this case,
195 * simply claim the candidate is pending. */
196
197 case DNS_TRANSACTION_PENDING:
198 case DNS_TRANSACTION_VALIDATING:
199 /* If there's one transaction currently in
200 * VALIDATING state, then this means there's
201 * also one in PENDING state, hence we can
202 * return PENDING immediately. */
203 return DNS_TRANSACTION_PENDING;
204
205 case DNS_TRANSACTION_SUCCESS:
206 state = t->state;
207 break;
208
209 default:
210 if (state != DNS_TRANSACTION_SUCCESS)
211 state = t->state;
212
213 break;
214 }
215 }
216
217 return state;
218 }
219
220 static int dns_query_candidate_setup_transactions(DnsQueryCandidate *c) {
221 DnsQuestion *question;
222 DnsResourceKey *key;
223 int n = 0, r;
224
225 assert(c);
226
227 dns_query_candidate_stop(c);
228
229 question = dns_query_question_for_protocol(c->query, c->scope->protocol);
230
231 /* Create one transaction per question key */
232 DNS_QUESTION_FOREACH(key, question) {
233 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *new_key = NULL;
234
235 if (c->search_domain) {
236 r = dns_resource_key_new_append_suffix(&new_key, key, c->search_domain->name);
237 if (r < 0)
238 goto fail;
239 }
240
241 r = dns_query_candidate_add_transaction(c, new_key ?: key);
242 if (r < 0)
243 goto fail;
244
245 n++;
246 }
247
248 return n;
249
250 fail:
251 dns_query_candidate_stop(c);
252 return r;
253 }
254
255 void dns_query_candidate_notify(DnsQueryCandidate *c) {
256 DnsTransactionState state;
257 int r;
258
259 assert(c);
260
261 state = dns_query_candidate_state(c);
262
263 if (DNS_TRANSACTION_IS_LIVE(state))
264 return;
265
266 if (state != DNS_TRANSACTION_SUCCESS && c->search_domain) {
267
268 r = dns_query_candidate_next_search_domain(c);
269 if (r < 0)
270 goto fail;
271
272 if (r > 0) {
273 /* OK, there's another search domain to try, let's do so. */
274
275 r = dns_query_candidate_setup_transactions(c);
276 if (r < 0)
277 goto fail;
278
279 if (r > 0) {
280 /* New transactions where queued. Start them and wait */
281
282 r = dns_query_candidate_go(c);
283 if (r < 0)
284 goto fail;
285
286 return;
287 }
288 }
289
290 }
291
292 dns_query_ready(c->query);
293 return;
294
295 fail:
296 log_warning_errno(r, "Failed to follow search domains: %m");
297 c->error_code = r;
298 dns_query_ready(c->query);
299 }
300
301 static void dns_query_stop(DnsQuery *q) {
302 DnsQueryCandidate *c;
303
304 assert(q);
305
306 q->timeout_event_source = sd_event_source_unref(q->timeout_event_source);
307
308 LIST_FOREACH(candidates_by_query, c, q->candidates)
309 dns_query_candidate_stop(c);
310 }
311
312 static void dns_query_free_candidates(DnsQuery *q) {
313 assert(q);
314
315 while (q->candidates)
316 dns_query_candidate_free(q->candidates);
317 }
318
319 static void dns_query_reset_answer(DnsQuery *q) {
320 assert(q);
321
322 q->answer = dns_answer_unref(q->answer);
323 q->answer_rcode = 0;
324 q->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
325 q->answer_authenticated = false;
326 q->answer_protocol = _DNS_PROTOCOL_INVALID;
327 q->answer_family = AF_UNSPEC;
328 q->answer_search_domain = dns_search_domain_unref(q->answer_search_domain);
329 }
330
331 DnsQuery *dns_query_free(DnsQuery *q) {
332 if (!q)
333 return NULL;
334
335 while (q->auxiliary_queries)
336 dns_query_free(q->auxiliary_queries);
337
338 if (q->auxiliary_for) {
339 assert(q->auxiliary_for->n_auxiliary_queries > 0);
340 q->auxiliary_for->n_auxiliary_queries--;
341 LIST_REMOVE(auxiliary_queries, q->auxiliary_for->auxiliary_queries, q);
342 }
343
344 dns_query_free_candidates(q);
345
346 dns_question_unref(q->question_idna);
347 dns_question_unref(q->question_utf8);
348
349 dns_query_reset_answer(q);
350
351 sd_bus_message_unref(q->request);
352 sd_bus_track_unref(q->bus_track);
353
354 free(q->request_address_string);
355
356 if (q->manager) {
357 LIST_REMOVE(queries, q->manager->dns_queries, q);
358 q->manager->n_dns_queries--;
359 }
360
361 free(q);
362
363 return NULL;
364 }
365
366 int dns_query_new(
367 Manager *m,
368 DnsQuery **ret,
369 DnsQuestion *question_utf8,
370 DnsQuestion *question_idna,
371 int ifindex, uint64_t flags) {
372
373 _cleanup_(dns_query_freep) DnsQuery *q = NULL;
374 DnsResourceKey *key;
375 bool good = false;
376 int r;
377
378 assert(m);
379
380 if (dns_question_size(question_utf8) > 0) {
381 r = dns_question_is_valid_for_query(question_utf8);
382 if (r < 0)
383 return r;
384 if (r == 0)
385 return -EINVAL;
386
387 good = true;
388 }
389
390 /* If the IDNA and UTF8 questions are the same, merge their references */
391 r = dns_question_is_equal(question_idna, question_utf8);
392 if (r < 0)
393 return r;
394 if (r > 0)
395 question_idna = question_utf8;
396 else {
397 if (dns_question_size(question_idna) > 0) {
398 r = dns_question_is_valid_for_query(question_idna);
399 if (r < 0)
400 return r;
401 if (r == 0)
402 return -EINVAL;
403
404 good = true;
405 }
406 }
407
408 if (!good) /* don't allow empty queries */
409 return -EINVAL;
410
411 if (m->n_dns_queries >= QUERIES_MAX)
412 return -EBUSY;
413
414 q = new0(DnsQuery, 1);
415 if (!q)
416 return -ENOMEM;
417
418 q->question_utf8 = dns_question_ref(question_utf8);
419 q->question_idna = dns_question_ref(question_idna);
420 q->ifindex = ifindex;
421 q->flags = flags;
422 q->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
423 q->answer_protocol = _DNS_PROTOCOL_INVALID;
424 q->answer_family = AF_UNSPEC;
425
426 /* First dump UTF8 question */
427 DNS_QUESTION_FOREACH(key, question_utf8) {
428 _cleanup_free_ char *p = NULL;
429
430 r = dns_resource_key_to_string(key, &p);
431 if (r < 0)
432 return r;
433
434 log_debug("Looking up RR for %s.", strstrip(p));
435 }
436
437 /* And then dump the IDNA question, but only what hasn't been dumped already through the UTF8 question. */
438 DNS_QUESTION_FOREACH(key, question_idna) {
439 _cleanup_free_ char *p = NULL;
440
441 r = dns_question_contains(question_utf8, key);
442 if (r < 0)
443 return r;
444 if (r > 0)
445 continue;
446
447 r = dns_resource_key_to_string(key, &p);
448 if (r < 0)
449 return r;
450
451 log_debug("Looking up IDNA RR for %s.", strstrip(p));
452 }
453
454 LIST_PREPEND(queries, m->dns_queries, q);
455 m->n_dns_queries++;
456 q->manager = m;
457
458 if (ret)
459 *ret = q;
460 q = NULL;
461
462 return 0;
463 }
464
465 int dns_query_make_auxiliary(DnsQuery *q, DnsQuery *auxiliary_for) {
466 assert(q);
467 assert(auxiliary_for);
468
469 /* Ensure that that the query is not auxiliary yet, and
470 * nothing else is auxiliary to it either */
471 assert(!q->auxiliary_for);
472 assert(!q->auxiliary_queries);
473
474 /* Ensure that the unit we shall be made auxiliary for isn't
475 * auxiliary itself */
476 assert(!auxiliary_for->auxiliary_for);
477
478 if (auxiliary_for->n_auxiliary_queries >= AUXILIARY_QUERIES_MAX)
479 return -EAGAIN;
480
481 LIST_PREPEND(auxiliary_queries, auxiliary_for->auxiliary_queries, q);
482 q->auxiliary_for = auxiliary_for;
483
484 auxiliary_for->n_auxiliary_queries++;
485 return 0;
486 }
487
488 static void dns_query_complete(DnsQuery *q, DnsTransactionState state) {
489 assert(q);
490 assert(!DNS_TRANSACTION_IS_LIVE(state));
491 assert(DNS_TRANSACTION_IS_LIVE(q->state));
492
493 /* Note that this call might invalidate the query. Callers
494 * should hence not attempt to access the query or transaction
495 * after calling this function. */
496
497 q->state = state;
498
499 dns_query_stop(q);
500 if (q->complete)
501 q->complete(q);
502 }
503
504 static int on_query_timeout(sd_event_source *s, usec_t usec, void *userdata) {
505 DnsQuery *q = userdata;
506
507 assert(s);
508 assert(q);
509
510 dns_query_complete(q, DNS_TRANSACTION_TIMEOUT);
511 return 0;
512 }
513
514 static int dns_query_add_candidate(DnsQuery *q, DnsScope *s) {
515 DnsQueryCandidate *c;
516 int r;
517
518 assert(q);
519 assert(s);
520
521 r = dns_query_candidate_new(&c, q, s);
522 if (r < 0)
523 return r;
524
525 /* If this a single-label domain on DNS, we might append a suitable search domain first. */
526 if ((q->flags & SD_RESOLVED_NO_SEARCH) == 0) {
527 r = dns_scope_name_needs_search_domain(s, dns_question_first_name(q->question_idna));
528 if (r < 0)
529 goto fail;
530 if (r > 0) {
531 /* OK, we need a search domain now. Let's find one for this scope */
532
533 r = dns_query_candidate_next_search_domain(c);
534 if (r <= 0) /* if there's no search domain, then we won't add any transaction. */
535 goto fail;
536 }
537 }
538
539 r = dns_query_candidate_setup_transactions(c);
540 if (r < 0)
541 goto fail;
542
543 return 0;
544
545 fail:
546 dns_query_candidate_free(c);
547 return r;
548 }
549
550 static int SYNTHESIZE_IFINDEX(int ifindex) {
551
552 /* When the caller asked for resolving on a specific
553 * interface, we synthesize the answer for that
554 * interface. However, if nothing specific was claimed and we
555 * only return localhost RRs, we synthesize the answer for
556 * localhost. */
557
558 if (ifindex > 0)
559 return ifindex;
560
561 return LOOPBACK_IFINDEX;
562 }
563
564 static int SYNTHESIZE_FAMILY(uint64_t flags) {
565
566 /* Picks an address family depending on set flags. This is
567 * purely for synthesized answers, where the family we return
568 * for the reply should match what was requested in the
569 * question, even though we are synthesizing the answer
570 * here. */
571
572 if (!(flags & SD_RESOLVED_DNS)) {
573 if (flags & SD_RESOLVED_LLMNR_IPV4)
574 return AF_INET;
575 if (flags & SD_RESOLVED_LLMNR_IPV6)
576 return AF_INET6;
577 }
578
579 return AF_UNSPEC;
580 }
581
582 static DnsProtocol SYNTHESIZE_PROTOCOL(uint64_t flags) {
583
584 /* Similar as SYNTHESIZE_FAMILY() but does this for the
585 * protocol. If resolving via DNS was requested, we claim it
586 * was DNS. Similar, if nothing specific was
587 * requested. However, if only resolving via LLMNR was
588 * requested we return that. */
589
590 if (flags & SD_RESOLVED_DNS)
591 return DNS_PROTOCOL_DNS;
592 if (flags & SD_RESOLVED_LLMNR)
593 return DNS_PROTOCOL_LLMNR;
594
595 return DNS_PROTOCOL_DNS;
596 }
597
598 static int dns_type_to_af(uint16_t t) {
599 switch (t) {
600
601 case DNS_TYPE_A:
602 return AF_INET;
603
604 case DNS_TYPE_AAAA:
605 return AF_INET6;
606
607 case DNS_TYPE_ANY:
608 return AF_UNSPEC;
609
610 default:
611 return -EINVAL;
612 }
613 }
614
615 static int synthesize_localhost_rr(DnsQuery *q, const DnsResourceKey *key, DnsAnswer **answer) {
616 int r;
617
618 assert(q);
619 assert(key);
620 assert(answer);
621
622 r = dns_answer_reserve(answer, 2);
623 if (r < 0)
624 return r;
625
626 if (IN_SET(key->type, DNS_TYPE_A, DNS_TYPE_ANY)) {
627 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
628
629 rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, DNS_RESOURCE_KEY_NAME(key));
630 if (!rr)
631 return -ENOMEM;
632
633 rr->a.in_addr.s_addr = htobe32(INADDR_LOOPBACK);
634
635 r = dns_answer_add(*answer, rr, SYNTHESIZE_IFINDEX(q->ifindex), DNS_ANSWER_AUTHENTICATED);
636 if (r < 0)
637 return r;
638 }
639
640 if (IN_SET(key->type, DNS_TYPE_AAAA, DNS_TYPE_ANY)) {
641 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
642
643 rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_AAAA, DNS_RESOURCE_KEY_NAME(key));
644 if (!rr)
645 return -ENOMEM;
646
647 rr->aaaa.in6_addr = in6addr_loopback;
648
649 r = dns_answer_add(*answer, rr, SYNTHESIZE_IFINDEX(q->ifindex), DNS_ANSWER_AUTHENTICATED);
650 if (r < 0)
651 return r;
652 }
653
654 return 0;
655 }
656
657 static int answer_add_ptr(DnsAnswer **answer, const char *from, const char *to, int ifindex, DnsAnswerFlags flags) {
658 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
659
660 rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_PTR, from);
661 if (!rr)
662 return -ENOMEM;
663
664 rr->ptr.name = strdup(to);
665 if (!rr->ptr.name)
666 return -ENOMEM;
667
668 return dns_answer_add(*answer, rr, ifindex, flags);
669 }
670
671 static int synthesize_localhost_ptr(DnsQuery *q, const DnsResourceKey *key, DnsAnswer **answer) {
672 int r;
673
674 assert(q);
675 assert(key);
676 assert(answer);
677
678 if (IN_SET(key->type, DNS_TYPE_PTR, DNS_TYPE_ANY)) {
679 r = dns_answer_reserve(answer, 1);
680 if (r < 0)
681 return r;
682
683 r = answer_add_ptr(answer, DNS_RESOURCE_KEY_NAME(key), "localhost", SYNTHESIZE_IFINDEX(q->ifindex), DNS_ANSWER_AUTHENTICATED);
684 if (r < 0)
685 return r;
686 }
687
688 return 0;
689 }
690
691 static int answer_add_addresses_rr(
692 DnsAnswer **answer,
693 const char *name,
694 struct local_address *addresses,
695 unsigned n_addresses) {
696
697 unsigned j;
698 int r;
699
700 assert(answer);
701 assert(name);
702
703 r = dns_answer_reserve(answer, n_addresses);
704 if (r < 0)
705 return r;
706
707 for (j = 0; j < n_addresses; j++) {
708 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
709
710 r = dns_resource_record_new_address(&rr, addresses[j].family, &addresses[j].address, name);
711 if (r < 0)
712 return r;
713
714 r = dns_answer_add(*answer, rr, addresses[j].ifindex, DNS_ANSWER_AUTHENTICATED);
715 if (r < 0)
716 return r;
717 }
718
719 return 0;
720 }
721
722 static int answer_add_addresses_ptr(
723 DnsAnswer **answer,
724 const char *name,
725 struct local_address *addresses,
726 unsigned n_addresses,
727 int af, const union in_addr_union *match) {
728
729 unsigned j;
730 int r;
731
732 assert(answer);
733 assert(name);
734
735 for (j = 0; j < n_addresses; j++) {
736 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
737
738 if (af != AF_UNSPEC) {
739
740 if (addresses[j].family != af)
741 continue;
742
743 if (match && !in_addr_equal(af, match, &addresses[j].address))
744 continue;
745 }
746
747 r = dns_answer_reserve(answer, 1);
748 if (r < 0)
749 return r;
750
751 r = dns_resource_record_new_reverse(&rr, addresses[j].family, &addresses[j].address, name);
752 if (r < 0)
753 return r;
754
755 r = dns_answer_add(*answer, rr, addresses[j].ifindex, DNS_ANSWER_AUTHENTICATED);
756 if (r < 0)
757 return r;
758 }
759
760 return 0;
761 }
762
763 static int synthesize_system_hostname_rr(DnsQuery *q, const DnsResourceKey *key, DnsAnswer **answer) {
764 _cleanup_free_ struct local_address *addresses = NULL;
765 int n = 0, af;
766
767 assert(q);
768 assert(key);
769 assert(answer);
770
771 af = dns_type_to_af(key->type);
772 if (af >= 0) {
773 n = local_addresses(q->manager->rtnl, q->ifindex, af, &addresses);
774 if (n < 0)
775 return n;
776
777 if (n == 0) {
778 struct local_address buffer[2];
779
780 /* If we have no local addresses then use ::1
781 * and 127.0.0.2 as local ones. */
782
783 if (af == AF_INET || af == AF_UNSPEC)
784 buffer[n++] = (struct local_address) {
785 .family = AF_INET,
786 .ifindex = SYNTHESIZE_IFINDEX(q->ifindex),
787 .address.in.s_addr = htobe32(0x7F000002),
788 };
789
790 if (af == AF_INET6 || af == AF_UNSPEC)
791 buffer[n++] = (struct local_address) {
792 .family = AF_INET6,
793 .ifindex = SYNTHESIZE_IFINDEX(q->ifindex),
794 .address.in6 = in6addr_loopback,
795 };
796
797 return answer_add_addresses_rr(answer, DNS_RESOURCE_KEY_NAME(key), buffer, n);
798 }
799 }
800
801 return answer_add_addresses_rr(answer, DNS_RESOURCE_KEY_NAME(key), addresses, n);
802 }
803
804 static int synthesize_system_hostname_ptr(DnsQuery *q, int af, const union in_addr_union *address, DnsAnswer **answer) {
805 _cleanup_free_ struct local_address *addresses = NULL;
806 int n, r;
807
808 assert(q);
809 assert(address);
810 assert(answer);
811
812 if (af == AF_INET && address->in.s_addr == htobe32(0x7F000002)) {
813
814 /* Always map the IPv4 address 127.0.0.2 to the local
815 * hostname, in addition to "localhost": */
816
817 r = dns_answer_reserve(answer, 3);
818 if (r < 0)
819 return r;
820
821 r = answer_add_ptr(answer, "2.0.0.127.in-addr.arpa", q->manager->llmnr_hostname, SYNTHESIZE_IFINDEX(q->ifindex), DNS_ANSWER_AUTHENTICATED);
822 if (r < 0)
823 return r;
824
825 r = answer_add_ptr(answer, "2.0.0.127.in-addr.arpa", q->manager->mdns_hostname, SYNTHESIZE_IFINDEX(q->ifindex), DNS_ANSWER_AUTHENTICATED);
826 if (r < 0)
827 return r;
828
829 r = answer_add_ptr(answer, "2.0.0.127.in-addr.arpa", "localhost", SYNTHESIZE_IFINDEX(q->ifindex), DNS_ANSWER_AUTHENTICATED);
830 if (r < 0)
831 return r;
832
833 return 0;
834 }
835
836 n = local_addresses(q->manager->rtnl, q->ifindex, af, &addresses);
837 if (n < 0)
838 return n;
839
840 r = answer_add_addresses_ptr(answer, q->manager->llmnr_hostname, addresses, n, af, address);
841 if (r < 0)
842 return r;
843
844 return answer_add_addresses_ptr(answer, q->manager->mdns_hostname, addresses, n, af, address);
845 }
846
847 static int synthesize_gateway_rr(DnsQuery *q, const DnsResourceKey *key, DnsAnswer **answer) {
848 _cleanup_free_ struct local_address *addresses = NULL;
849 int n = 0, af;
850
851 assert(q);
852 assert(key);
853 assert(answer);
854
855 af = dns_type_to_af(key->type);
856 if (af >= 0) {
857 n = local_gateways(q->manager->rtnl, q->ifindex, af, &addresses);
858 if (n < 0)
859 return n;
860 }
861
862 return answer_add_addresses_rr(answer, DNS_RESOURCE_KEY_NAME(key), addresses, n);
863 }
864
865 static int synthesize_gateway_ptr(DnsQuery *q, int af, const union in_addr_union *address, DnsAnswer **answer) {
866 _cleanup_free_ struct local_address *addresses = NULL;
867 int n;
868
869 assert(q);
870 assert(address);
871 assert(answer);
872
873 n = local_gateways(q->manager->rtnl, q->ifindex, af, &addresses);
874 if (n < 0)
875 return n;
876
877 return answer_add_addresses_ptr(answer, "gateway", addresses, n, af, address);
878 }
879
880 static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) {
881 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
882 DnsResourceKey *key;
883 int r;
884
885 assert(q);
886 assert(state);
887
888 /* Tries to synthesize localhost RR replies where appropriate */
889
890 if (!IN_SET(*state,
891 DNS_TRANSACTION_RCODE_FAILURE,
892 DNS_TRANSACTION_NO_SERVERS,
893 DNS_TRANSACTION_TIMEOUT,
894 DNS_TRANSACTION_ATTEMPTS_MAX_REACHED))
895 return 0;
896
897 DNS_QUESTION_FOREACH(key, q->question_utf8) {
898 union in_addr_union address;
899 const char *name;
900 int af;
901
902 if (key->class != DNS_CLASS_IN &&
903 key->class != DNS_CLASS_ANY)
904 continue;
905
906 name = DNS_RESOURCE_KEY_NAME(key);
907
908 if (is_localhost(name)) {
909
910 r = synthesize_localhost_rr(q, key, &answer);
911 if (r < 0)
912 return log_error_errno(r, "Failed to synthesize localhost RRs: %m");
913
914 } else if (manager_is_own_hostname(q->manager, name)) {
915
916 r = synthesize_system_hostname_rr(q, key, &answer);
917 if (r < 0)
918 return log_error_errno(r, "Failed to synthesize system hostname RRs: %m");
919
920 } else if (is_gateway_hostname(name)) {
921
922 r = synthesize_gateway_rr(q, key, &answer);
923 if (r < 0)
924 return log_error_errno(r, "Failed to synthesize gateway RRs: %m");
925
926 } else if ((dns_name_endswith(name, "127.in-addr.arpa") > 0 && dns_name_equal(name, "2.0.0.127.in-addr.arpa") == 0) ||
927 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) {
928
929 r = synthesize_localhost_ptr(q, key, &answer);
930 if (r < 0)
931 return log_error_errno(r, "Failed to synthesize localhost PTR RRs: %m");
932
933 } else if (dns_name_address(name, &af, &address) > 0) {
934
935 r = synthesize_system_hostname_ptr(q, af, &address, &answer);
936 if (r < 0)
937 return log_error_errno(r, "Failed to synthesize system hostname PTR RR: %m");
938
939 r = synthesize_gateway_ptr(q, af, &address, &answer);
940 if (r < 0)
941 return log_error_errno(r, "Failed to synthesize gateway hostname PTR RR: %m");
942 }
943 }
944
945 if (!answer)
946 return 0;
947
948 dns_answer_unref(q->answer);
949 q->answer = answer;
950 answer = NULL;
951
952 q->answer_rcode = DNS_RCODE_SUCCESS;
953 q->answer_protocol = SYNTHESIZE_PROTOCOL(q->flags);
954 q->answer_family = SYNTHESIZE_FAMILY(q->flags);
955
956 *state = DNS_TRANSACTION_SUCCESS;
957
958 return 1;
959 }
960
961 int dns_query_go(DnsQuery *q) {
962 DnsScopeMatch found = DNS_SCOPE_NO;
963 DnsScope *s, *first = NULL;
964 DnsQueryCandidate *c;
965 int r;
966
967 assert(q);
968
969 if (q->state != DNS_TRANSACTION_NULL)
970 return 0;
971
972 LIST_FOREACH(scopes, s, q->manager->dns_scopes) {
973 DnsScopeMatch match;
974 const char *name;
975
976 name = dns_question_first_name(dns_query_question_for_protocol(q, s->protocol));
977 if (!name)
978 continue;
979
980 match = dns_scope_good_domain(s, q->ifindex, q->flags, name);
981 if (match < 0)
982 return match;
983
984 if (match == DNS_SCOPE_NO)
985 continue;
986
987 found = match;
988
989 if (match == DNS_SCOPE_YES) {
990 first = s;
991 break;
992 } else {
993 assert(match == DNS_SCOPE_MAYBE);
994
995 if (!first)
996 first = s;
997 }
998 }
999
1000 if (found == DNS_SCOPE_NO) {
1001 DnsTransactionState state = DNS_TRANSACTION_NO_SERVERS;
1002
1003 dns_query_synthesize_reply(q, &state);
1004 dns_query_complete(q, state);
1005 return 1;
1006 }
1007
1008 r = dns_query_add_candidate(q, first);
1009 if (r < 0)
1010 goto fail;
1011
1012 LIST_FOREACH(scopes, s, first->scopes_next) {
1013 DnsScopeMatch match;
1014 const char *name;
1015
1016 name = dns_question_first_name(dns_query_question_for_protocol(q, s->protocol));
1017 if (!name)
1018 continue;
1019
1020 match = dns_scope_good_domain(s, q->ifindex, q->flags, name);
1021 if (match < 0)
1022 goto fail;
1023
1024 if (match != found)
1025 continue;
1026
1027 r = dns_query_add_candidate(q, s);
1028 if (r < 0)
1029 goto fail;
1030 }
1031
1032 q->answer = dns_answer_unref(q->answer);
1033 q->answer_rcode = 0;
1034 q->answer_family = AF_UNSPEC;
1035 q->answer_protocol = _DNS_PROTOCOL_INVALID;
1036
1037 r = sd_event_add_time(
1038 q->manager->event,
1039 &q->timeout_event_source,
1040 clock_boottime_or_monotonic(),
1041 now(clock_boottime_or_monotonic()) + QUERY_TIMEOUT_USEC, 0,
1042 on_query_timeout, q);
1043 if (r < 0)
1044 goto fail;
1045
1046 (void) sd_event_source_set_description(q->timeout_event_source, "query-timeout");
1047
1048 q->state = DNS_TRANSACTION_PENDING;
1049 q->block_ready++;
1050
1051 /* Start the transactions */
1052 LIST_FOREACH(candidates_by_query, c, q->candidates) {
1053 r = dns_query_candidate_go(c);
1054 if (r < 0) {
1055 q->block_ready--;
1056 goto fail;
1057 }
1058 }
1059
1060 q->block_ready--;
1061 dns_query_ready(q);
1062
1063 return 1;
1064
1065 fail:
1066 dns_query_stop(q);
1067 return r;
1068 }
1069
1070 static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) {
1071 DnsTransactionState state = DNS_TRANSACTION_NO_SERVERS;
1072 bool has_authenticated = false, has_non_authenticated = false;
1073 DnssecResult dnssec_result_authenticated = _DNSSEC_RESULT_INVALID, dnssec_result_non_authenticated = _DNSSEC_RESULT_INVALID;
1074 DnsTransaction *t;
1075 Iterator i;
1076 int r;
1077
1078 assert(q);
1079
1080 if (!c) {
1081 dns_query_synthesize_reply(q, &state);
1082 dns_query_complete(q, state);
1083 return;
1084 }
1085
1086 SET_FOREACH(t, c->transactions, i) {
1087
1088 switch (t->state) {
1089
1090 case DNS_TRANSACTION_SUCCESS: {
1091 /* We found a successfuly reply, merge it into the answer */
1092 r = dns_answer_extend(&q->answer, t->answer);
1093 if (r < 0) {
1094 dns_query_complete(q, DNS_TRANSACTION_RESOURCES);
1095 return;
1096 }
1097
1098 q->answer_rcode = t->answer_rcode;
1099
1100 if (t->answer_authenticated) {
1101 has_authenticated = true;
1102 dnssec_result_authenticated = t->answer_dnssec_result;
1103 } else {
1104 has_non_authenticated = true;
1105 dnssec_result_non_authenticated = t->answer_dnssec_result;
1106 }
1107
1108 state = DNS_TRANSACTION_SUCCESS;
1109 break;
1110 }
1111
1112 case DNS_TRANSACTION_NULL:
1113 case DNS_TRANSACTION_PENDING:
1114 case DNS_TRANSACTION_VALIDATING:
1115 case DNS_TRANSACTION_ABORTED:
1116 /* Ignore transactions that didn't complete */
1117 continue;
1118
1119 default:
1120 /* Any kind of failure? Store the data away,
1121 * if there's nothing stored yet. */
1122
1123 if (state == DNS_TRANSACTION_SUCCESS)
1124 continue;
1125
1126 q->answer = dns_answer_unref(q->answer);
1127 q->answer_rcode = t->answer_rcode;
1128 q->answer_dnssec_result = t->answer_dnssec_result;
1129
1130 state = t->state;
1131 break;
1132 }
1133 }
1134
1135 if (state == DNS_TRANSACTION_SUCCESS) {
1136 q->answer_authenticated = has_authenticated && !has_non_authenticated;
1137 q->answer_dnssec_result = q->answer_authenticated ? dnssec_result_authenticated : dnssec_result_non_authenticated;
1138 }
1139
1140 q->answer_protocol = c->scope->protocol;
1141 q->answer_family = c->scope->family;
1142
1143 dns_search_domain_unref(q->answer_search_domain);
1144 q->answer_search_domain = dns_search_domain_ref(c->search_domain);
1145
1146 dns_query_synthesize_reply(q, &state);
1147 dns_query_complete(q, state);
1148 }
1149
1150 void dns_query_ready(DnsQuery *q) {
1151
1152 DnsQueryCandidate *bad = NULL, *c;
1153 bool pending = false;
1154
1155 assert(q);
1156 assert(DNS_TRANSACTION_IS_LIVE(q->state));
1157
1158 /* Note that this call might invalidate the query. Callers
1159 * should hence not attempt to access the query or transaction
1160 * after calling this function, unless the block_ready
1161 * counter was explicitly bumped before doing so. */
1162
1163 if (q->block_ready > 0)
1164 return;
1165
1166 LIST_FOREACH(candidates_by_query, c, q->candidates) {
1167 DnsTransactionState state;
1168
1169 state = dns_query_candidate_state(c);
1170 switch (state) {
1171
1172 case DNS_TRANSACTION_SUCCESS:
1173 /* One of the candidates is successful,
1174 * let's use it, and copy its data out */
1175 dns_query_accept(q, c);
1176 return;
1177
1178 case DNS_TRANSACTION_NULL:
1179 case DNS_TRANSACTION_PENDING:
1180 case DNS_TRANSACTION_VALIDATING:
1181 /* One of the candidates is still going on,
1182 * let's maybe wait for it */
1183 pending = true;
1184 break;
1185
1186 default:
1187 /* Any kind of failure */
1188 bad = c;
1189 break;
1190 }
1191 }
1192
1193 if (pending)
1194 return;
1195
1196 dns_query_accept(q, bad);
1197 }
1198
1199 static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname) {
1200 _cleanup_(dns_question_unrefp) DnsQuestion *nq_idna = NULL, *nq_utf8 = NULL;
1201 int r, k;
1202
1203 assert(q);
1204
1205 q->n_cname_redirects ++;
1206 if (q->n_cname_redirects > CNAME_MAX)
1207 return -ELOOP;
1208
1209 r = dns_question_cname_redirect(q->question_idna, cname, &nq_idna);
1210 if (r < 0)
1211 return r;
1212 else if (r > 0)
1213 log_debug("Following CNAME/DNAME %s → %s.", dns_question_first_name(q->question_idna), dns_question_first_name(nq_idna));
1214
1215 k = dns_question_is_equal(q->question_idna, q->question_utf8);
1216 if (k < 0)
1217 return r;
1218 if (k > 0) {
1219 /* Same question? Shortcut new question generation */
1220 nq_utf8 = dns_question_ref(nq_idna);
1221 k = r;
1222 } else {
1223 k = dns_question_cname_redirect(q->question_utf8, cname, &nq_utf8);
1224 if (k < 0)
1225 return k;
1226 else if (k > 0)
1227 log_debug("Following UTF8 CNAME/DNAME %s → %s.", dns_question_first_name(q->question_utf8), dns_question_first_name(nq_utf8));
1228 }
1229
1230 if (r == 0 && k == 0) /* No actual cname happened? */
1231 return -ELOOP;
1232
1233 dns_question_unref(q->question_idna);
1234 q->question_idna = nq_idna;
1235 nq_idna = NULL;
1236
1237 dns_question_unref(q->question_utf8);
1238 q->question_utf8 = nq_utf8;
1239 nq_utf8 = NULL;
1240
1241 dns_query_free_candidates(q);
1242 dns_query_reset_answer(q);
1243 q->state = DNS_TRANSACTION_NULL;
1244
1245 /* Turn off searching for the new name */
1246 q->flags |= SD_RESOLVED_NO_SEARCH;
1247
1248 return 0;
1249 }
1250
1251 int dns_query_process_cname(DnsQuery *q) {
1252 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *cname = NULL;
1253 DnsQuestion *question;
1254 DnsResourceRecord *rr;
1255 int r;
1256
1257 assert(q);
1258
1259 if (!IN_SET(q->state, DNS_TRANSACTION_SUCCESS, DNS_TRANSACTION_NULL))
1260 return DNS_QUERY_NOMATCH;
1261
1262 question = dns_query_question_for_protocol(q, q->answer_protocol);
1263
1264 DNS_ANSWER_FOREACH(rr, q->answer) {
1265 r = dns_question_matches_rr(question, rr, DNS_SEARCH_DOMAIN_NAME(q->answer_search_domain));
1266 if (r < 0)
1267 return r;
1268 if (r > 0)
1269 return DNS_QUERY_MATCH; /* The answer matches directly, no need to follow cnames */
1270
1271 r = dns_question_matches_cname_or_dname(question, rr, DNS_SEARCH_DOMAIN_NAME(q->answer_search_domain));
1272 if (r < 0)
1273 return r;
1274 if (r > 0 && !cname)
1275 cname = dns_resource_record_ref(rr);
1276 }
1277
1278 if (!cname)
1279 return DNS_QUERY_NOMATCH; /* No match and no cname to follow */
1280
1281 if (q->flags & SD_RESOLVED_NO_CNAME)
1282 return -ELOOP;
1283
1284 /* OK, let's actually follow the CNAME */
1285 r = dns_query_cname_redirect(q, cname);
1286 if (r < 0)
1287 return r;
1288
1289 /* Let's see if the answer can already answer the new
1290 * redirected question */
1291 r = dns_query_process_cname(q);
1292 if (r != DNS_QUERY_NOMATCH)
1293 return r;
1294
1295 /* OK, it cannot, let's begin with the new query */
1296 r = dns_query_go(q);
1297 if (r < 0)
1298 return r;
1299
1300 return DNS_QUERY_RESTARTED; /* We restarted the query for a new cname */
1301 }
1302
1303 static int on_bus_track(sd_bus_track *t, void *userdata) {
1304 DnsQuery *q = userdata;
1305
1306 assert(t);
1307 assert(q);
1308
1309 log_debug("Client of active query vanished, aborting query.");
1310 dns_query_complete(q, DNS_TRANSACTION_ABORTED);
1311 return 0;
1312 }
1313
1314 int dns_query_bus_track(DnsQuery *q, sd_bus_message *m) {
1315 int r;
1316
1317 assert(q);
1318 assert(m);
1319
1320 if (!q->bus_track) {
1321 r = sd_bus_track_new(sd_bus_message_get_bus(m), &q->bus_track, on_bus_track, q);
1322 if (r < 0)
1323 return r;
1324 }
1325
1326 r = sd_bus_track_add_sender(q->bus_track, m);
1327 if (r < 0)
1328 return r;
1329
1330 return 0;
1331 }
1332
1333 DnsQuestion* dns_query_question_for_protocol(DnsQuery *q, DnsProtocol protocol) {
1334 assert(q);
1335
1336 switch (protocol) {
1337
1338 case DNS_PROTOCOL_DNS:
1339 return q->question_idna;
1340
1341 case DNS_PROTOCOL_MDNS:
1342 case DNS_PROTOCOL_LLMNR:
1343 return q->question_utf8;
1344
1345 default:
1346 return NULL;
1347 }
1348 }
1349
1350 const char *dns_query_string(DnsQuery *q) {
1351 const char *name;
1352 int r;
1353
1354 /* Returns a somewhat useful human-readable lookup key string for this query */
1355
1356 if (q->request_address_string)
1357 return q->request_address_string;
1358
1359 if (q->request_address_valid) {
1360 r = in_addr_to_string(q->request_family, &q->request_address, &q->request_address_string);
1361 if (r >= 0)
1362 return q->request_address_string;
1363 }
1364
1365 name = dns_question_first_name(q->question_utf8);
1366 if (name)
1367 return name;
1368
1369 return dns_question_first_name(q->question_idna);
1370 }