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