chiark / gitweb /
resolve: reject empty TXT records
[elogind.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
24 #include "resolved-dns-transaction.h"
25
26 DnsTransaction* dns_transaction_free(DnsTransaction *t) {
27         DnsQuery *q;
28         DnsZoneItem *i;
29
30         if (!t)
31                 return NULL;
32
33         sd_event_source_unref(t->timeout_event_source);
34
35         dns_question_unref(t->question);
36         dns_packet_unref(t->sent);
37         dns_packet_unref(t->received);
38         dns_answer_unref(t->cached);
39
40         dns_stream_free(t->stream);
41
42         if (t->scope) {
43                 LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
44
45                 if (t->id != 0)
46                         hashmap_remove(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id));
47         }
48
49         while ((q = set_steal_first(t->queries)))
50                 set_remove(q->transactions, t);
51         set_free(t->queries);
52
53         while ((i = set_steal_first(t->zone_items)))
54                 i->probe_transaction = NULL;
55         set_free(t->zone_items);
56
57         free(t);
58         return NULL;
59 }
60
61 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_free);
62
63 void dns_transaction_gc(DnsTransaction *t) {
64         assert(t);
65
66         if (t->block_gc > 0)
67                 return;
68
69         if (set_isempty(t->queries) && set_isempty(t->zone_items))
70                 dns_transaction_free(t);
71 }
72
73 int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsQuestion *q) {
74         _cleanup_(dns_transaction_freep) DnsTransaction *t = NULL;
75         int r;
76
77         assert(ret);
78         assert(s);
79         assert(q);
80
81         r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL);
82         if (r < 0)
83                 return r;
84
85         t = new0(DnsTransaction, 1);
86         if (!t)
87                 return -ENOMEM;
88
89         t->question = dns_question_ref(q);
90
91         do
92                 random_bytes(&t->id, sizeof(t->id));
93         while (t->id == 0 ||
94                hashmap_get(s->manager->dns_transactions, UINT_TO_PTR(t->id)));
95
96         r = hashmap_put(s->manager->dns_transactions, UINT_TO_PTR(t->id), t);
97         if (r < 0) {
98                 t->id = 0;
99                 return r;
100         }
101
102         LIST_PREPEND(transactions_by_scope, s->transactions, t);
103         t->scope = s;
104
105         if (ret)
106                 *ret = t;
107
108         t = NULL;
109
110         return 0;
111 }
112
113 static void dns_transaction_stop(DnsTransaction *t) {
114         assert(t);
115
116         t->timeout_event_source = sd_event_source_unref(t->timeout_event_source);
117         t->stream = dns_stream_free(t->stream);
118 }
119
120 static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
121         _cleanup_free_ char *pretty = NULL;
122         DnsZoneItem *z;
123
124         assert(t);
125         assert(p);
126
127         if (manager_our_packet(t->scope->manager, p) != 0)
128                 return;
129
130         in_addr_to_string(p->family, &p->sender, &pretty);
131
132         log_debug("Transaction on scope %s on %s/%s got tentative packet from %s",
133                   dns_protocol_to_string(t->scope->protocol),
134                   t->scope->link ? t->scope->link->name : "*",
135                   t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
136                   pretty);
137
138         /* RFC 4795, Section 4.1 says that the peer with the
139          * lexicographically smaller IP address loses */
140         if (memcmp(&p->sender, &p->destination, FAMILY_ADDRESS_SIZE(p->family)) >= 0) {
141                 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
142                 return;
143         }
144
145         log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
146
147         t->block_gc++;
148         while ((z = set_first(t->zone_items))) {
149                 /* First, make sure the zone item drops the reference
150                  * to us */
151                 dns_zone_item_probe_stop(z);
152
153                 /* Secondly, report this as conflict, so that we might
154                  * look for a different hostname */
155                 dns_zone_item_conflict(z);
156         }
157         t->block_gc--;
158
159         dns_transaction_gc(t);
160 }
161
162 void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
163         DnsQuery *q;
164         DnsZoneItem *z;
165         Iterator i;
166
167         assert(t);
168         assert(!IN_SET(state, DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING));
169
170         if (!IN_SET(t->state, DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING))
171                 return;
172
173         /* Note that this call might invalidate the query. Callers
174          * should hence not attempt to access the query or transaction
175          * after calling this function. */
176
177         log_debug("Transaction on scope %s on %s/%s now complete with <%s>",
178                   dns_protocol_to_string(t->scope->protocol),
179                   t->scope->link ? t->scope->link->name : "*",
180                   t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
181                   dns_transaction_state_to_string(state));
182
183         t->state = state;
184
185         dns_transaction_stop(t);
186
187         /* Notify all queries that are interested, but make sure the
188          * transaction isn't freed while we are still looking at it */
189         t->block_gc++;
190         SET_FOREACH(q, t->queries, i)
191                 dns_query_ready(q);
192         SET_FOREACH(z, t->zone_items, i)
193                 dns_zone_item_ready(z);
194         t->block_gc--;
195
196         dns_transaction_gc(t);
197 }
198
199 static int on_stream_complete(DnsStream *s, int error) {
200         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
201         DnsTransaction *t;
202
203         assert(s);
204         assert(s->transaction);
205
206         /* Copy the data we care about out of the stream before we
207          * destroy it. */
208         t = s->transaction;
209         p = dns_packet_ref(s->read_packet);
210
211         t->stream = dns_stream_free(t->stream);
212
213         if (error != 0) {
214                 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
215                 return 0;
216         }
217
218         if (dns_packet_validate_reply(p) <= 0) {
219                 log_debug("Invalid LLMNR TCP packet.");
220                 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
221                 return 0;
222         }
223
224         dns_scope_check_conflicts(t->scope, p);
225
226         t->block_gc++;
227         dns_transaction_process_reply(t, p);
228         t->block_gc--;
229
230         /* If the response wasn't useful, then complete the transition now */
231         if (t->state == DNS_TRANSACTION_PENDING)
232                 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
233
234         return 0;
235 }
236
237 static int dns_transaction_open_tcp(DnsTransaction *t) {
238         _cleanup_close_ int fd = -1;
239         int r;
240
241         assert(t);
242
243         if (t->stream)
244                 return 0;
245
246         if (t->scope->protocol == DNS_PROTOCOL_DNS)
247                 fd = dns_scope_tcp_socket(t->scope, AF_UNSPEC, NULL, 53);
248         else if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
249
250                 /* When we already received a query to this (but it was truncated), send to its sender address */
251                 if (t->received)
252                         fd = dns_scope_tcp_socket(t->scope, t->received->family, &t->received->sender, t->received->sender_port);
253                 else {
254                         union in_addr_union address;
255                         int family;
256
257                         /* Otherwise, try to talk to the owner of a
258                          * the IP address, in case this is a reverse
259                          * PTR lookup */
260                         r = dns_question_extract_reverse_address(t->question, &family, &address);
261                         if (r < 0)
262                                 return r;
263                         if (r == 0)
264                                 return -EINVAL;
265
266                         fd = dns_scope_tcp_socket(t->scope, family, &address, 5355);
267                 }
268         } else
269                 return -EAFNOSUPPORT;
270
271         if (fd < 0)
272                 return fd;
273
274         r = dns_stream_new(t->scope->manager, &t->stream, t->scope->protocol, fd);
275         if (r < 0)
276                 return r;
277
278         fd = -1;
279
280         r = dns_stream_write_packet(t->stream, t->sent);
281         if (r < 0) {
282                 t->stream = dns_stream_free(t->stream);
283                 return r;
284         }
285
286         t->received = dns_packet_unref(t->received);
287         t->stream->complete = on_stream_complete;
288         t->stream->transaction = t;
289
290         /* The interface index is difficult to determine if we are
291          * connecting to the local host, hence fill this in right away
292          * instead of determining it from the socket */
293         if (t->scope->link)
294                 t->stream->ifindex = t->scope->link->ifindex;
295
296         return 0;
297 }
298
299 void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
300         int r;
301
302         assert(t);
303         assert(p);
304         assert(t->state == DNS_TRANSACTION_PENDING);
305
306         /* Note that this call might invalidate the query. Callers
307          * should hence not attempt to access the query or transaction
308          * after calling this function. */
309
310         if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
311                 assert(t->scope->link);
312
313                 /* For LLMNR we will not accept any packets from other
314                  * interfaces */
315
316                 if (p->ifindex != t->scope->link->ifindex)
317                         return;
318
319                 if (p->family != t->scope->family)
320                         return;
321
322                 /* Tentative packets are not full responses but still
323                  * useful for identifying uniqueness conflicts during
324                  * probing. */
325                 if (DNS_PACKET_T(p)) {
326                         dns_transaction_tentative(t, p);
327                         return;
328                 }
329         }
330
331         if (t->scope->protocol == DNS_PROTOCOL_DNS) {
332
333                 /* For DNS we are fine with accepting packets on any
334                  * interface, but the source IP address must be one of
335                  * a valid DNS server */
336
337                 if (!dns_scope_good_dns_server(t->scope, p->family, &p->sender))
338                         return;
339
340                 if (p->sender_port != 53)
341                         return;
342         }
343
344         if (t->received != p) {
345                 dns_packet_unref(t->received);
346                 t->received = dns_packet_ref(p);
347         }
348
349         if (p->ipproto == IPPROTO_TCP) {
350                 if (DNS_PACKET_TC(p)) {
351                         /* Truncated via TCP? Somebody must be fucking with us */
352                         dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
353                         return;
354                 }
355
356                 if (DNS_PACKET_ID(p) != t->id) {
357                         /* Not the reply to our query? Somebody must be fucking with us */
358                         dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
359                         return;
360                 }
361         }
362
363         if (DNS_PACKET_TC(p)) {
364                 /* Response was truncated, let's try again with good old TCP */
365                 r = dns_transaction_open_tcp(t);
366                 if (r == -ESRCH) {
367                         /* No servers found? Damn! */
368                         dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
369                         return;
370                 }
371                 if (r < 0) {
372                         /* On LLMNR, if we cannot connect to the host,
373                          * we immediately give up */
374                         if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
375                                 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
376                                 return;
377                         }
378
379                         /* On DNS, couldn't send? Try immediately again, with a new server */
380                         dns_scope_next_dns_server(t->scope);
381
382                         r = dns_transaction_go(t);
383                         if (r < 0) {
384                                 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
385                                 return;
386                         }
387
388                         return;
389                 }
390         }
391
392         /* Parse and update the cache */
393         r = dns_packet_extract(p);
394         if (r < 0) {
395                 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
396                 return;
397         }
398
399         /* According to RFC 4795, section 2.9. only the RRs from the answer section shall be cached */
400         dns_cache_put(&t->scope->cache, p->question, DNS_PACKET_RCODE(p), p->answer, DNS_PACKET_ANCOUNT(p), 0, p->family, &p->sender);
401
402         if (DNS_PACKET_RCODE(p) == DNS_RCODE_SUCCESS)
403                 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
404         else
405                 dns_transaction_complete(t, DNS_TRANSACTION_FAILURE);
406 }
407
408 static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
409         DnsTransaction *t = userdata;
410         int r;
411
412         assert(s);
413         assert(t);
414
415         /* Timeout reached? Try again, with a new server */
416         dns_scope_next_dns_server(t->scope);
417
418         r = dns_transaction_go(t);
419         if (r < 0)
420                 dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
421
422         return 0;
423 }
424
425 static int dns_transaction_make_packet(DnsTransaction *t) {
426         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
427         unsigned n, added = 0;
428         int r;
429
430         assert(t);
431
432         if (t->sent)
433                 return 0;
434
435         r = dns_packet_new_query(&p, t->scope->protocol, 0);
436         if (r < 0)
437                 return r;
438
439         for (n = 0; n < t->question->n_keys; n++) {
440                 r = dns_scope_good_key(t->scope, t->question->keys[n]);
441                 if (r < 0)
442                         return r;
443                 if (r == 0)
444                         continue;
445
446                 r = dns_packet_append_key(p, t->question->keys[n], NULL);
447                 if (r < 0)
448                         return r;
449
450                 added++;
451         }
452
453         if (added <= 0)
454                 return -EDOM;
455
456         DNS_PACKET_HEADER(p)->qdcount = htobe16(added);
457         DNS_PACKET_HEADER(p)->id = t->id;
458
459         t->sent = p;
460         p = NULL;
461
462         return 0;
463 }
464
465 int dns_transaction_go(DnsTransaction *t) {
466         bool had_stream;
467         int r;
468
469         assert(t);
470
471         had_stream = !!t->stream;
472
473         dns_transaction_stop(t);
474
475         log_debug("Excercising transaction on scope %s on %s/%s",
476                   dns_protocol_to_string(t->scope->protocol),
477                   t->scope->link ? t->scope->link->name : "*",
478                   t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family));
479
480         if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t->scope->protocol)) {
481                 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
482                 return 0;
483         }
484
485         if (t->scope->protocol == DNS_PROTOCOL_LLMNR && had_stream) {
486                 /* If we already tried via a stream, then we don't
487                  * retry on LLMNR. See RFC 4795, Section 2.7. */
488                 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
489                 return 0;
490         }
491
492         t->n_attempts++;
493         t->received = dns_packet_unref(t->received);
494         t->cached = dns_answer_unref(t->cached);
495         t->cached_rcode = 0;
496
497         /* Check the cache, but only if this transaction is not used
498          * for probing or verifying a zone item. */
499         if (set_isempty(t->zone_items)) {
500
501                 /* Before trying the cache, let's make sure we figured out a
502                  * server to use. Should this cause a change of server this
503                  * might flush the cache. */
504                 dns_scope_get_dns_server(t->scope);
505
506                 /* Let's then prune all outdated entries */
507                 dns_cache_prune(&t->scope->cache);
508
509                 r = dns_cache_lookup(&t->scope->cache, t->question, &t->cached_rcode, &t->cached);
510                 if (r < 0)
511                         return r;
512                 if (r > 0) {
513                         log_debug("Cache hit!");
514                         if (t->cached_rcode == DNS_RCODE_SUCCESS)
515                                 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
516                         else
517                                 dns_transaction_complete(t, DNS_TRANSACTION_FAILURE);
518                         return 0;
519                 }
520         }
521
522         if (t->scope->protocol == DNS_PROTOCOL_LLMNR && !t->initial_jitter) {
523                 usec_t jitter;
524
525                 /* RFC 4795 Section 2.7 suggests all queries should be
526                  * delayed by a random time from 0 to JITTER_INTERVAL. */
527
528                 t->initial_jitter = true;
529
530                 random_bytes(&jitter, sizeof(jitter));
531                 jitter %= LLMNR_JITTER_INTERVAL_USEC;
532
533                 r = sd_event_add_time(
534                                 t->scope->manager->event,
535                                 &t->timeout_event_source,
536                                 clock_boottime_or_monotonic(),
537                                 now(clock_boottime_or_monotonic()) + jitter,
538                                 LLMNR_JITTER_INTERVAL_USEC,
539                                 on_transaction_timeout, t);
540                 if (r < 0)
541                         return r;
542
543                 t->n_attempts = 0;
544                 t->state = DNS_TRANSACTION_PENDING;
545
546                 log_debug("Delaying LLMNR transaction for " USEC_FMT "us.", jitter);
547                 return 0;
548         }
549
550         log_debug("Cache miss!");
551
552         /* Otherwise, we need to ask the network */
553         r = dns_transaction_make_packet(t);
554         if (r == -EDOM) {
555                 /* Not the right request to make on this network?
556                  * (i.e. an A request made on IPv6 or an AAAA request
557                  * made on IPv4, on LLMNR or mDNS.) */
558                 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
559                 return 0;
560         }
561         if (r < 0)
562                 return r;
563
564         if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
565             (dns_question_endswith(t->question, "in-addr.arpa") > 0 ||
566              dns_question_endswith(t->question, "ip6.arpa") > 0)) {
567
568                 /* RFC 4795, Section 2.4. says reverse lookups shall
569                  * always be made via TCP on LLMNR */
570                 r = dns_transaction_open_tcp(t);
571         } else {
572                 /* Try via UDP, and if that fails due to large size try via TCP */
573                 r = dns_scope_emit(t->scope, t->sent);
574                 if (r == -EMSGSIZE)
575                         r = dns_transaction_open_tcp(t);
576         }
577         if (r == -ESRCH) {
578                 /* No servers to send this to? */
579                 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
580                 return 0;
581         }
582         if (r < 0) {
583                 if (t->scope->protocol != DNS_PROTOCOL_DNS) {
584                         dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
585                         return 0;
586                 }
587
588                 /* Couldn't send? Try immediately again, with a new server */
589                 dns_scope_next_dns_server(t->scope);
590
591                 return dns_transaction_go(t);
592         }
593
594         r = sd_event_add_time(
595                         t->scope->manager->event,
596                         &t->timeout_event_source,
597                         clock_boottime_or_monotonic(),
598                         now(clock_boottime_or_monotonic()) + TRANSACTION_TIMEOUT_USEC(t->scope->protocol), 0,
599                         on_transaction_timeout, t);
600         if (r < 0)
601                 return r;
602
603         t->state = DNS_TRANSACTION_PENDING;
604         return 1;
605 }
606
607 static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX] = {
608         [DNS_TRANSACTION_NULL] = "null",
609         [DNS_TRANSACTION_PENDING] = "pending",
610         [DNS_TRANSACTION_FAILURE] = "failure",
611         [DNS_TRANSACTION_SUCCESS] = "success",
612         [DNS_TRANSACTION_NO_SERVERS] = "no-servers",
613         [DNS_TRANSACTION_TIMEOUT] = "timeout",
614         [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED] = "attempts-max-reached",
615         [DNS_TRANSACTION_INVALID_REPLY] = "invalid-reply",
616         [DNS_TRANSACTION_RESOURCES] = "resources",
617         [DNS_TRANSACTION_ABORTED] = "aborted",
618 };
619 DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);