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