]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-transaction.c
resolved: split out check whether reply matches our question
[thirdparty/systemd.git] / src / resolve / resolved-dns-transaction.c
CommitLineData
ec2c5e43
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2014 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include "af-list.h"
b5efdb8a 23#include "alloc-util.h"
f52e61da 24#include "dns-domain.h"
3ffd4af2
LP
25#include "fd-util.h"
26#include "random-util.h"
7778dfff 27#include "resolved-dns-cache.h"
3ffd4af2
LP
28#include "resolved-dns-transaction.h"
29#include "resolved-llmnr.h"
8b43440b 30#include "string-table.h"
ec2c5e43
LP
31
32DnsTransaction* dns_transaction_free(DnsTransaction *t) {
801ad6a6 33 DnsQueryCandidate *c;
ec2c5e43
LP
34 DnsZoneItem *i;
35
36 if (!t)
37 return NULL;
38
39 sd_event_source_unref(t->timeout_event_source);
40
ec2c5e43
LP
41 dns_packet_unref(t->sent);
42 dns_packet_unref(t->received);
ae6a4bbf
LP
43
44 dns_answer_unref(t->answer);
ec2c5e43 45
4667e00a
LP
46 sd_event_source_unref(t->dns_udp_event_source);
47 safe_close(t->dns_udp_fd);
d20b1667 48
8300ba21 49 dns_server_unref(t->server);
ec2c5e43
LP
50 dns_stream_free(t->stream);
51
52 if (t->scope) {
f9ebb22a
LP
53 hashmap_remove_value(t->scope->transactions_by_key, t->key, t);
54 LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
ec2c5e43
LP
55
56 if (t->id != 0)
57 hashmap_remove(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id));
58 }
59
da0c630e
LP
60 dns_resource_key_unref(t->key);
61
801ad6a6
LP
62 while ((c = set_steal_first(t->query_candidates)))
63 set_remove(c->transactions, t);
64
65 set_free(t->query_candidates);
ec2c5e43
LP
66
67 while ((i = set_steal_first(t->zone_items)))
68 i->probe_transaction = NULL;
69 set_free(t->zone_items);
70
71 free(t);
72 return NULL;
73}
74
75DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_free);
76
77void dns_transaction_gc(DnsTransaction *t) {
78 assert(t);
79
80 if (t->block_gc > 0)
81 return;
82
801ad6a6 83 if (set_isempty(t->query_candidates) && set_isempty(t->zone_items))
ec2c5e43
LP
84 dns_transaction_free(t);
85}
86
f52e61da 87int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key) {
ec2c5e43
LP
88 _cleanup_(dns_transaction_freep) DnsTransaction *t = NULL;
89 int r;
90
91 assert(ret);
92 assert(s);
f52e61da 93 assert(key);
ec2c5e43 94
d5099efc 95 r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL);
ec2c5e43
LP
96 if (r < 0)
97 return r;
98
f9ebb22a 99 r = hashmap_ensure_allocated(&s->transactions_by_key, &dns_resource_key_hash_ops);
da0c630e
LP
100 if (r < 0)
101 return r;
102
ec2c5e43
LP
103 t = new0(DnsTransaction, 1);
104 if (!t)
105 return -ENOMEM;
106
4667e00a 107 t->dns_udp_fd = -1;
c3bc53e6 108 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
f52e61da 109 t->key = dns_resource_key_ref(key);
ec2c5e43 110
da0c630e 111 /* Find a fresh, unused transaction id */
ec2c5e43
LP
112 do
113 random_bytes(&t->id, sizeof(t->id));
114 while (t->id == 0 ||
115 hashmap_get(s->manager->dns_transactions, UINT_TO_PTR(t->id)));
116
117 r = hashmap_put(s->manager->dns_transactions, UINT_TO_PTR(t->id), t);
118 if (r < 0) {
119 t->id = 0;
120 return r;
121 }
122
f9ebb22a 123 r = hashmap_replace(s->transactions_by_key, t->key, t);
da0c630e
LP
124 if (r < 0) {
125 hashmap_remove(s->manager->dns_transactions, UINT_TO_PTR(t->id));
126 return r;
127 }
128
f9ebb22a 129 LIST_PREPEND(transactions_by_scope, s->transactions, t);
ec2c5e43
LP
130 t->scope = s;
131
132 if (ret)
133 *ret = t;
134
135 t = NULL;
136
137 return 0;
138}
139
140static void dns_transaction_stop(DnsTransaction *t) {
141 assert(t);
142
143 t->timeout_event_source = sd_event_source_unref(t->timeout_event_source);
144 t->stream = dns_stream_free(t->stream);
ae6a4bbf
LP
145
146 /* Note that we do not drop the UDP socket here, as we want to
147 * reuse it to repeat the interaction. */
ec2c5e43
LP
148}
149
150static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
2fb3034c 151 _cleanup_free_ char *pretty = NULL;
ec2c5e43 152 DnsZoneItem *z;
ec2c5e43
LP
153
154 assert(t);
155 assert(p);
156
157 if (manager_our_packet(t->scope->manager, p) != 0)
158 return;
159
2fb3034c
LP
160 in_addr_to_string(p->family, &p->sender, &pretty);
161
162 log_debug("Transaction on scope %s on %s/%s got tentative packet from %s",
ec2c5e43
LP
163 dns_protocol_to_string(t->scope->protocol),
164 t->scope->link ? t->scope->link->name : "*",
2fb3034c
LP
165 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
166 pretty);
ec2c5e43 167
a4076574
LP
168 /* RFC 4795, Section 4.1 says that the peer with the
169 * lexicographically smaller IP address loses */
4d91eec4
LP
170 if (memcmp(&p->sender, &p->destination, FAMILY_ADDRESS_SIZE(p->family)) >= 0) {
171 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
a4076574
LP
172 return;
173 }
174
4d91eec4 175 log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
a4076574 176
ec2c5e43 177 t->block_gc++;
3ef64445
LP
178 while ((z = set_first(t->zone_items))) {
179 /* First, make sure the zone item drops the reference
180 * to us */
181 dns_zone_item_probe_stop(z);
182
183 /* Secondly, report this as conflict, so that we might
184 * look for a different hostname */
ec2c5e43 185 dns_zone_item_conflict(z);
3ef64445 186 }
ec2c5e43
LP
187 t->block_gc--;
188
189 dns_transaction_gc(t);
190}
191
192void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
801ad6a6 193 DnsQueryCandidate *c;
ec2c5e43
LP
194 DnsZoneItem *z;
195 Iterator i;
196
197 assert(t);
198 assert(!IN_SET(state, DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING));
e56187ca 199
ec2c5e43
LP
200 /* Note that this call might invalidate the query. Callers
201 * should hence not attempt to access the query or transaction
202 * after calling this function. */
203
c3bc53e6 204 log_debug("Transaction on scope %s on %s/%s now complete with <%s> from %s",
ec2c5e43
LP
205 dns_protocol_to_string(t->scope->protocol),
206 t->scope->link ? t->scope->link->name : "*",
207 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
c3bc53e6
LP
208 dns_transaction_state_to_string(state),
209 t->answer_source < 0 ? "none" : dns_transaction_source_to_string(t->answer_source));
ec2c5e43
LP
210
211 t->state = state;
212
213 dns_transaction_stop(t);
214
215 /* Notify all queries that are interested, but make sure the
216 * transaction isn't freed while we are still looking at it */
217 t->block_gc++;
801ad6a6
LP
218 SET_FOREACH(c, t->query_candidates, i)
219 dns_query_candidate_ready(c);
ec2c5e43
LP
220 SET_FOREACH(z, t->zone_items, i)
221 dns_zone_item_ready(z);
222 t->block_gc--;
223
224 dns_transaction_gc(t);
225}
226
227static int on_stream_complete(DnsStream *s, int error) {
228 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
229 DnsTransaction *t;
230
231 assert(s);
232 assert(s->transaction);
233
234 /* Copy the data we care about out of the stream before we
235 * destroy it. */
236 t = s->transaction;
237 p = dns_packet_ref(s->read_packet);
238
239 t->stream = dns_stream_free(t->stream);
240
241 if (error != 0) {
242 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
243 return 0;
244 }
245
a4076574 246 if (dns_packet_validate_reply(p) <= 0) {
a20b9592 247 log_debug("Invalid TCP reply packet.");
a4076574
LP
248 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
249 return 0;
250 }
251
252 dns_scope_check_conflicts(t->scope, p);
253
ec2c5e43
LP
254 t->block_gc++;
255 dns_transaction_process_reply(t, p);
256 t->block_gc--;
257
258 /* If the response wasn't useful, then complete the transition now */
259 if (t->state == DNS_TRANSACTION_PENDING)
260 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
261
262 return 0;
263}
264
265static int dns_transaction_open_tcp(DnsTransaction *t) {
088480fa 266 DnsServer *server = NULL;
ec2c5e43
LP
267 _cleanup_close_ int fd = -1;
268 int r;
269
270 assert(t);
271
272 if (t->stream)
273 return 0;
274
106784eb
DM
275 switch (t->scope->protocol) {
276 case DNS_PROTOCOL_DNS:
8300ba21 277 fd = dns_scope_tcp_socket(t->scope, AF_UNSPEC, NULL, 53, &server);
106784eb 278 break;
ec2c5e43 279
106784eb 280 case DNS_PROTOCOL_LLMNR:
a8f6397f 281 /* When we already received a reply to this (but it was truncated), send to its sender address */
ec2c5e43 282 if (t->received)
8300ba21 283 fd = dns_scope_tcp_socket(t->scope, t->received->family, &t->received->sender, t->received->sender_port, NULL);
ec2c5e43
LP
284 else {
285 union in_addr_union address;
a7f7d1bd 286 int family = AF_UNSPEC;
ec2c5e43
LP
287
288 /* Otherwise, try to talk to the owner of a
289 * the IP address, in case this is a reverse
290 * PTR lookup */
f52e61da
LP
291
292 r = dns_name_address(DNS_RESOURCE_KEY_NAME(t->key), &family, &address);
ec2c5e43
LP
293 if (r < 0)
294 return r;
295 if (r == 0)
296 return -EINVAL;
9e08a6e0 297 if (family != t->scope->family)
9318cdd3 298 return -ESRCH;
ec2c5e43 299
8300ba21 300 fd = dns_scope_tcp_socket(t->scope, family, &address, LLMNR_PORT, NULL);
ec2c5e43 301 }
106784eb
DM
302
303 break;
304
305 default:
ec2c5e43 306 return -EAFNOSUPPORT;
106784eb 307 }
ec2c5e43
LP
308
309 if (fd < 0)
310 return fd;
311
312 r = dns_stream_new(t->scope->manager, &t->stream, t->scope->protocol, fd);
313 if (r < 0)
314 return r;
315
316 fd = -1;
317
318 r = dns_stream_write_packet(t->stream, t->sent);
319 if (r < 0) {
320 t->stream = dns_stream_free(t->stream);
321 return r;
322 }
323
8300ba21
TG
324 dns_server_unref(t->server);
325 t->server = dns_server_ref(server);
ec2c5e43 326 t->received = dns_packet_unref(t->received);
ae6a4bbf
LP
327 t->answer = dns_answer_unref(t->answer);
328 t->answer_rcode = 0;
ec2c5e43
LP
329 t->stream->complete = on_stream_complete;
330 t->stream->transaction = t;
331
332 /* The interface index is difficult to determine if we are
333 * connecting to the local host, hence fill this in right away
334 * instead of determining it from the socket */
335 if (t->scope->link)
336 t->stream->ifindex = t->scope->link->ifindex;
337
338 return 0;
339}
340
647f6aa8
TG
341static void dns_transaction_next_dns_server(DnsTransaction *t) {
342 assert(t);
343
344 t->server = dns_server_unref(t->server);
4667e00a
LP
345 t->dns_udp_event_source = sd_event_source_unref(t->dns_udp_event_source);
346 t->dns_udp_fd = safe_close(t->dns_udp_fd);
647f6aa8
TG
347
348 dns_scope_next_dns_server(t->scope);
349}
350
ec2c5e43 351void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
9df3ba6c 352 usec_t ts;
ec2c5e43
LP
353 int r;
354
355 assert(t);
356 assert(p);
357 assert(t->state == DNS_TRANSACTION_PENDING);
9df3ba6c
TG
358 assert(t->scope);
359 assert(t->scope->manager);
ec2c5e43
LP
360
361 /* Note that this call might invalidate the query. Callers
362 * should hence not attempt to access the query or transaction
363 * after calling this function. */
364
106784eb
DM
365 switch (t->scope->protocol) {
366 case DNS_PROTOCOL_LLMNR:
ec2c5e43
LP
367 assert(t->scope->link);
368
369 /* For LLMNR we will not accept any packets from other
370 * interfaces */
371
372 if (p->ifindex != t->scope->link->ifindex)
373 return;
374
375 if (p->family != t->scope->family)
376 return;
377
378 /* Tentative packets are not full responses but still
379 * useful for identifying uniqueness conflicts during
380 * probing. */
8b757a38 381 if (DNS_PACKET_LLMNR_T(p)) {
ec2c5e43
LP
382 dns_transaction_tentative(t, p);
383 return;
384 }
106784eb
DM
385
386 break;
387
4e5bf5e1
DM
388 case DNS_PROTOCOL_MDNS:
389 assert(t->scope->link);
390
391 /* For mDNS we will not accept any packets from other interfaces */
392 if (p->ifindex != t->scope->link->ifindex)
393 return;
394
395 if (p->family != t->scope->family)
396 return;
397
398 break;
399
106784eb
DM
400 case DNS_PROTOCOL_DNS:
401 break;
402
403 default:
9c56a6f3 404 assert_not_reached("Invalid DNS protocol.");
ec2c5e43
LP
405 }
406
ec2c5e43
LP
407 if (t->received != p) {
408 dns_packet_unref(t->received);
409 t->received = dns_packet_ref(p);
410 }
411
c3bc53e6
LP
412 t->answer_source = DNS_TRANSACTION_NETWORK;
413
ec2c5e43
LP
414 if (p->ipproto == IPPROTO_TCP) {
415 if (DNS_PACKET_TC(p)) {
416 /* Truncated via TCP? Somebody must be fucking with us */
417 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
418 return;
419 }
420
421 if (DNS_PACKET_ID(p) != t->id) {
422 /* Not the reply to our query? Somebody must be fucking with us */
423 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
424 return;
425 }
426 }
427
38a03f06 428 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
9df3ba6c
TG
429
430 switch (t->scope->protocol) {
8af5b883 431
9df3ba6c
TG
432 case DNS_PROTOCOL_DNS:
433 assert(t->server);
434
4e0b8b17
TG
435 if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_FORMERR, DNS_RCODE_SERVFAIL, DNS_RCODE_NOTIMP)) {
436
8af5b883 437 /* Request failed, immediately try again with reduced features */
4e0b8b17
TG
438 log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p)));
439
440 dns_server_packet_failed(t->server, t->current_features);
441
442 r = dns_transaction_go(t);
443 if (r < 0) {
444 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
445 return;
446 }
447
448 return;
449 } else
d74fb368 450 dns_server_packet_received(t->server, t->current_features, ts - t->start_usec, p->size);
9df3ba6c
TG
451
452 break;
8af5b883 453
9df3ba6c
TG
454 case DNS_PROTOCOL_LLMNR:
455 case DNS_PROTOCOL_MDNS:
456 dns_scope_packet_received(t->scope, ts - t->start_usec);
9df3ba6c 457 break;
8af5b883 458
9df3ba6c 459 default:
8af5b883 460 assert_not_reached("Invalid DNS protocol.");
9df3ba6c
TG
461 }
462
ec2c5e43 463 if (DNS_PACKET_TC(p)) {
547493c5
DM
464
465 /* Truncated packets for mDNS are not allowed. Give up immediately. */
466 if (t->scope->protocol == DNS_PROTOCOL_MDNS) {
467 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
468 return;
469 }
470
ec2c5e43
LP
471 /* Response was truncated, let's try again with good old TCP */
472 r = dns_transaction_open_tcp(t);
473 if (r == -ESRCH) {
474 /* No servers found? Damn! */
475 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
476 return;
477 }
478 if (r < 0) {
8af5b883 479 /* On LLMNR, if we cannot connect to the host,
ec2c5e43
LP
480 * we immediately give up */
481 if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
482 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
483 return;
484 }
485
486 /* On DNS, couldn't send? Try immediately again, with a new server */
647f6aa8 487 dns_transaction_next_dns_server(t);
ec2c5e43
LP
488
489 r = dns_transaction_go(t);
490 if (r < 0) {
491 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
492 return;
493 }
494
495 return;
496 }
497 }
498
8af5b883 499 /* Parse message, if it isn't parsed yet. */
ec2c5e43
LP
500 r = dns_packet_extract(p);
501 if (r < 0) {
502 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
503 return;
504 }
505
547493c5
DM
506 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
507 /* Only consider responses with equivalent query section to the request */
8af5b883
LP
508 r = dns_packet_is_reply_for(p, t->key);
509 if (r < 0) {
510 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
511 return;
512 }
513 if (r == 0) {
547493c5
DM
514 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
515 return;
516 }
29815b6c 517
547493c5
DM
518 /* Install the answer as answer to the transaction */
519 dns_answer_unref(t->answer);
520 t->answer = dns_answer_ref(p->answer);
521 t->answer_rcode = DNS_PACKET_RCODE(p);
522 t->answer_authenticated = t->scope->dnssec_mode == DNSSEC_TRUST && DNS_PACKET_AD(p);
523
524 /* According to RFC 4795, section 2.9. only the RRs from the answer section shall be cached */
525 if (DNS_PACKET_SHALL_CACHE(p))
526 dns_cache_put(&t->scope->cache,
527 t->key,
528 DNS_PACKET_RCODE(p),
529 p->answer,
530 DNS_PACKET_ANCOUNT(p),
531 t->answer_authenticated,
532 0,
533 p->family,
534 &p->sender);
535 }
ec2c5e43
LP
536
537 if (DNS_PACKET_RCODE(p) == DNS_RCODE_SUCCESS)
538 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
539 else
540 dns_transaction_complete(t, DNS_TRANSACTION_FAILURE);
541}
542
c19ffd9f
TG
543static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
544 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
545 DnsTransaction *t = userdata;
546 int r;
547
548 assert(t);
549 assert(t->scope);
550
551 r = manager_recv(t->scope->manager, fd, DNS_PROTOCOL_DNS, &p);
552 if (r <= 0)
553 return r;
554
555 if (dns_packet_validate_reply(p) > 0 &&
9df3ba6c 556 DNS_PACKET_ID(p) == t->id)
c19ffd9f 557 dns_transaction_process_reply(t, p);
9df3ba6c 558 else
8af5b883 559 log_debug("Invalid DNS packet, ignoring.");
c19ffd9f
TG
560
561 return 0;
562}
563
471d40d9 564static int dns_transaction_emit(DnsTransaction *t) {
c19ffd9f
TG
565 int r;
566
567 assert(t);
c19ffd9f 568
471d40d9
TG
569 if (t->scope->protocol == DNS_PROTOCOL_DNS && !t->server) {
570 DnsServer *server = NULL;
571 _cleanup_close_ int fd = -1;
c19ffd9f 572
471d40d9
TG
573 fd = dns_scope_udp_dns_socket(t->scope, &server);
574 if (fd < 0)
575 return fd;
c19ffd9f 576
4667e00a 577 r = sd_event_add_io(t->scope->manager->event, &t->dns_udp_event_source, fd, EPOLLIN, on_dns_packet, t);
471d40d9
TG
578 if (r < 0)
579 return r;
c19ffd9f 580
4667e00a 581 t->dns_udp_fd = fd;
471d40d9
TG
582 fd = -1;
583 t->server = dns_server_ref(server);
584 }
c19ffd9f 585
9c5e12a4 586 r = dns_scope_emit(t->scope, t->dns_udp_fd, t->server, t->sent);
471d40d9
TG
587 if (r < 0)
588 return r;
c19ffd9f 589
be808ea0
TG
590 if (t->server)
591 t->current_features = t->server->possible_features;
592
471d40d9 593 return 0;
c19ffd9f
TG
594}
595
ec2c5e43
LP
596static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
597 DnsTransaction *t = userdata;
598 int r;
599
600 assert(s);
601 assert(t);
602
ef7ce6df
DM
603 if (!t->initial_jitter_scheduled || t->initial_jitter_elapsed) {
604 /* Timeout reached? Increase the timeout for the server used */
605 switch (t->scope->protocol) {
606 case DNS_PROTOCOL_DNS:
607 assert(t->server);
ec2c5e43 608
ef7ce6df 609 dns_server_packet_lost(t->server, t->current_features, usec - t->start_usec);
be808ea0 610
ef7ce6df
DM
611 break;
612 case DNS_PROTOCOL_LLMNR:
613 case DNS_PROTOCOL_MDNS:
614 dns_scope_packet_lost(t->scope, usec - t->start_usec);
9df3ba6c 615
ef7ce6df
DM
616 break;
617 default:
618 assert_not_reached("Invalid DNS protocol.");
619 }
620
621 if (t->initial_jitter_scheduled)
622 t->initial_jitter_elapsed = true;
be808ea0
TG
623 }
624
625 /* ...and try again with a new server */
626 dns_transaction_next_dns_server(t);
627
ec2c5e43
LP
628 r = dns_transaction_go(t);
629 if (r < 0)
630 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
631
632 return 0;
633}
634
9df3ba6c
TG
635static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
636 assert(t);
637 assert(t->scope);
638
639 switch (t->scope->protocol) {
640 case DNS_PROTOCOL_DNS:
641 assert(t->server);
642
643 return t->server->resend_timeout;
9df3ba6c 644 case DNS_PROTOCOL_MDNS:
11a27c2e
DM
645 assert(t->n_attempts > 0);
646 return (1 << (t->n_attempts - 1)) * USEC_PER_SEC;
647 case DNS_PROTOCOL_LLMNR:
9df3ba6c
TG
648 return t->scope->resend_timeout;
649 default:
650 assert_not_reached("Invalid DNS protocol.");
651 }
652}
653
1effe965 654static int dns_transaction_prepare_next_attempt(DnsTransaction *t, usec_t ts) {
ec2c5e43
LP
655 bool had_stream;
656 int r;
657
658 assert(t);
659
660 had_stream = !!t->stream;
661
662 dns_transaction_stop(t);
663
ec2c5e43
LP
664 if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t->scope->protocol)) {
665 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
666 return 0;
667 }
668
669 if (t->scope->protocol == DNS_PROTOCOL_LLMNR && had_stream) {
670 /* If we already tried via a stream, then we don't
671 * retry on LLMNR. See RFC 4795, Section 2.7. */
672 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
673 return 0;
674 }
675
676 t->n_attempts++;
9df3ba6c 677 t->start_usec = ts;
ec2c5e43 678 t->received = dns_packet_unref(t->received);
ae6a4bbf
LP
679 t->answer = dns_answer_unref(t->answer);
680 t->answer_rcode = 0;
c3bc53e6 681 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
ec2c5e43 682
0d2cd476
LP
683 /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
684 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
685 r = dns_trust_anchor_lookup(&t->scope->manager->trust_anchor, t->key, &t->answer);
686 if (r < 0)
687 return r;
688 if (r > 0) {
689 t->answer_rcode = DNS_RCODE_SUCCESS;
690 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
931851e8 691 t->answer_authenticated = true;
0d2cd476
LP
692 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
693 return 0;
694 }
695 }
696
697 /* Check the zone, but only if this transaction is not used
d746bb3e
LP
698 * for probing or verifying a zone item. */
699 if (set_isempty(t->zone_items)) {
700
ae6a4bbf 701 r = dns_zone_lookup(&t->scope->zone, t->key, &t->answer, NULL, NULL);
d746bb3e
LP
702 if (r < 0)
703 return r;
704 if (r > 0) {
ae6a4bbf 705 t->answer_rcode = DNS_RCODE_SUCCESS;
c3bc53e6 706 t->answer_source = DNS_TRANSACTION_ZONE;
931851e8 707 t->answer_authenticated = true;
d746bb3e
LP
708 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
709 return 0;
710 }
711 }
712
4d926a69
LP
713 /* Check the cache, but only if this transaction is not used
714 * for probing or verifying a zone item. */
715 if (set_isempty(t->zone_items)) {
2c27fbca 716
4d926a69
LP
717 /* Before trying the cache, let's make sure we figured out a
718 * server to use. Should this cause a change of server this
719 * might flush the cache. */
720 dns_scope_get_dns_server(t->scope);
2c27fbca 721
4d926a69
LP
722 /* Let's then prune all outdated entries */
723 dns_cache_prune(&t->scope->cache);
724
931851e8 725 r = dns_cache_lookup(&t->scope->cache, t->key, &t->answer_rcode, &t->answer, &t->answer_authenticated);
4d926a69
LP
726 if (r < 0)
727 return r;
728 if (r > 0) {
c3bc53e6 729 t->answer_source = DNS_TRANSACTION_CACHE;
ae6a4bbf 730 if (t->answer_rcode == DNS_RCODE_SUCCESS)
4d926a69
LP
731 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
732 else
733 dns_transaction_complete(t, DNS_TRANSACTION_FAILURE);
734 return 0;
735 }
ec2c5e43
LP
736 }
737
1effe965
DM
738 return 1;
739}
740
0afa57e2
DM
741static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
742
743 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
7778dfff 744 bool add_known_answers = false;
0afa57e2
DM
745 DnsTransaction *other;
746 unsigned qdcount;
747 usec_t ts;
748 int r;
749
750 assert(t);
751 assert(t->scope->protocol == DNS_PROTOCOL_MDNS);
752
753 /* Discard any previously prepared packet, so we can start over and coaleasce again */
754 t->sent = dns_packet_unref(t->sent);
755
756 r = dns_packet_new_query(&p, t->scope->protocol, 0, false);
757 if (r < 0)
758 return r;
759
760 r = dns_packet_append_key(p, t->key, NULL);
761 if (r < 0)
762 return r;
763
764 qdcount = 1;
765
7778dfff
DM
766 if (dns_key_is_shared(t->key))
767 add_known_answers = true;
768
0afa57e2
DM
769 /*
770 * For mDNS, we want to coalesce as many open queries in pending transactions into one single
771 * query packet on the wire as possible. To achieve that, we iterate through all pending transactions
772 * in our current scope, and see whether their timing contraints allow them to be sent.
773 */
774
775 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
776
777 LIST_FOREACH(transactions_by_scope, other, t->scope->transactions) {
778
779 /* Skip ourselves */
780 if (other == t)
781 continue;
782
783 if (other->state != DNS_TRANSACTION_PENDING)
784 continue;
785
786 if (other->next_attempt_after > ts)
787 continue;
788
789 if (qdcount >= UINT16_MAX)
790 break;
791
792 r = dns_packet_append_key(p, other->key, NULL);
793
794 /*
795 * If we can't stuff more questions into the packet, just give up.
796 * One of the 'other' transactions will fire later and take care of the rest.
797 */
798 if (r == -EMSGSIZE)
799 break;
800
801 if (r < 0)
802 return r;
803
804 r = dns_transaction_prepare_next_attempt(other, ts);
805 if (r <= 0)
806 continue;
807
808 ts += transaction_get_resend_timeout(other);
809
810 r = sd_event_add_time(
811 other->scope->manager->event,
812 &other->timeout_event_source,
813 clock_boottime_or_monotonic(),
814 ts, 0,
815 on_transaction_timeout, other);
816 if (r < 0)
817 return r;
818
819 other->state = DNS_TRANSACTION_PENDING;
820 other->next_attempt_after = ts;
821
822 qdcount ++;
7778dfff
DM
823
824 if (dns_key_is_shared(other->key))
825 add_known_answers = true;
0afa57e2
DM
826 }
827
828 DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount);
829 DNS_PACKET_HEADER(p)->id = t->id;
830
7778dfff
DM
831 /* Append known answer section if we're asking for any shared record */
832 if (add_known_answers) {
833 r = dns_cache_export_shared_to_packet(&t->scope->cache, p);
834 if (r < 0)
835 return r;
836 }
837
0afa57e2
DM
838 t->sent = p;
839 p = NULL;
840
841 return 0;
842}
843
844static int dns_transaction_make_packet(DnsTransaction *t) {
845 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
846 int r;
847
848 assert(t);
849
850 if (t->scope->protocol == DNS_PROTOCOL_MDNS)
851 return dns_transaction_make_packet_mdns(t);
852
853 if (t->sent)
854 return 0;
855
856 r = dns_packet_new_query(&p, t->scope->protocol, 0, t->scope->dnssec_mode == DNSSEC_YES);
857 if (r < 0)
858 return r;
859
860 r = dns_scope_good_key(t->scope, t->key);
861 if (r < 0)
862 return r;
863 if (r == 0)
864 return -EDOM;
865
866 r = dns_packet_append_key(p, t->key, NULL);
867 if (r < 0)
868 return r;
869
870 DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
871 DNS_PACKET_HEADER(p)->id = t->id;
872
873 t->sent = p;
874 p = NULL;
875
876 return 0;
877}
878
1effe965
DM
879int dns_transaction_go(DnsTransaction *t) {
880 usec_t ts;
881 int r;
882
883 assert(t);
884
885 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
886 r = dns_transaction_prepare_next_attempt(t, ts);
887 if (r <= 0)
888 return r;
889
890 log_debug("Excercising transaction on scope %s on %s/%s",
891 dns_protocol_to_string(t->scope->protocol),
892 t->scope->link ? t->scope->link->name : "*",
893 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family));
894
ef7ce6df 895 if (!t->initial_jitter_scheduled &&
ea12bcc7
DM
896 (t->scope->protocol == DNS_PROTOCOL_LLMNR ||
897 t->scope->protocol == DNS_PROTOCOL_MDNS)) {
898 usec_t jitter, accuracy;
6e068472
LP
899
900 /* RFC 4795 Section 2.7 suggests all queries should be
901 * delayed by a random time from 0 to JITTER_INTERVAL. */
902
ef7ce6df 903 t->initial_jitter_scheduled = true;
6e068472
LP
904
905 random_bytes(&jitter, sizeof(jitter));
ea12bcc7
DM
906
907 switch (t->scope->protocol) {
908 case DNS_PROTOCOL_LLMNR:
909 jitter %= LLMNR_JITTER_INTERVAL_USEC;
910 accuracy = LLMNR_JITTER_INTERVAL_USEC;
911 break;
912 case DNS_PROTOCOL_MDNS:
913 jitter %= MDNS_JITTER_RANGE_USEC;
914 jitter += MDNS_JITTER_MIN_USEC;
915 accuracy = MDNS_JITTER_RANGE_USEC;
916 break;
917 default:
918 assert_not_reached("bad protocol");
919 }
6e068472
LP
920
921 r = sd_event_add_time(
922 t->scope->manager->event,
923 &t->timeout_event_source,
924 clock_boottime_or_monotonic(),
ea12bcc7 925 ts + jitter, accuracy,
6e068472
LP
926 on_transaction_timeout, t);
927 if (r < 0)
928 return r;
929
930 t->n_attempts = 0;
a9da14e1 931 t->next_attempt_after = ts;
6e068472
LP
932 t->state = DNS_TRANSACTION_PENDING;
933
ea12bcc7 934 log_debug("Delaying %s transaction for " USEC_FMT "us.", dns_protocol_to_string(t->scope->protocol), jitter);
6e068472
LP
935 return 0;
936 }
937
ec2c5e43
LP
938 /* Otherwise, we need to ask the network */
939 r = dns_transaction_make_packet(t);
940 if (r == -EDOM) {
941 /* Not the right request to make on this network?
942 * (i.e. an A request made on IPv6 or an AAAA request
943 * made on IPv4, on LLMNR or mDNS.) */
944 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
945 return 0;
946 }
947 if (r < 0)
948 return r;
949
950 if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
f52e61da
LP
951 (dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), "in-addr.arpa") > 0 ||
952 dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), "ip6.arpa") > 0)) {
ec2c5e43
LP
953
954 /* RFC 4795, Section 2.4. says reverse lookups shall
955 * always be made via TCP on LLMNR */
956 r = dns_transaction_open_tcp(t);
957 } else {
be808ea0
TG
958 /* Try via UDP, and if that fails due to large size or lack of
959 * support try via TCP */
471d40d9 960 r = dns_transaction_emit(t);
be808ea0 961 if (r == -EMSGSIZE || r == -EAGAIN)
ec2c5e43
LP
962 r = dns_transaction_open_tcp(t);
963 }
be808ea0 964
ec2c5e43
LP
965 if (r == -ESRCH) {
966 /* No servers to send this to? */
967 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
968 return 0;
8300ba21 969 } else if (r < 0) {
13b551ac
LP
970 if (t->scope->protocol != DNS_PROTOCOL_DNS) {
971 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
972 return 0;
973 }
974
ec2c5e43 975 /* Couldn't send? Try immediately again, with a new server */
647f6aa8 976 dns_transaction_next_dns_server(t);
ec2c5e43
LP
977
978 return dns_transaction_go(t);
979 }
980
a9da14e1
DM
981 ts += transaction_get_resend_timeout(t);
982
9a015429
LP
983 r = sd_event_add_time(
984 t->scope->manager->event,
985 &t->timeout_event_source,
986 clock_boottime_or_monotonic(),
a9da14e1 987 ts, 0,
9a015429 988 on_transaction_timeout, t);
ec2c5e43
LP
989 if (r < 0)
990 return r;
991
992 t->state = DNS_TRANSACTION_PENDING;
a9da14e1
DM
993 t->next_attempt_after = ts;
994
ec2c5e43
LP
995 return 1;
996}
997
998static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX] = {
999 [DNS_TRANSACTION_NULL] = "null",
1000 [DNS_TRANSACTION_PENDING] = "pending",
1001 [DNS_TRANSACTION_FAILURE] = "failure",
1002 [DNS_TRANSACTION_SUCCESS] = "success",
1003 [DNS_TRANSACTION_NO_SERVERS] = "no-servers",
1004 [DNS_TRANSACTION_TIMEOUT] = "timeout",
1005 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED] = "attempts-max-reached",
1006 [DNS_TRANSACTION_INVALID_REPLY] = "invalid-reply",
1007 [DNS_TRANSACTION_RESOURCES] = "resources",
1008 [DNS_TRANSACTION_ABORTED] = "aborted",
1009};
1010DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);
c3bc53e6
LP
1011
1012static const char* const dns_transaction_source_table[_DNS_TRANSACTION_SOURCE_MAX] = {
1013 [DNS_TRANSACTION_NETWORK] = "network",
1014 [DNS_TRANSACTION_CACHE] = "cache",
1015 [DNS_TRANSACTION_ZONE] = "zone",
0d2cd476 1016 [DNS_TRANSACTION_TRUST_ANCHOR] = "trust-anchor",
c3bc53e6
LP
1017};
1018DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source, DnsTransactionSource);