GNUnet 0.22.2
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
52int
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
78int
80{
81 char *ldup;
82 char *output;
83 size_t slen;
84 char *tok;
85
86 ldup = GNUNET_strdup (name);
87 for (tok = strtok (ldup, "."); NULL != tok; tok = strtok (NULL, "."))
89 {
90 GNUNET_free (ldup);
91 return GNUNET_SYSERR;
92 }
93 GNUNET_free (ldup);
94 if (IDNA_SUCCESS != idna_to_ascii_8z (name, &output, IDNA_ALLOW_UNASSIGNED))
95 return GNUNET_SYSERR;
96 slen = strlen (output);
97 free (output);
98 return (slen > 253) ? GNUNET_SYSERR : GNUNET_OK;
99}
100
101
107void
109{
110 if (NULL == soa)
111 return;
112 GNUNET_free (soa->mname);
113 GNUNET_free (soa->rname);
114 GNUNET_free (soa);
115}
116
117
123void
125{
126 if (NULL == cert)
127 return;
129 GNUNET_free (cert);
130}
131
132
138void
140{
141 if (NULL == srv)
142 return;
143 GNUNET_free (srv->target);
144 GNUNET_free (srv);
145}
146
147
153void
155{
156 if (NULL == uri)
157 return;
158 GNUNET_free (uri->target);
160}
161
162
168void
170{
171 if (NULL == mx)
172 return;
173 GNUNET_free (mx->mxhost);
174 GNUNET_free (mx);
175}
176
177
183void
185{
186 GNUNET_free (r->name);
187 switch (r->type)
188 {
191 break;
192
195 break;
196
199 break;
200
203 break;
204
207 break;
208
213 break;
214
215 default:
217 break;
218 }
219}
220
221
232static char *
233parse_name (const char *udp_payload,
234 size_t udp_payload_length,
235 size_t *off,
236 unsigned int depth)
237{
238 const uint8_t *input = (const uint8_t *) udp_payload;
239 char *ret;
240 char *tmp;
241 char *xstr;
242 uint8_t len;
243 size_t xoff;
244 char *utf8;
245 Idna_rc rc;
246
247 ret = GNUNET_strdup ("");
248 while (1)
249 {
250 if (*off >= udp_payload_length)
251 {
252 GNUNET_break_op (0);
253 goto error;
254 }
255 len = input[*off];
256 if (0 == len)
257 {
258 (*off)++;
259 break;
260 }
261 if (len < 64)
262 {
263 if (*off + 1 + len > udp_payload_length)
264 {
265 GNUNET_break_op (0);
266 goto error;
267 }
268 GNUNET_asprintf (&tmp, "%.*s", (int) len, &udp_payload[*off + 1]);
269 if (IDNA_SUCCESS !=
270 (rc = idna_to_unicode_8z8z (tmp, &utf8, IDNA_ALLOW_UNASSIGNED)))
271 {
273 _ ("Failed to convert DNS IDNA name `%s' to UTF-8: %s\n"),
274 tmp,
275 idna_strerror (rc));
276 GNUNET_free (tmp);
277 GNUNET_asprintf (&tmp,
278 "%s%.*s.",
279 ret,
280 (int) len,
281 &udp_payload[*off + 1]);
282 }
283 else
284 {
285 GNUNET_free (tmp);
286 GNUNET_asprintf (&tmp, "%s%s.", ret, utf8);
287 free (utf8);
288 }
290 ret = tmp;
291 *off += 1 + len;
292 }
293 else if ((64 | 128) == (len & (64 | 128)))
294 {
295 if (depth > 32)
296 {
297 GNUNET_break_op (0);
298 goto error; /* hard bound on stack to prevent "infinite" recursion, disallow! */
299 }
300 /* pointer to string */
301 if (*off + 1 > udp_payload_length)
302 {
303 GNUNET_break_op (0);
304 goto error;
305 }
306 xoff = ((len - (64 | 128)) << 8) + input[*off + 1];
307 xstr = parse_name (udp_payload, udp_payload_length, &xoff, depth + 1);
308 if (NULL == xstr)
309 {
310 GNUNET_break_op (0);
311 goto error;
312 }
313 GNUNET_asprintf (&tmp, "%s%s.", ret, xstr);
315 GNUNET_free (xstr);
316 ret = tmp;
317 if (strlen (ret) > udp_payload_length)
318 {
319 GNUNET_break_op (0);
320 goto error; /* we are looping (building an infinite string) */
321 }
322 *off += 2;
323 /* pointers always terminate names */
324 break;
325 }
326 else
327 {
328 /* neither pointer nor inline string, not supported... */
329 GNUNET_break_op (0);
330 goto error;
331 }
332 }
333 if (0 < strlen (ret))
334 ret[strlen (ret) - 1] = '\0'; /* eat tailing '.' */
335 return ret;
336error:
337 GNUNET_break_op (0);
339 return NULL;
340}
341
342
352char *
353GNUNET_DNSPARSER_parse_name (const char *udp_payload,
354 size_t udp_payload_length,
355 size_t *off)
356{
357 return parse_name (udp_payload, udp_payload_length, off, 0);
358}
359
360
371int
372GNUNET_DNSPARSER_parse_query (const char *udp_payload,
373 size_t udp_payload_length,
374 size_t *off,
376{
377 char *name;
378 struct GNUNET_TUN_DnsQueryLine ql;
379
380 name = GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
381 if (NULL == name)
382 {
383 GNUNET_break_op (0);
384 return GNUNET_SYSERR;
385 }
386 q->name = name;
387 if (*off + sizeof(struct GNUNET_TUN_DnsQueryLine) > udp_payload_length)
388 {
389 GNUNET_break_op (0);
390 return GNUNET_SYSERR;
391 }
392 GNUNET_memcpy (&ql, &udp_payload[*off], sizeof(ql));
393 *off += sizeof(ql);
394 q->type = ntohs (ql.type);
395 q->dns_traffic_class = ntohs (ql.dns_traffic_class);
396 return GNUNET_OK;
397}
398
399
410GNUNET_DNSPARSER_parse_soa (const char *udp_payload,
411 size_t udp_payload_length,
412 size_t *off)
413{
414 struct GNUNET_DNSPARSER_SoaRecord *soa;
415 struct GNUNET_TUN_DnsSoaRecord soa_bin;
416 size_t old_off;
417
418 old_off = *off;
420 soa->mname =
421 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
422 soa->rname =
423 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
424 if ((NULL == soa->mname) || (NULL == soa->rname) ||
425 (*off + sizeof(struct GNUNET_TUN_DnsSoaRecord) > udp_payload_length))
426 {
427 GNUNET_break_op (0);
429 *off = old_off;
430 return NULL;
431 }
432 GNUNET_memcpy (&soa_bin,
433 &udp_payload[*off],
434 sizeof(struct GNUNET_TUN_DnsSoaRecord));
435 soa->serial = ntohl (soa_bin.serial);
436 soa->refresh = ntohl (soa_bin.refresh);
437 soa->retry = ntohl (soa_bin.retry);
438 soa->expire = ntohl (soa_bin.expire);
439 soa->minimum_ttl = ntohl (soa_bin.minimum);
440 (*off) += sizeof(struct GNUNET_TUN_DnsSoaRecord);
441 return soa;
442}
443
444
455GNUNET_DNSPARSER_parse_mx (const char *udp_payload,
456 size_t udp_payload_length,
457 size_t *off)
458{
459 struct GNUNET_DNSPARSER_MxRecord *mx;
460 uint16_t mxpref;
461 size_t old_off;
462
463 old_off = *off;
464 if (*off + sizeof(uint16_t) > udp_payload_length)
465 {
466 GNUNET_break_op (0);
467 return NULL;
468 }
469 GNUNET_memcpy (&mxpref, &udp_payload[*off], sizeof(uint16_t));
470 (*off) += sizeof(uint16_t);
472 mx->preference = ntohs (mxpref);
473 mx->mxhost =
474 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
475 if (NULL == mx->mxhost)
476 {
477 GNUNET_break_op (0);
479 *off = old_off;
480 return NULL;
481 }
482 return mx;
483}
484
485
496GNUNET_DNSPARSER_parse_srv (const char *udp_payload,
497 size_t udp_payload_length,
498 size_t *off)
499{
500 struct GNUNET_DNSPARSER_SrvRecord *srv;
501 struct GNUNET_TUN_DnsSrvRecord srv_bin;
502 size_t old_off;
503
504 old_off = *off;
505 if (*off + sizeof(struct GNUNET_TUN_DnsSrvRecord) > udp_payload_length)
506 return NULL;
507 GNUNET_memcpy (&srv_bin,
508 &udp_payload[*off],
509 sizeof(struct GNUNET_TUN_DnsSrvRecord));
510 (*off) += sizeof(struct GNUNET_TUN_DnsSrvRecord);
512 srv->priority = ntohs (srv_bin.prio);
513 srv->weight = ntohs (srv_bin.weight);
514 srv->port = ntohs (srv_bin.port);
515 srv->target =
516 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
517 if (NULL == srv->target)
518 {
520 *off = old_off;
521 return NULL;
522 }
523 return srv;
524}
525
526
537GNUNET_DNSPARSER_parse_uri (const char *udp_payload,
538 size_t udp_payload_length,
539 size_t *off)
540{
542 struct GNUNET_TUN_DnsUriRecord uri_bin;
543 size_t old_off;
544 int max_len;
545 int len;
546
547 old_off = *off;
548 if (*off + sizeof(struct GNUNET_TUN_DnsUriRecord) > udp_payload_length)
549 return NULL;
550 GNUNET_memcpy (&uri_bin,
551 &udp_payload[*off],
552 sizeof(struct GNUNET_TUN_DnsUriRecord));
553 (*off) += sizeof(struct GNUNET_TUN_DnsUriRecord);
555 uri->priority = ntohs (uri_bin.prio);
556 uri->weight = ntohs (uri_bin.weight);
557 max_len = udp_payload_length - sizeof(struct GNUNET_TUN_DnsUriRecord);
558 len = GNUNET_asprintf (&(uri->target), "%.*s", max_len,
559 &udp_payload[*off]);
560 (*off) += len;
561 if (NULL == uri->target)
562 {
564 *off = old_off;
565 return NULL;
566 }
567 return uri;
568}
569
570
581GNUNET_DNSPARSER_parse_cert (const char *udp_payload,
582 size_t udp_payload_length,
583 size_t *off)
584{
585 struct GNUNET_DNSPARSER_CertRecord *cert;
586 struct GNUNET_TUN_DnsCertRecord dcert;
587
588 if (*off + sizeof(struct GNUNET_TUN_DnsCertRecord) >= udp_payload_length)
589 {
590 GNUNET_break_op (0);
591 return NULL;
592 }
593 GNUNET_memcpy (&dcert,
594 &udp_payload[*off],
595 sizeof(struct GNUNET_TUN_DnsCertRecord));
596 (*off) += sizeof(struct GNUNET_TUN_DnsCertRecord);
598 cert->cert_type = ntohs (dcert.cert_type);
599 cert->cert_tag = ntohs (dcert.cert_tag);
600 cert->algorithm = dcert.algorithm;
601 cert->certificate_size = udp_payload_length - (*off);
604 &udp_payload[*off],
605 cert->certificate_size);
606 (*off) += cert->certificate_size;
607 return cert;
608}
609
610
621int
622GNUNET_DNSPARSER_parse_record (const char *udp_payload,
623 size_t udp_payload_length,
624 size_t *off,
625 struct GNUNET_DNSPARSER_Record *r)
626{
627 char *name;
628 struct GNUNET_TUN_DnsRecordLine rl;
629 size_t old_off;
630 uint16_t data_len;
631
632 name = GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
633 if (NULL == name)
634 {
635 GNUNET_break_op (0);
636 return GNUNET_SYSERR;
637 }
638 r->name = name;
639 if (*off + sizeof(struct GNUNET_TUN_DnsRecordLine) > udp_payload_length)
640 {
641 GNUNET_break_op (0);
642 return GNUNET_SYSERR;
643 }
644 GNUNET_memcpy (&rl, &udp_payload[*off], sizeof(rl));
645 (*off) += sizeof(rl);
646 r->type = ntohs (rl.type);
647 r->dns_traffic_class = ntohs (rl.dns_traffic_class);
650 data_len = ntohs (rl.data_len);
651 if (*off + data_len > udp_payload_length)
652 {
653 GNUNET_break_op (0);
654 return GNUNET_SYSERR;
655 }
656 old_off = *off;
657 switch (r->type)
658 {
663 r->data.hostname =
664 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
665 if ((NULL == r->data.hostname) || (old_off + data_len != *off))
666 return GNUNET_SYSERR;
667 return GNUNET_OK;
668
670 r->data.soa =
671 GNUNET_DNSPARSER_parse_soa (udp_payload, udp_payload_length, off);
672 if ((NULL == r->data.soa) || (old_off + data_len != *off))
673 {
674 GNUNET_break_op (0);
675 return GNUNET_SYSERR;
676 }
677 return GNUNET_OK;
678
680 r->data.mx =
681 GNUNET_DNSPARSER_parse_mx (udp_payload, udp_payload_length, off);
682 if ((NULL == r->data.mx) || (old_off + data_len != *off))
683 {
684 GNUNET_break_op (0);
685 return GNUNET_SYSERR;
686 }
687 return GNUNET_OK;
688
690 r->data.srv =
691 GNUNET_DNSPARSER_parse_srv (udp_payload, udp_payload_length, off);
692 if ((NULL == r->data.srv) || (old_off + data_len != *off))
693 {
694 GNUNET_break_op (0);
695 return GNUNET_SYSERR;
696 }
697 return GNUNET_OK;
698
700 r->data.uri =
701 GNUNET_DNSPARSER_parse_uri (udp_payload, udp_payload_length, off);
702 if ((NULL == r->data.uri) || (old_off + data_len != *off))
703 {
704 GNUNET_break_op (0);
705 return GNUNET_SYSERR;
706 }
707 return GNUNET_OK;
708
709 default:
712 GNUNET_memcpy (r->data.raw.data, &udp_payload[*off], data_len);
713 break;
714 }
715 (*off) += data_len;
716 return GNUNET_OK;
717}
718
719
729GNUNET_DNSPARSER_parse (const char *udp_payload, size_t udp_payload_length)
730{
732 const struct GNUNET_TUN_DnsHeader *dns;
733 size_t off;
734 unsigned int n;
735
736 if (udp_payload_length < sizeof(struct GNUNET_TUN_DnsHeader))
737 return NULL;
738 dns = (const struct GNUNET_TUN_DnsHeader *) udp_payload;
739 off = sizeof(struct GNUNET_TUN_DnsHeader);
741 p->flags = dns->flags;
742 p->id = dns->id;
743 n = ntohs (dns->query_count);
744 if (n > 0)
745 {
746 p->queries = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Query);
747 p->num_queries = n;
748 for (unsigned int i = 0; i < n; i++)
749 if (GNUNET_OK != GNUNET_DNSPARSER_parse_query (udp_payload,
750 udp_payload_length,
751 &off,
752 &p->queries[i]))
753 goto error;
754 }
755 n = ntohs (dns->answer_rcount);
756 if (n > 0)
757 {
758 p->answers = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Record);
759 p->num_answers = n;
760 for (unsigned int i = 0; i < n; i++)
761 if (GNUNET_OK != GNUNET_DNSPARSER_parse_record (udp_payload,
762 udp_payload_length,
763 &off,
764 &p->answers[i]))
765 goto error;
766 }
767 n = ntohs (dns->authority_rcount);
768 if (n > 0)
769 {
770 p->authority_records = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Record);
771 p->num_authority_records = n;
772 for (unsigned int i = 0; i < n; i++)
773 if (GNUNET_OK != GNUNET_DNSPARSER_parse_record (udp_payload,
774 udp_payload_length,
775 &off,
776 &p->authority_records[i]))
777 goto error;
778 }
779 n = ntohs (dns->additional_rcount);
780 if (n > 0)
781 {
782 p->additional_records =
784 p->num_additional_records = n;
785 for (unsigned int i = 0; i < n; i++)
786 {
787 if (GNUNET_OK !=
789 udp_payload_length,
790 &off,
791 &p->additional_records[i]))
792 goto error;
793 }
794 }
795 return p;
796error:
797 GNUNET_break_op (0);
799 return NULL;
800}
801
802
811{
812 struct GNUNET_DNSPARSER_Record *dup = GNUNET_memdup (r, sizeof(*r));
813
814 dup->name = GNUNET_strdup (r->name);
815 switch (r->type)
816 {
821 break;
822 }
823
826 break;
827 }
828
831 break;
832 }
833
836 break;
837 }
838
841 break;
842 }
843
846 break;
847 }
848
849 default: {
851 r->data.raw.data_len);
852 }
853 }
854 return dup;
855}
856
857
866 const struct GNUNET_DNSPARSER_SoaRecord *r)
867{
868 struct GNUNET_DNSPARSER_SoaRecord *dup = GNUNET_memdup (r, sizeof(*r));
869
870 dup->mname = GNUNET_strdup (r->mname);
871 dup->rname = GNUNET_strdup (r->rname);
872 return dup;
873}
874
875
884 const struct GNUNET_DNSPARSER_CertRecord *r)
885{
886 struct GNUNET_DNSPARSER_CertRecord *dup = GNUNET_memdup (r, sizeof(*r));
887
890 return dup;
891}
892
893
902{
903 struct GNUNET_DNSPARSER_MxRecord *dup = GNUNET_memdup (r, sizeof(*r));
904
905 dup->mxhost = GNUNET_strdup (r->mxhost);
906 return dup;
907}
908
909
918 const struct GNUNET_DNSPARSER_SrvRecord *r)
919{
920 struct GNUNET_DNSPARSER_SrvRecord *dup = GNUNET_memdup (r, sizeof(*r));
921
922 dup->target = GNUNET_strdup (r->target);
923 return dup;
924}
925
926
935 const struct GNUNET_DNSPARSER_UriRecord *r)
936{
937 struct GNUNET_DNSPARSER_UriRecord *dup = GNUNET_memdup (r, sizeof(*r));
938
939 dup->target = GNUNET_strdup (r->target);
940 return dup;
941}
942
943
949void
951{
952 for (unsigned int i = 0; i < p->num_queries; i++)
953 GNUNET_free (p->queries[i].name);
954 GNUNET_free (p->queries);
955 for (unsigned int i = 0; i < p->num_answers; i++)
956 GNUNET_DNSPARSER_free_record (&p->answers[i]);
957 GNUNET_free (p->answers);
958 for (unsigned int i = 0; i < p->num_authority_records; i++)
959 GNUNET_DNSPARSER_free_record (&p->authority_records[i]);
960 GNUNET_free (p->authority_records);
961 for (unsigned int i = 0; i < p->num_additional_records; i++)
962 GNUNET_DNSPARSER_free_record (&p->additional_records[i]);
963 GNUNET_free (p->additional_records);
964 GNUNET_free (p);
965}
966
967
968/* ********************** DNS packet assembly code **************** */
969
970
984int
986 size_t dst_len,
987 size_t *off,
988 const char *name)
989{
990 const char *dot;
991 const char *idna_name;
992 char *idna_start;
993 size_t start;
994 size_t pos;
995 size_t len;
996 Idna_rc rc;
997
998 if (NULL == name)
999 return GNUNET_SYSERR;
1000
1001 if (IDNA_SUCCESS !=
1002 (rc = idna_to_ascii_8z (name, &idna_start, IDNA_ALLOW_UNASSIGNED)))
1003 {
1005 _ (
1006 "Failed to convert UTF-8 name `%s' to DNS IDNA format: %s\n"),
1007 name,
1008 idna_strerror (rc));
1009 return GNUNET_NO;
1010 }
1011 idna_name = idna_start;
1012 GNUNET_assert (*off <= SIZE_MAX - strlen (idna_name) - 2);
1013 start = *off;
1014 if (start + strlen (idna_name) + 2 > dst_len)
1015 goto fail;
1016 pos = start;
1017 do
1018 {
1019 dot = strchr (idna_name, '.');
1020 if (NULL == dot)
1021 len = strlen (idna_name);
1022 else
1023 len = dot - idna_name;
1024 if (len == 0)
1025 break;
1026 if (len >= 64)
1027 {
1029 "Invalid DNS name `%s': label with %u characters encountered\n",
1030 name,
1031 (unsigned int) len);
1032 goto fail; /* label too long or empty */
1033 }
1034 dst[pos++] = (char) (uint8_t) len;
1035 GNUNET_memcpy (&dst[pos], idna_name, len);
1036 pos += len;
1037 idna_name += len + 1; /* also skip dot */
1038 }
1039 while (NULL != dot);
1040 dst[pos++] = '\0'; /* terminator */
1041 *off = pos;
1042 free (idna_start);
1043 return GNUNET_OK;
1044fail:
1045 free (idna_start);
1046 return GNUNET_NO;
1047}
1048
1049
1062int
1064 size_t dst_len,
1065 size_t *off,
1066 const struct GNUNET_DNSPARSER_Query *query)
1067{
1068 int ret;
1069 struct GNUNET_TUN_DnsQueryLine ql;
1070
1071 GNUNET_assert (dst_len >= sizeof (ql));
1073 dst_len - sizeof(ql),
1074 off,
1075 query->name);
1076 if (ret != GNUNET_OK)
1077 return ret;
1078 ql.type = htons (query->type);
1079 ql.dns_traffic_class = htons (query->dns_traffic_class);
1080 GNUNET_memcpy (&dst[*off], &ql, sizeof(ql));
1081 (*off) += sizeof(ql);
1082 return GNUNET_OK;
1083}
1084
1085
1098int
1100 size_t dst_len,
1101 size_t *off,
1102 const struct GNUNET_DNSPARSER_MxRecord *mx)
1103{
1104 uint16_t mxpref;
1105
1106 GNUNET_assert (*off <= SIZE_MAX - sizeof (uint16_t));
1107 if (*off + sizeof(uint16_t) > dst_len)
1108 return GNUNET_NO;
1109 mxpref = htons (mx->preference);
1110 GNUNET_memcpy (&dst[*off], &mxpref, sizeof(mxpref));
1111 (*off) += sizeof(mxpref);
1112 return GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, mx->mxhost);
1113}
1114
1115
1128int
1130 char *dst,
1131 size_t dst_len,
1132 size_t *off,
1133 const struct GNUNET_DNSPARSER_CertRecord *cert)
1134{
1135 struct GNUNET_TUN_DnsCertRecord dcert;
1136
1137#ifdef __clang__
1138#pragma clang diagnostic push
1139#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
1140#endif
1141 if ((cert->cert_type > UINT16_MAX) || (cert->algorithm > UINT8_MAX))
1142 {
1143 GNUNET_break (0);
1144 return GNUNET_SYSERR;
1145 }
1146#ifdef __clang__
1147#pragma clang diagnostic pop
1148#endif
1149 GNUNET_assert (*off <= SIZE_MAX - sizeof (dcert));
1150 GNUNET_assert (cert->certificate_size <= SIZE_MAX - *off - sizeof (dcert));
1151 if (*off + sizeof(dcert) + cert->certificate_size > dst_len)
1152 return GNUNET_NO;
1153 dcert.cert_type = htons ((uint16_t) cert->cert_type);
1154 dcert.cert_tag = htons ((uint16_t) cert->cert_tag);
1155 dcert.algorithm = (uint8_t) cert->algorithm;
1156 GNUNET_memcpy (&dst[*off], &dcert, sizeof(dcert));
1157 (*off) += sizeof(dcert);
1158 GNUNET_memcpy (&dst[*off], cert->certificate_data, cert->certificate_size);
1159 (*off) += cert->certificate_size;
1160 return GNUNET_OK;
1161}
1162
1163
1176int
1178 size_t dst_len,
1179 size_t *off,
1180 const struct GNUNET_DNSPARSER_SoaRecord *soa)
1181{
1182 struct GNUNET_TUN_DnsSoaRecord sd;
1183 int ret;
1184
1185 if ((GNUNET_OK !=
1186 (ret =
1187 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, soa->mname))) ||
1188 (GNUNET_OK !=
1189 (ret =
1190 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, soa->rname))))
1191 return ret;
1192 if (*off + sizeof(struct GNUNET_TUN_DnsSoaRecord) > dst_len)
1193 return GNUNET_NO;
1194 sd.serial = htonl (soa->serial);
1195 sd.refresh = htonl (soa->refresh);
1196 sd.retry = htonl (soa->retry);
1197 sd.expire = htonl (soa->expire);
1198 sd.minimum = htonl (soa->minimum_ttl);
1199 GNUNET_memcpy (&dst[*off], &sd, sizeof(sd));
1200 (*off) += sizeof(sd);
1201 return GNUNET_OK;
1202}
1203
1204
1217int
1219 size_t dst_len,
1220 size_t *off,
1221 const struct GNUNET_DNSPARSER_SrvRecord *srv)
1222{
1223 struct GNUNET_TUN_DnsSrvRecord sd;
1224 int ret;
1225
1226 GNUNET_assert (*off <= SIZE_MAX - sizeof (sd));
1227 if (*off + sizeof(sd) > dst_len)
1228 return GNUNET_NO;
1229 sd.prio = htons (srv->priority);
1230 sd.weight = htons (srv->weight);
1231 sd.port = htons (srv->port);
1232 GNUNET_memcpy (&dst[*off], &sd, sizeof(sd));
1233 (*off) += sizeof(sd);
1234 if (GNUNET_OK !=
1235 (ret =
1236 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, srv->target)))
1237 return ret;
1238 return GNUNET_OK;
1239}
1240
1241
1254int
1256 size_t dst_len,
1257 size_t *off,
1258 const struct GNUNET_DNSPARSER_UriRecord *uri)
1259{
1260 struct GNUNET_TUN_DnsUriRecord sd;
1261 int written;
1262 size_t max_target_len;
1263
1264 GNUNET_assert (dst_len > sizeof (sd));
1265 GNUNET_assert (*off <= SIZE_MAX - sizeof (sd));
1266 max_target_len = dst_len - sizeof (sd) - 1;
1267 if (*off + sizeof(sd) > dst_len)
1268 return GNUNET_NO;
1269 sd.prio = htons (uri->priority);
1270 sd.weight = htons (uri->weight);
1271 GNUNET_memcpy (&dst[*off], &sd, sizeof(sd));
1272 (*off) += sizeof(sd);
1273 written = GNUNET_snprintf (&dst[*off], max_target_len, "%s", uri->target);
1274 (*off) += written;
1275 dst[*off] = '\0';
1276 return GNUNET_OK;
1277}
1278
1279
1292static int
1293add_record (char *dst,
1294 size_t dst_len,
1295 size_t *off,
1296 const struct GNUNET_DNSPARSER_Record *record)
1297{
1298 int ret;
1299 size_t start;
1300 size_t pos;
1301 struct GNUNET_TUN_DnsRecordLine rl;
1302
1303 if (dst_len < sizeof(struct GNUNET_TUN_DnsRecordLine))
1304 return GNUNET_NO;
1305 start = *off;
1307 dst,
1308 dst_len - sizeof(struct GNUNET_TUN_DnsRecordLine),
1309 off,
1310 record->name);
1311 if (GNUNET_OK != ret)
1312 return ret;
1313 /* '*off' is now the position where we will need to write the record line */
1314
1315 pos = *off + sizeof(struct GNUNET_TUN_DnsRecordLine);
1316 switch (record->type)
1317 {
1319 ret = GNUNET_DNSPARSER_builder_add_mx (dst, dst_len, &pos, record->data.mx);
1320 break;
1321
1323 ret =
1324 GNUNET_DNSPARSER_builder_add_cert (dst, dst_len, &pos, record->data.cert);
1325 break;
1326
1328 ret =
1329 GNUNET_DNSPARSER_builder_add_soa (dst, dst_len, &pos, record->data.soa);
1330 break;
1331
1336 dst_len,
1337 &pos,
1338 record->data.hostname);
1339 break;
1341 ret =
1342 GNUNET_DNSPARSER_builder_add_srv (dst, dst_len, &pos, record->data.srv);
1343 break;
1345 ret =
1346 GNUNET_DNSPARSER_builder_add_uri (dst, dst_len, &pos, record->data.uri);
1347 break;
1348 default:
1349 if ( (pos + record->data.raw.data_len < pos) ||
1350 (pos + record->data.raw.data_len > dst_len) )
1351 {
1352 ret = GNUNET_NO;
1353 break;
1354 }
1355 GNUNET_memcpy (&dst[pos], record->data.raw.data, record->data.raw.data_len);
1356 pos += record->data.raw.data_len;
1357 ret = GNUNET_OK;
1358 break;
1359 }
1360 if (GNUNET_OK != ret)
1361 {
1362 *off = start;
1363 return GNUNET_NO;
1364 }
1365
1366 if (pos - (*off + sizeof(struct GNUNET_TUN_DnsRecordLine)) > UINT16_MAX)
1367 {
1368 /* record data too long */
1369 *off = start;
1370 return GNUNET_NO;
1371 }
1372 rl.type = htons (record->type);
1373 rl.dns_traffic_class = htons (record->dns_traffic_class);
1374 rl.ttl = htonl (
1376 / 1000LL / 1000LL); /* in seconds */
1377 rl.data_len = htons (
1378 (uint16_t) (pos - (*off + sizeof(struct GNUNET_TUN_DnsRecordLine))));
1379 GNUNET_memcpy (&dst[*off], &rl, sizeof(struct GNUNET_TUN_DnsRecordLine));
1380 *off = pos;
1381 return GNUNET_OK;
1382}
1383
1384
1399int
1401 uint16_t max,
1402 char **buf,
1403 size_t *buf_length)
1404{
1405 struct GNUNET_TUN_DnsHeader dns;
1406 size_t off;
1407 char tmp[max];
1408 int ret;
1409 int trc;
1410
1411 if ((p->num_queries > UINT16_MAX) || (p->num_answers > UINT16_MAX) ||
1412 (p->num_authority_records > UINT16_MAX) ||
1413 (p->num_additional_records > UINT16_MAX))
1414 return GNUNET_SYSERR;
1415 dns.id = p->id;
1416 dns.flags = p->flags;
1417 dns.query_count = htons (p->num_queries);
1418 dns.answer_rcount = htons (p->num_answers);
1419 dns.authority_rcount = htons (p->num_authority_records);
1420 dns.additional_rcount = htons (p->num_additional_records);
1421
1422 off = sizeof(struct GNUNET_TUN_DnsHeader);
1423 trc = GNUNET_NO;
1424 for (unsigned int i = 0; i < p->num_queries; i++)
1425 {
1427 sizeof(tmp),
1428 &off,
1429 &p->queries[i]);
1430 if (GNUNET_SYSERR == ret)
1431 return GNUNET_SYSERR;
1432 if (GNUNET_NO == ret)
1433 {
1434 dns.query_count = htons ((uint16_t) (i - 1));
1435 trc = GNUNET_YES;
1436 break;
1437 }
1438 }
1439 for (unsigned int i = 0; i < p->num_answers; i++)
1440 {
1441 ret = add_record (tmp, sizeof(tmp), &off, &p->answers[i]);
1442 if (GNUNET_SYSERR == ret)
1443 return GNUNET_SYSERR;
1444 if (GNUNET_NO == ret)
1445 {
1446 dns.answer_rcount = htons ((uint16_t) (i - 1));
1447 trc = GNUNET_YES;
1448 break;
1449 }
1450 }
1451 for (unsigned int i = 0; i < p->num_authority_records; i++)
1452 {
1453 ret = add_record (tmp, sizeof(tmp), &off, &p->authority_records[i]);
1454 if (GNUNET_SYSERR == ret)
1455 return GNUNET_SYSERR;
1456 if (GNUNET_NO == ret)
1457 {
1458 dns.authority_rcount = htons ((uint16_t) (i - 1));
1459 trc = GNUNET_YES;
1460 break;
1461 }
1462 }
1463 for (unsigned int i = 0; i < p->num_additional_records; i++)
1464 {
1465 ret = add_record (tmp, sizeof(tmp), &off, &p->additional_records[i]);
1466 if (GNUNET_SYSERR == ret)
1467 return GNUNET_SYSERR;
1468 if (GNUNET_NO == ret)
1469 {
1470 dns.additional_rcount = htons (i - 1);
1471 trc = GNUNET_YES;
1472 break;
1473 }
1474 }
1475
1476 if (GNUNET_YES == trc)
1477 dns.flags.message_truncated = 1;
1478 GNUNET_memcpy (tmp, &dns, sizeof(struct GNUNET_TUN_DnsHeader));
1479
1480 *buf = GNUNET_malloc (off);
1481 *buf_length = off;
1482 GNUNET_memcpy (*buf, tmp, off);
1483 if (GNUNET_YES == trc)
1484 return GNUNET_NO;
1485 return GNUNET_OK;
1486}
1487
1488
1496char *
1498{
1499 char *ret;
1500 size_t off;
1501 const uint8_t *idata;
1502
1503 idata = data;
1504 ret = GNUNET_malloc (data_size * 2 + 1);
1505 for (off = 0; off < data_size; off++)
1506 sprintf (&ret[off * 2], "%02x", idata[off]);
1507 return ret;
1508}
1509
1510
1519size_t
1520GNUNET_DNSPARSER_hex_to_bin (const char *hex, void *data)
1521{
1522 size_t data_size;
1523 size_t off;
1524 uint8_t *idata;
1525 unsigned int h;
1526 char in[3];
1527
1528 data_size = strlen (hex) / 2;
1529 idata = data;
1530 in[2] = '\0';
1531 for (off = 0; off < data_size; off++)
1532 {
1533 in[0] = tolower ((unsigned char) hex[off * 2]);
1534 in[1] = tolower ((unsigned char) hex[off * 2 + 1]);
1535 if (1 != sscanf (in, "%x", &h))
1536 return off;
1537 idata[off] = (uint8_t) h;
1538 }
1539 return off;
1540}
1541
1542
1543/* 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:1293
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:233
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_OS_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:455
char * GNUNET_DNSPARSER_bin_to_hex(const void *data, size_t data_size)
Convert a block of binary data to HEX.
Definition: dnsparser.c:1497
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:985
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:1129
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition: dnsparser.c:950
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:901
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:1063
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:865
#define GNUNET_DNSPARSER_TYPE_SRV
void GNUNET_DNSPARSER_free_record(struct GNUNET_DNSPARSER_Record *r)
Free the given DNS record.
Definition: dnsparser.c:184
#define GNUNET_DNSPARSER_TYPE_SOA
void GNUNET_DNSPARSER_free_cert(struct GNUNET_DNSPARSER_CertRecord *cert)
Free CERT information record.
Definition: dnsparser.c:124
#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:1520
void GNUNET_DNSPARSER_free_srv(struct GNUNET_DNSPARSER_SrvRecord *srv)
Free SRV information record.
Definition: dnsparser.c:139
#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:917
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:410
int 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
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:581
void GNUNET_DNSPARSER_free_uri(struct GNUNET_DNSPARSER_UriRecord *uri)
Free URI information record.
Definition: dnsparser.c:154
#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:1177
#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:537
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:496
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:883
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:353
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:1099
void GNUNET_DNSPARSER_free_soa(struct GNUNET_DNSPARSER_SoaRecord *soa)
Free SOA information record.
Definition: dnsparser.c:108
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:1218
void GNUNET_DNSPARSER_free_mx(struct GNUNET_DNSPARSER_MxRecord *mx)
Free MX information record.
Definition: dnsparser.c:169
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:934
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:372
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:1400
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:1255
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:622
#define GNUNET_DNSPARSER_TYPE_MX
int 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
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:729
struct GNUNET_DNSPARSER_Record * GNUNET_DNSPARSER_duplicate_record(const struct GNUNET_DNSPARSER_Record *r)
Duplicate (deep-copy) the given DNS record.
Definition: dnsparser.c:810
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ 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?
char * name
Name of the record that the query is for (0-terminated).
struct GNUNET_DNSPARSER_RawRecord raw
Raw data for all other types.
union GNUNET_DNSPARSER_Record::@20 data
Payload of the record (which one of these is valid depends on the 'type').
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.
DNS query prefix.
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.