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