chiark / gitweb /
22770023047fdd3cd18b84cd42c9bccb2b15459f
[elogind.git] / src / resolve / resolved-dns-query.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
24 #include "resolved-dns-query.h"
25 #include "resolved-dns-domain.h"
26
27 /* After how much time to repeat classic DNS requests */
28 #define DNS_TRANSACTION_TIMEOUT_USEC (5 * USEC_PER_SEC)
29
30 /* After how much time to repeat LLMNR requests, see RFC 4795 Section 7 */
31 #define LLMNR_TRANSACTION_TIMEOUT_USEC (1 * USEC_PER_SEC)
32
33 /* How long to wait for the query in total */
34 #define QUERY_TIMEOUT_USEC (30 * USEC_PER_SEC)
35
36 /* Maximum attempts to send DNS requests, across all DNS servers */
37 #define DNS_TRANSACTION_ATTEMPTS_MAX 8
38
39 /* Maximum attempts to send LLMNR requests, see RFC 4795 Section 2.7 */
40 #define LLMNR_TRANSACTION_ATTEMPTS_MAX 3
41
42 #define CNAME_MAX 8
43 #define QUERIES_MAX 2048
44
45 #define TRANSACTION_TIMEOUT_USEC(p) ((t)->scope->protocol == DNS_PROTOCOL_LLMNR ? LLMNR_TRANSACTION_TIMEOUT_USEC : DNS_TRANSACTION_TIMEOUT_USEC)
46 #define TRANSACTION_ATTEMPTS_MAX(p) ((t)->scope->protocol == DNS_PROTOCOL_LLMNR ? LLMNR_TRANSACTION_ATTEMPTS_MAX : DNS_TRANSACTION_ATTEMPTS_MAX)
47
48 static int dns_query_transaction_go(DnsQueryTransaction *t);
49
50 DnsQueryTransaction* dns_query_transaction_free(DnsQueryTransaction *t) {
51         DnsQuery *q;
52
53         if (!t)
54                 return NULL;
55
56         sd_event_source_unref(t->timeout_event_source);
57
58         dns_question_unref(t->question);
59         dns_packet_unref(t->sent);
60         dns_packet_unref(t->received);
61         dns_answer_unref(t->cached);
62
63         dns_stream_free(t->stream);
64
65         if (t->scope) {
66                 LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
67
68                 if (t->id != 0)
69                         hashmap_remove(t->scope->manager->dns_query_transactions, UINT_TO_PTR(t->id));
70         }
71
72         while ((q = set_steal_first(t->queries)))
73                 set_remove(q->transactions, t);
74
75         set_free(t->queries);
76
77         free(t);
78         return NULL;
79 }
80
81 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQueryTransaction*, dns_query_transaction_free);
82
83 static void dns_query_transaction_gc(DnsQueryTransaction *t) {
84         assert(t);
85
86         if (t->block_gc > 0)
87                 return;
88
89         if (set_isempty(t->queries))
90                 dns_query_transaction_free(t);
91 }
92
93 static int dns_query_transaction_new(DnsQueryTransaction **ret, DnsScope *s, DnsQuestion *q) {
94         _cleanup_(dns_query_transaction_freep) DnsQueryTransaction *t = NULL;
95         int r;
96
97         assert(ret);
98         assert(s);
99         assert(q);
100
101         r = hashmap_ensure_allocated(&s->manager->dns_query_transactions, NULL, NULL);
102         if (r < 0)
103                 return r;
104
105         t = new0(DnsQueryTransaction, 1);
106         if (!t)
107                 return -ENOMEM;
108
109         t->question = dns_question_ref(q);
110
111         do
112                 random_bytes(&t->id, sizeof(t->id));
113         while (t->id == 0 ||
114                hashmap_get(s->manager->dns_query_transactions, UINT_TO_PTR(t->id)));
115
116         r = hashmap_put(s->manager->dns_query_transactions, UINT_TO_PTR(t->id), t);
117         if (r < 0) {
118                 t->id = 0;
119                 return r;
120         }
121
122         LIST_PREPEND(transactions_by_scope, s->transactions, t);
123         t->scope = s;
124
125         if (ret)
126                 *ret = t;
127
128         t = NULL;
129
130         return 0;
131 }
132
133 static void dns_query_transaction_stop(DnsQueryTransaction *t) {
134         assert(t);
135
136         t->timeout_event_source = sd_event_source_unref(t->timeout_event_source);
137         t->stream = dns_stream_free(t->stream);
138 }
139
140 void dns_query_transaction_complete(DnsQueryTransaction *t, DnsQueryState state) {
141         DnsQuery *q;
142         Iterator i;
143
144         assert(t);
145         assert(!IN_SET(state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
146         assert(IN_SET(t->state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
147
148         /* Note that this call might invalidate the query. Callers
149          * should hence not attempt to access the query or transaction
150          * after calling this function. */
151
152         log_debug("Transaction on scope %s on %s/%s now complete with %s",
153                   dns_protocol_to_string(t->scope->protocol),
154                   t->scope->link ? t->scope->link->name : "*",
155                   t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
156                   dns_query_state_to_string(state));
157
158         t->state = state;
159
160         dns_query_transaction_stop(t);
161
162         /* Notify all queries that are interested, but make sure the
163          * transaction isn't freed while we are still looking at it */
164         t->block_gc++;
165         SET_FOREACH(q, t->queries, i)
166                 dns_query_ready(q);
167         t->block_gc--;
168
169         dns_query_transaction_gc(t);
170 }
171
172 static int on_stream_complete(DnsStream *s, int error) {
173         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
174         DnsQueryTransaction *t;
175
176         assert(s);
177         assert(s->transaction);
178
179         /* Copy the data we care about out of the stream before we
180          * destroy it. */
181         t = s->transaction;
182         p = dns_packet_ref(s->read_packet);
183
184         t->stream = dns_stream_free(t->stream);
185
186         if (error != 0) {
187                 dns_query_transaction_complete(t, DNS_QUERY_RESOURCES);
188                 return 0;
189         }
190
191         t->block_gc++;
192         dns_query_transaction_process_reply(t, p);
193         t->block_gc--;
194
195         /* If the response wasn't useful, then complete the transition now */
196         if (t->state == DNS_QUERY_PENDING)
197                 dns_query_transaction_complete(t, DNS_QUERY_INVALID_REPLY);
198
199         return 0;
200 }
201
202 static int dns_query_transaction_open_tcp(DnsQueryTransaction *t) {
203         _cleanup_close_ int fd = -1;
204         int r;
205
206         assert(t);
207
208         if (t->stream)
209                 return 0;
210
211         if (t->scope->protocol == DNS_PROTOCOL_DNS)
212                 fd = dns_scope_tcp_socket(t->scope, AF_UNSPEC, NULL, 53);
213         else if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
214
215                 /* When we already received a query to this (but it was truncated), send to its sender address */
216                 if (t->received)
217                         fd = dns_scope_tcp_socket(t->scope, t->received->family, &t->received->sender, t->received->sender_port);
218                 else {
219                         union in_addr_union address;
220                         int family;
221
222                         /* Otherwise, try to talk to the owner of a
223                          * the IP address, in case this is a reverse
224                          * PTR lookup */
225                         r = dns_question_extract_reverse_address(t->question, &family, &address);
226                         if (r < 0)
227                                 return r;
228                         if (r == 0)
229                                 return -EINVAL;
230
231                         fd = dns_scope_tcp_socket(t->scope, family, &address, 5355);
232                 }
233         } else
234                 return -EAFNOSUPPORT;
235
236         if (fd < 0)
237                 return fd;
238
239         r = dns_stream_new(t->scope->manager, &t->stream, t->scope->protocol, fd);
240         if (r < 0)
241                 return r;
242
243         fd = -1;
244
245         r = dns_stream_write_packet(t->stream, t->sent);
246         if (r < 0) {
247                 t->stream = dns_stream_free(t->stream);
248                 return r;
249         }
250
251         t->received = dns_packet_unref(t->received);
252         t->stream->complete = on_stream_complete;
253         t->stream->transaction = t;
254
255         /* The interface index is difficult to determine if we are
256          * connecting to the local host, hence fill this in right away
257          * instead of determining it from the socket */
258         if (t->scope->link)
259                 t->stream->ifindex = t->scope->link->ifindex;
260
261         return 0;
262 }
263
264 void dns_query_transaction_process_reply(DnsQueryTransaction *t, DnsPacket *p) {
265         int r;
266
267         assert(t);
268         assert(p);
269         assert(t->state == DNS_QUERY_PENDING);
270
271         /* Note that this call might invalidate the query. Callers
272          * should hence not attempt to access the query or transaction
273          * after calling this function. */
274
275         if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
276                 assert(t->scope->link);
277
278                 /* For LLMNR we will not accept any packets from other
279                  * interfaces */
280
281                 if (p->ifindex != t->scope->link->ifindex)
282                         return;
283
284                 if (p->family != t->scope->family)
285                         return;
286
287                 /* Tentative replies shall be discarded, see RFC 4795,
288                  * 2.1.1 */
289
290                 if (DNS_PACKET_T(p))
291                         return;
292         }
293
294         if (t->scope->protocol == DNS_PROTOCOL_DNS) {
295
296                 /* For DNS we are fine with accepting packets on any
297                  * interface, but the source IP address must be one of
298                  * a valid DNS server */
299
300                 if (!dns_scope_good_dns_server(t->scope, p->family, &p->sender))
301                         return;
302
303                 if (p->sender_port != 53)
304                         return;
305         }
306
307         if (t->received != p) {
308                 dns_packet_unref(t->received);
309                 t->received = dns_packet_ref(p);
310         }
311
312         if (p->ipproto == IPPROTO_TCP) {
313                 if (DNS_PACKET_TC(p)) {
314                         /* Truncated via TCP? Somebody must be fucking with us */
315                         dns_query_transaction_complete(t, DNS_QUERY_INVALID_REPLY);
316                         return;
317                 }
318
319                 if (DNS_PACKET_ID(p) != t->id) {
320                         /* Not the reply to our query? Somebody must be fucking with us */
321                         dns_query_transaction_complete(t, DNS_QUERY_INVALID_REPLY);
322                         return;
323                 }
324         }
325
326         if (DNS_PACKET_TC(p)) {
327                 /* Response was truncated, let's try again with good old TCP */
328                 r = dns_query_transaction_open_tcp(t);
329                 if (r == -ESRCH) {
330                         /* No servers found? Damn! */
331                         dns_query_transaction_complete(t, DNS_QUERY_NO_SERVERS);
332                         return;
333                 }
334                 if (r < 0) {
335                         /* On LLMNR, if we cannot connect to the host,
336                          * we immediately give up */
337                         if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
338                                 dns_query_transaction_complete(t, DNS_QUERY_RESOURCES);
339                                 return;
340                         }
341
342                         /* On DNS, couldn't send? Try immediately again, with a new server */
343                         dns_scope_next_dns_server(t->scope);
344
345                         r = dns_query_transaction_go(t);
346                         if (r < 0) {
347                                 dns_query_transaction_complete(t, DNS_QUERY_RESOURCES);
348                                 return;
349                         }
350
351                         return;
352                 }
353         }
354
355         /* Parse and update the cache */
356         r = dns_packet_extract(p);
357         if (r < 0) {
358                 dns_query_transaction_complete(t, DNS_QUERY_INVALID_REPLY);
359                 return;
360         }
361
362         /* According to RFC 4795, section 2.9. only the RRs from the answer section shall be cached */
363         dns_cache_put(&t->scope->cache, p->question, DNS_PACKET_RCODE(p), p->answer, DNS_PACKET_ANCOUNT(p), 0);
364
365         if (DNS_PACKET_RCODE(p) == DNS_RCODE_SUCCESS)
366                 dns_query_transaction_complete(t, DNS_QUERY_SUCCESS);
367         else
368                 dns_query_transaction_complete(t, DNS_QUERY_FAILURE);
369 }
370
371 static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
372         DnsQueryTransaction *t = userdata;
373         int r;
374
375         assert(s);
376         assert(t);
377
378         /* Timeout reached? Try again, with a new server */
379         dns_scope_next_dns_server(t->scope);
380
381         r = dns_query_transaction_go(t);
382         if (r < 0)
383                 dns_query_transaction_complete(t, DNS_QUERY_RESOURCES);
384
385         return 0;
386 }
387
388 static int dns_query_make_packet(DnsQueryTransaction *t) {
389         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
390         unsigned n, added = 0;
391         int r;
392
393         assert(t);
394
395         if (t->sent)
396                 return 0;
397
398         r = dns_packet_new_query(&p, t->scope->protocol, 0);
399         if (r < 0)
400                 return r;
401
402         for (n = 0; n < t->question->n_keys; n++) {
403                 r = dns_scope_good_key(t->scope, t->question->keys[n]);
404                 if (r < 0)
405                         return r;
406                 if (r == 0)
407                         continue;
408
409                 r = dns_packet_append_key(p, t->question->keys[n], NULL);
410                 if (r < 0)
411                         return r;
412
413                 added++;
414         }
415
416         if (added <= 0)
417                 return -EDOM;
418
419         DNS_PACKET_HEADER(p)->qdcount = htobe16(added);
420         DNS_PACKET_HEADER(p)->id = t->id;
421
422         t->sent = p;
423         p = NULL;
424
425         return 0;
426 }
427
428 static int dns_query_transaction_go(DnsQueryTransaction *t) {
429         bool had_stream;
430         int r;
431
432         assert(t);
433
434         had_stream = !!t->stream;
435
436         dns_query_transaction_stop(t);
437
438         log_debug("Beginning transaction on scope %s on %s/%s",
439                   dns_protocol_to_string(t->scope->protocol),
440                   t->scope->link ? t->scope->link->name : "*",
441                   t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family));
442
443         if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t)) {
444                 dns_query_transaction_complete(t, DNS_QUERY_ATTEMPTS_MAX);
445                 return 0;
446         }
447
448         if (t->scope->protocol == DNS_PROTOCOL_LLMNR && had_stream) {
449                 /* If we already tried via a stream, then we don't
450                  * retry on LLMNR. See RFC 4795, Section 2.7. */
451                 dns_query_transaction_complete(t, DNS_QUERY_ATTEMPTS_MAX);
452                 return 0;
453         }
454
455         t->n_attempts++;
456         t->received = dns_packet_unref(t->received);
457         t->cached = dns_answer_unref(t->cached);
458         t->cached_rcode = 0;
459
460         /* First, let's try the cache */
461         dns_cache_prune(&t->scope->cache);
462         r = dns_cache_lookup(&t->scope->cache, t->question, &t->cached_rcode, &t->cached);
463         if (r < 0)
464                 return r;
465         if (r > 0) {
466                 if (t->cached_rcode == DNS_RCODE_SUCCESS)
467                         dns_query_transaction_complete(t, DNS_QUERY_SUCCESS);
468                 else
469                         dns_query_transaction_complete(t, DNS_QUERY_FAILURE);
470                 return 0;
471         }
472
473         /* Otherwise, we need to ask the network */
474         r = dns_query_make_packet(t);
475         if (r == -EDOM) {
476                 /* Not the right request to make on this network?
477                  * (i.e. an A request made on IPv6 or an AAAA request
478                  * made on IPv4, on LLMNR or mDNS.) */
479                 dns_query_transaction_complete(t, DNS_QUERY_NO_SERVERS);
480                 return 0;
481         }
482         if (r < 0)
483                 return r;
484
485         if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
486             (dns_question_endswith(t->question, "in-addr.arpa") > 0 ||
487              dns_question_endswith(t->question, "ip6.arpa") > 0)) {
488
489                 /* RFC 4795, Section 2.4. says reverse lookups shall
490                  * always be made via TCP on LLMNR */
491                 r = dns_query_transaction_open_tcp(t);
492         } else {
493                 /* Try via UDP, and if that fails due to large size try via TCP */
494                 r = dns_scope_send(t->scope, t->sent);
495                 if (r == -EMSGSIZE)
496                         r = dns_query_transaction_open_tcp(t);
497         }
498         if (r == -ESRCH) {
499                 /* No servers to send this to? */
500                 dns_query_transaction_complete(t, DNS_QUERY_NO_SERVERS);
501                 return 0;
502         }
503         if (r < 0) {
504                 /* Couldn't send? Try immediately again, with a new server */
505                 dns_scope_next_dns_server(t->scope);
506
507                 return dns_query_transaction_go(t);
508         }
509
510         r = sd_event_add_time(t->scope->manager->event, &t->timeout_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + TRANSACTION_TIMEOUT_USEC(t), 0, on_transaction_timeout, t);
511         if (r < 0)
512                 return r;
513
514         t->state = DNS_QUERY_PENDING;
515         return 1;
516 }
517
518 DnsQuery *dns_query_free(DnsQuery *q) {
519         DnsQueryTransaction *t;
520
521         if (!q)
522                 return NULL;
523
524         sd_bus_message_unref(q->request);
525
526         dns_question_unref(q->question);
527         dns_answer_unref(q->answer);
528
529         sd_event_source_unref(q->timeout_event_source);
530
531         while ((t = set_steal_first(q->transactions))) {
532                 set_remove(t->queries, q);
533                 dns_query_transaction_gc(t);
534         }
535
536         set_free(q->transactions);
537
538         if (q->manager) {
539                 LIST_REMOVE(queries, q->manager->dns_queries, q);
540                 q->manager->n_dns_queries--;
541         }
542
543         free(q);
544
545         return NULL;
546 }
547
548 int dns_query_new(Manager *m, DnsQuery **ret, DnsQuestion *question) {
549         _cleanup_(dns_query_freep) DnsQuery *q = NULL;
550         unsigned i;
551         int r;
552
553         assert(m);
554         assert(question);
555
556         r = dns_question_is_valid(question);
557         if (r < 0)
558                 return r;
559
560         if (m->n_dns_queries >= QUERIES_MAX)
561                 return -EBUSY;
562
563         q = new0(DnsQuery, 1);
564         if (!q)
565                 return -ENOMEM;
566
567         q->question = dns_question_ref(question);
568
569         for (i = 0; i < question->n_keys; i++) {
570                 _cleanup_free_ char *p;
571
572                 r = dns_resource_key_to_string(question->keys[i], &p);
573                 if (r < 0)
574                         return r;
575
576                 log_debug("Looking up RR for %s", p);
577         }
578
579         LIST_PREPEND(queries, m->dns_queries, q);
580         m->n_dns_queries++;
581         q->manager = m;
582
583         if (ret)
584                 *ret = q;
585         q = NULL;
586
587         return 0;
588 }
589
590 static void dns_query_stop(DnsQuery *q) {
591         DnsQueryTransaction *t;
592
593         assert(q);
594
595         q->timeout_event_source = sd_event_source_unref(q->timeout_event_source);
596
597         while ((t = set_steal_first(q->transactions))) {
598                 set_remove(t->queries, q);
599                 dns_query_transaction_gc(t);
600         }
601 }
602
603 static void dns_query_complete(DnsQuery *q, DnsQueryState state) {
604         assert(q);
605         assert(!IN_SET(state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
606         assert(IN_SET(q->state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
607
608         /* Note that this call might invalidate the query. Callers
609          * should hence not attempt to access the query or transaction
610          * after calling this function. */
611
612         q->state = state;
613
614         dns_query_stop(q);
615         if (q->complete)
616                 q->complete(q);
617 }
618
619 static int on_query_timeout(sd_event_source *s, usec_t usec, void *userdata) {
620         DnsQuery *q = userdata;
621
622         assert(s);
623         assert(q);
624
625         dns_query_complete(q, DNS_QUERY_TIMEOUT);
626         return 0;
627 }
628
629 static int dns_query_add_transaction(DnsQuery *q, DnsScope *s, DnsResourceKey *key) {
630         _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
631         DnsQueryTransaction *t;
632         int r;
633
634         assert(q);
635
636         r = set_ensure_allocated(&q->transactions, NULL, NULL);
637         if (r < 0)
638                 return r;
639
640         if (key) {
641                 question = dns_question_new(1);
642                 if (!question)
643                         return -ENOMEM;
644
645                 r = dns_question_add(question, key);
646                 if (r < 0)
647                         return r;
648         } else
649                 question = dns_question_ref(q->question);
650
651         LIST_FOREACH(transactions_by_scope, t, s->transactions)
652                 if (dns_question_is_superset(t->question, question))
653                         break;
654
655         if (!t) {
656                 r = dns_query_transaction_new(&t, s, question);
657                 if (r < 0)
658                         return r;
659         }
660
661         r = set_ensure_allocated(&t->queries, NULL, NULL);
662         if (r < 0)
663                 goto fail;
664
665         r = set_put(t->queries, q);
666         if (r < 0)
667                 goto fail;
668
669         r = set_put(q->transactions, t);
670         if (r < 0) {
671                 set_remove(t->queries, q);
672                 goto fail;
673         }
674
675         return 0;
676
677 fail:
678         dns_query_transaction_gc(t);
679         return r;
680 }
681
682 static int dns_query_add_transaction_split(DnsQuery *q, DnsScope *s) {
683         int r;
684
685         assert(q);
686         assert(s);
687
688         if (s->protocol == DNS_PROTOCOL_MDNS) {
689                 r = dns_query_add_transaction(q, s, NULL);
690                 if (r < 0)
691                         return r;
692         } else {
693                 unsigned i;
694
695                 /* On DNS and LLMNR we can only send a single
696                  * question per datagram, hence issue multiple
697                  * transactions. */
698
699                 for (i = 0; i < q->question->n_keys; i++) {
700                         r = dns_query_add_transaction(q, s, q->question->keys[i]);
701                         if (r < 0)
702                                 return r;
703                 }
704         }
705
706         return 0;
707 }
708
709 int dns_query_go(DnsQuery *q) {
710         DnsScopeMatch found = DNS_SCOPE_NO;
711         DnsScope *s, *first = NULL;
712         DnsQueryTransaction *t;
713         const char *name;
714         Iterator i;
715         int r;
716
717         assert(q);
718
719         if (q->state != DNS_QUERY_NULL)
720                 return 0;
721
722         assert(q->question);
723         assert(q->question->n_keys > 0);
724
725         name = DNS_RESOURCE_KEY_NAME(q->question->keys[0]);
726
727         LIST_FOREACH(scopes, s, q->manager->dns_scopes) {
728                 DnsScopeMatch match;
729
730                 match = dns_scope_good_domain(s, name);
731                 if (match < 0)
732                         return match;
733
734                 if (match == DNS_SCOPE_NO)
735                         continue;
736
737                 found = match;
738
739                 if (match == DNS_SCOPE_YES) {
740                         first = s;
741                         break;
742                 } else {
743                         assert(match == DNS_SCOPE_MAYBE);
744
745                         if (!first)
746                                 first = s;
747                 }
748         }
749
750         if (found == DNS_SCOPE_NO)
751                 return -ESRCH;
752
753         r = dns_query_add_transaction_split(q, first);
754         if (r < 0)
755                 return r;
756
757         LIST_FOREACH(scopes, s, first->scopes_next) {
758                 DnsScopeMatch match;
759
760                 match = dns_scope_good_domain(s, name);
761                 if (match < 0)
762                         return match;
763
764                 if (match != found)
765                         continue;
766
767                 r = dns_query_add_transaction_split(q, s);
768                 if (r < 0)
769                         return r;
770         }
771
772         q->answer = dns_answer_unref(q->answer);
773         q->answer_ifindex = 0;
774         q->answer_rcode = 0;
775
776         r = sd_event_add_time(q->manager->event, &q->timeout_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + QUERY_TIMEOUT_USEC, 0, on_query_timeout, q);
777         if (r < 0)
778                 goto fail;
779
780         q->state = DNS_QUERY_PENDING;
781         q->block_ready++;
782
783         SET_FOREACH(t, q->transactions, i) {
784                 if (t->state == DNS_QUERY_NULL) {
785                         r = dns_query_transaction_go(t);
786                         if (r < 0)
787                                 goto fail;
788                 }
789         }
790
791         q->block_ready--;
792         dns_query_ready(q);
793
794         return 1;
795
796 fail:
797         dns_query_stop(q);
798         return r;
799 }
800
801 void dns_query_ready(DnsQuery *q) {
802         DnsQueryTransaction *t;
803         DnsQueryState state = DNS_QUERY_NO_SERVERS;
804         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
805         int rcode = 0;
806         DnsScope *scope = NULL;
807         bool pending = false;
808         Iterator i;
809
810         assert(q);
811         assert(IN_SET(q->state, DNS_QUERY_NULL, DNS_QUERY_PENDING));
812
813         /* Note that this call might invalidate the query. Callers
814          * should hence not attempt to access the query or transaction
815          * after calling this function, unless the block_ready
816          * counter was explicitly bumped before doing so. */
817
818         if (q->block_ready > 0)
819                 return;
820
821         SET_FOREACH(t, q->transactions, i) {
822
823                 /* If we found a successful answer, ignore all answers from other scopes */
824                 if (state == DNS_QUERY_SUCCESS && t->scope != scope)
825                         continue;
826
827                 /* One of the transactions is still going on, let's maybe wait for it */
828                 if (IN_SET(t->state, DNS_QUERY_PENDING, DNS_QUERY_NULL)) {
829                         pending = true;
830                         continue;
831                 }
832
833                 /* One of the transactions is successful, let's use
834                  * it, and copy its data out */
835                 if (t->state == DNS_QUERY_SUCCESS) {
836                         DnsAnswer *a;
837
838                         if (t->received) {
839                                 rcode = DNS_PACKET_RCODE(t->received);
840                                 a = t->received->answer;
841                         } else {
842                                 rcode = t->cached_rcode;
843                                 a = t->cached;
844                         }
845
846                         if (state == DNS_QUERY_SUCCESS) {
847                                 DnsAnswer *merged;
848
849                                 merged = dns_answer_merge(answer, a);
850                                 if (!merged) {
851                                         dns_query_complete(q, DNS_QUERY_RESOURCES);
852                                         return;
853                                 }
854
855                                 dns_answer_unref(answer);
856                                 answer = merged;
857                         } else {
858                                 dns_answer_unref(answer);
859                                 answer = dns_answer_ref(a);
860                         }
861
862                         scope = t->scope;
863                         state = DNS_QUERY_SUCCESS;
864                         continue;
865                 }
866
867                 /* One of the transactions has failed, let's see
868                  * whether we find anything better, but if not, return
869                  * its response data */
870                 if (state != DNS_QUERY_SUCCESS && t->state == DNS_QUERY_FAILURE) {
871                         DnsAnswer *a;
872
873                         if (t->received) {
874                                 rcode = DNS_PACKET_RCODE(t->received);
875                                 a = t->received->answer;
876                         } else {
877                                 rcode = t->cached_rcode;
878                                 a = t->cached;
879                         }
880
881                         dns_answer_unref(answer);
882                         answer = dns_answer_ref(a);
883
884                         scope = t->scope;
885                         state = DNS_QUERY_FAILURE;
886                         continue;
887                 }
888
889                 if (state == DNS_QUERY_NO_SERVERS && t->state != DNS_QUERY_NO_SERVERS)
890                         state = t->state;
891         }
892
893         if (pending) {
894
895                 /* If so far we weren't successful, and there's
896                  * something still pending, then wait for it */
897                 if (state != DNS_QUERY_SUCCESS)
898                         return;
899
900                 /* If we already were successful, then only wait for
901                  * other transactions on the same scope to finish. */
902                 SET_FOREACH(t, q->transactions, i) {
903                         if (t->scope == scope && IN_SET(t->state, DNS_QUERY_PENDING, DNS_QUERY_NULL))
904                                 return;
905                 }
906         }
907
908         if (IN_SET(state, DNS_QUERY_SUCCESS, DNS_QUERY_FAILURE)) {
909                 q->answer = dns_answer_ref(answer);
910                 q->answer_rcode = rcode;
911                 q->answer_ifindex = (scope && scope->link) ? scope->link->ifindex : 0;
912         }
913
914         dns_query_complete(q, state);
915 }
916
917 int dns_query_cname_redirect(DnsQuery *q, const char *name) {
918         _cleanup_(dns_question_unrefp) DnsQuestion *nq = NULL;
919         int r;
920
921         assert(q);
922
923         if (q->n_cname_redirects > CNAME_MAX)
924                 return -ELOOP;
925
926         r = dns_question_cname_redirect(q->question, name, &nq);
927         if (r < 0)
928                 return r;
929
930         dns_question_unref(q->question);
931         q->question = nq;
932         nq = NULL;
933
934         q->n_cname_redirects++;
935
936         dns_query_stop(q);
937         q->state = DNS_QUERY_NULL;
938
939         return 0;
940 }
941
942 static const char* const dns_query_state_table[_DNS_QUERY_STATE_MAX] = {
943         [DNS_QUERY_NULL] = "null",
944         [DNS_QUERY_PENDING] = "pending",
945         [DNS_QUERY_FAILURE] = "failure",
946         [DNS_QUERY_SUCCESS] = "success",
947         [DNS_QUERY_NO_SERVERS] = "no-servers",
948         [DNS_QUERY_TIMEOUT] = "timeout",
949         [DNS_QUERY_ATTEMPTS_MAX] = "attempts-max",
950         [DNS_QUERY_INVALID_REPLY] = "invalid-reply",
951         [DNS_QUERY_RESOURCES] = "resources",
952         [DNS_QUERY_ABORTED] = "aborted",
953 };
954 DEFINE_STRING_TABLE_LOOKUP(dns_query_state, DnsQueryState);