]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-transaction.c
Merge pull request #2115 from dvdhrm/rbtree
[thirdparty/systemd.git] / src / resolve / resolved-dns-transaction.c
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"
23 #include "alloc-util.h"
24 #include "dns-domain.h"
25 #include "fd-util.h"
26 #include "random-util.h"
27 #include "resolved-dns-cache.h"
28 #include "resolved-dns-transaction.h"
29 #include "resolved-llmnr.h"
30 #include "string-table.h"
31
32 DnsTransaction* dns_transaction_free(DnsTransaction *t) {
33 DnsQueryCandidate *c;
34 DnsZoneItem *i;
35
36 if (!t)
37 return NULL;
38
39 sd_event_source_unref(t->timeout_event_source);
40
41 dns_packet_unref(t->sent);
42 dns_packet_unref(t->received);
43
44 dns_answer_unref(t->answer);
45
46 sd_event_source_unref(t->dns_udp_event_source);
47 safe_close(t->dns_udp_fd);
48
49 dns_server_unref(t->server);
50 dns_stream_free(t->stream);
51
52 if (t->scope) {
53 hashmap_remove_value(t->scope->transactions_by_key, t->key, t);
54 LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
55
56 if (t->id != 0)
57 hashmap_remove(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id));
58 }
59
60 dns_resource_key_unref(t->key);
61
62 while ((c = set_steal_first(t->query_candidates)))
63 set_remove(c->transactions, t);
64
65 set_free(t->query_candidates);
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
75 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_free);
76
77 void dns_transaction_gc(DnsTransaction *t) {
78 assert(t);
79
80 if (t->block_gc > 0)
81 return;
82
83 if (set_isempty(t->query_candidates) && set_isempty(t->zone_items))
84 dns_transaction_free(t);
85 }
86
87 int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key) {
88 _cleanup_(dns_transaction_freep) DnsTransaction *t = NULL;
89 int r;
90
91 assert(ret);
92 assert(s);
93 assert(key);
94
95 r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL);
96 if (r < 0)
97 return r;
98
99 r = hashmap_ensure_allocated(&s->transactions_by_key, &dns_resource_key_hash_ops);
100 if (r < 0)
101 return r;
102
103 t = new0(DnsTransaction, 1);
104 if (!t)
105 return -ENOMEM;
106
107 t->dns_udp_fd = -1;
108 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
109 t->key = dns_resource_key_ref(key);
110
111 /* Find a fresh, unused transaction id */
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
123 r = hashmap_replace(s->transactions_by_key, t->key, t);
124 if (r < 0) {
125 hashmap_remove(s->manager->dns_transactions, UINT_TO_PTR(t->id));
126 return r;
127 }
128
129 LIST_PREPEND(transactions_by_scope, s->transactions, t);
130 t->scope = s;
131
132 if (ret)
133 *ret = t;
134
135 t = NULL;
136
137 return 0;
138 }
139
140 static 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);
145
146 /* Note that we do not drop the UDP socket here, as we want to
147 * reuse it to repeat the interaction. */
148 }
149
150 static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
151 _cleanup_free_ char *pretty = NULL;
152 DnsZoneItem *z;
153
154 assert(t);
155 assert(p);
156
157 if (manager_our_packet(t->scope->manager, p) != 0)
158 return;
159
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",
163 dns_protocol_to_string(t->scope->protocol),
164 t->scope->link ? t->scope->link->name : "*",
165 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
166 pretty);
167
168 /* RFC 4795, Section 4.1 says that the peer with the
169 * lexicographically smaller IP address loses */
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.");
172 return;
173 }
174
175 log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
176
177 t->block_gc++;
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 */
185 dns_zone_item_conflict(z);
186 }
187 t->block_gc--;
188
189 dns_transaction_gc(t);
190 }
191
192 void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
193 DnsQueryCandidate *c;
194 DnsZoneItem *z;
195 Iterator i;
196
197 assert(t);
198 assert(!IN_SET(state, DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING));
199
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
204 log_debug("Transaction on scope %s on %s/%s now complete with <%s> from %s",
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),
208 dns_transaction_state_to_string(state),
209 t->answer_source < 0 ? "none" : dns_transaction_source_to_string(t->answer_source));
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++;
218 SET_FOREACH(c, t->query_candidates, i)
219 dns_query_candidate_ready(c);
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
227 static 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
246 if (dns_packet_validate_reply(p) <= 0) {
247 log_debug("Invalid TCP reply packet.");
248 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
249 return 0;
250 }
251
252 dns_scope_check_conflicts(t->scope, p);
253
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
265 static int dns_transaction_open_tcp(DnsTransaction *t) {
266 DnsServer *server = NULL;
267 _cleanup_close_ int fd = -1;
268 int r;
269
270 assert(t);
271
272 if (t->stream)
273 return 0;
274
275 switch (t->scope->protocol) {
276 case DNS_PROTOCOL_DNS:
277 fd = dns_scope_tcp_socket(t->scope, AF_UNSPEC, NULL, 53, &server);
278 break;
279
280 case DNS_PROTOCOL_LLMNR:
281 /* When we already received a reply to this (but it was truncated), send to its sender address */
282 if (t->received)
283 fd = dns_scope_tcp_socket(t->scope, t->received->family, &t->received->sender, t->received->sender_port, NULL);
284 else {
285 union in_addr_union address;
286 int family = AF_UNSPEC;
287
288 /* Otherwise, try to talk to the owner of a
289 * the IP address, in case this is a reverse
290 * PTR lookup */
291
292 r = dns_name_address(DNS_RESOURCE_KEY_NAME(t->key), &family, &address);
293 if (r < 0)
294 return r;
295 if (r == 0)
296 return -EINVAL;
297 if (family != t->scope->family)
298 return -ESRCH;
299
300 fd = dns_scope_tcp_socket(t->scope, family, &address, LLMNR_PORT, NULL);
301 }
302
303 break;
304
305 default:
306 return -EAFNOSUPPORT;
307 }
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
324 dns_server_unref(t->server);
325 t->server = dns_server_ref(server);
326 t->received = dns_packet_unref(t->received);
327 t->answer = dns_answer_unref(t->answer);
328 t->answer_rcode = 0;
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
341 static void dns_transaction_next_dns_server(DnsTransaction *t) {
342 assert(t);
343
344 t->server = dns_server_unref(t->server);
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);
347
348 dns_scope_next_dns_server(t->scope);
349 }
350
351 void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
352 usec_t ts;
353 int r;
354
355 assert(t);
356 assert(p);
357 assert(t->state == DNS_TRANSACTION_PENDING);
358 assert(t->scope);
359 assert(t->scope->manager);
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
365 switch (t->scope->protocol) {
366 case DNS_PROTOCOL_LLMNR:
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. */
381 if (DNS_PACKET_LLMNR_T(p)) {
382 dns_transaction_tentative(t, p);
383 return;
384 }
385
386 break;
387
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
400 case DNS_PROTOCOL_DNS:
401 break;
402
403 default:
404 assert_not_reached("Invalid DNS protocol.");
405 }
406
407 if (t->received != p) {
408 dns_packet_unref(t->received);
409 t->received = dns_packet_ref(p);
410 }
411
412 t->answer_source = DNS_TRANSACTION_NETWORK;
413
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
428 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
429
430 switch (t->scope->protocol) {
431 case DNS_PROTOCOL_DNS:
432 assert(t->server);
433
434 if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_FORMERR, DNS_RCODE_SERVFAIL, DNS_RCODE_NOTIMP)) {
435
436 /* request failed, immediately try again with reduced features */
437 log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p)));
438
439 dns_server_packet_failed(t->server, t->current_features);
440
441 r = dns_transaction_go(t);
442 if (r < 0) {
443 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
444 return;
445 }
446
447 return;
448 } else
449 dns_server_packet_received(t->server, t->current_features, ts - t->start_usec, p->size);
450
451 break;
452 case DNS_PROTOCOL_LLMNR:
453 case DNS_PROTOCOL_MDNS:
454 dns_scope_packet_received(t->scope, ts - t->start_usec);
455
456 break;
457 default:
458 break;
459 }
460
461 if (DNS_PACKET_TC(p)) {
462
463 /* Truncated packets for mDNS are not allowed. Give up immediately. */
464 if (t->scope->protocol == DNS_PROTOCOL_MDNS) {
465 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
466 return;
467 }
468
469 /* Response was truncated, let's try again with good old TCP */
470 r = dns_transaction_open_tcp(t);
471 if (r == -ESRCH) {
472 /* No servers found? Damn! */
473 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
474 return;
475 }
476 if (r < 0) {
477 /* On LLMNR and mDNS, if we cannot connect to the host,
478 * we immediately give up */
479 if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
480 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
481 return;
482 }
483
484 /* On DNS, couldn't send? Try immediately again, with a new server */
485 dns_transaction_next_dns_server(t);
486
487 r = dns_transaction_go(t);
488 if (r < 0) {
489 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
490 return;
491 }
492
493 return;
494 }
495 }
496
497 /* Parse and update the cache */
498 r = dns_packet_extract(p);
499 if (r < 0) {
500 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
501 return;
502 }
503
504 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
505 /* Only consider responses with equivalent query section to the request */
506 if (p->question->n_keys != 1 || dns_resource_key_equal(p->question->keys[0], t->key) <= 0) {
507 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
508 return;
509 }
510
511 /* Install the answer as answer to the transaction */
512 dns_answer_unref(t->answer);
513 t->answer = dns_answer_ref(p->answer);
514 t->answer_rcode = DNS_PACKET_RCODE(p);
515 t->answer_authenticated = t->scope->dnssec_mode == DNSSEC_TRUST && DNS_PACKET_AD(p);
516
517 /* According to RFC 4795, section 2.9. only the RRs from the answer section shall be cached */
518 if (DNS_PACKET_SHALL_CACHE(p))
519 dns_cache_put(&t->scope->cache,
520 t->key,
521 DNS_PACKET_RCODE(p),
522 p->answer,
523 DNS_PACKET_ANCOUNT(p),
524 t->answer_authenticated,
525 0,
526 p->family,
527 &p->sender);
528 }
529
530 if (DNS_PACKET_RCODE(p) == DNS_RCODE_SUCCESS)
531 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
532 else
533 dns_transaction_complete(t, DNS_TRANSACTION_FAILURE);
534 }
535
536 static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
537 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
538 DnsTransaction *t = userdata;
539 int r;
540
541 assert(t);
542 assert(t->scope);
543
544 r = manager_recv(t->scope->manager, fd, DNS_PROTOCOL_DNS, &p);
545 if (r <= 0)
546 return r;
547
548 if (dns_packet_validate_reply(p) > 0 &&
549 DNS_PACKET_ID(p) == t->id)
550 dns_transaction_process_reply(t, p);
551 else
552 log_debug("Invalid DNS packet.");
553
554 return 0;
555 }
556
557 static int dns_transaction_emit(DnsTransaction *t) {
558 int r;
559
560 assert(t);
561
562 if (t->scope->protocol == DNS_PROTOCOL_DNS && !t->server) {
563 DnsServer *server = NULL;
564 _cleanup_close_ int fd = -1;
565
566 fd = dns_scope_udp_dns_socket(t->scope, &server);
567 if (fd < 0)
568 return fd;
569
570 r = sd_event_add_io(t->scope->manager->event, &t->dns_udp_event_source, fd, EPOLLIN, on_dns_packet, t);
571 if (r < 0)
572 return r;
573
574 t->dns_udp_fd = fd;
575 fd = -1;
576 t->server = dns_server_ref(server);
577 }
578
579 r = dns_scope_emit(t->scope, t->dns_udp_fd, t->server, t->sent);
580 if (r < 0)
581 return r;
582
583 if (t->server)
584 t->current_features = t->server->possible_features;
585
586 return 0;
587 }
588
589 static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
590 DnsTransaction *t = userdata;
591 int r;
592
593 assert(s);
594 assert(t);
595
596 if (!t->initial_jitter_scheduled || t->initial_jitter_elapsed) {
597 /* Timeout reached? Increase the timeout for the server used */
598 switch (t->scope->protocol) {
599 case DNS_PROTOCOL_DNS:
600 assert(t->server);
601
602 dns_server_packet_lost(t->server, t->current_features, usec - t->start_usec);
603
604 break;
605 case DNS_PROTOCOL_LLMNR:
606 case DNS_PROTOCOL_MDNS:
607 dns_scope_packet_lost(t->scope, usec - t->start_usec);
608
609 break;
610 default:
611 assert_not_reached("Invalid DNS protocol.");
612 }
613
614 if (t->initial_jitter_scheduled)
615 t->initial_jitter_elapsed = true;
616 }
617
618 /* ...and try again with a new server */
619 dns_transaction_next_dns_server(t);
620
621 r = dns_transaction_go(t);
622 if (r < 0)
623 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
624
625 return 0;
626 }
627
628 static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
629 assert(t);
630 assert(t->scope);
631
632 switch (t->scope->protocol) {
633 case DNS_PROTOCOL_DNS:
634 assert(t->server);
635
636 return t->server->resend_timeout;
637 case DNS_PROTOCOL_MDNS:
638 assert(t->n_attempts > 0);
639 return (1 << (t->n_attempts - 1)) * USEC_PER_SEC;
640 case DNS_PROTOCOL_LLMNR:
641 return t->scope->resend_timeout;
642 default:
643 assert_not_reached("Invalid DNS protocol.");
644 }
645 }
646
647 static int dns_transaction_prepare_next_attempt(DnsTransaction *t, usec_t ts) {
648 bool had_stream;
649 int r;
650
651 assert(t);
652
653 had_stream = !!t->stream;
654
655 dns_transaction_stop(t);
656
657 if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t->scope->protocol)) {
658 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
659 return 0;
660 }
661
662 if (t->scope->protocol == DNS_PROTOCOL_LLMNR && had_stream) {
663 /* If we already tried via a stream, then we don't
664 * retry on LLMNR. See RFC 4795, Section 2.7. */
665 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
666 return 0;
667 }
668
669 t->n_attempts++;
670 t->start_usec = ts;
671 t->received = dns_packet_unref(t->received);
672 t->answer = dns_answer_unref(t->answer);
673 t->answer_rcode = 0;
674 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
675
676 /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
677 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
678 r = dns_trust_anchor_lookup(&t->scope->manager->trust_anchor, t->key, &t->answer);
679 if (r < 0)
680 return r;
681 if (r > 0) {
682 t->answer_rcode = DNS_RCODE_SUCCESS;
683 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
684 t->answer_authenticated = true;
685 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
686 return 0;
687 }
688 }
689
690 /* Check the zone, but only if this transaction is not used
691 * for probing or verifying a zone item. */
692 if (set_isempty(t->zone_items)) {
693
694 r = dns_zone_lookup(&t->scope->zone, t->key, &t->answer, NULL, NULL);
695 if (r < 0)
696 return r;
697 if (r > 0) {
698 t->answer_rcode = DNS_RCODE_SUCCESS;
699 t->answer_source = DNS_TRANSACTION_ZONE;
700 t->answer_authenticated = true;
701 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
702 return 0;
703 }
704 }
705
706 /* Check the cache, but only if this transaction is not used
707 * for probing or verifying a zone item. */
708 if (set_isempty(t->zone_items)) {
709
710 /* Before trying the cache, let's make sure we figured out a
711 * server to use. Should this cause a change of server this
712 * might flush the cache. */
713 dns_scope_get_dns_server(t->scope);
714
715 /* Let's then prune all outdated entries */
716 dns_cache_prune(&t->scope->cache);
717
718 r = dns_cache_lookup(&t->scope->cache, t->key, &t->answer_rcode, &t->answer, &t->answer_authenticated);
719 if (r < 0)
720 return r;
721 if (r > 0) {
722 t->answer_source = DNS_TRANSACTION_CACHE;
723 if (t->answer_rcode == DNS_RCODE_SUCCESS)
724 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
725 else
726 dns_transaction_complete(t, DNS_TRANSACTION_FAILURE);
727 return 0;
728 }
729 }
730
731 return 1;
732 }
733
734 static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
735
736 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
737 bool add_known_answers = false;
738 DnsTransaction *other;
739 unsigned qdcount;
740 usec_t ts;
741 int r;
742
743 assert(t);
744 assert(t->scope->protocol == DNS_PROTOCOL_MDNS);
745
746 /* Discard any previously prepared packet, so we can start over and coaleasce again */
747 t->sent = dns_packet_unref(t->sent);
748
749 r = dns_packet_new_query(&p, t->scope->protocol, 0, false);
750 if (r < 0)
751 return r;
752
753 r = dns_packet_append_key(p, t->key, NULL);
754 if (r < 0)
755 return r;
756
757 qdcount = 1;
758
759 if (dns_key_is_shared(t->key))
760 add_known_answers = true;
761
762 /*
763 * For mDNS, we want to coalesce as many open queries in pending transactions into one single
764 * query packet on the wire as possible. To achieve that, we iterate through all pending transactions
765 * in our current scope, and see whether their timing contraints allow them to be sent.
766 */
767
768 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
769
770 LIST_FOREACH(transactions_by_scope, other, t->scope->transactions) {
771
772 /* Skip ourselves */
773 if (other == t)
774 continue;
775
776 if (other->state != DNS_TRANSACTION_PENDING)
777 continue;
778
779 if (other->next_attempt_after > ts)
780 continue;
781
782 if (qdcount >= UINT16_MAX)
783 break;
784
785 r = dns_packet_append_key(p, other->key, NULL);
786
787 /*
788 * If we can't stuff more questions into the packet, just give up.
789 * One of the 'other' transactions will fire later and take care of the rest.
790 */
791 if (r == -EMSGSIZE)
792 break;
793
794 if (r < 0)
795 return r;
796
797 r = dns_transaction_prepare_next_attempt(other, ts);
798 if (r <= 0)
799 continue;
800
801 ts += transaction_get_resend_timeout(other);
802
803 r = sd_event_add_time(
804 other->scope->manager->event,
805 &other->timeout_event_source,
806 clock_boottime_or_monotonic(),
807 ts, 0,
808 on_transaction_timeout, other);
809 if (r < 0)
810 return r;
811
812 other->state = DNS_TRANSACTION_PENDING;
813 other->next_attempt_after = ts;
814
815 qdcount ++;
816
817 if (dns_key_is_shared(other->key))
818 add_known_answers = true;
819 }
820
821 DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount);
822 DNS_PACKET_HEADER(p)->id = t->id;
823
824 /* Append known answer section if we're asking for any shared record */
825 if (add_known_answers) {
826 r = dns_cache_export_shared_to_packet(&t->scope->cache, p);
827 if (r < 0)
828 return r;
829 }
830
831 t->sent = p;
832 p = NULL;
833
834 return 0;
835 }
836
837 static int dns_transaction_make_packet(DnsTransaction *t) {
838 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
839 int r;
840
841 assert(t);
842
843 if (t->scope->protocol == DNS_PROTOCOL_MDNS)
844 return dns_transaction_make_packet_mdns(t);
845
846 if (t->sent)
847 return 0;
848
849 r = dns_packet_new_query(&p, t->scope->protocol, 0, t->scope->dnssec_mode == DNSSEC_YES);
850 if (r < 0)
851 return r;
852
853 r = dns_scope_good_key(t->scope, t->key);
854 if (r < 0)
855 return r;
856 if (r == 0)
857 return -EDOM;
858
859 r = dns_packet_append_key(p, t->key, NULL);
860 if (r < 0)
861 return r;
862
863 DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
864 DNS_PACKET_HEADER(p)->id = t->id;
865
866 t->sent = p;
867 p = NULL;
868
869 return 0;
870 }
871
872 int dns_transaction_go(DnsTransaction *t) {
873 usec_t ts;
874 int r;
875
876 assert(t);
877
878 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
879 r = dns_transaction_prepare_next_attempt(t, ts);
880 if (r <= 0)
881 return r;
882
883 log_debug("Excercising transaction on scope %s on %s/%s",
884 dns_protocol_to_string(t->scope->protocol),
885 t->scope->link ? t->scope->link->name : "*",
886 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family));
887
888 if (!t->initial_jitter_scheduled &&
889 (t->scope->protocol == DNS_PROTOCOL_LLMNR ||
890 t->scope->protocol == DNS_PROTOCOL_MDNS)) {
891 usec_t jitter, accuracy;
892
893 /* RFC 4795 Section 2.7 suggests all queries should be
894 * delayed by a random time from 0 to JITTER_INTERVAL. */
895
896 t->initial_jitter_scheduled = true;
897
898 random_bytes(&jitter, sizeof(jitter));
899
900 switch (t->scope->protocol) {
901 case DNS_PROTOCOL_LLMNR:
902 jitter %= LLMNR_JITTER_INTERVAL_USEC;
903 accuracy = LLMNR_JITTER_INTERVAL_USEC;
904 break;
905 case DNS_PROTOCOL_MDNS:
906 jitter %= MDNS_JITTER_RANGE_USEC;
907 jitter += MDNS_JITTER_MIN_USEC;
908 accuracy = MDNS_JITTER_RANGE_USEC;
909 break;
910 default:
911 assert_not_reached("bad protocol");
912 }
913
914 r = sd_event_add_time(
915 t->scope->manager->event,
916 &t->timeout_event_source,
917 clock_boottime_or_monotonic(),
918 ts + jitter, accuracy,
919 on_transaction_timeout, t);
920 if (r < 0)
921 return r;
922
923 t->n_attempts = 0;
924 t->next_attempt_after = ts;
925 t->state = DNS_TRANSACTION_PENDING;
926
927 log_debug("Delaying %s transaction for " USEC_FMT "us.", dns_protocol_to_string(t->scope->protocol), jitter);
928 return 0;
929 }
930
931 /* Otherwise, we need to ask the network */
932 r = dns_transaction_make_packet(t);
933 if (r == -EDOM) {
934 /* Not the right request to make on this network?
935 * (i.e. an A request made on IPv6 or an AAAA request
936 * made on IPv4, on LLMNR or mDNS.) */
937 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
938 return 0;
939 }
940 if (r < 0)
941 return r;
942
943 if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
944 (dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), "in-addr.arpa") > 0 ||
945 dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), "ip6.arpa") > 0)) {
946
947 /* RFC 4795, Section 2.4. says reverse lookups shall
948 * always be made via TCP on LLMNR */
949 r = dns_transaction_open_tcp(t);
950 } else {
951 /* Try via UDP, and if that fails due to large size or lack of
952 * support try via TCP */
953 r = dns_transaction_emit(t);
954 if (r == -EMSGSIZE || r == -EAGAIN)
955 r = dns_transaction_open_tcp(t);
956 }
957
958 if (r == -ESRCH) {
959 /* No servers to send this to? */
960 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
961 return 0;
962 } else if (r < 0) {
963 if (t->scope->protocol != DNS_PROTOCOL_DNS) {
964 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
965 return 0;
966 }
967
968 /* Couldn't send? Try immediately again, with a new server */
969 dns_transaction_next_dns_server(t);
970
971 return dns_transaction_go(t);
972 }
973
974 ts += transaction_get_resend_timeout(t);
975
976 r = sd_event_add_time(
977 t->scope->manager->event,
978 &t->timeout_event_source,
979 clock_boottime_or_monotonic(),
980 ts, 0,
981 on_transaction_timeout, t);
982 if (r < 0)
983 return r;
984
985 t->state = DNS_TRANSACTION_PENDING;
986 t->next_attempt_after = ts;
987
988 return 1;
989 }
990
991 static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX] = {
992 [DNS_TRANSACTION_NULL] = "null",
993 [DNS_TRANSACTION_PENDING] = "pending",
994 [DNS_TRANSACTION_FAILURE] = "failure",
995 [DNS_TRANSACTION_SUCCESS] = "success",
996 [DNS_TRANSACTION_NO_SERVERS] = "no-servers",
997 [DNS_TRANSACTION_TIMEOUT] = "timeout",
998 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED] = "attempts-max-reached",
999 [DNS_TRANSACTION_INVALID_REPLY] = "invalid-reply",
1000 [DNS_TRANSACTION_RESOURCES] = "resources",
1001 [DNS_TRANSACTION_ABORTED] = "aborted",
1002 };
1003 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);
1004
1005 static const char* const dns_transaction_source_table[_DNS_TRANSACTION_SOURCE_MAX] = {
1006 [DNS_TRANSACTION_NETWORK] = "network",
1007 [DNS_TRANSACTION_CACHE] = "cache",
1008 [DNS_TRANSACTION_ZONE] = "zone",
1009 [DNS_TRANSACTION_TRUST_ANCHOR] = "trust-anchor",
1010 };
1011 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source, DnsTransactionSource);