GNUnet 0.28.0
 
Loading...
Searching...
No Matches
dnsparser.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 2010-2014, 2018 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#if HAVE_LIBIDN2
31#if HAVE_IDN2_H
32#include <idn2.h>
33#elif HAVE_IDN2_IDN2_H
34#include <idn2/idn2.h>
35#endif
36#elif HAVE_LIBIDN
37#if HAVE_IDNA_H
38#include <idna.h>
39#elif HAVE_IDN_IDNA_H
40#include <idn/idna.h>
41#endif
42#endif
43
54{
55 char *output;
56 size_t slen;
57
58 if (NULL != strchr (label, '.'))
59 return GNUNET_SYSERR; /* not a label! Did you mean GNUNET_DNSPARSER_check_name? */
60 if (0 == strcmp (label, "@")) /* '@' is reserved for the empty label, see #GNUNET_GNS_EMPTY_LABEL_AT */
61 return GNUNET_SYSERR;
62 if (IDNA_SUCCESS != idna_to_ascii_8z (label, &output, IDNA_ALLOW_UNASSIGNED))
63 return GNUNET_SYSERR;
64 slen = strlen (output);
65 free (output);
66 return (slen > 63) ? GNUNET_SYSERR : GNUNET_OK;
67}
68
69
80{
81 {
82 char *ldup;
83 char *saveptr;
84
85 ldup = GNUNET_strdup (name);
86 for (const char *tok = strtok_r (ldup,
87 ".",
88 &saveptr);
89 NULL != tok;
90 tok = strtok_r (NULL,
91 ".",
92 &saveptr))
93 {
94 if (GNUNET_OK !=
96 {
97 GNUNET_free (ldup);
98 return GNUNET_SYSERR;
99 }
100 }
101 GNUNET_free (ldup);
102 }
103 {
104 char *output;
105 size_t slen;
106
107 if (IDNA_SUCCESS !=
108 idna_to_ascii_8z (name,
109 &output,
110 IDNA_ALLOW_UNASSIGNED))
111 return GNUNET_SYSERR;
112 slen = strlen (output);
113 free (output);
114 return (slen > 253) ? GNUNET_SYSERR : GNUNET_OK;
115 }
116}
117
118
124void
126{
127 if (NULL == soa)
128 return;
129 GNUNET_free (soa->mname);
130 GNUNET_free (soa->rname);
131 GNUNET_free (soa);
132}
133
134
140void
142{
143 if (NULL == cert)
144 return;
146 GNUNET_free (cert);
147}
148
149
155void
157{
158 if (NULL == srv)
159 return;
160 GNUNET_free (srv->target);
161 GNUNET_free (srv);
162}
163
164
170void
172{
173 if (NULL == uri)
174 return;
175 GNUNET_free (uri->target);
177}
178
179
185void
187{
188 if (NULL == mx)
189 return;
190 GNUNET_free (mx->mxhost);
191 GNUNET_free (mx);
192}
193
194
200void
202{
203 GNUNET_free (r->name);
204 switch (r->type)
205 {
208 break;
209
212 break;
213
216 break;
217
220 break;
221
224 break;
225
231 break;
232
233 default:
235 break;
236 }
237}
238
239
250static char *
251parse_name (const char *udp_payload,
252 size_t udp_payload_length,
253 size_t *off,
254 unsigned int depth)
255{
256 const uint8_t *input = (const uint8_t *) udp_payload;
257 char *ret;
258 char *tmp;
259 char *xstr;
260 uint8_t len;
261 size_t xoff;
262 char *utf8;
263 Idna_rc rc;
264
265 ret = GNUNET_strdup ("");
266 while (1)
267 {
268 if (*off >= udp_payload_length)
269 {
270 GNUNET_break_op (0);
271 goto error;
272 }
273 len = input[*off];
274 if (0 == len)
275 {
276 (*off)++;
277 break;
278 }
279 if (len < 64)
280 {
281 if (*off + 1 + len > udp_payload_length)
282 {
283 GNUNET_break_op (0);
284 goto error;
285 }
286 GNUNET_asprintf (&tmp, "%.*s", (int) len, &udp_payload[*off + 1]);
287 if (IDNA_SUCCESS !=
288 (rc = idna_to_unicode_8z8z (tmp, &utf8, IDNA_ALLOW_UNASSIGNED)))
289 {
291 _ ("Failed to convert DNS IDNA name `%s' to UTF-8: %s\n"),
292 tmp,
293 idna_strerror (rc));
294 GNUNET_free (tmp);
295 GNUNET_asprintf (&tmp,
296 "%s%.*s.",
297 ret,
298 (int) len,
299 &udp_payload[*off + 1]);
300 }
301 else
302 {
303 GNUNET_free (tmp);
304 GNUNET_asprintf (&tmp, "%s%s.", ret, utf8);
305 free (utf8);
306 }
308 ret = tmp;
309 *off += 1 + len;
310 }
311 else if ((64 | 128) == (len & (64 | 128)))
312 {
313 if (depth > 32)
314 {
315 GNUNET_break_op (0);
316 goto error; /* hard bound on stack to prevent "infinite" recursion, disallow! */
317 }
318 /* pointer to string */
319 if (*off + 1 > udp_payload_length)
320 {
321 GNUNET_break_op (0);
322 goto error;
323 }
324 xoff = ((len - (64 | 128)) << 8) + input[*off + 1];
325 xstr = parse_name (udp_payload, udp_payload_length, &xoff, depth + 1);
326 if (NULL == xstr)
327 {
328 GNUNET_break_op (0);
329 goto error;
330 }
331 GNUNET_asprintf (&tmp, "%s%s.", ret, xstr);
333 GNUNET_free (xstr);
334 ret = tmp;
335 if (strlen (ret) > udp_payload_length)
336 {
337 GNUNET_break_op (0);
338 goto error; /* we are looping (building an infinite string) */
339 }
340 *off += 2;
341 /* pointers always terminate names */
342 break;
343 }
344 else
345 {
346 /* neither pointer nor inline string, not supported... */
347 GNUNET_break_op (0);
348 goto error;
349 }
350 }
351 if (0 < strlen (ret))
352 ret[strlen (ret) - 1] = '\0'; /* eat tailing '.' */
353 return ret;
354error:
355 GNUNET_break_op (0);
357 return NULL;
358}
359
360
370char *
371GNUNET_DNSPARSER_parse_name (const char *udp_payload,
372 size_t udp_payload_length,
373 size_t *off)
374{
375 return parse_name (udp_payload, udp_payload_length, off, 0);
376}
377
378
389int
390GNUNET_DNSPARSER_parse_query (const char *udp_payload,
391 size_t udp_payload_length,
392 size_t *off,
394{
395 char *name;
396 struct GNUNET_TUN_DnsQueryLine ql;
397
398 name = GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
399 if (NULL == name)
400 {
401 GNUNET_break_op (0);
402 return GNUNET_SYSERR;
403 }
404 q->name = name;
405 if (*off + sizeof(struct GNUNET_TUN_DnsQueryLine) > udp_payload_length)
406 {
407 GNUNET_break_op (0);
408 return GNUNET_SYSERR;
409 }
410 GNUNET_memcpy (&ql, &udp_payload[*off], sizeof(ql));
411 *off += sizeof(ql);
412 q->type = ntohs (ql.type);
413 q->dns_traffic_class = ntohs (ql.dns_traffic_class);
414 return GNUNET_OK;
415}
416
417
428GNUNET_DNSPARSER_parse_soa (const char *udp_payload,
429 size_t udp_payload_length,
430 size_t *off)
431{
432 struct GNUNET_DNSPARSER_SoaRecord *soa;
433 struct GNUNET_TUN_DnsSoaRecord soa_bin;
434 size_t old_off;
435
436 old_off = *off;
438 soa->mname =
439 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
440 soa->rname =
441 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
442 if ((NULL == soa->mname) || (NULL == soa->rname) ||
443 (*off + sizeof(struct GNUNET_TUN_DnsSoaRecord) > udp_payload_length))
444 {
445 GNUNET_break_op (0);
447 *off = old_off;
448 return NULL;
449 }
450 GNUNET_memcpy (&soa_bin,
451 &udp_payload[*off],
452 sizeof(struct GNUNET_TUN_DnsSoaRecord));
453 soa->serial = ntohl (soa_bin.serial);
454 soa->refresh = ntohl (soa_bin.refresh);
455 soa->retry = ntohl (soa_bin.retry);
456 soa->expire = ntohl (soa_bin.expire);
457 soa->minimum_ttl = ntohl (soa_bin.minimum);
458 (*off) += sizeof(struct GNUNET_TUN_DnsSoaRecord);
459 return soa;
460}
461
462
473GNUNET_DNSPARSER_parse_mx (const char *udp_payload,
474 size_t udp_payload_length,
475 size_t *off)
476{
477 struct GNUNET_DNSPARSER_MxRecord *mx;
478 uint16_t mxpref;
479 size_t old_off;
480
481 old_off = *off;
482 if (*off + sizeof(uint16_t) > udp_payload_length)
483 {
484 GNUNET_break_op (0);
485 return NULL;
486 }
487 GNUNET_memcpy (&mxpref, &udp_payload[*off], sizeof(uint16_t));
488 (*off) += sizeof(uint16_t);
490 mx->preference = ntohs (mxpref);
491 mx->mxhost =
492 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
493 if (NULL == mx->mxhost)
494 {
495 GNUNET_break_op (0);
497 *off = old_off;
498 return NULL;
499 }
500 return mx;
501}
502
503
514GNUNET_DNSPARSER_parse_srv (const char *udp_payload,
515 size_t udp_payload_length,
516 size_t *off)
517{
518 struct GNUNET_DNSPARSER_SrvRecord *srv;
519 struct GNUNET_TUN_DnsSrvRecord srv_bin;
520 size_t old_off;
521
522 old_off = *off;
523 if (*off + sizeof(struct GNUNET_TUN_DnsSrvRecord) > udp_payload_length)
524 return NULL;
525 GNUNET_memcpy (&srv_bin,
526 &udp_payload[*off],
527 sizeof(struct GNUNET_TUN_DnsSrvRecord));
528 (*off) += sizeof(struct GNUNET_TUN_DnsSrvRecord);
530 srv->priority = ntohs (srv_bin.prio);
531 srv->weight = ntohs (srv_bin.weight);
532 srv->port = ntohs (srv_bin.port);
533 srv->target =
534 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
535 if (NULL == srv->target)
536 {
538 *off = old_off;
539 return NULL;
540 }
541 return srv;
542}
543
544
555GNUNET_DNSPARSER_parse_uri (const char *udp_payload,
556 size_t udp_payload_length,
557 size_t *off)
558{
560 struct GNUNET_TUN_DnsUriRecord uri_bin;
561 size_t old_off;
562 int max_len;
563 int len;
564
565 old_off = *off;
566 if (*off + sizeof(struct GNUNET_TUN_DnsUriRecord) > udp_payload_length)
567 return NULL;
568 GNUNET_memcpy (&uri_bin,
569 &udp_payload[*off],
570 sizeof(struct GNUNET_TUN_DnsUriRecord));
571 (*off) += sizeof(struct GNUNET_TUN_DnsUriRecord);
573 uri->priority = ntohs (uri_bin.prio);
574 uri->weight = ntohs (uri_bin.weight);
575 max_len = udp_payload_length - *off - sizeof(struct GNUNET_TUN_DnsUriRecord);
576 len = GNUNET_asprintf (&(uri->target), "%.*s", max_len,
577 &udp_payload[*off]);
578 (*off) += len;
579 if (NULL == uri->target)
580 {
582 *off = old_off;
583 return NULL;
584 }
585 return uri;
586}
587
588
599GNUNET_DNSPARSER_parse_cert (const char *udp_payload,
600 size_t udp_payload_length,
601 size_t *off)
602{
603 struct GNUNET_DNSPARSER_CertRecord *cert;
604 struct GNUNET_TUN_DnsCertRecord dcert;
605
606 if (*off + sizeof(struct GNUNET_TUN_DnsCertRecord) >= udp_payload_length)
607 {
608 GNUNET_break_op (0);
609 return NULL;
610 }
611 GNUNET_memcpy (&dcert,
612 &udp_payload[*off],
613 sizeof(struct GNUNET_TUN_DnsCertRecord));
614 (*off) += sizeof(struct GNUNET_TUN_DnsCertRecord);
616 cert->cert_type = ntohs (dcert.cert_type);
617 cert->cert_tag = ntohs (dcert.cert_tag);
618 cert->algorithm = dcert.algorithm;
619 cert->certificate_size = udp_payload_length - (*off);
622 &udp_payload[*off],
623 cert->certificate_size);
624 (*off) += cert->certificate_size;
625 return cert;
626}
627
628
639int
640GNUNET_DNSPARSER_parse_record (const char *udp_payload,
641 size_t udp_payload_length,
642 size_t *off,
643 struct GNUNET_DNSPARSER_Record *r)
644{
645 char *name;
646 struct GNUNET_TUN_DnsRecordLine rl;
647 size_t old_off;
648 uint16_t data_len;
649
650 name = GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
651 if (NULL == name)
652 {
653 GNUNET_break_op (0);
654 return GNUNET_SYSERR;
655 }
656 r->name = name;
657 if (*off + sizeof(struct GNUNET_TUN_DnsRecordLine) > udp_payload_length)
658 {
659 GNUNET_break_op (0);
660 return GNUNET_SYSERR;
661 }
662 GNUNET_memcpy (&rl, &udp_payload[*off], sizeof(rl));
663 (*off) += sizeof(rl);
664 r->type = ntohs (rl.type);
665 r->dns_traffic_class = ntohs (rl.dns_traffic_class);
668 data_len = ntohs (rl.data_len);
669 if (*off + data_len > udp_payload_length)
670 {
671 GNUNET_break_op (0);
672 return GNUNET_SYSERR;
673 }
674 old_off = *off;
675 switch (r->type)
676 {
681 r->data.hostname =
682 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
683 if ((NULL == r->data.hostname) || (old_off + data_len != *off))
684 return GNUNET_SYSERR;
685 return GNUNET_OK;
686
688 r->data.soa =
689 GNUNET_DNSPARSER_parse_soa (udp_payload, udp_payload_length, off);
690 if ((NULL == r->data.soa) || (old_off + data_len != *off))
691 {
692 GNUNET_break_op (0);
693 return GNUNET_SYSERR;
694 }
695 return GNUNET_OK;
696
698 r->data.mx =
699 GNUNET_DNSPARSER_parse_mx (udp_payload, udp_payload_length, off);
700 if ((NULL == r->data.mx) || (old_off + data_len != *off))
701 {
702 GNUNET_break_op (0);
703 return GNUNET_SYSERR;
704 }
705 return GNUNET_OK;
706
708 r->data.srv =
709 GNUNET_DNSPARSER_parse_srv (udp_payload, udp_payload_length, off);
710 if ((NULL == r->data.srv) || (old_off + data_len != *off))
711 {
712 GNUNET_break_op (0);
713 return GNUNET_SYSERR;
714 }
715 return GNUNET_OK;
716
718 r->data.uri =
719 GNUNET_DNSPARSER_parse_uri (udp_payload, udp_payload_length, off);
720 if ((NULL == r->data.uri) || (old_off + data_len != *off))
721 {
722 GNUNET_break_op (0);
723 return GNUNET_SYSERR;
724 }
725 return GNUNET_OK;
727 r->data.cert =
728 GNUNET_DNSPARSER_parse_cert (udp_payload,
729 udp_payload_length,
730 off);
731 if ((NULL == r->data.cert) || (old_off + data_len != *off))
732 {
733 GNUNET_break_op (0);
734 return GNUNET_SYSERR;
735 }
736 default:
739 GNUNET_memcpy (r->data.raw.data, &udp_payload[*off], data_len);
740 break;
741 }
742 (*off) += data_len;
743 return GNUNET_OK;
744}
745
746
756GNUNET_DNSPARSER_parse (const char *udp_payload, size_t udp_payload_length)
757{
759 const struct GNUNET_TUN_DnsHeader *dns;
760 size_t off;
761 unsigned int n;
762
763 if (udp_payload_length < sizeof(struct GNUNET_TUN_DnsHeader))
764 return NULL;
765 dns = (const struct GNUNET_TUN_DnsHeader *) udp_payload;
766 off = sizeof(struct GNUNET_TUN_DnsHeader);
768 p->flags = dns->flags;
769 p->id = dns->id;
770 n = ntohs (dns->query_count);
771 if (n > 0)
772 {
773 p->queries = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Query);
774 p->num_queries = n;
775 for (unsigned int i = 0; i < n; i++)
776 if (GNUNET_OK != GNUNET_DNSPARSER_parse_query (udp_payload,
777 udp_payload_length,
778 &off,
779 &p->queries[i]))
780 goto error;
781 }
782 n = ntohs (dns->answer_rcount);
783 if (n > 0)
784 {
785 p->answers = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Record);
786 p->num_answers = n;
787 for (unsigned int i = 0; i < n; i++)
788 if (GNUNET_OK != GNUNET_DNSPARSER_parse_record (udp_payload,
789 udp_payload_length,
790 &off,
791 &p->answers[i]))
792 goto error;
793 }
794 n = ntohs (dns->authority_rcount);
795 if (n > 0)
796 {
797 p->authority_records = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Record);
798 p->num_authority_records = n;
799 for (unsigned int i = 0; i < n; i++)
800 if (GNUNET_OK != GNUNET_DNSPARSER_parse_record (udp_payload,
801 udp_payload_length,
802 &off,
803 &p->authority_records[i]))
804 goto error;
805 }
806 n = ntohs (dns->additional_rcount);
807 if (n > 0)
808 {
809 p->additional_records =
811 p->num_additional_records = n;
812 for (unsigned int i = 0; i < n; i++)
813 {
814 if (GNUNET_OK !=
816 udp_payload_length,
817 &off,
818 &p->additional_records[i]))
819 goto error;
820 }
821 }
822 return p;
823error:
824 GNUNET_break_op (0);
826 return NULL;
827}
828
829
838{
839 struct GNUNET_DNSPARSER_Record *dup = GNUNET_memdup (r, sizeof(*r));
840
841 dup->name = GNUNET_strdup (r->name);
842 switch (r->type)
843 {
849 break;
850 }
851
854 break;
855 }
856
859 break;
860 }
861
864 break;
865 }
866
869 break;
870 }
871
874 break;
875 }
876
877 default: {
879 r->data.raw.data_len);
880 }
881 }
882 return dup;
883}
884
885
894 const struct GNUNET_DNSPARSER_SoaRecord *r)
895{
896 struct GNUNET_DNSPARSER_SoaRecord *dup = GNUNET_memdup (r, sizeof(*r));
897
898 dup->mname = GNUNET_strdup (r->mname);
899 dup->rname = GNUNET_strdup (r->rname);
900 return dup;
901}
902
903
912 const struct GNUNET_DNSPARSER_CertRecord *r)
913{
914 struct GNUNET_DNSPARSER_CertRecord *dup = GNUNET_memdup (r, sizeof(*r));
915
918 return dup;
919}
920
921
930{
931 struct GNUNET_DNSPARSER_MxRecord *dup = GNUNET_memdup (r, sizeof(*r));
932
933 dup->mxhost = GNUNET_strdup (r->mxhost);
934 return dup;
935}
936
937
946 const struct GNUNET_DNSPARSER_SrvRecord *r)
947{
948 struct GNUNET_DNSPARSER_SrvRecord *dup = GNUNET_memdup (r, sizeof(*r));
949
950 dup->target = GNUNET_strdup (r->target);
951 return dup;
952}
953
954
963 const struct GNUNET_DNSPARSER_UriRecord *r)
964{
965 struct GNUNET_DNSPARSER_UriRecord *dup = GNUNET_memdup (r, sizeof(*r));
966
967 dup->target = GNUNET_strdup (r->target);
968 return dup;
969}
970
971
977void
979{
980 for (unsigned int i = 0; i < p->num_queries; i++)
981 GNUNET_free (p->queries[i].name);
982 GNUNET_free (p->queries);
983 for (unsigned int i = 0; i < p->num_answers; i++)
984 GNUNET_DNSPARSER_free_record (&p->answers[i]);
985 GNUNET_free (p->answers);
986 for (unsigned int i = 0; i < p->num_authority_records; i++)
987 GNUNET_DNSPARSER_free_record (&p->authority_records[i]);
988 GNUNET_free (p->authority_records);
989 for (unsigned int i = 0; i < p->num_additional_records; i++)
990 GNUNET_DNSPARSER_free_record (&p->additional_records[i]);
991 GNUNET_free (p->additional_records);
992 GNUNET_free (p);
993}
994
995
996/* ********************** DNS packet assembly code **************** */
997
998
1012int
1014 size_t dst_len,
1015 size_t *off,
1016 const char *name)
1017{
1018 const char *dot;
1019 const char *idna_name;
1020 char *idna_start;
1021 size_t start;
1022 size_t pos;
1023 size_t len;
1024 Idna_rc rc;
1025
1026 if (NULL == name)
1027 return GNUNET_SYSERR;
1028
1029 if (IDNA_SUCCESS !=
1030 (rc = idna_to_ascii_8z (name, &idna_start, IDNA_ALLOW_UNASSIGNED)))
1031 {
1033 _ (
1034 "Failed to convert UTF-8 name `%s' to DNS IDNA format: %s\n"),
1035 name,
1036 idna_strerror (rc));
1037 return GNUNET_NO;
1038 }
1039 idna_name = idna_start;
1040 GNUNET_assert (*off <= SIZE_MAX - strlen (idna_name) - 2);
1041 start = *off;
1042 if (start + strlen (idna_name) + 2 > dst_len)
1043 goto fail;
1044 pos = start;
1045 do
1046 {
1047 dot = strchr (idna_name, '.');
1048 if (NULL == dot)
1049 len = strlen (idna_name);
1050 else
1051 len = dot - idna_name;
1052 if (len == 0)
1053 break;
1054 if (len >= 64)
1055 {
1057 "Invalid DNS name `%s': label with %u characters encountered\n",
1058 name,
1059 (unsigned int) len);
1060 goto fail; /* label too long or empty */
1061 }
1062 dst[pos++] = (char) (uint8_t) len;
1063 GNUNET_memcpy (&dst[pos], idna_name, len);
1064 pos += len;
1065 idna_name += len + 1; /* also skip dot */
1066 }
1067 while (NULL != dot);
1068 dst[pos++] = '\0'; /* terminator */
1069 *off = pos;
1070 free (idna_start);
1071 return GNUNET_OK;
1072fail:
1073 free (idna_start);
1074 return GNUNET_NO;
1075}
1076
1077
1090int
1092 size_t dst_len,
1093 size_t *off,
1094 const struct GNUNET_DNSPARSER_Query *query)
1095{
1096 int ret;
1097 struct GNUNET_TUN_DnsQueryLine ql;
1098
1099 GNUNET_assert (dst_len >= sizeof (ql));
1101 dst_len - sizeof(ql),
1102 off,
1103 query->name);
1104 if (ret != GNUNET_OK)
1105 return ret;
1106 ql.type = htons (query->type);
1107 ql.dns_traffic_class = htons (query->dns_traffic_class);
1108 GNUNET_memcpy (&dst[*off], &ql, sizeof(ql));
1109 (*off) += sizeof(ql);
1110 return GNUNET_OK;
1111}
1112
1113
1126int
1128 size_t dst_len,
1129 size_t *off,
1130 const struct GNUNET_DNSPARSER_MxRecord *mx)
1131{
1132 uint16_t mxpref;
1133
1134 GNUNET_assert (*off <= SIZE_MAX - sizeof (uint16_t));
1135 if (*off + sizeof(uint16_t) > dst_len)
1136 return GNUNET_NO;
1137 mxpref = htons (mx->preference);
1138 GNUNET_memcpy (&dst[*off], &mxpref, sizeof(mxpref));
1139 (*off) += sizeof(mxpref);
1140 return GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, mx->mxhost);
1141}
1142
1143
1156int
1158 char *dst,
1159 size_t dst_len,
1160 size_t *off,
1161 const struct GNUNET_DNSPARSER_CertRecord *cert)
1162{
1163 struct GNUNET_TUN_DnsCertRecord dcert;
1164
1165#ifdef __clang__
1166#pragma clang diagnostic push
1167#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
1168#endif
1169 if ((cert->cert_type > UINT16_MAX) || (cert->algorithm > UINT8_MAX))
1170 {
1171 GNUNET_break (0);
1172 return GNUNET_SYSERR;
1173 }
1174#ifdef __clang__
1175#pragma clang diagnostic pop
1176#endif
1177 GNUNET_assert (*off <= SIZE_MAX - sizeof (dcert));
1178 GNUNET_assert (cert->certificate_size <= SIZE_MAX - *off - sizeof (dcert));
1179 if (*off + sizeof(dcert) + cert->certificate_size > dst_len)
1180 return GNUNET_NO;
1181 dcert.cert_type = htons ((uint16_t) cert->cert_type);
1182 dcert.cert_tag = htons ((uint16_t) cert->cert_tag);
1183 dcert.algorithm = (uint8_t) cert->algorithm;
1184 GNUNET_memcpy (&dst[*off], &dcert, sizeof(dcert));
1185 (*off) += sizeof(dcert);
1186 GNUNET_memcpy (&dst[*off], cert->certificate_data, cert->certificate_size);
1187 (*off) += cert->certificate_size;
1188 return GNUNET_OK;
1189}
1190
1191
1204int
1206 size_t dst_len,
1207 size_t *off,
1208 const struct GNUNET_DNSPARSER_SoaRecord *soa)
1209{
1210 struct GNUNET_TUN_DnsSoaRecord sd;
1211 int ret;
1212
1213 if ((GNUNET_OK !=
1214 (ret =
1215 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, soa->mname))) ||
1216 (GNUNET_OK !=
1217 (ret =
1218 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, soa->rname))))
1219 return ret;
1220 if (*off + sizeof(struct GNUNET_TUN_DnsSoaRecord) > dst_len)
1221 return GNUNET_NO;
1222 sd.serial = htonl (soa->serial);
1223 sd.refresh = htonl (soa->refresh);
1224 sd.retry = htonl (soa->retry);
1225 sd.expire = htonl (soa->expire);
1226 sd.minimum = htonl (soa->minimum_ttl);
1227 GNUNET_memcpy (&dst[*off], &sd, sizeof(sd));
1228 (*off) += sizeof(sd);
1229 return GNUNET_OK;
1230}
1231
1232
1245int
1247 size_t dst_len,
1248 size_t *off,
1249 const struct GNUNET_DNSPARSER_SrvRecord *srv)
1250{
1251 struct GNUNET_TUN_DnsSrvRecord sd;
1252 int ret;
1253
1254 GNUNET_assert (*off <= SIZE_MAX - sizeof (sd));
1255 if (*off + sizeof(sd) > dst_len)
1256 return GNUNET_NO;
1257 sd.prio = htons (srv->priority);
1258 sd.weight = htons (srv->weight);
1259 sd.port = htons (srv->port);
1260 GNUNET_memcpy (&dst[*off], &sd, sizeof(sd));
1261 (*off) += sizeof(sd);
1262 if (GNUNET_OK !=
1263 (ret =
1264 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, srv->target)))
1265 return ret;
1266 return GNUNET_OK;
1267}
1268
1269
1282int
1284 size_t dst_len,
1285 size_t *off,
1286 const struct GNUNET_DNSPARSER_UriRecord *uri)
1287{
1288 struct GNUNET_TUN_DnsUriRecord sd;
1289 int written;
1290 size_t max_target_len;
1291
1292 GNUNET_assert (dst_len > sizeof (sd));
1293 GNUNET_assert (*off <= SIZE_MAX - sizeof (sd));
1294 max_target_len = dst_len - sizeof (sd) - 1;
1295 if (*off + sizeof(sd) > dst_len)
1296 return GNUNET_NO;
1297 sd.prio = htons (uri->priority);
1298 sd.weight = htons (uri->weight);
1299 GNUNET_memcpy (&dst[*off], &sd, sizeof(sd));
1300 (*off) += sizeof(sd);
1301 written = GNUNET_snprintf (&dst[*off], max_target_len, "%s", uri->target);
1302 (*off) += written;
1303 dst[*off] = '\0';
1304 return GNUNET_OK;
1305}
1306
1307
1320static int
1321add_record (char *dst,
1322 size_t dst_len,
1323 size_t *off,
1324 const struct GNUNET_DNSPARSER_Record *record)
1325{
1326 int ret;
1327 size_t start;
1328 size_t pos;
1329 struct GNUNET_TUN_DnsRecordLine rl;
1330
1331 if (dst_len < sizeof(struct GNUNET_TUN_DnsRecordLine))
1332 return GNUNET_NO;
1333 start = *off;
1335 dst,
1336 dst_len - sizeof(struct GNUNET_TUN_DnsRecordLine),
1337 off,
1338 record->name);
1339 if (GNUNET_OK != ret)
1340 return ret;
1341 /* '*off' is now the position where we will need to write the record line */
1342
1343 pos = *off + sizeof(struct GNUNET_TUN_DnsRecordLine);
1344 switch (record->type)
1345 {
1347 ret = GNUNET_DNSPARSER_builder_add_mx (dst, dst_len, &pos, record->data.mx);
1348 break;
1349
1351 ret =
1352 GNUNET_DNSPARSER_builder_add_cert (dst, dst_len, &pos, record->data.cert);
1353 break;
1354
1356 ret =
1357 GNUNET_DNSPARSER_builder_add_soa (dst, dst_len, &pos, record->data.soa);
1358 break;
1359
1364 dst_len,
1365 &pos,
1366 record->data.hostname);
1367 break;
1369 ret =
1370 GNUNET_DNSPARSER_builder_add_srv (dst, dst_len, &pos, record->data.srv);
1371 break;
1373 ret =
1374 GNUNET_DNSPARSER_builder_add_uri (dst, dst_len, &pos, record->data.uri);
1375 break;
1376 default:
1377 if ( (pos + record->data.raw.data_len < pos) ||
1378 (pos + record->data.raw.data_len > dst_len) )
1379 {
1380 ret = GNUNET_NO;
1381 break;
1382 }
1383 GNUNET_memcpy (&dst[pos], record->data.raw.data, record->data.raw.data_len);
1384 pos += record->data.raw.data_len;
1385 ret = GNUNET_OK;
1386 break;
1387 }
1388 if (GNUNET_OK != ret)
1389 {
1390 *off = start;
1391 return GNUNET_NO;
1392 }
1393
1394 if (pos - (*off + sizeof(struct GNUNET_TUN_DnsRecordLine)) > UINT16_MAX)
1395 {
1396 /* record data too long */
1397 *off = start;
1398 return GNUNET_NO;
1399 }
1400 rl.type = htons (record->type);
1401 rl.dns_traffic_class = htons (record->dns_traffic_class);
1402 rl.ttl = htonl (
1404 / 1000LL / 1000LL); /* in seconds */
1405 rl.data_len = htons (
1406 (uint16_t) (pos - (*off + sizeof(struct GNUNET_TUN_DnsRecordLine))));
1407 GNUNET_memcpy (&dst[*off], &rl, sizeof(struct GNUNET_TUN_DnsRecordLine));
1408 *off = pos;
1409 return GNUNET_OK;
1410}
1411
1412
1427int
1429 uint16_t max,
1430 char **buf,
1431 size_t *buf_length)
1432{
1433 struct GNUNET_TUN_DnsHeader dns;
1434 size_t off;
1435 char tmp[max];
1436 int ret;
1437 int trc;
1438
1439 if ((p->num_queries > UINT16_MAX) || (p->num_answers > UINT16_MAX) ||
1440 (p->num_authority_records > UINT16_MAX) ||
1441 (p->num_additional_records > UINT16_MAX))
1442 return GNUNET_SYSERR;
1443 dns.id = p->id;
1444 dns.flags = p->flags;
1445 dns.query_count = htons (p->num_queries);
1446 dns.answer_rcount = htons (p->num_answers);
1447 dns.authority_rcount = htons (p->num_authority_records);
1448 dns.additional_rcount = htons (p->num_additional_records);
1449
1450 off = sizeof(struct GNUNET_TUN_DnsHeader);
1451 trc = GNUNET_NO;
1452 for (unsigned int i = 0; i < p->num_queries; i++)
1453 {
1455 sizeof(tmp),
1456 &off,
1457 &p->queries[i]);
1458 if (GNUNET_SYSERR == ret)
1459 return GNUNET_SYSERR;
1460 if (GNUNET_NO == ret)
1461 {
1462 dns.query_count = htons ((uint16_t) (i - 1));
1463 trc = GNUNET_YES;
1464 break;
1465 }
1466 }
1467 for (unsigned int i = 0; i < p->num_answers; i++)
1468 {
1469 ret = add_record (tmp, sizeof(tmp), &off, &p->answers[i]);
1470 if (GNUNET_SYSERR == ret)
1471 return GNUNET_SYSERR;
1472 if (GNUNET_NO == ret)
1473 {
1474 dns.answer_rcount = htons ((uint16_t) (i - 1));
1475 trc = GNUNET_YES;
1476 break;
1477 }
1478 }
1479 for (unsigned int i = 0; i < p->num_authority_records; i++)
1480 {
1481 ret = add_record (tmp, sizeof(tmp), &off, &p->authority_records[i]);
1482 if (GNUNET_SYSERR == ret)
1483 return GNUNET_SYSERR;
1484 if (GNUNET_NO == ret)
1485 {
1486 dns.authority_rcount = htons ((uint16_t) (i - 1));
1487 trc = GNUNET_YES;
1488 break;
1489 }
1490 }
1491 for (unsigned int i = 0; i < p->num_additional_records; i++)
1492 {
1493 ret = add_record (tmp, sizeof(tmp), &off, &p->additional_records[i]);
1494 if (GNUNET_SYSERR == ret)
1495 return GNUNET_SYSERR;
1496 if (GNUNET_NO == ret)
1497 {
1498 dns.additional_rcount = htons (i - 1);
1499 trc = GNUNET_YES;
1500 break;
1501 }
1502 }
1503
1504 if (GNUNET_YES == trc)
1505 dns.flags.message_truncated = 1;
1506 GNUNET_memcpy (tmp, &dns, sizeof(struct GNUNET_TUN_DnsHeader));
1507
1508 *buf = GNUNET_malloc (off);
1509 *buf_length = off;
1510 GNUNET_memcpy (*buf, tmp, off);
1511 if (GNUNET_YES == trc)
1512 return GNUNET_NO;
1513 return GNUNET_OK;
1514}
1515
1516
1524char *
1526{
1527 char *ret;
1528 size_t off;
1529 const uint8_t *idata;
1530
1531 idata = data;
1532 ret = GNUNET_malloc (data_size * 2 + 1);
1533 for (off = 0; off < data_size; off++)
1534 sprintf (&ret[off * 2], "%02x", idata[off]);
1535 return ret;
1536}
1537
1538
1547size_t
1548GNUNET_DNSPARSER_hex_to_bin (const char *hex, void *data)
1549{
1550 size_t data_size;
1551 size_t off;
1552 uint8_t *idata;
1553 unsigned int h;
1554 char in[3];
1555
1556 data_size = strlen (hex) / 2;
1557 idata = data;
1558 in[2] = '\0';
1559 for (off = 0; off < data_size; off++)
1560 {
1561 in[0] = tolower ((unsigned char) hex[off * 2]);
1562 in[1] = tolower ((unsigned char) hex[off * 2 + 1]);
1563 if (1 != sscanf (in, "%x", &h))
1564 return off;
1565 idata[off] = (uint8_t) h;
1566 }
1567 return off;
1568}
1569
1570
1571/* end of dnsparser.c */
static int add_record(char *dst, size_t dst_len, size_t *off, const struct GNUNET_DNSPARSER_Record *record)
Add a DNS record to the UDP packet at the given location.
Definition dnsparser.c:1321
static char * parse_name(const char *udp_payload, size_t udp_payload_length, size_t *off, unsigned int depth)
Parse name inside of a DNS query or record.
Definition dnsparser.c:251
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition gnunet-arm.c:98
static int start
Set if we are to start default services (including ARM).
Definition gnunet-arm.c:38
static int ret
Final status code.
Definition gnunet-arm.c:93
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
static char * data
The data to insert into the dht.
char * idna_name
DNS IDNA name to lookup.
Definition gnunet-gns.c:63
static char * name
Name (label) of the records to list.
static size_t data_size
Number of bytes in data.
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
static struct GNUNET_REVOCATION_Query * q
Handle for revocation query.
static struct GNUNET_Process * p
Helper process we started.
Definition gnunet-uri.c:38
#define GNUNET_DNSPARSER_TYPE_URI
struct GNUNET_DNSPARSER_MxRecord * GNUNET_DNSPARSER_parse_mx(const char *udp_payload, size_t udp_payload_length, size_t *off)
Parse a DNS MX record.
Definition dnsparser.c:473
char * GNUNET_DNSPARSER_bin_to_hex(const void *data, size_t data_size)
Convert a block of binary data to HEX.
Definition dnsparser.c:1525
int GNUNET_DNSPARSER_builder_add_name(char *dst, size_t dst_len, size_t *off, const char *name)
Add a DNS name to the UDP packet at the given location, converting the name to IDNA notation as neces...
Definition dnsparser.c:1013
int GNUNET_DNSPARSER_builder_add_cert(char *dst, size_t dst_len, size_t *off, const struct GNUNET_DNSPARSER_CertRecord *cert)
Add a CERT record to the UDP packet at the given location.
Definition dnsparser.c:1157
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition dnsparser.c:978
struct GNUNET_DNSPARSER_MxRecord * GNUNET_DNSPARSER_duplicate_mx_record(const struct GNUNET_DNSPARSER_MxRecord *r)
Duplicate (deep-copy) the given DNS record.
Definition dnsparser.c:929
int GNUNET_DNSPARSER_builder_add_query(char *dst, size_t dst_len, size_t *off, const struct GNUNET_DNSPARSER_Query *query)
Add a DNS query to the UDP packet at the given location.
Definition dnsparser.c:1091
struct GNUNET_DNSPARSER_SoaRecord * GNUNET_DNSPARSER_duplicate_soa_record(const struct GNUNET_DNSPARSER_SoaRecord *r)
Duplicate (deep-copy) the given DNS record.
Definition dnsparser.c:893
#define GNUNET_DNSPARSER_TYPE_SRV
void GNUNET_DNSPARSER_free_record(struct GNUNET_DNSPARSER_Record *r)
Free the given DNS record.
Definition dnsparser.c:201
#define GNUNET_DNSPARSER_TYPE_SOA
void GNUNET_DNSPARSER_free_cert(struct GNUNET_DNSPARSER_CertRecord *cert)
Free CERT information record.
Definition dnsparser.c:141
#define GNUNET_DNSPARSER_TYPE_CERT
size_t GNUNET_DNSPARSER_hex_to_bin(const char *hex, void *data)
Convert a HEX string to block of binary data.
Definition dnsparser.c:1548
enum GNUNET_GenericReturnValue GNUNET_DNSPARSER_check_label(const char *label)
Check if a label in UTF-8 format can be coded into valid IDNA.
Definition dnsparser.c:53
void GNUNET_DNSPARSER_free_srv(struct GNUNET_DNSPARSER_SrvRecord *srv)
Free SRV information record.
Definition dnsparser.c:156
#define GNUNET_DNSPARSER_TYPE_PTR
struct GNUNET_DNSPARSER_SrvRecord * GNUNET_DNSPARSER_duplicate_srv_record(const struct GNUNET_DNSPARSER_SrvRecord *r)
Duplicate (deep-copy) the given DNS record.
Definition dnsparser.c:945
struct GNUNET_DNSPARSER_SoaRecord * GNUNET_DNSPARSER_parse_soa(const char *udp_payload, size_t udp_payload_length, size_t *off)
Parse a DNS SOA record.
Definition dnsparser.c:428
struct GNUNET_DNSPARSER_CertRecord * GNUNET_DNSPARSER_parse_cert(const char *udp_payload, size_t udp_payload_length, size_t *off)
Parse a DNS CERT record.
Definition dnsparser.c:599
void GNUNET_DNSPARSER_free_uri(struct GNUNET_DNSPARSER_UriRecord *uri)
Free URI information record.
Definition dnsparser.c:171
#define GNUNET_DNSPARSER_TYPE_NS
int GNUNET_DNSPARSER_builder_add_soa(char *dst, size_t dst_len, size_t *off, const struct GNUNET_DNSPARSER_SoaRecord *soa)
Add an SOA record to the UDP packet at the given location.
Definition dnsparser.c:1205
#define GNUNET_DNSPARSER_TYPE_CNAME
#define GNUNET_DNSPARSER_TYPE_DNAME
struct GNUNET_DNSPARSER_UriRecord * GNUNET_DNSPARSER_parse_uri(const char *udp_payload, size_t udp_payload_length, size_t *off)
Parse a DNS URI record.
Definition dnsparser.c:555
struct GNUNET_DNSPARSER_SrvRecord * GNUNET_DNSPARSER_parse_srv(const char *udp_payload, size_t udp_payload_length, size_t *off)
Parse a DNS SRV record.
Definition dnsparser.c:514
struct GNUNET_DNSPARSER_CertRecord * GNUNET_DNSPARSER_duplicate_cert_record(const struct GNUNET_DNSPARSER_CertRecord *r)
Duplicate (deep-copy) the given DNS record.
Definition dnsparser.c:911
char * GNUNET_DNSPARSER_parse_name(const char *udp_payload, size_t udp_payload_length, size_t *off)
Parse name inside of a DNS query or record.
Definition dnsparser.c:371
int GNUNET_DNSPARSER_builder_add_mx(char *dst, size_t dst_len, size_t *off, const struct GNUNET_DNSPARSER_MxRecord *mx)
Add an MX record to the UDP packet at the given location.
Definition dnsparser.c:1127
void GNUNET_DNSPARSER_free_soa(struct GNUNET_DNSPARSER_SoaRecord *soa)
Free SOA information record.
Definition dnsparser.c:125
int GNUNET_DNSPARSER_builder_add_srv(char *dst, size_t dst_len, size_t *off, const struct GNUNET_DNSPARSER_SrvRecord *srv)
Add an SRV record to the UDP packet at the given location.
Definition dnsparser.c:1246
void GNUNET_DNSPARSER_free_mx(struct GNUNET_DNSPARSER_MxRecord *mx)
Free MX information record.
Definition dnsparser.c:186
struct GNUNET_DNSPARSER_UriRecord * GNUNET_DNSPARSER_duplicate_uri_record(const struct GNUNET_DNSPARSER_UriRecord *r)
Duplicate (deep-copy) the given DNS record.
Definition dnsparser.c:962
int GNUNET_DNSPARSER_parse_query(const char *udp_payload, size_t udp_payload_length, size_t *off, struct GNUNET_DNSPARSER_Query *q)
Parse a DNS query entry.
Definition dnsparser.c:390
int GNUNET_DNSPARSER_pack(const struct GNUNET_DNSPARSER_Packet *p, uint16_t max, char **buf, size_t *buf_length)
Given a DNS packet p, generate the corresponding UDP payload.
Definition dnsparser.c:1428
int GNUNET_DNSPARSER_builder_add_uri(char *dst, size_t dst_len, size_t *off, const struct GNUNET_DNSPARSER_UriRecord *uri)
Add an URI record to the UDP packet at the given location.
Definition dnsparser.c:1283
int GNUNET_DNSPARSER_parse_record(const char *udp_payload, size_t udp_payload_length, size_t *off, struct GNUNET_DNSPARSER_Record *r)
Parse a DNS record entry.
Definition dnsparser.c:640
enum GNUNET_GenericReturnValue GNUNET_DNSPARSER_check_name(const char *name)
Check if a label in UTF-8 format can be coded into valid IDNA.
Definition dnsparser.c:79
#define GNUNET_DNSPARSER_TYPE_MX
struct GNUNET_DNSPARSER_Packet * GNUNET_DNSPARSER_parse(const char *udp_payload, size_t udp_payload_length)
Parse a UDP payload of a DNS packet in to a nice struct for further processing and manipulation.
Definition dnsparser.c:756
struct GNUNET_DNSPARSER_Record * GNUNET_DNSPARSER_duplicate_record(const struct GNUNET_DNSPARSER_Record *r)
Duplicate (deep-copy) the given DNS record.
Definition dnsparser.c:837
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition time.c:406
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition time.c:316
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition time.c:486
#define max(x, y)
#define _(String)
GNU gettext support macro.
Definition platform.h:179
#define SIZE_MAX
Definition platform.h:213
Information from CERT records (RFC 4034).
enum GNUNET_DNSPARSER_CertType cert_type
Certificate type.
char * certificate_data
Data of the certificate.
enum GNUNET_DNSPARSER_CertAlgorithm algorithm
Algorithm.
size_t certificate_size
Number of bytes in certificate_data.
uint16_t cert_tag
Certificate KeyTag.
Information from MX records (RFC 1035).
char * mxhost
Name of the mail server.
uint16_t preference
Preference for this entry (lower value is higher preference).
Easy-to-process, parsed version of a DNS packet.
uint16_t dns_traffic_class
See GNUNET_TUN_DNS_CLASS_*.
uint16_t type
See GNUNET_DNSPARSER_TYPE_*.
char * name
Name of the record that the query is for (0-terminated).
void * data
Binary record data.
size_t data_len
Number of bytes in data.
A DNS response record.
uint16_t dns_traffic_class
See GNUNET_TUN_DNS_CLASS_*.
struct GNUNET_DNSPARSER_SoaRecord * soa
SOA data for SOA records.
struct GNUNET_DNSPARSER_SrvRecord * srv
SRV data for SRV records.
struct GNUNET_DNSPARSER_MxRecord * mx
MX data for MX records.
char * hostname
For NS, CNAME and PTR records, this is the uncompressed 0-terminated hostname.
struct GNUNET_DNSPARSER_CertRecord * cert
CERT data for CERT records.
uint16_t type
See GNUNET_DNSPARSER_TYPE_*.
struct GNUNET_TIME_Absolute expiration_time
When does the record expire?
union GNUNET_DNSPARSER_Record::@24 data
Payload of the record (which one of these is valid depends on the 'type').
char * name
Name of the record that the query is for (0-terminated).
struct GNUNET_DNSPARSER_RawRecord raw
Raw data for all other types.
struct GNUNET_DNSPARSER_UriRecord * uri
URI data for URI records.
Information from SOA records (RFC 1035).
uint32_t retry
Time interval that should elapse before a failed refresh should be retried.
char * mname
The domainname of the name server that was the original or primary source of data for this zone.
uint32_t refresh
Time interval before the zone should be refreshed.
uint32_t minimum_ttl
The bit minimum TTL field that should be exported with any RR from this zone.
char * rname
A domainname which specifies the mailbox of the person responsible for this zone.
uint32_t expire
Time value that specifies the upper limit on the time interval that can elapse before the zone is no ...
uint32_t serial
The version number of the original copy of the zone.
Information from SRV records (RFC 2782).
uint16_t port
TCP or UDP port of the service.
uint16_t weight
Relative weight for records with the same priority.
uint16_t priority
Preference for this entry (lower value is higher preference).
char * target
Hostname offering the service.
Information from URI records (RFC 7553).
char * target
URI of the target, where the URI is as specified in RFC 3986.
uint64_t rel_value_us
The actual value.
Payload of DNS CERT record.
uint16_t cert_type
Certificate type.
uint16_t cert_tag
Certificate KeyTag.
uint8_t algorithm
Algorithm.
unsigned int message_truncated
Set to 1 if message is truncated.
struct GNUNET_TUN_DnsFlags flags
Flags.
uint16_t query_count
Number of queries.
uint16_t authority_rcount
Number of authoritative answers.
uint16_t id
Unique identifier for the request/response.
uint16_t additional_rcount
Number of additional records.
uint16_t answer_rcount
Number of answers.
uint16_t type
Desired type (GNUNET_DNSPARSER_TYPE_XXX).
uint16_t dns_traffic_class
Desired class (usually GNUNET_TUN_DNS_CLASS_INTERNET).
General DNS record prefix.
uint32_t ttl
Expiration for the record (in seconds).
uint16_t dns_traffic_class
Record class (usually GNUNET_TUN_DNS_CLASS_INTERNET).
uint16_t type
Record type (GNUNET_DNSPARSER_TYPE_XXX).
uint16_t data_len
Number of bytes of data that follow.
Payload of DNS SOA record (header).
uint32_t minimum
The bit minimum TTL field that should be exported with any RR from this zone.
uint32_t expire
Time value that specifies the upper limit on the time interval that can elapse before the zone is no ...
uint32_t refresh
Time interval before the zone should be refreshed.
uint32_t serial
The version number of the original copy of the zone.
uint32_t retry
Time interval that should elapse before a failed refresh should be retried.
Payload of DNS SRV record (header).
uint16_t prio
Preference for this entry (lower value is higher preference).
uint16_t weight
Relative weight for records with the same priority.
uint16_t port
TCP or UDP port of the service.
Payload of DNS URI record (header).
uint16_t prio
Preference for this entry (lower value is higher preference).
uint16_t weight
Relative weight for records with the same priority.