]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-transaction.c
Merge pull request #2095 from evverx/fix-distcheck-for-disable-timesync
[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-transaction.h"
28 #include "resolved-llmnr.h"
29 #include "string-table.h"
30
31 DnsTransaction* dns_transaction_free(DnsTransaction *t) {
32 DnsQueryCandidate *c;
33 DnsZoneItem *i;
34
35 if (!t)
36 return NULL;
37
38 sd_event_source_unref(t->timeout_event_source);
39
40 dns_packet_unref(t->sent);
41 dns_packet_unref(t->received);
42
43 dns_answer_unref(t->answer);
44
45 sd_event_source_unref(t->dns_udp_event_source);
46 safe_close(t->dns_udp_fd);
47
48 dns_server_unref(t->server);
49 dns_stream_free(t->stream);
50
51 if (t->scope) {
52 hashmap_remove_value(t->scope->transactions_by_key, t->key, t);
53 LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
54
55 if (t->id != 0)
56 hashmap_remove(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id));
57 }
58
59 dns_resource_key_unref(t->key);
60
61 while ((c = set_steal_first(t->query_candidates)))
62 set_remove(c->transactions, t);
63
64 set_free(t->query_candidates);
65
66 while ((i = set_steal_first(t->zone_items)))
67 i->probe_transaction = NULL;
68 set_free(t->zone_items);
69
70 free(t);
71 return NULL;
72 }
73
74 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_free);
75
76 void dns_transaction_gc(DnsTransaction *t) {
77 assert(t);
78
79 if (t->block_gc > 0)
80 return;
81
82 if (set_isempty(t->query_candidates) && set_isempty(t->zone_items))
83 dns_transaction_free(t);
84 }
85
86 int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key) {
87 _cleanup_(dns_transaction_freep) DnsTransaction *t = NULL;
88 int r;
89
90 assert(ret);
91 assert(s);
92 assert(key);
93
94 r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL);
95 if (r < 0)
96 return r;
97
98 r = hashmap_ensure_allocated(&s->transactions_by_key, &dns_resource_key_hash_ops);
99 if (r < 0)
100 return r;
101
102 t = new0(DnsTransaction, 1);
103 if (!t)
104 return -ENOMEM;
105
106 t->dns_udp_fd = -1;
107 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
108 t->key = dns_resource_key_ref(key);
109
110 /* Find a fresh, unused transaction id */
111 do
112 random_bytes(&t->id, sizeof(t->id));
113 while (t->id == 0 ||
114 hashmap_get(s->manager->dns_transactions, UINT_TO_PTR(t->id)));
115
116 r = hashmap_put(s->manager->dns_transactions, UINT_TO_PTR(t->id), t);
117 if (r < 0) {
118 t->id = 0;
119 return r;
120 }
121
122 r = hashmap_replace(s->transactions_by_key, t->key, t);
123 if (r < 0) {
124 hashmap_remove(s->manager->dns_transactions, UINT_TO_PTR(t->id));
125 return r;
126 }
127
128 LIST_PREPEND(transactions_by_scope, s->transactions, t);
129 t->scope = s;
130
131 if (ret)
132 *ret = t;
133
134 t = NULL;
135
136 return 0;
137 }
138
139 static void dns_transaction_stop(DnsTransaction *t) {
140 assert(t);
141
142 t->timeout_event_source = sd_event_source_unref(t->timeout_event_source);
143 t->stream = dns_stream_free(t->stream);
144
145 /* Note that we do not drop the UDP socket here, as we want to
146 * reuse it to repeat the interaction. */
147 }
148
149 static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
150 _cleanup_free_ char *pretty = NULL;
151 DnsZoneItem *z;
152
153 assert(t);
154 assert(p);
155
156 if (manager_our_packet(t->scope->manager, p) != 0)
157 return;
158
159 in_addr_to_string(p->family, &p->sender, &pretty);
160
161 log_debug("Transaction on scope %s on %s/%s got tentative packet from %s",
162 dns_protocol_to_string(t->scope->protocol),
163 t->scope->link ? t->scope->link->name : "*",
164 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
165 pretty);
166
167 /* RFC 4795, Section 4.1 says that the peer with the
168 * lexicographically smaller IP address loses */
169 if (memcmp(&p->sender, &p->destination, FAMILY_ADDRESS_SIZE(p->family)) >= 0) {
170 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
171 return;
172 }
173
174 log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
175
176 t->block_gc++;
177 while ((z = set_first(t->zone_items))) {
178 /* First, make sure the zone item drops the reference
179 * to us */
180 dns_zone_item_probe_stop(z);
181
182 /* Secondly, report this as conflict, so that we might
183 * look for a different hostname */
184 dns_zone_item_conflict(z);
185 }
186 t->block_gc--;
187
188 dns_transaction_gc(t);
189 }
190
191 void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
192 DnsQueryCandidate *c;
193 DnsZoneItem *z;
194 Iterator i;
195
196 assert(t);
197 assert(!IN_SET(state, DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING));
198
199 /* Note that this call might invalidate the query. Callers
200 * should hence not attempt to access the query or transaction
201 * after calling this function. */
202
203 log_debug("Transaction on scope %s on %s/%s now complete with <%s> from %s",
204 dns_protocol_to_string(t->scope->protocol),
205 t->scope->link ? t->scope->link->name : "*",
206 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
207 dns_transaction_state_to_string(state),
208 t->answer_source < 0 ? "none" : dns_transaction_source_to_string(t->answer_source));
209
210 t->state = state;
211
212 dns_transaction_stop(t);
213
214 /* Notify all queries that are interested, but make sure the
215 * transaction isn't freed while we are still looking at it */
216 t->block_gc++;
217 SET_FOREACH(c, t->query_candidates, i)
218 dns_query_candidate_ready(c);
219 SET_FOREACH(z, t->zone_items, i)
220 dns_zone_item_ready(z);
221 t->block_gc--;
222
223 dns_transaction_gc(t);
224 }
225
226 static int on_stream_complete(DnsStream *s, int error) {
227 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
228 DnsTransaction *t;
229
230 assert(s);
231 assert(s->transaction);
232
233 /* Copy the data we care about out of the stream before we
234 * destroy it. */
235 t = s->transaction;
236 p = dns_packet_ref(s->read_packet);
237
238 t->stream = dns_stream_free(t->stream);
239
240 if (error != 0) {
241 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
242 return 0;
243 }
244
245 if (dns_packet_validate_reply(p) <= 0) {
246 log_debug("Invalid LLMNR TCP packet.");
247 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
248 return 0;
249 }
250
251 dns_scope_check_conflicts(t->scope, p);
252
253 t->block_gc++;
254 dns_transaction_process_reply(t, p);
255 t->block_gc--;
256
257 /* If the response wasn't useful, then complete the transition now */
258 if (t->state == DNS_TRANSACTION_PENDING)
259 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
260
261 return 0;
262 }
263
264 static int dns_transaction_open_tcp(DnsTransaction *t) {
265 DnsServer *server = NULL;
266 _cleanup_close_ int fd = -1;
267 int r;
268
269 assert(t);
270
271 if (t->stream)
272 return 0;
273
274 switch (t->scope->protocol) {
275 case DNS_PROTOCOL_DNS:
276 fd = dns_scope_tcp_socket(t->scope, AF_UNSPEC, NULL, 53, &server);
277 break;
278
279 case DNS_PROTOCOL_LLMNR:
280 /* When we already received a reply to this (but it was truncated), send to its sender address */
281 if (t->received)
282 fd = dns_scope_tcp_socket(t->scope, t->received->family, &t->received->sender, t->received->sender_port, NULL);
283 else {
284 union in_addr_union address;
285 int family = AF_UNSPEC;
286
287 /* Otherwise, try to talk to the owner of a
288 * the IP address, in case this is a reverse
289 * PTR lookup */
290
291 r = dns_name_address(DNS_RESOURCE_KEY_NAME(t->key), &family, &address);
292 if (r < 0)
293 return r;
294 if (r == 0)
295 return -EINVAL;
296 if (family != t->scope->family)
297 return -ESRCH;
298
299 fd = dns_scope_tcp_socket(t->scope, family, &address, LLMNR_PORT, NULL);
300 }
301
302 break;
303
304 default:
305 return -EAFNOSUPPORT;
306 }
307
308 if (fd < 0)
309 return fd;
310
311 r = dns_stream_new(t->scope->manager, &t->stream, t->scope->protocol, fd);
312 if (r < 0)
313 return r;
314
315 fd = -1;
316
317 r = dns_stream_write_packet(t->stream, t->sent);
318 if (r < 0) {
319 t->stream = dns_stream_free(t->stream);
320 return r;
321 }
322
323 dns_server_unref(t->server);
324 t->server = dns_server_ref(server);
325 t->received = dns_packet_unref(t->received);
326 t->answer = dns_answer_unref(t->answer);
327 t->answer_rcode = 0;
328 t->stream->complete = on_stream_complete;
329 t->stream->transaction = t;
330
331 /* The interface index is difficult to determine if we are
332 * connecting to the local host, hence fill this in right away
333 * instead of determining it from the socket */
334 if (t->scope->link)
335 t->stream->ifindex = t->scope->link->ifindex;
336
337 return 0;
338 }
339
340 static void dns_transaction_next_dns_server(DnsTransaction *t) {
341 assert(t);
342
343 t->server = dns_server_unref(t->server);
344 t->dns_udp_event_source = sd_event_source_unref(t->dns_udp_event_source);
345 t->dns_udp_fd = safe_close(t->dns_udp_fd);
346
347 dns_scope_next_dns_server(t->scope);
348 }
349
350 void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
351 usec_t ts;
352 int r;
353
354 assert(t);
355 assert(p);
356 assert(t->state == DNS_TRANSACTION_PENDING);
357 assert(t->scope);
358 assert(t->scope->manager);
359
360 /* Note that this call might invalidate the query. Callers
361 * should hence not attempt to access the query or transaction
362 * after calling this function. */
363
364 switch (t->scope->protocol) {
365 case DNS_PROTOCOL_LLMNR:
366 assert(t->scope->link);
367
368 /* For LLMNR we will not accept any packets from other
369 * interfaces */
370
371 if (p->ifindex != t->scope->link->ifindex)
372 return;
373
374 if (p->family != t->scope->family)
375 return;
376
377 /* Tentative packets are not full responses but still
378 * useful for identifying uniqueness conflicts during
379 * probing. */
380 if (DNS_PACKET_LLMNR_T(p)) {
381 dns_transaction_tentative(t, p);
382 return;
383 }
384
385 break;
386
387 case DNS_PROTOCOL_DNS:
388 break;
389
390 default:
391 assert_not_reached("Invalid DNS protocol.");
392 }
393
394 if (t->received != p) {
395 dns_packet_unref(t->received);
396 t->received = dns_packet_ref(p);
397 }
398
399 t->answer_source = DNS_TRANSACTION_NETWORK;
400
401 if (p->ipproto == IPPROTO_TCP) {
402 if (DNS_PACKET_TC(p)) {
403 /* Truncated via TCP? Somebody must be fucking with us */
404 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
405 return;
406 }
407
408 if (DNS_PACKET_ID(p) != t->id) {
409 /* Not the reply to our query? Somebody must be fucking with us */
410 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
411 return;
412 }
413 }
414
415 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
416
417 switch (t->scope->protocol) {
418 case DNS_PROTOCOL_DNS:
419 assert(t->server);
420
421 if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_FORMERR, DNS_RCODE_SERVFAIL, DNS_RCODE_NOTIMP)) {
422
423 /* request failed, immediately try again with reduced features */
424 log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p)));
425
426 dns_server_packet_failed(t->server, t->current_features);
427
428 r = dns_transaction_go(t);
429 if (r < 0) {
430 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
431 return;
432 }
433
434 return;
435 } else
436 dns_server_packet_received(t->server, t->current_features, ts - t->start_usec, p->size);
437
438 break;
439 case DNS_PROTOCOL_LLMNR:
440 case DNS_PROTOCOL_MDNS:
441 dns_scope_packet_received(t->scope, ts - t->start_usec);
442
443 break;
444 default:
445 break;
446 }
447
448 if (DNS_PACKET_TC(p)) {
449 /* Response was truncated, let's try again with good old TCP */
450 r = dns_transaction_open_tcp(t);
451 if (r == -ESRCH) {
452 /* No servers found? Damn! */
453 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
454 return;
455 }
456 if (r < 0) {
457 /* On LLMNR, if we cannot connect to the host,
458 * we immediately give up */
459 if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
460 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
461 return;
462 }
463
464 /* On DNS, couldn't send? Try immediately again, with a new server */
465 dns_transaction_next_dns_server(t);
466
467 r = dns_transaction_go(t);
468 if (r < 0) {
469 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
470 return;
471 }
472
473 return;
474 }
475 }
476
477 /* Parse and update the cache */
478 r = dns_packet_extract(p);
479 if (r < 0) {
480 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
481 return;
482 }
483
484 /* Only consider responses with equivalent query section to the request */
485 if (p->question->n_keys != 1 || dns_resource_key_equal(p->question->keys[0], t->key) <= 0) {
486 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
487 return;
488 }
489
490 /* Install the answer as answer to the transaction */
491 dns_answer_unref(t->answer);
492 t->answer = dns_answer_ref(p->answer);
493 t->answer_rcode = DNS_PACKET_RCODE(p);
494 t->answer_authenticated = t->scope->dnssec_mode == DNSSEC_TRUST && DNS_PACKET_AD(p);
495
496 /* According to RFC 4795, section 2.9. only the RRs from the answer section shall be cached */
497 if (DNS_PACKET_SHALL_CACHE(p))
498 dns_cache_put(&t->scope->cache,
499 t->key,
500 DNS_PACKET_RCODE(p),
501 p->answer,
502 DNS_PACKET_ANCOUNT(p),
503 t->answer_authenticated,
504 0,
505 p->family,
506 &p->sender);
507
508 if (DNS_PACKET_RCODE(p) == DNS_RCODE_SUCCESS)
509 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
510 else
511 dns_transaction_complete(t, DNS_TRANSACTION_FAILURE);
512 }
513
514 static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
515 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
516 DnsTransaction *t = userdata;
517 int r;
518
519 assert(t);
520 assert(t->scope);
521
522 r = manager_recv(t->scope->manager, fd, DNS_PROTOCOL_DNS, &p);
523 if (r <= 0)
524 return r;
525
526 if (dns_packet_validate_reply(p) > 0 &&
527 DNS_PACKET_ID(p) == t->id)
528 dns_transaction_process_reply(t, p);
529 else
530 log_debug("Invalid DNS packet.");
531
532 return 0;
533 }
534
535 static int dns_transaction_emit(DnsTransaction *t) {
536 int r;
537
538 assert(t);
539
540 if (t->scope->protocol == DNS_PROTOCOL_DNS && !t->server) {
541 DnsServer *server = NULL;
542 _cleanup_close_ int fd = -1;
543
544 fd = dns_scope_udp_dns_socket(t->scope, &server);
545 if (fd < 0)
546 return fd;
547
548 r = sd_event_add_io(t->scope->manager->event, &t->dns_udp_event_source, fd, EPOLLIN, on_dns_packet, t);
549 if (r < 0)
550 return r;
551
552 t->dns_udp_fd = fd;
553 fd = -1;
554 t->server = dns_server_ref(server);
555 }
556
557 r = dns_scope_emit(t->scope, t->dns_udp_fd, t->server, t->sent);
558 if (r < 0)
559 return r;
560
561 if (t->server)
562 t->current_features = t->server->possible_features;
563
564 return 0;
565 }
566
567 static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
568 DnsTransaction *t = userdata;
569 int r;
570
571 assert(s);
572 assert(t);
573
574 /* Timeout reached? Increase the timeout for the server used */
575 switch (t->scope->protocol) {
576 case DNS_PROTOCOL_DNS:
577 assert(t->server);
578
579 dns_server_packet_lost(t->server, t->current_features, usec - t->start_usec);
580
581 break;
582 case DNS_PROTOCOL_LLMNR:
583 case DNS_PROTOCOL_MDNS:
584 dns_scope_packet_lost(t->scope, usec - t->start_usec);
585
586 break;
587 default:
588 assert_not_reached("Invalid DNS protocol.");
589 }
590
591 /* ...and try again with a new server */
592 dns_transaction_next_dns_server(t);
593
594 r = dns_transaction_go(t);
595 if (r < 0)
596 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
597
598 return 0;
599 }
600
601 static int dns_transaction_make_packet(DnsTransaction *t) {
602 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
603 int r;
604
605 assert(t);
606
607 if (t->sent)
608 return 0;
609
610 r = dns_packet_new_query(&p, t->scope->protocol, 0, t->scope->dnssec_mode == DNSSEC_YES);
611 if (r < 0)
612 return r;
613
614 r = dns_scope_good_key(t->scope, t->key);
615 if (r < 0)
616 return r;
617 if (r == 0)
618 return -EDOM;
619
620 r = dns_packet_append_key(p, t->key, NULL);
621 if (r < 0)
622 return r;
623
624 DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
625 DNS_PACKET_HEADER(p)->id = t->id;
626
627 t->sent = p;
628 p = NULL;
629
630 return 0;
631 }
632
633 static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
634 assert(t);
635 assert(t->scope);
636
637 switch (t->scope->protocol) {
638 case DNS_PROTOCOL_DNS:
639 assert(t->server);
640
641 return t->server->resend_timeout;
642 case DNS_PROTOCOL_LLMNR:
643 case DNS_PROTOCOL_MDNS:
644 return t->scope->resend_timeout;
645 default:
646 assert_not_reached("Invalid DNS protocol.");
647 }
648 }
649
650 int dns_transaction_go(DnsTransaction *t) {
651 bool had_stream;
652 usec_t ts;
653 int r;
654
655 assert(t);
656
657 had_stream = !!t->stream;
658
659 dns_transaction_stop(t);
660
661 log_debug("Excercising transaction on scope %s on %s/%s",
662 dns_protocol_to_string(t->scope->protocol),
663 t->scope->link ? t->scope->link->name : "*",
664 t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family));
665
666 if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t->scope->protocol)) {
667 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
668 return 0;
669 }
670
671 if (t->scope->protocol == DNS_PROTOCOL_LLMNR && had_stream) {
672 /* If we already tried via a stream, then we don't
673 * retry on LLMNR. See RFC 4795, Section 2.7. */
674 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
675 return 0;
676 }
677
678 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
679
680 t->n_attempts++;
681 t->start_usec = ts;
682 t->received = dns_packet_unref(t->received);
683 t->answer = dns_answer_unref(t->answer);
684 t->answer_rcode = 0;
685 t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
686
687 /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
688 if (t->scope->protocol == DNS_PROTOCOL_DNS) {
689 r = dns_trust_anchor_lookup(&t->scope->manager->trust_anchor, t->key, &t->answer);
690 if (r < 0)
691 return r;
692 if (r > 0) {
693 t->answer_rcode = DNS_RCODE_SUCCESS;
694 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
695 t->answer_authenticated = true;
696 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
697 return 0;
698 }
699 }
700
701 /* Check the zone, but only if this transaction is not used
702 * for probing or verifying a zone item. */
703 if (set_isempty(t->zone_items)) {
704
705 r = dns_zone_lookup(&t->scope->zone, t->key, &t->answer, NULL, NULL);
706 if (r < 0)
707 return r;
708 if (r > 0) {
709 t->answer_rcode = DNS_RCODE_SUCCESS;
710 t->answer_source = DNS_TRANSACTION_ZONE;
711 t->answer_authenticated = true;
712 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
713 return 0;
714 }
715 }
716
717 /* Check the cache, but only if this transaction is not used
718 * for probing or verifying a zone item. */
719 if (set_isempty(t->zone_items)) {
720
721 /* Before trying the cache, let's make sure we figured out a
722 * server to use. Should this cause a change of server this
723 * might flush the cache. */
724 dns_scope_get_dns_server(t->scope);
725
726 /* Let's then prune all outdated entries */
727 dns_cache_prune(&t->scope->cache);
728
729 r = dns_cache_lookup(&t->scope->cache, t->key, &t->answer_rcode, &t->answer, &t->answer_authenticated);
730 if (r < 0)
731 return r;
732 if (r > 0) {
733 t->answer_source = DNS_TRANSACTION_CACHE;
734 if (t->answer_rcode == DNS_RCODE_SUCCESS)
735 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
736 else
737 dns_transaction_complete(t, DNS_TRANSACTION_FAILURE);
738 return 0;
739 }
740 }
741
742 if (t->scope->protocol == DNS_PROTOCOL_LLMNR && !t->initial_jitter) {
743 usec_t jitter;
744
745 /* RFC 4795 Section 2.7 suggests all queries should be
746 * delayed by a random time from 0 to JITTER_INTERVAL. */
747
748 t->initial_jitter = true;
749
750 random_bytes(&jitter, sizeof(jitter));
751 jitter %= LLMNR_JITTER_INTERVAL_USEC;
752
753 r = sd_event_add_time(
754 t->scope->manager->event,
755 &t->timeout_event_source,
756 clock_boottime_or_monotonic(),
757 ts + jitter,
758 LLMNR_JITTER_INTERVAL_USEC,
759 on_transaction_timeout, t);
760 if (r < 0)
761 return r;
762
763 t->n_attempts = 0;
764 t->state = DNS_TRANSACTION_PENDING;
765
766 log_debug("Delaying LLMNR transaction for " USEC_FMT "us.", jitter);
767 return 0;
768 }
769
770 /* Otherwise, we need to ask the network */
771 r = dns_transaction_make_packet(t);
772 if (r == -EDOM) {
773 /* Not the right request to make on this network?
774 * (i.e. an A request made on IPv6 or an AAAA request
775 * made on IPv4, on LLMNR or mDNS.) */
776 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
777 return 0;
778 }
779 if (r < 0)
780 return r;
781
782 if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
783 (dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), "in-addr.arpa") > 0 ||
784 dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), "ip6.arpa") > 0)) {
785
786 /* RFC 4795, Section 2.4. says reverse lookups shall
787 * always be made via TCP on LLMNR */
788 r = dns_transaction_open_tcp(t);
789 } else {
790 /* Try via UDP, and if that fails due to large size or lack of
791 * support try via TCP */
792 r = dns_transaction_emit(t);
793 if (r == -EMSGSIZE || r == -EAGAIN)
794 r = dns_transaction_open_tcp(t);
795 }
796
797 if (r == -ESRCH) {
798 /* No servers to send this to? */
799 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
800 return 0;
801 } else if (r < 0) {
802 if (t->scope->protocol != DNS_PROTOCOL_DNS) {
803 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
804 return 0;
805 }
806
807 /* Couldn't send? Try immediately again, with a new server */
808 dns_transaction_next_dns_server(t);
809
810 return dns_transaction_go(t);
811 }
812
813 r = sd_event_add_time(
814 t->scope->manager->event,
815 &t->timeout_event_source,
816 clock_boottime_or_monotonic(),
817 ts + transaction_get_resend_timeout(t), 0,
818 on_transaction_timeout, t);
819 if (r < 0)
820 return r;
821
822 t->state = DNS_TRANSACTION_PENDING;
823 return 1;
824 }
825
826 static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX] = {
827 [DNS_TRANSACTION_NULL] = "null",
828 [DNS_TRANSACTION_PENDING] = "pending",
829 [DNS_TRANSACTION_FAILURE] = "failure",
830 [DNS_TRANSACTION_SUCCESS] = "success",
831 [DNS_TRANSACTION_NO_SERVERS] = "no-servers",
832 [DNS_TRANSACTION_TIMEOUT] = "timeout",
833 [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED] = "attempts-max-reached",
834 [DNS_TRANSACTION_INVALID_REPLY] = "invalid-reply",
835 [DNS_TRANSACTION_RESOURCES] = "resources",
836 [DNS_TRANSACTION_ABORTED] = "aborted",
837 };
838 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);
839
840 static const char* const dns_transaction_source_table[_DNS_TRANSACTION_SOURCE_MAX] = {
841 [DNS_TRANSACTION_NETWORK] = "network",
842 [DNS_TRANSACTION_CACHE] = "cache",
843 [DNS_TRANSACTION_ZONE] = "zone",
844 [DNS_TRANSACTION_TRUST_ANCHOR] = "trust-anchor",
845 };
846 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source, DnsTransactionSource);