GNUnet 0.28.0-dev.1-1-gd5f66caac
 
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
230 break;
231
232 default:
234 break;
235 }
236}
237
238
249static char *
250parse_name (const char *udp_payload,
251 size_t udp_payload_length,
252 size_t *off,
253 unsigned int depth)
254{
255 const uint8_t *input = (const uint8_t *) udp_payload;
256 char *ret;
257 char *tmp;
258 char *xstr;
259 uint8_t len;
260 size_t xoff;
261 char *utf8;
262 Idna_rc rc;
263
264 ret = GNUNET_strdup ("");
265 while (1)
266 {
267 if (*off >= udp_payload_length)
268 {
269 GNUNET_break_op (0);
270 goto error;
271 }
272 len = input[*off];
273 if (0 == len)
274 {
275 (*off)++;
276 break;
277 }
278 if (len < 64)
279 {
280 if (*off + 1 + len > udp_payload_length)
281 {
282 GNUNET_break_op (0);
283 goto error;
284 }
285 GNUNET_asprintf (&tmp, "%.*s", (int) len, &udp_payload[*off + 1]);
286 if (IDNA_SUCCESS !=
287 (rc = idna_to_unicode_8z8z (tmp, &utf8, IDNA_ALLOW_UNASSIGNED)))
288 {
290 _ ("Failed to convert DNS IDNA name `%s' to UTF-8: %s\n"),
291 tmp,
292 idna_strerror (rc));
293 GNUNET_free (tmp);
294 GNUNET_asprintf (&tmp,
295 "%s%.*s.",
296 ret,
297 (int) len,
298 &udp_payload[*off + 1]);
299 }
300 else
301 {
302 GNUNET_free (tmp);
303 GNUNET_asprintf (&tmp, "%s%s.", ret, utf8);
304 free (utf8);
305 }
307 ret = tmp;
308 *off += 1 + len;
309 }
310 else if ((64 | 128) == (len & (64 | 128)))
311 {
312 if (depth > 32)
313 {
314 GNUNET_break_op (0);
315 goto error; /* hard bound on stack to prevent "infinite" recursion, disallow! */
316 }
317 /* pointer to string */
318 if (*off + 1 > udp_payload_length)
319 {
320 GNUNET_break_op (0);
321 goto error;
322 }
323 xoff = ((len - (64 | 128)) << 8) + input[*off + 1];
324 xstr = parse_name (udp_payload, udp_payload_length, &xoff, depth + 1);
325 if (NULL == xstr)
326 {
327 GNUNET_break_op (0);
328 goto error;
329 }
330 GNUNET_asprintf (&tmp, "%s%s.", ret, xstr);
332 GNUNET_free (xstr);
333 ret = tmp;
334 if (strlen (ret) > udp_payload_length)
335 {
336 GNUNET_break_op (0);
337 goto error; /* we are looping (building an infinite string) */
338 }
339 *off += 2;
340 /* pointers always terminate names */
341 break;
342 }
343 else
344 {
345 /* neither pointer nor inline string, not supported... */
346 GNUNET_break_op (0);
347 goto error;
348 }
349 }
350 if (0 < strlen (ret))
351 ret[strlen (ret) - 1] = '\0'; /* eat tailing '.' */
352 return ret;
353error:
354 GNUNET_break_op (0);
356 return NULL;
357}
358
359
369char *
370GNUNET_DNSPARSER_parse_name (const char *udp_payload,
371 size_t udp_payload_length,
372 size_t *off)
373{
374 return parse_name (udp_payload, udp_payload_length, off, 0);
375}
376
377
388int
389GNUNET_DNSPARSER_parse_query (const char *udp_payload,
390 size_t udp_payload_length,
391 size_t *off,
393{
394 char *name;
395 struct GNUNET_TUN_DnsQueryLine ql;
396
397 name = GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
398 if (NULL == name)
399 {
400 GNUNET_break_op (0);
401 return GNUNET_SYSERR;
402 }
403 q->name = name;
404 if (*off + sizeof(struct GNUNET_TUN_DnsQueryLine) > udp_payload_length)
405 {
406 GNUNET_break_op (0);
407 return GNUNET_SYSERR;
408 }
409 GNUNET_memcpy (&ql, &udp_payload[*off], sizeof(ql));
410 *off += sizeof(ql);
411 q->type = ntohs (ql.type);
412 q->dns_traffic_class = ntohs (ql.dns_traffic_class);
413 return GNUNET_OK;
414}
415
416
427GNUNET_DNSPARSER_parse_soa (const char *udp_payload,
428 size_t udp_payload_length,
429 size_t *off)
430{
431 struct GNUNET_DNSPARSER_SoaRecord *soa;
432 struct GNUNET_TUN_DnsSoaRecord soa_bin;
433 size_t old_off;
434
435 old_off = *off;
437 soa->mname =
438 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
439 soa->rname =
440 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
441 if ((NULL == soa->mname) || (NULL == soa->rname) ||
442 (*off + sizeof(struct GNUNET_TUN_DnsSoaRecord) > udp_payload_length))
443 {
444 GNUNET_break_op (0);
446 *off = old_off;
447 return NULL;
448 }
449 GNUNET_memcpy (&soa_bin,
450 &udp_payload[*off],
451 sizeof(struct GNUNET_TUN_DnsSoaRecord));
452 soa->serial = ntohl (soa_bin.serial);
453 soa->refresh = ntohl (soa_bin.refresh);
454 soa->retry = ntohl (soa_bin.retry);
455 soa->expire = ntohl (soa_bin.expire);
456 soa->minimum_ttl = ntohl (soa_bin.minimum);
457 (*off) += sizeof(struct GNUNET_TUN_DnsSoaRecord);
458 return soa;
459}
460
461
472GNUNET_DNSPARSER_parse_mx (const char *udp_payload,
473 size_t udp_payload_length,
474 size_t *off)
475{
476 struct GNUNET_DNSPARSER_MxRecord *mx;
477 uint16_t mxpref;
478 size_t old_off;
479
480 old_off = *off;
481 if (*off + sizeof(uint16_t) > udp_payload_length)
482 {
483 GNUNET_break_op (0);
484 return NULL;
485 }
486 GNUNET_memcpy (&mxpref, &udp_payload[*off], sizeof(uint16_t));
487 (*off) += sizeof(uint16_t);
489 mx->preference = ntohs (mxpref);
490 mx->mxhost =
491 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
492 if (NULL == mx->mxhost)
493 {
494 GNUNET_break_op (0);
496 *off = old_off;
497 return NULL;
498 }
499 return mx;
500}
501
502
513GNUNET_DNSPARSER_parse_srv (const char *udp_payload,
514 size_t udp_payload_length,
515 size_t *off)
516{
517 struct GNUNET_DNSPARSER_SrvRecord *srv;
518 struct GNUNET_TUN_DnsSrvRecord srv_bin;
519 size_t old_off;
520
521 old_off = *off;
522 if (*off + sizeof(struct GNUNET_TUN_DnsSrvRecord) > udp_payload_length)
523 return NULL;
524 GNUNET_memcpy (&srv_bin,
525 &udp_payload[*off],
526 sizeof(struct GNUNET_TUN_DnsSrvRecord));
527 (*off) += sizeof(struct GNUNET_TUN_DnsSrvRecord);
529 srv->priority = ntohs (srv_bin.prio);
530 srv->weight = ntohs (srv_bin.weight);
531 srv->port = ntohs (srv_bin.port);
532 srv->target =
533 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
534 if (NULL == srv->target)
535 {
537 *off = old_off;
538 return NULL;
539 }
540 return srv;
541}
542
543
554GNUNET_DNSPARSER_parse_uri (const char *udp_payload,
555 size_t udp_payload_length,
556 size_t *off)
557{
559 struct GNUNET_TUN_DnsUriRecord uri_bin;
560 size_t old_off;
561 int max_len;
562 int len;
563
564 old_off = *off;
565 if (*off + sizeof(struct GNUNET_TUN_DnsUriRecord) > udp_payload_length)
566 return NULL;
567 GNUNET_memcpy (&uri_bin,
568 &udp_payload[*off],
569 sizeof(struct GNUNET_TUN_DnsUriRecord));
570 (*off) += sizeof(struct GNUNET_TUN_DnsUriRecord);
572 uri->priority = ntohs (uri_bin.prio);
573 uri->weight = ntohs (uri_bin.weight);
574 max_len = udp_payload_length - sizeof(struct GNUNET_TUN_DnsUriRecord);
575 len = GNUNET_asprintf (&(uri->target), "%.*s", max_len,
576 &udp_payload[*off]);
577 (*off) += len;
578 if (NULL == uri->target)
579 {
581 *off = old_off;
582 return NULL;
583 }
584 return uri;
585}
586
587
598GNUNET_DNSPARSER_parse_cert (const char *udp_payload,
599 size_t udp_payload_length,
600 size_t *off)
601{
602 struct GNUNET_DNSPARSER_CertRecord *cert;
603 struct GNUNET_TUN_DnsCertRecord dcert;
604
605 if (*off + sizeof(struct GNUNET_TUN_DnsCertRecord) >= udp_payload_length)
606 {
607 GNUNET_break_op (0);
608 return NULL;
609 }
610 GNUNET_memcpy (&dcert,
611 &udp_payload[*off],
612 sizeof(struct GNUNET_TUN_DnsCertRecord));
613 (*off) += sizeof(struct GNUNET_TUN_DnsCertRecord);
615 cert->cert_type = ntohs (dcert.cert_type);
616 cert->cert_tag = ntohs (dcert.cert_tag);
617 cert->algorithm = dcert.algorithm;
618 cert->certificate_size = udp_payload_length - (*off);
621 &udp_payload[*off],
622 cert->certificate_size);
623 (*off) += cert->certificate_size;
624 return cert;
625}
626
627
638int
639GNUNET_DNSPARSER_parse_record (const char *udp_payload,
640 size_t udp_payload_length,
641 size_t *off,
642 struct GNUNET_DNSPARSER_Record *r)
643{
644 char *name;
645 struct GNUNET_TUN_DnsRecordLine rl;
646 size_t old_off;
647 uint16_t data_len;
648
649 name = GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
650 if (NULL == name)
651 {
652 GNUNET_break_op (0);
653 return GNUNET_SYSERR;
654 }
655 r->name = name;
656 if (*off + sizeof(struct GNUNET_TUN_DnsRecordLine) > udp_payload_length)
657 {
658 GNUNET_break_op (0);
659 return GNUNET_SYSERR;
660 }
661 GNUNET_memcpy (&rl, &udp_payload[*off], sizeof(rl));
662 (*off) += sizeof(rl);
663 r->type = ntohs (rl.type);
664 r->dns_traffic_class = ntohs (rl.dns_traffic_class);
667 data_len = ntohs (rl.data_len);
668 if (*off + data_len > udp_payload_length)
669 {
670 GNUNET_break_op (0);
671 return GNUNET_SYSERR;
672 }
673 old_off = *off;
674 switch (r->type)
675 {
680 r->data.hostname =
681 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
682 if ((NULL == r->data.hostname) || (old_off + data_len != *off))
683 return GNUNET_SYSERR;
684 return GNUNET_OK;
685
687 r->data.soa =
688 GNUNET_DNSPARSER_parse_soa (udp_payload, udp_payload_length, off);
689 if ((NULL == r->data.soa) || (old_off + data_len != *off))
690 {
691 GNUNET_break_op (0);
692 return GNUNET_SYSERR;
693 }
694 return GNUNET_OK;
695
697 r->data.mx =
698 GNUNET_DNSPARSER_parse_mx (udp_payload, udp_payload_length, off);
699 if ((NULL == r->data.mx) || (old_off + data_len != *off))
700 {
701 GNUNET_break_op (0);
702 return GNUNET_SYSERR;
703 }
704 return GNUNET_OK;
705
707 r->data.srv =
708 GNUNET_DNSPARSER_parse_srv (udp_payload, udp_payload_length, off);
709 if ((NULL == r->data.srv) || (old_off + data_len != *off))
710 {
711 GNUNET_break_op (0);
712 return GNUNET_SYSERR;
713 }
714 return GNUNET_OK;
715
717 r->data.uri =
718 GNUNET_DNSPARSER_parse_uri (udp_payload, udp_payload_length, off);
719 if ((NULL == r->data.uri) || (old_off + data_len != *off))
720 {
721 GNUNET_break_op (0);
722 return GNUNET_SYSERR;
723 }
724 return GNUNET_OK;
725
726 default:
729 GNUNET_memcpy (r->data.raw.data, &udp_payload[*off], data_len);
730 break;
731 }
732 (*off) += data_len;
733 return GNUNET_OK;
734}
735
736
746GNUNET_DNSPARSER_parse (const char *udp_payload, size_t udp_payload_length)
747{
749 const struct GNUNET_TUN_DnsHeader *dns;
750 size_t off;
751 unsigned int n;
752
753 if (udp_payload_length < sizeof(struct GNUNET_TUN_DnsHeader))
754 return NULL;
755 dns = (const struct GNUNET_TUN_DnsHeader *) udp_payload;
756 off = sizeof(struct GNUNET_TUN_DnsHeader);
758 p->flags = dns->flags;
759 p->id = dns->id;
760 n = ntohs (dns->query_count);
761 if (n > 0)
762 {
763 p->queries = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Query);
764 p->num_queries = n;
765 for (unsigned int i = 0; i < n; i++)
766 if (GNUNET_OK != GNUNET_DNSPARSER_parse_query (udp_payload,
767 udp_payload_length,
768 &off,
769 &p->queries[i]))
770 goto error;
771 }
772 n = ntohs (dns->answer_rcount);
773 if (n > 0)
774 {
775 p->answers = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Record);
776 p->num_answers = n;
777 for (unsigned int i = 0; i < n; i++)
778 if (GNUNET_OK != GNUNET_DNSPARSER_parse_record (udp_payload,
779 udp_payload_length,
780 &off,
781 &p->answers[i]))
782 goto error;
783 }
784 n = ntohs (dns->authority_rcount);
785 if (n > 0)
786 {
787 p->authority_records = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Record);
788 p->num_authority_records = n;
789 for (unsigned int i = 0; i < n; i++)
790 if (GNUNET_OK != GNUNET_DNSPARSER_parse_record (udp_payload,
791 udp_payload_length,
792 &off,
793 &p->authority_records[i]))
794 goto error;
795 }
796 n = ntohs (dns->additional_rcount);
797 if (n > 0)
798 {
799 p->additional_records =
801 p->num_additional_records = n;
802 for (unsigned int i = 0; i < n; i++)
803 {
804 if (GNUNET_OK !=
806 udp_payload_length,
807 &off,
808 &p->additional_records[i]))
809 goto error;
810 }
811 }
812 return p;
813error:
814 GNUNET_break_op (0);
816 return NULL;
817}
818
819
828{
829 struct GNUNET_DNSPARSER_Record *dup = GNUNET_memdup (r, sizeof(*r));
830
831 dup->name = GNUNET_strdup (r->name);
832 switch (r->type)
833 {
838 break;
839 }
840
843 break;
844 }
845
848 break;
849 }
850
853 break;
854 }
855
858 break;
859 }
860
863 break;
864 }
865
866 default: {
868 r->data.raw.data_len);
869 }
870 }
871 return dup;
872}
873
874
883 const struct GNUNET_DNSPARSER_SoaRecord *r)
884{
885 struct GNUNET_DNSPARSER_SoaRecord *dup = GNUNET_memdup (r, sizeof(*r));
886
887 dup->mname = GNUNET_strdup (r->mname);
888 dup->rname = GNUNET_strdup (r->rname);
889 return dup;
890}
891
892
901 const struct GNUNET_DNSPARSER_CertRecord *r)
902{
903 struct GNUNET_DNSPARSER_CertRecord *dup = GNUNET_memdup (r, sizeof(*r));
904
907 return dup;
908}
909
910
919{
920 struct GNUNET_DNSPARSER_MxRecord *dup = GNUNET_memdup (r, sizeof(*r));
921
922 dup->mxhost = GNUNET_strdup (r->mxhost);
923 return dup;
924}
925
926
935 const struct GNUNET_DNSPARSER_SrvRecord *r)
936{
937 struct GNUNET_DNSPARSER_SrvRecord *dup = GNUNET_memdup (r, sizeof(*r));
938
939 dup->target = GNUNET_strdup (r->target);
940 return dup;
941}
942
943
952 const struct GNUNET_DNSPARSER_UriRecord *r)
953{
954 struct GNUNET_DNSPARSER_UriRecord *dup = GNUNET_memdup (r, sizeof(*r));
955
956 dup->target = GNUNET_strdup (r->target);
957 return dup;
958}
959
960
966void
968{
969 for (unsigned int i = 0; i < p->num_queries; i++)
970 GNUNET_free (p->queries[i].name);
971 GNUNET_free (p->queries);
972 for (unsigned int i = 0; i < p->num_answers; i++)
973 GNUNET_DNSPARSER_free_record (&p->answers[i]);
974 GNUNET_free (p->answers);
975 for (unsigned int i = 0; i < p->num_authority_records; i++)
976 GNUNET_DNSPARSER_free_record (&p->authority_records[i]);
977 GNUNET_free (p->authority_records);
978 for (unsigned int i = 0; i < p->num_additional_records; i++)
979 GNUNET_DNSPARSER_free_record (&p->additional_records[i]);
980 GNUNET_free (p->additional_records);
981 GNUNET_free (p);
982}
983
984
985/* ********************** DNS packet assembly code **************** */
986
987
1001int
1003 size_t dst_len,
1004 size_t *off,
1005 const char *name)
1006{
1007 const char *dot;
1008 const char *idna_name;
1009 char *idna_start;
1010 size_t start;
1011 size_t pos;
1012 size_t len;
1013 Idna_rc rc;
1014
1015 if (NULL == name)
1016 return GNUNET_SYSERR;
1017
1018 if (IDNA_SUCCESS !=
1019 (rc = idna_to_ascii_8z (name, &idna_start, IDNA_ALLOW_UNASSIGNED)))
1020 {
1022 _ (
1023 "Failed to convert UTF-8 name `%s' to DNS IDNA format: %s\n"),
1024 name,
1025 idna_strerror (rc));
1026 return GNUNET_NO;
1027 }
1028 idna_name = idna_start;
1029 GNUNET_assert (*off <= SIZE_MAX - strlen (idna_name) - 2);
1030 start = *off;
1031 if (start + strlen (idna_name) + 2 > dst_len)
1032 goto fail;
1033 pos = start;
1034 do
1035 {
1036 dot = strchr (idna_name, '.');
1037 if (NULL == dot)
1038 len = strlen (idna_name);
1039 else
1040 len = dot - idna_name;
1041 if (len == 0)
1042 break;
1043 if (len >= 64)
1044 {
1046 "Invalid DNS name `%s': label with %u characters encountered\n",
1047 name,
1048 (unsigned int) len);
1049 goto fail; /* label too long or empty */
1050 }
1051 dst[pos++] = (char) (uint8_t) len;
1052 GNUNET_memcpy (&dst[pos], idna_name, len);
1053 pos += len;
1054 idna_name += len + 1; /* also skip dot */
1055 }
1056 while (NULL != dot);
1057 dst[pos++] = '\0'; /* terminator */
1058 *off = pos;
1059 free (idna_start);
1060 return GNUNET_OK;
1061fail:
1062 free (idna_start);
1063 return GNUNET_NO;
1064}
1065
1066
1079int
1081 size_t dst_len,
1082 size_t *off,
1083 const struct GNUNET_DNSPARSER_Query *query)
1084{
1085 int ret;
1086 struct GNUNET_TUN_DnsQueryLine ql;
1087
1088 GNUNET_assert (dst_len >= sizeof (ql));
1090 dst_len - sizeof(ql),
1091 off,
1092 query->name);
1093 if (ret != GNUNET_OK)
1094 return ret;
1095 ql.type = htons (query->type);
1096 ql.dns_traffic_class = htons (query->dns_traffic_class);
1097 GNUNET_memcpy (&dst[*off], &ql, sizeof(ql));
1098 (*off) += sizeof(ql);
1099 return GNUNET_OK;
1100}
1101
1102
1115int
1117 size_t dst_len,
1118 size_t *off,
1119 const struct GNUNET_DNSPARSER_MxRecord *mx)
1120{
1121 uint16_t mxpref;
1122
1123 GNUNET_assert (*off <= SIZE_MAX - sizeof (uint16_t));
1124 if (*off + sizeof(uint16_t) > dst_len)
1125 return GNUNET_NO;
1126 mxpref = htons (mx->preference);
1127 GNUNET_memcpy (&dst[*off], &mxpref, sizeof(mxpref));
1128 (*off) += sizeof(mxpref);
1129 return GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, mx->mxhost);
1130}
1131
1132
1145int
1147 char *dst,
1148 size_t dst_len,
1149 size_t *off,
1150 const struct GNUNET_DNSPARSER_CertRecord *cert)
1151{
1152 struct GNUNET_TUN_DnsCertRecord dcert;
1153
1154#ifdef __clang__
1155#pragma clang diagnostic push
1156#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
1157#endif
1158 if ((cert->cert_type > UINT16_MAX) || (cert->algorithm > UINT8_MAX))
1159 {
1160 GNUNET_break (0);
1161 return GNUNET_SYSERR;
1162 }
1163#ifdef __clang__
1164#pragma clang diagnostic pop
1165#endif
1166 GNUNET_assert (*off <= SIZE_MAX - sizeof (dcert));
1167 GNUNET_assert (cert->certificate_size <= SIZE_MAX - *off - sizeof (dcert));
1168 if (*off + sizeof(dcert) + cert->certificate_size > dst_len)
1169 return GNUNET_NO;
1170 dcert.cert_type = htons ((uint16_t) cert->cert_type);
1171 dcert.cert_tag = htons ((uint16_t) cert->cert_tag);
1172 dcert.algorithm = (uint8_t) cert->algorithm;
1173 GNUNET_memcpy (&dst[*off], &dcert, sizeof(dcert));
1174 (*off) += sizeof(dcert);
1175 GNUNET_memcpy (&dst[*off], cert->certificate_data, cert->certificate_size);
1176 (*off) += cert->certificate_size;
1177 return GNUNET_OK;
1178}
1179
1180
1193int
1195 size_t dst_len,
1196 size_t *off,
1197 const struct GNUNET_DNSPARSER_SoaRecord *soa)
1198{
1199 struct GNUNET_TUN_DnsSoaRecord sd;
1200 int ret;
1201
1202 if ((GNUNET_OK !=
1203 (ret =
1204 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, soa->mname))) ||
1205 (GNUNET_OK !=
1206 (ret =
1207 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, soa->rname))))
1208 return ret;
1209 if (*off + sizeof(struct GNUNET_TUN_DnsSoaRecord) > dst_len)
1210 return GNUNET_NO;
1211 sd.serial = htonl (soa->serial);
1212 sd.refresh = htonl (soa->refresh);
1213 sd.retry = htonl (soa->retry);
1214 sd.expire = htonl (soa->expire);
1215 sd.minimum = htonl (soa->minimum_ttl);
1216 GNUNET_memcpy (&dst[*off], &sd, sizeof(sd));
1217 (*off) += sizeof(sd);
1218 return GNUNET_OK;
1219}
1220
1221
1234int
1236 size_t dst_len,
1237 size_t *off,
1238 const struct GNUNET_DNSPARSER_SrvRecord *srv)
1239{
1240 struct GNUNET_TUN_DnsSrvRecord sd;
1241 int ret;
1242
1243 GNUNET_assert (*off <= SIZE_MAX - sizeof (sd));
1244 if (*off + sizeof(sd) > dst_len)
1245 return GNUNET_NO;
1246 sd.prio = htons (srv->priority);
1247 sd.weight = htons (srv->weight);
1248 sd.port = htons (srv->port);
1249 GNUNET_memcpy (&dst[*off], &sd, sizeof(sd));
1250 (*off) += sizeof(sd);
1251 if (GNUNET_OK !=
1252 (ret =
1253 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, srv->target)))
1254 return ret;
1255 return GNUNET_OK;
1256}
1257
1258
1271int
1273 size_t dst_len,
1274 size_t *off,
1275 const struct GNUNET_DNSPARSER_UriRecord *uri)
1276{
1277 struct GNUNET_TUN_DnsUriRecord sd;
1278 int written;
1279 size_t max_target_len;
1280
1281 GNUNET_assert (dst_len > sizeof (sd));
1282 GNUNET_assert (*off <= SIZE_MAX - sizeof (sd));
1283 max_target_len = dst_len - sizeof (sd) - 1;
1284 if (*off + sizeof(sd) > dst_len)
1285 return GNUNET_NO;
1286 sd.prio = htons (uri->priority);
1287 sd.weight = htons (uri->weight);
1288 GNUNET_memcpy (&dst[*off], &sd, sizeof(sd));
1289 (*off) += sizeof(sd);
1290 written = GNUNET_snprintf (&dst[*off], max_target_len, "%s", uri->target);
1291 (*off) += written;
1292 dst[*off] = '\0';
1293 return GNUNET_OK;
1294}
1295
1296
1309static int
1310add_record (char *dst,
1311 size_t dst_len,
1312 size_t *off,
1313 const struct GNUNET_DNSPARSER_Record *record)
1314{
1315 int ret;
1316 size_t start;
1317 size_t pos;
1318 struct GNUNET_TUN_DnsRecordLine rl;
1319
1320 if (dst_len < sizeof(struct GNUNET_TUN_DnsRecordLine))
1321 return GNUNET_NO;
1322 start = *off;
1324 dst,
1325 dst_len - sizeof(struct GNUNET_TUN_DnsRecordLine),
1326 off,
1327 record->name);
1328 if (GNUNET_OK != ret)
1329 return ret;
1330 /* '*off' is now the position where we will need to write the record line */
1331
1332 pos = *off + sizeof(struct GNUNET_TUN_DnsRecordLine);
1333 switch (record->type)
1334 {
1336 ret = GNUNET_DNSPARSER_builder_add_mx (dst, dst_len, &pos, record->data.mx);
1337 break;
1338
1340 ret =
1341 GNUNET_DNSPARSER_builder_add_cert (dst, dst_len, &pos, record->data.cert);
1342 break;
1343
1345 ret =
1346 GNUNET_DNSPARSER_builder_add_soa (dst, dst_len, &pos, record->data.soa);
1347 break;
1348
1353 dst_len,
1354 &pos,
1355 record->data.hostname);
1356 break;
1358 ret =
1359 GNUNET_DNSPARSER_builder_add_srv (dst, dst_len, &pos, record->data.srv);
1360 break;
1362 ret =
1363 GNUNET_DNSPARSER_builder_add_uri (dst, dst_len, &pos, record->data.uri);
1364 break;
1365 default:
1366 if ( (pos + record->data.raw.data_len < pos) ||
1367 (pos + record->data.raw.data_len > dst_len) )
1368 {
1369 ret = GNUNET_NO;
1370 break;
1371 }
1372 GNUNET_memcpy (&dst[pos], record->data.raw.data, record->data.raw.data_len);
1373 pos += record->data.raw.data_len;
1374 ret = GNUNET_OK;
1375 break;
1376 }
1377 if (GNUNET_OK != ret)
1378 {
1379 *off = start;
1380 return GNUNET_NO;
1381 }
1382
1383 if (pos - (*off + sizeof(struct GNUNET_TUN_DnsRecordLine)) > UINT16_MAX)
1384 {
1385 /* record data too long */
1386 *off = start;
1387 return GNUNET_NO;
1388 }
1389 rl.type = htons (record->type);
1390 rl.dns_traffic_class = htons (record->dns_traffic_class);
1391 rl.ttl = htonl (
1393 / 1000LL / 1000LL); /* in seconds */
1394 rl.data_len = htons (
1395 (uint16_t) (pos - (*off + sizeof(struct GNUNET_TUN_DnsRecordLine))));
1396 GNUNET_memcpy (&dst[*off], &rl, sizeof(struct GNUNET_TUN_DnsRecordLine));
1397 *off = pos;
1398 return GNUNET_OK;
1399}
1400
1401
1416int
1418 uint16_t max,
1419 char **buf,
1420 size_t *buf_length)
1421{
1422 struct GNUNET_TUN_DnsHeader dns;
1423 size_t off;
1424 char tmp[max];
1425 int ret;
1426 int trc;
1427
1428 if ((p->num_queries > UINT16_MAX) || (p->num_answers > UINT16_MAX) ||
1429 (p->num_authority_records > UINT16_MAX) ||
1430 (p->num_additional_records > UINT16_MAX))
1431 return GNUNET_SYSERR;
1432 dns.id = p->id;
1433 dns.flags = p->flags;
1434 dns.query_count = htons (p->num_queries);
1435 dns.answer_rcount = htons (p->num_answers);
1436 dns.authority_rcount = htons (p->num_authority_records);
1437 dns.additional_rcount = htons (p->num_additional_records);
1438
1439 off = sizeof(struct GNUNET_TUN_DnsHeader);
1440 trc = GNUNET_NO;
1441 for (unsigned int i = 0; i < p->num_queries; i++)
1442 {
1444 sizeof(tmp),
1445 &off,
1446 &p->queries[i]);
1447 if (GNUNET_SYSERR == ret)
1448 return GNUNET_SYSERR;
1449 if (GNUNET_NO == ret)
1450 {
1451 dns.query_count = htons ((uint16_t) (i - 1));
1452 trc = GNUNET_YES;
1453 break;
1454 }
1455 }
1456 for (unsigned int i = 0; i < p->num_answers; i++)
1457 {
1458 ret = add_record (tmp, sizeof(tmp), &off, &p->answers[i]);
1459 if (GNUNET_SYSERR == ret)
1460 return GNUNET_SYSERR;
1461 if (GNUNET_NO == ret)
1462 {
1463 dns.answer_rcount = htons ((uint16_t) (i - 1));
1464 trc = GNUNET_YES;
1465 break;
1466 }
1467 }
1468 for (unsigned int i = 0; i < p->num_authority_records; i++)
1469 {
1470 ret = add_record (tmp, sizeof(tmp), &off, &p->authority_records[i]);
1471 if (GNUNET_SYSERR == ret)
1472 return GNUNET_SYSERR;
1473 if (GNUNET_NO == ret)
1474 {
1475 dns.authority_rcount = htons ((uint16_t) (i - 1));
1476 trc = GNUNET_YES;
1477 break;
1478 }
1479 }
1480 for (unsigned int i = 0; i < p->num_additional_records; i++)
1481 {
1482 ret = add_record (tmp, sizeof(tmp), &off, &p->additional_records[i]);
1483 if (GNUNET_SYSERR == ret)
1484 return GNUNET_SYSERR;
1485 if (GNUNET_NO == ret)
1486 {
1487 dns.additional_rcount = htons (i - 1);
1488 trc = GNUNET_YES;
1489 break;
1490 }
1491 }
1492
1493 if (GNUNET_YES == trc)
1494 dns.flags.message_truncated = 1;
1495 GNUNET_memcpy (tmp, &dns, sizeof(struct GNUNET_TUN_DnsHeader));
1496
1497 *buf = GNUNET_malloc (off);
1498 *buf_length = off;
1499 GNUNET_memcpy (*buf, tmp, off);
1500 if (GNUNET_YES == trc)
1501 return GNUNET_NO;
1502 return GNUNET_OK;
1503}
1504
1505
1513char *
1515{
1516 char *ret;
1517 size_t off;
1518 const uint8_t *idata;
1519
1520 idata = data;
1521 ret = GNUNET_malloc (data_size * 2 + 1);
1522 for (off = 0; off < data_size; off++)
1523 sprintf (&ret[off * 2], "%02x", idata[off]);
1524 return ret;
1525}
1526
1527
1536size_t
1537GNUNET_DNSPARSER_hex_to_bin (const char *hex, void *data)
1538{
1539 size_t data_size;
1540 size_t off;
1541 uint8_t *idata;
1542 unsigned int h;
1543 char in[3];
1544
1545 data_size = strlen (hex) / 2;
1546 idata = data;
1547 in[2] = '\0';
1548 for (off = 0; off < data_size; off++)
1549 {
1550 in[0] = tolower ((unsigned char) hex[off * 2]);
1551 in[1] = tolower ((unsigned char) hex[off * 2 + 1]);
1552 if (1 != sscanf (in, "%x", &h))
1553 return off;
1554 idata[off] = (uint8_t) h;
1555 }
1556 return off;
1557}
1558
1559
1560/* 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:1310
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:250
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:472
char * GNUNET_DNSPARSER_bin_to_hex(const void *data, size_t data_size)
Convert a block of binary data to HEX.
Definition dnsparser.c:1514
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:1002
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:1146
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition dnsparser.c:967
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:918
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:1080
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:882
#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:1537
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:934
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:427
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:598
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:1194
#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:554
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:513
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:900
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:370
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:1116
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:1235
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:951
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:389
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:1417
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:1272
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:639
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:746
struct GNUNET_DNSPARSER_Record * GNUNET_DNSPARSER_duplicate_record(const struct GNUNET_DNSPARSER_Record *r)
Duplicate (deep-copy) the given DNS record.
Definition dnsparser.c:827
#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:209
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.