]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-transaction.c
resolved: merge two comments
[thirdparty/systemd.git] / src / resolve / resolved-dns-transaction.c
CommitLineData
ec2c5e43
LP
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 "af-list.h"
b5efdb8a 23#include "alloc-util.h"
f52e61da 24#include "dns-domain.h"
3ffd4af2
LP
25#include "fd-util.h"
26#include "random-util.h"
7778dfff 27#include "resolved-dns-cache.h"
3ffd4af2
LP
28#include "resolved-dns-transaction.h"
29#include "resolved-llmnr.h"
8b43440b 30#include "string-table.h"
ec2c5e43
LP
31
32DnsTransaction* dns_transaction_free(DnsTransaction *t) {
801ad6a6 33 DnsQueryCandidate *c;
ec2c5e43 34 DnsZoneItem *i;
547973de 35 DnsTransaction *z;
ec2c5e43
LP
36
37 if (!t)
38 return NULL;
39
40 sd_event_source_unref(t->timeout_event_source);
41
ec2c5e43
LP
42 dns_packet_unref(t->sent);
43 dns_packet_unref(t->received);
ae6a4bbf
LP
44
45 dns_answer_unref(t->answer);
ec2c5e43 46
4667e00a
LP
47 sd_event_source_unref(t->dns_udp_event_source);
48 safe_close(t->dns_udp_fd);
d20b1667 49
8300ba21 50 dns_server_unref(t->server);
ec2c5e43
LP
51 dns_stream_free(t->stream);
52
53 if (t->scope) {
f9ebb22a
LP
54 hashmap_remove_value(t->scope->transactions_by_key, t->key, t);
55 LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
ec2c5e43
LP
56
57 if (t->id != 0)
58 hashmap_remove(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id));
59 }
60
da0c630e
LP
61 dns_resource_key_unref(t->key);
62
547973de 63 while ((c = set_steal_first(t->notify_query_candidates)))
801ad6a6 64 set_remove(c->transactions, t);
547973de 65 set_free(t->notify_query_candidates);
801ad6a6 66
547973de 67 while ((i = set_steal_first(t->notify_zone_items)))
ec2c5e43 68 i->probe_transaction = NULL;
547973de
LP
69 set_free(t->notify_zone_items);
70
71 while ((z = set_steal_first(t->notify_transactions)))
72 set_remove(z->dnssec_transactions, t);
73 set_free(t->notify_transactions);
74
75 while ((z = set_steal_first(t->dnssec_transactions))) {
76 set_remove(z->notify_transactions, t);
77 dns_transaction_gc(z);
78 }
79 set_free(t->dnssec_transactions);
80
81 dns_answer_unref(t->validated_keys);
ec2c5e43 82
a5784c49 83 free(t->key_string);
ec2c5e43
LP
84 free(t);
85 return NULL;
86}
87
88DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_free);
89
90void dns_transaction_gc(DnsTransaction *t) {
91 assert(t);
92
93 if (t->block_gc > 0)
94 return;
95
547973de
LP
96 if (set_isempty(t->notify_query_candidates) &&
97 set_isempty(t->notify_zone_items) &&
98 set_isempty(t->notify_transactions))
ec2c5e43
LP
99 dns_transaction_free(t);
100}
101
f52e61da 102int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key) {
ec2c5e43
LP
103 _cleanup_(dns_transaction_freep) DnsTransaction *t = NULL;
104 int r;
105
106 assert(ret);
107 assert(s);
f52e61da 108 assert(key);
ec2c5e43 109
9eae2bf3 110 /* Don't allow looking up invalid or pseudo RRs */
c463eb78 111 if (!dns_type_is_valid_query(key->type))
9eae2bf3
LP
112 return -EINVAL;
113
114 /* We only support the IN class */
c463eb78 115 if (key->class != DNS_CLASS_IN && key->class != DNS_CLASS_ANY)
9eae2bf3
LP
116 return -EOPNOTSUPP;
117
d5099efc 118 r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL);
ec2c5e43
LP
119 if (r < 0)
120 return r;
121
f9ebb22a 122 r = hashmap_ensure_allocated(&s->transactions_by_key, &dns_resource_key_hash_ops);
da0c630e
LP
123 if (r < 0)
124 return r;
125
ec2c5e43
LP
126 t = new0(DnsTransaction, 1);
127 if (!t)
128 return -ENOMEM;
129
4667e00a 130 t->dns_udp_fd = -1;
c3bc53e6 131 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
547973de 132 t->dnssec_result = _DNSSEC_RESULT_INVALID;
f52e61da 133 t->key = dns_resource_key_ref(key);
ec2c5e43 134
da0c630e 135 /* Find a fresh, unused transaction id */
ec2c5e43
LP
136 do
137 random_bytes(&t->id, sizeof(t->id));
138 while (t->id == 0 ||
139 hashmap_get(s->manager->dns_transactions, UINT_TO_PTR(t->id)));
140
141 r = hashmap_put(s->manager->dns_transactions, UINT_TO_PTR(t->id), t);
142 if (r < 0) {
143 t->id = 0;
144 return r;
145 }
146
f9ebb22a 147 r = hashmap_replace(s->transactions_by_key, t->key, t);
da0c630e
LP
148 if (r < 0) {
149 hashmap_remove(s->manager->dns_transactions, UINT_TO_PTR(t->id));
150 return r;
151 }
152
f9ebb22a 153 LIST_PREPEND(transactions_by_scope, s->transactions, t);
ec2c5e43
LP
154 t->scope = s;
155
156 if (ret)
157 *ret = t;
158
159 t = NULL;
160
161 return 0;
162}
163
164static void dns_transaction_stop(DnsTransaction *t) {
165 assert(t);
166
167 t->timeout_event_source = sd_event_source_unref(t->timeout_event_source);
168 t->stream = dns_stream_free(t->stream);
ae6a4bbf
LP
169
170 /* Note that we do not drop the UDP socket here, as we want to
171 * reuse it to repeat the interaction. */
ec2c5e43
LP
172}
173
174static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
2fb3034c 175 _cleanup_free_ char *pretty = NULL;
ec2c5e43 176 DnsZoneItem *z;
ec2c5e43
LP
177
178 assert(t);
179 assert(p);
180
181 if (manager_our_packet(t->scope->manager, p) != 0)
182 return;
183
2fb3034c
LP
184 in_addr_to_string(p->family, &p->sender, &pretty);
185
a5784c49
LP
186 log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s got tentative packet from %s.",
187 t->id,
188 dns_transaction_key_string(t),
ec2c5e43
LP
189 dns_protocol_to_string(t->scope->protocol),
190 t->scope->link ? t->scope->link->name : "*",
2fb3034c
LP
191 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
192 pretty);
ec2c5e43 193
a4076574
LP
194 /* RFC 4795, Section 4.1 says that the peer with the
195 * lexicographically smaller IP address loses */
4d91eec4
LP
196 if (memcmp(&p->sender, &p->destination, FAMILY_ADDRESS_SIZE(p->family)) >= 0) {
197 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
a4076574
LP
198 return;
199 }
200
4d91eec4 201 log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
a4076574 202
ec2c5e43 203 t->block_gc++;
547973de 204 while ((z = set_first(t->notify_zone_items))) {
3ef64445
LP
205 /* First, make sure the zone item drops the reference
206 * to us */
207 dns_zone_item_probe_stop(z);
208
209 /* Secondly, report this as conflict, so that we might
210 * look for a different hostname */
ec2c5e43 211 dns_zone_item_conflict(z);
3ef64445 212 }
ec2c5e43
LP
213 t->block_gc--;
214
215 dns_transaction_gc(t);
216}
217
218void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
801ad6a6 219 DnsQueryCandidate *c;
ec2c5e43 220 DnsZoneItem *z;
547973de 221 DnsTransaction *d;
ec2c5e43
LP
222 Iterator i;
223
224 assert(t);
547973de 225 assert(!DNS_TRANSACTION_IS_LIVE(state));
e56187ca 226
ec2c5e43
LP
227 /* Note that this call might invalidate the query. Callers
228 * should hence not attempt to access the query or transaction
229 * after calling this function. */
230
a5784c49
LP
231 log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s now complete with <%s> from %s (%s).",
232 t->id,
233 dns_transaction_key_string(t),
ec2c5e43
LP
234 dns_protocol_to_string(t->scope->protocol),
235 t->scope->link ? t->scope->link->name : "*",
236 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
c3bc53e6 237 dns_transaction_state_to_string(state),
a5784c49
LP
238 t->answer_source < 0 ? "none" : dns_transaction_source_to_string(t->answer_source),
239 t->answer_authenticated ? "authenticated" : "unsigned");
ec2c5e43
LP
240
241 t->state = state;
242
243 dns_transaction_stop(t);
244
245 /* Notify all queries that are interested, but make sure the
246 * transaction isn't freed while we are still looking at it */
247 t->block_gc++;
f7014757 248
547973de
LP
249 SET_FOREACH(c, t->notify_query_candidates, i)
250 dns_query_candidate_notify(c);
251 SET_FOREACH(z, t->notify_zone_items, i)
252 dns_zone_item_notify(z);
ec2c5e43 253
f7014757
LP
254 if (!set_isempty(t->notify_transactions)) {
255 DnsTransaction **nt;
256 unsigned j, n = 0;
257
258 /* We need to be careful when notifying other
259 * transactions, as that might destroy other
260 * transactions in our list. Hence, in order to be
261 * able to safely iterate through the list of
262 * transactions, take a GC lock on all of them
263 * first. Then, in a second loop, notify them, but
264 * first unlock that specific transaction. */
265
266 nt = newa(DnsTransaction*, set_size(t->notify_transactions));
267 SET_FOREACH(d, t->notify_transactions, i) {
268 nt[n++] = d;
269 d->block_gc++;
270 }
271
272 assert(n == set_size(t->notify_transactions));
273
274 for (j = 0; j < n; j++) {
275 if (set_contains(t->notify_transactions, nt[j]))
276 dns_transaction_notify(nt[j], t);
277
278 nt[j]->block_gc--;
279 dns_transaction_gc(nt[j]);
280 }
281 }
282
283 t->block_gc--;
ec2c5e43
LP
284 dns_transaction_gc(t);
285}
286
287static int on_stream_complete(DnsStream *s, int error) {
288 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
289 DnsTransaction *t;
290
291 assert(s);
292 assert(s->transaction);
293
294 /* Copy the data we care about out of the stream before we
295 * destroy it. */
296 t = s->transaction;
297 p = dns_packet_ref(s->read_packet);
298
299 t->stream = dns_stream_free(t->stream);
300
301 if (error != 0) {
302 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
303 return 0;
304 }
305
a4076574 306 if (dns_packet_validate_reply(p) <= 0) {
a20b9592 307 log_debug("Invalid TCP reply packet.");
a4076574
LP
308 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
309 return 0;
310 }
311
312 dns_scope_check_conflicts(t->scope, p);
313
ec2c5e43
LP
314 t->block_gc++;
315 dns_transaction_process_reply(t, p);
316 t->block_gc--;
317
318 /* If the response wasn't useful, then complete the transition now */
319 if (t->state == DNS_TRANSACTION_PENDING)
320 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
321
322 return 0;
323}
324
325static int dns_transaction_open_tcp(DnsTransaction *t) {
088480fa 326 DnsServer *server = NULL;
ec2c5e43
LP
327 _cleanup_close_ int fd = -1;
328 int r;
329
330 assert(t);
331
332 if (t->stream)
333 return 0;
334
106784eb
DM
335 switch (t->scope->protocol) {
336 case DNS_PROTOCOL_DNS:
8300ba21 337 fd = dns_scope_tcp_socket(t->scope, AF_UNSPEC, NULL, 53, &server);
106784eb 338 break;
ec2c5e43 339
106784eb 340 case DNS_PROTOCOL_LLMNR:
a8f6397f 341 /* When we already received a reply to this (but it was truncated), send to its sender address */
ec2c5e43 342 if (t->received)
8300ba21 343 fd = dns_scope_tcp_socket(t->scope, t->received->family, &t->received->sender, t->received->sender_port, NULL);
ec2c5e43
LP
344 else {
345 union in_addr_union address;
a7f7d1bd 346 int family = AF_UNSPEC;
ec2c5e43
LP
347
348 /* Otherwise, try to talk to the owner of a
349 * the IP address, in case this is a reverse
350 * PTR lookup */
f52e61da
LP
351
352 r = dns_name_address(DNS_RESOURCE_KEY_NAME(t->key), &family, &address);
ec2c5e43
LP
353 if (r < 0)
354 return r;
355 if (r == 0)
356 return -EINVAL;
9e08a6e0 357 if (family != t->scope->family)
9318cdd3 358 return -ESRCH;
ec2c5e43 359
8300ba21 360 fd = dns_scope_tcp_socket(t->scope, family, &address, LLMNR_PORT, NULL);
ec2c5e43 361 }
106784eb
DM
362
363 break;
364
365 default:
ec2c5e43 366 return -EAFNOSUPPORT;
106784eb 367 }
ec2c5e43
LP
368
369 if (fd < 0)
370 return fd;
371
372 r = dns_stream_new(t->scope->manager, &t->stream, t->scope->protocol, fd);
373 if (r < 0)
374 return r;
375
376 fd = -1;
377
378 r = dns_stream_write_packet(t->stream, t->sent);
379 if (r < 0) {
380 t->stream = dns_stream_free(t->stream);
381 return r;
382 }
383
8300ba21
TG
384 dns_server_unref(t->server);
385 t->server = dns_server_ref(server);
ec2c5e43 386 t->received = dns_packet_unref(t->received);
ae6a4bbf
LP
387 t->answer = dns_answer_unref(t->answer);
388 t->answer_rcode = 0;
ec2c5e43
LP
389 t->stream->complete = on_stream_complete;
390 t->stream->transaction = t;
391
392 /* The interface index is difficult to determine if we are
393 * connecting to the local host, hence fill this in right away
394 * instead of determining it from the socket */
395 if (t->scope->link)
396 t->stream->ifindex = t->scope->link->ifindex;
397
398 return 0;
399}
400
647f6aa8
TG
401static void dns_transaction_next_dns_server(DnsTransaction *t) {
402 assert(t);
403
404 t->server = dns_server_unref(t->server);
4667e00a
LP
405 t->dns_udp_event_source = sd_event_source_unref(t->dns_udp_event_source);
406 t->dns_udp_fd = safe_close(t->dns_udp_fd);
647f6aa8
TG
407
408 dns_scope_next_dns_server(t->scope);
409}
410
547973de 411static void dns_transaction_cache_answer(DnsTransaction *t) {
547973de
LP
412 assert(t);
413
414 /* For mDNS we cache whenever we get the packet, rather than
415 * in each transaction. */
416 if (!IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR))
417 return;
418
419 /* We never cache if this packet is from the local host, under
420 * the assumption that a locally running DNS server would
421 * cache this anyway, and probably knows better when to flush
422 * the cache then we could. */
423 if (!DNS_PACKET_SHALL_CACHE(t->received))
424 return;
425
547973de
LP
426 dns_cache_put(&t->scope->cache,
427 t->key,
428 t->answer_rcode,
429 t->answer,
547973de
LP
430 t->answer_authenticated,
431 0,
432 t->received->family,
433 &t->received->sender);
434}
435
105e1512
LP
436static bool dns_transaction_dnssec_is_live(DnsTransaction *t) {
437 DnsTransaction *dt;
438 Iterator i;
439
440 assert(t);
441
442 SET_FOREACH(dt, t->dnssec_transactions, i)
443 if (DNS_TRANSACTION_IS_LIVE(dt->state))
444 return true;
445
446 return false;
447}
448
547973de
LP
449static void dns_transaction_process_dnssec(DnsTransaction *t) {
450 int r;
451
452 assert(t);
453
454 /* Are there ongoing DNSSEC transactions? If so, let's wait for them. */
105e1512 455 if (dns_transaction_dnssec_is_live(t))
547973de
LP
456 return;
457
458 /* All our auxiliary DNSSEC transactions are complete now. Try
459 * to validate our RRset now. */
460 r = dns_transaction_validate_dnssec(t);
461 if (r < 0) {
462 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
463 return;
464 }
465
105e1512
LP
466 if (!IN_SET(t->dnssec_result,
467 _DNSSEC_RESULT_INVALID, /* No DNSSEC validation enabled */
468 DNSSEC_VALIDATED, /* Answer is signed and validated successfully */
469 DNSSEC_UNSIGNED)) { /* Answer is right-fully unsigned */
547973de
LP
470 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
471 return;
472 }
473
474 dns_transaction_cache_answer(t);
475
476 if (t->answer_rcode == DNS_RCODE_SUCCESS)
477 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
478 else
479 dns_transaction_complete(t, DNS_TRANSACTION_FAILURE);
480}
481
ec2c5e43 482void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
9df3ba6c 483 usec_t ts;
ec2c5e43
LP
484 int r;
485
486 assert(t);
487 assert(p);
488 assert(t->state == DNS_TRANSACTION_PENDING);
9df3ba6c
TG
489 assert(t->scope);
490 assert(t->scope->manager);
ec2c5e43
LP
491
492 /* Note that this call might invalidate the query. Callers
493 * should hence not attempt to access the query or transaction
494 * after calling this function. */
495
b5efcf29
LP
496 log_debug("Processing incoming packet on transaction %" PRIu16".", t->id);
497
106784eb 498 switch (t->scope->protocol) {
b5efcf29 499
106784eb 500 case DNS_PROTOCOL_LLMNR:
ec2c5e43
LP
501 assert(t->scope->link);
502
503 /* For LLMNR we will not accept any packets from other
504 * interfaces */
505
506 if (p->ifindex != t->scope->link->ifindex)
507 return;
508
509 if (p->family != t->scope->family)
510 return;
511
512 /* Tentative packets are not full responses but still
513 * useful for identifying uniqueness conflicts during
514 * probing. */
8b757a38 515 if (DNS_PACKET_LLMNR_T(p)) {
ec2c5e43
LP
516 dns_transaction_tentative(t, p);
517 return;
518 }
106784eb
DM
519
520 break;
521
4e5bf5e1
DM
522 case DNS_PROTOCOL_MDNS:
523 assert(t->scope->link);
524
525 /* For mDNS we will not accept any packets from other interfaces */
526 if (p->ifindex != t->scope->link->ifindex)
527 return;
528
529 if (p->family != t->scope->family)
530 return;
531
532 break;
533
106784eb
DM
534 case DNS_PROTOCOL_DNS:
535 break;
536
537 default:
9c56a6f3 538 assert_not_reached("Invalid DNS protocol.");
ec2c5e43
LP
539 }
540
ec2c5e43
LP
541 if (t->received != p) {
542 dns_packet_unref(t->received);
543 t->received = dns_packet_ref(p);
544 }
545
c3bc53e6
LP
546 t->answer_source = DNS_TRANSACTION_NETWORK;
547
ec2c5e43
LP
548 if (p->ipproto == IPPROTO_TCP) {
549 if (DNS_PACKET_TC(p)) {
550 /* Truncated via TCP? Somebody must be fucking with us */
551 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
552 return;
553 }
554
555 if (DNS_PACKET_ID(p) != t->id) {
556 /* Not the reply to our query? Somebody must be fucking with us */
557 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
558 return;
559 }
560 }
561
38a03f06 562 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
9df3ba6c
TG
563
564 switch (t->scope->protocol) {
8af5b883 565
9df3ba6c
TG
566 case DNS_PROTOCOL_DNS:
567 assert(t->server);
568
4e0b8b17
TG
569 if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_FORMERR, DNS_RCODE_SERVFAIL, DNS_RCODE_NOTIMP)) {
570
8af5b883 571 /* Request failed, immediately try again with reduced features */
4e0b8b17
TG
572 log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p)));
573
574 dns_server_packet_failed(t->server, t->current_features);
575
576 r = dns_transaction_go(t);
577 if (r < 0) {
578 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
579 return;
580 }
581
582 return;
583 } else
d74fb368 584 dns_server_packet_received(t->server, t->current_features, ts - t->start_usec, p->size);
9df3ba6c
TG
585
586 break;
8af5b883 587
9df3ba6c
TG
588 case DNS_PROTOCOL_LLMNR:
589 case DNS_PROTOCOL_MDNS:
590 dns_scope_packet_received(t->scope, ts - t->start_usec);
9df3ba6c 591 break;
8af5b883 592
9df3ba6c 593 default:
8af5b883 594 assert_not_reached("Invalid DNS protocol.");
9df3ba6c
TG
595 }
596
ec2c5e43 597 if (DNS_PACKET_TC(p)) {
547493c5
DM
598
599 /* Truncated packets for mDNS are not allowed. Give up immediately. */
600 if (t->scope->protocol == DNS_PROTOCOL_MDNS) {
601 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
602 return;
603 }
604
ec2c5e43
LP
605 /* Response was truncated, let's try again with good old TCP */
606 r = dns_transaction_open_tcp(t);
607 if (r == -ESRCH) {
608 /* No servers found? Damn! */
609 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
610 return;
611 }
612 if (r < 0) {
8af5b883 613 /* On LLMNR, if we cannot connect to the host,
ec2c5e43
LP
614 * we immediately give up */
615 if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
616 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
617 return;
618 }
619
620 /* On DNS, couldn't send? Try immediately again, with a new server */
647f6aa8 621 dns_transaction_next_dns_server(t);
ec2c5e43
LP
622
623 r = dns_transaction_go(t);
624 if (r < 0) {
625 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
626 return;
627 }
628
629 return;
630 }
631 }
632
8af5b883 633 /* Parse message, if it isn't parsed yet. */
ec2c5e43
LP
634 r = dns_packet_extract(p);
635 if (r < 0) {
636 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
637 return;
638 }
639
b5efcf29
LP
640 if (IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR)) {
641
547493c5 642 /* Only consider responses with equivalent query section to the request */
8af5b883
LP
643 r = dns_packet_is_reply_for(p, t->key);
644 if (r < 0) {
645 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
646 return;
647 }
648 if (r == 0) {
547493c5
DM
649 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
650 return;
651 }
29815b6c 652
547493c5
DM
653 /* Install the answer as answer to the transaction */
654 dns_answer_unref(t->answer);
655 t->answer = dns_answer_ref(p->answer);
656 t->answer_rcode = DNS_PACKET_RCODE(p);
105e1512 657 t->answer_authenticated = false;
79e24931 658
547973de
LP
659 r = dns_transaction_request_dnssec_keys(t);
660 if (r < 0) {
661 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
662 return;
663 }
664 if (r > 0) {
665 /* There are DNSSEC transactions pending now. Update the state accordingly. */
666 t->state = DNS_TRANSACTION_VALIDATING;
423659ab 667 dns_transaction_stop(t);
547973de
LP
668 return;
669 }
547493c5 670 }
ec2c5e43 671
547973de 672 dns_transaction_process_dnssec(t);
ec2c5e43
LP
673}
674
c19ffd9f
TG
675static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
676 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
677 DnsTransaction *t = userdata;
678 int r;
679
680 assert(t);
681 assert(t->scope);
682
683 r = manager_recv(t->scope->manager, fd, DNS_PROTOCOL_DNS, &p);
684 if (r <= 0)
685 return r;
686
687 if (dns_packet_validate_reply(p) > 0 &&
9df3ba6c 688 DNS_PACKET_ID(p) == t->id)
c19ffd9f 689 dns_transaction_process_reply(t, p);
9df3ba6c 690 else
8af5b883 691 log_debug("Invalid DNS packet, ignoring.");
c19ffd9f
TG
692
693 return 0;
694}
695
471d40d9 696static int dns_transaction_emit(DnsTransaction *t) {
c19ffd9f
TG
697 int r;
698
699 assert(t);
c19ffd9f 700
471d40d9
TG
701 if (t->scope->protocol == DNS_PROTOCOL_DNS && !t->server) {
702 DnsServer *server = NULL;
703 _cleanup_close_ int fd = -1;
c19ffd9f 704
471d40d9
TG
705 fd = dns_scope_udp_dns_socket(t->scope, &server);
706 if (fd < 0)
707 return fd;
c19ffd9f 708
4667e00a 709 r = sd_event_add_io(t->scope->manager->event, &t->dns_udp_event_source, fd, EPOLLIN, on_dns_packet, t);
471d40d9
TG
710 if (r < 0)
711 return r;
c19ffd9f 712
4667e00a 713 t->dns_udp_fd = fd;
471d40d9
TG
714 fd = -1;
715 t->server = dns_server_ref(server);
716 }
c19ffd9f 717
9c5e12a4 718 r = dns_scope_emit(t->scope, t->dns_udp_fd, t->server, t->sent);
471d40d9
TG
719 if (r < 0)
720 return r;
c19ffd9f 721
be808ea0
TG
722 if (t->server)
723 t->current_features = t->server->possible_features;
724
471d40d9 725 return 0;
c19ffd9f
TG
726}
727
ec2c5e43
LP
728static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
729 DnsTransaction *t = userdata;
730 int r;
731
732 assert(s);
733 assert(t);
734
ef7ce6df
DM
735 if (!t->initial_jitter_scheduled || t->initial_jitter_elapsed) {
736 /* Timeout reached? Increase the timeout for the server used */
737 switch (t->scope->protocol) {
738 case DNS_PROTOCOL_DNS:
739 assert(t->server);
ec2c5e43 740
ef7ce6df 741 dns_server_packet_lost(t->server, t->current_features, usec - t->start_usec);
be808ea0 742
ef7ce6df
DM
743 break;
744 case DNS_PROTOCOL_LLMNR:
745 case DNS_PROTOCOL_MDNS:
746 dns_scope_packet_lost(t->scope, usec - t->start_usec);
9df3ba6c 747
ef7ce6df
DM
748 break;
749 default:
750 assert_not_reached("Invalid DNS protocol.");
751 }
752
753 if (t->initial_jitter_scheduled)
754 t->initial_jitter_elapsed = true;
be808ea0
TG
755 }
756
423659ab
LP
757 log_debug("Timeout reached on transaction %" PRIu16 ".", t->id);
758
be808ea0
TG
759 /* ...and try again with a new server */
760 dns_transaction_next_dns_server(t);
761
ec2c5e43
LP
762 r = dns_transaction_go(t);
763 if (r < 0)
764 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
765
766 return 0;
767}
768
9df3ba6c
TG
769static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
770 assert(t);
771 assert(t->scope);
772
773 switch (t->scope->protocol) {
774 case DNS_PROTOCOL_DNS:
775 assert(t->server);
776
777 return t->server->resend_timeout;
9df3ba6c 778 case DNS_PROTOCOL_MDNS:
11a27c2e
DM
779 assert(t->n_attempts > 0);
780 return (1 << (t->n_attempts - 1)) * USEC_PER_SEC;
781 case DNS_PROTOCOL_LLMNR:
9df3ba6c
TG
782 return t->scope->resend_timeout;
783 default:
784 assert_not_reached("Invalid DNS protocol.");
785 }
786}
787
c842ff24 788static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
ec2c5e43
LP
789 bool had_stream;
790 int r;
791
792 assert(t);
793
794 had_stream = !!t->stream;
795
796 dns_transaction_stop(t);
797
ec2c5e43
LP
798 if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t->scope->protocol)) {
799 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
800 return 0;
801 }
802
803 if (t->scope->protocol == DNS_PROTOCOL_LLMNR && had_stream) {
804 /* If we already tried via a stream, then we don't
805 * retry on LLMNR. See RFC 4795, Section 2.7. */
806 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
807 return 0;
808 }
809
810 t->n_attempts++;
9df3ba6c 811 t->start_usec = ts;
ec2c5e43 812 t->received = dns_packet_unref(t->received);
ae6a4bbf
LP
813 t->answer = dns_answer_unref(t->answer);
814 t->answer_rcode = 0;
c3bc53e6 815 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
ec2c5e43 816
0d2cd476
LP
817 /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
818 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
819 r = dns_trust_anchor_lookup(&t->scope->manager->trust_anchor, t->key, &t->answer);
820 if (r < 0)
821 return r;
822 if (r > 0) {
823 t->answer_rcode = DNS_RCODE_SUCCESS;
824 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
931851e8 825 t->answer_authenticated = true;
0d2cd476
LP
826 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
827 return 0;
828 }
829 }
830
831 /* Check the zone, but only if this transaction is not used
d746bb3e 832 * for probing or verifying a zone item. */
547973de 833 if (set_isempty(t->notify_zone_items)) {
d746bb3e 834
ae6a4bbf 835 r = dns_zone_lookup(&t->scope->zone, t->key, &t->answer, NULL, NULL);
d746bb3e
LP
836 if (r < 0)
837 return r;
838 if (r > 0) {
ae6a4bbf 839 t->answer_rcode = DNS_RCODE_SUCCESS;
c3bc53e6 840 t->answer_source = DNS_TRANSACTION_ZONE;
931851e8 841 t->answer_authenticated = true;
d746bb3e
LP
842 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
843 return 0;
844 }
845 }
846
4d926a69
LP
847 /* Check the cache, but only if this transaction is not used
848 * for probing or verifying a zone item. */
547973de 849 if (set_isempty(t->notify_zone_items)) {
2c27fbca 850
4d926a69
LP
851 /* Before trying the cache, let's make sure we figured out a
852 * server to use. Should this cause a change of server this
853 * might flush the cache. */
854 dns_scope_get_dns_server(t->scope);
2c27fbca 855
4d926a69
LP
856 /* Let's then prune all outdated entries */
857 dns_cache_prune(&t->scope->cache);
858
931851e8 859 r = dns_cache_lookup(&t->scope->cache, t->key, &t->answer_rcode, &t->answer, &t->answer_authenticated);
4d926a69
LP
860 if (r < 0)
861 return r;
862 if (r > 0) {
c3bc53e6 863 t->answer_source = DNS_TRANSACTION_CACHE;
ae6a4bbf 864 if (t->answer_rcode == DNS_RCODE_SUCCESS)
4d926a69
LP
865 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
866 else
867 dns_transaction_complete(t, DNS_TRANSACTION_FAILURE);
868 return 0;
869 }
ec2c5e43
LP
870 }
871
1effe965
DM
872 return 1;
873}
874
0afa57e2
DM
875static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
876
877 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
7778dfff 878 bool add_known_answers = false;
0afa57e2
DM
879 DnsTransaction *other;
880 unsigned qdcount;
881 usec_t ts;
882 int r;
883
884 assert(t);
885 assert(t->scope->protocol == DNS_PROTOCOL_MDNS);
886
e5abebab 887 /* Discard any previously prepared packet, so we can start over and coalesce again */
0afa57e2
DM
888 t->sent = dns_packet_unref(t->sent);
889
890 r = dns_packet_new_query(&p, t->scope->protocol, 0, false);
891 if (r < 0)
892 return r;
893
894 r = dns_packet_append_key(p, t->key, NULL);
895 if (r < 0)
896 return r;
897
898 qdcount = 1;
899
7778dfff
DM
900 if (dns_key_is_shared(t->key))
901 add_known_answers = true;
902
0afa57e2
DM
903 /*
904 * For mDNS, we want to coalesce as many open queries in pending transactions into one single
905 * query packet on the wire as possible. To achieve that, we iterate through all pending transactions
906 * in our current scope, and see whether their timing contraints allow them to be sent.
907 */
908
909 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
910
911 LIST_FOREACH(transactions_by_scope, other, t->scope->transactions) {
912
913 /* Skip ourselves */
914 if (other == t)
915 continue;
916
917 if (other->state != DNS_TRANSACTION_PENDING)
918 continue;
919
920 if (other->next_attempt_after > ts)
921 continue;
922
923 if (qdcount >= UINT16_MAX)
924 break;
925
926 r = dns_packet_append_key(p, other->key, NULL);
927
928 /*
929 * If we can't stuff more questions into the packet, just give up.
930 * One of the 'other' transactions will fire later and take care of the rest.
931 */
932 if (r == -EMSGSIZE)
933 break;
934
935 if (r < 0)
936 return r;
937
c842ff24 938 r = dns_transaction_prepare(other, ts);
0afa57e2
DM
939 if (r <= 0)
940 continue;
941
942 ts += transaction_get_resend_timeout(other);
943
944 r = sd_event_add_time(
945 other->scope->manager->event,
946 &other->timeout_event_source,
947 clock_boottime_or_monotonic(),
948 ts, 0,
949 on_transaction_timeout, other);
950 if (r < 0)
951 return r;
952
953 other->state = DNS_TRANSACTION_PENDING;
954 other->next_attempt_after = ts;
955
956 qdcount ++;
7778dfff
DM
957
958 if (dns_key_is_shared(other->key))
959 add_known_answers = true;
0afa57e2
DM
960 }
961
962 DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount);
0afa57e2 963
7778dfff
DM
964 /* Append known answer section if we're asking for any shared record */
965 if (add_known_answers) {
966 r = dns_cache_export_shared_to_packet(&t->scope->cache, p);
967 if (r < 0)
968 return r;
969 }
970
0afa57e2
DM
971 t->sent = p;
972 p = NULL;
973
974 return 0;
975}
976
977static int dns_transaction_make_packet(DnsTransaction *t) {
978 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
979 int r;
980
981 assert(t);
982
983 if (t->scope->protocol == DNS_PROTOCOL_MDNS)
984 return dns_transaction_make_packet_mdns(t);
985
986 if (t->sent)
987 return 0;
988
989 r = dns_packet_new_query(&p, t->scope->protocol, 0, t->scope->dnssec_mode == DNSSEC_YES);
990 if (r < 0)
991 return r;
992
993 r = dns_scope_good_key(t->scope, t->key);
994 if (r < 0)
995 return r;
996 if (r == 0)
997 return -EDOM;
998
999 r = dns_packet_append_key(p, t->key, NULL);
1000 if (r < 0)
1001 return r;
1002
1003 DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
1004 DNS_PACKET_HEADER(p)->id = t->id;
1005
1006 t->sent = p;
1007 p = NULL;
1008
1009 return 0;
1010}
1011
1effe965
DM
1012int dns_transaction_go(DnsTransaction *t) {
1013 usec_t ts;
1014 int r;
1015
1016 assert(t);
1017
1018 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
547973de 1019
c842ff24 1020 r = dns_transaction_prepare(t, ts);
1effe965
DM
1021 if (r <= 0)
1022 return r;
1023
a5784c49
LP
1024 log_debug("Excercising transaction %" PRIu16 " for <%s> on scope %s on %s/%s.",
1025 t->id,
1026 dns_transaction_key_string(t),
1027 dns_protocol_to_string(t->scope->protocol),
1028 t->scope->link ? t->scope->link->name : "*",
1029 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family));
1effe965 1030
ef7ce6df 1031 if (!t->initial_jitter_scheduled &&
ea12bcc7
DM
1032 (t->scope->protocol == DNS_PROTOCOL_LLMNR ||
1033 t->scope->protocol == DNS_PROTOCOL_MDNS)) {
1034 usec_t jitter, accuracy;
6e068472
LP
1035
1036 /* RFC 4795 Section 2.7 suggests all queries should be
1037 * delayed by a random time from 0 to JITTER_INTERVAL. */
1038
ef7ce6df 1039 t->initial_jitter_scheduled = true;
6e068472
LP
1040
1041 random_bytes(&jitter, sizeof(jitter));
ea12bcc7
DM
1042
1043 switch (t->scope->protocol) {
1044 case DNS_PROTOCOL_LLMNR:
1045 jitter %= LLMNR_JITTER_INTERVAL_USEC;
1046 accuracy = LLMNR_JITTER_INTERVAL_USEC;
1047 break;
1048 case DNS_PROTOCOL_MDNS:
1049 jitter %= MDNS_JITTER_RANGE_USEC;
1050 jitter += MDNS_JITTER_MIN_USEC;
1051 accuracy = MDNS_JITTER_RANGE_USEC;
1052 break;
1053 default:
1054 assert_not_reached("bad protocol");
1055 }
6e068472
LP
1056
1057 r = sd_event_add_time(
1058 t->scope->manager->event,
1059 &t->timeout_event_source,
1060 clock_boottime_or_monotonic(),
ea12bcc7 1061 ts + jitter, accuracy,
6e068472
LP
1062 on_transaction_timeout, t);
1063 if (r < 0)
1064 return r;
1065
1066 t->n_attempts = 0;
a9da14e1 1067 t->next_attempt_after = ts;
6e068472
LP
1068 t->state = DNS_TRANSACTION_PENDING;
1069
ea12bcc7 1070 log_debug("Delaying %s transaction for " USEC_FMT "us.", dns_protocol_to_string(t->scope->protocol), jitter);
6e068472
LP
1071 return 0;
1072 }
1073
ec2c5e43
LP
1074 /* Otherwise, we need to ask the network */
1075 r = dns_transaction_make_packet(t);
1076 if (r == -EDOM) {
1077 /* Not the right request to make on this network?
1078 * (i.e. an A request made on IPv6 or an AAAA request
1079 * made on IPv4, on LLMNR or mDNS.) */
1080 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
1081 return 0;
1082 }
1083 if (r < 0)
1084 return r;
1085
1086 if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
f52e61da
LP
1087 (dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), "in-addr.arpa") > 0 ||
1088 dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), "ip6.arpa") > 0)) {
ec2c5e43
LP
1089
1090 /* RFC 4795, Section 2.4. says reverse lookups shall
1091 * always be made via TCP on LLMNR */
1092 r = dns_transaction_open_tcp(t);
1093 } else {
be808ea0
TG
1094 /* Try via UDP, and if that fails due to large size or lack of
1095 * support try via TCP */
471d40d9 1096 r = dns_transaction_emit(t);
be808ea0 1097 if (r == -EMSGSIZE || r == -EAGAIN)
ec2c5e43
LP
1098 r = dns_transaction_open_tcp(t);
1099 }
be808ea0 1100
ec2c5e43
LP
1101 if (r == -ESRCH) {
1102 /* No servers to send this to? */
1103 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
1104 return 0;
8300ba21 1105 } else if (r < 0) {
13b551ac
LP
1106 if (t->scope->protocol != DNS_PROTOCOL_DNS) {
1107 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
1108 return 0;
1109 }
1110
ec2c5e43 1111 /* Couldn't send? Try immediately again, with a new server */
647f6aa8 1112 dns_transaction_next_dns_server(t);
ec2c5e43
LP
1113
1114 return dns_transaction_go(t);
1115 }
1116
a9da14e1
DM
1117 ts += transaction_get_resend_timeout(t);
1118
9a015429
LP
1119 r = sd_event_add_time(
1120 t->scope->manager->event,
1121 &t->timeout_event_source,
1122 clock_boottime_or_monotonic(),
a9da14e1 1123 ts, 0,
9a015429 1124 on_transaction_timeout, t);
ec2c5e43
LP
1125 if (r < 0)
1126 return r;
1127
1128 t->state = DNS_TRANSACTION_PENDING;
a9da14e1
DM
1129 t->next_attempt_after = ts;
1130
ec2c5e43
LP
1131 return 1;
1132}
1133
547973de
LP
1134static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResourceKey *key, DnsTransaction **ret) {
1135 DnsTransaction *aux;
1136 int r;
1137
1138 assert(t);
1139 assert(ret);
1140 assert(key);
1141
1142 aux = dns_scope_find_transaction(t->scope, key, true);
1143 if (!aux) {
1144 r = dns_transaction_new(&aux, t->scope, key);
1145 if (r < 0)
1146 return r;
1147 } else {
1148 if (set_contains(t->dnssec_transactions, aux)) {
1149 *ret = aux;
1150 return 0;
1151 }
1152 }
1153
1154 r = set_ensure_allocated(&t->dnssec_transactions, NULL);
1155 if (r < 0)
1156 goto gc;
1157
1158 r = set_ensure_allocated(&aux->notify_transactions, NULL);
1159 if (r < 0)
1160 goto gc;
1161
1162 r = set_put(t->dnssec_transactions, aux);
1163 if (r < 0)
1164 goto gc;
1165
1166 r = set_put(aux->notify_transactions, t);
1167 if (r < 0) {
1168 (void) set_remove(t->dnssec_transactions, aux);
1169 goto gc;
1170 }
1171
1172 *ret = aux;
1173 return 1;
1174
1175gc:
1176 dns_transaction_gc(aux);
1177 return r;
1178}
1179
1180static int dns_transaction_request_dnssec_rr(DnsTransaction *t, DnsResourceKey *key) {
1181 _cleanup_(dns_answer_unrefp) DnsAnswer *a = NULL;
1182 DnsTransaction *aux;
1183 int r;
1184
1185 assert(t);
1186 assert(key);
1187
aae6a86e
LP
1188 r = dns_resource_key_equal(t->key, key);
1189 if (r < 0)
1190 return r;
1191 if (r > 0) /* Don't go in circles */
1192 return 0;
1193
547973de
LP
1194 /* Try to get the data from the trust anchor */
1195 r = dns_trust_anchor_lookup(&t->scope->manager->trust_anchor, key, &a);
1196 if (r < 0)
1197 return r;
1198 if (r > 0) {
1199 r = dns_answer_extend(&t->validated_keys, a);
1200 if (r < 0)
1201 return r;
1202
1203 return 0;
1204 }
1205
1206 /* This didn't work, ask for it via the network/cache then. */
1207 r = dns_transaction_add_dnssec_transaction(t, key, &aux);
1208 if (r < 0)
1209 return r;
1210
1211 if (aux->state == DNS_TRANSACTION_NULL) {
1212 r = dns_transaction_go(aux);
1213 if (r < 0)
1214 return r;
1215 }
1216
1217 return 0;
1218}
1219
105e1512
LP
1220static int dns_transaction_has_positive_answer(DnsTransaction *t, DnsAnswerFlags *flags) {
1221 int r;
1222
1223 assert(t);
1224
1225 /* Checks whether the answer is positive, i.e. either a direct
1226 * answer to the question, or a CNAME/DNAME for it */
1227
1228 r = dns_answer_match_key(t->answer, t->key, flags);
1229 if (r != 0)
1230 return r;
1231
1232 r = dns_answer_find_cname_or_dname(t->answer, t->key, NULL, flags);
1233 if (r != 0)
1234 return r;
1235
1236 return false;
1237}
1238
1239static int dns_transaction_has_unsigned_negative_answer(DnsTransaction *t) {
1240 int r;
1241
1242 assert(t);
1243
1244 /* Checks whether the answer is negative, and lacks NSEC/NSEC3
1245 * RRs to prove it */
1246
1247 r = dns_transaction_has_positive_answer(t, NULL);
1248 if (r < 0)
1249 return r;
1250 if (r > 0)
1251 return false;
1252
1253 /* The answer does not contain any RRs that match to the
1254 * question. If so, let's see if there are any NSEC/NSEC3 RRs
1255 * included. If not, the answer is unsigned. */
1256
1257 r = dns_answer_contains_nsec_or_nsec3(t->answer);
1258 if (r < 0)
1259 return r;
1260 if (r > 0)
1261 return false;
1262
1263 return true;
1264}
1265
1266static int dns_transaction_is_primary_response(DnsTransaction *t, DnsResourceRecord *rr) {
1267 int r;
1268
1269 assert(t);
1270 assert(rr);
1271
1272 /* Check if the specified RR is the "primary" response,
1273 * i.e. either matches the question precisely or is a
1274 * CNAME/DNAME for it, or is any kind of NSEC/NSEC3 RR */
1275
1276 r = dns_resource_key_match_rr(t->key, rr, NULL);
1277 if (r != 0)
1278 return r;
1279
1280 r = dns_resource_key_match_cname_or_dname(t->key, rr->key, NULL);
1281 if (r != 0)
1282 return r;
1283
1284 if (rr->key->type == DNS_TYPE_NSEC3) {
1285 const char *p;
1286
1287 p = DNS_RESOURCE_KEY_NAME(rr->key);
1288 r = dns_name_parent(&p);
1289 if (r < 0)
1290 return r;
1291 if (r > 0) {
1292 r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), p);
1293 if (r < 0)
1294 return r;
1295 if (r > 0)
1296 return true;
1297 }
1298 }
1299
1300 return rr->key->type == DNS_TYPE_NSEC;
1301}
1302
547973de
LP
1303int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
1304 DnsResourceRecord *rr;
105e1512 1305
547973de
LP
1306 int r;
1307
1308 assert(t);
1309
105e1512
LP
1310 /*
1311 * Retrieve all auxiliary RRs for the answer we got, so that
1312 * we can verify signatures or prove that RRs are rightfully
1313 * unsigned. Specifically:
1314 *
1315 * - For RRSIG we get the matching DNSKEY
1316 * - For DNSKEY we get the matching DS
1317 * - For unsigned SOA/NS we get the matching DS
1318 * - For unsigned CNAME/DNAME we get the parent SOA RR
1319 * - For other unsigned RRs we get the matching SOA RR
1320 * - For SOA/NS/DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
1321 * - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR
1322 */
1323
547973de
LP
1324 if (t->scope->dnssec_mode != DNSSEC_YES)
1325 return 0;
1326
1327 DNS_ANSWER_FOREACH(rr, t->answer) {
1328
105e1512
LP
1329 if (dns_type_is_pseudo(rr->key->type))
1330 continue;
1331
547973de
LP
1332 switch (rr->key->type) {
1333
1334 case DNS_TYPE_RRSIG: {
1335 /* For each RRSIG we request the matching DNSKEY */
1336 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *dnskey = NULL;
1337
1338 /* If this RRSIG is about a DNSKEY RR and the
1339 * signer is the same as the owner, then we
1340 * already have the DNSKEY, and we don't have
1341 * to look for more. */
1342 if (rr->rrsig.type_covered == DNS_TYPE_DNSKEY) {
1343 r = dns_name_equal(rr->rrsig.signer, DNS_RESOURCE_KEY_NAME(rr->key));
1344 if (r < 0)
1345 return r;
1346 if (r > 0)
1347 continue;
1348 }
1349
105e1512
LP
1350 /* If the signer is not a parent of our
1351 * original query, then this is about an
1352 * auxiliary RRset, but not anything we asked
1353 * for. In this case we aren't interested,
1354 * because we don't want to request additional
1355 * RRs for stuff we didn't really ask for, and
1356 * also to avoid request loops, where
1357 * additional RRs from one transaction result
1358 * in another transaction whose additonal RRs
1359 * point back to the original transaction, and
1360 * we deadlock. */
1361 r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), rr->rrsig.signer);
547973de
LP
1362 if (r < 0)
1363 return r;
1364 if (r == 0)
1365 continue;
1366
1367 dnskey = dns_resource_key_new(rr->key->class, DNS_TYPE_DNSKEY, rr->rrsig.signer);
1368 if (!dnskey)
1369 return -ENOMEM;
1370
105e1512 1371 log_debug("Requesting DNSKEY to validate transaction %" PRIu16" (%s, RRSIG with key tag: %" PRIu16 ").", t->id, DNS_RESOURCE_KEY_NAME(rr->key), rr->rrsig.key_tag);
547973de
LP
1372 r = dns_transaction_request_dnssec_rr(t, dnskey);
1373 if (r < 0)
1374 return r;
1375 break;
1376 }
1377
1378 case DNS_TYPE_DNSKEY: {
1379 /* For each DNSKEY we request the matching DS */
1380 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
1381
105e1512
LP
1382 /* If the DNSKEY we are looking at is not for
1383 * zone we are interested in, nor any of its
1384 * parents, we aren't interested, and don't
1385 * request it. After all, we don't want to end
1386 * up in request loops, and want to keep
1387 * additional traffic down. */
1388
1389 r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), DNS_RESOURCE_KEY_NAME(rr->key));
1390 if (r < 0)
1391 return r;
1392 if (r == 0)
1393 continue;
1394
547973de
LP
1395 ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, DNS_RESOURCE_KEY_NAME(rr->key));
1396 if (!ds)
1397 return -ENOMEM;
1398
105e1512
LP
1399 log_debug("Requesting DS to validate transaction %" PRIu16" (%s, DNSKEY with key tag: %" PRIu16 ").", t->id, DNS_RESOURCE_KEY_NAME(rr->key), dnssec_keytag(rr));
1400 r = dns_transaction_request_dnssec_rr(t, ds);
1401 if (r < 0)
1402 return r;
547973de 1403
105e1512
LP
1404 break;
1405 }
1406
1407 case DNS_TYPE_DS:
1408 case DNS_TYPE_NSEC:
1409 case DNS_TYPE_NSEC3:
1410 /* Don't acquire anything for
1411 * DS/NSEC/NSEC3. We require they come with an
1412 * RRSIG without us asking for anything, and
1413 * that's sufficient. */
1414 break;
1415
1416 case DNS_TYPE_SOA:
1417 case DNS_TYPE_NS: {
1418 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
1419
1420 /* For an unsigned SOA or NS, try to acquire
1421 * the matching DS RR, as we are at a zone cut
1422 * then, and whether a DS exists tells us
1423 * whether the zone is signed. Do so only if
1424 * this RR matches our original question,
1425 * however. */
1426
1427 r = dns_resource_key_match_rr(t->key, rr, NULL);
1428 if (r < 0)
1429 return r;
1430 if (r == 0)
1431 continue;
1432
1433 r = dnssec_has_rrsig(t->answer, rr->key);
1434 if (r < 0)
1435 return r;
1436 if (r > 0)
1437 continue;
1438
1439 ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, DNS_RESOURCE_KEY_NAME(rr->key));
1440 if (!ds)
1441 return -ENOMEM;
1442
1443 log_debug("Requesting DS to validate transaction %" PRIu16 " (%s, unsigned SOA/NS RRset).", t->id, DNS_RESOURCE_KEY_NAME(rr->key));
547973de
LP
1444 r = dns_transaction_request_dnssec_rr(t, ds);
1445 if (r < 0)
1446 return r;
1447
1448 break;
105e1512
LP
1449 }
1450
1451 case DNS_TYPE_CNAME:
1452 case DNS_TYPE_DNAME: {
1453 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
1454 const char *name;
1455
1456 /* CNAMEs and DNAMEs cannot be located at a
1457 * zone apex, hence ask for the parent SOA for
1458 * unsigned CNAME/DNAME RRs, maybe that's the
1459 * apex. But do all that only if this is
1460 * actually a response to our original
1461 * question. */
1462
1463 r = dns_transaction_is_primary_response(t, rr);
1464 if (r < 0)
1465 return r;
1466 if (r == 0)
1467 continue;
1468
1469 r = dnssec_has_rrsig(t->answer, rr->key);
1470 if (r < 0)
1471 return r;
1472 if (r > 0)
1473 continue;
1474
1475 name = DNS_RESOURCE_KEY_NAME(rr->key);
1476 r = dns_name_parent(&name);
1477 if (r < 0)
1478 return r;
1479 if (r == 0)
1480 continue;
1481
1482 soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, name);
1483 if (!soa)
1484 return -ENOMEM;
1485
1486 log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned CNAME/DNAME RRset).", t->id, DNS_RESOURCE_KEY_NAME(rr->key));
1487 r = dns_transaction_request_dnssec_rr(t, soa);
1488 if (r < 0)
1489 return r;
1490
1491 break;
1492 }
1493
1494 default: {
1495 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
1496
1497 /* For other unsigned RRsets, look for proof
1498 * the zone is unsigned, by requesting the SOA
1499 * RR of the zone. However, do so only if they
1500 * are directly relevant to our original
1501 * question. */
1502
1503 r = dns_transaction_is_primary_response(t, rr);
1504 if (r < 0)
1505 return r;
1506 if (r == 0)
1507 continue;
1508
1509 r = dnssec_has_rrsig(t->answer, rr->key);
1510 if (r < 0)
1511 return r;
1512 if (r > 0)
1513 continue;
1514
1515 soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, DNS_RESOURCE_KEY_NAME(rr->key));
1516 if (!soa)
1517 return -ENOMEM;
1518
1519 log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned non-SOA/NS RRset).", t->id, DNS_RESOURCE_KEY_NAME(rr->key));
1520 r = dns_transaction_request_dnssec_rr(t, soa);
1521 if (r < 0)
1522 return r;
1523 break;
547973de
LP
1524 }}
1525 }
1526
105e1512
LP
1527 /* Above, we requested everything necessary to validate what
1528 * we got. Now, let's request what we need to validate what we
1529 * didn't get... */
1530
1531 r = dns_transaction_has_unsigned_negative_answer(t);
1532 if (r < 0)
1533 return r;
1534 if (r > 0) {
1535 const char *name;
1536
1537 name = DNS_RESOURCE_KEY_NAME(t->key);
1538
1539 /* If this was a SOA or NS request, then this
1540 * indicates that we are not at a zone apex, hence ask
1541 * the parent name instead. If this was a DS request,
1542 * then it's signed when the parent zone is signed,
1543 * hence ask the parent in that case, too. */
1544
1545 if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS, DNS_TYPE_DS)) {
1546 r = dns_name_parent(&name);
1547 if (r < 0)
1548 return r;
1549 if (r > 0)
1550 log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned empty SOA/NS/DS response).", t->id, DNS_RESOURCE_KEY_NAME(t->key));
1551 else
1552 name = NULL;
1553 } else
1554 log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned empty non-SOA/NS/DS response).", t->id, DNS_RESOURCE_KEY_NAME(t->key));
1555
1556 if (name) {
1557 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
1558
1559 soa = dns_resource_key_new(t->key->class, DNS_TYPE_SOA, name);
1560 if (!soa)
1561 return -ENOMEM;
1562
1563 r = dns_transaction_request_dnssec_rr(t, soa);
1564 if (r < 0)
1565 return r;
1566 }
1567 }
1568
1569 return dns_transaction_dnssec_is_live(t);
547973de
LP
1570}
1571
1572void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source) {
1573 int r;
1574
1575 assert(t);
547973de
LP
1576 assert(source);
1577
105e1512
LP
1578 if (!IN_SET(t->state, DNS_TRANSACTION_PENDING, DNS_TRANSACTION_VALIDATING))
1579 return;
1580
547973de 1581 /* Invoked whenever any of our auxiliary DNSSEC transactions
105e1512
LP
1582 completed its work. We copy any RRs from that transaction
1583 over into our list of validated keys -- but only if the
1584 answer is authenticated.
1585
1586 Note that we fail our transaction if the auxiliary
1587 transaction failed, except on NXDOMAIN. This is because
1588 some broken DNS servers (Akamai...) will return NXDOMAIN
1589 for empty non-terminals. */
1590
1591 if (source->state != DNS_TRANSACTION_SUCCESS &&
1592 !(source->state == DNS_TRANSACTION_FAILURE && source->answer_rcode == DNS_RCODE_NXDOMAIN)) {
1593 log_debug("Auxiliary DNSSEC RR query failed: rcode=%i.", source->answer_rcode);
1594 goto fail;
1595 } else if (source->answer_authenticated) {
547973de 1596
547973de
LP
1597 r = dns_answer_extend(&t->validated_keys, source->answer);
1598 if (r < 0) {
1599 log_error_errno(r, "Failed to merge validated DNSSEC key data: %m");
105e1512 1600 goto fail;
547973de
LP
1601 }
1602 }
1603
547973de
LP
1604 /* If the state is still PENDING, we are still in the loop
1605 * that adds further DNSSEC transactions, hence don't check if
1606 * we are ready yet. If the state is VALIDATING however, we
1607 * should check if we are complete now. */
1608 if (t->state == DNS_TRANSACTION_VALIDATING)
1609 dns_transaction_process_dnssec(t);
105e1512
LP
1610
1611 return;
1612
1613fail:
1614 t->dnssec_result = DNSSEC_FAILED_AUXILIARY;
1615 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
547973de
LP
1616}
1617
105e1512
LP
1618static int dns_transaction_validate_dnskey_by_ds(DnsTransaction *t) {
1619 DnsResourceRecord *rr;
1620 int ifindex, r;
1621
1622 assert(t);
1623
1624 /* Add all DNSKEY RRs from the answer that are validated by DS
1625 * RRs from the list of validated keys to the list of
1626 * validated keys. */
1627
1628 DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, t->answer) {
1629
1630 r = dnssec_verify_dnskey_search(rr, t->validated_keys);
1631 if (r < 0)
1632 return r;
1633 if (r == 0)
1634 continue;
1635
1636 /* If so, the DNSKEY is validated too. */
1637 r = dns_answer_add_extend(&t->validated_keys, rr, ifindex, DNS_ANSWER_AUTHENTICATED);
1638 if (r < 0)
1639 return r;
1640 }
1641
1642 return 0;
1643}
1644
1645static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *rr) {
56352fe9
LP
1646 int r;
1647
1648 assert(t);
1649 assert(rr);
1650
105e1512
LP
1651 /* Checks if the RR we are looking for must be signed with an
1652 * RRSIG. This is used for positive responses. */
24a5b982 1653
105e1512
LP
1654 if (t->scope->dnssec_mode != DNSSEC_YES)
1655 return false;
56352fe9 1656
105e1512
LP
1657 if (dns_type_is_pseudo(rr->key->type))
1658 return -EINVAL;
56352fe9 1659
105e1512 1660 switch (rr->key->type) {
56352fe9 1661
105e1512
LP
1662 case DNS_TYPE_DNSKEY:
1663 case DNS_TYPE_DS:
1664 case DNS_TYPE_NSEC:
1665 case DNS_TYPE_NSEC3:
1666 /* We never consider DNSKEY, DS, NSEC, NSEC3 RRs if they aren't signed. */
1667 return true;
1668
1669 case DNS_TYPE_RRSIG:
1670 /* RRSIGs are the signatures themselves, they need no signing. */
1671 return false;
1672
1673 case DNS_TYPE_SOA:
1674 case DNS_TYPE_NS: {
1675 DnsTransaction *dt;
1676 Iterator i;
1677
1678 /* For SOA or NS RRs we look for a matching DS transaction, or a SOA transaction of the parent */
1679
1680 SET_FOREACH(dt, t->dnssec_transactions, i) {
1681
1682 if (dt->key->class != rr->key->class)
1683 continue;
1684 if (dt->key->type != DNS_TYPE_DS)
1685 continue;
1686
1687 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), DNS_RESOURCE_KEY_NAME(rr->key));
1688 if (r < 0)
1689 return r;
1690 if (r == 0)
1691 continue;
1692
1693 /* We found a DS transactions for the SOA/NS
1694 * RRs we are looking at. If it discovered signed DS
1695 * RRs, then we need to be signed, too. */
1696
1697 if (!dt->answer_authenticated)
1698 return false;
1699
1700 return dns_answer_match_key(dt->answer, dt->key, NULL);
1701 }
1702
1703 /* We found nothing that proves this is safe to leave
1704 * this unauthenticated, hence ask inist on
1705 * authentication. */
1706 return true;
1707 }
1708
1709 case DNS_TYPE_CNAME:
1710 case DNS_TYPE_DNAME: {
1711 const char *parent = NULL;
1712 DnsTransaction *dt;
1713 Iterator i;
1714
1715 /* CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent SOA. */
1716
1717 SET_FOREACH(dt, t->dnssec_transactions, i) {
1718
1719 if (dt->key->class != rr->key->class)
1720 continue;
1721 if (dt->key->type != DNS_TYPE_SOA)
1722 continue;
1723
1724 if (!parent) {
1725 parent = DNS_RESOURCE_KEY_NAME(rr->key);
1726 r = dns_name_parent(&parent);
1727 if (r < 0)
1728 return r;
1729 if (r == 0) {
1730 /* A CNAME/DNAME without a parent? That's sooo weird. */
1731 log_debug("Transaction %" PRIu16 " claims CNAME/DNAME at root. Refusing.", t->id);
1732 return -EBADMSG;
1733 }
1734 }
1735
1736 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), parent);
1737 if (r < 0)
1738 return r;
1739 if (r == 0)
1740 continue;
1741
1742 return t->answer_authenticated;
1743 }
1744
1745 return true;
1746 }
1747
1748 default: {
1749 DnsTransaction *dt;
1750 Iterator i;
1751
1752 /* Any other kind of RR. Let's see if our SOA lookup was authenticated */
1753
1754 SET_FOREACH(dt, t->dnssec_transactions, i) {
1755
1756 if (dt->key->class != rr->key->class)
1757 continue;
1758 if (dt->key->type != DNS_TYPE_SOA)
1759 continue;
1760
1761 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), DNS_RESOURCE_KEY_NAME(rr->key));
1762 if (r < 0)
1763 return r;
1764 if (r == 0)
1765 continue;
1766
1767 /* We found the transaction that was supposed to find
1768 * the SOA RR for us. It was successful, but found no
1769 * RR for us. This means we are not at a zone cut. In
1770 * this case, we require authentication if the SOA
1771 * lookup was authenticated too. */
1772 return t->answer_authenticated;
1773 }
1774
1775 return true;
1776 }}
56352fe9
LP
1777}
1778
105e1512
LP
1779static int dns_transaction_requires_nsec(DnsTransaction *t) {
1780 DnsTransaction *dt;
1781 const char *name;
1782 Iterator i;
1783 int r;
56352fe9
LP
1784
1785 assert(t);
1786
105e1512
LP
1787 /* Checks if we need to insist on NSEC/NSEC3 RRs for proving
1788 * this negative reply */
56352fe9 1789
105e1512
LP
1790 if (t->scope->dnssec_mode != DNSSEC_YES)
1791 return false;
56352fe9 1792
105e1512
LP
1793 if (dns_type_is_pseudo(t->key->type))
1794 return -EINVAL;
1795
1796 name = DNS_RESOURCE_KEY_NAME(t->key);
1797
1798 if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS, DNS_TYPE_DS)) {
1799
1800 /* We got a negative reply for this SOA/NS lookup? If
1801 * so, then we are not at a zone apex, and thus should
1802 * look at the result of the parent SOA lookup.
1803 *
1804 * We got a negative reply for this DS lookup? DS RRs
1805 * are signed when their parent zone is signed, hence
1806 * also check the parent SOA in this case. */
1807
1808 r = dns_name_parent(&name);
56352fe9
LP
1809 if (r < 0)
1810 return r;
1811 if (r == 0)
105e1512
LP
1812 return true;
1813 }
1814
1815 /* For all other RRs we check the SOA on the same level to see
1816 * if it's signed. */
1817
1818 SET_FOREACH(dt, t->dnssec_transactions, i) {
1819
1820 if (dt->key->class != t->key->class)
1821 continue;
1822 if (dt->key->type != DNS_TYPE_SOA)
56352fe9
LP
1823 continue;
1824
105e1512 1825 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), name);
56352fe9
LP
1826 if (r < 0)
1827 return r;
105e1512
LP
1828 if (r == 0)
1829 continue;
1830
1831 return dt->answer_authenticated;
56352fe9
LP
1832 }
1833
105e1512
LP
1834 /* If in doubt, require NSEC/NSEC3 */
1835 return true;
56352fe9
LP
1836}
1837
547973de
LP
1838int dns_transaction_validate_dnssec(DnsTransaction *t) {
1839 _cleanup_(dns_answer_unrefp) DnsAnswer *validated = NULL;
56352fe9 1840 bool dnskeys_finalized = false;
547973de 1841 DnsResourceRecord *rr;
105e1512 1842 DnsAnswerFlags flags;
56352fe9 1843 int r;
547973de
LP
1844
1845 assert(t);
1846
1847 /* We have now collected all DS and DNSKEY RRs in
1848 * t->validated_keys, let's see which RRs we can now
1849 * authenticate with that. */
1850
1851 if (t->scope->dnssec_mode != DNSSEC_YES)
1852 return 0;
1853
1854 /* Already validated */
1855 if (t->dnssec_result != _DNSSEC_RESULT_INVALID)
1856 return 0;
1857
105e1512 1858 /* Our own stuff needs no validation */
547973de
LP
1859 if (IN_SET(t->answer_source, DNS_TRANSACTION_ZONE, DNS_TRANSACTION_TRUST_ANCHOR)) {
1860 t->dnssec_result = DNSSEC_VALIDATED;
1861 t->answer_authenticated = true;
1862 return 0;
1863 }
1864
105e1512
LP
1865 /* Cached stuff is not affected by validation. */
1866 if (t->answer_source != DNS_TRANSACTION_NETWORK)
1867 return 0;
1868
a5784c49 1869 log_debug("Validating response from transaction %" PRIu16 " (%s).", t->id, dns_transaction_key_string(t));
547973de
LP
1870
1871 /* First see if there are DNSKEYs we already known a validated DS for. */
56352fe9
LP
1872 r = dns_transaction_validate_dnskey_by_ds(t);
1873 if (r < 0)
1874 return r;
547973de
LP
1875
1876 for (;;) {
56352fe9 1877 bool changed = false;
547973de
LP
1878
1879 DNS_ANSWER_FOREACH(rr, t->answer) {
1880 DnssecResult result;
1881
1882 if (rr->key->type == DNS_TYPE_RRSIG)
1883 continue;
1884
1885 r = dnssec_verify_rrset_search(t->answer, rr->key, t->validated_keys, USEC_INFINITY, &result);
1886 if (r < 0)
1887 return r;
1888
1889 if (log_get_max_level() >= LOG_DEBUG) {
1890 _cleanup_free_ char *rrs = NULL;
1891
1892 (void) dns_resource_record_to_string(rr, &rrs);
1893 log_debug("Looking at %s: %s", rrs ? strstrip(rrs) : "???", dnssec_result_to_string(result));
1894 }
1895
56352fe9 1896 if (result == DNSSEC_VALIDATED) {
547973de 1897
547973de
LP
1898 if (rr->key->type == DNS_TYPE_DNSKEY) {
1899 /* If we just validated a
1900 * DNSKEY RRset, then let's
1901 * add these keys to the set
1902 * of validated keys for this
1903 * transaction. */
1904
105e1512 1905 r = dns_answer_copy_by_key(&t->validated_keys, t->answer, rr->key, DNS_ANSWER_AUTHENTICATED);
547973de
LP
1906 if (r < 0)
1907 return r;
1908 }
1909
105e1512
LP
1910 /* Add the validated RRset to the new
1911 * list of validated RRsets, and
1912 * remove it from the unvalidated
1913 * RRsets. We mark the RRset as
1914 * authenticated and cacheable. */
1915 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE);
547973de
LP
1916 if (r < 0)
1917 return r;
1918
56352fe9 1919 /* Exit the loop, we dropped something from the answer, start from the beginning */
547973de
LP
1920 changed = true;
1921 break;
1922
56352fe9
LP
1923 } else if (dnskeys_finalized) {
1924 /* If we haven't read all DNSKEYs yet
1925 * a negative result of the validation
1926 * is irrelevant, as there might be
1927 * more DNSKEYs coming. */
547973de 1928
105e1512
LP
1929 if (result == DNSSEC_NO_SIGNATURE) {
1930 r = dns_transaction_requires_rrsig(t, rr);
1931 if (r < 0)
1932 return r;
1933 if (r == 0) {
1934 /* Data does not require signing. In that case, just copy it over,
1935 * but remember that this is by no means authenticated.*/
1936 r = dns_answer_move_by_key(&validated, &t->answer, rr->key, 0);
1937 if (r < 0)
1938 return r;
1939
1940 changed = true;
1941 break;
1942 }
1943 }
1944
56352fe9 1945 r = dns_transaction_is_primary_response(t, rr);
547973de
LP
1946 if (r < 0)
1947 return r;
1948 if (r > 0) {
56352fe9
LP
1949 /* This is a primary response
1950 * to our question, and it
1951 * failed validation. That's
1952 * fatal. */
547973de
LP
1953 t->dnssec_result = result;
1954 return 0;
1955 }
1956
56352fe9
LP
1957 /* This is just some auxiliary
1958 * data. Just remove the RRset and
1959 * continue. */
547973de
LP
1960 r = dns_answer_remove_by_key(&t->answer, rr->key);
1961 if (r < 0)
1962 return r;
1963
56352fe9 1964 /* Exit the loop, we dropped something from the answer, start from the beginning */
547973de
LP
1965 changed = true;
1966 break;
547973de 1967 }
547973de
LP
1968 }
1969
1970 if (changed)
1971 continue;
1972
56352fe9
LP
1973 if (!dnskeys_finalized) {
1974 /* OK, now we know we have added all DNSKEYs
1975 * we possibly could to our validated
1976 * list. Now run the whole thing once more,
1977 * and strip everything we still cannot
1978 * validate.
1979 */
1980 dnskeys_finalized = true;
1981 continue;
547973de
LP
1982 }
1983
56352fe9 1984 /* We're done */
547973de
LP
1985 break;
1986 }
1987
1988 dns_answer_unref(t->answer);
1989 t->answer = validated;
1990 validated = NULL;
1991
72667f08
LP
1992 /* At this point the answer only contains validated
1993 * RRsets. Now, let's see if it actually answers the question
1994 * we asked. If so, great! If it doesn't, then see if
1995 * NSEC/NSEC3 can prove this. */
105e1512 1996 r = dns_transaction_has_positive_answer(t, &flags);
72667f08 1997 if (r > 0) {
105e1512
LP
1998 /* Yes, it answers the question! */
1999
2000 if (flags & DNS_ANSWER_AUTHENTICATED) {
2001 /* The answer is fully authenticated, yay. */
2002 t->dnssec_result = DNSSEC_VALIDATED;
2003 t->answer_rcode = DNS_RCODE_SUCCESS;
2004 t->answer_authenticated = true;
2005 } else {
2006 /* The answer is not fully authenticated. */
2007 t->dnssec_result = DNSSEC_UNSIGNED;
2008 t->answer_authenticated = false;
2009 }
2010
72667f08
LP
2011 } else if (r == 0) {
2012 DnssecNsecResult nr;
2013
2014 /* Bummer! Let's check NSEC/NSEC3 */
2015 r = dnssec_test_nsec(t->answer, t->key, &nr);
2016 if (r < 0)
2017 return r;
2018
2019 switch (nr) {
2020
2021 case DNSSEC_NSEC_NXDOMAIN:
2022 /* NSEC proves the domain doesn't exist. Very good. */
105e1512 2023 log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t->id, dns_transaction_key_string(t));
72667f08
LP
2024 t->dnssec_result = DNSSEC_VALIDATED;
2025 t->answer_rcode = DNS_RCODE_NXDOMAIN;
2026 t->answer_authenticated = true;
2027 break;
2028
2029 case DNSSEC_NSEC_NODATA:
2030 /* NSEC proves that there's no data here, very good. */
105e1512 2031 log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t->id, dns_transaction_key_string(t));
72667f08
LP
2032 t->dnssec_result = DNSSEC_VALIDATED;
2033 t->answer_rcode = DNS_RCODE_SUCCESS;
2034 t->answer_authenticated = true;
2035 break;
2036
105e1512
LP
2037 case DNSSEC_NSEC_OPTOUT:
2038 /* NSEC3 says the data might not be signed */
2039 log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t->id, dns_transaction_key_string(t));
2040 t->dnssec_result = DNSSEC_UNSIGNED;
2041 t->answer_authenticated = false;
2042 break;
2043
72667f08
LP
2044 case DNSSEC_NSEC_NO_RR:
2045 /* No NSEC data? Bummer! */
105e1512
LP
2046
2047 r = dns_transaction_requires_nsec(t);
2048 if (r < 0)
2049 return r;
2050 if (r > 0)
2051 t->dnssec_result = DNSSEC_NO_SIGNATURE;
2052 else {
2053 t->dnssec_result = DNSSEC_UNSIGNED;
2054 t->answer_authenticated = false;
2055 }
2056
2057 break;
2058
2059 case DNSSEC_NSEC_UNSUPPORTED_ALGORITHM:
2060 /* We don't know the NSEC3 algorithm used? */
2061 t->dnssec_result = DNSSEC_UNSUPPORTED_ALGORITHM;
72667f08
LP
2062 break;
2063
2064 case DNSSEC_NSEC_FOUND:
2065 /* NSEC says it needs to be there, but we couldn't find it? Bummer! */
2066 t->dnssec_result = DNSSEC_NSEC_MISMATCH;
2067 break;
2068
2069 default:
2070 assert_not_reached("Unexpected NSEC result.");
2071 }
2072 }
2073
547973de
LP
2074 return 1;
2075}
2076
a5784c49
LP
2077const char *dns_transaction_key_string(DnsTransaction *t) {
2078 assert(t);
2079
2080 if (!t->key_string) {
2081 if (dns_resource_key_to_string(t->key, &t->key_string) < 0)
2082 return "n/a";
2083 }
2084
2085 return strstrip(t->key_string);
2086}
2087
ec2c5e43
LP
2088static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX] = {
2089 [DNS_TRANSACTION_NULL] = "null",
2090 [DNS_TRANSACTION_PENDING] = "pending",
547973de 2091 [DNS_TRANSACTION_VALIDATING] = "validating",
ec2c5e43
LP
2092 [DNS_TRANSACTION_FAILURE] = "failure",
2093 [DNS_TRANSACTION_SUCCESS] = "success",
2094 [DNS_TRANSACTION_NO_SERVERS] = "no-servers",
2095 [DNS_TRANSACTION_TIMEOUT] = "timeout",
2096 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED] = "attempts-max-reached",
2097 [DNS_TRANSACTION_INVALID_REPLY] = "invalid-reply",
2098 [DNS_TRANSACTION_RESOURCES] = "resources",
2099 [DNS_TRANSACTION_ABORTED] = "aborted",
547973de 2100 [DNS_TRANSACTION_DNSSEC_FAILED] = "dnssec-failed",
ec2c5e43
LP
2101};
2102DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);
c3bc53e6
LP
2103
2104static const char* const dns_transaction_source_table[_DNS_TRANSACTION_SOURCE_MAX] = {
2105 [DNS_TRANSACTION_NETWORK] = "network",
2106 [DNS_TRANSACTION_CACHE] = "cache",
2107 [DNS_TRANSACTION_ZONE] = "zone",
0d2cd476 2108 [DNS_TRANSACTION_TRUST_ANCHOR] = "trust-anchor",
c3bc53e6
LP
2109};
2110DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source, DnsTransactionSource);