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