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