GNUnet 0.21.1
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
545 old_off = *off;
546 if (*off + sizeof(struct GNUNET_TUN_DnsUriRecord) > udp_payload_length)
547 return NULL;
548 GNUNET_memcpy (&uri_bin,
549 &udp_payload[*off],
550 sizeof(struct GNUNET_TUN_DnsUriRecord));
551 (*off) += sizeof(struct GNUNET_TUN_DnsUriRecord);
553 uri->priority = ntohs (uri_bin.prio);
554 uri->weight = ntohs (uri_bin.weight);
555 int max_len = udp_payload_length - sizeof(struct GNUNET_TUN_DnsUriRecord);
556 int len = GNUNET_asprintf (&(uri->target), "%.*s", max_len,
557 &udp_payload[*off]);
558 (*off) += len;
559 if (NULL == uri->target)
560 {
562 *off = old_off;
563 return NULL;
564 }
565 return uri;
566}
567
568
579GNUNET_DNSPARSER_parse_cert (const char *udp_payload,
580 size_t udp_payload_length,
581 size_t *off)
582{
583 struct GNUNET_DNSPARSER_CertRecord *cert;
584 struct GNUNET_TUN_DnsCertRecord dcert;
585
586 if (*off + sizeof(struct GNUNET_TUN_DnsCertRecord) >= udp_payload_length)
587 {
588 GNUNET_break_op (0);
589 return NULL;
590 }
591 GNUNET_memcpy (&dcert,
592 &udp_payload[*off],
593 sizeof(struct GNUNET_TUN_DnsCertRecord));
594 (*off) += sizeof(struct GNUNET_TUN_DnsCertRecord);
596 cert->cert_type = ntohs (dcert.cert_type);
597 cert->cert_tag = ntohs (dcert.cert_tag);
598 cert->algorithm = dcert.algorithm;
599 cert->certificate_size = udp_payload_length - (*off);
602 &udp_payload[*off],
603 cert->certificate_size);
604 (*off) += cert->certificate_size;
605 return cert;
606}
607
608
619int
620GNUNET_DNSPARSER_parse_record (const char *udp_payload,
621 size_t udp_payload_length,
622 size_t *off,
623 struct GNUNET_DNSPARSER_Record *r)
624{
625 char *name;
626 struct GNUNET_TUN_DnsRecordLine rl;
627 size_t old_off;
628 uint16_t data_len;
629
630 name = GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
631 if (NULL == name)
632 {
633 GNUNET_break_op (0);
634 return GNUNET_SYSERR;
635 }
636 r->name = name;
637 if (*off + sizeof(struct GNUNET_TUN_DnsRecordLine) > udp_payload_length)
638 {
639 GNUNET_break_op (0);
640 return GNUNET_SYSERR;
641 }
642 GNUNET_memcpy (&rl, &udp_payload[*off], sizeof(rl));
643 (*off) += sizeof(rl);
644 r->type = ntohs (rl.type);
645 r->dns_traffic_class = ntohs (rl.dns_traffic_class);
648 data_len = ntohs (rl.data_len);
649 if (*off + data_len > udp_payload_length)
650 {
651 GNUNET_break_op (0);
652 return GNUNET_SYSERR;
653 }
654 old_off = *off;
655 switch (r->type)
656 {
661 r->data.hostname =
662 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
663 if ((NULL == r->data.hostname) || (old_off + data_len != *off))
664 return GNUNET_SYSERR;
665 return GNUNET_OK;
666
668 r->data.soa =
669 GNUNET_DNSPARSER_parse_soa (udp_payload, udp_payload_length, off);
670 if ((NULL == r->data.soa) || (old_off + data_len != *off))
671 {
672 GNUNET_break_op (0);
673 return GNUNET_SYSERR;
674 }
675 return GNUNET_OK;
676
678 r->data.mx =
679 GNUNET_DNSPARSER_parse_mx (udp_payload, udp_payload_length, off);
680 if ((NULL == r->data.mx) || (old_off + data_len != *off))
681 {
682 GNUNET_break_op (0);
683 return GNUNET_SYSERR;
684 }
685 return GNUNET_OK;
686
688 r->data.srv =
689 GNUNET_DNSPARSER_parse_srv (udp_payload, udp_payload_length, off);
690 if ((NULL == r->data.srv) || (old_off + data_len != *off))
691 {
692 GNUNET_break_op (0);
693 return GNUNET_SYSERR;
694 }
695 return GNUNET_OK;
696
698 r->data.uri =
699 GNUNET_DNSPARSER_parse_uri (udp_payload, udp_payload_length, off);
700 if ((NULL == r->data.uri) || (old_off + data_len != *off))
701 {
702 GNUNET_break_op (0);
703 return GNUNET_SYSERR;
704 }
705 return GNUNET_OK;
706
707 default:
710 GNUNET_memcpy (r->data.raw.data, &udp_payload[*off], data_len);
711 break;
712 }
713 (*off) += data_len;
714 return GNUNET_OK;
715}
716
717
727GNUNET_DNSPARSER_parse (const char *udp_payload, size_t udp_payload_length)
728{
730 const struct GNUNET_TUN_DnsHeader *dns;
731 size_t off;
732 unsigned int n;
733
734 if (udp_payload_length < sizeof(struct GNUNET_TUN_DnsHeader))
735 return NULL;
736 dns = (const struct GNUNET_TUN_DnsHeader *) udp_payload;
737 off = sizeof(struct GNUNET_TUN_DnsHeader);
739 p->flags = dns->flags;
740 p->id = dns->id;
741 n = ntohs (dns->query_count);
742 if (n > 0)
743 {
744 p->queries = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Query);
745 p->num_queries = n;
746 for (unsigned int i = 0; i < n; i++)
747 if (GNUNET_OK != GNUNET_DNSPARSER_parse_query (udp_payload,
748 udp_payload_length,
749 &off,
750 &p->queries[i]))
751 goto error;
752 }
753 n = ntohs (dns->answer_rcount);
754 if (n > 0)
755 {
756 p->answers = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Record);
757 p->num_answers = n;
758 for (unsigned int i = 0; i < n; i++)
759 if (GNUNET_OK != GNUNET_DNSPARSER_parse_record (udp_payload,
760 udp_payload_length,
761 &off,
762 &p->answers[i]))
763 goto error;
764 }
765 n = ntohs (dns->authority_rcount);
766 if (n > 0)
767 {
768 p->authority_records = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Record);
769 p->num_authority_records = n;
770 for (unsigned int i = 0; i < n; i++)
771 if (GNUNET_OK != GNUNET_DNSPARSER_parse_record (udp_payload,
772 udp_payload_length,
773 &off,
774 &p->authority_records[i]))
775 goto error;
776 }
777 n = ntohs (dns->additional_rcount);
778 if (n > 0)
779 {
780 p->additional_records =
782 p->num_additional_records = n;
783 for (unsigned int i = 0; i < n; i++)
784 {
785 if (GNUNET_OK !=
787 udp_payload_length,
788 &off,
789 &p->additional_records[i]))
790 goto error;
791 }
792 }
793 return p;
794error:
795 GNUNET_break_op (0);
797 return NULL;
798}
799
800
809{
810 struct GNUNET_DNSPARSER_Record *dup = GNUNET_memdup (r, sizeof(*r));
811
812 dup->name = GNUNET_strdup (r->name);
813 switch (r->type)
814 {
819 break;
820 }
821
824 break;
825 }
826
829 break;
830 }
831
834 break;
835 }
836
839 break;
840 }
841
844 break;
845 }
846
847 default: {
849 r->data.raw.data_len);
850 }
851 }
852 return dup;
853}
854
855
864 const struct GNUNET_DNSPARSER_SoaRecord *r)
865{
866 struct GNUNET_DNSPARSER_SoaRecord *dup = GNUNET_memdup (r, sizeof(*r));
867
868 dup->mname = GNUNET_strdup (r->mname);
869 dup->rname = GNUNET_strdup (r->rname);
870 return dup;
871}
872
873
882 const struct GNUNET_DNSPARSER_CertRecord *r)
883{
884 struct GNUNET_DNSPARSER_CertRecord *dup = GNUNET_memdup (r, sizeof(*r));
885
887 return dup;
888}
889
890
899{
900 struct GNUNET_DNSPARSER_MxRecord *dup = GNUNET_memdup (r, sizeof(*r));
901
902 dup->mxhost = GNUNET_strdup (r->mxhost);
903 return dup;
904}
905
906
915 const struct GNUNET_DNSPARSER_SrvRecord *r)
916{
917 struct GNUNET_DNSPARSER_SrvRecord *dup = GNUNET_memdup (r, sizeof(*r));
918
919 dup->target = GNUNET_strdup (r->target);
920 return dup;
921}
922
923
932 const struct GNUNET_DNSPARSER_UriRecord *r)
933{
934 struct GNUNET_DNSPARSER_UriRecord *dup = GNUNET_memdup (r, sizeof(*r));
935
936 dup->target = GNUNET_strdup (r->target);
937 return dup;
938}
939
940
946void
948{
949 for (unsigned int i = 0; i < p->num_queries; i++)
950 GNUNET_free (p->queries[i].name);
951 GNUNET_free (p->queries);
952 for (unsigned int i = 0; i < p->num_answers; i++)
953 GNUNET_DNSPARSER_free_record (&p->answers[i]);
954 GNUNET_free (p->answers);
955 for (unsigned int i = 0; i < p->num_authority_records; i++)
956 GNUNET_DNSPARSER_free_record (&p->authority_records[i]);
957 GNUNET_free (p->authority_records);
958 for (unsigned int i = 0; i < p->num_additional_records; i++)
959 GNUNET_DNSPARSER_free_record (&p->additional_records[i]);
960 GNUNET_free (p->additional_records);
961 GNUNET_free (p);
962}
963
964
965/* ********************** DNS packet assembly code **************** */
966
967
981int
983 size_t dst_len,
984 size_t *off,
985 const char *name)
986{
987 const char *dot;
988 const char *idna_name;
989 char *idna_start;
990 size_t start;
991 size_t pos;
992 size_t len;
993 Idna_rc rc;
994
995 if (NULL == name)
996 return GNUNET_SYSERR;
997
998 if (IDNA_SUCCESS !=
999 (rc = idna_to_ascii_8z (name, &idna_start, IDNA_ALLOW_UNASSIGNED)))
1000 {
1002 _ (
1003 "Failed to convert UTF-8 name `%s' to DNS IDNA format: %s\n"),
1004 name,
1005 idna_strerror (rc));
1006 return GNUNET_NO;
1007 }
1008 idna_name = idna_start;
1009 start = *off;
1010 if (start + strlen (idna_name) + 2 > dst_len)
1011 goto fail;
1012 pos = start;
1013 do
1014 {
1015 dot = strchr (idna_name, '.');
1016 if (NULL == dot)
1017 len = strlen (idna_name);
1018 else
1019 len = dot - idna_name;
1020 if (len == 0)
1021 break;
1022 if (len >= 64)
1023 {
1025 "Invalid DNS name `%s': label with %u characters encountered\n",
1026 name,
1027 (unsigned int) len);
1028 goto fail; /* label too long or empty */
1029 }
1030 dst[pos++] = (char) (uint8_t) len;
1031 GNUNET_memcpy (&dst[pos], idna_name, len);
1032 pos += len;
1033 idna_name += len + 1; /* also skip dot */
1034 }
1035 while (NULL != dot);
1036 dst[pos++] = '\0'; /* terminator */
1037 *off = pos;
1038 free (idna_start);
1039 return GNUNET_OK;
1040fail:
1041 free (idna_start);
1042 return GNUNET_NO;
1043}
1044
1045
1058int
1060 size_t dst_len,
1061 size_t *off,
1062 const struct GNUNET_DNSPARSER_Query *query)
1063{
1064 int ret;
1065 struct GNUNET_TUN_DnsQueryLine ql;
1066
1068 dst_len
1069 - sizeof(
1071 off,
1072 query->name);
1073 if (ret != GNUNET_OK)
1074 return ret;
1075 ql.type = htons (query->type);
1076 ql.dns_traffic_class = htons (query->dns_traffic_class);
1077 GNUNET_memcpy (&dst[*off], &ql, sizeof(ql));
1078 (*off) += sizeof(ql);
1079 return GNUNET_OK;
1080}
1081
1082
1095int
1097 size_t dst_len,
1098 size_t *off,
1099 const struct GNUNET_DNSPARSER_MxRecord *mx)
1100{
1101 uint16_t mxpref;
1102
1103 if (*off + sizeof(uint16_t) > dst_len)
1104 return GNUNET_NO;
1105 mxpref = htons (mx->preference);
1106 GNUNET_memcpy (&dst[*off], &mxpref, sizeof(mxpref));
1107 (*off) += sizeof(mxpref);
1108 return GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, mx->mxhost);
1109}
1110
1111
1124int
1126 char *dst,
1127 size_t dst_len,
1128 size_t *off,
1129 const struct GNUNET_DNSPARSER_CertRecord *cert)
1130{
1131 struct GNUNET_TUN_DnsCertRecord dcert;
1132
1133#ifdef __clang__
1134#pragma clang diagnostic push
1135#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
1136#endif
1137 if ((cert->cert_type > UINT16_MAX) || (cert->algorithm > UINT8_MAX))
1138 {
1139 GNUNET_break (0);
1140 return GNUNET_SYSERR;
1141 }
1142#ifdef __clang__
1143#pragma clang diagnostic pop
1144#endif
1145 if (*off + sizeof(struct GNUNET_TUN_DnsCertRecord) + cert->certificate_size >
1146 dst_len)
1147 return GNUNET_NO;
1148 dcert.cert_type = htons ((uint16_t) cert->cert_type);
1149 dcert.cert_tag = htons ((uint16_t) cert->cert_tag);
1150 dcert.algorithm = (uint8_t) cert->algorithm;
1151 GNUNET_memcpy (&dst[*off], &dcert, sizeof(dcert));
1152 (*off) += sizeof(dcert);
1153 GNUNET_memcpy (&dst[*off], cert->certificate_data, cert->certificate_size);
1154 (*off) += cert->certificate_size;
1155 return GNUNET_OK;
1156}
1157
1158
1171int
1173 size_t dst_len,
1174 size_t *off,
1175 const struct GNUNET_DNSPARSER_SoaRecord *soa)
1176{
1177 struct GNUNET_TUN_DnsSoaRecord sd;
1178 int ret;
1179
1180 if ((GNUNET_OK !=
1181 (ret =
1182 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, soa->mname))) ||
1183 (GNUNET_OK !=
1184 (ret =
1185 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, soa->rname))))
1186 return ret;
1187 if (*off + sizeof(struct GNUNET_TUN_DnsSoaRecord) > dst_len)
1188 return GNUNET_NO;
1189 sd.serial = htonl (soa->serial);
1190 sd.refresh = htonl (soa->refresh);
1191 sd.retry = htonl (soa->retry);
1192 sd.expire = htonl (soa->expire);
1193 sd.minimum = htonl (soa->minimum_ttl);
1194 GNUNET_memcpy (&dst[*off], &sd, sizeof(sd));
1195 (*off) += sizeof(sd);
1196 return GNUNET_OK;
1197}
1198
1199
1212int
1214 size_t dst_len,
1215 size_t *off,
1216 const struct GNUNET_DNSPARSER_SrvRecord *srv)
1217{
1218 struct GNUNET_TUN_DnsSrvRecord sd;
1219 int ret;
1220
1221 if (*off + sizeof(struct GNUNET_TUN_DnsSrvRecord) > dst_len)
1222 return GNUNET_NO;
1223 sd.prio = htons (srv->priority);
1224 sd.weight = htons (srv->weight);
1225 sd.port = htons (srv->port);
1226 GNUNET_memcpy (&dst[*off], &sd, sizeof(sd));
1227 (*off) += sizeof(sd);
1228 if (GNUNET_OK !=
1229 (ret =
1230 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, srv->target)))
1231 return ret;
1232 return GNUNET_OK;
1233}
1234
1235
1248int
1250 size_t dst_len,
1251 size_t *off,
1252 const struct GNUNET_DNSPARSER_UriRecord *uri)
1253{
1254 struct GNUNET_TUN_DnsUriRecord sd;
1255
1256 if (*off + sizeof(struct GNUNET_TUN_DnsUriRecord) > dst_len)
1257 return GNUNET_NO;
1258 sd.prio = htons (uri->priority);
1259 sd.weight = htons (uri->weight);
1260 GNUNET_memcpy (&dst[*off], &sd, sizeof(sd));
1261 (*off) += sizeof(sd);
1262 strncpy (&dst[*off], uri->target, dst_len - sizeof(struct
1264 - 1);
1265 (*off) += strlen (uri->target);
1266 dst[*off] = '\0';
1267 return GNUNET_OK;
1268}
1269
1270
1283static int
1284add_record (char *dst,
1285 size_t dst_len,
1286 size_t *off,
1287 const struct GNUNET_DNSPARSER_Record *record)
1288{
1289 int ret;
1290 size_t start;
1291 size_t pos;
1292 struct GNUNET_TUN_DnsRecordLine rl;
1293
1294 start = *off;
1296 dst_len
1297 - sizeof(
1299 off,
1300 record->name);
1301 if (GNUNET_OK != ret)
1302 return ret;
1303 /* '*off' is now the position where we will need to write the record line */
1304
1305 pos = *off + sizeof(struct GNUNET_TUN_DnsRecordLine);
1306 switch (record->type)
1307 {
1309 ret = GNUNET_DNSPARSER_builder_add_mx (dst, dst_len, &pos, record->data.mx);
1310 break;
1311
1313 ret =
1314 GNUNET_DNSPARSER_builder_add_cert (dst, dst_len, &pos, record->data.cert);
1315 break;
1316
1318 ret =
1319 GNUNET_DNSPARSER_builder_add_soa (dst, dst_len, &pos, record->data.soa);
1320 break;
1321
1326 dst_len,
1327 &pos,
1328 record->data.hostname);
1329 break;
1330
1332 ret =
1333 GNUNET_DNSPARSER_builder_add_srv (dst, dst_len, &pos, record->data.srv);
1334 break;
1335
1337 ret =
1338 GNUNET_DNSPARSER_builder_add_uri (dst, dst_len, &pos, record->data.uri);
1339 break;
1340
1341 default:
1342 if (pos + record->data.raw.data_len > dst_len)
1343 {
1344 ret = GNUNET_NO;
1345 break;
1346 }
1347 GNUNET_memcpy (&dst[pos], record->data.raw.data, record->data.raw.data_len);
1348 pos += record->data.raw.data_len;
1349 ret = GNUNET_OK;
1350 break;
1351 }
1352 if (GNUNET_OK != ret)
1353 {
1354 *off = start;
1355 return GNUNET_NO;
1356 }
1357
1358 if (pos - (*off + sizeof(struct GNUNET_TUN_DnsRecordLine)) > UINT16_MAX)
1359 {
1360 /* record data too long */
1361 *off = start;
1362 return GNUNET_NO;
1363 }
1364 rl.type = htons (record->type);
1365 rl.dns_traffic_class = htons (record->dns_traffic_class);
1366 rl.ttl = htonl (
1368 / 1000LL / 1000LL); /* in seconds */
1369 rl.data_len = htons (
1370 (uint16_t) (pos - (*off + sizeof(struct GNUNET_TUN_DnsRecordLine))));
1371 GNUNET_memcpy (&dst[*off], &rl, sizeof(struct GNUNET_TUN_DnsRecordLine));
1372 *off = pos;
1373 return GNUNET_OK;
1374}
1375
1376
1391int
1393 uint16_t max,
1394 char **buf,
1395 size_t *buf_length)
1396{
1397 struct GNUNET_TUN_DnsHeader dns;
1398 size_t off;
1399 char tmp[max];
1400 int ret;
1401 int trc;
1402
1403 if ((p->num_queries > UINT16_MAX) || (p->num_answers > UINT16_MAX) ||
1404 (p->num_authority_records > UINT16_MAX) ||
1405 (p->num_additional_records > UINT16_MAX))
1406 return GNUNET_SYSERR;
1407 dns.id = p->id;
1408 dns.flags = p->flags;
1409 dns.query_count = htons (p->num_queries);
1410 dns.answer_rcount = htons (p->num_answers);
1411 dns.authority_rcount = htons (p->num_authority_records);
1412 dns.additional_rcount = htons (p->num_additional_records);
1413
1414 off = sizeof(struct GNUNET_TUN_DnsHeader);
1415 trc = GNUNET_NO;
1416 for (unsigned int i = 0; i < p->num_queries; i++)
1417 {
1419 sizeof(tmp),
1420 &off,
1421 &p->queries[i]);
1422 if (GNUNET_SYSERR == ret)
1423 return GNUNET_SYSERR;
1424 if (GNUNET_NO == ret)
1425 {
1426 dns.query_count = htons ((uint16_t) (i - 1));
1427 trc = GNUNET_YES;
1428 break;
1429 }
1430 }
1431 for (unsigned int i = 0; i < p->num_answers; i++)
1432 {
1433 ret = add_record (tmp, sizeof(tmp), &off, &p->answers[i]);
1434 if (GNUNET_SYSERR == ret)
1435 return GNUNET_SYSERR;
1436 if (GNUNET_NO == ret)
1437 {
1438 dns.answer_rcount = htons ((uint16_t) (i - 1));
1439 trc = GNUNET_YES;
1440 break;
1441 }
1442 }
1443 for (unsigned int i = 0; i < p->num_authority_records; i++)
1444 {
1445 ret = add_record (tmp, sizeof(tmp), &off, &p->authority_records[i]);
1446 if (GNUNET_SYSERR == ret)
1447 return GNUNET_SYSERR;
1448 if (GNUNET_NO == ret)
1449 {
1450 dns.authority_rcount = htons ((uint16_t) (i - 1));
1451 trc = GNUNET_YES;
1452 break;
1453 }
1454 }
1455 for (unsigned int i = 0; i < p->num_additional_records; i++)
1456 {
1457 ret = add_record (tmp, sizeof(tmp), &off, &p->additional_records[i]);
1458 if (GNUNET_SYSERR == ret)
1459 return GNUNET_SYSERR;
1460 if (GNUNET_NO == ret)
1461 {
1462 dns.additional_rcount = htons (i - 1);
1463 trc = GNUNET_YES;
1464 break;
1465 }
1466 }
1467
1468 if (GNUNET_YES == trc)
1469 dns.flags.message_truncated = 1;
1470 GNUNET_memcpy (tmp, &dns, sizeof(struct GNUNET_TUN_DnsHeader));
1471
1472 *buf = GNUNET_malloc (off);
1473 *buf_length = off;
1474 GNUNET_memcpy (*buf, tmp, off);
1475 if (GNUNET_YES == trc)
1476 return GNUNET_NO;
1477 return GNUNET_OK;
1478}
1479
1480
1488char *
1490{
1491 char *ret;
1492 size_t off;
1493 const uint8_t *idata;
1494
1495 idata = data;
1496 ret = GNUNET_malloc (data_size * 2 + 1);
1497 for (off = 0; off < data_size; off++)
1498 sprintf (&ret[off * 2], "%02x", idata[off]);
1499 return ret;
1500}
1501
1502
1511size_t
1512GNUNET_DNSPARSER_hex_to_bin (const char *hex, void *data)
1513{
1514 size_t data_size;
1515 size_t off;
1516 uint8_t *idata;
1517 unsigned int h;
1518 char in[3];
1519
1520 data_size = strlen (hex) / 2;
1521 idata = data;
1522 in[2] = '\0';
1523 for (off = 0; off < data_size; off++)
1524 {
1525 in[0] = tolower ((unsigned char) hex[off * 2]);
1526 in[1] = tolower ((unsigned char) hex[off * 2 + 1]);
1527 if (1 != sscanf (in, "%x", &h))
1528 return off;
1529 idata[off] = (uint8_t) h;
1530 }
1531 return off;
1532}
1533
1534
1535/* 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:1284
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:99
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static int ret
Final status code.
Definition: gnunet-arm.c:94
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:1489
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:982
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:1125
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition: dnsparser.c:947
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:898
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:1059
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:863
#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:1512
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:914
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:579
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:1172
#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:881
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:1096
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:1213
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:931
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:1392
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:1249
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:620
#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:727
struct GNUNET_DNSPARSER_Record * GNUNET_DNSPARSER_duplicate_record(const struct GNUNET_DNSPARSER_Record *r)
Duplicate (deep-copy) the given DNS record.
Definition: dnsparser.c:808
#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_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_.
#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:405
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:484
#define max(x, y)
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
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.