]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-packet.c
resolved: add missing error code check when initializing DNS-over-TLS
[thirdparty/systemd.git] / src / resolve / resolved-dns-packet.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #if HAVE_GCRYPT
4 #include <gcrypt.h>
5 #endif
6
7 #include "alloc-util.h"
8 #include "dns-domain.h"
9 #include "memory-util.h"
10 #include "resolved-dns-packet.h"
11 #include "set.h"
12 #include "string-table.h"
13 #include "strv.h"
14 #include "unaligned.h"
15 #include "utf8.h"
16 #include "util.h"
17
18 #define EDNS0_OPT_DO (1<<15)
19
20 assert_cc(DNS_PACKET_SIZE_START > DNS_PACKET_HEADER_SIZE)
21
22 typedef struct DnsPacketRewinder {
23 DnsPacket *packet;
24 size_t saved_rindex;
25 } DnsPacketRewinder;
26
27 static void rewind_dns_packet(DnsPacketRewinder *rewinder) {
28 if (rewinder->packet)
29 dns_packet_rewind(rewinder->packet, rewinder->saved_rindex);
30 }
31
32 #define INIT_REWINDER(rewinder, p) do { rewinder.packet = p; rewinder.saved_rindex = p->rindex; } while (0)
33 #define CANCEL_REWINDER(rewinder) do { rewinder.packet = NULL; } while (0)
34
35 int dns_packet_new(
36 DnsPacket **ret,
37 DnsProtocol protocol,
38 size_t min_alloc_dsize,
39 size_t max_size) {
40
41 DnsPacket *p;
42 size_t a;
43
44 assert(ret);
45 assert(max_size >= DNS_PACKET_HEADER_SIZE);
46
47 if (max_size > DNS_PACKET_SIZE_MAX)
48 max_size = DNS_PACKET_SIZE_MAX;
49
50 /* The caller may not check what is going to be truly allocated, so do not allow to
51 * allocate a DNS packet bigger than DNS_PACKET_SIZE_MAX.
52 */
53 if (min_alloc_dsize > DNS_PACKET_SIZE_MAX)
54 return log_error_errno(SYNTHETIC_ERRNO(EFBIG),
55 "Requested packet data size too big: %zu",
56 min_alloc_dsize);
57
58 /* When dns_packet_new() is called with min_alloc_dsize == 0, allocate more than the
59 * absolute minimum (which is the dns packet header size), to avoid
60 * resizing immediately again after appending the first data to the packet.
61 */
62 if (min_alloc_dsize < DNS_PACKET_HEADER_SIZE)
63 a = DNS_PACKET_SIZE_START;
64 else
65 a = min_alloc_dsize;
66
67 /* round up to next page size */
68 a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
69
70 /* make sure we never allocate more than useful */
71 if (a > max_size)
72 a = max_size;
73
74 p = malloc0(ALIGN(sizeof(DnsPacket)) + a);
75 if (!p)
76 return -ENOMEM;
77
78 p->size = p->rindex = DNS_PACKET_HEADER_SIZE;
79 p->allocated = a;
80 p->max_size = max_size;
81 p->protocol = protocol;
82 p->opt_start = p->opt_size = (size_t) -1;
83 p->n_ref = 1;
84
85 *ret = p;
86
87 return 0;
88 }
89
90 void dns_packet_set_flags(DnsPacket *p, bool dnssec_checking_disabled, bool truncated) {
91
92 DnsPacketHeader *h;
93
94 assert(p);
95
96 h = DNS_PACKET_HEADER(p);
97
98 switch(p->protocol) {
99 case DNS_PROTOCOL_LLMNR:
100 assert(!truncated);
101
102 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
103 0 /* opcode */,
104 0 /* c */,
105 0 /* tc */,
106 0 /* t */,
107 0 /* ra */,
108 0 /* ad */,
109 0 /* cd */,
110 0 /* rcode */));
111 break;
112
113 case DNS_PROTOCOL_MDNS:
114 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
115 0 /* opcode */,
116 0 /* aa */,
117 truncated /* tc */,
118 0 /* rd (ask for recursion) */,
119 0 /* ra */,
120 0 /* ad */,
121 0 /* cd */,
122 0 /* rcode */));
123 break;
124
125 default:
126 assert(!truncated);
127
128 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
129 0 /* opcode */,
130 0 /* aa */,
131 0 /* tc */,
132 1 /* rd (ask for recursion) */,
133 0 /* ra */,
134 0 /* ad */,
135 dnssec_checking_disabled /* cd */,
136 0 /* rcode */));
137 }
138 }
139
140 int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t min_alloc_dsize, bool dnssec_checking_disabled) {
141 DnsPacket *p;
142 int r;
143
144 assert(ret);
145
146 r = dns_packet_new(&p, protocol, min_alloc_dsize, DNS_PACKET_SIZE_MAX);
147 if (r < 0)
148 return r;
149
150 /* Always set the TC bit to 0 initially.
151 * If there are multiple packets later, we'll update the bit shortly before sending.
152 */
153 dns_packet_set_flags(p, dnssec_checking_disabled, false);
154
155 *ret = p;
156 return 0;
157 }
158
159 DnsPacket *dns_packet_ref(DnsPacket *p) {
160
161 if (!p)
162 return NULL;
163
164 assert(!p->on_stack);
165
166 assert(p->n_ref > 0);
167 p->n_ref++;
168 return p;
169 }
170
171 static void dns_packet_free(DnsPacket *p) {
172 char *s;
173
174 assert(p);
175
176 dns_question_unref(p->question);
177 dns_answer_unref(p->answer);
178 dns_resource_record_unref(p->opt);
179
180 while ((s = hashmap_steal_first_key(p->names)))
181 free(s);
182 hashmap_free(p->names);
183
184 free(p->_data);
185
186 if (!p->on_stack)
187 free(p);
188 }
189
190 DnsPacket *dns_packet_unref(DnsPacket *p) {
191 if (!p)
192 return NULL;
193
194 assert(p->n_ref > 0);
195
196 dns_packet_unref(p->more);
197
198 if (p->n_ref == 1)
199 dns_packet_free(p);
200 else
201 p->n_ref--;
202
203 return NULL;
204 }
205
206 int dns_packet_validate(DnsPacket *p) {
207 assert(p);
208
209 if (p->size < DNS_PACKET_HEADER_SIZE)
210 return -EBADMSG;
211
212 if (p->size > DNS_PACKET_SIZE_MAX)
213 return -EBADMSG;
214
215 return 1;
216 }
217
218 int dns_packet_validate_reply(DnsPacket *p) {
219 int r;
220
221 assert(p);
222
223 r = dns_packet_validate(p);
224 if (r < 0)
225 return r;
226
227 if (DNS_PACKET_QR(p) != 1)
228 return 0;
229
230 if (DNS_PACKET_OPCODE(p) != 0)
231 return -EBADMSG;
232
233 switch (p->protocol) {
234
235 case DNS_PROTOCOL_LLMNR:
236 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
237 if (DNS_PACKET_QDCOUNT(p) != 1)
238 return -EBADMSG;
239
240 break;
241
242 case DNS_PROTOCOL_MDNS:
243 /* RFC 6762, Section 18 */
244 if (DNS_PACKET_RCODE(p) != 0)
245 return -EBADMSG;
246
247 break;
248
249 default:
250 break;
251 }
252
253 return 1;
254 }
255
256 int dns_packet_validate_query(DnsPacket *p) {
257 int r;
258
259 assert(p);
260
261 r = dns_packet_validate(p);
262 if (r < 0)
263 return r;
264
265 if (DNS_PACKET_QR(p) != 0)
266 return 0;
267
268 if (DNS_PACKET_OPCODE(p) != 0)
269 return -EBADMSG;
270
271 if (DNS_PACKET_TC(p))
272 return -EBADMSG;
273
274 switch (p->protocol) {
275
276 case DNS_PROTOCOL_LLMNR:
277 case DNS_PROTOCOL_DNS:
278 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
279 if (DNS_PACKET_QDCOUNT(p) != 1)
280 return -EBADMSG;
281
282 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
283 if (DNS_PACKET_ANCOUNT(p) > 0)
284 return -EBADMSG;
285
286 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
287 if (DNS_PACKET_NSCOUNT(p) > 0)
288 return -EBADMSG;
289
290 break;
291
292 case DNS_PROTOCOL_MDNS:
293 /* RFC 6762, Section 18 */
294 if (DNS_PACKET_AA(p) != 0 ||
295 DNS_PACKET_RD(p) != 0 ||
296 DNS_PACKET_RA(p) != 0 ||
297 DNS_PACKET_AD(p) != 0 ||
298 DNS_PACKET_CD(p) != 0 ||
299 DNS_PACKET_RCODE(p) != 0)
300 return -EBADMSG;
301
302 break;
303
304 default:
305 break;
306 }
307
308 return 1;
309 }
310
311 static int dns_packet_extend(DnsPacket *p, size_t add, void **ret, size_t *start) {
312 assert(p);
313
314 if (p->size + add > p->allocated) {
315 size_t a, ms;
316
317 a = PAGE_ALIGN((p->size + add) * 2);
318
319 ms = dns_packet_size_max(p);
320 if (a > ms)
321 a = ms;
322
323 if (p->size + add > a)
324 return -EMSGSIZE;
325
326 if (p->_data) {
327 void *d;
328
329 d = realloc(p->_data, a);
330 if (!d)
331 return -ENOMEM;
332
333 p->_data = d;
334 } else {
335 p->_data = malloc(a);
336 if (!p->_data)
337 return -ENOMEM;
338
339 memcpy(p->_data, (uint8_t*) p + ALIGN(sizeof(DnsPacket)), p->size);
340 memzero((uint8_t*) p->_data + p->size, a - p->size);
341 }
342
343 p->allocated = a;
344 }
345
346 if (start)
347 *start = p->size;
348
349 if (ret)
350 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->size;
351
352 p->size += add;
353 return 0;
354 }
355
356 void dns_packet_truncate(DnsPacket *p, size_t sz) {
357 Iterator i;
358 char *s;
359 void *n;
360
361 assert(p);
362
363 if (p->size <= sz)
364 return;
365
366 HASHMAP_FOREACH_KEY(n, s, p->names, i) {
367
368 if (PTR_TO_SIZE(n) < sz)
369 continue;
370
371 hashmap_remove(p->names, s);
372 free(s);
373 }
374
375 p->size = sz;
376 }
377
378 int dns_packet_append_blob(DnsPacket *p, const void *d, size_t l, size_t *start) {
379 void *q;
380 int r;
381
382 assert(p);
383
384 r = dns_packet_extend(p, l, &q, start);
385 if (r < 0)
386 return r;
387
388 memcpy_safe(q, d, l);
389 return 0;
390 }
391
392 int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start) {
393 void *d;
394 int r;
395
396 assert(p);
397
398 r = dns_packet_extend(p, sizeof(uint8_t), &d, start);
399 if (r < 0)
400 return r;
401
402 ((uint8_t*) d)[0] = v;
403
404 return 0;
405 }
406
407 int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start) {
408 void *d;
409 int r;
410
411 assert(p);
412
413 r = dns_packet_extend(p, sizeof(uint16_t), &d, start);
414 if (r < 0)
415 return r;
416
417 unaligned_write_be16(d, v);
418
419 return 0;
420 }
421
422 int dns_packet_append_uint32(DnsPacket *p, uint32_t v, size_t *start) {
423 void *d;
424 int r;
425
426 assert(p);
427
428 r = dns_packet_extend(p, sizeof(uint32_t), &d, start);
429 if (r < 0)
430 return r;
431
432 unaligned_write_be32(d, v);
433
434 return 0;
435 }
436
437 int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start) {
438 assert(p);
439 assert(s);
440
441 return dns_packet_append_raw_string(p, s, strlen(s), start);
442 }
443
444 int dns_packet_append_raw_string(DnsPacket *p, const void *s, size_t size, size_t *start) {
445 void *d;
446 int r;
447
448 assert(p);
449 assert(s || size == 0);
450
451 if (size > 255)
452 return -E2BIG;
453
454 r = dns_packet_extend(p, 1 + size, &d, start);
455 if (r < 0)
456 return r;
457
458 ((uint8_t*) d)[0] = (uint8_t) size;
459
460 memcpy_safe(((uint8_t*) d) + 1, s, size);
461
462 return 0;
463 }
464
465 int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, bool canonical_candidate, size_t *start) {
466 uint8_t *w;
467 int r;
468
469 /* Append a label to a packet. Optionally, does this in DNSSEC
470 * canonical form, if this label is marked as a candidate for
471 * it, and the canonical form logic is enabled for the
472 * packet */
473
474 assert(p);
475 assert(d);
476
477 if (l > DNS_LABEL_MAX)
478 return -E2BIG;
479
480 r = dns_packet_extend(p, 1 + l, (void**) &w, start);
481 if (r < 0)
482 return r;
483
484 *(w++) = (uint8_t) l;
485
486 if (p->canonical_form && canonical_candidate) {
487 size_t i;
488
489 /* Generate in canonical form, as defined by DNSSEC
490 * RFC 4034, Section 6.2, i.e. all lower-case. */
491
492 for (i = 0; i < l; i++)
493 w[i] = (uint8_t) ascii_tolower(d[i]);
494 } else
495 /* Otherwise, just copy the string unaltered. This is
496 * essential for DNS-SD, where the casing of labels
497 * matters and needs to be retained. */
498 memcpy(w, d, l);
499
500 return 0;
501 }
502
503 int dns_packet_append_name(
504 DnsPacket *p,
505 const char *name,
506 bool allow_compression,
507 bool canonical_candidate,
508 size_t *start) {
509
510 size_t saved_size;
511 int r;
512
513 assert(p);
514 assert(name);
515
516 if (p->refuse_compression)
517 allow_compression = false;
518
519 saved_size = p->size;
520
521 while (!dns_name_is_root(name)) {
522 const char *z = name;
523 char label[DNS_LABEL_MAX];
524 size_t n = 0;
525
526 if (allow_compression)
527 n = PTR_TO_SIZE(hashmap_get(p->names, name));
528 if (n > 0) {
529 assert(n < p->size);
530
531 if (n < 0x4000) {
532 r = dns_packet_append_uint16(p, 0xC000 | n, NULL);
533 if (r < 0)
534 goto fail;
535
536 goto done;
537 }
538 }
539
540 r = dns_label_unescape(&name, label, sizeof label, 0);
541 if (r < 0)
542 goto fail;
543
544 r = dns_packet_append_label(p, label, r, canonical_candidate, &n);
545 if (r < 0)
546 goto fail;
547
548 if (allow_compression) {
549 _cleanup_free_ char *s = NULL;
550
551 s = strdup(z);
552 if (!s) {
553 r = -ENOMEM;
554 goto fail;
555 }
556
557 r = hashmap_ensure_allocated(&p->names, &dns_name_hash_ops);
558 if (r < 0)
559 goto fail;
560
561 r = hashmap_put(p->names, s, SIZE_TO_PTR(n));
562 if (r < 0)
563 goto fail;
564
565 s = NULL;
566 }
567 }
568
569 r = dns_packet_append_uint8(p, 0, NULL);
570 if (r < 0)
571 return r;
572
573 done:
574 if (start)
575 *start = saved_size;
576
577 return 0;
578
579 fail:
580 dns_packet_truncate(p, saved_size);
581 return r;
582 }
583
584 int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, const DnsAnswerFlags flags, size_t *start) {
585 size_t saved_size;
586 uint16_t class;
587 int r;
588
589 assert(p);
590 assert(k);
591
592 saved_size = p->size;
593
594 r = dns_packet_append_name(p, dns_resource_key_name(k), true, true, NULL);
595 if (r < 0)
596 goto fail;
597
598 r = dns_packet_append_uint16(p, k->type, NULL);
599 if (r < 0)
600 goto fail;
601
602 class = flags & DNS_ANSWER_CACHE_FLUSH ? k->class | MDNS_RR_CACHE_FLUSH : k->class;
603 r = dns_packet_append_uint16(p, class, NULL);
604 if (r < 0)
605 goto fail;
606
607 if (start)
608 *start = saved_size;
609
610 return 0;
611
612 fail:
613 dns_packet_truncate(p, saved_size);
614 return r;
615 }
616
617 static int dns_packet_append_type_window(DnsPacket *p, uint8_t window, uint8_t length, const uint8_t *types, size_t *start) {
618 size_t saved_size;
619 int r;
620
621 assert(p);
622 assert(types);
623 assert(length > 0);
624
625 saved_size = p->size;
626
627 r = dns_packet_append_uint8(p, window, NULL);
628 if (r < 0)
629 goto fail;
630
631 r = dns_packet_append_uint8(p, length, NULL);
632 if (r < 0)
633 goto fail;
634
635 r = dns_packet_append_blob(p, types, length, NULL);
636 if (r < 0)
637 goto fail;
638
639 if (start)
640 *start = saved_size;
641
642 return 0;
643 fail:
644 dns_packet_truncate(p, saved_size);
645 return r;
646 }
647
648 static int dns_packet_append_types(DnsPacket *p, Bitmap *types, size_t *start) {
649 Iterator i;
650 uint8_t window = 0;
651 uint8_t entry = 0;
652 uint8_t bitmaps[32] = {};
653 unsigned n;
654 size_t saved_size;
655 int r;
656
657 assert(p);
658
659 saved_size = p->size;
660
661 BITMAP_FOREACH(n, types, i) {
662 assert(n <= 0xffff);
663
664 if ((n >> 8) != window && bitmaps[entry / 8] != 0) {
665 r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL);
666 if (r < 0)
667 goto fail;
668
669 zero(bitmaps);
670 }
671
672 window = n >> 8;
673 entry = n & 255;
674
675 bitmaps[entry / 8] |= 1 << (7 - (entry % 8));
676 }
677
678 if (bitmaps[entry / 8] != 0) {
679 r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL);
680 if (r < 0)
681 goto fail;
682 }
683
684 if (start)
685 *start = saved_size;
686
687 return 0;
688 fail:
689 dns_packet_truncate(p, saved_size);
690 return r;
691 }
692
693 /* Append the OPT pseudo-RR described in RFC6891 */
694 int dns_packet_append_opt(DnsPacket *p, uint16_t max_udp_size, bool edns0_do, int rcode, size_t *start) {
695 size_t saved_size;
696 int r;
697
698 assert(p);
699 /* we must never advertise supported packet size smaller than the legacy max */
700 assert(max_udp_size >= DNS_PACKET_UNICAST_SIZE_MAX);
701 assert(rcode >= 0);
702 assert(rcode <= _DNS_RCODE_MAX);
703
704 if (p->opt_start != (size_t) -1)
705 return -EBUSY;
706
707 assert(p->opt_size == (size_t) -1);
708
709 saved_size = p->size;
710
711 /* empty name */
712 r = dns_packet_append_uint8(p, 0, NULL);
713 if (r < 0)
714 return r;
715
716 /* type */
717 r = dns_packet_append_uint16(p, DNS_TYPE_OPT, NULL);
718 if (r < 0)
719 goto fail;
720
721 /* class: maximum udp packet that can be received */
722 r = dns_packet_append_uint16(p, max_udp_size, NULL);
723 if (r < 0)
724 goto fail;
725
726 /* extended RCODE and VERSION */
727 r = dns_packet_append_uint16(p, ((uint16_t) rcode & 0x0FF0) << 4, NULL);
728 if (r < 0)
729 goto fail;
730
731 /* flags: DNSSEC OK (DO), see RFC3225 */
732 r = dns_packet_append_uint16(p, edns0_do ? EDNS0_OPT_DO : 0, NULL);
733 if (r < 0)
734 goto fail;
735
736 /* RDLENGTH */
737 if (edns0_do && !DNS_PACKET_QR(p)) {
738 /* If DO is on and this is not a reply, also append RFC6975 Algorithm data */
739
740 static const uint8_t rfc6975[] = {
741
742 0, 5, /* OPTION_CODE: DAU */
743 #if HAVE_GCRYPT && GCRYPT_VERSION_NUMBER >= 0x010600
744 0, 7, /* LIST_LENGTH */
745 #else
746 0, 6, /* LIST_LENGTH */
747 #endif
748 DNSSEC_ALGORITHM_RSASHA1,
749 DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1,
750 DNSSEC_ALGORITHM_RSASHA256,
751 DNSSEC_ALGORITHM_RSASHA512,
752 DNSSEC_ALGORITHM_ECDSAP256SHA256,
753 DNSSEC_ALGORITHM_ECDSAP384SHA384,
754 #if HAVE_GCRYPT && GCRYPT_VERSION_NUMBER >= 0x010600
755 DNSSEC_ALGORITHM_ED25519,
756 #endif
757
758 0, 6, /* OPTION_CODE: DHU */
759 0, 3, /* LIST_LENGTH */
760 DNSSEC_DIGEST_SHA1,
761 DNSSEC_DIGEST_SHA256,
762 DNSSEC_DIGEST_SHA384,
763
764 0, 7, /* OPTION_CODE: N3U */
765 0, 1, /* LIST_LENGTH */
766 NSEC3_ALGORITHM_SHA1,
767 };
768
769 r = dns_packet_append_uint16(p, sizeof(rfc6975), NULL);
770 if (r < 0)
771 goto fail;
772
773 r = dns_packet_append_blob(p, rfc6975, sizeof(rfc6975), NULL);
774 } else
775 r = dns_packet_append_uint16(p, 0, NULL);
776 if (r < 0)
777 goto fail;
778
779 DNS_PACKET_HEADER(p)->arcount = htobe16(DNS_PACKET_ARCOUNT(p) + 1);
780
781 p->opt_start = saved_size;
782 p->opt_size = p->size - saved_size;
783
784 if (start)
785 *start = saved_size;
786
787 return 0;
788
789 fail:
790 dns_packet_truncate(p, saved_size);
791 return r;
792 }
793
794 int dns_packet_truncate_opt(DnsPacket *p) {
795 assert(p);
796
797 if (p->opt_start == (size_t) -1) {
798 assert(p->opt_size == (size_t) -1);
799 return 0;
800 }
801
802 assert(p->opt_size != (size_t) -1);
803 assert(DNS_PACKET_ARCOUNT(p) > 0);
804
805 if (p->opt_start + p->opt_size != p->size)
806 return -EBUSY;
807
808 dns_packet_truncate(p, p->opt_start);
809 DNS_PACKET_HEADER(p)->arcount = htobe16(DNS_PACKET_ARCOUNT(p) - 1);
810 p->opt_start = p->opt_size = (size_t) -1;
811
812 return 1;
813 }
814
815 int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, const DnsAnswerFlags flags, size_t *start, size_t *rdata_start) {
816
817 size_t saved_size, rdlength_offset, end, rdlength, rds;
818 uint32_t ttl;
819 int r;
820
821 assert(p);
822 assert(rr);
823
824 saved_size = p->size;
825
826 r = dns_packet_append_key(p, rr->key, flags, NULL);
827 if (r < 0)
828 goto fail;
829
830 ttl = flags & DNS_ANSWER_GOODBYE ? 0 : rr->ttl;
831 r = dns_packet_append_uint32(p, ttl, NULL);
832 if (r < 0)
833 goto fail;
834
835 /* Initially we write 0 here */
836 r = dns_packet_append_uint16(p, 0, &rdlength_offset);
837 if (r < 0)
838 goto fail;
839
840 rds = p->size - saved_size;
841
842 switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
843
844 case DNS_TYPE_SRV:
845 r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
846 if (r < 0)
847 goto fail;
848
849 r = dns_packet_append_uint16(p, rr->srv.weight, NULL);
850 if (r < 0)
851 goto fail;
852
853 r = dns_packet_append_uint16(p, rr->srv.port, NULL);
854 if (r < 0)
855 goto fail;
856
857 /* RFC 2782 states "Unless and until permitted by future standards
858 * action, name compression is not to be used for this field." */
859 r = dns_packet_append_name(p, rr->srv.name, false, false, NULL);
860 break;
861
862 case DNS_TYPE_PTR:
863 case DNS_TYPE_NS:
864 case DNS_TYPE_CNAME:
865 case DNS_TYPE_DNAME:
866 r = dns_packet_append_name(p, rr->ptr.name, true, false, NULL);
867 break;
868
869 case DNS_TYPE_HINFO:
870 r = dns_packet_append_string(p, rr->hinfo.cpu, NULL);
871 if (r < 0)
872 goto fail;
873
874 r = dns_packet_append_string(p, rr->hinfo.os, NULL);
875 break;
876
877 case DNS_TYPE_SPF: /* exactly the same as TXT */
878 case DNS_TYPE_TXT:
879
880 if (!rr->txt.items) {
881 /* RFC 6763, section 6.1 suggests to generate
882 * single empty string for an empty array. */
883
884 r = dns_packet_append_raw_string(p, NULL, 0, NULL);
885 if (r < 0)
886 goto fail;
887 } else {
888 DnsTxtItem *i;
889
890 LIST_FOREACH(items, i, rr->txt.items) {
891 r = dns_packet_append_raw_string(p, i->data, i->length, NULL);
892 if (r < 0)
893 goto fail;
894 }
895 }
896
897 r = 0;
898 break;
899
900 case DNS_TYPE_A:
901 r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
902 break;
903
904 case DNS_TYPE_AAAA:
905 r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
906 break;
907
908 case DNS_TYPE_SOA:
909 r = dns_packet_append_name(p, rr->soa.mname, true, false, NULL);
910 if (r < 0)
911 goto fail;
912
913 r = dns_packet_append_name(p, rr->soa.rname, true, false, NULL);
914 if (r < 0)
915 goto fail;
916
917 r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
918 if (r < 0)
919 goto fail;
920
921 r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
922 if (r < 0)
923 goto fail;
924
925 r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
926 if (r < 0)
927 goto fail;
928
929 r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
930 if (r < 0)
931 goto fail;
932
933 r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
934 break;
935
936 case DNS_TYPE_MX:
937 r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
938 if (r < 0)
939 goto fail;
940
941 r = dns_packet_append_name(p, rr->mx.exchange, true, false, NULL);
942 break;
943
944 case DNS_TYPE_LOC:
945 r = dns_packet_append_uint8(p, rr->loc.version, NULL);
946 if (r < 0)
947 goto fail;
948
949 r = dns_packet_append_uint8(p, rr->loc.size, NULL);
950 if (r < 0)
951 goto fail;
952
953 r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
954 if (r < 0)
955 goto fail;
956
957 r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
958 if (r < 0)
959 goto fail;
960
961 r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
962 if (r < 0)
963 goto fail;
964
965 r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
966 if (r < 0)
967 goto fail;
968
969 r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
970 break;
971
972 case DNS_TYPE_DS:
973 r = dns_packet_append_uint16(p, rr->ds.key_tag, NULL);
974 if (r < 0)
975 goto fail;
976
977 r = dns_packet_append_uint8(p, rr->ds.algorithm, NULL);
978 if (r < 0)
979 goto fail;
980
981 r = dns_packet_append_uint8(p, rr->ds.digest_type, NULL);
982 if (r < 0)
983 goto fail;
984
985 r = dns_packet_append_blob(p, rr->ds.digest, rr->ds.digest_size, NULL);
986 break;
987
988 case DNS_TYPE_SSHFP:
989 r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
990 if (r < 0)
991 goto fail;
992
993 r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
994 if (r < 0)
995 goto fail;
996
997 r = dns_packet_append_blob(p, rr->sshfp.fingerprint, rr->sshfp.fingerprint_size, NULL);
998 break;
999
1000 case DNS_TYPE_DNSKEY:
1001 r = dns_packet_append_uint16(p, rr->dnskey.flags, NULL);
1002 if (r < 0)
1003 goto fail;
1004
1005 r = dns_packet_append_uint8(p, rr->dnskey.protocol, NULL);
1006 if (r < 0)
1007 goto fail;
1008
1009 r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
1010 if (r < 0)
1011 goto fail;
1012
1013 r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
1014 break;
1015
1016 case DNS_TYPE_RRSIG:
1017 r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
1018 if (r < 0)
1019 goto fail;
1020
1021 r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
1022 if (r < 0)
1023 goto fail;
1024
1025 r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
1026 if (r < 0)
1027 goto fail;
1028
1029 r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
1030 if (r < 0)
1031 goto fail;
1032
1033 r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
1034 if (r < 0)
1035 goto fail;
1036
1037 r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
1038 if (r < 0)
1039 goto fail;
1040
1041 r = dns_packet_append_uint16(p, rr->rrsig.key_tag, NULL);
1042 if (r < 0)
1043 goto fail;
1044
1045 r = dns_packet_append_name(p, rr->rrsig.signer, false, true, NULL);
1046 if (r < 0)
1047 goto fail;
1048
1049 r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
1050 break;
1051
1052 case DNS_TYPE_NSEC:
1053 r = dns_packet_append_name(p, rr->nsec.next_domain_name, false, false, NULL);
1054 if (r < 0)
1055 goto fail;
1056
1057 r = dns_packet_append_types(p, rr->nsec.types, NULL);
1058 if (r < 0)
1059 goto fail;
1060
1061 break;
1062
1063 case DNS_TYPE_NSEC3:
1064 r = dns_packet_append_uint8(p, rr->nsec3.algorithm, NULL);
1065 if (r < 0)
1066 goto fail;
1067
1068 r = dns_packet_append_uint8(p, rr->nsec3.flags, NULL);
1069 if (r < 0)
1070 goto fail;
1071
1072 r = dns_packet_append_uint16(p, rr->nsec3.iterations, NULL);
1073 if (r < 0)
1074 goto fail;
1075
1076 r = dns_packet_append_uint8(p, rr->nsec3.salt_size, NULL);
1077 if (r < 0)
1078 goto fail;
1079
1080 r = dns_packet_append_blob(p, rr->nsec3.salt, rr->nsec3.salt_size, NULL);
1081 if (r < 0)
1082 goto fail;
1083
1084 r = dns_packet_append_uint8(p, rr->nsec3.next_hashed_name_size, NULL);
1085 if (r < 0)
1086 goto fail;
1087
1088 r = dns_packet_append_blob(p, rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, NULL);
1089 if (r < 0)
1090 goto fail;
1091
1092 r = dns_packet_append_types(p, rr->nsec3.types, NULL);
1093 if (r < 0)
1094 goto fail;
1095
1096 break;
1097
1098 case DNS_TYPE_TLSA:
1099 r = dns_packet_append_uint8(p, rr->tlsa.cert_usage, NULL);
1100 if (r < 0)
1101 goto fail;
1102
1103 r = dns_packet_append_uint8(p, rr->tlsa.selector, NULL);
1104 if (r < 0)
1105 goto fail;
1106
1107 r = dns_packet_append_uint8(p, rr->tlsa.matching_type, NULL);
1108 if (r < 0)
1109 goto fail;
1110
1111 r = dns_packet_append_blob(p, rr->tlsa.data, rr->tlsa.data_size, NULL);
1112 break;
1113
1114 case DNS_TYPE_CAA:
1115 r = dns_packet_append_uint8(p, rr->caa.flags, NULL);
1116 if (r < 0)
1117 goto fail;
1118
1119 r = dns_packet_append_string(p, rr->caa.tag, NULL);
1120 if (r < 0)
1121 goto fail;
1122
1123 r = dns_packet_append_blob(p, rr->caa.value, rr->caa.value_size, NULL);
1124 break;
1125
1126 case DNS_TYPE_OPT:
1127 case DNS_TYPE_OPENPGPKEY:
1128 case _DNS_TYPE_INVALID: /* unparseable */
1129 default:
1130
1131 r = dns_packet_append_blob(p, rr->generic.data, rr->generic.data_size, NULL);
1132 break;
1133 }
1134 if (r < 0)
1135 goto fail;
1136
1137 /* Let's calculate the actual data size and update the field */
1138 rdlength = p->size - rdlength_offset - sizeof(uint16_t);
1139 if (rdlength > 0xFFFF) {
1140 r = -ENOSPC;
1141 goto fail;
1142 }
1143
1144 end = p->size;
1145 p->size = rdlength_offset;
1146 r = dns_packet_append_uint16(p, rdlength, NULL);
1147 if (r < 0)
1148 goto fail;
1149 p->size = end;
1150
1151 if (start)
1152 *start = saved_size;
1153
1154 if (rdata_start)
1155 *rdata_start = rds;
1156
1157 return 0;
1158
1159 fail:
1160 dns_packet_truncate(p, saved_size);
1161 return r;
1162 }
1163
1164 int dns_packet_append_question(DnsPacket *p, DnsQuestion *q) {
1165 DnsResourceKey *key;
1166 int r;
1167
1168 assert(p);
1169
1170 DNS_QUESTION_FOREACH(key, q) {
1171 r = dns_packet_append_key(p, key, 0, NULL);
1172 if (r < 0)
1173 return r;
1174 }
1175
1176 return 0;
1177 }
1178
1179 int dns_packet_append_answer(DnsPacket *p, DnsAnswer *a) {
1180 DnsResourceRecord *rr;
1181 DnsAnswerFlags flags;
1182 int r;
1183
1184 assert(p);
1185
1186 DNS_ANSWER_FOREACH_FLAGS(rr, flags, a) {
1187 r = dns_packet_append_rr(p, rr, flags, NULL, NULL);
1188 if (r < 0)
1189 return r;
1190 }
1191
1192 return 0;
1193 }
1194
1195 int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
1196 assert(p);
1197
1198 if (p->rindex + sz > p->size)
1199 return -EMSGSIZE;
1200
1201 if (ret)
1202 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
1203
1204 if (start)
1205 *start = p->rindex;
1206
1207 p->rindex += sz;
1208 return 0;
1209 }
1210
1211 void dns_packet_rewind(DnsPacket *p, size_t idx) {
1212 assert(p);
1213 assert(idx <= p->size);
1214 assert(idx >= DNS_PACKET_HEADER_SIZE);
1215
1216 p->rindex = idx;
1217 }
1218
1219 int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
1220 const void *q;
1221 int r;
1222
1223 assert(p);
1224 assert(d);
1225
1226 r = dns_packet_read(p, sz, &q, start);
1227 if (r < 0)
1228 return r;
1229
1230 memcpy(d, q, sz);
1231 return 0;
1232 }
1233
1234 static int dns_packet_read_memdup(
1235 DnsPacket *p, size_t size,
1236 void **ret, size_t *ret_size,
1237 size_t *ret_start) {
1238
1239 const void *src;
1240 size_t start;
1241 int r;
1242
1243 assert(p);
1244 assert(ret);
1245
1246 r = dns_packet_read(p, size, &src, &start);
1247 if (r < 0)
1248 return r;
1249
1250 if (size <= 0)
1251 *ret = NULL;
1252 else {
1253 void *copy;
1254
1255 copy = memdup(src, size);
1256 if (!copy)
1257 return -ENOMEM;
1258
1259 *ret = copy;
1260 }
1261
1262 if (ret_size)
1263 *ret_size = size;
1264 if (ret_start)
1265 *ret_start = start;
1266
1267 return 0;
1268 }
1269
1270 int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
1271 const void *d;
1272 int r;
1273
1274 assert(p);
1275
1276 r = dns_packet_read(p, sizeof(uint8_t), &d, start);
1277 if (r < 0)
1278 return r;
1279
1280 *ret = ((uint8_t*) d)[0];
1281 return 0;
1282 }
1283
1284 int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
1285 const void *d;
1286 int r;
1287
1288 assert(p);
1289
1290 r = dns_packet_read(p, sizeof(uint16_t), &d, start);
1291 if (r < 0)
1292 return r;
1293
1294 *ret = unaligned_read_be16(d);
1295
1296 return 0;
1297 }
1298
1299 int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
1300 const void *d;
1301 int r;
1302
1303 assert(p);
1304
1305 r = dns_packet_read(p, sizeof(uint32_t), &d, start);
1306 if (r < 0)
1307 return r;
1308
1309 *ret = unaligned_read_be32(d);
1310
1311 return 0;
1312 }
1313
1314 int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
1315 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
1316 const void *d;
1317 char *t;
1318 uint8_t c;
1319 int r;
1320
1321 assert(p);
1322 INIT_REWINDER(rewinder, p);
1323
1324 r = dns_packet_read_uint8(p, &c, NULL);
1325 if (r < 0)
1326 return r;
1327
1328 r = dns_packet_read(p, c, &d, NULL);
1329 if (r < 0)
1330 return r;
1331
1332 if (memchr(d, 0, c))
1333 return -EBADMSG;
1334
1335 t = strndup(d, c);
1336 if (!t)
1337 return -ENOMEM;
1338
1339 if (!utf8_is_valid(t)) {
1340 free(t);
1341 return -EBADMSG;
1342 }
1343
1344 *ret = t;
1345
1346 if (start)
1347 *start = rewinder.saved_rindex;
1348 CANCEL_REWINDER(rewinder);
1349
1350 return 0;
1351 }
1352
1353 int dns_packet_read_raw_string(DnsPacket *p, const void **ret, size_t *size, size_t *start) {
1354 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
1355 uint8_t c;
1356 int r;
1357
1358 assert(p);
1359 INIT_REWINDER(rewinder, p);
1360
1361 r = dns_packet_read_uint8(p, &c, NULL);
1362 if (r < 0)
1363 return r;
1364
1365 r = dns_packet_read(p, c, ret, NULL);
1366 if (r < 0)
1367 return r;
1368
1369 if (size)
1370 *size = c;
1371 if (start)
1372 *start = rewinder.saved_rindex;
1373 CANCEL_REWINDER(rewinder);
1374
1375 return 0;
1376 }
1377
1378 int dns_packet_read_name(
1379 DnsPacket *p,
1380 char **_ret,
1381 bool allow_compression,
1382 size_t *start) {
1383
1384 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
1385 size_t after_rindex = 0, jump_barrier;
1386 _cleanup_free_ char *ret = NULL;
1387 size_t n = 0, allocated = 0;
1388 bool first = true;
1389 int r;
1390
1391 assert(p);
1392 assert(_ret);
1393 INIT_REWINDER(rewinder, p);
1394 jump_barrier = p->rindex;
1395
1396 if (p->refuse_compression)
1397 allow_compression = false;
1398
1399 for (;;) {
1400 uint8_t c, d;
1401
1402 r = dns_packet_read_uint8(p, &c, NULL);
1403 if (r < 0)
1404 return r;
1405
1406 if (c == 0)
1407 /* End of name */
1408 break;
1409 else if (c <= 63) {
1410 const char *label;
1411
1412 /* Literal label */
1413 r = dns_packet_read(p, c, (const void**) &label, NULL);
1414 if (r < 0)
1415 return r;
1416
1417 if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
1418 return -ENOMEM;
1419
1420 if (first)
1421 first = false;
1422 else
1423 ret[n++] = '.';
1424
1425 r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX);
1426 if (r < 0)
1427 return r;
1428
1429 n += r;
1430 continue;
1431 } else if (allow_compression && (c & 0xc0) == 0xc0) {
1432 uint16_t ptr;
1433
1434 /* Pointer */
1435 r = dns_packet_read_uint8(p, &d, NULL);
1436 if (r < 0)
1437 return r;
1438
1439 ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
1440 if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier)
1441 return -EBADMSG;
1442
1443 if (after_rindex == 0)
1444 after_rindex = p->rindex;
1445
1446 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
1447 jump_barrier = ptr;
1448 p->rindex = ptr;
1449 } else
1450 return -EBADMSG;
1451 }
1452
1453 if (!GREEDY_REALLOC(ret, allocated, n + 1))
1454 return -ENOMEM;
1455
1456 ret[n] = 0;
1457
1458 if (after_rindex != 0)
1459 p->rindex= after_rindex;
1460
1461 *_ret = TAKE_PTR(ret);
1462
1463 if (start)
1464 *start = rewinder.saved_rindex;
1465 CANCEL_REWINDER(rewinder);
1466
1467 return 0;
1468 }
1469
1470 static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *start) {
1471 uint8_t window;
1472 uint8_t length;
1473 const uint8_t *bitmap;
1474 uint8_t bit = 0;
1475 unsigned i;
1476 bool found = false;
1477 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
1478 int r;
1479
1480 assert(p);
1481 assert(types);
1482 INIT_REWINDER(rewinder, p);
1483
1484 r = bitmap_ensure_allocated(types);
1485 if (r < 0)
1486 return r;
1487
1488 r = dns_packet_read_uint8(p, &window, NULL);
1489 if (r < 0)
1490 return r;
1491
1492 r = dns_packet_read_uint8(p, &length, NULL);
1493 if (r < 0)
1494 return r;
1495
1496 if (length == 0 || length > 32)
1497 return -EBADMSG;
1498
1499 r = dns_packet_read(p, length, (const void **)&bitmap, NULL);
1500 if (r < 0)
1501 return r;
1502
1503 for (i = 0; i < length; i++) {
1504 uint8_t bitmask = 1 << 7;
1505
1506 if (!bitmap[i]) {
1507 found = false;
1508 bit += 8;
1509 continue;
1510 }
1511
1512 found = true;
1513
1514 for (; bitmask; bit++, bitmask >>= 1)
1515 if (bitmap[i] & bitmask) {
1516 uint16_t n;
1517
1518 n = (uint16_t) window << 8 | (uint16_t) bit;
1519
1520 /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
1521 if (dns_type_is_pseudo(n))
1522 continue;
1523
1524 r = bitmap_set(*types, n);
1525 if (r < 0)
1526 return r;
1527 }
1528 }
1529
1530 if (!found)
1531 return -EBADMSG;
1532
1533 if (start)
1534 *start = rewinder.saved_rindex;
1535 CANCEL_REWINDER(rewinder);
1536
1537 return 0;
1538 }
1539
1540 static int dns_packet_read_type_windows(DnsPacket *p, Bitmap **types, size_t size, size_t *start) {
1541 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
1542 int r;
1543
1544 INIT_REWINDER(rewinder, p);
1545
1546 while (p->rindex < rewinder.saved_rindex + size) {
1547 r = dns_packet_read_type_window(p, types, NULL);
1548 if (r < 0)
1549 return r;
1550
1551 /* don't read past end of current RR */
1552 if (p->rindex > rewinder.saved_rindex + size)
1553 return -EBADMSG;
1554 }
1555
1556 if (p->rindex != rewinder.saved_rindex + size)
1557 return -EBADMSG;
1558
1559 if (start)
1560 *start = rewinder.saved_rindex;
1561 CANCEL_REWINDER(rewinder);
1562
1563 return 0;
1564 }
1565
1566 int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, bool *ret_cache_flush, size_t *start) {
1567 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
1568 _cleanup_free_ char *name = NULL;
1569 bool cache_flush = false;
1570 uint16_t class, type;
1571 DnsResourceKey *key;
1572 int r;
1573
1574 assert(p);
1575 assert(ret);
1576 INIT_REWINDER(rewinder, p);
1577
1578 r = dns_packet_read_name(p, &name, true, NULL);
1579 if (r < 0)
1580 return r;
1581
1582 r = dns_packet_read_uint16(p, &type, NULL);
1583 if (r < 0)
1584 return r;
1585
1586 r = dns_packet_read_uint16(p, &class, NULL);
1587 if (r < 0)
1588 return r;
1589
1590 if (p->protocol == DNS_PROTOCOL_MDNS) {
1591 /* See RFC6762, Section 10.2 */
1592
1593 if (type != DNS_TYPE_OPT && (class & MDNS_RR_CACHE_FLUSH)) {
1594 class &= ~MDNS_RR_CACHE_FLUSH;
1595 cache_flush = true;
1596 }
1597 }
1598
1599 key = dns_resource_key_new_consume(class, type, name);
1600 if (!key)
1601 return -ENOMEM;
1602
1603 name = NULL;
1604 *ret = key;
1605
1606 if (ret_cache_flush)
1607 *ret_cache_flush = cache_flush;
1608 if (start)
1609 *start = rewinder.saved_rindex;
1610 CANCEL_REWINDER(rewinder);
1611
1612 return 0;
1613 }
1614
1615 static bool loc_size_ok(uint8_t size) {
1616 uint8_t m = size >> 4, e = size & 0xF;
1617
1618 return m <= 9 && e <= 9 && (m > 0 || e == 0);
1619 }
1620
1621 int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_flush, size_t *start) {
1622 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1623 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1624 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
1625 size_t offset;
1626 uint16_t rdlength;
1627 bool cache_flush;
1628 int r;
1629
1630 assert(p);
1631 assert(ret);
1632
1633 INIT_REWINDER(rewinder, p);
1634
1635 r = dns_packet_read_key(p, &key, &cache_flush, NULL);
1636 if (r < 0)
1637 return r;
1638
1639 if (!dns_class_is_valid_rr(key->class) || !dns_type_is_valid_rr(key->type))
1640 return -EBADMSG;
1641
1642 rr = dns_resource_record_new(key);
1643 if (!rr)
1644 return -ENOMEM;
1645
1646 r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1647 if (r < 0)
1648 return r;
1649
1650 /* RFC 2181, Section 8, suggests to
1651 * treat a TTL with the MSB set as a zero TTL. */
1652 if (rr->ttl & UINT32_C(0x80000000))
1653 rr->ttl = 0;
1654
1655 r = dns_packet_read_uint16(p, &rdlength, NULL);
1656 if (r < 0)
1657 return r;
1658
1659 if (p->rindex + rdlength > p->size)
1660 return -EBADMSG;
1661
1662 offset = p->rindex;
1663
1664 switch (rr->key->type) {
1665
1666 case DNS_TYPE_SRV:
1667 r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1668 if (r < 0)
1669 return r;
1670 r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1671 if (r < 0)
1672 return r;
1673 r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1674 if (r < 0)
1675 return r;
1676 r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
1677 break;
1678
1679 case DNS_TYPE_PTR:
1680 case DNS_TYPE_NS:
1681 case DNS_TYPE_CNAME:
1682 case DNS_TYPE_DNAME:
1683 r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
1684 break;
1685
1686 case DNS_TYPE_HINFO:
1687 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1688 if (r < 0)
1689 return r;
1690
1691 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1692 break;
1693
1694 case DNS_TYPE_SPF: /* exactly the same as TXT */
1695 case DNS_TYPE_TXT:
1696 if (rdlength <= 0) {
1697 r = dns_txt_item_new_empty(&rr->txt.items);
1698 if (r < 0)
1699 return r;
1700 } else {
1701 DnsTxtItem *last = NULL;
1702
1703 while (p->rindex < offset + rdlength) {
1704 DnsTxtItem *i;
1705 const void *data;
1706 size_t sz;
1707
1708 r = dns_packet_read_raw_string(p, &data, &sz, NULL);
1709 if (r < 0)
1710 return r;
1711
1712 i = malloc0(offsetof(DnsTxtItem, data) + sz + 1); /* extra NUL byte at the end */
1713 if (!i)
1714 return -ENOMEM;
1715
1716 memcpy(i->data, data, sz);
1717 i->length = sz;
1718
1719 LIST_INSERT_AFTER(items, rr->txt.items, last, i);
1720 last = i;
1721 }
1722 }
1723
1724 r = 0;
1725 break;
1726
1727 case DNS_TYPE_A:
1728 r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
1729 break;
1730
1731 case DNS_TYPE_AAAA:
1732 r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
1733 break;
1734
1735 case DNS_TYPE_SOA:
1736 r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
1737 if (r < 0)
1738 return r;
1739
1740 r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
1741 if (r < 0)
1742 return r;
1743
1744 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1745 if (r < 0)
1746 return r;
1747
1748 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1749 if (r < 0)
1750 return r;
1751
1752 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1753 if (r < 0)
1754 return r;
1755
1756 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1757 if (r < 0)
1758 return r;
1759
1760 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1761 break;
1762
1763 case DNS_TYPE_MX:
1764 r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
1765 if (r < 0)
1766 return r;
1767
1768 r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
1769 break;
1770
1771 case DNS_TYPE_LOC: {
1772 uint8_t t;
1773 size_t pos;
1774
1775 r = dns_packet_read_uint8(p, &t, &pos);
1776 if (r < 0)
1777 return r;
1778
1779 if (t == 0) {
1780 rr->loc.version = t;
1781
1782 r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
1783 if (r < 0)
1784 return r;
1785
1786 if (!loc_size_ok(rr->loc.size))
1787 return -EBADMSG;
1788
1789 r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
1790 if (r < 0)
1791 return r;
1792
1793 if (!loc_size_ok(rr->loc.horiz_pre))
1794 return -EBADMSG;
1795
1796 r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
1797 if (r < 0)
1798 return r;
1799
1800 if (!loc_size_ok(rr->loc.vert_pre))
1801 return -EBADMSG;
1802
1803 r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
1804 if (r < 0)
1805 return r;
1806
1807 r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
1808 if (r < 0)
1809 return r;
1810
1811 r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
1812 if (r < 0)
1813 return r;
1814
1815 break;
1816 } else {
1817 dns_packet_rewind(p, pos);
1818 rr->unparseable = true;
1819 goto unparseable;
1820 }
1821 }
1822
1823 case DNS_TYPE_DS:
1824 r = dns_packet_read_uint16(p, &rr->ds.key_tag, NULL);
1825 if (r < 0)
1826 return r;
1827
1828 r = dns_packet_read_uint8(p, &rr->ds.algorithm, NULL);
1829 if (r < 0)
1830 return r;
1831
1832 r = dns_packet_read_uint8(p, &rr->ds.digest_type, NULL);
1833 if (r < 0)
1834 return r;
1835
1836 if (rdlength < 4)
1837 return -EBADMSG;
1838
1839 r = dns_packet_read_memdup(p, rdlength - 4,
1840 &rr->ds.digest, &rr->ds.digest_size,
1841 NULL);
1842 if (r < 0)
1843 return r;
1844
1845 if (rr->ds.digest_size <= 0)
1846 /* the accepted size depends on the algorithm, but for now
1847 just ensure that the value is greater than zero */
1848 return -EBADMSG;
1849
1850 break;
1851
1852 case DNS_TYPE_SSHFP:
1853 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1854 if (r < 0)
1855 return r;
1856
1857 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1858 if (r < 0)
1859 return r;
1860
1861 if (rdlength < 2)
1862 return -EBADMSG;
1863
1864 r = dns_packet_read_memdup(p, rdlength - 2,
1865 &rr->sshfp.fingerprint, &rr->sshfp.fingerprint_size,
1866 NULL);
1867
1868 if (rr->sshfp.fingerprint_size <= 0)
1869 /* the accepted size depends on the algorithm, but for now
1870 just ensure that the value is greater than zero */
1871 return -EBADMSG;
1872
1873 break;
1874
1875 case DNS_TYPE_DNSKEY:
1876 r = dns_packet_read_uint16(p, &rr->dnskey.flags, NULL);
1877 if (r < 0)
1878 return r;
1879
1880 r = dns_packet_read_uint8(p, &rr->dnskey.protocol, NULL);
1881 if (r < 0)
1882 return r;
1883
1884 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1885 if (r < 0)
1886 return r;
1887
1888 if (rdlength < 4)
1889 return -EBADMSG;
1890
1891 r = dns_packet_read_memdup(p, rdlength - 4,
1892 &rr->dnskey.key, &rr->dnskey.key_size,
1893 NULL);
1894
1895 if (rr->dnskey.key_size <= 0)
1896 /* the accepted size depends on the algorithm, but for now
1897 just ensure that the value is greater than zero */
1898 return -EBADMSG;
1899
1900 break;
1901
1902 case DNS_TYPE_RRSIG:
1903 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
1904 if (r < 0)
1905 return r;
1906
1907 r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
1908 if (r < 0)
1909 return r;
1910
1911 r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
1912 if (r < 0)
1913 return r;
1914
1915 r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
1916 if (r < 0)
1917 return r;
1918
1919 r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
1920 if (r < 0)
1921 return r;
1922
1923 r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
1924 if (r < 0)
1925 return r;
1926
1927 r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
1928 if (r < 0)
1929 return r;
1930
1931 r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
1932 if (r < 0)
1933 return r;
1934
1935 if (rdlength + offset < p->rindex)
1936 return -EBADMSG;
1937
1938 r = dns_packet_read_memdup(p, offset + rdlength - p->rindex,
1939 &rr->rrsig.signature, &rr->rrsig.signature_size,
1940 NULL);
1941
1942 if (rr->rrsig.signature_size <= 0)
1943 /* the accepted size depends on the algorithm, but for now
1944 just ensure that the value is greater than zero */
1945 return -EBADMSG;
1946
1947 break;
1948
1949 case DNS_TYPE_NSEC: {
1950
1951 /*
1952 * RFC6762, section 18.14 explicitly states mDNS should use name compression.
1953 * This contradicts RFC3845, section 2.1.1
1954 */
1955
1956 bool allow_compressed = p->protocol == DNS_PROTOCOL_MDNS;
1957
1958 r = dns_packet_read_name(p, &rr->nsec.next_domain_name, allow_compressed, NULL);
1959 if (r < 0)
1960 return r;
1961
1962 r = dns_packet_read_type_windows(p, &rr->nsec.types, offset + rdlength - p->rindex, NULL);
1963
1964 /* We accept empty NSEC bitmaps. The bit indicating the presence of the NSEC record itself
1965 * is redundant and in e.g., RFC4956 this fact is used to define a use for NSEC records
1966 * without the NSEC bit set. */
1967
1968 break;
1969 }
1970 case DNS_TYPE_NSEC3: {
1971 uint8_t size;
1972
1973 r = dns_packet_read_uint8(p, &rr->nsec3.algorithm, NULL);
1974 if (r < 0)
1975 return r;
1976
1977 r = dns_packet_read_uint8(p, &rr->nsec3.flags, NULL);
1978 if (r < 0)
1979 return r;
1980
1981 r = dns_packet_read_uint16(p, &rr->nsec3.iterations, NULL);
1982 if (r < 0)
1983 return r;
1984
1985 /* this may be zero */
1986 r = dns_packet_read_uint8(p, &size, NULL);
1987 if (r < 0)
1988 return r;
1989
1990 r = dns_packet_read_memdup(p, size, &rr->nsec3.salt, &rr->nsec3.salt_size, NULL);
1991 if (r < 0)
1992 return r;
1993
1994 r = dns_packet_read_uint8(p, &size, NULL);
1995 if (r < 0)
1996 return r;
1997
1998 if (size <= 0)
1999 return -EBADMSG;
2000
2001 r = dns_packet_read_memdup(p, size,
2002 &rr->nsec3.next_hashed_name, &rr->nsec3.next_hashed_name_size,
2003 NULL);
2004 if (r < 0)
2005 return r;
2006
2007 r = dns_packet_read_type_windows(p, &rr->nsec3.types, offset + rdlength - p->rindex, NULL);
2008
2009 /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
2010
2011 break;
2012 }
2013
2014 case DNS_TYPE_TLSA:
2015 r = dns_packet_read_uint8(p, &rr->tlsa.cert_usage, NULL);
2016 if (r < 0)
2017 return r;
2018
2019 r = dns_packet_read_uint8(p, &rr->tlsa.selector, NULL);
2020 if (r < 0)
2021 return r;
2022
2023 r = dns_packet_read_uint8(p, &rr->tlsa.matching_type, NULL);
2024 if (r < 0)
2025 return r;
2026
2027 if (rdlength < 3)
2028 return -EBADMSG;
2029
2030 r = dns_packet_read_memdup(p, rdlength - 3,
2031 &rr->tlsa.data, &rr->tlsa.data_size,
2032 NULL);
2033
2034 if (rr->tlsa.data_size <= 0)
2035 /* the accepted size depends on the algorithm, but for now
2036 just ensure that the value is greater than zero */
2037 return -EBADMSG;
2038
2039 break;
2040
2041 case DNS_TYPE_CAA:
2042 r = dns_packet_read_uint8(p, &rr->caa.flags, NULL);
2043 if (r < 0)
2044 return r;
2045
2046 r = dns_packet_read_string(p, &rr->caa.tag, NULL);
2047 if (r < 0)
2048 return r;
2049
2050 if (rdlength + offset < p->rindex)
2051 return -EBADMSG;
2052
2053 r = dns_packet_read_memdup(p,
2054 rdlength + offset - p->rindex,
2055 &rr->caa.value, &rr->caa.value_size, NULL);
2056
2057 break;
2058
2059 case DNS_TYPE_OPT: /* we only care about the header of OPT for now. */
2060 case DNS_TYPE_OPENPGPKEY:
2061 default:
2062 unparseable:
2063 r = dns_packet_read_memdup(p, rdlength, &rr->generic.data, &rr->generic.data_size, NULL);
2064
2065 break;
2066 }
2067 if (r < 0)
2068 return r;
2069 if (p->rindex != offset + rdlength)
2070 return -EBADMSG;
2071
2072 *ret = TAKE_PTR(rr);
2073
2074 if (ret_cache_flush)
2075 *ret_cache_flush = cache_flush;
2076 if (start)
2077 *start = rewinder.saved_rindex;
2078 CANCEL_REWINDER(rewinder);
2079
2080 return 0;
2081 }
2082
2083 static bool opt_is_good(DnsResourceRecord *rr, bool *rfc6975) {
2084 const uint8_t* p;
2085 bool found_dau_dhu_n3u = false;
2086 size_t l;
2087
2088 /* Checks whether the specified OPT RR is well-formed and whether it contains RFC6975 data (which is not OK in
2089 * a reply). */
2090
2091 assert(rr);
2092 assert(rr->key->type == DNS_TYPE_OPT);
2093
2094 /* Check that the version is 0 */
2095 if (((rr->ttl >> 16) & UINT32_C(0xFF)) != 0) {
2096 *rfc6975 = false;
2097 return true; /* if it's not version 0, it's OK, but we will ignore the OPT field contents */
2098 }
2099
2100 p = rr->opt.data;
2101 l = rr->opt.data_size;
2102 while (l > 0) {
2103 uint16_t option_code, option_length;
2104
2105 /* At least four bytes for OPTION-CODE and OPTION-LENGTH are required */
2106 if (l < 4U)
2107 return false;
2108
2109 option_code = unaligned_read_be16(p);
2110 option_length = unaligned_read_be16(p + 2);
2111
2112 if (l < option_length + 4U)
2113 return false;
2114
2115 /* RFC 6975 DAU, DHU or N3U fields found. */
2116 if (IN_SET(option_code, 5, 6, 7))
2117 found_dau_dhu_n3u = true;
2118
2119 p += option_length + 4U;
2120 l -= option_length + 4U;
2121 }
2122
2123 *rfc6975 = found_dau_dhu_n3u;
2124 return true;
2125 }
2126
2127 static int dns_packet_extract_question(DnsPacket *p, DnsQuestion **ret_question) {
2128 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
2129 unsigned n, i;
2130 int r;
2131
2132 n = DNS_PACKET_QDCOUNT(p);
2133 if (n > 0) {
2134 question = dns_question_new(n);
2135 if (!question)
2136 return -ENOMEM;
2137
2138 _cleanup_set_free_ Set *keys = NULL; /* references to keys are kept by Question */
2139
2140 keys = set_new(&dns_resource_key_hash_ops);
2141 if (!keys)
2142 return log_oom();
2143
2144 r = set_reserve(keys, n * 2); /* Higher multipliers give slightly higher efficiency through
2145 * hash collisions, but the gains quickly drop of after 2. */
2146 if (r < 0)
2147 return r;
2148
2149 for (i = 0; i < n; i++) {
2150 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
2151 bool cache_flush;
2152
2153 r = dns_packet_read_key(p, &key, &cache_flush, NULL);
2154 if (r < 0)
2155 return r;
2156
2157 if (cache_flush)
2158 return -EBADMSG;
2159
2160 if (!dns_type_is_valid_query(key->type))
2161 return -EBADMSG;
2162
2163 r = set_put(keys, key);
2164 if (r < 0)
2165 return r;
2166 if (r == 0)
2167 /* Already in the Question, let's skip */
2168 continue;
2169
2170 r = dns_question_add_raw(question, key);
2171 if (r < 0)
2172 return r;
2173 }
2174 }
2175
2176 *ret_question = TAKE_PTR(question);
2177
2178 return 0;
2179 }
2180
2181 static int dns_packet_extract_answer(DnsPacket *p, DnsAnswer **ret_answer) {
2182 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
2183 unsigned n, i;
2184 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *previous = NULL;
2185 bool bad_opt = false;
2186 int r;
2187
2188 n = DNS_PACKET_RRCOUNT(p);
2189 if (n == 0)
2190 return 0;
2191
2192 answer = dns_answer_new(n);
2193 if (!answer)
2194 return -ENOMEM;
2195
2196 for (i = 0; i < n; i++) {
2197 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
2198 bool cache_flush = false;
2199
2200 r = dns_packet_read_rr(p, &rr, &cache_flush, NULL);
2201 if (r < 0)
2202 return r;
2203
2204 /* Try to reduce memory usage a bit */
2205 if (previous)
2206 dns_resource_key_reduce(&rr->key, &previous->key);
2207
2208 if (rr->key->type == DNS_TYPE_OPT) {
2209 bool has_rfc6975;
2210
2211 if (p->opt || bad_opt) {
2212 /* Multiple OPT RRs? if so, let's ignore all, because there's
2213 * something wrong with the server, and if one is valid we wouldn't
2214 * know which one. */
2215 log_debug("Multiple OPT RRs detected, ignoring all.");
2216 bad_opt = true;
2217 continue;
2218 }
2219
2220 if (!dns_name_is_root(dns_resource_key_name(rr->key))) {
2221 /* If the OPT RR is not owned by the root domain, then it is bad,
2222 * let's ignore it. */
2223 log_debug("OPT RR is not owned by root domain, ignoring.");
2224 bad_opt = true;
2225 continue;
2226 }
2227
2228 if (i < DNS_PACKET_ANCOUNT(p) + DNS_PACKET_NSCOUNT(p)) {
2229 /* OPT RR is in the wrong section? Some Belkin routers do this. This
2230 * is a hint the EDNS implementation is borked, like the Belkin one
2231 * is, hence ignore it. */
2232 log_debug("OPT RR in wrong section, ignoring.");
2233 bad_opt = true;
2234 continue;
2235 }
2236
2237 if (!opt_is_good(rr, &has_rfc6975)) {
2238 log_debug("Malformed OPT RR, ignoring.");
2239 bad_opt = true;
2240 continue;
2241 }
2242
2243 if (DNS_PACKET_QR(p)) {
2244 /* Additional checks for responses */
2245
2246 if (!DNS_RESOURCE_RECORD_OPT_VERSION_SUPPORTED(rr)) {
2247 /* If this is a reply and we don't know the EDNS version
2248 * then something is weird... */
2249 log_debug("EDNS version newer that our request, bad server.");
2250 return -EBADMSG;
2251 }
2252
2253 if (has_rfc6975) {
2254 /* If the OPT RR contains RFC6975 algorithm data, then this
2255 * is indication that the server just copied the OPT it got
2256 * from us (which contained that data) back into the reply.
2257 * If so, then it doesn't properly support EDNS, as RFC6975
2258 * makes it very clear that the algorithm data should only
2259 * be contained in questions, never in replies. Crappy
2260 * Belkin routers copy the OPT data for example, hence let's
2261 * detect this so that we downgrade early. */
2262 log_debug("OPT RR contains RFC6975 data, ignoring.");
2263 bad_opt = true;
2264 continue;
2265 }
2266 }
2267
2268 p->opt = dns_resource_record_ref(rr);
2269 } else {
2270 /* According to RFC 4795, section 2.9. only the RRs from the Answer section
2271 * shall be cached. Hence mark only those RRs as cacheable by default, but
2272 * not the ones from the Additional or Authority sections. */
2273 DnsAnswerFlags flags =
2274 (i < DNS_PACKET_ANCOUNT(p) ? DNS_ANSWER_CACHEABLE : 0) |
2275 (p->protocol == DNS_PROTOCOL_MDNS && !cache_flush ? DNS_ANSWER_SHARED_OWNER : 0);
2276
2277 r = dns_answer_add(answer, rr, p->ifindex, flags);
2278 if (r < 0)
2279 return r;
2280 }
2281
2282 /* Remember this RR, so that we potentically can merge it's ->key object with the
2283 * next RR. Note that we only do this if we actually decided to keep the RR around.
2284 */
2285 dns_resource_record_unref(previous);
2286 previous = dns_resource_record_ref(rr);
2287 }
2288
2289 if (bad_opt)
2290 p->opt = dns_resource_record_unref(p->opt);
2291
2292 *ret_answer = TAKE_PTR(answer);
2293
2294 return 0;
2295 }
2296
2297 int dns_packet_extract(DnsPacket *p) {
2298 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
2299 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
2300 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = {};
2301 int r;
2302
2303 if (p->extracted)
2304 return 0;
2305
2306 INIT_REWINDER(rewinder, p);
2307 dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
2308
2309 r = dns_packet_extract_question(p, &question);
2310 if (r < 0)
2311 return r;
2312
2313 r = dns_packet_extract_answer(p, &answer);
2314 if (r < 0)
2315 return r;
2316
2317 p->question = TAKE_PTR(question);
2318 p->answer = TAKE_PTR(answer);
2319
2320 p->extracted = true;
2321
2322 /* no CANCEL, always rewind */
2323 return 0;
2324 }
2325
2326 int dns_packet_is_reply_for(DnsPacket *p, const DnsResourceKey *key) {
2327 int r;
2328
2329 assert(p);
2330 assert(key);
2331
2332 /* Checks if the specified packet is a reply for the specified
2333 * key and the specified key is the only one in the question
2334 * section. */
2335
2336 if (DNS_PACKET_QR(p) != 1)
2337 return 0;
2338
2339 /* Let's unpack the packet, if that hasn't happened yet. */
2340 r = dns_packet_extract(p);
2341 if (r < 0)
2342 return r;
2343
2344 if (!p->question)
2345 return 0;
2346
2347 if (p->question->n_keys != 1)
2348 return 0;
2349
2350 return dns_resource_key_equal(p->question->keys[0], key);
2351 }
2352
2353 static void dns_packet_hash_func(const DnsPacket *s, struct siphash *state) {
2354 assert(s);
2355
2356 siphash24_compress(&s->size, sizeof(s->size), state);
2357 siphash24_compress(DNS_PACKET_DATA((DnsPacket*) s), s->size, state);
2358 }
2359
2360 static int dns_packet_compare_func(const DnsPacket *x, const DnsPacket *y) {
2361 int r;
2362
2363 r = CMP(x->size, y->size);
2364 if (r != 0)
2365 return r;
2366
2367 return memcmp(DNS_PACKET_DATA((DnsPacket*) x), DNS_PACKET_DATA((DnsPacket*) y), x->size);
2368 }
2369
2370 DEFINE_HASH_OPS(dns_packet_hash_ops, DnsPacket, dns_packet_hash_func, dns_packet_compare_func);
2371
2372 static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
2373 [DNS_RCODE_SUCCESS] = "SUCCESS",
2374 [DNS_RCODE_FORMERR] = "FORMERR",
2375 [DNS_RCODE_SERVFAIL] = "SERVFAIL",
2376 [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
2377 [DNS_RCODE_NOTIMP] = "NOTIMP",
2378 [DNS_RCODE_REFUSED] = "REFUSED",
2379 [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
2380 [DNS_RCODE_YXRRSET] = "YRRSET",
2381 [DNS_RCODE_NXRRSET] = "NXRRSET",
2382 [DNS_RCODE_NOTAUTH] = "NOTAUTH",
2383 [DNS_RCODE_NOTZONE] = "NOTZONE",
2384 [DNS_RCODE_BADVERS] = "BADVERS",
2385 [DNS_RCODE_BADKEY] = "BADKEY",
2386 [DNS_RCODE_BADTIME] = "BADTIME",
2387 [DNS_RCODE_BADMODE] = "BADMODE",
2388 [DNS_RCODE_BADNAME] = "BADNAME",
2389 [DNS_RCODE_BADALG] = "BADALG",
2390 [DNS_RCODE_BADTRUNC] = "BADTRUNC",
2391 [DNS_RCODE_BADCOOKIE] = "BADCOOKIE",
2392 };
2393 DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
2394
2395 static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
2396 [DNS_PROTOCOL_DNS] = "dns",
2397 [DNS_PROTOCOL_MDNS] = "mdns",
2398 [DNS_PROTOCOL_LLMNR] = "llmnr",
2399 };
2400 DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);