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