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