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