]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-transaction.c
resolved: support for DNS-over-TLS
[thirdparty/systemd.git] / src / resolve / resolved-dns-transaction.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
ec2c5e43
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2014 Lennart Poettering
ec2c5e43
LP
6***/
7
62cc1c55 8#include "sd-messages.h"
beef6a5f 9
ec2c5e43 10#include "af-list.h"
b5efdb8a 11#include "alloc-util.h"
f52e61da 12#include "dns-domain.h"
7cc6ed7b 13#include "errno-list.h"
3ffd4af2
LP
14#include "fd-util.h"
15#include "random-util.h"
7778dfff 16#include "resolved-dns-cache.h"
3ffd4af2
LP
17#include "resolved-dns-transaction.h"
18#include "resolved-llmnr.h"
8b43440b 19#include "string-table.h"
ec2c5e43 20
5d67a7ae
IT
21#if HAVE_GNUTLS
22#include <gnutls/socket.h>
23#endif
24
b214dc0f 25#define TRANSACTIONS_MAX 4096
dc349f5f 26#define TRANSACTION_TCP_TIMEOUT_USEC (10U*USEC_PER_SEC)
b214dc0f 27
c61d2b44
LP
28static void dns_transaction_reset_answer(DnsTransaction *t) {
29 assert(t);
30
31 t->received = dns_packet_unref(t->received);
32 t->answer = dns_answer_unref(t->answer);
33 t->answer_rcode = 0;
34 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
35 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
36 t->answer_authenticated = false;
d3760be0 37 t->answer_nsec_ttl = (uint32_t) -1;
7cc6ed7b 38 t->answer_errno = 0;
c61d2b44
LP
39}
40
c5b4f861
LP
41static void dns_transaction_flush_dnssec_transactions(DnsTransaction *t) {
42 DnsTransaction *z;
43
44 assert(t);
45
46 while ((z = set_steal_first(t->dnssec_transactions))) {
47 set_remove(z->notify_transactions, t);
35aa04e9 48 set_remove(z->notify_transactions_done, t);
c5b4f861
LP
49 dns_transaction_gc(z);
50 }
51}
52
f32f0e57
LP
53static void dns_transaction_close_connection(DnsTransaction *t) {
54 assert(t);
55
b30bf55d
LP
56 if (t->stream) {
57 /* Let's detach the stream from our transaction, in case something else keeps a reference to it. */
98767d75
IT
58 LIST_REMOVE(transactions_by_stream, t->stream->transactions, t);
59
60 /* Remove packet in case it's still in the queue */
61 dns_packet_unref(ordered_set_remove(t->stream->write_queue, t->sent));
62
b30bf55d
LP
63 t->stream = dns_stream_unref(t->stream);
64 }
65
f32f0e57
LP
66 t->dns_udp_event_source = sd_event_source_unref(t->dns_udp_event_source);
67 t->dns_udp_fd = safe_close(t->dns_udp_fd);
68}
69
f535705a 70static void dns_transaction_stop_timeout(DnsTransaction *t) {
97cc656c
LP
71 assert(t);
72
73 t->timeout_event_source = sd_event_source_unref(t->timeout_event_source);
97cc656c
LP
74}
75
ec2c5e43 76DnsTransaction* dns_transaction_free(DnsTransaction *t) {
801ad6a6 77 DnsQueryCandidate *c;
ec2c5e43 78 DnsZoneItem *i;
547973de 79 DnsTransaction *z;
ec2c5e43
LP
80
81 if (!t)
82 return NULL;
83
51e399bc
LP
84 log_debug("Freeing transaction %" PRIu16 ".", t->id);
85
f32f0e57 86 dns_transaction_close_connection(t);
f535705a 87 dns_transaction_stop_timeout(t);
ec2c5e43 88
ec2c5e43 89 dns_packet_unref(t->sent);
c61d2b44 90 dns_transaction_reset_answer(t);
ec2c5e43 91
8300ba21 92 dns_server_unref(t->server);
ec2c5e43
LP
93
94 if (t->scope) {
f9ebb22a
LP
95 hashmap_remove_value(t->scope->transactions_by_key, t->key, t);
96 LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
ec2c5e43
LP
97
98 if (t->id != 0)
99 hashmap_remove(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id));
100 }
101
547973de 102 while ((c = set_steal_first(t->notify_query_candidates)))
801ad6a6 103 set_remove(c->transactions, t);
547973de 104 set_free(t->notify_query_candidates);
801ad6a6 105
35aa04e9
LP
106 while ((c = set_steal_first(t->notify_query_candidates_done)))
107 set_remove(c->transactions, t);
108 set_free(t->notify_query_candidates_done);
109
547973de 110 while ((i = set_steal_first(t->notify_zone_items)))
ec2c5e43 111 i->probe_transaction = NULL;
547973de
LP
112 set_free(t->notify_zone_items);
113
35aa04e9
LP
114 while ((i = set_steal_first(t->notify_zone_items_done)))
115 i->probe_transaction = NULL;
116 set_free(t->notify_zone_items_done);
117
547973de
LP
118 while ((z = set_steal_first(t->notify_transactions)))
119 set_remove(z->dnssec_transactions, t);
120 set_free(t->notify_transactions);
121
35aa04e9
LP
122 while ((z = set_steal_first(t->notify_transactions_done)))
123 set_remove(z->dnssec_transactions, t);
124 set_free(t->notify_transactions_done);
125
c5b4f861 126 dns_transaction_flush_dnssec_transactions(t);
547973de
LP
127 set_free(t->dnssec_transactions);
128
129 dns_answer_unref(t->validated_keys);
97cc656c 130 dns_resource_key_unref(t->key);
97cc656c 131
6b430fdb 132 return mfree(t);
ec2c5e43
LP
133}
134
135DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_free);
136
51e399bc 137bool dns_transaction_gc(DnsTransaction *t) {
ec2c5e43
LP
138 assert(t);
139
140 if (t->block_gc > 0)
51e399bc 141 return true;
ec2c5e43 142
547973de 143 if (set_isempty(t->notify_query_candidates) &&
35aa04e9 144 set_isempty(t->notify_query_candidates_done) &&
547973de 145 set_isempty(t->notify_zone_items) &&
35aa04e9
LP
146 set_isempty(t->notify_zone_items_done) &&
147 set_isempty(t->notify_transactions) &&
148 set_isempty(t->notify_transactions_done)) {
ec2c5e43 149 dns_transaction_free(t);
51e399bc
LP
150 return false;
151 }
152
153 return true;
ec2c5e43
LP
154}
155
4dd15077
LP
156static uint16_t pick_new_id(Manager *m) {
157 uint16_t new_id;
158
159 /* Find a fresh, unused transaction id. Note that this loop is bounded because there's a limit on the number of
160 * transactions, and it's much lower than the space of IDs. */
161
162 assert_cc(TRANSACTIONS_MAX < 0xFFFF);
163
164 do
165 random_bytes(&new_id, sizeof(new_id));
166 while (new_id == 0 ||
167 hashmap_get(m->dns_transactions, UINT_TO_PTR(new_id)));
168
169 return new_id;
170}
171
f52e61da 172int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key) {
ec2c5e43
LP
173 _cleanup_(dns_transaction_freep) DnsTransaction *t = NULL;
174 int r;
175
176 assert(ret);
177 assert(s);
f52e61da 178 assert(key);
ec2c5e43 179
9eae2bf3 180 /* Don't allow looking up invalid or pseudo RRs */
c463eb78 181 if (!dns_type_is_valid_query(key->type))
9eae2bf3 182 return -EINVAL;
d0129ddb
LP
183 if (dns_type_is_obsolete(key->type))
184 return -EOPNOTSUPP;
9eae2bf3
LP
185
186 /* We only support the IN class */
4c701096 187 if (!IN_SET(key->class, DNS_CLASS_IN, DNS_CLASS_ANY))
9eae2bf3
LP
188 return -EOPNOTSUPP;
189
b214dc0f
LP
190 if (hashmap_size(s->manager->dns_transactions) >= TRANSACTIONS_MAX)
191 return -EBUSY;
192
d5099efc 193 r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL);
ec2c5e43
LP
194 if (r < 0)
195 return r;
196
f9ebb22a 197 r = hashmap_ensure_allocated(&s->transactions_by_key, &dns_resource_key_hash_ops);
da0c630e
LP
198 if (r < 0)
199 return r;
200
ec2c5e43
LP
201 t = new0(DnsTransaction, 1);
202 if (!t)
203 return -ENOMEM;
204
4667e00a 205 t->dns_udp_fd = -1;
c3bc53e6 206 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
019036a4 207 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
d3760be0 208 t->answer_nsec_ttl = (uint32_t) -1;
f52e61da 209 t->key = dns_resource_key_ref(key);
274b8748 210 t->current_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID;
d001e0a3 211 t->clamp_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID;
ec2c5e43 212
4dd15077 213 t->id = pick_new_id(s->manager);
ec2c5e43
LP
214
215 r = hashmap_put(s->manager->dns_transactions, UINT_TO_PTR(t->id), t);
216 if (r < 0) {
217 t->id = 0;
218 return r;
219 }
220
f9ebb22a 221 r = hashmap_replace(s->transactions_by_key, t->key, t);
da0c630e
LP
222 if (r < 0) {
223 hashmap_remove(s->manager->dns_transactions, UINT_TO_PTR(t->id));
224 return r;
225 }
226
f9ebb22a 227 LIST_PREPEND(transactions_by_scope, s->transactions, t);
ec2c5e43
LP
228 t->scope = s;
229
313cefa1 230 s->manager->n_transactions_total++;
a150ff5e 231
ec2c5e43
LP
232 if (ret)
233 *ret = t;
234
235 t = NULL;
236
237 return 0;
238}
239
4dd15077
LP
240static void dns_transaction_shuffle_id(DnsTransaction *t) {
241 uint16_t new_id;
242 assert(t);
243
244 /* Pick a new ID for this transaction. */
245
246 new_id = pick_new_id(t->scope->manager);
247 assert_se(hashmap_remove_and_put(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id), UINT_TO_PTR(new_id), t) >= 0);
248
249 log_debug("Transaction %" PRIu16 " is now %" PRIu16 ".", t->id, new_id);
250 t->id = new_id;
251
252 /* Make sure we generate a new packet with the new ID */
253 t->sent = dns_packet_unref(t->sent);
254}
255
ec2c5e43 256static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
2fb3034c 257 _cleanup_free_ char *pretty = NULL;
202b76ae 258 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
ec2c5e43 259 DnsZoneItem *z;
ec2c5e43
LP
260
261 assert(t);
262 assert(p);
263
264 if (manager_our_packet(t->scope->manager, p) != 0)
265 return;
266
164d025d 267 (void) in_addr_to_string(p->family, &p->sender, &pretty);
2fb3034c 268
a5784c49
LP
269 log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s got tentative packet from %s.",
270 t->id,
202b76ae 271 dns_resource_key_to_string(t->key, key_str, sizeof key_str),
ec2c5e43
LP
272 dns_protocol_to_string(t->scope->protocol),
273 t->scope->link ? t->scope->link->name : "*",
202b76ae 274 af_to_name_short(t->scope->family),
164d025d 275 strnull(pretty));
ec2c5e43 276
a4076574
LP
277 /* RFC 4795, Section 4.1 says that the peer with the
278 * lexicographically smaller IP address loses */
4d91eec4
LP
279 if (memcmp(&p->sender, &p->destination, FAMILY_ADDRESS_SIZE(p->family)) >= 0) {
280 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
a4076574
LP
281 return;
282 }
283
4d91eec4 284 log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
a4076574 285
ec2c5e43 286 t->block_gc++;
35aa04e9 287
547973de 288 while ((z = set_first(t->notify_zone_items))) {
3ef64445
LP
289 /* First, make sure the zone item drops the reference
290 * to us */
291 dns_zone_item_probe_stop(z);
292
293 /* Secondly, report this as conflict, so that we might
294 * look for a different hostname */
ec2c5e43 295 dns_zone_item_conflict(z);
3ef64445 296 }
ec2c5e43
LP
297 t->block_gc--;
298
299 dns_transaction_gc(t);
300}
301
302void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
801ad6a6 303 DnsQueryCandidate *c;
ec2c5e43 304 DnsZoneItem *z;
547973de 305 DnsTransaction *d;
7cc6ed7b 306 const char *st;
202b76ae 307 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
ec2c5e43
LP
308
309 assert(t);
547973de 310 assert(!DNS_TRANSACTION_IS_LIVE(state));
e56187ca 311
202b76ae
ZJS
312 if (state == DNS_TRANSACTION_DNSSEC_FAILED) {
313 dns_resource_key_to_string(t->key, key_str, sizeof key_str);
314
f61dfddb 315 log_struct(LOG_NOTICE,
2b044526 316 "MESSAGE_ID=" SD_MESSAGE_DNSSEC_FAILURE_STR,
202b76ae 317 LOG_MESSAGE("DNSSEC validation failed for question %s: %s", key_str, dnssec_result_to_string(t->answer_dnssec_result)),
f61dfddb 318 "DNS_TRANSACTION=%" PRIu16, t->id,
202b76ae 319 "DNS_QUESTION=%s", key_str,
f61dfddb 320 "DNSSEC_RESULT=%s", dnssec_result_to_string(t->answer_dnssec_result),
1e02e182 321 "DNS_SERVER=%s", dns_server_string(t->server),
a1230ff9 322 "DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(t->server->possible_feature_level));
202b76ae 323 }
f61dfddb 324
ec2c5e43
LP
325 /* Note that this call might invalidate the query. Callers
326 * should hence not attempt to access the query or transaction
327 * after calling this function. */
328
7cc6ed7b
LP
329 if (state == DNS_TRANSACTION_ERRNO)
330 st = errno_to_name(t->answer_errno);
331 else
332 st = dns_transaction_state_to_string(state);
333
a5784c49
LP
334 log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s now complete with <%s> from %s (%s).",
335 t->id,
202b76ae 336 dns_resource_key_to_string(t->key, key_str, sizeof key_str),
ec2c5e43
LP
337 dns_protocol_to_string(t->scope->protocol),
338 t->scope->link ? t->scope->link->name : "*",
202b76ae 339 af_to_name_short(t->scope->family),
7cc6ed7b 340 st,
a5784c49
LP
341 t->answer_source < 0 ? "none" : dns_transaction_source_to_string(t->answer_source),
342 t->answer_authenticated ? "authenticated" : "unsigned");
ec2c5e43
LP
343
344 t->state = state;
345
f32f0e57 346 dns_transaction_close_connection(t);
f535705a 347 dns_transaction_stop_timeout(t);
ec2c5e43
LP
348
349 /* Notify all queries that are interested, but make sure the
350 * transaction isn't freed while we are still looking at it */
351 t->block_gc++;
f7014757 352
35aa04e9 353 SET_FOREACH_MOVE(c, t->notify_query_candidates_done, t->notify_query_candidates)
547973de 354 dns_query_candidate_notify(c);
35aa04e9 355 SWAP_TWO(t->notify_query_candidates, t->notify_query_candidates_done);
ec2c5e43 356
35aa04e9
LP
357 SET_FOREACH_MOVE(z, t->notify_zone_items_done, t->notify_zone_items)
358 dns_zone_item_notify(z);
359 SWAP_TWO(t->notify_zone_items, t->notify_zone_items_done);
8d67e72c 360 if (t->probing && t->state == DNS_TRANSACTION_ATTEMPTS_MAX_REACHED)
1a63fc54 361 (void) dns_scope_announce(t->scope, false);
f7014757 362
35aa04e9
LP
363 SET_FOREACH_MOVE(d, t->notify_transactions_done, t->notify_transactions)
364 dns_transaction_notify(d, t);
365 SWAP_TWO(t->notify_transactions, t->notify_transactions_done);
f7014757
LP
366
367 t->block_gc--;
ec2c5e43
LP
368 dns_transaction_gc(t);
369}
370
519ef046
LP
371static int dns_transaction_pick_server(DnsTransaction *t) {
372 DnsServer *server;
373
374 assert(t);
375 assert(t->scope->protocol == DNS_PROTOCOL_DNS);
376
d001e0a3
LP
377 /* Pick a DNS server and a feature level for it. */
378
519ef046
LP
379 server = dns_scope_get_dns_server(t->scope);
380 if (!server)
381 return -ESRCH;
382
d001e0a3
LP
383 /* If we changed the server invalidate the feature level clamping, as the new server might have completely
384 * different properties. */
385 if (server != t->server)
386 t->clamp_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID;
387
274b8748 388 t->current_feature_level = dns_server_possible_feature_level(server);
519ef046 389
d001e0a3
LP
390 /* Clamp the feature level if that is requested. */
391 if (t->clamp_feature_level != _DNS_SERVER_FEATURE_LEVEL_INVALID &&
392 t->current_feature_level > t->clamp_feature_level)
393 t->current_feature_level = t->clamp_feature_level;
394
395 log_debug("Using feature level %s for transaction %u.", dns_server_feature_level_to_string(t->current_feature_level), t->id);
396
519ef046
LP
397 if (server == t->server)
398 return 0;
399
400 dns_server_unref(t->server);
401 t->server = dns_server_ref(server);
402
44db02d0
LP
403 t->n_picked_servers ++;
404
d001e0a3
LP
405 log_debug("Using DNS server %s for transaction %u.", dns_server_string(t->server), t->id);
406
519ef046
LP
407 return 1;
408}
409
d001e0a3 410static void dns_transaction_retry(DnsTransaction *t, bool next_server) {
8d10d620
LP
411 int r;
412
413 assert(t);
414
415 log_debug("Retrying transaction %" PRIu16 ".", t->id);
416
417 /* Before we try again, switch to a new server. */
d001e0a3
LP
418 if (next_server)
419 dns_scope_next_dns_server(t->scope);
8d10d620
LP
420
421 r = dns_transaction_go(t);
7cc6ed7b
LP
422 if (r < 0) {
423 t->answer_errno = -r;
424 dns_transaction_complete(t, DNS_TRANSACTION_ERRNO);
425 }
8d10d620
LP
426}
427
c02cf2f4 428static int dns_transaction_maybe_restart(DnsTransaction *t) {
5278bbfe
LP
429 int r;
430
c02cf2f4
LP
431 assert(t);
432
5278bbfe
LP
433 /* Returns > 0 if the transaction was restarted, 0 if not */
434
c02cf2f4
LP
435 if (!t->server)
436 return 0;
437
438 if (t->current_feature_level <= dns_server_possible_feature_level(t->server))
439 return 0;
440
441 /* The server's current feature level is lower than when we sent the original query. We learnt something from
442 the response or possibly an auxiliary DNSSEC response that we didn't know before. We take that as reason to
443 restart the whole transaction. This is a good idea to deal with servers that respond rubbish if we include
444 OPT RR or DO bit. One of these cases is documented here, for example:
445 https://open.nlnetlabs.nl/pipermail/dnssec-trigger/2014-November/000376.html */
446
4dd15077
LP
447 log_debug("Server feature level is now lower than when we began our transaction. Restarting with new ID.");
448 dns_transaction_shuffle_id(t);
5278bbfe
LP
449
450 r = dns_transaction_go(t);
451 if (r < 0)
452 return r;
453
454 return 1;
c02cf2f4
LP
455}
456
98767d75
IT
457static void on_transaction_stream_error(DnsTransaction *t, int error) {
458 assert(t);
ec2c5e43 459
b30bf55d 460 dns_transaction_close_connection(t);
ec2c5e43 461
a1a3f73a 462 if (ERRNO_IS_DISCONNECT(error)) {
0791110f
LP
463 if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
464 /* If the LLMNR/TCP connection failed, the host doesn't support LLMNR, and we cannot answer the
465 * question on this scope. */
466 dns_transaction_complete(t, DNS_TRANSACTION_NOT_FOUND);
0791110f
LP
467 }
468
d001e0a3 469 dns_transaction_retry(t, true);
ac720200 470 }
ec2c5e43 471 if (error != 0) {
7cc6ed7b
LP
472 t->answer_errno = error;
473 dns_transaction_complete(t, DNS_TRANSACTION_ERRNO);
ec2c5e43 474 }
98767d75
IT
475}
476
477static int dns_transaction_on_stream_packet(DnsTransaction *t, DnsPacket *p) {
478 assert(t);
479 assert(p);
480
481 dns_transaction_close_connection(t);
ec2c5e43 482
a4076574 483 if (dns_packet_validate_reply(p) <= 0) {
a20b9592 484 log_debug("Invalid TCP reply packet.");
a4076574
LP
485 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
486 return 0;
487 }
488
489 dns_scope_check_conflicts(t->scope, p);
490
ec2c5e43
LP
491 t->block_gc++;
492 dns_transaction_process_reply(t, p);
493 t->block_gc--;
494
519ef046
LP
495 /* If the response wasn't useful, then complete the transition
496 * now. After all, we are the worst feature set now with TCP
497 * sockets, and there's really no point in retrying. */
ec2c5e43
LP
498 if (t->state == DNS_TRANSACTION_PENDING)
499 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
598f44bd
LP
500 else
501 dns_transaction_gc(t);
ec2c5e43
LP
502
503 return 0;
504}
505
5d67a7ae
IT
506static int on_stream_connection(DnsStream *s) {
507#if HAVE_GNUTLS
508 /* Store TLS Ticket for faster succesive TLS handshakes */
509 if (s->tls_session && s->server) {
510 if (s->server->tls_session_data.data)
511 gnutls_free(s->server->tls_session_data.data);
512
513 gnutls_session_get_data2(s->tls_session, &s->server->tls_session_data);
514 }
515#endif
516
517 return 0;
518}
519
98767d75
IT
520static int on_stream_complete(DnsStream *s, int error) {
521 DnsTransaction *t, *n;
522 int r = 0;
523
524 /* Do not let new transactions use this stream */
525 if (s->server && s->server->stream == s)
526 s->server->stream = dns_stream_unref(s->server->stream);
527
528 if (ERRNO_IS_DISCONNECT(error) && s->protocol != DNS_PROTOCOL_LLMNR) {
529 usec_t usec;
530
531 log_debug_errno(error, "Connection failure for DNS TCP stream: %m");
532
533 if (s->transactions) {
534 t = s->transactions;
535 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
536 dns_server_packet_lost(t->server, IPPROTO_UDP, t->current_feature_level, usec - t->start_usec);
537 }
538 }
539
540 LIST_FOREACH_SAFE(transactions_by_stream, t, n, s->transactions)
541 if (error != 0)
542 on_transaction_stream_error(t, error);
543 else if (DNS_PACKET_ID(s->read_packet) == t->id)
544 /* As each transaction have a unique id the return code is only set once */
545 r = dns_transaction_on_stream_packet(t, s->read_packet);
546
547 return r;
548}
549
550static int dns_stream_on_packet(DnsStream *s) {
551 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
552 int r = 0;
553 DnsTransaction *t;
554
555 /* Take ownership of packet to be able to receive new packets */
556 p = TAKE_PTR(s->read_packet);
557 s->n_read = 0;
558
559 t = hashmap_get(s->manager->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
560
561 /* Ignore incorrect transaction id as transaction can have been canceled */
562 if (t)
563 r = dns_transaction_on_stream_packet(t, p);
564 else {
565 if (dns_packet_validate_reply(p) <= 0) {
566 log_debug("Invalid TCP reply packet.");
567 on_stream_complete(s, 0);
568 }
569 return 0;
570 }
571
572 return r;
573}
574
575static int dns_transaction_emit_tcp(DnsTransaction *t) {
ec2c5e43 576 _cleanup_close_ int fd = -1;
98767d75 577 _cleanup_(dns_stream_unrefp) DnsStream *s = NULL;
91ccab1e 578 union sockaddr_union sa;
ec2c5e43 579 int r;
5d67a7ae
IT
580#if HAVE_GNUTLS
581 gnutls_session_t gs;
582#endif
ec2c5e43
LP
583
584 assert(t);
585
519ef046 586 dns_transaction_close_connection(t);
ec2c5e43 587
106784eb 588 switch (t->scope->protocol) {
519ef046 589
106784eb 590 case DNS_PROTOCOL_DNS:
519ef046
LP
591 r = dns_transaction_pick_server(t);
592 if (r < 0)
593 return r;
594
92ec902a 595 if (!dns_server_dnssec_supported(t->server) && dns_type_is_dnssec(t->key->type))
91adc4db
LP
596 return -EOPNOTSUPP;
597
274b8748 598 r = dns_server_adjust_opt(t->server, t->sent, t->current_feature_level);
519ef046
LP
599 if (r < 0)
600 return r;
601
5d67a7ae 602 if (t->server->stream && (DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level) == t->server->stream->encrypted))
98767d75
IT
603 s = dns_stream_ref(t->server->stream);
604 else
5d67a7ae 605 fd = dns_scope_socket_tcp(t->scope, AF_UNSPEC, NULL, t->server, DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level) ? 853 : 53, &sa);
98767d75 606
106784eb 607 break;
ec2c5e43 608
106784eb 609 case DNS_PROTOCOL_LLMNR:
a8f6397f 610 /* When we already received a reply to this (but it was truncated), send to its sender address */
ec2c5e43 611 if (t->received)
91ccab1e 612 fd = dns_scope_socket_tcp(t->scope, t->received->family, &t->received->sender, NULL, t->received->sender_port, &sa);
ec2c5e43
LP
613 else {
614 union in_addr_union address;
a7f7d1bd 615 int family = AF_UNSPEC;
ec2c5e43
LP
616
617 /* Otherwise, try to talk to the owner of a
618 * the IP address, in case this is a reverse
619 * PTR lookup */
f52e61da 620
1c02e7ba 621 r = dns_name_address(dns_resource_key_name(t->key), &family, &address);
ec2c5e43
LP
622 if (r < 0)
623 return r;
624 if (r == 0)
625 return -EINVAL;
9e08a6e0 626 if (family != t->scope->family)
9318cdd3 627 return -ESRCH;
ec2c5e43 628
91ccab1e 629 fd = dns_scope_socket_tcp(t->scope, family, &address, NULL, LLMNR_PORT, &sa);
ec2c5e43 630 }
106784eb
DM
631
632 break;
633
634 default:
ec2c5e43 635 return -EAFNOSUPPORT;
106784eb 636 }
ec2c5e43 637
98767d75
IT
638 if (!s) {
639 if (fd < 0)
640 return fd;
ec2c5e43 641
91ccab1e 642 r = dns_stream_new(t->scope->manager, &s, t->scope->protocol, fd, &sa);
98767d75
IT
643 if (r < 0)
644 return r;
645
646 fd = -1;
647
648 if (t->server) {
649 dns_stream_unref(t->server->stream);
650 t->server->stream = dns_stream_ref(s);
651 s->server = dns_server_ref(t->server);
652 }
653
5d67a7ae
IT
654#if HAVE_GNUTLS
655 if (DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level)) {
656 r = gnutls_init(&gs, GNUTLS_CLIENT | GNUTLS_ENABLE_FALSE_START | GNUTLS_NONBLOCK);
657 if (r < 0)
658 return r;
659
660 /* As DNS-over-TLS is a recent protocol, older TLS versions can be disabled */
661 r = gnutls_priority_set_direct(gs, "NORMAL:-VERS-ALL:+VERS-TLS1.2", NULL);
662 if (r < 0)
663 return r;
664
665 r = gnutls_credentials_set(gs, GNUTLS_CRD_CERTIFICATE, t->server->tls_cert_cred);
666 if (r < 0)
667 return r;
668
669 if (t->server && t->server->tls_session_data.size > 0)
670 gnutls_session_set_data(gs, t->server->tls_session_data.data, t->server->tls_session_data.size);
671
672 gnutls_handshake_set_timeout(gs, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
673
674 r = dns_stream_connect_tls(s, gs);
675 if (r < 0)
676 return r;
677 }
678#endif
679
680 s->on_connection = on_stream_connection;
98767d75
IT
681 s->complete = on_stream_complete;
682 s->on_packet = dns_stream_on_packet;
683
684 /* The interface index is difficult to determine if we are
685 * connecting to the local host, hence fill this in right away
686 * instead of determining it from the socket */
687 s->ifindex = dns_scope_ifindex(t->scope);
688 }
689
690 t->stream = TAKE_PTR(s);
691 LIST_PREPEND(transactions_by_stream, t->stream->transactions, t);
ec2c5e43
LP
692
693 r = dns_stream_write_packet(t->stream, t->sent);
694 if (r < 0) {
98767d75 695 dns_transaction_close_connection(t);
ec2c5e43
LP
696 return r;
697 }
698
519ef046
LP
699 dns_transaction_reset_answer(t);
700
cbe4216d
LP
701 t->tried_stream = true;
702
ec2c5e43
LP
703 return 0;
704}
705
547973de 706static void dns_transaction_cache_answer(DnsTransaction *t) {
547973de
LP
707 assert(t);
708
709 /* For mDNS we cache whenever we get the packet, rather than
710 * in each transaction. */
711 if (!IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR))
712 return;
713
ceeddf79
MP
714 /* Caching disabled? */
715 if (!t->scope->manager->enable_cache)
716 return;
717
547973de
LP
718 /* We never cache if this packet is from the local host, under
719 * the assumption that a locally running DNS server would
720 * cache this anyway, and probably knows better when to flush
721 * the cache then we could. */
722 if (!DNS_PACKET_SHALL_CACHE(t->received))
723 return;
724
547973de
LP
725 dns_cache_put(&t->scope->cache,
726 t->key,
727 t->answer_rcode,
728 t->answer,
547973de 729 t->answer_authenticated,
d3760be0 730 t->answer_nsec_ttl,
547973de
LP
731 0,
732 t->received->family,
733 &t->received->sender);
734}
735
105e1512
LP
736static bool dns_transaction_dnssec_is_live(DnsTransaction *t) {
737 DnsTransaction *dt;
738 Iterator i;
739
740 assert(t);
741
742 SET_FOREACH(dt, t->dnssec_transactions, i)
743 if (DNS_TRANSACTION_IS_LIVE(dt->state))
744 return true;
745
746 return false;
747}
748
942eb2e7
LP
749static int dns_transaction_dnssec_ready(DnsTransaction *t) {
750 DnsTransaction *dt;
751 Iterator i;
752
753 assert(t);
754
755 /* Checks whether the auxiliary DNSSEC transactions of our transaction have completed, or are still
756 * ongoing. Returns 0, if we aren't ready for the DNSSEC validation, positive if we are. */
757
758 SET_FOREACH(dt, t->dnssec_transactions, i) {
759
760 switch (dt->state) {
761
762 case DNS_TRANSACTION_NULL:
763 case DNS_TRANSACTION_PENDING:
764 case DNS_TRANSACTION_VALIDATING:
765 /* Still ongoing */
766 return 0;
767
768 case DNS_TRANSACTION_RCODE_FAILURE:
b3c6b00a 769 if (!IN_SET(dt->answer_rcode, DNS_RCODE_NXDOMAIN, DNS_RCODE_SERVFAIL)) {
942eb2e7
LP
770 log_debug("Auxiliary DNSSEC RR query failed with rcode=%s.", dns_rcode_to_string(dt->answer_rcode));
771 goto fail;
772 }
773
b3c6b00a
LP
774 /* Fall-through: NXDOMAIN/SERVFAIL is good enough for us. This is because some DNS servers
775 * erronously return NXDOMAIN/SERVFAIL for empty non-terminals (Akamai...) or missing DS
776 * records (Facebook), and we need to handle that nicely, when asking for parent SOA or similar
777 * RRs to make unsigned proofs. */
942eb2e7
LP
778
779 case DNS_TRANSACTION_SUCCESS:
780 /* All good. */
781 break;
782
783 case DNS_TRANSACTION_DNSSEC_FAILED:
784 /* We handle DNSSEC failures different from other errors, as we care about the DNSSEC
785 * validationr result */
786
787 log_debug("Auxiliary DNSSEC RR query failed validation: %s", dnssec_result_to_string(dt->answer_dnssec_result));
788 t->answer_dnssec_result = dt->answer_dnssec_result; /* Copy error code over */
789 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
790 return 0;
791
942eb2e7
LP
792 default:
793 log_debug("Auxiliary DNSSEC RR query failed with %s", dns_transaction_state_to_string(dt->state));
794 goto fail;
795 }
796 }
797
798 /* All is ready, we can go and validate */
799 return 1;
800
801fail:
802 t->answer_dnssec_result = DNSSEC_FAILED_AUXILIARY;
803 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
804 return 0;
805}
806
547973de
LP
807static void dns_transaction_process_dnssec(DnsTransaction *t) {
808 int r;
809
810 assert(t);
811
812 /* Are there ongoing DNSSEC transactions? If so, let's wait for them. */
942eb2e7 813 r = dns_transaction_dnssec_ready(t);
7cc6ed7b
LP
814 if (r < 0)
815 goto fail;
942eb2e7 816 if (r == 0) /* We aren't ready yet (or one of our auxiliary transactions failed, and we shouldn't validate now */
547973de
LP
817 return;
818
c02cf2f4
LP
819 /* See if we learnt things from the additional DNSSEC transactions, that we didn't know before, and better
820 * restart the lookup immediately. */
821 r = dns_transaction_maybe_restart(t);
7cc6ed7b
LP
822 if (r < 0)
823 goto fail;
c02cf2f4
LP
824 if (r > 0) /* Transaction got restarted... */
825 return;
826
547973de
LP
827 /* All our auxiliary DNSSEC transactions are complete now. Try
828 * to validate our RRset now. */
829 r = dns_transaction_validate_dnssec(t);
fcfaff12
LP
830 if (r == -EBADMSG) {
831 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
832 return;
833 }
7cc6ed7b
LP
834 if (r < 0)
835 goto fail;
547973de 836
b652d4a2
LP
837 if (t->answer_dnssec_result == DNSSEC_INCOMPATIBLE_SERVER &&
838 t->scope->dnssec_mode == DNSSEC_YES) {
e82b1132
LP
839
840 /* We are not in automatic downgrade mode, and the server is bad. Let's try a different server, maybe
841 * that works. */
842
843 if (t->n_picked_servers < dns_scope_get_n_dns_servers(t->scope)) {
844 /* We tried fewer servers on this transaction than we know, let's try another one then */
845 dns_transaction_retry(t, true);
846 return;
847 }
848
849 /* OK, let's give up, apparently all servers we tried didn't work. */
b652d4a2
LP
850 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
851 return;
852 }
853
019036a4 854 if (!IN_SET(t->answer_dnssec_result,
b652d4a2
LP
855 _DNSSEC_RESULT_INVALID, /* No DNSSEC validation enabled */
856 DNSSEC_VALIDATED, /* Answer is signed and validated successfully */
857 DNSSEC_UNSIGNED, /* Answer is right-fully unsigned */
858 DNSSEC_INCOMPATIBLE_SERVER)) { /* Server does not do DNSSEC (Yay, we are downgrade attack vulnerable!) */
547973de
LP
859 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
860 return;
861 }
862
1e02e182
LP
863 if (t->answer_dnssec_result == DNSSEC_INCOMPATIBLE_SERVER)
864 dns_server_warn_downgrade(t->server);
865
547973de
LP
866 dns_transaction_cache_answer(t);
867
868 if (t->answer_rcode == DNS_RCODE_SUCCESS)
869 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
870 else
3bbdc31d 871 dns_transaction_complete(t, DNS_TRANSACTION_RCODE_FAILURE);
7cc6ed7b
LP
872
873 return;
874
875fail:
876 t->answer_errno = -r;
877 dns_transaction_complete(t, DNS_TRANSACTION_ERRNO);
547973de
LP
878}
879
eac7cda2
LP
880static int dns_transaction_has_positive_answer(DnsTransaction *t, DnsAnswerFlags *flags) {
881 int r;
882
883 assert(t);
884
885 /* Checks whether the answer is positive, i.e. either a direct
886 * answer to the question, or a CNAME/DNAME for it */
887
888 r = dns_answer_match_key(t->answer, t->key, flags);
889 if (r != 0)
890 return r;
891
892 r = dns_answer_find_cname_or_dname(t->answer, t->key, NULL, flags);
893 if (r != 0)
894 return r;
895
896 return false;
897}
898
899static int dns_transaction_fix_rcode(DnsTransaction *t) {
900 int r;
901
902 assert(t);
903
904 /* Fix up the RCODE to SUCCESS if we get at least one matching RR in a response. Note that this contradicts the
905 * DNS RFCs a bit. Specifically, RFC 6604 Section 3 clarifies that the RCODE shall say something about a
906 * CNAME/DNAME chain element coming after the last chain element contained in the message, and not the first
907 * one included. However, it also indicates that not all DNS servers implement this correctly. Moreover, when
908 * using DNSSEC we usually only can prove the first element of a CNAME/DNAME chain anyway, hence let's settle
909 * on always processing the RCODE as referring to the immediate look-up we do, i.e. the first element of a
910 * CNAME/DNAME chain. This way, we uniformly handle CNAME/DNAME chains, regardless if the DNS server
911 * incorrectly implements RCODE, whether DNSSEC is in use, or whether the DNS server only supplied us with an
912 * incomplete CNAME/DNAME chain.
913 *
914 * Or in other words: if we get at least one positive reply in a message we patch NXDOMAIN to become SUCCESS,
915 * and then rely on the CNAME chasing logic to figure out that there's actually a CNAME error with a new
916 * lookup. */
917
918 if (t->answer_rcode != DNS_RCODE_NXDOMAIN)
919 return 0;
920
921 r = dns_transaction_has_positive_answer(t, NULL);
922 if (r <= 0)
923 return r;
924
925 t->answer_rcode = DNS_RCODE_SUCCESS;
926 return 0;
927}
928
ec2c5e43 929void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
9df3ba6c 930 usec_t ts;
ec2c5e43
LP
931 int r;
932
933 assert(t);
934 assert(p);
9df3ba6c
TG
935 assert(t->scope);
936 assert(t->scope->manager);
ec2c5e43 937
5a7e41a3
LP
938 if (t->state != DNS_TRANSACTION_PENDING)
939 return;
940
ec2c5e43
LP
941 /* Note that this call might invalidate the query. Callers
942 * should hence not attempt to access the query or transaction
943 * after calling this function. */
944
1fdeaeb7 945 log_debug("Processing incoming packet on transaction %" PRIu16". (rcode=%s)", t->id, dns_rcode_to_string(DNS_PACKET_RCODE(p)));
b5efcf29 946
106784eb 947 switch (t->scope->protocol) {
b5efcf29 948
106784eb 949 case DNS_PROTOCOL_LLMNR:
97ebebbc 950 /* For LLMNR we will not accept any packets from other interfaces */
ec2c5e43 951
97ebebbc 952 if (p->ifindex != dns_scope_ifindex(t->scope))
ec2c5e43
LP
953 return;
954
955 if (p->family != t->scope->family)
956 return;
957
958 /* Tentative packets are not full responses but still
959 * useful for identifying uniqueness conflicts during
960 * probing. */
8b757a38 961 if (DNS_PACKET_LLMNR_T(p)) {
ec2c5e43
LP
962 dns_transaction_tentative(t, p);
963 return;
964 }
106784eb
DM
965
966 break;
967
4e5bf5e1 968 case DNS_PROTOCOL_MDNS:
4e5bf5e1 969 /* For mDNS we will not accept any packets from other interfaces */
97ebebbc
LP
970
971 if (p->ifindex != dns_scope_ifindex(t->scope))
4e5bf5e1
DM
972 return;
973
974 if (p->family != t->scope->family)
975 return;
976
977 break;
978
106784eb 979 case DNS_PROTOCOL_DNS:
8ad182a1
LP
980 /* Note that we do not need to verify the
981 * addresses/port numbers of incoming traffic, as we
982 * invoked connect() on our UDP socket in which case
983 * the kernel already does the needed verification for
984 * us. */
106784eb
DM
985 break;
986
987 default:
9c56a6f3 988 assert_not_reached("Invalid DNS protocol.");
ec2c5e43
LP
989 }
990
ec2c5e43
LP
991 if (t->received != p) {
992 dns_packet_unref(t->received);
993 t->received = dns_packet_ref(p);
994 }
995
c3bc53e6
LP
996 t->answer_source = DNS_TRANSACTION_NETWORK;
997
ec2c5e43
LP
998 if (p->ipproto == IPPROTO_TCP) {
999 if (DNS_PACKET_TC(p)) {
1000 /* Truncated via TCP? Somebody must be fucking with us */
1001 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
1002 return;
1003 }
1004
1005 if (DNS_PACKET_ID(p) != t->id) {
1006 /* Not the reply to our query? Somebody must be fucking with us */
1007 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
1008 return;
1009 }
1010 }
1011
38a03f06 1012 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
9df3ba6c
TG
1013
1014 switch (t->scope->protocol) {
8af5b883 1015
9df3ba6c
TG
1016 case DNS_PROTOCOL_DNS:
1017 assert(t->server);
1018
4e0b8b17
TG
1019 if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_FORMERR, DNS_RCODE_SERVFAIL, DNS_RCODE_NOTIMP)) {
1020
8af5b883 1021 /* Request failed, immediately try again with reduced features */
4e0b8b17 1022
7d581a65 1023 if (t->current_feature_level <= DNS_SERVER_FEATURE_LEVEL_UDP) {
44db02d0 1024
7d581a65 1025 /* This was already at UDP feature level? If so, it doesn't make sense to downgrade
44db02d0
LP
1026 * this transaction anymore, but let's see if it might make sense to send the request
1027 * to a different DNS server instead. If not let's process the response, and accept the
7d581a65
LP
1028 * rcode. Note that we don't retry on TCP, since that's a suitable way to mitigate
1029 * packet loss, but is not going to give us better rcodes should we actually have
1030 * managed to get them already at UDP level. */
1031
44db02d0
LP
1032 if (t->n_picked_servers < dns_scope_get_n_dns_servers(t->scope)) {
1033 /* We tried fewer servers on this transaction than we know, let's try another one then */
1034 dns_transaction_retry(t, true);
1035 return;
1036 }
1037
1038 /* Give up, accept the rcode */
d001e0a3
LP
1039 log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p)));
1040 break;
1041 }
1042
1043 /* Reduce this feature level by one and try again. */
5d67a7ae
IT
1044 switch (t->current_feature_level) {
1045 case DNS_SERVER_FEATURE_LEVEL_TLS_DO:
1046 t->clamp_feature_level = DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN;
1047 break;
1048 case DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN + 1:
1049 /* Skip plain TLS when TLS is not supported */
1050 t->clamp_feature_level = DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN - 1;
1051 break;
1052 default:
1053 t->clamp_feature_level = t->current_feature_level - 1;
1054 }
d001e0a3
LP
1055
1056 log_debug("Server returned error %s, retrying transaction with reduced feature level %s.",
1057 dns_rcode_to_string(DNS_PACKET_RCODE(p)),
1058 dns_server_feature_level_to_string(t->clamp_feature_level));
1059
1060 dns_transaction_retry(t, false /* use the same server */);
4e0b8b17 1061 return;
eb08640a
LP
1062 }
1063
1064 if (DNS_PACKET_RCODE(p) == DNS_RCODE_REFUSED) {
1065 /* This server refused our request? If so, try again, use a different server */
1066 log_debug("Server returned REFUSED, switching servers, and retrying.");
1067 dns_transaction_retry(t, true /* pick a new server */);
1068 return;
1069 }
1070
1071 if (DNS_PACKET_TC(p))
274b8748 1072 dns_server_packet_truncated(t->server, t->current_feature_level);
9df3ba6c
TG
1073
1074 break;
8af5b883 1075
9df3ba6c
TG
1076 case DNS_PROTOCOL_LLMNR:
1077 case DNS_PROTOCOL_MDNS:
1078 dns_scope_packet_received(t->scope, ts - t->start_usec);
9df3ba6c 1079 break;
8af5b883 1080
9df3ba6c 1081 default:
8af5b883 1082 assert_not_reached("Invalid DNS protocol.");
9df3ba6c
TG
1083 }
1084
ec2c5e43 1085 if (DNS_PACKET_TC(p)) {
547493c5
DM
1086
1087 /* Truncated packets for mDNS are not allowed. Give up immediately. */
1088 if (t->scope->protocol == DNS_PROTOCOL_MDNS) {
1089 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
1090 return;
1091 }
1092
f757cd85
LP
1093 log_debug("Reply truncated, retrying via TCP.");
1094
ec2c5e43 1095 /* Response was truncated, let's try again with good old TCP */
98767d75 1096 r = dns_transaction_emit_tcp(t);
ec2c5e43
LP
1097 if (r == -ESRCH) {
1098 /* No servers found? Damn! */
1099 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
1100 return;
1101 }
91adc4db
LP
1102 if (r == -EOPNOTSUPP) {
1103 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC */
1104 dns_transaction_complete(t, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED);
1105 return;
1106 }
ec2c5e43 1107 if (r < 0) {
8af5b883 1108 /* On LLMNR, if we cannot connect to the host,
ec2c5e43 1109 * we immediately give up */
7cc6ed7b
LP
1110 if (t->scope->protocol != DNS_PROTOCOL_DNS)
1111 goto fail;
ec2c5e43
LP
1112
1113 /* On DNS, couldn't send? Try immediately again, with a new server */
d001e0a3 1114 dns_transaction_retry(t, true);
ec2c5e43 1115 }
2a6658ef
LP
1116
1117 return;
ec2c5e43
LP
1118 }
1119
de54e62b 1120 /* After the superficial checks, actually parse the message. */
ec2c5e43
LP
1121 r = dns_packet_extract(p);
1122 if (r < 0) {
1123 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
1124 return;
1125 }
1126
ed9717fc 1127 if (t->server) {
d001e0a3
LP
1128 /* Report that we successfully received a valid packet with a good rcode after we initially got a bad
1129 * rcode and subsequently downgraded the protocol */
1130
1131 if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN) &&
1132 t->clamp_feature_level != _DNS_SERVER_FEATURE_LEVEL_INVALID)
1133 dns_server_packet_rcode_downgrade(t->server, t->clamp_feature_level);
1134
1135 /* Report that the OPT RR was missing */
ed9717fc
LP
1136 if (!p->opt)
1137 dns_server_packet_bad_opt(t->server, t->current_feature_level);
1138
d001e0a3 1139 /* Report that we successfully received a packet */
ed9717fc
LP
1140 dns_server_packet_received(t->server, p->ipproto, t->current_feature_level, ts - t->start_usec, p->size);
1141 }
de54e62b 1142
c02cf2f4
LP
1143 /* See if we know things we didn't know before that indicate we better restart the lookup immediately. */
1144 r = dns_transaction_maybe_restart(t);
7cc6ed7b
LP
1145 if (r < 0)
1146 goto fail;
c02cf2f4
LP
1147 if (r > 0) /* Transaction got restarted... */
1148 return;
1149
8b419837 1150 if (IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR, DNS_PROTOCOL_MDNS)) {
b5efcf29 1151
8b419837
DR
1152 /* When dealing with protocols other than mDNS only consider responses with
1153 * equivalent query section to the request. For mDNS this check doesn't make
1154 * sense, because the section 6 of RFC6762 states that "Multicast DNS responses MUST NOT
1155 * contain any questions in the Question Section". */
1156 if (t->scope->protocol != DNS_PROTOCOL_MDNS) {
1157 r = dns_packet_is_reply_for(p, t->key);
1158 if (r < 0)
1159 goto fail;
1160 if (r == 0) {
1161 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
1162 return;
1163 }
547493c5 1164 }
29815b6c 1165
547493c5
DM
1166 /* Install the answer as answer to the transaction */
1167 dns_answer_unref(t->answer);
1168 t->answer = dns_answer_ref(p->answer);
1169 t->answer_rcode = DNS_PACKET_RCODE(p);
919c2ae0 1170 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
105e1512 1171 t->answer_authenticated = false;
79e24931 1172
eac7cda2
LP
1173 r = dns_transaction_fix_rcode(t);
1174 if (r < 0)
1175 goto fail;
1176
51e399bc
LP
1177 /* Block GC while starting requests for additional DNSSEC RRs */
1178 t->block_gc++;
547973de 1179 r = dns_transaction_request_dnssec_keys(t);
51e399bc
LP
1180 t->block_gc--;
1181
1182 /* Maybe the transaction is ready for GC'ing now? If so, free it and return. */
1183 if (!dns_transaction_gc(t))
1184 return;
1185
1186 /* Requesting additional keys might have resulted in
1187 * this transaction to fail, since the auxiliary
1188 * request failed for some reason. If so, we are not
1189 * in pending state anymore, and we should exit
1190 * quickly. */
1191 if (t->state != DNS_TRANSACTION_PENDING)
1192 return;
7cc6ed7b
LP
1193 if (r < 0)
1194 goto fail;
547973de
LP
1195 if (r > 0) {
1196 /* There are DNSSEC transactions pending now. Update the state accordingly. */
1197 t->state = DNS_TRANSACTION_VALIDATING;
f535705a
LP
1198 dns_transaction_close_connection(t);
1199 dns_transaction_stop_timeout(t);
547973de
LP
1200 return;
1201 }
547493c5 1202 }
ec2c5e43 1203
547973de 1204 dns_transaction_process_dnssec(t);
7cc6ed7b
LP
1205 return;
1206
1207fail:
1208 t->answer_errno = -r;
1209 dns_transaction_complete(t, DNS_TRANSACTION_ERRNO);
ec2c5e43
LP
1210}
1211
c19ffd9f
TG
1212static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1213 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1214 DnsTransaction *t = userdata;
1215 int r;
1216
1217 assert(t);
1218 assert(t->scope);
1219
1220 r = manager_recv(t->scope->manager, fd, DNS_PROTOCOL_DNS, &p);
7e1851e3
LP
1221 if (ERRNO_IS_DISCONNECT(-r)) {
1222 usec_t usec;
c19ffd9f 1223
7e1851e3
LP
1224 /* UDP connection failure get reported via ICMP and then are possible delivered to us on the next
1225 * recvmsg(). Treat this like a lost packet. */
1226
92ec902a 1227 log_debug_errno(r, "Connection failure for DNS UDP packet: %m");
7e1851e3 1228 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
274b8748 1229 dns_server_packet_lost(t->server, IPPROTO_UDP, t->current_feature_level, usec - t->start_usec);
7e1851e3 1230
d001e0a3 1231 dns_transaction_retry(t, true);
7e1851e3
LP
1232 return 0;
1233 }
1234 if (r < 0) {
7cc6ed7b
LP
1235 dns_transaction_complete(t, DNS_TRANSACTION_ERRNO);
1236 t->answer_errno = -r;
7e1851e3
LP
1237 return 0;
1238 }
1239
1240 r = dns_packet_validate_reply(p);
1241 if (r < 0) {
1242 log_debug_errno(r, "Received invalid DNS packet as response, ignoring: %m");
1243 return 0;
1244 }
1245 if (r == 0) {
e09f605e 1246 log_debug("Received inappropriate DNS packet as response, ignoring.");
7e1851e3
LP
1247 return 0;
1248 }
1249
1250 if (DNS_PACKET_ID(p) != t->id) {
e09f605e 1251 log_debug("Received packet with incorrect transaction ID, ignoring.");
7e1851e3
LP
1252 return 0;
1253 }
c19ffd9f 1254
7e1851e3 1255 dns_transaction_process_reply(t, p);
c19ffd9f
TG
1256 return 0;
1257}
1258
49cce12d 1259static int dns_transaction_emit_udp(DnsTransaction *t) {
c19ffd9f
TG
1260 int r;
1261
1262 assert(t);
c19ffd9f 1263
519ef046 1264 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
c19ffd9f 1265
519ef046 1266 r = dns_transaction_pick_server(t);
471d40d9
TG
1267 if (r < 0)
1268 return r;
c19ffd9f 1269
5d67a7ae 1270 if (t->current_feature_level < DNS_SERVER_FEATURE_LEVEL_UDP || DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level))
7d581a65 1271 return -EAGAIN; /* Sorry, can't do UDP, try TCP! */
519ef046 1272
92ec902a 1273 if (!dns_server_dnssec_supported(t->server) && dns_type_is_dnssec(t->key->type))
91adc4db
LP
1274 return -EOPNOTSUPP;
1275
519ef046
LP
1276 if (r > 0 || t->dns_udp_fd < 0) { /* Server changed, or no connection yet. */
1277 int fd;
1278
1279 dns_transaction_close_connection(t);
c19ffd9f 1280
519ef046
LP
1281 fd = dns_scope_socket_udp(t->scope, t->server, 53);
1282 if (fd < 0)
1283 return fd;
1284
1285 r = sd_event_add_io(t->scope->manager->event, &t->dns_udp_event_source, fd, EPOLLIN, on_dns_packet, t);
1286 if (r < 0) {
1287 safe_close(fd);
1288 return r;
1289 }
1290
aa4a9deb 1291 (void) sd_event_source_set_description(t->dns_udp_event_source, "dns-transaction-udp");
519ef046
LP
1292 t->dns_udp_fd = fd;
1293 }
1294
274b8748 1295 r = dns_server_adjust_opt(t->server, t->sent, t->current_feature_level);
519ef046
LP
1296 if (r < 0)
1297 return r;
1298 } else
1299 dns_transaction_close_connection(t);
1300
1301 r = dns_scope_emit_udp(t->scope, t->dns_udp_fd, t->sent);
471d40d9
TG
1302 if (r < 0)
1303 return r;
c19ffd9f 1304
519ef046 1305 dns_transaction_reset_answer(t);
be808ea0 1306
471d40d9 1307 return 0;
c19ffd9f
TG
1308}
1309
ec2c5e43
LP
1310static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
1311 DnsTransaction *t = userdata;
ec2c5e43
LP
1312
1313 assert(s);
1314 assert(t);
1315
ef7ce6df
DM
1316 if (!t->initial_jitter_scheduled || t->initial_jitter_elapsed) {
1317 /* Timeout reached? Increase the timeout for the server used */
1318 switch (t->scope->protocol) {
49cce12d 1319
ef7ce6df
DM
1320 case DNS_PROTOCOL_DNS:
1321 assert(t->server);
274b8748 1322 dns_server_packet_lost(t->server, t->stream ? IPPROTO_TCP : IPPROTO_UDP, t->current_feature_level, usec - t->start_usec);
ef7ce6df 1323 break;
49cce12d 1324
ef7ce6df
DM
1325 case DNS_PROTOCOL_LLMNR:
1326 case DNS_PROTOCOL_MDNS:
1327 dns_scope_packet_lost(t->scope, usec - t->start_usec);
ef7ce6df 1328 break;
49cce12d 1329
ef7ce6df
DM
1330 default:
1331 assert_not_reached("Invalid DNS protocol.");
1332 }
1333
1334 if (t->initial_jitter_scheduled)
1335 t->initial_jitter_elapsed = true;
be808ea0
TG
1336 }
1337
423659ab
LP
1338 log_debug("Timeout reached on transaction %" PRIu16 ".", t->id);
1339
d001e0a3 1340 dns_transaction_retry(t, true);
ec2c5e43
LP
1341 return 0;
1342}
1343
9df3ba6c
TG
1344static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
1345 assert(t);
1346 assert(t->scope);
1347
1348 switch (t->scope->protocol) {
49cce12d 1349
9df3ba6c 1350 case DNS_PROTOCOL_DNS:
dc349f5f
LP
1351
1352 /* When we do TCP, grant a much longer timeout, as in this case there's no need for us to quickly
1353 * resend, as the kernel does that anyway for us, and we really don't want to interrupt it in that
1354 * needlessly. */
1355 if (t->stream)
1356 return TRANSACTION_TCP_TIMEOUT_USEC;
1357
9df3ba6c 1358 assert(t->server);
9df3ba6c 1359 return t->server->resend_timeout;
49cce12d 1360
9df3ba6c 1361 case DNS_PROTOCOL_MDNS:
11a27c2e 1362 assert(t->n_attempts > 0);
53fda2bb
DR
1363 if (t->probing)
1364 return MDNS_PROBING_INTERVAL_USEC;
1365 else
1366 return (1 << (t->n_attempts - 1)) * USEC_PER_SEC;
49cce12d 1367
11a27c2e 1368 case DNS_PROTOCOL_LLMNR:
9df3ba6c 1369 return t->scope->resend_timeout;
49cce12d 1370
9df3ba6c
TG
1371 default:
1372 assert_not_reached("Invalid DNS protocol.");
1373 }
1374}
1375
c842ff24 1376static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
ec2c5e43
LP
1377 int r;
1378
1379 assert(t);
1380
f535705a 1381 dns_transaction_stop_timeout(t);
ec2c5e43 1382
edbcc1fd
LP
1383 r = dns_scope_network_good(t->scope);
1384 if (r < 0)
1385 return r;
1386 if (r == 0) {
1387 dns_transaction_complete(t, DNS_TRANSACTION_NETWORK_DOWN);
1388 return 0;
1389 }
1390
ec2c5e43
LP
1391 if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t->scope->protocol)) {
1392 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
1393 return 0;
1394 }
1395
cbe4216d 1396 if (t->scope->protocol == DNS_PROTOCOL_LLMNR && t->tried_stream) {
ec2c5e43
LP
1397 /* If we already tried via a stream, then we don't
1398 * retry on LLMNR. See RFC 4795, Section 2.7. */
1399 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
1400 return 0;
1401 }
1402
1403 t->n_attempts++;
9df3ba6c 1404 t->start_usec = ts;
c61d2b44
LP
1405
1406 dns_transaction_reset_answer(t);
c5b4f861 1407 dns_transaction_flush_dnssec_transactions(t);
ec2c5e43 1408
0d2cd476
LP
1409 /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
1410 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
8e54f5d9 1411 r = dns_trust_anchor_lookup_positive(&t->scope->manager->trust_anchor, t->key, &t->answer);
0d2cd476
LP
1412 if (r < 0)
1413 return r;
1414 if (r > 0) {
1415 t->answer_rcode = DNS_RCODE_SUCCESS;
1416 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
931851e8 1417 t->answer_authenticated = true;
0d2cd476
LP
1418 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1419 return 0;
1420 }
b2b796b8 1421
1c02e7ba 1422 if (dns_name_is_root(dns_resource_key_name(t->key)) &&
b2b796b8
LP
1423 t->key->type == DNS_TYPE_DS) {
1424
1425 /* Hmm, this is a request for the root DS? A
1426 * DS RR doesn't exist in the root zone, and
1427 * if our trust anchor didn't know it either,
1428 * this means we cannot do any DNSSEC logic
1429 * anymore. */
1430
1ed8c0fb 1431 if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
b2b796b8
LP
1432 /* We are in downgrade mode. In this
1433 * case, synthesize an unsigned empty
1434 * response, so that the any lookup
1435 * depending on this one can continue
1436 * assuming there was no DS, and hence
1437 * the root zone was unsigned. */
1438
1439 t->answer_rcode = DNS_RCODE_SUCCESS;
1440 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
1441 t->answer_authenticated = false;
1442 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1443 } else
1444 /* If we are not in downgrade mode,
1445 * then fail the lookup, because we
1446 * cannot reasonably answer it. There
1447 * might be DS RRs, but we don't know
1448 * them, and the DNS server won't tell
1449 * them to us (and even if it would,
202b76ae 1450 * we couldn't validate and trust them. */
b2b796b8
LP
1451 dns_transaction_complete(t, DNS_TRANSACTION_NO_TRUST_ANCHOR);
1452
1453 return 0;
1454 }
0d2cd476
LP
1455 }
1456
1457 /* Check the zone, but only if this transaction is not used
d746bb3e 1458 * for probing or verifying a zone item. */
547973de 1459 if (set_isempty(t->notify_zone_items)) {
d746bb3e 1460
97ebebbc 1461 r = dns_zone_lookup(&t->scope->zone, t->key, dns_scope_ifindex(t->scope), &t->answer, NULL, NULL);
d746bb3e
LP
1462 if (r < 0)
1463 return r;
1464 if (r > 0) {
ae6a4bbf 1465 t->answer_rcode = DNS_RCODE_SUCCESS;
c3bc53e6 1466 t->answer_source = DNS_TRANSACTION_ZONE;
931851e8 1467 t->answer_authenticated = true;
d746bb3e
LP
1468 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1469 return 0;
1470 }
1471 }
1472
4d926a69
LP
1473 /* Check the cache, but only if this transaction is not used
1474 * for probing or verifying a zone item. */
547973de 1475 if (set_isempty(t->notify_zone_items)) {
2c27fbca 1476
4d926a69
LP
1477 /* Before trying the cache, let's make sure we figured out a
1478 * server to use. Should this cause a change of server this
1479 * might flush the cache. */
5cdb8930 1480 (void) dns_scope_get_dns_server(t->scope);
2c27fbca 1481
4d926a69
LP
1482 /* Let's then prune all outdated entries */
1483 dns_cache_prune(&t->scope->cache);
1484
17c8de63 1485 r = dns_cache_lookup(&t->scope->cache, t->key, t->clamp_ttl, &t->answer_rcode, &t->answer, &t->answer_authenticated);
4d926a69
LP
1486 if (r < 0)
1487 return r;
1488 if (r > 0) {
c3bc53e6 1489 t->answer_source = DNS_TRANSACTION_CACHE;
ae6a4bbf 1490 if (t->answer_rcode == DNS_RCODE_SUCCESS)
4d926a69
LP
1491 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
1492 else
3bbdc31d 1493 dns_transaction_complete(t, DNS_TRANSACTION_RCODE_FAILURE);
4d926a69
LP
1494 return 0;
1495 }
ec2c5e43
LP
1496 }
1497
1effe965
DM
1498 return 1;
1499}
1500
0afa57e2
DM
1501static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
1502
1503 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
7778dfff 1504 bool add_known_answers = false;
0afa57e2 1505 DnsTransaction *other;
0d5ee47d
DR
1506 Iterator i;
1507 DnsResourceKey *tkey;
1508 _cleanup_set_free_ Set *keys = NULL;
0afa57e2 1509 unsigned qdcount;
0d5ee47d 1510 unsigned nscount = 0;
0afa57e2
DM
1511 usec_t ts;
1512 int r;
1513
1514 assert(t);
1515 assert(t->scope->protocol == DNS_PROTOCOL_MDNS);
1516
e5abebab 1517 /* Discard any previously prepared packet, so we can start over and coalesce again */
0afa57e2
DM
1518 t->sent = dns_packet_unref(t->sent);
1519
1520 r = dns_packet_new_query(&p, t->scope->protocol, 0, false);
1521 if (r < 0)
1522 return r;
1523
58ab31d5 1524 r = dns_packet_append_key(p, t->key, 0, NULL);
0afa57e2
DM
1525 if (r < 0)
1526 return r;
1527
1528 qdcount = 1;
1529
7778dfff
DM
1530 if (dns_key_is_shared(t->key))
1531 add_known_answers = true;
1532
0d5ee47d
DR
1533 if (t->key->type == DNS_TYPE_ANY) {
1534 r = set_ensure_allocated(&keys, &dns_resource_key_hash_ops);
1535 if (r < 0)
1536 return r;
1537
1538 r = set_put(keys, t->key);
1539 if (r < 0)
1540 return r;
1541 }
1542
0afa57e2
DM
1543 /*
1544 * For mDNS, we want to coalesce as many open queries in pending transactions into one single
1545 * query packet on the wire as possible. To achieve that, we iterate through all pending transactions
1546 * in our current scope, and see whether their timing contraints allow them to be sent.
1547 */
1548
1549 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
1550
1551 LIST_FOREACH(transactions_by_scope, other, t->scope->transactions) {
1552
1553 /* Skip ourselves */
1554 if (other == t)
1555 continue;
1556
1557 if (other->state != DNS_TRANSACTION_PENDING)
1558 continue;
1559
1560 if (other->next_attempt_after > ts)
1561 continue;
1562
1563 if (qdcount >= UINT16_MAX)
1564 break;
1565
58ab31d5 1566 r = dns_packet_append_key(p, other->key, 0, NULL);
0afa57e2
DM
1567
1568 /*
1569 * If we can't stuff more questions into the packet, just give up.
1570 * One of the 'other' transactions will fire later and take care of the rest.
1571 */
1572 if (r == -EMSGSIZE)
1573 break;
1574
1575 if (r < 0)
1576 return r;
1577
c842ff24 1578 r = dns_transaction_prepare(other, ts);
0afa57e2
DM
1579 if (r <= 0)
1580 continue;
1581
1582 ts += transaction_get_resend_timeout(other);
1583
1584 r = sd_event_add_time(
1585 other->scope->manager->event,
1586 &other->timeout_event_source,
1587 clock_boottime_or_monotonic(),
1588 ts, 0,
1589 on_transaction_timeout, other);
1590 if (r < 0)
1591 return r;
1592
ff537038 1593 (void) sd_event_source_set_description(other->timeout_event_source, "dns-transaction-timeout");
aa4a9deb 1594
0afa57e2
DM
1595 other->state = DNS_TRANSACTION_PENDING;
1596 other->next_attempt_after = ts;
1597
313cefa1 1598 qdcount++;
7778dfff
DM
1599
1600 if (dns_key_is_shared(other->key))
1601 add_known_answers = true;
0d5ee47d
DR
1602
1603 if (other->key->type == DNS_TYPE_ANY) {
1604 r = set_ensure_allocated(&keys, &dns_resource_key_hash_ops);
1605 if (r < 0)
1606 return r;
1607
1608 r = set_put(keys, other->key);
1609 if (r < 0)
1610 return r;
1611 }
0afa57e2
DM
1612 }
1613
1614 DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount);
0afa57e2 1615
7778dfff
DM
1616 /* Append known answer section if we're asking for any shared record */
1617 if (add_known_answers) {
1618 r = dns_cache_export_shared_to_packet(&t->scope->cache, p);
1619 if (r < 0)
1620 return r;
1621 }
1622
0d5ee47d
DR
1623 SET_FOREACH(tkey, keys, i) {
1624 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1625 bool tentative;
1626
1627 r = dns_zone_lookup(&t->scope->zone, tkey, t->scope->link->ifindex, &answer, NULL, &tentative);
1628 if (r < 0)
1629 return r;
1630
1631 r = dns_packet_append_answer(p, answer);
1632 if (r < 0)
1633 return r;
1634
1635 nscount += dns_answer_size(answer);
1636 }
1637 DNS_PACKET_HEADER(p)->nscount = htobe16(nscount);
1638
1cc6c93a 1639 t->sent = TAKE_PTR(p);
0afa57e2
DM
1640
1641 return 0;
1642}
1643
1644static int dns_transaction_make_packet(DnsTransaction *t) {
1645 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1646 int r;
1647
1648 assert(t);
1649
1650 if (t->scope->protocol == DNS_PROTOCOL_MDNS)
1651 return dns_transaction_make_packet_mdns(t);
1652
1653 if (t->sent)
1654 return 0;
1655
b652d4a2 1656 r = dns_packet_new_query(&p, t->scope->protocol, 0, t->scope->dnssec_mode != DNSSEC_NO);
0afa57e2
DM
1657 if (r < 0)
1658 return r;
1659
58ab31d5 1660 r = dns_packet_append_key(p, t->key, 0, NULL);
0afa57e2
DM
1661 if (r < 0)
1662 return r;
1663
1664 DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
1665 DNS_PACKET_HEADER(p)->id = t->id;
1666
1cc6c93a 1667 t->sent = TAKE_PTR(p);
0afa57e2
DM
1668
1669 return 0;
1670}
1671
1effe965
DM
1672int dns_transaction_go(DnsTransaction *t) {
1673 usec_t ts;
1674 int r;
202b76ae 1675 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
1effe965
DM
1676
1677 assert(t);
1678
5278bbfe
LP
1679 /* Returns > 0 if the transaction is now pending, returns 0 if could be processed immediately and has finished
1680 * now. */
1681
1effe965 1682 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
547973de 1683
c842ff24 1684 r = dns_transaction_prepare(t, ts);
1effe965
DM
1685 if (r <= 0)
1686 return r;
1687
202b76ae 1688 log_debug("Transaction %" PRIu16 " for <%s> scope %s on %s/%s.",
a5784c49 1689 t->id,
202b76ae 1690 dns_resource_key_to_string(t->key, key_str, sizeof key_str),
a5784c49
LP
1691 dns_protocol_to_string(t->scope->protocol),
1692 t->scope->link ? t->scope->link->name : "*",
202b76ae 1693 af_to_name_short(t->scope->family));
1effe965 1694
ef7ce6df 1695 if (!t->initial_jitter_scheduled &&
3742095b 1696 IN_SET(t->scope->protocol, DNS_PROTOCOL_LLMNR, DNS_PROTOCOL_MDNS)) {
ea12bcc7 1697 usec_t jitter, accuracy;
6e068472
LP
1698
1699 /* RFC 4795 Section 2.7 suggests all queries should be
1700 * delayed by a random time from 0 to JITTER_INTERVAL. */
1701
ef7ce6df 1702 t->initial_jitter_scheduled = true;
6e068472
LP
1703
1704 random_bytes(&jitter, sizeof(jitter));
ea12bcc7
DM
1705
1706 switch (t->scope->protocol) {
519ef046 1707
ea12bcc7
DM
1708 case DNS_PROTOCOL_LLMNR:
1709 jitter %= LLMNR_JITTER_INTERVAL_USEC;
1710 accuracy = LLMNR_JITTER_INTERVAL_USEC;
1711 break;
519ef046 1712
ea12bcc7
DM
1713 case DNS_PROTOCOL_MDNS:
1714 jitter %= MDNS_JITTER_RANGE_USEC;
1715 jitter += MDNS_JITTER_MIN_USEC;
1716 accuracy = MDNS_JITTER_RANGE_USEC;
1717 break;
1718 default:
1719 assert_not_reached("bad protocol");
1720 }
6e068472
LP
1721
1722 r = sd_event_add_time(
1723 t->scope->manager->event,
1724 &t->timeout_event_source,
1725 clock_boottime_or_monotonic(),
ea12bcc7 1726 ts + jitter, accuracy,
6e068472
LP
1727 on_transaction_timeout, t);
1728 if (r < 0)
1729 return r;
1730
aa4a9deb
LP
1731 (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
1732
6e068472 1733 t->n_attempts = 0;
a9da14e1 1734 t->next_attempt_after = ts;
6e068472
LP
1735 t->state = DNS_TRANSACTION_PENDING;
1736
ea12bcc7 1737 log_debug("Delaying %s transaction for " USEC_FMT "us.", dns_protocol_to_string(t->scope->protocol), jitter);
6e068472
LP
1738 return 0;
1739 }
1740
ec2c5e43
LP
1741 /* Otherwise, we need to ask the network */
1742 r = dns_transaction_make_packet(t);
ec2c5e43
LP
1743 if (r < 0)
1744 return r;
1745
1746 if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
1c02e7ba
ZJS
1747 (dns_name_endswith(dns_resource_key_name(t->key), "in-addr.arpa") > 0 ||
1748 dns_name_endswith(dns_resource_key_name(t->key), "ip6.arpa") > 0)) {
ec2c5e43
LP
1749
1750 /* RFC 4795, Section 2.4. says reverse lookups shall
1751 * always be made via TCP on LLMNR */
98767d75 1752 r = dns_transaction_emit_tcp(t);
ec2c5e43 1753 } else {
be808ea0
TG
1754 /* Try via UDP, and if that fails due to large size or lack of
1755 * support try via TCP */
49cce12d 1756 r = dns_transaction_emit_udp(t);
29ab0552
LP
1757 if (r == -EMSGSIZE)
1758 log_debug("Sending query via TCP since it is too large.");
dc349f5f 1759 else if (r == -EAGAIN)
5d67a7ae 1760 log_debug("Sending query via TCP since UDP isn't supported.");
4c701096 1761 if (IN_SET(r, -EMSGSIZE, -EAGAIN))
98767d75 1762 r = dns_transaction_emit_tcp(t);
ec2c5e43 1763 }
be808ea0 1764
ec2c5e43
LP
1765 if (r == -ESRCH) {
1766 /* No servers to send this to? */
1767 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
1768 return 0;
91adc4db
LP
1769 }
1770 if (r == -EOPNOTSUPP) {
1771 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC */
1772 dns_transaction_complete(t, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED);
1773 return 0;
1774 }
0791110f 1775 if (t->scope->protocol == DNS_PROTOCOL_LLMNR && ERRNO_IS_DISCONNECT(-r)) {
e94968ba 1776 /* On LLMNR, if we cannot connect to a host via TCP when doing reverse lookups. This means we cannot
0791110f
LP
1777 * answer this request with this protocol. */
1778 dns_transaction_complete(t, DNS_TRANSACTION_NOT_FOUND);
1779 return 0;
1780 }
91adc4db 1781 if (r < 0) {
7cc6ed7b
LP
1782 if (t->scope->protocol != DNS_PROTOCOL_DNS)
1783 return r;
13b551ac 1784
ec2c5e43 1785 /* Couldn't send? Try immediately again, with a new server */
519ef046 1786 dns_scope_next_dns_server(t->scope);
ec2c5e43
LP
1787
1788 return dns_transaction_go(t);
1789 }
1790
a9da14e1
DM
1791 ts += transaction_get_resend_timeout(t);
1792
9a015429
LP
1793 r = sd_event_add_time(
1794 t->scope->manager->event,
1795 &t->timeout_event_source,
1796 clock_boottime_or_monotonic(),
a9da14e1 1797 ts, 0,
9a015429 1798 on_transaction_timeout, t);
ec2c5e43
LP
1799 if (r < 0)
1800 return r;
1801
aa4a9deb
LP
1802 (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
1803
ec2c5e43 1804 t->state = DNS_TRANSACTION_PENDING;
a9da14e1
DM
1805 t->next_attempt_after = ts;
1806
ec2c5e43
LP
1807 return 1;
1808}
1809
f2992dc1
LP
1810static int dns_transaction_find_cyclic(DnsTransaction *t, DnsTransaction *aux) {
1811 DnsTransaction *n;
1812 Iterator i;
1813 int r;
1814
1815 assert(t);
1816 assert(aux);
1817
1818 /* Try to find cyclic dependencies between transaction objects */
1819
1820 if (t == aux)
1821 return 1;
1822
3eb6aa00 1823 SET_FOREACH(n, aux->dnssec_transactions, i) {
f2992dc1
LP
1824 r = dns_transaction_find_cyclic(t, n);
1825 if (r != 0)
1826 return r;
1827 }
1828
3eb6aa00 1829 return 0;
f2992dc1
LP
1830}
1831
547973de
LP
1832static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResourceKey *key, DnsTransaction **ret) {
1833 DnsTransaction *aux;
1834 int r;
1835
1836 assert(t);
1837 assert(ret);
1838 assert(key);
1839
1840 aux = dns_scope_find_transaction(t->scope, key, true);
1841 if (!aux) {
1842 r = dns_transaction_new(&aux, t->scope, key);
1843 if (r < 0)
1844 return r;
1845 } else {
1846 if (set_contains(t->dnssec_transactions, aux)) {
1847 *ret = aux;
1848 return 0;
1849 }
f2992dc1
LP
1850
1851 r = dns_transaction_find_cyclic(t, aux);
1852 if (r < 0)
1853 return r;
1854 if (r > 0) {
202b76ae
ZJS
1855 char s[DNS_RESOURCE_KEY_STRING_MAX], saux[DNS_RESOURCE_KEY_STRING_MAX];
1856
1857 log_debug("Potential cyclic dependency, refusing to add transaction %" PRIu16 " (%s) as dependency for %" PRIu16 " (%s).",
f2992dc1 1858 aux->id,
202b76ae 1859 dns_resource_key_to_string(t->key, s, sizeof s),
f2992dc1 1860 t->id,
202b76ae
ZJS
1861 dns_resource_key_to_string(aux->key, saux, sizeof saux));
1862
f2992dc1
LP
1863 return -ELOOP;
1864 }
547973de
LP
1865 }
1866
1867 r = set_ensure_allocated(&t->dnssec_transactions, NULL);
1868 if (r < 0)
1869 goto gc;
1870
1871 r = set_ensure_allocated(&aux->notify_transactions, NULL);
1872 if (r < 0)
35aa04e9
LP
1873 goto gc;
1874
1875 r = set_ensure_allocated(&aux->notify_transactions_done, NULL);
1876 if (r < 0)
547973de
LP
1877 goto gc;
1878
1879 r = set_put(t->dnssec_transactions, aux);
1880 if (r < 0)
1881 goto gc;
1882
1883 r = set_put(aux->notify_transactions, t);
1884 if (r < 0) {
1885 (void) set_remove(t->dnssec_transactions, aux);
1886 goto gc;
1887 }
1888
1889 *ret = aux;
1890 return 1;
1891
1892gc:
1893 dns_transaction_gc(aux);
1894 return r;
1895}
1896
1897static int dns_transaction_request_dnssec_rr(DnsTransaction *t, DnsResourceKey *key) {
1898 _cleanup_(dns_answer_unrefp) DnsAnswer *a = NULL;
1899 DnsTransaction *aux;
1900 int r;
1901
1902 assert(t);
1903 assert(key);
1904
1905 /* Try to get the data from the trust anchor */
8e54f5d9 1906 r = dns_trust_anchor_lookup_positive(&t->scope->manager->trust_anchor, key, &a);
547973de
LP
1907 if (r < 0)
1908 return r;
1909 if (r > 0) {
1910 r = dns_answer_extend(&t->validated_keys, a);
1911 if (r < 0)
1912 return r;
1913
1914 return 0;
1915 }
1916
1917 /* This didn't work, ask for it via the network/cache then. */
1918 r = dns_transaction_add_dnssec_transaction(t, key, &aux);
f2992dc1
LP
1919 if (r == -ELOOP) /* This would result in a cyclic dependency */
1920 return 0;
547973de
LP
1921 if (r < 0)
1922 return r;
1923
1924 if (aux->state == DNS_TRANSACTION_NULL) {
1925 r = dns_transaction_go(aux);
1926 if (r < 0)
1927 return r;
1928 }
1929
f2992dc1 1930 return 1;
547973de
LP
1931}
1932
8a516214
LP
1933static int dns_transaction_negative_trust_anchor_lookup(DnsTransaction *t, const char *name) {
1934 int r;
1935
1936 assert(t);
1937
c629ff58 1938 /* Check whether the specified name is in the NTA
8a516214
LP
1939 * database, either in the global one, or the link-local
1940 * one. */
1941
1942 r = dns_trust_anchor_lookup_negative(&t->scope->manager->trust_anchor, name);
1943 if (r != 0)
1944 return r;
1945
1946 if (!t->scope->link)
1947 return 0;
1948
1949 return set_contains(t->scope->link->dnssec_negative_trust_anchors, name);
1950}
1951
105e1512
LP
1952static int dns_transaction_has_unsigned_negative_answer(DnsTransaction *t) {
1953 int r;
1954
1955 assert(t);
1956
1957 /* Checks whether the answer is negative, and lacks NSEC/NSEC3
1958 * RRs to prove it */
1959
1960 r = dns_transaction_has_positive_answer(t, NULL);
1961 if (r < 0)
1962 return r;
1963 if (r > 0)
1964 return false;
1965
8e54f5d9
LP
1966 /* Is this key explicitly listed as a negative trust anchor?
1967 * If so, it's nothing we need to care about */
1c02e7ba 1968 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(t->key));
8e54f5d9
LP
1969 if (r < 0)
1970 return r;
1971 if (r > 0)
1972 return false;
1973
105e1512
LP
1974 /* The answer does not contain any RRs that match to the
1975 * question. If so, let's see if there are any NSEC/NSEC3 RRs
1976 * included. If not, the answer is unsigned. */
1977
1978 r = dns_answer_contains_nsec_or_nsec3(t->answer);
1979 if (r < 0)
1980 return r;
1981 if (r > 0)
1982 return false;
1983
1984 return true;
1985}
1986
1987static int dns_transaction_is_primary_response(DnsTransaction *t, DnsResourceRecord *rr) {
1988 int r;
1989
1990 assert(t);
1991 assert(rr);
1992
1993 /* Check if the specified RR is the "primary" response,
1994 * i.e. either matches the question precisely or is a
4cb94977 1995 * CNAME/DNAME for it. */
105e1512
LP
1996
1997 r = dns_resource_key_match_rr(t->key, rr, NULL);
1998 if (r != 0)
1999 return r;
2000
4cb94977 2001 return dns_resource_key_match_cname_or_dname(t->key, rr->key, NULL);
105e1512
LP
2002}
2003
92ec902a
LP
2004static bool dns_transaction_dnssec_supported(DnsTransaction *t) {
2005 assert(t);
2006
2007 /* Checks whether our transaction's DNS server is assumed to be compatible with DNSSEC. Returns false as soon
2008 * as we changed our mind about a server, and now believe it is incompatible with DNSSEC. */
2009
2010 if (t->scope->protocol != DNS_PROTOCOL_DNS)
2011 return false;
2012
2013 /* If we have picked no server, then we are working from the cache or some other source, and DNSSEC might well
2014 * be supported, hence return true. */
2015 if (!t->server)
2016 return true;
2017
d001e0a3
LP
2018 /* Note that we do not check the feature level actually used for the transaction but instead the feature level
2019 * the server is known to support currently, as the transaction feature level might be lower than what the
2020 * server actually supports, since we might have downgraded this transaction's feature level because we got a
2021 * SERVFAIL earlier and wanted to check whether downgrading fixes it. */
92ec902a
LP
2022
2023 return dns_server_dnssec_supported(t->server);
2024}
2025
2026static bool dns_transaction_dnssec_supported_full(DnsTransaction *t) {
2027 DnsTransaction *dt;
2028 Iterator i;
2029
2030 assert(t);
2031
2032 /* Checks whether our transaction our any of the auxiliary transactions couldn't do DNSSEC. */
2033
2034 if (!dns_transaction_dnssec_supported(t))
2035 return false;
2036
2037 SET_FOREACH(dt, t->dnssec_transactions, i)
2038 if (!dns_transaction_dnssec_supported(dt))
2039 return false;
2040
2041 return true;
2042}
2043
547973de
LP
2044int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
2045 DnsResourceRecord *rr;
105e1512 2046
547973de
LP
2047 int r;
2048
2049 assert(t);
2050
105e1512
LP
2051 /*
2052 * Retrieve all auxiliary RRs for the answer we got, so that
2053 * we can verify signatures or prove that RRs are rightfully
2054 * unsigned. Specifically:
2055 *
2056 * - For RRSIG we get the matching DNSKEY
2057 * - For DNSKEY we get the matching DS
2058 * - For unsigned SOA/NS we get the matching DS
b63fca62 2059 * - For unsigned CNAME/DNAME/DS we get the parent SOA RR
105e1512 2060 * - For other unsigned RRs we get the matching SOA RR
4bbc06cc
LP
2061 * - For SOA/NS queries with no matching response RR, and no NSEC/NSEC3, the DS RR
2062 * - For DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
105e1512
LP
2063 * - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR
2064 */
2065
b652d4a2 2066 if (t->scope->dnssec_mode == DNSSEC_NO)
547973de 2067 return 0;
92ec902a
LP
2068 if (t->answer_source != DNS_TRANSACTION_NETWORK)
2069 return 0; /* We only need to validate stuff from the network */
2070 if (!dns_transaction_dnssec_supported(t))
2071 return 0; /* If we can't do DNSSEC anyway there's no point in geting the auxiliary RRs */
b652d4a2 2072
547973de
LP
2073 DNS_ANSWER_FOREACH(rr, t->answer) {
2074
105e1512
LP
2075 if (dns_type_is_pseudo(rr->key->type))
2076 continue;
2077
8e54f5d9 2078 /* If this RR is in the negative trust anchor, we don't need to validate it. */
1c02e7ba 2079 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
8e54f5d9
LP
2080 if (r < 0)
2081 return r;
2082 if (r > 0)
2083 continue;
2084
547973de
LP
2085 switch (rr->key->type) {
2086
2087 case DNS_TYPE_RRSIG: {
2088 /* For each RRSIG we request the matching DNSKEY */
2089 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *dnskey = NULL;
2090
2091 /* If this RRSIG is about a DNSKEY RR and the
2092 * signer is the same as the owner, then we
2093 * already have the DNSKEY, and we don't have
2094 * to look for more. */
2095 if (rr->rrsig.type_covered == DNS_TYPE_DNSKEY) {
1c02e7ba 2096 r = dns_name_equal(rr->rrsig.signer, dns_resource_key_name(rr->key));
547973de
LP
2097 if (r < 0)
2098 return r;
2099 if (r > 0)
2100 continue;
2101 }
2102
105e1512
LP
2103 /* If the signer is not a parent of our
2104 * original query, then this is about an
2105 * auxiliary RRset, but not anything we asked
2106 * for. In this case we aren't interested,
2107 * because we don't want to request additional
2108 * RRs for stuff we didn't really ask for, and
2109 * also to avoid request loops, where
2110 * additional RRs from one transaction result
2111 * in another transaction whose additonal RRs
2112 * point back to the original transaction, and
2113 * we deadlock. */
1c02e7ba 2114 r = dns_name_endswith(dns_resource_key_name(t->key), rr->rrsig.signer);
547973de
LP
2115 if (r < 0)
2116 return r;
2117 if (r == 0)
2118 continue;
2119
2120 dnskey = dns_resource_key_new(rr->key->class, DNS_TYPE_DNSKEY, rr->rrsig.signer);
2121 if (!dnskey)
2122 return -ENOMEM;
2123
1c02e7ba
ZJS
2124 log_debug("Requesting DNSKEY to validate transaction %" PRIu16" (%s, RRSIG with key tag: %" PRIu16 ").",
2125 t->id, dns_resource_key_name(rr->key), rr->rrsig.key_tag);
547973de
LP
2126 r = dns_transaction_request_dnssec_rr(t, dnskey);
2127 if (r < 0)
2128 return r;
2129 break;
2130 }
2131
2132 case DNS_TYPE_DNSKEY: {
2133 /* For each DNSKEY we request the matching DS */
2134 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
2135
105e1512
LP
2136 /* If the DNSKEY we are looking at is not for
2137 * zone we are interested in, nor any of its
2138 * parents, we aren't interested, and don't
2139 * request it. After all, we don't want to end
2140 * up in request loops, and want to keep
2141 * additional traffic down. */
2142
1c02e7ba 2143 r = dns_name_endswith(dns_resource_key_name(t->key), dns_resource_key_name(rr->key));
105e1512
LP
2144 if (r < 0)
2145 return r;
2146 if (r == 0)
2147 continue;
2148
1c02e7ba 2149 ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key));
547973de
LP
2150 if (!ds)
2151 return -ENOMEM;
2152
1c02e7ba
ZJS
2153 log_debug("Requesting DS to validate transaction %" PRIu16" (%s, DNSKEY with key tag: %" PRIu16 ").",
2154 t->id, dns_resource_key_name(rr->key), dnssec_keytag(rr, false));
105e1512
LP
2155 r = dns_transaction_request_dnssec_rr(t, ds);
2156 if (r < 0)
2157 return r;
547973de 2158
105e1512
LP
2159 break;
2160 }
2161
105e1512
LP
2162 case DNS_TYPE_SOA:
2163 case DNS_TYPE_NS: {
2164 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
2165
2166 /* For an unsigned SOA or NS, try to acquire
2167 * the matching DS RR, as we are at a zone cut
2168 * then, and whether a DS exists tells us
2169 * whether the zone is signed. Do so only if
2170 * this RR matches our original question,
2171 * however. */
2172
2173 r = dns_resource_key_match_rr(t->key, rr, NULL);
2174 if (r < 0)
2175 return r;
6993d264
LP
2176 if (r == 0) {
2177 /* Hmm, so this SOA RR doesn't match our original question. In this case, maybe this is
2178 * a negative reply, and we need the a SOA RR's TTL in order to cache a negative entry?
2179 * If so, we need to validate it, too. */
2180
2181 r = dns_answer_match_key(t->answer, t->key, NULL);
2182 if (r < 0)
2183 return r;
2184 if (r > 0) /* positive reply, we won't need the SOA and hence don't need to validate
2185 * it. */
2186 continue;
2187 }
105e1512
LP
2188
2189 r = dnssec_has_rrsig(t->answer, rr->key);
2190 if (r < 0)
2191 return r;
2192 if (r > 0)
2193 continue;
2194
1c02e7ba 2195 ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key));
105e1512
LP
2196 if (!ds)
2197 return -ENOMEM;
2198
1c02e7ba
ZJS
2199 log_debug("Requesting DS to validate transaction %" PRIu16 " (%s, unsigned SOA/NS RRset).",
2200 t->id, dns_resource_key_name(rr->key));
547973de
LP
2201 r = dns_transaction_request_dnssec_rr(t, ds);
2202 if (r < 0)
2203 return r;
2204
2205 break;
105e1512
LP
2206 }
2207
b63fca62 2208 case DNS_TYPE_DS:
105e1512
LP
2209 case DNS_TYPE_CNAME:
2210 case DNS_TYPE_DNAME: {
2211 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
2212 const char *name;
2213
2214 /* CNAMEs and DNAMEs cannot be located at a
2215 * zone apex, hence ask for the parent SOA for
2216 * unsigned CNAME/DNAME RRs, maybe that's the
2217 * apex. But do all that only if this is
2218 * actually a response to our original
b63fca62
LP
2219 * question.
2220 *
2221 * Similar for DS RRs, which are signed when
2222 * the parent SOA is signed. */
105e1512
LP
2223
2224 r = dns_transaction_is_primary_response(t, rr);
2225 if (r < 0)
2226 return r;
2227 if (r == 0)
2228 continue;
2229
2230 r = dnssec_has_rrsig(t->answer, rr->key);
2231 if (r < 0)
2232 return r;
2233 if (r > 0)
2234 continue;
2235
43e6779a
LP
2236 r = dns_answer_has_dname_for_cname(t->answer, rr);
2237 if (r < 0)
2238 return r;
2239 if (r > 0)
2240 continue;
2241
1c02e7ba 2242 name = dns_resource_key_name(rr->key);
105e1512
LP
2243 r = dns_name_parent(&name);
2244 if (r < 0)
2245 return r;
2246 if (r == 0)
2247 continue;
2248
2249 soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, name);
2250 if (!soa)
2251 return -ENOMEM;
2252
1c02e7ba
ZJS
2253 log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned CNAME/DNAME/DS RRset).",
2254 t->id, dns_resource_key_name(rr->key));
105e1512
LP
2255 r = dns_transaction_request_dnssec_rr(t, soa);
2256 if (r < 0)
2257 return r;
2258
2259 break;
2260 }
2261
2262 default: {
2263 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
2264
b63fca62
LP
2265 /* For other unsigned RRsets (including
2266 * NSEC/NSEC3!), look for proof the zone is
2267 * unsigned, by requesting the SOA RR of the
2268 * zone. However, do so only if they are
2269 * directly relevant to our original
105e1512
LP
2270 * question. */
2271
2272 r = dns_transaction_is_primary_response(t, rr);
2273 if (r < 0)
2274 return r;
2275 if (r == 0)
2276 continue;
2277
2278 r = dnssec_has_rrsig(t->answer, rr->key);
2279 if (r < 0)
2280 return r;
2281 if (r > 0)
2282 continue;
2283
1c02e7ba 2284 soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, dns_resource_key_name(rr->key));
105e1512
LP
2285 if (!soa)
2286 return -ENOMEM;
2287
1c02e7ba
ZJS
2288 log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned non-SOA/NS RRset <%s>).",
2289 t->id, dns_resource_key_name(rr->key), dns_resource_record_to_string(rr));
105e1512
LP
2290 r = dns_transaction_request_dnssec_rr(t, soa);
2291 if (r < 0)
2292 return r;
2293 break;
547973de
LP
2294 }}
2295 }
2296
105e1512
LP
2297 /* Above, we requested everything necessary to validate what
2298 * we got. Now, let's request what we need to validate what we
2299 * didn't get... */
2300
2301 r = dns_transaction_has_unsigned_negative_answer(t);
2302 if (r < 0)
2303 return r;
2304 if (r > 0) {
2305 const char *name;
4bbc06cc 2306 uint16_t type = 0;
105e1512 2307
1c02e7ba 2308 name = dns_resource_key_name(t->key);
105e1512 2309
4bbc06cc
LP
2310 /* If this was a SOA or NS request, then check if there's a DS RR for the same domain. Note that this
2311 * could also be used as indication that we are not at a zone apex, but in real world setups there are
2312 * too many broken DNS servers (Hello, incapdns.net!) where non-terminal zones return NXDOMAIN even
2313 * though they have further children. If this was a DS request, then it's signed when the parent zone
2314 * is signed, hence ask the parent SOA in that case. If this was any other RR then ask for the SOA RR,
2315 * to see if that is signed. */
105e1512 2316
4bbc06cc 2317 if (t->key->type == DNS_TYPE_DS) {
105e1512 2318 r = dns_name_parent(&name);
4bbc06cc
LP
2319 if (r > 0) {
2320 type = DNS_TYPE_SOA;
2321 log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned empty DS response).",
1c02e7ba 2322 t->id, dns_resource_key_name(t->key));
4bbc06cc 2323 } else
105e1512 2324 name = NULL;
4bbc06cc
LP
2325
2326 } else if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS)) {
2327
2328 type = DNS_TYPE_DS;
2329 log_debug("Requesting DS to validate transaction %" PRIu16 " (%s, unsigned empty SOA/NS response).",
2330 t->id, dns_resource_key_name(t->key));
2331
2332 } else {
2333 type = DNS_TYPE_SOA;
1c02e7ba
ZJS
2334 log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned empty non-SOA/NS/DS response).",
2335 t->id, dns_resource_key_name(t->key));
4bbc06cc 2336 }
105e1512
LP
2337
2338 if (name) {
2339 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
2340
4bbc06cc 2341 soa = dns_resource_key_new(t->key->class, type, name);
105e1512
LP
2342 if (!soa)
2343 return -ENOMEM;
2344
2345 r = dns_transaction_request_dnssec_rr(t, soa);
2346 if (r < 0)
2347 return r;
2348 }
2349 }
2350
2351 return dns_transaction_dnssec_is_live(t);
547973de
LP
2352}
2353
2354void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source) {
547973de 2355 assert(t);
547973de
LP
2356 assert(source);
2357
942eb2e7
LP
2358 /* Invoked whenever any of our auxiliary DNSSEC transactions completed its work. If the state is still PENDING,
2359 we are still in the loop that adds further DNSSEC transactions, hence don't check if we are ready yet. If
2360 the state is VALIDATING however, we should check if we are complete now. */
105e1512 2361
942eb2e7
LP
2362 if (t->state == DNS_TRANSACTION_VALIDATING)
2363 dns_transaction_process_dnssec(t);
547973de
LP
2364}
2365
105e1512
LP
2366static int dns_transaction_validate_dnskey_by_ds(DnsTransaction *t) {
2367 DnsResourceRecord *rr;
2368 int ifindex, r;
2369
2370 assert(t);
2371
2372 /* Add all DNSKEY RRs from the answer that are validated by DS
2373 * RRs from the list of validated keys to the list of
2374 * validated keys. */
2375
2376 DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, t->answer) {
2377
96bb7673 2378 r = dnssec_verify_dnskey_by_ds_search(rr, t->validated_keys);
105e1512
LP
2379 if (r < 0)
2380 return r;
2381 if (r == 0)
2382 continue;
2383
2384 /* If so, the DNSKEY is validated too. */
2385 r = dns_answer_add_extend(&t->validated_keys, rr, ifindex, DNS_ANSWER_AUTHENTICATED);
2386 if (r < 0)
2387 return r;
2388 }
2389
2390 return 0;
2391}
2392
2393static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *rr) {
56352fe9
LP
2394 int r;
2395
2396 assert(t);
2397 assert(rr);
2398
105e1512
LP
2399 /* Checks if the RR we are looking for must be signed with an
2400 * RRSIG. This is used for positive responses. */
24a5b982 2401
b652d4a2 2402 if (t->scope->dnssec_mode == DNSSEC_NO)
105e1512 2403 return false;
56352fe9 2404
105e1512
LP
2405 if (dns_type_is_pseudo(rr->key->type))
2406 return -EINVAL;
56352fe9 2407
1c02e7ba 2408 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
8e54f5d9
LP
2409 if (r < 0)
2410 return r;
2411 if (r > 0)
2412 return false;
2413
105e1512 2414 switch (rr->key->type) {
56352fe9 2415
105e1512
LP
2416 case DNS_TYPE_RRSIG:
2417 /* RRSIGs are the signatures themselves, they need no signing. */
2418 return false;
2419
2420 case DNS_TYPE_SOA:
2421 case DNS_TYPE_NS: {
2422 DnsTransaction *dt;
2423 Iterator i;
2424
b63fca62 2425 /* For SOA or NS RRs we look for a matching DS transaction */
105e1512
LP
2426
2427 SET_FOREACH(dt, t->dnssec_transactions, i) {
2428
2429 if (dt->key->class != rr->key->class)
2430 continue;
2431 if (dt->key->type != DNS_TYPE_DS)
2432 continue;
2433
1c02e7ba 2434 r = dns_name_equal(dns_resource_key_name(dt->key), dns_resource_key_name(rr->key));
105e1512
LP
2435 if (r < 0)
2436 return r;
2437 if (r == 0)
2438 continue;
2439
2440 /* We found a DS transactions for the SOA/NS
2441 * RRs we are looking at. If it discovered signed DS
2442 * RRs, then we need to be signed, too. */
2443
097a2517
TA
2444 if (!dt->answer_authenticated)
2445 return false;
105e1512 2446
097a2517 2447 return dns_answer_match_key(dt->answer, dt->key, NULL);
105e1512
LP
2448 }
2449
2450 /* We found nothing that proves this is safe to leave
2451 * this unauthenticated, hence ask inist on
2452 * authentication. */
2453 return true;
2454 }
2455
b63fca62 2456 case DNS_TYPE_DS:
105e1512
LP
2457 case DNS_TYPE_CNAME:
2458 case DNS_TYPE_DNAME: {
2459 const char *parent = NULL;
2460 DnsTransaction *dt;
2461 Iterator i;
2462
b63fca62
LP
2463 /*
2464 * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent SOA.
2465 *
2466 * DS RRs are signed if the parent is signed, hence also look at the parent SOA
2467 */
105e1512
LP
2468
2469 SET_FOREACH(dt, t->dnssec_transactions, i) {
2470
2471 if (dt->key->class != rr->key->class)
2472 continue;
2473 if (dt->key->type != DNS_TYPE_SOA)
2474 continue;
2475
2476 if (!parent) {
1c02e7ba 2477 parent = dns_resource_key_name(rr->key);
105e1512
LP
2478 r = dns_name_parent(&parent);
2479 if (r < 0)
2480 return r;
2481 if (r == 0) {
b63fca62
LP
2482 if (rr->key->type == DNS_TYPE_DS)
2483 return true;
2484
105e1512
LP
2485 /* A CNAME/DNAME without a parent? That's sooo weird. */
2486 log_debug("Transaction %" PRIu16 " claims CNAME/DNAME at root. Refusing.", t->id);
2487 return -EBADMSG;
2488 }
2489 }
2490
1c02e7ba 2491 r = dns_name_equal(dns_resource_key_name(dt->key), parent);
105e1512
LP
2492 if (r < 0)
2493 return r;
2494 if (r == 0)
2495 continue;
2496
2497 return t->answer_authenticated;
2498 }
2499
2500 return true;
2501 }
2502
2503 default: {
2504 DnsTransaction *dt;
2505 Iterator i;
2506
b63fca62 2507 /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our SOA lookup was authenticated */
105e1512
LP
2508
2509 SET_FOREACH(dt, t->dnssec_transactions, i) {
2510
2511 if (dt->key->class != rr->key->class)
2512 continue;
2513 if (dt->key->type != DNS_TYPE_SOA)
2514 continue;
2515
1c02e7ba 2516 r = dns_name_equal(dns_resource_key_name(dt->key), dns_resource_key_name(rr->key));
105e1512
LP
2517 if (r < 0)
2518 return r;
2519 if (r == 0)
2520 continue;
2521
2522 /* We found the transaction that was supposed to find
2523 * the SOA RR for us. It was successful, but found no
2524 * RR for us. This means we are not at a zone cut. In
2525 * this case, we require authentication if the SOA
2526 * lookup was authenticated too. */
2527 return t->answer_authenticated;
2528 }
2529
2530 return true;
2531 }}
56352fe9
LP
2532}
2533
d33b6cf3
LP
2534static int dns_transaction_in_private_tld(DnsTransaction *t, const DnsResourceKey *key) {
2535 DnsTransaction *dt;
2536 const char *tld;
2537 Iterator i;
2538 int r;
2539
2540 /* If DNSSEC downgrade mode is on, checks whether the
2541 * specified RR is one level below a TLD we have proven not to
2542 * exist. In such a case we assume that this is a private
2543 * domain, and permit it.
2544 *
2545 * This detects cases like the Fritz!Box router networks. Each
2546 * Fritz!Box router serves a private "fritz.box" zone, in the
2547 * non-existing TLD "box". Requests for the "fritz.box" domain
2548 * are served by the router itself, while requests for the
2549 * "box" domain will result in NXDOMAIN.
2550 *
2551 * Note that this logic is unable to detect cases where a
2552 * router serves a private DNS zone directly under
2553 * non-existing TLD. In such a case we cannot detect whether
2554 * the TLD is supposed to exist or not, as all requests we
2555 * make for it will be answered by the router's zone, and not
2556 * by the root zone. */
2557
2558 assert(t);
2559
2560 if (t->scope->dnssec_mode != DNSSEC_ALLOW_DOWNGRADE)
2561 return false; /* In strict DNSSEC mode what doesn't exist, doesn't exist */
2562
1c02e7ba 2563 tld = dns_resource_key_name(key);
d33b6cf3
LP
2564 r = dns_name_parent(&tld);
2565 if (r < 0)
2566 return r;
2567 if (r == 0)
2568 return false; /* Already the root domain */
2569
2570 if (!dns_name_is_single_label(tld))
2571 return false;
2572
2573 SET_FOREACH(dt, t->dnssec_transactions, i) {
2574
2575 if (dt->key->class != key->class)
2576 continue;
2577
1c02e7ba 2578 r = dns_name_equal(dns_resource_key_name(dt->key), tld);
d33b6cf3
LP
2579 if (r < 0)
2580 return r;
2581 if (r == 0)
2582 continue;
2583
2584 /* We found an auxiliary lookup we did for the TLD. If
2585 * that returned with NXDOMAIN, we know the TLD didn't
2586 * exist, and hence this might be a private zone. */
2587
2588 return dt->answer_rcode == DNS_RCODE_NXDOMAIN;
2589 }
2590
2591 return false;
2592}
2593
105e1512 2594static int dns_transaction_requires_nsec(DnsTransaction *t) {
4bbc06cc 2595 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
105e1512
LP
2596 DnsTransaction *dt;
2597 const char *name;
4bbc06cc 2598 uint16_t type = 0;
105e1512
LP
2599 Iterator i;
2600 int r;
56352fe9
LP
2601
2602 assert(t);
2603
105e1512
LP
2604 /* Checks if we need to insist on NSEC/NSEC3 RRs for proving
2605 * this negative reply */
56352fe9 2606
b652d4a2 2607 if (t->scope->dnssec_mode == DNSSEC_NO)
105e1512 2608 return false;
56352fe9 2609
105e1512
LP
2610 if (dns_type_is_pseudo(t->key->type))
2611 return -EINVAL;
2612
1c02e7ba 2613 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(t->key));
8e54f5d9
LP
2614 if (r < 0)
2615 return r;
2616 if (r > 0)
2617 return false;
2618
d33b6cf3
LP
2619 r = dns_transaction_in_private_tld(t, t->key);
2620 if (r < 0)
2621 return r;
2622 if (r > 0) {
2623 /* The lookup is from a TLD that is proven not to
2624 * exist, and we are in downgrade mode, hence ignore
13e785f7 2625 * that fact that we didn't get any NSEC RRs. */
d33b6cf3 2626
202b76ae
ZJS
2627 log_info("Detected a negative query %s in a private DNS zone, permitting unsigned response.",
2628 dns_resource_key_to_string(t->key, key_str, sizeof key_str));
d33b6cf3
LP
2629 return false;
2630 }
2631
1c02e7ba 2632 name = dns_resource_key_name(t->key);
105e1512 2633
4bbc06cc 2634 if (t->key->type == DNS_TYPE_DS) {
105e1512 2635
4bbc06cc
LP
2636 /* We got a negative reply for this DS lookup? DS RRs are signed when their parent zone is signed,
2637 * hence check the parent SOA in this case. */
105e1512
LP
2638
2639 r = dns_name_parent(&name);
56352fe9
LP
2640 if (r < 0)
2641 return r;
2642 if (r == 0)
105e1512 2643 return true;
4bbc06cc
LP
2644
2645 type = DNS_TYPE_SOA;
2646
2647 } else if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS))
2648 /* We got a negative reply for this SOA/NS lookup? If so, check if there's a DS RR for this */
2649 type = DNS_TYPE_DS;
2650 else
2651 /* For all other negative replies, check for the SOA lookup */
2652 type = DNS_TYPE_SOA;
105e1512
LP
2653
2654 /* For all other RRs we check the SOA on the same level to see
2655 * if it's signed. */
2656
2657 SET_FOREACH(dt, t->dnssec_transactions, i) {
2658
2659 if (dt->key->class != t->key->class)
2660 continue;
4bbc06cc 2661 if (dt->key->type != type)
56352fe9
LP
2662 continue;
2663
1c02e7ba 2664 r = dns_name_equal(dns_resource_key_name(dt->key), name);
56352fe9
LP
2665 if (r < 0)
2666 return r;
105e1512
LP
2667 if (r == 0)
2668 continue;
2669
2670 return dt->answer_authenticated;
56352fe9
LP
2671 }
2672
105e1512
LP
2673 /* If in doubt, require NSEC/NSEC3 */
2674 return true;
56352fe9
LP
2675}
2676
94aa7071
LP
2677static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRecord *rr) {
2678 DnsResourceRecord *rrsig;
2679 bool found = false;
2680 int r;
2681
2682 /* Checks whether any of the DNSKEYs used for the RRSIGs for
2683 * the specified RRset is authenticated (i.e. has a matching
2684 * DS RR). */
2685
1c02e7ba 2686 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
8e54f5d9
LP
2687 if (r < 0)
2688 return r;
2689 if (r > 0)
2690 return false;
2691
94aa7071
LP
2692 DNS_ANSWER_FOREACH(rrsig, t->answer) {
2693 DnsTransaction *dt;
2694 Iterator i;
2695
2696 r = dnssec_key_match_rrsig(rr->key, rrsig);
2697 if (r < 0)
2698 return r;
2699 if (r == 0)
2700 continue;
2701
2702 SET_FOREACH(dt, t->dnssec_transactions, i) {
2703
2704 if (dt->key->class != rr->key->class)
2705 continue;
2706
2707 if (dt->key->type == DNS_TYPE_DNSKEY) {
2708
1c02e7ba 2709 r = dns_name_equal(dns_resource_key_name(dt->key), rrsig->rrsig.signer);
94aa7071
LP
2710 if (r < 0)
2711 return r;
2712 if (r == 0)
2713 continue;
2714
2715 /* OK, we found an auxiliary DNSKEY
2716 * lookup. If that lookup is
2717 * authenticated, report this. */
2718
2719 if (dt->answer_authenticated)
2720 return true;
2721
2722 found = true;
2723
2724 } else if (dt->key->type == DNS_TYPE_DS) {
2725
1c02e7ba 2726 r = dns_name_equal(dns_resource_key_name(dt->key), rrsig->rrsig.signer);
94aa7071
LP
2727 if (r < 0)
2728 return r;
2729 if (r == 0)
2730 continue;
2731
2732 /* OK, we found an auxiliary DS
2733 * lookup. If that lookup is
2734 * authenticated and non-zero, we
2735 * won! */
2736
2737 if (!dt->answer_authenticated)
2738 return false;
2739
2740 return dns_answer_match_key(dt->answer, dt->key, NULL);
2741 }
2742 }
2743 }
2744
2745 return found ? false : -ENXIO;
2746}
2747
b652d4a2
LP
2748static int dns_transaction_known_signed(DnsTransaction *t, DnsResourceRecord *rr) {
2749 assert(t);
2750 assert(rr);
2751
2752 /* We know that the root domain is signed, hence if it appears
2753 * not to be signed, there's a problem with the DNS server */
2754
2755 return rr->key->class == DNS_CLASS_IN &&
1c02e7ba 2756 dns_name_is_root(dns_resource_key_name(rr->key));
b652d4a2
LP
2757}
2758
0f87f3e8
LP
2759static int dns_transaction_check_revoked_trust_anchors(DnsTransaction *t) {
2760 DnsResourceRecord *rr;
2761 int r;
2762
2763 assert(t);
2764
2765 /* Maybe warn the user that we encountered a revoked DNSKEY
2766 * for a key from our trust anchor. Note that we don't care
2767 * whether the DNSKEY can be authenticated or not. It's
2768 * sufficient if it is self-signed. */
2769
2770 DNS_ANSWER_FOREACH(rr, t->answer) {
d424da2a 2771 r = dns_trust_anchor_check_revoked(&t->scope->manager->trust_anchor, rr, t->answer);
0f87f3e8
LP
2772 if (r < 0)
2773 return r;
2774 }
2775
2776 return 0;
2777}
2778
c9c72065
LP
2779static int dns_transaction_invalidate_revoked_keys(DnsTransaction *t) {
2780 bool changed;
2781 int r;
2782
2783 assert(t);
2784
2785 /* Removes all DNSKEY/DS objects from t->validated_keys that
2786 * our trust anchors database considers revoked. */
2787
2788 do {
2789 DnsResourceRecord *rr;
2790
2791 changed = false;
2792
2793 DNS_ANSWER_FOREACH(rr, t->validated_keys) {
2794 r = dns_trust_anchor_is_revoked(&t->scope->manager->trust_anchor, rr);
2795 if (r < 0)
2796 return r;
2797 if (r > 0) {
2798 r = dns_answer_remove_by_rr(&t->validated_keys, rr);
2799 if (r < 0)
2800 return r;
2801
2802 assert(r > 0);
2803 changed = true;
2804 break;
2805 }
2806 }
2807 } while (changed);
2808
2809 return 0;
2810}
2811
942eb2e7
LP
2812static int dns_transaction_copy_validated(DnsTransaction *t) {
2813 DnsTransaction *dt;
2814 Iterator i;
2815 int r;
2816
2817 assert(t);
2818
2819 /* Copy all validated RRs from the auxiliary DNSSEC transactions into our set of validated RRs */
2820
2821 SET_FOREACH(dt, t->dnssec_transactions, i) {
2822
2823 if (DNS_TRANSACTION_IS_LIVE(dt->state))
2824 continue;
2825
2826 if (!dt->answer_authenticated)
2827 continue;
2828
2829 r = dns_answer_extend(&t->validated_keys, dt->answer);
2830 if (r < 0)
2831 return r;
2832 }
2833
2834 return 0;
2835}
2836
c690b20a
ZJS
2837typedef enum {
2838 DNSSEC_PHASE_DNSKEY, /* Phase #1, only validate DNSKEYs */
2839 DNSSEC_PHASE_NSEC, /* Phase #2, only validate NSEC+NSEC3 */
2840 DNSSEC_PHASE_ALL, /* Phase #3, validate everything else */
2841} Phase;
2842
2843static int dnssec_validate_records(
2844 DnsTransaction *t,
2845 Phase phase,
2846 bool *have_nsec,
2847 DnsAnswer **validated) {
2848
547973de 2849 DnsResourceRecord *rr;
56352fe9 2850 int r;
547973de 2851
c690b20a 2852 /* Returns negative on error, 0 if validation failed, 1 to restart validation, 2 when finished. */
547973de 2853
c690b20a
ZJS
2854 DNS_ANSWER_FOREACH(rr, t->answer) {
2855 DnsResourceRecord *rrsig = NULL;
2856 DnssecResult result;
547973de 2857
c690b20a
ZJS
2858 switch (rr->key->type) {
2859 case DNS_TYPE_RRSIG:
2860 continue;
547973de 2861
c690b20a
ZJS
2862 case DNS_TYPE_DNSKEY:
2863 /* We validate DNSKEYs only in the DNSKEY and ALL phases */
2864 if (phase == DNSSEC_PHASE_NSEC)
2865 continue;
2866 break;
547973de 2867
c690b20a
ZJS
2868 case DNS_TYPE_NSEC:
2869 case DNS_TYPE_NSEC3:
2870 *have_nsec = true;
547973de 2871
c690b20a
ZJS
2872 /* We validate NSEC/NSEC3 only in the NSEC and ALL phases */
2873 if (phase == DNSSEC_PHASE_DNSKEY)
2874 continue;
2875 break;
105e1512 2876
c690b20a
ZJS
2877 default:
2878 /* We validate all other RRs only in the ALL phases */
2879 if (phase != DNSSEC_PHASE_ALL)
2880 continue;
2881 }
b652d4a2 2882
c690b20a
ZJS
2883 r = dnssec_verify_rrset_search(t->answer, rr->key, t->validated_keys, USEC_INFINITY, &result, &rrsig);
2884 if (r < 0)
2885 return r;
547973de 2886
c690b20a 2887 log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr)), dnssec_result_to_string(result));
0f87f3e8 2888
c690b20a 2889 if (result == DNSSEC_VALIDATED) {
942eb2e7 2890
c690b20a
ZJS
2891 if (rr->key->type == DNS_TYPE_DNSKEY) {
2892 /* If we just validated a DNSKEY RRset, then let's add these keys to
2893 * the set of validated keys for this transaction. */
547973de 2894
c690b20a
ZJS
2895 r = dns_answer_copy_by_key(&t->validated_keys, t->answer, rr->key, DNS_ANSWER_AUTHENTICATED);
2896 if (r < 0)
2897 return r;
c9c72065 2898
c690b20a
ZJS
2899 /* Some of the DNSKEYs we just added might already have been revoked,
2900 * remove them again in that case. */
2901 r = dns_transaction_invalidate_revoked_keys(t);
2902 if (r < 0)
2903 return r;
2904 }
547973de 2905
c690b20a
ZJS
2906 /* Add the validated RRset to the new list of validated
2907 * RRsets, and remove it from the unvalidated RRsets.
2908 * We mark the RRset as authenticated and cacheable. */
2909 r = dns_answer_move_by_key(validated, &t->answer, rr->key, DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE);
2910 if (r < 0)
2911 return r;
547973de 2912
c690b20a 2913 manager_dnssec_verdict(t->scope->manager, DNSSEC_SECURE, rr->key);
0c7bff0a 2914
c690b20a
ZJS
2915 /* Exit the loop, we dropped something from the answer, start from the beginning */
2916 return 1;
2917 }
547973de 2918
c690b20a
ZJS
2919 /* If we haven't read all DNSKEYs yet a negative result of the validation is irrelevant, as
2920 * there might be more DNSKEYs coming. Similar, if we haven't read all NSEC/NSEC3 RRs yet,
2921 * we cannot do positive wildcard proofs yet, as those require the NSEC/NSEC3 RRs. */
2922 if (phase != DNSSEC_PHASE_ALL)
2923 continue;
0c7bff0a 2924
c690b20a
ZJS
2925 if (result == DNSSEC_VALIDATED_WILDCARD) {
2926 bool authenticated = false;
2927 const char *source;
0c7bff0a 2928
c690b20a 2929 /* This RRset validated, but as a wildcard. This means we need
13e785f7 2930 * to prove via NSEC/NSEC3 that no matching non-wildcard RR exists. */
0c7bff0a 2931
c690b20a
ZJS
2932 /* First step, determine the source of synthesis */
2933 r = dns_resource_record_source(rrsig, &source);
2934 if (r < 0)
2935 return r;
0c7bff0a 2936
c690b20a 2937 r = dnssec_test_positive_wildcard(*validated,
1c02e7ba 2938 dns_resource_key_name(rr->key),
c690b20a
ZJS
2939 source,
2940 rrsig->rrsig.signer,
2941 &authenticated);
0c7bff0a 2942
c690b20a
ZJS
2943 /* Unless the NSEC proof showed that the key really doesn't exist something is off. */
2944 if (r == 0)
2945 result = DNSSEC_INVALID;
2946 else {
2947 r = dns_answer_move_by_key(validated, &t->answer, rr->key,
2948 authenticated ? (DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE) : 0);
2949 if (r < 0)
2950 return r;
2951
2952 manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, rr->key);
2953
2954 /* Exit the loop, we dropped something from the answer, start from the beginning */
2955 return 1;
0c7bff0a 2956 }
c690b20a 2957 }
0c7bff0a 2958
c690b20a
ZJS
2959 if (result == DNSSEC_NO_SIGNATURE) {
2960 r = dns_transaction_requires_rrsig(t, rr);
547973de
LP
2961 if (r < 0)
2962 return r;
c690b20a
ZJS
2963 if (r == 0) {
2964 /* Data does not require signing. In that case, just copy it over,
13e785f7 2965 * but remember that this is by no means authenticated. */
c690b20a
ZJS
2966 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
2967 if (r < 0)
2968 return r;
2969
2970 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
2971 return 1;
2972 }
547973de 2973
c690b20a
ZJS
2974 r = dns_transaction_known_signed(t, rr);
2975 if (r < 0)
2976 return r;
2977 if (r > 0) {
2978 /* This is an RR we know has to be signed. If it isn't this means
2979 * the server is not attaching RRSIGs, hence complain. */
547973de 2980
c690b20a 2981 dns_server_packet_rrsig_missing(t->server, t->current_feature_level);
547973de 2982
c690b20a 2983 if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
547973de 2984
c690b20a 2985 /* Downgrading is OK? If so, just consider the information unsigned */
c9c72065 2986
c690b20a 2987 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
c9c72065
LP
2988 if (r < 0)
2989 return r;
547973de 2990
c690b20a
ZJS
2991 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
2992 return 1;
2993 }
a150ff5e 2994
c690b20a
ZJS
2995 /* Otherwise, fail */
2996 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
2997 return 0;
f3cf586d 2998 }
547973de 2999
c690b20a
ZJS
3000 r = dns_transaction_in_private_tld(t, rr->key);
3001 if (r < 0)
3002 return r;
3003 if (r > 0) {
202b76ae 3004 char s[DNS_RESOURCE_KEY_STRING_MAX];
b652d4a2 3005
c690b20a
ZJS
3006 /* The data is from a TLD that is proven not to exist, and we are in downgrade
3007 * mode, hence ignore the fact that this was not signed. */
0c7bff0a 3008
202b76ae
ZJS
3009 log_info("Detected RRset %s is in a private DNS zone, permitting unsigned RRs.",
3010 dns_resource_key_to_string(rr->key, s, sizeof s));
0c7bff0a 3011
c690b20a 3012 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
0c7bff0a
LP
3013 if (r < 0)
3014 return r;
0c7bff0a 3015
c690b20a
ZJS
3016 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
3017 return 1;
3018 }
3019 }
0c7bff0a 3020
c690b20a
ZJS
3021 if (IN_SET(result,
3022 DNSSEC_MISSING_KEY,
3023 DNSSEC_SIGNATURE_EXPIRED,
3024 DNSSEC_UNSUPPORTED_ALGORITHM)) {
0c7bff0a 3025
c690b20a
ZJS
3026 r = dns_transaction_dnskey_authenticated(t, rr);
3027 if (r < 0 && r != -ENXIO)
3028 return r;
3029 if (r == 0) {
3030 /* The DNSKEY transaction was not authenticated, this means there's
3031 * no DS for this, which means it's OK if no keys are found for this signature. */
0c7bff0a 3032
c690b20a 3033 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
f3cf586d
LP
3034 if (r < 0)
3035 return r;
b652d4a2 3036
c690b20a
ZJS
3037 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
3038 return 1;
3039 }
3040 }
b652d4a2 3041
c690b20a
ZJS
3042 r = dns_transaction_is_primary_response(t, rr);
3043 if (r < 0)
3044 return r;
3045 if (r > 0) {
3046 /* Look for a matching DNAME for this CNAME */
3047 r = dns_answer_has_dname_for_cname(t->answer, rr);
3048 if (r < 0)
3049 return r;
3050 if (r == 0) {
3051 /* Also look among the stuff we already validated */
3052 r = dns_answer_has_dname_for_cname(*validated, rr);
f3cf586d
LP
3053 if (r < 0)
3054 return r;
c690b20a 3055 }
d33b6cf3 3056
c690b20a
ZJS
3057 if (r == 0) {
3058 if (IN_SET(result,
3059 DNSSEC_INVALID,
3060 DNSSEC_SIGNATURE_EXPIRED,
3061 DNSSEC_NO_SIGNATURE))
3062 manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, rr->key);
3063 else /* DNSSEC_MISSING_KEY or DNSSEC_UNSUPPORTED_ALGORITHM */
3064 manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, rr->key);
3065
3066 /* This is a primary response to our question, and it failed validation.
3067 * That's fatal. */
3068 t->answer_dnssec_result = result;
3069 return 0;
3070 }
d33b6cf3 3071
c690b20a
ZJS
3072 /* This is a primary response, but we do have a DNAME RR
3073 * in the RR that can replay this CNAME, hence rely on
3074 * that, and we can remove the CNAME in favour of it. */
3075 }
d33b6cf3 3076
c690b20a
ZJS
3077 /* This is just some auxiliary data. Just remove the RRset and continue. */
3078 r = dns_answer_remove_by_key(&t->answer, rr->key);
3079 if (r < 0)
3080 return r;
d33b6cf3 3081
c690b20a
ZJS
3082 /* We dropped something from the answer, start from the beginning. */
3083 return 1;
3084 }
f3cf586d 3085
c690b20a
ZJS
3086 return 2; /* Finito. */
3087}
94aa7071 3088
c690b20a
ZJS
3089int dns_transaction_validate_dnssec(DnsTransaction *t) {
3090 _cleanup_(dns_answer_unrefp) DnsAnswer *validated = NULL;
3091 Phase phase;
3092 DnsAnswerFlags flags;
3093 int r;
202b76ae 3094 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
94aa7071 3095
c690b20a 3096 assert(t);
94aa7071 3097
c690b20a
ZJS
3098 /* We have now collected all DS and DNSKEY RRs in
3099 * t->validated_keys, let's see which RRs we can now
3100 * authenticate with that. */
94aa7071 3101
c690b20a
ZJS
3102 if (t->scope->dnssec_mode == DNSSEC_NO)
3103 return 0;
a150ff5e 3104
c690b20a
ZJS
3105 /* Already validated */
3106 if (t->answer_dnssec_result != _DNSSEC_RESULT_INVALID)
3107 return 0;
105e1512 3108
c690b20a
ZJS
3109 /* Our own stuff needs no validation */
3110 if (IN_SET(t->answer_source, DNS_TRANSACTION_ZONE, DNS_TRANSACTION_TRUST_ANCHOR)) {
3111 t->answer_dnssec_result = DNSSEC_VALIDATED;
3112 t->answer_authenticated = true;
3113 return 0;
3114 }
a150ff5e 3115
c690b20a
ZJS
3116 /* Cached stuff is not affected by validation. */
3117 if (t->answer_source != DNS_TRANSACTION_NETWORK)
3118 return 0;
f3cf586d 3119
c690b20a
ZJS
3120 if (!dns_transaction_dnssec_supported_full(t)) {
3121 /* The server does not support DNSSEC, or doesn't augment responses with RRSIGs. */
3122 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
d001e0a3 3123 log_debug("Not validating response for %" PRIu16 ", used server feature level does not support DNSSEC.", t->id);
c690b20a
ZJS
3124 return 0;
3125 }
f3cf586d 3126
202b76ae
ZJS
3127 log_debug("Validating response from transaction %" PRIu16 " (%s).",
3128 t->id,
3129 dns_resource_key_to_string(t->key, key_str, sizeof key_str));
547973de 3130
c690b20a
ZJS
3131 /* First, see if this response contains any revoked trust
3132 * anchors we care about */
3133 r = dns_transaction_check_revoked_trust_anchors(t);
3134 if (r < 0)
3135 return r;
43e6779a 3136
c690b20a
ZJS
3137 /* Third, copy all RRs we acquired successfully from auxiliary RRs over. */
3138 r = dns_transaction_copy_validated(t);
3139 if (r < 0)
3140 return r;
43e6779a 3141
c690b20a
ZJS
3142 /* Second, see if there are DNSKEYs we already know a
3143 * validated DS for. */
3144 r = dns_transaction_validate_dnskey_by_ds(t);
3145 if (r < 0)
3146 return r;
43e6779a 3147
c690b20a
ZJS
3148 /* Fourth, remove all DNSKEY and DS RRs again that our trust
3149 * anchor says are revoked. After all we might have marked
3150 * some keys revoked above, but they might still be lingering
3151 * in our validated_keys list. */
3152 r = dns_transaction_invalidate_revoked_keys(t);
3153 if (r < 0)
3154 return r;
f3cf586d 3155
c690b20a
ZJS
3156 phase = DNSSEC_PHASE_DNSKEY;
3157 for (;;) {
3158 bool have_nsec = false;
f3cf586d 3159
c690b20a
ZJS
3160 r = dnssec_validate_records(t, phase, &have_nsec, &validated);
3161 if (r <= 0)
3162 return r;
547973de 3163
c690b20a
ZJS
3164 /* Try again as long as we managed to achieve something */
3165 if (r == 1)
547973de
LP
3166 continue;
3167
c690b20a 3168 if (phase == DNSSEC_PHASE_DNSKEY && have_nsec) {
0c7bff0a 3169 /* OK, we processed all DNSKEYs, and there are NSEC/NSEC3 RRs, look at those now. */
c690b20a 3170 phase = DNSSEC_PHASE_NSEC;
0c7bff0a
LP
3171 continue;
3172 }
3173
c690b20a
ZJS
3174 if (phase != DNSSEC_PHASE_ALL) {
3175 /* OK, we processed all DNSKEYs and NSEC/NSEC3 RRs, look at all the rest now.
3176 * Note that in this third phase we start to remove RRs we couldn't validate. */
3177 phase = DNSSEC_PHASE_ALL;
56352fe9 3178 continue;
547973de
LP
3179 }
3180
56352fe9 3181 /* We're done */
547973de
LP
3182 break;
3183 }
3184
3185 dns_answer_unref(t->answer);
1cc6c93a 3186 t->answer = TAKE_PTR(validated);
547973de 3187
72667f08
LP
3188 /* At this point the answer only contains validated
3189 * RRsets. Now, let's see if it actually answers the question
3190 * we asked. If so, great! If it doesn't, then see if
3191 * NSEC/NSEC3 can prove this. */
105e1512 3192 r = dns_transaction_has_positive_answer(t, &flags);
72667f08 3193 if (r > 0) {
105e1512
LP
3194 /* Yes, it answers the question! */
3195
3196 if (flags & DNS_ANSWER_AUTHENTICATED) {
3197 /* The answer is fully authenticated, yay. */
019036a4 3198 t->answer_dnssec_result = DNSSEC_VALIDATED;
105e1512
LP
3199 t->answer_rcode = DNS_RCODE_SUCCESS;
3200 t->answer_authenticated = true;
3201 } else {
3202 /* The answer is not fully authenticated. */
019036a4 3203 t->answer_dnssec_result = DNSSEC_UNSIGNED;
105e1512
LP
3204 t->answer_authenticated = false;
3205 }
3206
72667f08
LP
3207 } else if (r == 0) {
3208 DnssecNsecResult nr;
ed29bfdc 3209 bool authenticated = false;
72667f08
LP
3210
3211 /* Bummer! Let's check NSEC/NSEC3 */
0c7bff0a 3212 r = dnssec_nsec_test(t->answer, t->key, &nr, &authenticated, &t->answer_nsec_ttl);
72667f08
LP
3213 if (r < 0)
3214 return r;
3215
3216 switch (nr) {
3217
3218 case DNSSEC_NSEC_NXDOMAIN:
3219 /* NSEC proves the domain doesn't exist. Very good. */
202b76ae 3220 log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
019036a4 3221 t->answer_dnssec_result = DNSSEC_VALIDATED;
72667f08 3222 t->answer_rcode = DNS_RCODE_NXDOMAIN;
ed29bfdc 3223 t->answer_authenticated = authenticated;
7aa8ce98 3224
59c5b597 3225 manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, t->key);
72667f08
LP
3226 break;
3227
3228 case DNSSEC_NSEC_NODATA:
3229 /* NSEC proves that there's no data here, very good. */
202b76ae 3230 log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
019036a4 3231 t->answer_dnssec_result = DNSSEC_VALIDATED;
72667f08 3232 t->answer_rcode = DNS_RCODE_SUCCESS;
ed29bfdc 3233 t->answer_authenticated = authenticated;
7aa8ce98 3234
59c5b597 3235 manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, t->key);
72667f08
LP
3236 break;
3237
105e1512
LP
3238 case DNSSEC_NSEC_OPTOUT:
3239 /* NSEC3 says the data might not be signed */
202b76ae 3240 log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
019036a4 3241 t->answer_dnssec_result = DNSSEC_UNSIGNED;
105e1512 3242 t->answer_authenticated = false;
7aa8ce98 3243
59c5b597 3244 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, t->key);
105e1512
LP
3245 break;
3246
72667f08
LP
3247 case DNSSEC_NSEC_NO_RR:
3248 /* No NSEC data? Bummer! */
105e1512
LP
3249
3250 r = dns_transaction_requires_nsec(t);
3251 if (r < 0)
3252 return r;
7aa8ce98 3253 if (r > 0) {
019036a4 3254 t->answer_dnssec_result = DNSSEC_NO_SIGNATURE;
59c5b597 3255 manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, t->key);
7aa8ce98 3256 } else {
019036a4 3257 t->answer_dnssec_result = DNSSEC_UNSIGNED;
105e1512 3258 t->answer_authenticated = false;
59c5b597 3259 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, t->key);
105e1512
LP
3260 }
3261
3262 break;
3263
3264 case DNSSEC_NSEC_UNSUPPORTED_ALGORITHM:
3265 /* We don't know the NSEC3 algorithm used? */
019036a4 3266 t->answer_dnssec_result = DNSSEC_UNSUPPORTED_ALGORITHM;
59c5b597 3267 manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, t->key);
72667f08
LP
3268 break;
3269
3270 case DNSSEC_NSEC_FOUND:
146035b3 3271 case DNSSEC_NSEC_CNAME:
72667f08 3272 /* NSEC says it needs to be there, but we couldn't find it? Bummer! */
019036a4 3273 t->answer_dnssec_result = DNSSEC_NSEC_MISMATCH;
59c5b597 3274 manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, t->key);
72667f08
LP
3275 break;
3276
3277 default:
3278 assert_not_reached("Unexpected NSEC result.");
3279 }
3280 }
3281
547973de
LP
3282 return 1;
3283}
3284
ec2c5e43
LP
3285static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX] = {
3286 [DNS_TRANSACTION_NULL] = "null",
3287 [DNS_TRANSACTION_PENDING] = "pending",
547973de 3288 [DNS_TRANSACTION_VALIDATING] = "validating",
3bbdc31d 3289 [DNS_TRANSACTION_RCODE_FAILURE] = "rcode-failure",
ec2c5e43
LP
3290 [DNS_TRANSACTION_SUCCESS] = "success",
3291 [DNS_TRANSACTION_NO_SERVERS] = "no-servers",
3292 [DNS_TRANSACTION_TIMEOUT] = "timeout",
3293 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED] = "attempts-max-reached",
3294 [DNS_TRANSACTION_INVALID_REPLY] = "invalid-reply",
7cc6ed7b 3295 [DNS_TRANSACTION_ERRNO] = "errno",
ec2c5e43 3296 [DNS_TRANSACTION_ABORTED] = "aborted",
547973de 3297 [DNS_TRANSACTION_DNSSEC_FAILED] = "dnssec-failed",
b2b796b8 3298 [DNS_TRANSACTION_NO_TRUST_ANCHOR] = "no-trust-anchor",
91adc4db 3299 [DNS_TRANSACTION_RR_TYPE_UNSUPPORTED] = "rr-type-unsupported",
edbcc1fd 3300 [DNS_TRANSACTION_NETWORK_DOWN] = "network-down",
0791110f 3301 [DNS_TRANSACTION_NOT_FOUND] = "not-found",
ec2c5e43
LP
3302};
3303DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);
c3bc53e6
LP
3304
3305static const char* const dns_transaction_source_table[_DNS_TRANSACTION_SOURCE_MAX] = {
3306 [DNS_TRANSACTION_NETWORK] = "network",
3307 [DNS_TRANSACTION_CACHE] = "cache",
3308 [DNS_TRANSACTION_ZONE] = "zone",
0d2cd476 3309 [DNS_TRANSACTION_TRUST_ANCHOR] = "trust-anchor",
c3bc53e6
LP
3310};
3311DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source, DnsTransactionSource);