chiark / gitweb /
resolved: don't abort if a transaction is aborted because its scope is removed
[elogind.git] / src / resolve / resolved-dns-packet.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 "utf8.h"
23 #include "util.h"
24 #include "strv.h"
25 #include "resolved-dns-domain.h"
26 #include "resolved-dns-packet.h"
27
28 int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
29         DnsPacket *p;
30         size_t a;
31
32         assert(ret);
33
34         if (mtu <= 0)
35                 a = DNS_PACKET_SIZE_START;
36         else
37                 a = mtu;
38
39         if (a < DNS_PACKET_HEADER_SIZE)
40                 a = DNS_PACKET_HEADER_SIZE;
41
42         /* round up to next page size */
43         a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
44
45         /* make sure we never allocate more than useful */
46         if (a > DNS_PACKET_SIZE_MAX)
47                 a = DNS_PACKET_SIZE_MAX;
48
49         p = malloc0(ALIGN(sizeof(DnsPacket)) + a);
50         if (!p)
51                 return -ENOMEM;
52
53         p->size = p->rindex = DNS_PACKET_HEADER_SIZE;
54         p->allocated = a;
55         p->protocol = protocol;
56         p->n_ref = 1;
57
58         *ret = p;
59
60         return 0;
61 }
62
63 int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
64         DnsPacket *p;
65         DnsPacketHeader *h;
66         int r;
67
68         assert(ret);
69
70         r = dns_packet_new(&p, protocol, mtu);
71         if (r < 0)
72                 return r;
73
74         h = DNS_PACKET_HEADER(p);
75
76         if (protocol == DNS_PROTOCOL_LLMNR)
77                 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
78                                                          0 /* opcode */,
79                                                          0 /* c */,
80                                                          0 /* tc */,
81                                                          0 /* t */,
82                                                          0 /* ra */,
83                                                          0 /* ad */,
84                                                          0 /* cd */,
85                                                          0 /* rcode */));
86         else
87                 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
88                                                          0 /* opcode */,
89                                                          0 /* aa */,
90                                                          0 /* tc */,
91                                                          1 /* rd (ask for recursion) */,
92                                                          0 /* ra */,
93                                                          0 /* ad */,
94                                                          0 /* cd */,
95                                                          0 /* rcode */));
96
97         *ret = p;
98         return 0;
99 }
100
101 DnsPacket *dns_packet_ref(DnsPacket *p) {
102
103         if (!p)
104                 return NULL;
105
106         assert(p->n_ref > 0);
107         p->n_ref++;
108         return p;
109 }
110
111 static void dns_packet_free(DnsPacket *p) {
112         char *s;
113
114         assert(p);
115
116         dns_question_unref(p->question);
117         dns_answer_unref(p->answer);
118
119         while ((s = hashmap_steal_first_key(p->names)))
120                 free(s);
121         hashmap_free(p->names);
122
123         free(p->_data);
124         free(p);
125 }
126
127 DnsPacket *dns_packet_unref(DnsPacket *p) {
128         if (!p)
129                 return NULL;
130
131         assert(p->n_ref > 0);
132
133         if (p->n_ref == 1)
134                 dns_packet_free(p);
135         else
136                 p->n_ref--;
137
138         return NULL;
139 }
140
141 int dns_packet_validate(DnsPacket *p) {
142         assert(p);
143
144         if (p->size < DNS_PACKET_HEADER_SIZE)
145                 return -EBADMSG;
146
147         if (p->size > DNS_PACKET_SIZE_MAX)
148                 return -EBADMSG;
149
150         return 1;
151 }
152
153 int dns_packet_validate_reply(DnsPacket *p) {
154         int r;
155
156         assert(p);
157
158         r = dns_packet_validate(p);
159         if (r < 0)
160                 return r;
161
162         if (DNS_PACKET_QR(p) != 1)
163                 return 0;
164
165         if (DNS_PACKET_OPCODE(p) != 0)
166                 return -EBADMSG;
167
168         /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
169         if (p->protocol == DNS_PROTOCOL_LLMNR &&
170             DNS_PACKET_QDCOUNT(p) != 1)
171                 return -EBADMSG;
172
173         return 1;
174 }
175
176 int dns_packet_validate_query(DnsPacket *p) {
177         int r;
178
179         assert(p);
180
181         r = dns_packet_validate(p);
182         if (r < 0)
183                 return r;
184
185         if (DNS_PACKET_QR(p) != 0)
186                 return 0;
187
188         if (DNS_PACKET_OPCODE(p) != 0)
189                 return -EBADMSG;
190
191         if (DNS_PACKET_TC(p))
192                 return -EBADMSG;
193
194         /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
195         if (p->protocol == DNS_PROTOCOL_LLMNR &&
196             DNS_PACKET_QDCOUNT(p) != 1)
197                 return -EBADMSG;
198
199         /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
200         if (DNS_PACKET_ANCOUNT(p) > 0)
201                 return -EBADMSG;
202
203         /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
204         if (DNS_PACKET_NSCOUNT(p) > 0)
205                 return -EBADMSG;
206
207         return 1;
208 }
209
210 static int dns_packet_extend(DnsPacket *p, size_t add, void **ret, size_t *start) {
211         assert(p);
212
213         if (p->size + add > p->allocated) {
214                 size_t a;
215
216                 a = PAGE_ALIGN((p->size + add) * 2);
217                 if (a > DNS_PACKET_SIZE_MAX)
218                         a = DNS_PACKET_SIZE_MAX;
219
220                 if (p->size + add > a)
221                         return -EMSGSIZE;
222
223                 if (p->_data) {
224                         void *d;
225
226                         d = realloc(p->_data, a);
227                         if (!d)
228                                 return -ENOMEM;
229
230                         p->_data = d;
231                 } else {
232                         p->_data = malloc(a);
233                         if (!p->_data)
234                                 return -ENOMEM;
235
236                         memcpy(p->_data, (uint8_t*) p + ALIGN(sizeof(DnsPacket)), p->size);
237                         memzero((uint8_t*) p->_data + p->size, a - p->size);
238                 }
239
240                 p->allocated = a;
241         }
242
243         if (start)
244                 *start = p->size;
245
246         if (ret)
247                 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->size;
248
249         p->size += add;
250         return 0;
251 }
252
253 static void dns_packet_truncate(DnsPacket *p, size_t sz) {
254         Iterator i;
255         char *s;
256         void *n;
257
258         assert(p);
259
260         if (p->size <= sz)
261                 return;
262
263         HASHMAP_FOREACH_KEY(s, n, p->names, i) {
264
265                 if (PTR_TO_SIZE(n) < sz)
266                         continue;
267
268                 hashmap_remove(p->names, s);
269                 free(s);
270         }
271
272         p->size = sz;
273 }
274
275 int dns_packet_append_blob(DnsPacket *p, const void *d, size_t l, size_t *start) {
276         void *q;
277         int r;
278
279         assert(p);
280
281         r = dns_packet_extend(p, l, &q, start);
282         if (r < 0)
283                 return r;
284
285         memcpy(q, d, l);
286         return 0;
287 }
288
289 int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start) {
290         void *d;
291         int r;
292
293         assert(p);
294
295         r = dns_packet_extend(p, sizeof(uint8_t), &d, start);
296         if (r < 0)
297                 return r;
298
299         ((uint8_t*) d)[0] = v;
300
301         return 0;
302 }
303
304 int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start) {
305         void *d;
306         int r;
307
308         assert(p);
309
310         r = dns_packet_extend(p, sizeof(uint16_t), &d, start);
311         if (r < 0)
312                 return r;
313
314         ((uint8_t*) d)[0] = (uint8_t) (v >> 8);
315         ((uint8_t*) d)[1] = (uint8_t) v;
316
317         return 0;
318 }
319
320 int dns_packet_append_uint32(DnsPacket *p, uint32_t v, size_t *start) {
321         void *d;
322         int r;
323
324         assert(p);
325
326         r = dns_packet_extend(p, sizeof(uint32_t), &d, start);
327         if (r < 0)
328                 return r;
329
330         ((uint8_t*) d)[0] = (uint8_t) (v >> 24);
331         ((uint8_t*) d)[1] = (uint8_t) (v >> 16);
332         ((uint8_t*) d)[2] = (uint8_t) (v >> 8);
333         ((uint8_t*) d)[3] = (uint8_t) v;
334
335         return 0;
336 }
337
338 int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start) {
339         void *d;
340         size_t l;
341         int r;
342
343         assert(p);
344         assert(s);
345
346         l = strlen(s);
347         if (l > 255)
348                 return -E2BIG;
349
350         r = dns_packet_extend(p, 1 + l, &d, start);
351         if (r < 0)
352                 return r;
353
354         ((uint8_t*) d)[0] = (uint8_t) l;
355         memcpy(((uint8_t*) d) + 1, s, l);
356
357         return 0;
358 }
359
360 int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, size_t *start) {
361         void *w;
362         int r;
363
364         assert(p);
365         assert(d);
366
367         if (l > DNS_LABEL_MAX)
368                 return -E2BIG;
369
370         r = dns_packet_extend(p, 1 + l, &w, start);
371         if (r < 0)
372                 return r;
373
374         ((uint8_t*) w)[0] = (uint8_t) l;
375         memcpy(((uint8_t*) w) + 1, d, l);
376
377         return 0;
378 }
379
380 int dns_packet_append_name(DnsPacket *p, const char *name,
381                            bool allow_compression, size_t *start) {
382         size_t saved_size;
383         int r;
384
385         assert(p);
386         assert(name);
387
388         saved_size = p->size;
389
390         while (*name) {
391                 _cleanup_free_ char *s = NULL;
392                 char label[DNS_LABEL_MAX];
393                 size_t n = 0;
394                 int k;
395
396                 if (allow_compression)
397                         n = PTR_TO_SIZE(hashmap_get(p->names, name));
398                 if (n > 0) {
399                         assert(n < p->size);
400
401                         if (n < 0x4000) {
402                                 r = dns_packet_append_uint16(p, 0xC000 | n, NULL);
403                                 if (r < 0)
404                                         goto fail;
405
406                                 goto done;
407                         }
408                 }
409
410                 s = strdup(name);
411                 if (!s) {
412                         r = -ENOMEM;
413                         goto fail;
414                 }
415
416                 r = dns_label_unescape(&name, label, sizeof(label));
417                 if (r < 0)
418                         goto fail;
419
420                 if (p->protocol == DNS_PROTOCOL_DNS)
421                         k = dns_label_apply_idna(label, r, label, sizeof(label));
422                 else
423                         k = dns_label_undo_idna(label, r, label, sizeof(label));
424                 if (k < 0) {
425                         r = k;
426                         goto fail;
427                 }
428                 if (k > 0)
429                         r = k;
430
431                 r = dns_packet_append_label(p, label, r, &n);
432                 if (r < 0)
433                         goto fail;
434
435                 if (allow_compression) {
436                         r = hashmap_ensure_allocated(&p->names,
437                                                      dns_name_hash_func,
438                                                      dns_name_compare_func);
439                         if (r < 0)
440                                 goto fail;
441
442                         r = hashmap_put(p->names, s, SIZE_TO_PTR(n));
443                         if (r < 0)
444                                 goto fail;
445
446                         s = NULL;
447                 }
448         }
449
450         r = dns_packet_append_uint8(p, 0, NULL);
451         if (r < 0)
452                 return r;
453
454 done:
455         if (start)
456                 *start = saved_size;
457
458         return 0;
459
460 fail:
461         dns_packet_truncate(p, saved_size);
462         return r;
463 }
464
465 int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start) {
466         size_t saved_size;
467         int r;
468
469         assert(p);
470         assert(k);
471
472         saved_size = p->size;
473
474         r = dns_packet_append_name(p, DNS_RESOURCE_KEY_NAME(k), true, NULL);
475         if (r < 0)
476                 goto fail;
477
478         r = dns_packet_append_uint16(p, k->type, NULL);
479         if (r < 0)
480                 goto fail;
481
482         r = dns_packet_append_uint16(p, k->class, NULL);
483         if (r < 0)
484                 goto fail;
485
486         if (start)
487                 *start = saved_size;
488
489         return 0;
490
491 fail:
492         dns_packet_truncate(p, saved_size);
493         return r;
494 }
495
496 int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start) {
497         size_t saved_size, rdlength_offset, end, rdlength;
498         int r;
499
500         assert(p);
501         assert(rr);
502
503         saved_size = p->size;
504
505         r = dns_packet_append_key(p, rr->key, NULL);
506         if (r < 0)
507                 goto fail;
508
509         r = dns_packet_append_uint32(p, rr->ttl, NULL);
510         if (r < 0)
511                 goto fail;
512
513         /* Initially we write 0 here */
514         r = dns_packet_append_uint16(p, 0, &rdlength_offset);
515         if (r < 0)
516                 goto fail;
517
518         switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
519
520         case DNS_TYPE_SRV:
521                 r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
522                 if (r < 0)
523                         goto fail;
524
525                 r = dns_packet_append_uint16(p, rr->srv.weight, NULL);
526                 if (r < 0)
527                         goto fail;
528
529                 r = dns_packet_append_uint16(p, rr->srv.port, NULL);
530                 if (r < 0)
531                         goto fail;
532
533                 r = dns_packet_append_name(p, rr->srv.name, true, NULL);
534                 break;
535
536         case DNS_TYPE_PTR:
537         case DNS_TYPE_NS:
538         case DNS_TYPE_CNAME:
539         case DNS_TYPE_DNAME:
540                 r = dns_packet_append_name(p, rr->ptr.name, true, NULL);
541                 break;
542
543         case DNS_TYPE_HINFO:
544                 r = dns_packet_append_string(p, rr->hinfo.cpu, NULL);
545                 if (r < 0)
546                         goto fail;
547
548                 r = dns_packet_append_string(p, rr->hinfo.os, NULL);
549                 break;
550
551         case DNS_TYPE_SPF: /* exactly the same as TXT */
552         case DNS_TYPE_TXT: {
553                 char **s;
554
555                 STRV_FOREACH(s, rr->txt.strings) {
556                         r = dns_packet_append_string(p, *s, NULL);
557                         if (r < 0)
558                                 goto fail;
559                 }
560
561                 r = 0;
562                 break;
563         }
564
565         case DNS_TYPE_A:
566                 r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
567                 break;
568
569         case DNS_TYPE_AAAA:
570                 r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
571                 break;
572
573         case DNS_TYPE_SOA:
574                 r = dns_packet_append_name(p, rr->soa.mname, true, NULL);
575                 if (r < 0)
576                         goto fail;
577
578                 r = dns_packet_append_name(p, rr->soa.rname, true, NULL);
579                 if (r < 0)
580                         goto fail;
581
582                 r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
583                 if (r < 0)
584                         goto fail;
585
586                 r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
587                 if (r < 0)
588                         goto fail;
589
590                 r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
591                 if (r < 0)
592                         goto fail;
593
594                 r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
595                 if (r < 0)
596                         goto fail;
597
598                 r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
599                 break;
600
601         case DNS_TYPE_MX:
602                 r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
603                 if (r < 0)
604                         goto fail;
605
606                 r = dns_packet_append_name(p, rr->mx.exchange, true, NULL);
607                 break;
608
609         case DNS_TYPE_LOC:
610                 r = dns_packet_append_uint8(p, rr->loc.version, NULL);
611                 if (r < 0)
612                         goto fail;
613
614                 r = dns_packet_append_uint8(p, rr->loc.size, NULL);
615                 if (r < 0)
616                         goto fail;
617
618                 r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
619                 if (r < 0)
620                         goto fail;
621
622                 r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
623                 if (r < 0)
624                         goto fail;
625
626                 r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
627                 if (r < 0)
628                         goto fail;
629
630                 r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
631                 if (r < 0)
632                         goto fail;
633
634                 r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
635                 break;
636
637         case DNS_TYPE_SSHFP:
638                 r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
639                 if (r < 0)
640                         goto fail;
641
642                 r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
643                 if (r < 0)
644                         goto fail;
645
646                 r = dns_packet_append_blob(p, rr->sshfp.key, rr->sshfp.key_size, NULL);
647                 break;
648
649         case DNS_TYPE_DNSKEY:
650                 r = dns_packet_append_uint16(p, dnskey_to_flags(rr), NULL);
651                 if (r < 0)
652                         goto fail;
653
654                 r = dns_packet_append_uint8(p, 3u, NULL);
655                 if (r < 0)
656                         goto fail;
657
658                 r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
659                 if (r < 0)
660                         goto fail;
661
662                 r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
663                 break;
664
665         case DNS_TYPE_RRSIG:
666                 r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
667                 if (r < 0)
668                         goto fail;
669
670                 r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
671                 if (r < 0)
672                         goto fail;
673
674                 r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
675                 if (r < 0)
676                         goto fail;
677
678                 r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
679                 if (r < 0)
680                         goto fail;
681
682                 r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
683                 if (r < 0)
684                         goto fail;
685
686                 r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
687                 if (r < 0)
688                         goto fail;
689
690                 r = dns_packet_append_uint8(p, rr->rrsig.key_tag, NULL);
691                 if (r < 0)
692                         goto fail;
693
694                 r = dns_packet_append_name(p, rr->rrsig.signer, false, NULL);
695                 if (r < 0)
696                         goto fail;
697
698                 r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
699                 break;
700
701         case _DNS_TYPE_INVALID: /* unparseable */
702         default:
703
704                 r = dns_packet_append_blob(p, rr->generic.data, rr->generic.size, NULL);
705                 break;
706         }
707         if (r < 0)
708                 goto fail;
709
710         /* Let's calculate the actual data size and update the field */
711         rdlength = p->size - rdlength_offset - sizeof(uint16_t);
712         if (rdlength > 0xFFFF) {
713                 r = ENOSPC;
714                 goto fail;
715         }
716
717         end = p->size;
718         p->size = rdlength_offset;
719         r = dns_packet_append_uint16(p, rdlength, NULL);
720         if (r < 0)
721                 goto fail;
722         p->size = end;
723
724         if (start)
725                 *start = saved_size;
726
727         return 0;
728
729 fail:
730         dns_packet_truncate(p, saved_size);
731         return r;
732 }
733
734
735 int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
736         assert(p);
737
738         if (p->rindex + sz > p->size)
739                 return -EMSGSIZE;
740
741         if (ret)
742                 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
743
744         if (start)
745                 *start = p->rindex;
746
747         p->rindex += sz;
748         return 0;
749 }
750
751 void dns_packet_rewind(DnsPacket *p, size_t idx) {
752         assert(p);
753         assert(idx <= p->size);
754         assert(idx >= DNS_PACKET_HEADER_SIZE);
755
756         p->rindex = idx;
757 }
758
759 int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
760         const void *q;
761         int r;
762
763         assert(p);
764         assert(d);
765
766         r = dns_packet_read(p, sz, &q, start);
767         if (r < 0)
768                 return r;
769
770         memcpy(d, q, sz);
771         return 0;
772 }
773
774 int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
775         const void *d;
776         int r;
777
778         assert(p);
779
780         r = dns_packet_read(p, sizeof(uint8_t), &d, start);
781         if (r < 0)
782                 return r;
783
784         *ret = ((uint8_t*) d)[0];
785         return 0;
786 }
787
788 int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
789         const void *d;
790         int r;
791
792         assert(p);
793
794         r = dns_packet_read(p, sizeof(uint16_t), &d, start);
795         if (r < 0)
796                 return r;
797
798         *ret = (((uint16_t) ((uint8_t*) d)[0]) << 8) |
799                 ((uint16_t) ((uint8_t*) d)[1]);
800         return 0;
801 }
802
803 int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
804         const void *d;
805         int r;
806
807         assert(p);
808
809         r = dns_packet_read(p, sizeof(uint32_t), &d, start);
810         if (r < 0)
811                 return r;
812
813         *ret = (((uint32_t) ((uint8_t*) d)[0]) << 24) |
814                (((uint32_t) ((uint8_t*) d)[1]) << 16) |
815                (((uint32_t) ((uint8_t*) d)[2]) << 8) |
816                 ((uint32_t) ((uint8_t*) d)[3]);
817
818         return 0;
819 }
820
821 int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
822         size_t saved_rindex;
823         const void *d;
824         char *t;
825         uint8_t c;
826         int r;
827
828         assert(p);
829
830         saved_rindex = p->rindex;
831
832         r = dns_packet_read_uint8(p, &c, NULL);
833         if (r < 0)
834                 goto fail;
835
836         r = dns_packet_read(p, c, &d, NULL);
837         if (r < 0)
838                 goto fail;
839
840         if (memchr(d, 0, c)) {
841                 r = -EBADMSG;
842                 goto fail;
843         }
844
845         t = strndup(d, c);
846         if (!t) {
847                 r = -ENOMEM;
848                 goto fail;
849         }
850
851         if (!utf8_is_valid(t)) {
852                 free(t);
853                 r = -EBADMSG;
854                 goto fail;
855         }
856
857         *ret = t;
858
859         if (start)
860                 *start = saved_rindex;
861
862         return 0;
863
864 fail:
865         dns_packet_rewind(p, saved_rindex);
866         return r;
867 }
868
869 int dns_packet_read_name(DnsPacket *p, char **_ret,
870                          bool allow_compression, size_t *start) {
871         size_t saved_rindex, after_rindex = 0;
872         _cleanup_free_ char *ret = NULL;
873         size_t n = 0, allocated = 0;
874         bool first = true;
875         int r;
876
877         assert(p);
878         assert(_ret);
879
880         saved_rindex = p->rindex;
881
882         for (;;) {
883                 uint8_t c, d;
884
885                 r = dns_packet_read_uint8(p, &c, NULL);
886                 if (r < 0)
887                         goto fail;
888
889                 if (c == 0)
890                         /* End of name */
891                         break;
892                 else if (c <= 63) {
893                         _cleanup_free_ char *t = NULL;
894                         const char *label;
895
896                         /* Literal label */
897                         r = dns_packet_read(p, c, (const void**) &label, NULL);
898                         if (r < 0)
899                                 goto fail;
900
901                         r = dns_label_escape(label, c, &t);
902                         if (r < 0)
903                                 goto fail;
904
905                         if (!GREEDY_REALLOC(ret, allocated, n + !first + strlen(t) + 1)) {
906                                 r = -ENOMEM;
907                                 goto fail;
908                         }
909
910                         if (!first)
911                                 ret[n++] = '.';
912                         else
913                                 first = false;
914
915                         memcpy(ret + n, t, r);
916                         n += r;
917                         continue;
918                 } else if (allow_compression && (c & 0xc0) == 0xc0) {
919                         uint16_t ptr;
920
921                         /* Pointer */
922                         r = dns_packet_read_uint8(p, &d, NULL);
923                         if (r < 0)
924                                 goto fail;
925
926                         ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
927                         if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= saved_rindex) {
928                                 r = -EBADMSG;
929                                 goto fail;
930                         }
931
932                         if (after_rindex == 0)
933                                 after_rindex = p->rindex;
934
935                         p->rindex = ptr;
936                 } else
937                         goto fail;
938         }
939
940         if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
941                 r = -ENOMEM;
942                 goto fail;
943         }
944
945         ret[n] = 0;
946
947         if (after_rindex != 0)
948                 p->rindex= after_rindex;
949
950         *_ret = ret;
951         ret = NULL;
952
953         if (start)
954                 *start = saved_rindex;
955
956         return 0;
957
958 fail:
959         dns_packet_rewind(p, saved_rindex);
960         return r;
961 }
962
963 int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) {
964         _cleanup_free_ char *name = NULL;
965         uint16_t class, type;
966         DnsResourceKey *key;
967         size_t saved_rindex;
968         int r;
969
970         assert(p);
971         assert(ret);
972
973         saved_rindex = p->rindex;
974
975         r = dns_packet_read_name(p, &name, true, NULL);
976         if (r < 0)
977                 goto fail;
978
979         r = dns_packet_read_uint16(p, &type, NULL);
980         if (r < 0)
981                 goto fail;
982
983         r = dns_packet_read_uint16(p, &class, NULL);
984         if (r < 0)
985                 goto fail;
986
987         key = dns_resource_key_new_consume(class, type, name);
988         if (!key) {
989                 r = -ENOMEM;
990                 goto fail;
991         }
992
993         name = NULL;
994         *ret = key;
995
996         if (start)
997                 *start = saved_rindex;
998
999         return 0;
1000 fail:
1001         dns_packet_rewind(p, saved_rindex);
1002         return r;
1003 }
1004
1005 static int dns_packet_read_public_key(DnsPacket *p, size_t length,
1006                                       void **dp, size_t *lengthp,
1007                                       size_t *start) {
1008         int r;
1009         const void *d;
1010         void *d2;
1011
1012         r = dns_packet_read(p, length, &d, NULL);
1013         if (r < 0)
1014                 return r;
1015
1016         d2 = memdup(d, length);
1017         if (!d2)
1018                 return -ENOMEM;
1019
1020         *dp = d2;
1021         *lengthp = length;
1022         return 0;
1023 }
1024
1025 static bool loc_size_ok(uint8_t size) {
1026         uint8_t m = size >> 4, e = size & 0xF;
1027
1028         return m <= 9 && e <= 9 && (m > 0 || e == 0);
1029 }
1030
1031 static int dnskey_parse_flags(DnsResourceRecord *rr, uint16_t flags) {
1032         if (flags & ~(DNSKEY_FLAG_SEP | DNSKEY_FLAG_ZONE_KEY))
1033                 return -EBADMSG;
1034
1035         rr->dnskey.zone_key_flag = flags & DNSKEY_FLAG_ZONE_KEY;
1036         rr->dnskey.sep_flag = flags & DNSKEY_FLAG_SEP;
1037         return 0;
1038 }
1039
1040 int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
1041         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1042         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1043         size_t saved_rindex, offset;
1044         uint16_t rdlength;
1045         const void *d;
1046         int r;
1047
1048         assert(p);
1049         assert(ret);
1050
1051         saved_rindex = p->rindex;
1052
1053         r = dns_packet_read_key(p, &key, NULL);
1054         if (r < 0)
1055                 goto fail;
1056
1057         if (key->class == DNS_CLASS_ANY ||
1058             key->type == DNS_TYPE_ANY) {
1059                 r = -EBADMSG;
1060                 goto fail;
1061         }
1062
1063         rr = dns_resource_record_new(key);
1064         if (!rr) {
1065                 r = -ENOMEM;
1066                 goto fail;
1067         }
1068
1069         r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1070         if (r < 0)
1071                 goto fail;
1072
1073         r = dns_packet_read_uint16(p, &rdlength, NULL);
1074         if (r < 0)
1075                 goto fail;
1076
1077         if (p->rindex + rdlength > p->size) {
1078                 r = -EBADMSG;
1079                 goto fail;
1080         }
1081
1082         offset = p->rindex;
1083
1084         switch (rr->key->type) {
1085
1086         case DNS_TYPE_SRV:
1087                 r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1088                 if (r < 0)
1089                         goto fail;
1090                 r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1091                 if (r < 0)
1092                         goto fail;
1093                 r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1094                 if (r < 0)
1095                         goto fail;
1096                 r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
1097                 break;
1098
1099         case DNS_TYPE_PTR:
1100         case DNS_TYPE_NS:
1101         case DNS_TYPE_CNAME:
1102         case DNS_TYPE_DNAME:
1103                 r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
1104                 break;
1105
1106         case DNS_TYPE_HINFO:
1107                 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1108                 if (r < 0)
1109                         goto fail;
1110
1111                 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1112                 break;
1113
1114         case DNS_TYPE_SPF: /* exactly the same as TXT */
1115         case DNS_TYPE_TXT: {
1116                 char *s;
1117
1118                 while (p->rindex < offset + rdlength) {
1119                         r = dns_packet_read_string(p, &s, NULL);
1120                         if (r < 0)
1121                                 goto fail;
1122
1123                         r = strv_consume(&rr->txt.strings, s);
1124                         if (r < 0)
1125                                 goto fail;
1126                 }
1127
1128                 r = 0;
1129                 break;
1130         }
1131
1132         case DNS_TYPE_A:
1133                 r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
1134                 break;
1135
1136         case DNS_TYPE_AAAA:
1137                 r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
1138                 break;
1139
1140         case DNS_TYPE_SOA:
1141                 r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
1142                 if (r < 0)
1143                         goto fail;
1144
1145                 r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
1146                 if (r < 0)
1147                         goto fail;
1148
1149                 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1150                 if (r < 0)
1151                         goto fail;
1152
1153                 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1154                 if (r < 0)
1155                         goto fail;
1156
1157                 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1158                 if (r < 0)
1159                         goto fail;
1160
1161                 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1162                 if (r < 0)
1163                         goto fail;
1164
1165                 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1166                 break;
1167
1168         case DNS_TYPE_MX:
1169                 r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
1170                 if (r < 0)
1171                         goto fail;
1172
1173                 r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
1174                 break;
1175
1176         case DNS_TYPE_LOC: {
1177                 uint8_t t;
1178                 size_t pos;
1179
1180                 r = dns_packet_read_uint8(p, &t, &pos);
1181                 if (r < 0)
1182                         goto fail;
1183
1184                 if (t == 0) {
1185                         rr->loc.version = t;
1186
1187                         r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
1188                         if (r < 0)
1189                                 goto fail;
1190
1191                         if (!loc_size_ok(rr->loc.size)) {
1192                                 r = -EBADMSG;
1193                                 goto fail;
1194                         }
1195
1196                         r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
1197                         if (r < 0)
1198                                 goto fail;
1199
1200                         if (!loc_size_ok(rr->loc.horiz_pre)) {
1201                                 r = -EBADMSG;
1202                                 goto fail;
1203                         }
1204
1205                         r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
1206                         if (r < 0)
1207                                 goto fail;
1208
1209                         if (!loc_size_ok(rr->loc.vert_pre)) {
1210                                 r = -EBADMSG;
1211                                 goto fail;
1212                         }
1213
1214                         r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
1215                         if (r < 0)
1216                                 goto fail;
1217
1218                         r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
1219                         if (r < 0)
1220                                 goto fail;
1221
1222                         r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
1223                         if (r < 0)
1224                                 goto fail;
1225
1226                         break;
1227                 } else {
1228                         dns_packet_rewind(p, pos);
1229                         rr->unparseable = true;
1230                         goto unparseable;
1231                 }
1232         }
1233
1234         case DNS_TYPE_SSHFP:
1235                 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1236                 if (r < 0)
1237                         goto fail;
1238
1239                 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1240                 if (r < 0)
1241                         goto fail;
1242
1243                 r = dns_packet_read_public_key(p, rdlength - 2,
1244                                                &rr->sshfp.key, &rr->sshfp.key_size,
1245                                                NULL);
1246                 break;
1247
1248         case DNS_TYPE_DNSKEY: {
1249                 uint16_t flags;
1250                 uint8_t proto;
1251
1252                 r = dns_packet_read_uint16(p, &flags, NULL);
1253                 if (r < 0)
1254                         goto fail;
1255
1256                 r = dnskey_parse_flags(rr, flags);
1257                 if (r < 0)
1258                         goto fail;
1259
1260                 r = dns_packet_read_uint8(p, &proto, NULL);
1261                 if (r < 0)
1262                         goto fail;
1263
1264                 /* protocol is required to be always 3 */
1265                 if (proto != 3) {
1266                         r = -EBADMSG;
1267                         goto fail;
1268                 }
1269
1270                 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1271                 if (r < 0)
1272                         goto fail;
1273
1274                 r = dns_packet_read_public_key(p, rdlength - 4,
1275                                                &rr->dnskey.key, &rr->dnskey.key_size,
1276                                                NULL);
1277                 break;
1278         }
1279
1280         case DNS_TYPE_RRSIG:
1281                 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
1282                 if (r < 0)
1283                         goto fail;
1284
1285                 r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
1286                 if (r < 0)
1287                         goto fail;
1288
1289                 r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
1290                 if (r < 0)
1291                         goto fail;
1292
1293                 r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
1294                 if (r < 0)
1295                         goto fail;
1296
1297                 r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
1298                 if (r < 0)
1299                         goto fail;
1300
1301                 r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
1302                 if (r < 0)
1303                         goto fail;
1304
1305                 r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
1306                 if (r < 0)
1307                         goto fail;
1308
1309                 r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
1310                 if (r < 0)
1311                         goto fail;
1312
1313                 r = dns_packet_read_public_key(p, offset + rdlength - p->rindex,
1314                                                &rr->rrsig.signature, &rr->rrsig.signature_size,
1315                                                NULL);
1316                 break;
1317
1318         default:
1319         unparseable:
1320                 r = dns_packet_read(p, rdlength, &d, NULL);
1321                 if (r < 0)
1322                         goto fail;
1323
1324                 rr->generic.data = memdup(d, rdlength);
1325                 if (!rr->generic.data) {
1326                         r = -ENOMEM;
1327                         goto fail;
1328                 }
1329
1330                 rr->generic.size = rdlength;
1331                 break;
1332         }
1333         if (r < 0)
1334                 goto fail;
1335         if (p->rindex != offset + rdlength) {
1336                 r = -EBADMSG;
1337                 goto fail;
1338         }
1339
1340         *ret = rr;
1341         rr = NULL;
1342
1343         if (start)
1344                 *start = saved_rindex;
1345
1346         return 0;
1347 fail:
1348         dns_packet_rewind(p, saved_rindex);
1349         return r;
1350 }
1351
1352 int dns_packet_extract(DnsPacket *p) {
1353         _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
1354         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1355         size_t saved_rindex;
1356         unsigned n, i;
1357         int r;
1358
1359         saved_rindex = p->rindex;
1360         dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
1361
1362         n = DNS_PACKET_QDCOUNT(p);
1363         if (n > 0) {
1364                 question = dns_question_new(n);
1365                 if (!question) {
1366                         r = -ENOMEM;
1367                         goto finish;
1368                 }
1369
1370                 for (i = 0; i < n; i++) {
1371                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1372
1373                         r = dns_packet_read_key(p, &key, NULL);
1374                         if (r < 0)
1375                                 goto finish;
1376
1377                         r = dns_question_add(question, key);
1378                         if (r < 0)
1379                                 goto finish;
1380                 }
1381         }
1382
1383         n = DNS_PACKET_RRCOUNT(p);
1384         if (n > 0) {
1385                 answer = dns_answer_new(n);
1386                 if (!answer) {
1387                         r = -ENOMEM;
1388                         goto finish;
1389                 }
1390
1391                 for (i = 0; i < n; i++) {
1392                         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1393
1394                         r = dns_packet_read_rr(p, &rr, NULL);
1395                         if (r < 0)
1396                                 goto finish;
1397
1398                         r = dns_answer_add(answer, rr);
1399                         if (r < 0)
1400                                 goto finish;
1401                 }
1402         }
1403
1404         p->question = question;
1405         question = NULL;
1406
1407         p->answer = answer;
1408         answer = NULL;
1409
1410         r = 0;
1411
1412 finish:
1413         p->rindex = saved_rindex;
1414         return r;
1415 }
1416
1417 static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
1418         [DNS_RCODE_SUCCESS] = "SUCCESS",
1419         [DNS_RCODE_FORMERR] = "FORMERR",
1420         [DNS_RCODE_SERVFAIL] = "SERVFAIL",
1421         [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
1422         [DNS_RCODE_NOTIMP] = "NOTIMP",
1423         [DNS_RCODE_REFUSED] = "REFUSED",
1424         [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
1425         [DNS_RCODE_YXRRSET] = "YRRSET",
1426         [DNS_RCODE_NXRRSET] = "NXRRSET",
1427         [DNS_RCODE_NOTAUTH] = "NOTAUTH",
1428         [DNS_RCODE_NOTZONE] = "NOTZONE",
1429         [DNS_RCODE_BADVERS] = "BADVERS",
1430         [DNS_RCODE_BADKEY] = "BADKEY",
1431         [DNS_RCODE_BADTIME] = "BADTIME",
1432         [DNS_RCODE_BADMODE] = "BADMODE",
1433         [DNS_RCODE_BADNAME] = "BADNAME",
1434         [DNS_RCODE_BADALG] = "BADALG",
1435         [DNS_RCODE_BADTRUNC] = "BADTRUNC",
1436 };
1437 DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1438
1439 static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
1440         [DNS_PROTOCOL_DNS] = "dns",
1441         [DNS_PROTOCOL_MDNS] = "mdns",
1442         [DNS_PROTOCOL_LLMNR] = "llmnr",
1443 };
1444 DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
1445
1446 static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
1447         [DNSSEC_ALGORITHM_RSAMD5]     = "RSAMD5",
1448         [DNSSEC_ALGORITHM_DH]         = "DH",
1449         [DNSSEC_ALGORITHM_DSA]        = "DSA",
1450         [DNSSEC_ALGORITHM_ECC]        = "ECC",
1451         [DNSSEC_ALGORITHM_RSASHA1]    = "RSASHA1",
1452         [DNSSEC_ALGORITHM_INDIRECT]   = "INDIRECT",
1453         [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
1454         [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
1455 };
1456 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int);