GNUnet 0.24.4-talerdev.1-15-g77b7ed1a6
 
Loading...
Searching...
No Matches
gnunet-zoneimport.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 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 */
25#include "platform.h"
26#if HAVE_LIBIDN2
27#if HAVE_IDN2_H
28#include <idn2.h>
29#elif HAVE_IDN2_IDN2_H
30#include <idn2/idn2.h>
31#endif
32#elif HAVE_LIBIDN
33#if HAVE_IDNA_H
34#include <idna.h>
35#elif HAVE_IDN_IDNA_H
36#include <idn/idna.h>
37#endif
38#endif
39#include <gnunet_util_lib.h>
44
45
49#define THRESH 100
50
55#define TIME_THRESH 10
56
60#define MAX_RETRIES 5
61
65#define MAX_SERIES 10
66
70#define SERIES_DELAY \
71 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS, 10)
72
77
82#define NS_BATCH_SIZE 1024
83
90struct Zone
91{
95 struct Zone *next;
96
100 struct Zone *prev;
101
105 char *domain;
106
111};
112
113
117struct Record
118{
122 struct Record *next;
123
127 struct Record *prev;
128
133};
134
135
142{
147
151 struct Request *next;
152
156 struct Request *prev;
157
163
169
174
180 char *hostname;
181
186
190 const struct Zone *zone;
191
198
206
211 unsigned int issue_num;
212
216 uint16_t id;
217};
218
223{
224 // DLL
226
227 // DLL
229
230 // Operation
232
233 // NS Operation
235
236 // Request
237 struct Request *req;
238};
239
240// Missing zones list
242
243// Missing zones list
245
246// Lines provided on stdin
247static uint64_t stdin_lines_read;
248
255static unsigned int map_size = 1024;
256
261
266
271
276
280static unsigned int pending;
281
285static unsigned int pending_rs;
286
290static unsigned int lookups;
291
295static unsigned int cached;
296
300static unsigned int rejects;
301
305static unsigned int failures;
306
310static unsigned int records;
311
315static unsigned int record_sets;
316
322
326static struct Request *req_head;
327
331static struct Request *req_tail;
332
337
344
349
353static struct Zone *zone_head;
354
358static struct Zone *zone_tail;
359
365
369static uint64_t total_dns_latency_cnt;
370
375
379static uint64_t total_reg_proc_dns;
380
384static uint64_t total_reg_proc_dns_ns;
385
390
395
400
401
408typedef void (*RecordProcessor) (void *cls,
409 const struct GNUNET_DNSPARSER_Record *rec);
410
411
420static void
423 void *rp_cls)
424{
425 for (unsigned int i = 0; i < p->num_answers; i++)
426 {
427 struct GNUNET_DNSPARSER_Record *rs = &p->answers[i];
428
429 rp (rp_cls, rs);
430 }
431 for (unsigned int i = 0; i < p->num_authority_records; i++)
432 {
433 struct GNUNET_DNSPARSER_Record *rs = &p->authority_records[i];
434
435 rp (rp_cls, rs);
436 }
437 for (unsigned int i = 0; i < p->num_additional_records; i++)
438 {
439 struct GNUNET_DNSPARSER_Record *rs = &p->additional_records[i];
440
441 rp (rp_cls, rs);
442 }
443}
444
445
453static const char *
454get_label (struct Request *req)
455{
456 static char label[64];
457 const char *dot;
458
459 dot = strchr (req->hostname, (unsigned char) '.');
460 if (NULL == dot)
461 {
462 GNUNET_break (0);
463 return NULL;
464 }
465 if (((size_t) (dot - req->hostname)) >= sizeof(label))
466 {
467 GNUNET_break (0);
468 return NULL;
469 }
470 GNUNET_memcpy (label, req->hostname, dot - req->hostname);
471 label[dot - req->hostname] = '\0';
472
473 return label;
474}
475
476
477static char*
479{
480 char *label_utf8;
481 const char *label_ace;
482
483 label_ace = get_label (req);
484 idna_to_unicode_8z8z (label_ace,
485 &label_utf8,
486 IDNA_ALLOW_UNASSIGNED);
487 return label_utf8;
488}
489
490
499static void *
500build_dns_query (struct Request *req, size_t *raw_size)
501{
502 static char raw[512];
503 char *name_ace;
504 char *rawp;
507 int ret;
508
509 if (IDNA_SUCCESS != idna_to_ascii_8z (req->hostname,
510 &name_ace,
511 IDNA_ALLOW_UNASSIGNED))
512 {
514 _ ("Name `%s' cannot be converted to IDNA."),
515 req->hostname);
516 return NULL;
517 }
518 q.name = (char *) name_ace;
520 q.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
521
522 memset (&p, 0, sizeof(p));
523 p.num_queries = 1;
524 p.queries = &q;
525 p.id = req->id;
526 ret = GNUNET_DNSPARSER_pack (&p, UINT16_MAX, &rawp, raw_size);
527 if (GNUNET_OK != ret)
528 {
529 if (GNUNET_NO == ret)
530 GNUNET_free (rawp);
532 "Failed to pack query for hostname `%s'\n",
533 name_ace);
534 rejects++;
535 GNUNET_free (name_ace);
536 return NULL;
537 }
538 if (*raw_size > sizeof(raw))
539 {
541 "Failed to pack query for hostname `%s'\n",
542 name_ace);
543 rejects++;
544 GNUNET_break (0);
545 GNUNET_free (name_ace);
546 GNUNET_free (rawp);
547 return NULL;
548 }
549 GNUNET_memcpy (raw, rawp, *raw_size);
550 GNUNET_free (rawp);
551 return raw;
552}
553
554
560static void
562{
563 struct Record *rec;
564
565 /* Free records */
566 while (NULL != (rec = req->rec_head))
567 {
569 GNUNET_free (rec);
570 }
571}
572
573
579static void
581{
582 free_records (req);
583 GNUNET_free (req);
584}
585
586
592static void
593process_queue (void *cls);
594
595
601static void
603{
604 req->hn =
607 {
608 if (NULL != t)
612 }
613}
614
615
625static void
626add_record (struct Request *req,
627 uint32_t type,
628 struct GNUNET_TIME_Absolute expiration_time,
629 const void *data,
630 size_t data_len)
631{
632 struct Record *rec;
633
634 rec = GNUNET_malloc (sizeof(struct Record) + data_len);
635 rec->grd.data = &rec[1];
636 rec->grd.expiration_time = expiration_time.abs_value_us;
637 rec->grd.data_size = data_len;
638 rec->grd.record_type = type;
640 GNUNET_memcpy (&rec[1], data, data_len);
642}
643
644
649{
653 struct Request *req;
654
658 const char *ns;
659
663 int found;
664};
665
666
673static void
674check_for_glue (void *cls, const struct GNUNET_DNSPARSER_Record *rec)
675{
676 struct GlueClosure *gc = cls;
677 char dst[65536];
678 size_t rd_len;
679 char ip[INET6_ADDRSTRLEN + 1];
680 socklen_t ip_size = (socklen_t) sizeof(ip);
681 struct GNUNET_TIME_Absolute expiration_time;
682 struct GNUNET_TIME_Relative left;
683
684 if (0 != strcasecmp (rec->name, gc->ns))
685 return;
686 expiration_time = rec->expiration_time;
687 left = GNUNET_TIME_absolute_get_remaining (expiration_time);
688 if (0 == left.rel_value_us)
689 return; /* ignore expired glue records */
690 /* if expiration window is too short, bump it to configured minimum */
692 expiration_time =
694 rd_len = 0;
695 switch (rec->type)
696 {
698 if (sizeof(struct in_addr) != rec->data.raw.data_len)
699 {
700 GNUNET_break (0);
701 return;
702 }
703 if (NULL == inet_ntop (AF_INET, rec->data.raw.data, ip, ip_size))
704 {
705 GNUNET_break (0);
706 return;
707 }
708 // NAME
709 GNUNET_memcpy (dst,
710 gc->req->hostname,
711 strlen (gc->req->hostname) + 1);
712 rd_len += strlen (gc->req->hostname) + 1;
713 // DNS SERVER NAME
714 GNUNET_memcpy (dst + strlen (gc->req->hostname) + 1,
715 ip,
716 strlen (ip) + 1);
717 rd_len += strlen (ip) + 1;
718 add_record (gc->req,
720 expiration_time,
721 dst,
722 rd_len);
723 gc->found = GNUNET_YES;
724 break;
725
727 if (sizeof(struct in6_addr) != rec->data.raw.data_len)
728 {
729 GNUNET_break (0);
730 return;
731 }
732 if (NULL == inet_ntop (AF_INET6, rec->data.raw.data, ip, ip_size))
733 {
734 GNUNET_break (0);
735 return;
736 }
737 // NAME
738 GNUNET_memcpy (dst,
739 gc->req->hostname,
740 strlen (gc->req->hostname) + 1);
741 rd_len += strlen (gc->req->hostname) + 1;
742 // DNS SERVER NAME
743 GNUNET_memcpy (dst + strlen (gc->req->hostname) + 1,
744 ip,
745 strlen (ip) + 1);
746 rd_len += strlen (ip) + 1;
747 add_record (gc->req,
749 expiration_time,
750 dst,
751 rd_len);
752 gc->found = GNUNET_YES;
753 break;
754
756 // NAME
757 GNUNET_memcpy (dst,
758 gc->req->hostname,
759 strlen (gc->req->hostname) + 1);
760 rd_len += strlen (gc->req->hostname) + 1;
761 // DNS SERVER NAME
762 GNUNET_memcpy (dst + strlen (gc->req->hostname) + 1,
763 rec->data.hostname,
764 strlen (rec->data.hostname) + 1);
765 rd_len += strlen (ip) + 1;
766 add_record (gc->req,
768 expiration_time,
769 dst,
770 rd_len);
771 gc->found = GNUNET_YES;
772 break;
773
774 default:
775 /* useless, do nothing */
776 break;
777 }
778}
779
780
785{
791
795 struct Request *req;
796};
797
798
805static void
806process_record (void *cls, const struct GNUNET_DNSPARSER_Record *rec)
807{
808 struct ProcessRecordContext *prc = cls;
809 struct Request *req = prc->req;
810 char dst[65536];
811 size_t dst_len;
812 size_t off;
813 struct GNUNET_TIME_Absolute expiration_time;
814 struct GNUNET_TIME_Relative left;
815
816 dst_len = sizeof(dst);
817 off = 0;
818 records++;
819 if (0 != strcasecmp (rec->name, req->hostname))
820 {
821 GNUNET_log (
823 "DNS returned record from zone `%s' of type %u while resolving `%s'\n",
824 rec->name,
825 (unsigned int) rec->type,
826 req->hostname);
827 return; /* does not match hostname, might be glue, but
828 not useful for this pass! */
829 }
830 expiration_time = rec->expiration_time;
831 left = GNUNET_TIME_absolute_get_remaining (expiration_time);
832 if (0 == left.rel_value_us)
833 {
835 "DNS returned expired record for `%s'\n",
836 req->hostname);
838 "# expired records obtained from DNS",
839 1,
840 GNUNET_NO);
841 return; /* record expired */
842 }
843
845 "DNS returned record that expires at %s for `%s'\n",
847 req->hostname);
848 /* if expiration window is too short, bump it to configured minimum */
850 expiration_time =
852 switch (rec->type)
853 {
855 struct GlueClosure gc;
856
857 /* check for glue */
858 gc.req = req;
859 gc.ns = rec->data.hostname;
860 gc.found = GNUNET_NO;
861 for_all_records (prc->p, &check_for_glue, &gc);
862 if (GNUNET_NO == gc.found)
863 {
864 // NAME
865 GNUNET_memcpy (dst,
866 req->hostname,
867 strlen (req->hostname) + 1);
868 off += strlen (req->hostname) + 1;
869 // DNS SERVER NAME
870 GNUNET_memcpy (dst + strlen (req->hostname) + 1,
871 rec->data.hostname,
872 strlen (rec->data.hostname) + 1);
873 off += strlen (rec->data.hostname) + 1;
874 /* FIXME: actually check if this is out-of-bailiwick,
875 and if not request explicit resolution... */
877 "Converted OOB (`%s') NS record for `%s'\n",
878 rec->data.hostname,
879 rec->name);
882 expiration_time,
883 dst,
884 off);
885 }
886 else
887 {
889 "Converted NS record for `%s' using glue\n",
890 rec->name);
891 }
892 break;
893 }
894
897 dst_len,
898 &off,
899 rec->data.hostname))
900 {
902 "Converting CNAME (`%s') record for `%s'\n",
903 rec->data.hostname,
904 rec->name);
905 add_record (req, rec->type, expiration_time, dst, off);
906 }
907 break;
908
910 /* No support for DNAME in GNS yet! FIXME: support later! */
912 "FIXME: not supported: %s DNAME %s\n",
913 rec->name,
914 rec->data.hostname);
915 break;
916
918 if (GNUNET_OK ==
919 GNUNET_DNSPARSER_builder_add_mx (dst, dst_len, &off, rec->data.mx))
920 {
922 "Converting MX (`%s') record for `%s'\n",
923 rec->data.mx->mxhost,
924 rec->name);
925 add_record (req, rec->type, expiration_time, dst, off);
926 }
927 break;
928
930 if (GNUNET_OK ==
931 GNUNET_DNSPARSER_builder_add_soa (dst, dst_len, &off, rec->data.soa))
932 {
933 /* NOTE: GNS does not really use SOAs */
935 "Converting SOA record for `%s'\n",
936 rec->name);
937 add_record (req, rec->type, expiration_time, dst, off);
938 }
939 break;
940
942 if (GNUNET_OK ==
943 GNUNET_DNSPARSER_builder_add_srv (dst, dst_len, &off, rec->data.srv))
944 {
946 "Converting SRV record for `%s'\n",
947 rec->name);
948 add_record (req, rec->type, expiration_time, dst, off);
949 }
950 break;
951
953 if (GNUNET_OK ==
954 GNUNET_DNSPARSER_builder_add_uri (dst, dst_len, &off, rec->data.uri))
955 {
957 "Converting URI record for `%s'\n",
958 rec->name);
959 add_record (req, rec->type, expiration_time, dst, off);
960 }
961 break;
962
965 dst_len,
966 &off,
967 rec->data.hostname))
968 {
969 /* !?: what does a PTR record do in a regular TLD??? */
971 "Converting PTR record for `%s' (weird)\n",
972 rec->name);
973 add_record (req, rec->type, expiration_time, dst, off);
974 }
975 break;
976
978 if (GNUNET_OK ==
979 GNUNET_DNSPARSER_builder_add_cert (dst, dst_len, &off, rec->data.cert))
980 {
982 "Converting CERT record for `%s'\n",
983 rec->name);
984 add_record (req, rec->type, expiration_time, dst, off);
985 }
986 break;
987
988 /* Rest is 'raw' encoded and just needs to be copied IF
989 the hostname matches the requested name; otherwise we
990 simply cannot use it. */
994 default:
996 "Converting record of type %u for `%s'\n",
997 (unsigned int) rec->type,
998 rec->name);
1000 rec->type,
1001 expiration_time,
1002 rec->data.raw.data,
1003 rec->data.raw.data_len);
1004 break;
1005 }
1006}
1007
1008
1009static void
1011{
1012 static struct GNUNET_TIME_Absolute last;
1013 struct Request *req = cls;
1014
1015 req->qe = NULL;
1016 if (GNUNET_EC_NONE != ec)
1017 {
1019 "Failed to store zone data for `%s': %s\n",
1020 req->hostname,
1022 }
1023 else
1024 {
1026 "Stored records under `%s' (%d)\n",
1027 req->hostname,
1028 ec);
1029 }
1030 total_reg_proc_dns_ns++; /* finished regular processing */
1031 pending_rs--;
1032 free_records (req);
1033 /* compute NAMESTORE statistics */
1034 {
1035 static uint64_t total_ns_latency_cnt;
1036 static struct GNUNET_TIME_Relative total_ns_latency;
1037 struct GNUNET_TIME_Relative ns_latency;
1038
1040 total_ns_latency = GNUNET_TIME_relative_add (total_ns_latency, ns_latency);
1041 if (0 == total_ns_latency_cnt)
1042 last = GNUNET_TIME_absolute_get ();
1043 total_ns_latency_cnt++;
1044 if (0 == (total_ns_latency_cnt % 1000))
1045 {
1047 struct GNUNET_TIME_Relative est_remaining;
1048
1050 last = GNUNET_TIME_absolute_get ();
1051 est_remaining = GNUNET_TIME_relative_multiply (
1052 delta,
1053 (stdin_lines_read - total_ns_latency_cnt) / 1000);
1054 fprintf (stderr,
1055 "Processed 1000 records in %s. ",
1057 fprintf (stderr,
1058 "Estimated remaining time: %s. ",
1060 est_remaining,
1061 GNUNET_YES));
1062 fprintf (stderr,
1063 "Last domain processed: %s\n",
1064 req->hostname);
1066 "# average NAMESTORE PUT latency (μs)",
1067 total_ns_latency.rel_value_us
1068 / total_ns_latency_cnt,
1069 GNUNET_NO);
1070 }
1071 }
1072 /* compute and publish overall velocity */
1073 if (0 == (total_reg_proc_dns_ns % 100))
1074 {
1075 struct GNUNET_TIME_Relative runtime;
1076
1078 runtime = GNUNET_TIME_relative_subtract (runtime, idle_time);
1079 runtime =
1083 "# Regular processing completed without NAMESTORE",
1085 GNUNET_NO);
1087 "# Regular processing completed with NAMESTORE PUT",
1089 GNUNET_NO);
1091 "# average request processing latency (μs)",
1092 runtime.rel_value_us,
1093 GNUNET_NO);
1095 "# total time spent idle (μs)",
1097 GNUNET_NO);
1098 }
1099
1100 if (NULL == t)
1101 {
1104 }
1105}
1106
1107
1115static void
1117 const struct GNUNET_TUN_DnsHeader *dns,
1118 size_t dns_len)
1119{
1120 struct Request *req = cls;
1121 struct Record *rec;
1122 struct GNUNET_DNSPARSER_Packet *p;
1123 unsigned int rd_count;
1124
1125 GNUNET_assert (NULL == req->hn);
1126 if ((NULL == dns) ||
1128 {
1129 /* stub gave up */
1131 if (NULL != dns)
1132 {
1134 req->rs = NULL;
1135 }
1136 pending--;
1137 if (NULL == t)
1138 {
1141 }
1143 "Stub gave up on DNS reply for `%s'\n",
1144 req->hostname);
1145 GNUNET_STATISTICS_update (stats, "# Unsuccessful DNS lookups", 1, GNUNET_NO)
1146 ;
1147 if (req->issue_num > MAX_RETRIES)
1148 {
1149 failures++;
1150 free_request (req);
1151 GNUNET_STATISTICS_update (stats, "# DNS requests given up on", 1,
1152 GNUNET_NO);
1153 return;
1154 }
1156 req->rs = NULL;
1157 insert_sorted (req);
1158 return;
1159 }
1160 if (req->id != dns->id)
1161 {
1163 "DNS ID did not match request, ignoring reply\n");
1164 GNUNET_STATISTICS_update (stats, "# DNS ID mismatches", 1, GNUNET_NO);
1165 return;
1166 }
1169 req->rs = NULL;
1170 pending--;
1171 p = GNUNET_DNSPARSER_parse ((const char *) dns, dns_len);
1172 if (NULL == p)
1173 {
1175 "Failed to parse DNS reply for `%s'\n",
1176 req->hostname);
1177 GNUNET_STATISTICS_update (stats, "# DNS parser errors", 1, GNUNET_NO);
1178 if (NULL == t)
1179 {
1182 }
1183 if (req->issue_num > MAX_RETRIES)
1184 {
1185 failures++;
1186 free_request (req);
1187 GNUNET_STATISTICS_update (stats, "# requests given up on", 1, GNUNET_NO);
1188 return;
1189 }
1190 insert_sorted (req);
1191 return;
1192 }
1193 /* import new records */
1194 req->issue_num = 0; /* success, reset counter! */
1195 {
1196 struct ProcessRecordContext prc = { .req = req, .p = p };
1197
1199 }
1201 /* count records found, determine minimum expiration time */
1203 {
1204 struct GNUNET_TIME_Relative dns_latency;
1205
1210 if (0 == (total_dns_latency_cnt % 1000))
1211 {
1213 "# average DNS lookup latency (μs)",
1216 GNUNET_NO);
1217 }
1218 }
1219 rd_count = 0;
1220 for (rec = req->rec_head; NULL != rec; rec = rec->next)
1221 {
1222 struct GNUNET_TIME_Absolute at;
1223
1225 req->expires = GNUNET_TIME_absolute_min (req->expires, at);
1226 rd_count++;
1227 }
1229 "Obtained %u records for `%s'\n",
1230 rd_count,
1231 req->hostname);
1232 /* Instead of going for SOA, simplified for now to look each
1233 day in case we got an empty response */
1234 if (0 == rd_count)
1235 {
1238 "# empty DNS replies (usually NXDOMAIN)",
1239 1,
1240 GNUNET_NO);
1241 }
1242 else
1243 {
1244 record_sets++;
1245 }
1246 /* convert records to namestore import format */
1247 {
1249 unsigned int off = 0;
1250 char *label_utf8 = get_label_utf8 (req);
1251
1252 /* convert linked list into array */
1253 for (rec = req->rec_head; NULL != rec; rec = rec->next)
1254 rd[off++] = rec->grd;
1255 pending_rs++;
1258 &req->zone->key,
1259 label_utf8,
1260 rd_count,
1261 rd,
1263 req);
1264 GNUNET_free (label_utf8);
1265 GNUNET_assert (NULL != req->qe);
1266 }
1267 insert_sorted (req);
1268 return;
1269}
1270
1271
1277static void
1278process_queue (void *cls)
1279{
1280 struct Request *req;
1281 unsigned int series;
1282 void *raw;
1283 size_t raw_size;
1284 struct GNUNET_TIME_Relative delay;
1285
1286 (void) cls;
1289 series = 0;
1290 t = NULL;
1291 while (pending + pending_rs < THRESH)
1292 {
1294 if (NULL == req)
1295 break;
1296 if (NULL != req->qe)
1297 return; /* namestore op still pending */
1298 if (NULL != req->rs)
1299 {
1300 GNUNET_break (0);
1301 return; /* already submitted */
1302 }
1304 break;
1306 req->hn = NULL;
1308 GNUNET_assert (NULL == req->rs);
1310 "Requesting resolution for `%s'\n",
1311 req->hostname);
1312 raw = build_dns_query (req, &raw_size);
1313 if (NULL == raw)
1314 {
1315 GNUNET_break (0);
1316 free_request (req);
1317 continue;
1318 }
1320 req->rs = GNUNET_DNSSTUB_resolve (dns_ctx, raw, raw_size, &process_result,
1321 req);
1322 GNUNET_assert (NULL != req->rs);
1323 req->issue_num++;
1324 lookups++;
1325 pending++;
1326 series++;
1327 if (series > MAX_SERIES)
1328 break;
1329 }
1330 if (pending + pending_rs >= THRESH)
1331 {
1333 "Stopped processing queue (%u+%u/%u)]\n",
1334 pending,
1335 pending_rs,
1336 THRESH);
1337 return; /* wait for replies */
1338 }
1340 if (NULL == req)
1341 {
1343 "Stopped processing queue: empty queue\n");
1344 return;
1345 }
1347 {
1349 "Waiting until %s for next record (`%s') to expire\n",
1351 req->hostname);
1352 if (NULL != t)
1356 return;
1357 }
1358 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Throttling\n");
1359 if (NULL != t)
1363}
1364
1365
1375static int
1376free_request_it (void *cls, const struct GNUNET_HashCode *key, void *value)
1377{
1378 struct Request *req = value;
1379
1380 (void) cls;
1381 (void) key;
1382 free_request (req);
1383 return GNUNET_OK;
1384}
1385
1386
1392static void
1393do_shutdown (void *cls)
1394{
1395 struct Request *req;
1396 struct Zone *zone;
1397 struct MissingZoneCreationCtx *mzctx;
1398
1399 (void) cls;
1400 while (NULL != (mzctx = missing_zones_head))
1401 {
1404 mzctx);
1405 if (NULL != mzctx->id_op)
1406 {
1408 mzctx->id_op = NULL;
1409 }
1410 if (NULL != mzctx->ns_qe)
1411 {
1413 mzctx->ns_qe = NULL;
1414 }
1415 GNUNET_free (mzctx);
1416 }
1417 if (NULL != id)
1418 {
1420 id = NULL;
1421 }
1422 if (NULL != t)
1423 {
1425 t = NULL;
1426 }
1427 while (NULL != (req = req_head))
1428 {
1430 if (NULL != req->qe)
1432 free_request (req);
1433 }
1434 while (NULL != (req = GNUNET_CONTAINER_heap_remove_root (req_heap)))
1435 {
1436 req->hn = NULL;
1437 if (NULL != req->qe)
1439 free_request (req);
1440 }
1441 if (NULL != zone_it)
1442 {
1444 zone_it = NULL;
1445 }
1446 if (NULL != ns)
1447 {
1449 ns = NULL;
1450 }
1451 if (NULL != dns_ctx)
1452 {
1454 dns_ctx = NULL;
1455 }
1456 if (NULL != req_heap)
1457 {
1459 req_heap = NULL;
1460 }
1461 if (NULL != ns_pending)
1462 {
1465 ns_pending = NULL;
1466 }
1467 while (NULL != (zone = zone_head))
1468 {
1470 GNUNET_free (zone->domain);
1471 GNUNET_free (zone);
1472 }
1473 if (NULL != stats)
1474 {
1476 stats = NULL;
1477 }
1478}
1479
1480
1487static void
1488iterate_zones (void *cls);
1489
1490
1497static void
1499{
1500 struct Zone *zone = cls;
1501
1503 "Failed to load data from namestore for zone `%s'\n",
1504 zone->domain);
1505 zone_it = NULL;
1507 iterate_zones (NULL);
1508}
1509
1510
1520static void
1522 const struct GNUNET_CRYPTO_PrivateKey *key,
1523 const char *label_utf8,
1524 unsigned int rd_count,
1525 const struct GNUNET_GNSRECORD_Data *rd)
1526{
1527 struct Zone *zone = cls;
1528 struct Request *req;
1529 struct GNUNET_HashCode hc;
1530 char *label_ace;
1531 char *fqdn;
1532
1534 if (0 == ns_iterator_trigger_next)
1535 {
1538 "# NAMESTORE records requested from cache",
1540 GNUNET_NO);
1542 }
1543 if (IDNA_SUCCESS != idna_to_ascii_8z (label_utf8,
1544 &label_ace,
1545 IDNA_ALLOW_UNASSIGNED))
1546 {
1548 _ ("Name `%s' cannot be converted to IDNA."),
1549 label_utf8);
1550 return;
1551 }
1553 "Obtained NAMESTORE reply for %s (Punycode `%s', %llu left in round\n",
1554 label_utf8,
1555 label_ace,
1556 (unsigned long long) ns_iterator_trigger_next);
1557
1558 GNUNET_asprintf (&fqdn, "%s.%s", label_ace, zone->domain);
1559 GNUNET_CRYPTO_hash (fqdn, strlen (fqdn) + 1, &hc);
1560 GNUNET_free (fqdn);
1562 if (NULL == req)
1563 {
1565 "Ignoring record `%s' in zone `%s': not on my list!\n",
1566 label_ace,
1567 zone->domain);
1568 GNUNET_free (label_ace);
1569 return;
1570 }
1573 GNUNET_break (0 == GNUNET_memcmp (key, &req->zone->key));
1574 GNUNET_break (0 == strcasecmp (label_ace, get_label (req)));
1575 GNUNET_free (label_ace);
1576 for (unsigned int i = 0; i < rd_count; i++)
1577 {
1578 struct GNUNET_TIME_Absolute at;
1579
1581 {
1582 struct GNUNET_TIME_Relative rel;
1583
1586 }
1587 else
1588 {
1590 }
1591 add_record (req, rd->record_type, at, rd->data, rd->data_size);
1592 }
1593 if (0 == rd_count)
1594 {
1596 "Empty record set in namestore for `%s'\n",
1597 req->hostname);
1598 }
1599 else
1600 {
1601 unsigned int pos = 0;
1602
1603 cached++;
1605 for (struct Record *rec = req->rec_head; NULL != rec; rec = rec->next)
1606 {
1607 struct GNUNET_TIME_Absolute at;
1608
1609 at.abs_value_us = rec->grd.expiration_time;
1610 req->expires = GNUNET_TIME_absolute_min (req->expires, at);
1611 pos++;
1612 }
1613 if (0 == pos)
1616 "Hot-start with %u existing records for `%s'\n",
1617 pos,
1618 req->hostname);
1619 }
1620 free_records (req);
1621
1623 "Adding `%s' to worklist to start at %s\n",
1624 req->hostname,
1626 insert_sorted (req);
1627}
1628
1629
1630static void
1632 enum GNUNET_ErrorCode ec)
1633{
1634 struct MissingZoneCreationCtx *mzctx = cls;
1635
1636 mzctx->ns_qe = NULL;
1637 if (GNUNET_EC_NONE != ec)
1638 {
1640 "Failed to store delegation: `%s'\n",
1643 return;
1644 }
1646 "Added delegation successfully\n");
1649 mzctx);
1650 GNUNET_free (mzctx);
1651 if (NULL == missing_zones_head)
1652 {
1653 iterate_zones (NULL);
1654 }
1655
1656}
1657
1658
1659static void
1661 void *cls,
1662 const struct GNUNET_CRYPTO_PrivateKey *sk,
1663 enum GNUNET_ErrorCode ec)
1664{
1665 struct MissingZoneCreationCtx *mzctx = cls;
1667 struct Zone *parent_zone;
1668 struct Zone *zone;
1669 const char *dot;
1670 const char *expected_parent_zone_name;
1671 char parent_delegation_label[GNUNET_DNSPARSER_MAX_NAME_LENGTH];
1672
1673 if (GNUNET_EC_NONE != ec)
1674 {
1676 "Failed to create zone for `%s': %s\n",
1677 mzctx->req->hostname,
1680 return;
1681 }
1682 mzctx->id_op = NULL;
1683 dot = strchr (mzctx->req->hostname, (unsigned char) '.');
1685 "Created missing ego `%s'\n",
1686 dot + 1);
1687 zone = GNUNET_new (struct Zone);
1688 zone->key = *sk;
1689 zone->domain = GNUNET_strdup (dot + 1);
1690 mzctx->req->zone = zone;
1692
1693 expected_parent_zone_name = strchr (dot + 1,
1694 (unsigned char) '.');
1695 if (NULL == expected_parent_zone_name)
1696 {
1698 "Created identity without parent zone!\n");
1700 return;
1701 }
1702 {
1703 int label_len = strlen (dot + 1) - strlen (expected_parent_zone_name) + 1;
1704 snprintf (parent_delegation_label,
1705 label_len,
1706 "%s",
1707 dot + 1);
1708 parent_delegation_label[label_len] = '\0';
1709 }
1710 for (parent_zone = zone_head;
1711 NULL != parent_zone;
1712 parent_zone = parent_zone->next)
1713 {
1714 if (0 != strcmp (expected_parent_zone_name + 1,
1715 parent_zone->domain))
1716 continue;
1717 break;
1718 }
1720 struct GNUNET_GNSRECORD_Data delegation_rd;
1721 char *data;
1722 size_t data_size;
1725 &data,
1726 &data_size,
1727 &delegation_rd.record_type
1728 ));
1730 delegation_rd.expiration_time = GNUNET_TIME_UNIT_WEEKS.rel_value_us;
1731 delegation_rd.data = data;
1732 delegation_rd.data_size = data_size;
1734 &parent_zone->key,
1735 parent_delegation_label,
1736 1,
1737 &delegation_rd,
1739 mzctx);
1740 GNUNET_free (data);
1741}
1742
1743
1749static void
1750queue (const char *hostname)
1751{
1752 struct Request *req;
1753 const char *dot;
1754 struct Zone *zone;
1755 size_t hlen;
1756 struct GNUNET_HashCode hc;
1757
1758 if (GNUNET_OK != GNUNET_DNSPARSER_check_name (hostname))
1759 {
1761 "Refusing invalid hostname `%s'\n",
1762 hostname);
1763 rejects++;
1764 return;
1765 }
1766 dot = strchr (hostname, (unsigned char) '.');
1767 if (NULL == dot)
1768 {
1770 "Refusing invalid hostname `%s' (lacks '.')\n",
1771 hostname);
1772 rejects++;
1773 return;
1774 }
1775 for (zone = zone_head; NULL != zone; zone = zone->next)
1776 if (0 == strcmp (zone->domain, dot + 1))
1777 break;
1778 hlen = strlen (hostname) + 1;
1779 req = GNUNET_malloc (sizeof(struct Request) + hlen);
1780 if (NULL == zone)
1781 {
1782 struct MissingZoneCreationCtx *mzctx;
1783
1784 for (mzctx = missing_zones_head;
1785 NULL != mzctx;
1786 mzctx = mzctx->next)
1787 {
1788 const char *tmp_dot;
1789 tmp_dot = strchr (mzctx->req->hostname, (unsigned char) '.');
1790 if (0 != strcmp (dot + 1, tmp_dot + 1))
1791 continue;
1792 break;
1793 }
1794 if (NULL == mzctx)
1795 {
1797 "Domain name `%s' not in ego list! Creating.\n",
1798 dot + 1);
1799 mzctx = GNUNET_new (struct MissingZoneCreationCtx);
1800 mzctx->id_op = GNUNET_IDENTITY_create (id,
1801 dot + 1,
1802 NULL,
1805 mzctx);
1806 mzctx->req = req;
1809 mzctx);
1810 }
1811 }
1812 else
1813 {
1814 req->zone = zone;
1815 }
1816
1817 req->hostname = (char *) &req[1];
1818 GNUNET_memcpy (req->hostname, hostname, hlen);
1820 UINT16_MAX);
1821 GNUNET_CRYPTO_hash (req->hostname, hlen, &hc);
1823 ns_pending,
1824 &hc,
1825 req,
1827 {
1829 "Duplicate hostname `%s' ignored\n",
1830 hostname);
1831 GNUNET_free (req);
1832 return;
1833 }
1834}
1835
1836
1848static int
1849move_to_queue (void *cls, const struct GNUNET_HashCode *key, void *value)
1850{
1851 struct Request *req = value;
1852
1853 (void) cls;
1854 (void) key;
1855 insert_sorted (req);
1856 return GNUNET_OK;
1857}
1858
1859
1866static void
1867iterate_zones (void *cls)
1868{
1869 static struct Zone *last;
1870
1871 (void) cls;
1872 if (NULL != zone_it)
1873 {
1874 zone_it = NULL;
1876 "Finished iteration over zone `%s'!\n",
1877 last->domain);
1878 /* subtract left-overs from previous iteration */
1880 "# NAMESTORE records requested from cache",
1881 (long long) (-ns_iterator_trigger_next),
1882 GNUNET_NO);
1884 }
1885 GNUNET_assert (NULL != zone_tail);
1886 if (zone_tail == last)
1887 {
1888 /* Done iterating over relevant zones in NAMESTORE, move
1889 rest of hash map to work queue as well. */
1891 "Finished all NAMESTORE iterations!\n");
1893 "# Domain names without cached reply",
1895 GNUNET_NO);
1898 ns_pending = NULL;
1902 return;
1903 }
1904 if (NULL == last)
1905 last = zone_head;
1906 else
1907 last = last->next;
1909 "Starting iteration over zone `%s'!\n",
1910 last->domain);
1911 /* subtract left-overs from previous iteration */
1913 "# NAMESTORE records requested from cache",
1914 1,
1915 GNUNET_NO);
1917 GNUNET_STATISTICS_update (stats, "# zones iterated", 1, GNUNET_NO);
1919 &last->key,
1921 NULL,
1923 last,
1925 NULL);
1926}
1927
1928
1934static void
1935process_stdin (void *cls)
1936{
1937 static struct GNUNET_TIME_Absolute last;
1938 char hn[256];
1939 char *hn_utf8;
1940
1941 (void) cls;
1942 t = NULL;
1943 while (NULL != fgets (hn, sizeof(hn), stdin))
1944 {
1945 if (strlen (hn) > 0)
1946 hn[strlen (hn) - 1] = '\0'; /* eat newline */
1947 if (0 == stdin_lines_read)
1948 last = GNUNET_TIME_absolute_get ();
1950 if (0 == stdin_lines_read % 100000)
1951 {
1953
1955 last = GNUNET_TIME_absolute_get ();
1956 fprintf (stderr,
1957 "Read 100000 domain names in %s\n",
1959 GNUNET_STATISTICS_set (stats, "# domain names provided", stdin_lines_read,
1960 GNUNET_NO);
1961 }
1962 idna_to_unicode_8z8z (hn,
1963 &hn_utf8,
1964 IDNA_ALLOW_UNASSIGNED);
1965 queue (hn_utf8);
1966 GNUNET_free (hn_utf8);
1967 }
1968 fprintf (stderr,
1969 "Done reading %llu domain names\n",
1970 (unsigned long long) stdin_lines_read);
1971 GNUNET_STATISTICS_set (stats, "# domain names provided", stdin_lines_read,
1972 GNUNET_NO);
1973 // Only start iteration immediately if no zones are missing.
1974 if (NULL == missing_zones_head)
1975 {
1976 iterate_zones (NULL);
1977 }
1978}
1979
1980
2014static void
2015identity_cb (void *cls,
2016 struct GNUNET_IDENTITY_Ego *ego,
2017 void **ctx,
2018 const char *name)
2019{
2020 (void) cls;
2021 (void) ctx;
2022 static int initial_iteration = GNUNET_YES;
2023
2024 if (GNUNET_NO == initial_iteration)
2025 return;
2026 if (NULL == ego)
2027 {
2028 /* end of iteration */
2029 if (NULL == zone_head)
2030 {
2031 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No zone found\n");
2033 return;
2034 }
2035 initial_iteration = GNUNET_NO;
2036 /* zone_head non-null, process hostnames from stdin */
2038 return;
2039 }
2040 if (NULL != name)
2041 {
2042 struct Zone *zone;
2043
2044 zone = GNUNET_new (struct Zone);
2046 zone->domain = GNUNET_strdup (name);
2048 }
2049}
2050
2051
2061static void
2062run (void *cls,
2063 char *const *args,
2064 const char *cfgfile,
2065 const struct GNUNET_CONFIGURATION_Handle *cfg)
2066{
2067 (void) cls;
2068 (void) args;
2069 (void) cfgfile;
2070 stats = GNUNET_STATISTICS_create ("zoneimport", cfg);
2073 if (NULL == ns_pending)
2074 {
2075 fprintf (stderr, "Failed to allocate memory for main hash map\n");
2076 return;
2077 }
2079 if (NULL == dns_ctx)
2080 {
2081 fprintf (stderr, "Failed to initialize GNUnet DNS STUB\n");
2082 return;
2083 }
2084 if (NULL == args[0])
2085 {
2086 fprintf (stderr,
2087 "You must provide a list of DNS resolvers on the command line\n");
2088 return;
2089 }
2090 for (unsigned int i = 0; NULL != args[i]; i++)
2091 {
2093 {
2094 fprintf (stderr, "Failed to use `%s' for DNS resolver\n", args[i]);
2095 return;
2096 }
2097 }
2098
2099
2102 if (NULL == ns)
2103 {
2105 return;
2106 }
2108}
2109
2110
2118int
2119main (int argc, char *const *argv)
2120{
2123 "size",
2124 "MAPSIZE",
2125 gettext_noop (
2126 "size to use for the main hash map"),
2127 &map_size),
2129 'm',
2130 "minimum-expiration",
2131 "RELATIVETIME",
2132 gettext_noop ("minimum expiration time we assume for imported records"),
2135 int ret;
2136
2137 if (GNUNET_OK !=
2139 argc,
2140 argv,
2141 "gnunet-zoneimport",
2142 "import DNS zone into namestore",
2143 options,
2144 &run,
2145 NULL)))
2146 return 1;
2147 fprintf (stderr,
2148 "Rejected %u names, had %u cached, did %u lookups, stored %u record sets\n"
2149 "Found %u records, %u lookups failed, %u/%u pending on shutdown\n",
2150 rejects,
2151 cached,
2152 lookups,
2154 records,
2155 failures,
2156 pending,
2157 pending_rs);
2158 return 0;
2159}
2160
2161
2162/* end of gnunet-zoneimport.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition 002.c:5
int main()
Program to simulate results from GCP_get_desirability_of_path() for various plausible inputs.
#define gettext_noop(String)
Definition gettext.h:74
#define GNUNET_GNSRECORD_TYPE_GNS2DNS
Delegation to DNS.
static int ret
Final status code.
Definition gnunet-arm.c:93
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition gnunet-arm.c:108
static int do_shutdown
Set to GNUNET_YES if we are shutting down.
static char * data
The data to insert into the dht.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_FS_Handle * ctx
static int raw
raw output
Definition gnunet-gns.c:78
struct GNUNET_CRYPTO_PrivateKey pk
Private key from command line option, or NULL.
static char * name
Name (label) of the records to list.
static unsigned int rd_count
Number of records for currently parsed set.
static struct GNUNET_GNSRECORD_Data rd[50]
The record data under a single label.
static char * value
Value of the record to add/remove.
static uint32_t type
Type string converted to DNS type value.
static size_t data_size
Number of bytes in data.
static char * rp
Relying party.
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
static void free_records(struct Request *req)
Free records associated with req.
#define THRESH
Maximum number of queries pending at the same time.
static void for_all_records(const struct GNUNET_DNSPARSER_Packet *p, RecordProcessor rp, void *rp_cls)
Call rp for each record in p, regardless of what response section it is in.
static void add_record(struct Request *req, uint32_t type, struct GNUNET_TIME_Absolute expiration_time, const void *data, size_t data_len)
Add record to the GNS record set for req.
static unsigned int map_size
Command-line argument specifying desired size of the hash map with all of our pending names.
#define NS_BATCH_SIZE
How many requests do we request from NAMESTORE in one batch during our initial iteration?
static int move_to_queue(void *cls, const struct GNUNET_HashCode *key, void *value)
We have completed the initial iteration over the namestore's database.
static struct Zone * zone_tail
Tail of list of zones we are managing.
static void delegation_store_cont(void *cls, enum GNUNET_ErrorCode ec)
static unsigned int records
Number of records we found.
static struct GNUNET_CONTAINER_Heap * req_heap
Heap of all requests to perform, sorted by the time we should next do the request (i....
static void free_request(struct Request *req)
Free req and data structures reachable from it.
static struct GNUNET_TIME_Absolute start_time_reg_proc
Start time of the regular processing.
static void process_queue(void *cls)
Process as many requests as possible from the queue.
static void store_completed_cb(void *cls, enum GNUNET_ErrorCode ec)
static void queue(const char *hostname)
Add hostname to the list of requests to be made.
static unsigned int pending
The number of DNS queries that are outstanding.
void(* RecordProcessor)(void *cls, const struct GNUNET_DNSPARSER_Record *rec)
Callback for for_all_records.
static int free_request_it(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator called during do_shutdown() to free requests in the ns_pending map.
static struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
static struct GNUNET_NAMESTORE_ZoneIterator * zone_it
Current zone iteration handle.
#define MAX_SERIES
How many DNS requests do we at most issue in rapid series?
static uint64_t total_reg_proc_dns_ns
Number of records processed (DNS lookup, with NAMESTORE) in total.
static char * get_label_utf8(struct Request *req)
static struct GNUNET_TIME_Absolute sleep_time_reg_proc
Last time we worked before going idle.
static struct GNUNET_SCHEDULER_Task * t
Main task.
static struct Zone * zone_head
Head of list of zones we are managing.
static struct GNUNET_TIME_Relative idle_time
Time we slept just waiting for work.
static struct GNUNET_TIME_Relative minimum_expiration_time
How long do DNS records have to last at least after being imported?
static unsigned int cached
Number of records we had cached.
static struct GNUNET_TIME_Relative total_dns_latency
Sum of DNS latencies observed.
static struct GNUNET_CONTAINER_MultiHashMap * ns_pending
Hash map of requests for which we may still get a response from the namestore.
static uint64_t total_dns_latency_cnt
Number of DNS requests counted in latency total.
static uint64_t stdin_lines_read
static void insert_sorted(struct Request *req)
Insert req into DLL sorted by next fetch time.
static unsigned int lookups
Number of lookups we performed overall.
static void missing_zone_creation_cont(void *cls, const struct GNUNET_CRYPTO_PrivateKey *sk, enum GNUNET_ErrorCode ec)
static uint64_t ns_iterator_trigger_next
After how many more results must ns_lookup_result_cb() ask the namestore for more?
static uint64_t total_reg_proc_dns
Number of records processed (DNS lookup, no NAMESTORE) in total.
static void process_record(void *cls, const struct GNUNET_DNSPARSER_Record *rec)
We received rec for req.
static struct GNUNET_NAMESTORE_Handle * ns
Namestore handle.
static const char * get_label(struct Request *req)
Return just the label of the hostname in req.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Process requests from the queue, then if the queue is not empty, try again.
static struct GNUNET_IDENTITY_Handle * id
Handle to the identity service.
static void iterate_zones(void *cls)
Iterate over all of the zones we care about and see which records we may need to re-fetch when.
static unsigned int pending_rs
The number of NAMESTORE record store operations that are outstanding.
static void identity_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *name)
Method called to inform about the egos of this peer.
static void ns_lookup_error_cb(void *cls)
Function called if GNUNET_NAMESTORE_records_lookup() failed.
static void process_result(void *cls, const struct GNUNET_TUN_DnsHeader *dns, size_t dns_len)
Function called with the result of a DNS resolution.
static struct Request * req_tail
Active requests are kept in a DLL.
static struct MissingZoneCreationCtx * missing_zones_head
static void check_for_glue(void *cls, const struct GNUNET_DNSPARSER_Record *rec)
Try to find glue records for a given NS record.
static unsigned int record_sets
Number of record sets given to namestore.
static struct MissingZoneCreationCtx * missing_zones_tail
static unsigned int rejects
How many hostnames did we reject (malformed).
static void ns_lookup_result_cb(void *cls, const struct GNUNET_CRYPTO_PrivateKey *key, const char *label_utf8, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process a record that was stored in the namestore.
static void process_stdin(void *cls)
Begin processing hostnames from stdin.
static struct Request * req_head
Active requests are kept in a DLL.
static struct GNUNET_DNSSTUB_Context * dns_ctx
Context for DNS resolution.
#define MAX_RETRIES
How often do we retry a query before giving up for good?
static unsigned int failures
Number of lookups that failed.
#define SERIES_DELAY
How long do we wait at least between series of requests?
static void * build_dns_query(struct Request *req, size_t *raw_size)
Build DNS query for hostname.
const char * GNUNET_ErrorCode_get_hint(enum GNUNET_ErrorCode ec)
Returns a hint for a given error code.
GNUNET_ErrorCode
Taler error codes.
@ GNUNET_EC_NONE
No error (success).
API that can be used to manipulate GNS record data.
Identity service; implements identity management for GNUnet.
API that can be used to store naming information on a GNUnet node;.
API to create, modify and access statistics.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_NONCE
Randomness for IVs etc.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_DNSPARSER_TYPE_URI
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 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
#define GNUNET_DNSPARSER_TYPE_SRV
#define GNUNET_DNSPARSER_TYPE_SOA
#define GNUNET_DNSPARSER_TYPE_CERT
#define GNUNET_DNSPARSER_TYPE_A
#define GNUNET_DNSPARSER_TYPE_PTR
int GNUNET_DNSPARSER_check_name(const char *name)
Check if a hostname in UTF-8 format can be coded into valid IDNA.
Definition dnsparser.c:79
#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
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
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
#define GNUNET_DNSPARSER_TYPE_AAAA
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
#define GNUNET_DNSPARSER_TYPE_MX
#define GNUNET_DNSPARSER_TYPE_TXT
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
#define GNUNET_DNSPARSER_MAX_NAME_LENGTH
Maximum length of a name in DNS.
struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Definition dnsstub.c:586
int GNUNET_DNSSTUB_add_dns_ip(struct GNUNET_DNSSTUB_Context *ctx, const char *dns_ip)
Add nameserver for use by the DNSSTUB.
Definition dnsstub.c:613
void GNUNET_DNSSTUB_stop(struct GNUNET_DNSSTUB_Context *ctx)
Cleanup DNSSTUB resolver.
Definition dnsstub.c:705
struct GNUNET_DNSSTUB_RequestSocket * GNUNET_DNSSTUB_resolve(struct GNUNET_DNSSTUB_Context *ctx, const void *request, size_t request_len, GNUNET_DNSSTUB_ResultCallback rc, void *rc_cls)
Perform DNS resolution using our default IP from init.
Definition dnsstub.c:526
void GNUNET_DNSSTUB_resolve_cancel(struct GNUNET_DNSSTUB_RequestSocket *rs)
Cancel DNS resolution.
Definition dnsstub.c:562
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_uint(char shortName, const char *name, const char *argumentHelp, const char *description, unsigned int *val)
Allow user to specify an unsigned int.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_relative_time(char shortName, const char *name, const char *argumentHelp, const char *description, struct GNUNET_TIME_Relative *val)
Allow user to specify a struct GNUNET_TIME_Relative (using human-readable "fancy" time).
#define GNUNET_GETOPT_OPTION_END
Marker for the end of the list of options.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_data_from_identity(const struct GNUNET_CRYPTO_PublicKey *key, char **data, size_t *data_size, uint32_t *type)
Create record data and size from an identity key.
@ GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION
This expiration time of the record is a relative time (not an absolute time).
@ GNUNET_GNSRECORD_RF_NONE
Entry for no flags / cleared flags.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:41
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_create(struct GNUNET_IDENTITY_Handle *id, const char *name, const struct GNUNET_CRYPTO_PrivateKey *privkey, enum GNUNET_CRYPTO_KeyType ktype, GNUNET_IDENTITY_CreateContinuation cont, void *cont_cls)
Create a new ego with the given name.
const struct GNUNET_CRYPTO_PrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
struct GNUNET_IDENTITY_Handle * GNUNET_IDENTITY_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_IDENTITY_Callback cb, void *cb_cls)
Connect to the identity service.
void GNUNET_IDENTITY_cancel(struct GNUNET_IDENTITY_Operation *op)
Cancel an identity operation.
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
#define GNUNET_log(kind,...)
#define GNUNET_NZL(l)
Macro used to avoid using 0 for the length of a variable-size array (Non-Zero-Length).
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_key_get_public(const struct GNUNET_CRYPTO_PrivateKey *privkey, struct GNUNET_CRYPTO_PublicKey *key)
Retrieves the public key representation of a private key.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_PUBLIC_KEY_TYPE_EDDSA
EDDSA identity.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
#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_DEBUG
@ 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_free(ptr)
Wrapper around free.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_record_set_store(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_PrivateKey *pkey, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, GNUNET_NAMESTORE_ContinuationWithStatus cont, void *cont_cls)
Store an item in the namestore.
void GNUNET_NAMESTORE_disconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from the namestore service (and free associated resources).
void GNUNET_NAMESTORE_zone_iterator_next(struct GNUNET_NAMESTORE_ZoneIterator *it, uint64_t limit)
Calls the record processor specified in GNUNET_NAMESTORE_zone_iteration_start for the next record.
void GNUNET_NAMESTORE_cancel(struct GNUNET_NAMESTORE_QueueEntry *qe)
Cancel a namestore operation.
struct GNUNET_NAMESTORE_ZoneIterator * GNUNET_NAMESTORE_zone_iteration_start(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_PrivateKey *zone, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor proc, void *proc_cls, GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls)
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namestore service.
void GNUNET_NAMESTORE_zone_iteration_stop(struct GNUNET_NAMESTORE_ZoneIterator *it)
Stops iteration and releases the namestore handle for further calls.
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(const struct GNUNET_OS_ProjectData *pd, int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition program.c:407
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:567
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run at the specified time.
Definition scheduler.c:1254
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition scheduler.c:1339
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:980
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1304
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1277
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition time.c:438
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
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition strings.c:599
#define GNUNET_TIME_UNIT_DAYS
One day.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_subtract(struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative a2)
Subtract relative timestamp from the other.
Definition time.c:605
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
#define GNUNET_TIME_UNIT_WEEKS
One week.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_add(struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative a2)
Add relative times together.
Definition time.c:587
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
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_min(struct GNUNET_TIME_Absolute t1, struct GNUNET_TIME_Absolute t2)
Return the minimum of two absolute time values.
Definition time.c:360
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_divide(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Divide relative time by a given factor.
Definition time.c:552
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition strings.c:660
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define GNUNET_TUN_DNS_CLASS_INTERNET
A few common DNS classes (ok, only one is common, but I list a couple more to make it clear what we'r...
#define GNUNET_TUN_DNS_RETURN_CODE_NO_ERROR
RFC 1035 codes.
#define _(String)
GNU gettext support macro.
Definition platform.h:179
static struct GNUNET_TIME_Relative delta
Definition speedup.c:36
Handle to a node in a heap.
Internal representation of the hash map.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
char * mxhost
Name of the mail server.
Easy-to-process, parsed version of a DNS packet.
void * data
Binary record data.
size_t data_len
Number of bytes in data.
A DNS response record.
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.
Handle to the stub resolver.
Definition dnsstub.c:125
UDP socket we are using for sending DNS requests to the Internet.
Definition dnsstub.c:46
Definition of a command line option.
uint32_t record_type
Type of the GNS/DNS record.
const void * data
Binary value stored in the DNS record.
size_t data_size
Number of bytes in data.
enum GNUNET_GNSRECORD_Flags flags
Flags for the record.
uint64_t expiration_time
Expiration time for the DNS record.
A 512-bit hashcode.
Handle for an ego.
Definition identity.h:37
Handle for the service.
Handle for an operation with the identity service.
Connection to the NAMESTORE service.
An QueueEntry used to store information for a pending NAMESTORE record operation.
Handle for a zone iterator operation.
Entry in list of pending tasks.
Definition scheduler.c:136
Handle for the service.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
unsigned int return_code
See GNUNET_TUN_DNS_RETURN_CODE_ defines.
struct GNUNET_TUN_DnsFlags flags
Flags.
uint16_t id
Unique identifier for the request/response.
Closure for check_for_glue.
struct Request * req
Overall request we are processing.
int found
Set to GNUNET_YES if glue was found.
const char * ns
NS name we are looking for glue for.
Missing identity creation context.
struct MissingZoneCreationCtx * prev
struct MissingZoneCreationCtx * next
struct GNUNET_IDENTITY_Operation * id_op
struct GNUNET_NAMESTORE_QueueEntry * ns_qe
Closure for process_record().
struct Request * req
Request we are processing.
struct GNUNET_DNSPARSER_Packet * p
Answer we got back and are currently parsing, or NULL if not active.
Record for the request to be stored by GNS.
struct GNUNET_GNSRECORD_Data grd
GNS record.
struct Record * next
Kept in a DLL.
struct Record * prev
Kept in a DLL.
Request we should make.
const struct Zone * zone
Zone responsible for this request.
struct GNUNET_TIME_Absolute expires
At what time does the (earliest) of the returned records for this name expire? At this point,...
char * hostname
Hostname we are resolving, allocated at the end of this struct (optimizing memory consumption by redu...
struct Request * next
Active requests are kept in a DLL.
struct Record * rec_head
Head of records that should be published in GNS for this hostname.
struct GNUNET_NAMESTORE_QueueEntry * qe
Namestore operation pending for this record.
struct GNUNET_CONTAINER_HeapNode * hn
Requests are kept in a heap while waiting to be resolved.
struct GNUNET_DNSSTUB_RequestSocket * rs
Socket used to make the request, NULL if not active.
struct Record * rec_tail
Tail of records that should be published in GNS for this hostname.
struct GNUNET_TIME_Absolute op_start_time
While we are fetching the record, the value is set to the starting time of the DNS operation.
uint16_t id
random 16-bit DNS query identifier.
struct Request * prev
Active requests are kept in a DLL.
unsigned int issue_num
How often did we issue this query? (And failed, reset to zero once we were successful....
Egos / Zones.
struct Zone * prev
Kept in a DLL.
struct GNUNET_CRYPTO_PrivateKey key
Private key of the zone.
struct Zone * next
Kept in a DLL.
char * domain
Domain of the zone (i.e.