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