GNUnet 0.21.1
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 <gnunet_util_lib.h>
30
31
35#define THRESH 100
36
41#define TIME_THRESH 10
42
46#define MAX_RETRIES 5
47
51#define MAX_SERIES 10
52
56#define SERIES_DELAY \
57 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS, 10)
58
63
68#define NS_BATCH_SIZE 1024
69
76struct Zone
77{
81 struct Zone *next;
82
86 struct Zone *prev;
87
91 char *domain;
92
97};
98
99
103struct Record
104{
108 struct Record *next;
109
113 struct Record *prev;
114
119};
120
121
128{
133
137 struct Request *next;
138
142 struct Request *prev;
143
149
155
160
166 char *hostname;
167
172
176 const struct Zone *zone;
177
184
192
197 unsigned int issue_num;
198
202 uint16_t id;
203};
204
205
212static unsigned int map_size = 1024;
213
218
223
228
233
237static unsigned int pending;
238
242static unsigned int pending_rs;
243
247static unsigned int lookups;
248
252static unsigned int cached;
253
257static unsigned int rejects;
258
262static unsigned int failures;
263
267static unsigned int records;
268
272static unsigned int record_sets;
273
279
283static struct Request *req_head;
284
288static struct Request *req_tail;
289
294
301
306
310static struct Zone *zone_head;
311
315static struct Zone *zone_tail;
316
322
326static uint64_t total_dns_latency_cnt;
327
332
336static uint64_t total_reg_proc_dns;
337
341static uint64_t total_reg_proc_dns_ns;
342
347
352
357
358
365typedef void (*RecordProcessor) (void *cls,
366 const struct GNUNET_DNSPARSER_Record *rec);
367
368
377static void
380 void *rp_cls)
381{
382 for (unsigned int i = 0; i < p->num_answers; i++)
383 {
384 struct GNUNET_DNSPARSER_Record *rs = &p->answers[i];
385
386 rp (rp_cls, rs);
387 }
388 for (unsigned int i = 0; i < p->num_authority_records; i++)
389 {
390 struct GNUNET_DNSPARSER_Record *rs = &p->authority_records[i];
391
392 rp (rp_cls, rs);
393 }
394 for (unsigned int i = 0; i < p->num_additional_records; i++)
395 {
396 struct GNUNET_DNSPARSER_Record *rs = &p->additional_records[i];
397
398 rp (rp_cls, rs);
399 }
400}
401
402
410static const char *
411get_label (struct Request *req)
412{
413 static char label[64];
414 const char *dot;
415
416 dot = strchr (req->hostname, (unsigned char) '.');
417 if (NULL == dot)
418 {
419 GNUNET_break (0);
420 return NULL;
421 }
422 if (((size_t) (dot - req->hostname)) >= sizeof(label))
423 {
424 GNUNET_break (0);
425 return NULL;
426 }
427 GNUNET_memcpy (label, req->hostname, dot - req->hostname);
428 label[dot - req->hostname] = '\0';
429 return label;
430}
431
432
441static void *
442build_dns_query (struct Request *req, size_t *raw_size)
443{
444 static char raw[512];
445 char *rawp;
448 int ret;
449
450 q.name = (char *) req->hostname;
452 q.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
453
454 memset (&p, 0, sizeof(p));
455 p.num_queries = 1;
456 p.queries = &q;
457 p.id = req->id;
458 ret = GNUNET_DNSPARSER_pack (&p, UINT16_MAX, &rawp, raw_size);
459 if (GNUNET_OK != ret)
460 {
461 if (GNUNET_NO == ret)
462 GNUNET_free (rawp);
464 "Failed to pack query for hostname `%s'\n",
465 req->hostname);
466 rejects++;
467 return NULL;
468 }
469 if (*raw_size > sizeof(raw))
470 {
472 "Failed to pack query for hostname `%s'\n",
473 req->hostname);
474 rejects++;
475 GNUNET_break (0);
476 GNUNET_free (rawp);
477 return NULL;
478 }
479 GNUNET_memcpy (raw, rawp, *raw_size);
480 GNUNET_free (rawp);
481 return raw;
482}
483
484
490static void
492{
493 struct Record *rec;
494
495 /* Free records */
496 while (NULL != (rec = req->rec_head))
497 {
499 GNUNET_free (rec);
500 }
501}
502
503
509static void
511{
512 free_records (req);
513 GNUNET_free (req);
514}
515
516
522static void
523process_queue (void *cls);
524
525
531static void
533{
534 req->hn =
537 {
538 if (NULL != t)
542 }
543}
544
545
555static void
556add_record (struct Request *req,
557 uint32_t type,
558 struct GNUNET_TIME_Absolute expiration_time,
559 const void *data,
560 size_t data_len)
561{
562 struct Record *rec;
563
564 rec = GNUNET_malloc (sizeof(struct Record) + data_len);
565 rec->grd.data = &rec[1];
566 rec->grd.expiration_time = expiration_time.abs_value_us;
567 rec->grd.data_size = data_len;
568 rec->grd.record_type = type;
570 GNUNET_memcpy (&rec[1], data, data_len);
572}
573
574
579{
583 struct Request *req;
584
588 const char *ns;
589
593 int found;
594};
595
596
603static void
604check_for_glue (void *cls, const struct GNUNET_DNSPARSER_Record *rec)
605{
606 struct GlueClosure *gc = cls;
607 char dst[65536];
608 size_t dst_len;
609 size_t off;
610 char ip[INET6_ADDRSTRLEN + 1];
611 socklen_t ip_size = (socklen_t) sizeof(ip);
612 struct GNUNET_TIME_Absolute expiration_time;
613 struct GNUNET_TIME_Relative left;
614
615 if (0 != strcasecmp (rec->name, gc->ns))
616 return;
617 expiration_time = rec->expiration_time;
618 left = GNUNET_TIME_absolute_get_remaining (expiration_time);
619 if (0 == left.rel_value_us)
620 return; /* ignore expired glue records */
621 /* if expiration window is too short, bump it to configured minimum */
623 expiration_time =
625 dst_len = sizeof(dst);
626 off = 0;
627 switch (rec->type)
628 {
630 if (sizeof(struct in_addr) != rec->data.raw.data_len)
631 {
632 GNUNET_break (0);
633 return;
634 }
635 if (NULL == inet_ntop (AF_INET, rec->data.raw.data, ip, ip_size))
636 {
637 GNUNET_break (0);
638 return;
639 }
641 dst_len,
642 &off,
643 gc->req->hostname)) &&
644 (GNUNET_OK ==
645 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, &off, ip)))
646 {
647 add_record (gc->req,
649 expiration_time,
650 dst,
651 off);
652 gc->found = GNUNET_YES;
653 }
654 break;
655
657 if (sizeof(struct in6_addr) != rec->data.raw.data_len)
658 {
659 GNUNET_break (0);
660 return;
661 }
662 if (NULL == inet_ntop (AF_INET6, rec->data.raw.data, ip, ip_size))
663 {
664 GNUNET_break (0);
665 return;
666 }
668 dst_len,
669 &off,
670 gc->req->hostname)) &&
671 (GNUNET_OK ==
672 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, &off, ip)))
673 {
674 add_record (gc->req,
676 expiration_time,
677 dst,
678 off);
679 gc->found = GNUNET_YES;
680 }
681 break;
682
685 dst_len,
686 &off,
687 gc->req->hostname)) &&
689 dst_len,
690 &off,
691 rec->data.hostname)))
692 {
693 add_record (gc->req,
695 expiration_time,
696 dst,
697 off);
698 gc->found = GNUNET_YES;
699 }
700 break;
701
702 default:
703 /* useless, do nothing */
704 break;
705 }
706}
707
708
713{
719
723 struct Request *req;
724};
725
726
733static void
734process_record (void *cls, const struct GNUNET_DNSPARSER_Record *rec)
735{
736 struct ProcessRecordContext *prc = cls;
737 struct Request *req = prc->req;
738 char dst[65536];
739 size_t dst_len;
740 size_t off;
741 struct GNUNET_TIME_Absolute expiration_time;
742 struct GNUNET_TIME_Relative left;
743
744 dst_len = sizeof(dst);
745 off = 0;
746 records++;
747 if (0 != strcasecmp (rec->name, req->hostname))
748 {
749 GNUNET_log (
751 "DNS returned record from zone `%s' of type %u while resolving `%s'\n",
752 rec->name,
753 (unsigned int) rec->type,
754 req->hostname);
755 return; /* does not match hostname, might be glue, but
756 not useful for this pass! */
757 }
758 expiration_time = rec->expiration_time;
759 left = GNUNET_TIME_absolute_get_remaining (expiration_time);
760 if (0 == left.rel_value_us)
761 {
763 "DNS returned expired record for `%s'\n",
764 req->hostname);
766 "# expired records obtained from DNS",
767 1,
768 GNUNET_NO);
769 return; /* record expired */
770 }
771
773 "DNS returned record that expires at %s for `%s'\n",
775 req->hostname);
776 /* if expiration window is too short, bump it to configured minimum */
778 expiration_time =
780 switch (rec->type)
781 {
783 struct GlueClosure gc;
784
785 /* check for glue */
786 gc.req = req;
787 gc.ns = rec->data.hostname;
788 gc.found = GNUNET_NO;
789 for_all_records (prc->p, &check_for_glue, &gc);
790 if ((GNUNET_NO == gc.found) &&
792 dst_len,
793 &off,
794 req->hostname)) &&
796 dst_len,
797 &off,
798 rec->data.hostname)))
799 {
800 /* FIXME: actually check if this is out-of-bailiwick,
801 and if not request explicit resolution... */
803 "Converted OOB (`%s') NS record for `%s'\n",
804 rec->data.hostname,
805 rec->name);
808 expiration_time,
809 dst,
810 off);
811 }
812 else
813 {
815 "Converted NS record for `%s' using glue\n",
816 rec->name);
817 }
818 break;
819 }
820
823 dst_len,
824 &off,
825 rec->data.hostname))
826 {
828 "Converting CNAME (`%s') record for `%s'\n",
829 rec->data.hostname,
830 rec->name);
831 add_record (req, rec->type, expiration_time, dst, off);
832 }
833 break;
834
836 /* No support for DNAME in GNS yet! FIXME: support later! */
838 "FIXME: not supported: %s DNAME %s\n",
839 rec->name,
840 rec->data.hostname);
841 break;
842
844 if (GNUNET_OK ==
845 GNUNET_DNSPARSER_builder_add_mx (dst, dst_len, &off, rec->data.mx))
846 {
848 "Converting MX (`%s') record for `%s'\n",
849 rec->data.mx->mxhost,
850 rec->name);
851 add_record (req, rec->type, expiration_time, dst, off);
852 }
853 break;
854
856 if (GNUNET_OK ==
857 GNUNET_DNSPARSER_builder_add_soa (dst, dst_len, &off, rec->data.soa))
858 {
859 /* NOTE: GNS does not really use SOAs */
861 "Converting SOA record for `%s'\n",
862 rec->name);
863 add_record (req, rec->type, expiration_time, dst, off);
864 }
865 break;
866
868 if (GNUNET_OK ==
869 GNUNET_DNSPARSER_builder_add_srv (dst, dst_len, &off, rec->data.srv))
870 {
872 "Converting SRV record for `%s'\n",
873 rec->name);
874 add_record (req, rec->type, expiration_time, dst, off);
875 }
876 break;
877
879 if (GNUNET_OK ==
880 GNUNET_DNSPARSER_builder_add_uri (dst, dst_len, &off, rec->data.uri))
881 {
883 "Converting URI record for `%s'\n",
884 rec->name);
885 add_record (req, rec->type, expiration_time, dst, off);
886 }
887 break;
888
891 dst_len,
892 &off,
893 rec->data.hostname))
894 {
895 /* !?: what does a PTR record do in a regular TLD??? */
897 "Converting PTR record for `%s' (weird)\n",
898 rec->name);
899 add_record (req, rec->type, expiration_time, dst, off);
900 }
901 break;
902
904 if (GNUNET_OK ==
905 GNUNET_DNSPARSER_builder_add_cert (dst, dst_len, &off, rec->data.cert))
906 {
908 "Converting CERT record for `%s'\n",
909 rec->name);
910 add_record (req, rec->type, expiration_time, dst, off);
911 }
912 break;
913
914 /* Rest is 'raw' encoded and just needs to be copied IF
915 the hostname matches the requested name; otherwise we
916 simply cannot use it. */
920 default:
922 "Converting record of type %u for `%s'\n",
923 (unsigned int) rec->type,
924 rec->name);
926 rec->type,
927 expiration_time,
928 rec->data.raw.data,
929 rec->data.raw.data_len);
930 break;
931 }
932}
933
934
935static void
937{
938 static struct GNUNET_TIME_Absolute last;
939 struct Request *req = cls;
940
941 req->qe = NULL;
942 if (GNUNET_EC_NONE != ec)
943 {
945 "Failed to store zone data for `%s': %s\n",
946 req->hostname,
948 }
949 else
950 {
952 "Stored records under `%s' (%d)\n",
953 req->hostname,
954 ec);
955 }
956 total_reg_proc_dns_ns++; /* finished regular processing */
957 pending_rs--;
958 free_records (req);
959 /* compute NAMESTORE statistics */
960 {
961 static uint64_t total_ns_latency_cnt;
962 static struct GNUNET_TIME_Relative total_ns_latency;
963 struct GNUNET_TIME_Relative ns_latency;
964
966 total_ns_latency = GNUNET_TIME_relative_add (total_ns_latency, ns_latency);
967 if (0 == total_ns_latency_cnt)
968 last = GNUNET_TIME_absolute_get ();
969 total_ns_latency_cnt++;
970 if (0 == (total_ns_latency_cnt % 1000))
971 {
973
975 last = GNUNET_TIME_absolute_get ();
976 fprintf (stderr,
977 "Processed 1000 records in %s\n",
980 "# average NAMESTORE PUT latency (μs)",
981 total_ns_latency.rel_value_us
982 / total_ns_latency_cnt,
983 GNUNET_NO);
984 }
985 }
986 /* compute and publish overall velocity */
987 if (0 == (total_reg_proc_dns_ns % 100))
988 {
989 struct GNUNET_TIME_Relative runtime;
990
992 runtime = GNUNET_TIME_relative_subtract (runtime, idle_time);
993 runtime =
997 "# Regular processing completed without NAMESTORE",
999 GNUNET_NO);
1001 "# Regular processing completed with NAMESTORE PUT",
1003 GNUNET_NO);
1005 "# average request processing latency (μs)",
1006 runtime.rel_value_us,
1007 GNUNET_NO);
1009 "# total time spent idle (μs)",
1011 GNUNET_NO);
1012 }
1013
1014 if (NULL == t)
1015 {
1018 }
1019}
1020
1021
1029static void
1031 const struct GNUNET_TUN_DnsHeader *dns,
1032 size_t dns_len)
1033{
1034 struct Request *req = cls;
1035 struct Record *rec;
1036 struct GNUNET_DNSPARSER_Packet *p;
1037 unsigned int rd_count;
1038
1039 GNUNET_assert (NULL == req->hn);
1040 if (NULL == dns)
1041 {
1042 /* stub gave up */
1044 pending--;
1045 if (NULL == t)
1046 {
1049 }
1051 "Stub gave up on DNS reply for `%s'\n",
1052 req->hostname);
1053 GNUNET_STATISTICS_update (stats, "# DNS lookups timed out", 1, GNUNET_NO);
1054 if (req->issue_num > MAX_RETRIES)
1055 {
1056 failures++;
1057 free_request (req);
1058 GNUNET_STATISTICS_update (stats, "# requests given up on", 1, GNUNET_NO);
1059 return;
1060 }
1062 req->rs = NULL;
1063 insert_sorted (req);
1064 return;
1065 }
1066 if (req->id != dns->id)
1067 {
1069 "DNS ID did not match request, ignoring reply\n");
1070 GNUNET_STATISTICS_update (stats, "# DNS ID mismatches", 1, GNUNET_NO);
1071 return;
1072 }
1075 req->rs = NULL;
1076 pending--;
1077 p = GNUNET_DNSPARSER_parse ((const char *) dns, dns_len);
1078 if (NULL == p)
1079 {
1081 "Failed to parse DNS reply for `%s'\n",
1082 req->hostname);
1083 GNUNET_STATISTICS_update (stats, "# DNS parser errors", 1, GNUNET_NO);
1084 if (NULL == t)
1085 {
1088 }
1089 if (req->issue_num > MAX_RETRIES)
1090 {
1091 failures++;
1092 free_request (req);
1093 GNUNET_STATISTICS_update (stats, "# requests given up on", 1, GNUNET_NO);
1094 return;
1095 }
1096 insert_sorted (req);
1097 return;
1098 }
1099 /* import new records */
1100 req->issue_num = 0; /* success, reset counter! */
1101 {
1102 struct ProcessRecordContext prc = { .req = req, .p = p };
1103
1105 }
1107 /* count records found, determine minimum expiration time */
1109 {
1110 struct GNUNET_TIME_Relative dns_latency;
1111
1116 if (0 == (total_dns_latency_cnt % 1000))
1117 {
1119 "# average DNS lookup latency (μs)",
1122 GNUNET_NO);
1123 }
1124 }
1125 rd_count = 0;
1126 for (rec = req->rec_head; NULL != rec; rec = rec->next)
1127 {
1128 struct GNUNET_TIME_Absolute at;
1129
1131 req->expires = GNUNET_TIME_absolute_min (req->expires, at);
1132 rd_count++;
1133 }
1135 "Obtained %u records for `%s'\n",
1136 rd_count,
1137 req->hostname);
1138 /* Instead of going for SOA, simplified for now to look each
1139 day in case we got an empty response */
1140 if (0 == rd_count)
1141 {
1144 "# empty DNS replies (usually NXDOMAIN)",
1145 1,
1146 GNUNET_NO);
1147 }
1148 else
1149 {
1150 record_sets++;
1151 }
1152 /* convert records to namestore import format */
1153 {
1155 unsigned int off = 0;
1156
1157 /* convert linked list into array */
1158 for (rec = req->rec_head; NULL != rec; rec = rec->next)
1159 rd[off++] = rec->grd;
1160 pending_rs++;
1163 &req->zone->key,
1164 get_label (req),
1165 rd_count,
1166 rd,
1168 req);
1169 GNUNET_assert (NULL != req->qe);
1170 }
1171 insert_sorted (req);
1172}
1173
1174
1180static void
1181process_queue (void *cls)
1182{
1183 struct Request *req;
1184 unsigned int series;
1185 void *raw;
1186 size_t raw_size;
1187 struct GNUNET_TIME_Relative delay;
1188
1189 (void) cls;
1192 series = 0;
1193 t = NULL;
1194 while (pending + pending_rs < THRESH)
1195 {
1197 if (NULL == req)
1198 break;
1199 if (NULL != req->qe)
1200 return; /* namestore op still pending */
1201 if (NULL != req->rs)
1202 {
1203 GNUNET_break (0);
1204 return; /* already submitted */
1205 }
1207 break;
1209 req->hn = NULL;
1211 GNUNET_assert (NULL == req->rs);
1213 "Requesting resolution for `%s'\n",
1214 req->hostname);
1215 raw = build_dns_query (req, &raw_size);
1216 if (NULL == raw)
1217 {
1218 GNUNET_break (0);
1219 free_request (req);
1220 continue;
1221 }
1223 req->rs = GNUNET_DNSSTUB_resolve (ctx, raw, raw_size, &process_result, req);
1224 GNUNET_assert (NULL != req->rs);
1225 req->issue_num++;
1226 lookups++;
1227 pending++;
1228 series++;
1229 if (series > MAX_SERIES)
1230 break;
1231 }
1232 if (pending + pending_rs >= THRESH)
1233 {
1235 "Stopped processing queue (%u+%u/%u)]\n",
1236 pending,
1237 pending_rs,
1238 THRESH);
1239 return; /* wait for replies */
1240 }
1242 if (NULL == req)
1243 {
1245 "Stopped processing queue: empty queue\n");
1246 return;
1247 }
1249 {
1251 "Waiting until %s for next record (`%s') to expire\n",
1253 req->hostname);
1254 if (NULL != t)
1258 return;
1259 }
1260 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Throttling\n");
1261 if (NULL != t)
1265}
1266
1267
1277static int
1278free_request_it (void *cls, const struct GNUNET_HashCode *key, void *value)
1279{
1280 struct Request *req = value;
1281
1282 (void) cls;
1283 (void) key;
1284 free_request (req);
1285 return GNUNET_OK;
1286}
1287
1288
1294static void
1295do_shutdown (void *cls)
1296{
1297 struct Request *req;
1298 struct Zone *zone;
1299
1300 (void) cls;
1301 if (NULL != id)
1302 {
1304 id = NULL;
1305 }
1306 if (NULL != t)
1307 {
1309 t = NULL;
1310 }
1311 while (NULL != (req = req_head))
1312 {
1314 if (NULL != req->qe)
1316 free_request (req);
1317 }
1318 while (NULL != (req = GNUNET_CONTAINER_heap_remove_root (req_heap)))
1319 {
1320 req->hn = NULL;
1321 if (NULL != req->qe)
1323 free_request (req);
1324 }
1325 if (NULL != zone_it)
1326 {
1328 zone_it = NULL;
1329 }
1330 if (NULL != ns)
1331 {
1333 ns = NULL;
1334 }
1335 if (NULL != ctx)
1336 {
1338 ctx = NULL;
1339 }
1340 if (NULL != req_heap)
1341 {
1343 req_heap = NULL;
1344 }
1345 if (NULL != ns_pending)
1346 {
1349 ns_pending = NULL;
1350 }
1351 while (NULL != (zone = zone_head))
1352 {
1354 GNUNET_free (zone->domain);
1355 GNUNET_free (zone);
1356 }
1357 if (NULL != stats)
1358 {
1360 stats = NULL;
1361 }
1362}
1363
1364
1371static void
1372iterate_zones (void *cls);
1373
1374
1381static void
1383{
1384 struct Zone *zone = cls;
1385
1387 "Failed to load data from namestore for zone `%s'\n",
1388 zone->domain);
1389 zone_it = NULL;
1391 iterate_zones (NULL);
1392}
1393
1394
1404static void
1406 const struct GNUNET_CRYPTO_PrivateKey *key,
1407 const char *label,
1408 unsigned int rd_count,
1409 const struct GNUNET_GNSRECORD_Data *rd)
1410{
1411 struct Zone *zone = cls;
1412 struct Request *req;
1413 struct GNUNET_HashCode hc;
1414 char *fqdn;
1415
1418 "Obtained NAMESTORE reply, %llu left in round\n",
1419 (unsigned long long) ns_iterator_trigger_next);
1420 if (0 == ns_iterator_trigger_next)
1421 {
1424 "# NAMESTORE records requested from cache",
1426 GNUNET_NO);
1428 }
1429 GNUNET_asprintf (&fqdn, "%s.%s", label, zone->domain);
1430 GNUNET_CRYPTO_hash (fqdn, strlen (fqdn) + 1, &hc);
1431 GNUNET_free (fqdn);
1433 if (NULL == req)
1434 {
1436 "Ignoring record `%s' in zone `%s': not on my list!\n",
1437 label,
1438 zone->domain);
1439 return;
1440 }
1443 GNUNET_break (0 == GNUNET_memcmp (key, &req->zone->key));
1444 GNUNET_break (0 == strcasecmp (label, get_label (req)));
1445 for (unsigned int i = 0; i < rd_count; i++)
1446 {
1447 struct GNUNET_TIME_Absolute at;
1448
1450 {
1451 struct GNUNET_TIME_Relative rel;
1452
1455 }
1456 else
1457 {
1459 }
1460 add_record (req, rd->record_type, at, rd->data, rd->data_size);
1461 }
1462 if (0 == rd_count)
1463 {
1465 "Empty record set in namestore for `%s'\n",
1466 req->hostname);
1467 }
1468 else
1469 {
1470 unsigned int pos = 0;
1471
1472 cached++;
1474 for (struct Record *rec = req->rec_head; NULL != rec; rec = rec->next)
1475 {
1476 struct GNUNET_TIME_Absolute at;
1477
1478 at.abs_value_us = rec->grd.expiration_time;
1479 req->expires = GNUNET_TIME_absolute_min (req->expires, at);
1480 pos++;
1481 }
1482 if (0 == pos)
1485 "Hot-start with %u existing records for `%s'\n",
1486 pos,
1487 req->hostname);
1488 }
1489 free_records (req);
1490
1492 "Adding `%s' to worklist to start at %s\n",
1493 req->hostname,
1495 insert_sorted (req);
1496}
1497
1498
1504static void
1505queue (const char *hostname)
1506{
1507 struct Request *req;
1508 const char *dot;
1509 struct Zone *zone;
1510 size_t hlen;
1511 struct GNUNET_HashCode hc;
1512
1513 if (GNUNET_OK != GNUNET_DNSPARSER_check_name (hostname))
1514 {
1516 "Refusing invalid hostname `%s'\n",
1517 hostname);
1518 rejects++;
1519 return;
1520 }
1521 dot = strchr (hostname, (unsigned char) '.');
1522 if (NULL == dot)
1523 {
1525 "Refusing invalid hostname `%s' (lacks '.')\n",
1526 hostname);
1527 rejects++;
1528 return;
1529 }
1530 for (zone = zone_head; NULL != zone; zone = zone->next)
1531 if (0 == strcmp (zone->domain, dot + 1))
1532 break;
1533 if (NULL == zone)
1534 {
1535 rejects++;
1537 "Domain name `%s' not in ego list!\n",
1538 dot + 1);
1539 return;
1540 }
1541
1542 hlen = strlen (hostname) + 1;
1543 req = GNUNET_malloc (sizeof(struct Request) + hlen);
1544 req->zone = zone;
1545 req->hostname = (char *) &req[1];
1546 GNUNET_memcpy (req->hostname, hostname, hlen);
1548 UINT16_MAX);
1549 GNUNET_CRYPTO_hash (req->hostname, hlen, &hc);
1551 ns_pending,
1552 &hc,
1553 req,
1555 {
1557 "Duplicate hostname `%s' ignored\n",
1558 hostname);
1559 GNUNET_free (req);
1560 return;
1561 }
1562}
1563
1564
1576static int
1577move_to_queue (void *cls, const struct GNUNET_HashCode *key, void *value)
1578{
1579 struct Request *req = value;
1580
1581 (void) cls;
1582 (void) key;
1583 insert_sorted (req);
1584 return GNUNET_OK;
1585}
1586
1587
1594static void
1595iterate_zones (void *cls)
1596{
1597 static struct Zone *last;
1598
1599 (void) cls;
1600 if (NULL != zone_it)
1601 {
1602 zone_it = NULL;
1604 "Finished iteration over zone `%s'!\n",
1605 last->domain);
1606 /* subtract left-overs from previous iteration */
1608 "# NAMESTORE records requested from cache",
1609 (long long) (-ns_iterator_trigger_next),
1610 GNUNET_NO);
1612 }
1613 GNUNET_assert (NULL != zone_tail);
1614 if (zone_tail == last)
1615 {
1616 /* Done iterating over relevant zones in NAMESTORE, move
1617 rest of hash map to work queue as well. */
1619 "Finished all NAMESTORE iterations!\n");
1621 "# Domain names without cached reply",
1623 GNUNET_NO);
1626 ns_pending = NULL;
1630 return;
1631 }
1632 if (NULL == last)
1633 last = zone_head;
1634 else
1635 last = last->next;
1637 "Starting iteration over zone `%s'!\n",
1638 last->domain);
1639 /* subtract left-overs from previous iteration */
1641 "# NAMESTORE records requested from cache",
1642 1,
1643 GNUNET_NO);
1645 GNUNET_STATISTICS_update (stats, "# zones iterated", 1, GNUNET_NO);
1647 &last->key,
1649 NULL,
1651 last,
1653 NULL);
1654}
1655
1656
1662static void
1663process_stdin (void *cls)
1664{
1665 static struct GNUNET_TIME_Absolute last;
1666 static uint64_t idot;
1667 char hn[256];
1668
1669 (void) cls;
1670 t = NULL;
1671 if (NULL != id)
1672 {
1674 id = NULL;
1675 }
1676 while (NULL != fgets (hn, sizeof(hn), stdin))
1677 {
1678 if (strlen (hn) > 0)
1679 hn[strlen (hn) - 1] = '\0'; /* eat newline */
1680 if (0 == idot)
1681 last = GNUNET_TIME_absolute_get ();
1682 idot++;
1683 if (0 == idot % 100000)
1684 {
1686
1688 last = GNUNET_TIME_absolute_get ();
1689 fprintf (stderr,
1690 "Read 100000 domain names in %s\n",
1692 GNUNET_STATISTICS_set (stats, "# domain names provided", idot, GNUNET_NO);
1693 }
1694 queue (hn);
1695 }
1696 fprintf (stderr,
1697 "Done reading %llu domain names\n",
1698 (unsigned long long) idot);
1699 GNUNET_STATISTICS_set (stats, "# domain names provided", idot, GNUNET_NO);
1700 iterate_zones (NULL);
1701}
1702
1703
1737static void
1738identity_cb (void *cls,
1739 struct GNUNET_IDENTITY_Ego *ego,
1740 void **ctx,
1741 const char *name)
1742{
1743 (void) cls;
1744 (void) ctx;
1745
1746 if (NULL == ego)
1747 {
1748 /* end of iteration */
1749 if (NULL == zone_head)
1750 {
1751 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No zone found\n");
1753 return;
1754 }
1755 /* zone_head non-null, process hostnames from stdin */
1757 return;
1758 }
1759 if (NULL != name)
1760 {
1761 struct Zone *zone;
1762
1763 zone = GNUNET_new (struct Zone);
1765 zone->domain = GNUNET_strdup (name);
1767 }
1768}
1769
1770
1780static void
1781run (void *cls,
1782 char *const *args,
1783 const char *cfgfile,
1784 const struct GNUNET_CONFIGURATION_Handle *cfg)
1785{
1786 (void) cls;
1787 (void) args;
1788 (void) cfgfile;
1789 stats = GNUNET_STATISTICS_create ("zoneimport", cfg);
1792 if (NULL == ns_pending)
1793 {
1794 fprintf (stderr, "Failed to allocate memory for main hash map\n");
1795 return;
1796 }
1797 ctx = GNUNET_DNSSTUB_start (256);
1798 if (NULL == ctx)
1799 {
1800 fprintf (stderr, "Failed to initialize GNUnet DNS STUB\n");
1801 return;
1802 }
1803 if (NULL == args[0])
1804 {
1805 fprintf (stderr,
1806 "You must provide a list of DNS resolvers on the command line\n");
1807 return;
1808 }
1809 for (unsigned int i = 0; NULL != args[i]; i++)
1810 {
1812 {
1813 fprintf (stderr, "Failed to use `%s' for DNS resolver\n", args[i]);
1814 return;
1815 }
1816 }
1817
1818
1821 if (NULL == ns)
1822 {
1824 return;
1825 }
1827}
1828
1829
1837int
1838main (int argc, char *const *argv)
1839{
1842 "size",
1843 "MAPSIZE",
1844 gettext_noop (
1845 "size to use for the main hash map"),
1846 &map_size),
1848 'm',
1849 "minimum-expiration",
1850 "RELATIVETIME",
1851 gettext_noop ("minimum expiration time we assume for imported records"),
1854 int ret;
1855
1856 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1857 return 2;
1858 if (GNUNET_OK != (ret = GNUNET_PROGRAM_run (argc,
1859 argv,
1860 "gnunet-zoneimport",
1861 "import DNS zone into namestore",
1862 options,
1863 &run,
1864 NULL)))
1865 return ret;
1866 GNUNET_free_nz ((void *) argv);
1867 fprintf (stderr,
1868 "Rejected %u names, had %u cached, did %u lookups, stored %u record sets\n"
1869 "Found %u records, %u lookups failed, %u/%u pending on shutdown\n",
1870 rejects,
1871 cached,
1872 lookups,
1874 records,
1875 failures,
1876 pending,
1877 pending_rs);
1878 return 0;
1879}
1880
1881
1882/* end of gnunet-zoneimport.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define gettext_noop(String)
Definition: gettext.h:70
static int ret
Final status code.
Definition: gnunet-arm.c:94
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:109
static char * data
The data to insert into the dht.
struct GNUNET_HashCode key
The key used in the DHT.
static int raw
raw output
Definition: gnunet-gns.c:78
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 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 GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
static struct Zone * zone_tail
Tail of list of zones we are managing.
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 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 void do_shutdown(void *cls)
Clean up and terminate the process.
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 ns_lookup_result_cb(void *cls, const struct GNUNET_CRYPTO_PrivateKey *key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process a record that was stored in the namestore.
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.
int main(int argc, char *const *argv)
Call with IP address of resolver to query.
static struct Request * req_tail
Active requests are kept in a DLL.
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 unsigned int rejects
How many hostnames did we reject (malformed).
static void process_stdin(void *cls)
Begin processing hostnames from stdin.
static struct Request * req_head
Active requests are kept in a DLL.
#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.
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:982
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:1125
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition: dnsparser.c:947
#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:1172
#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:1096
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
#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: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
#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:727
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).
@ 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.
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.
Definition: identity_api.c:517
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.
Definition: identity_api.c:487
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:732
#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).
#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_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.
#define GNUNET_free_nz(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.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(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:400
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:1255
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:1340
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:981
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:1305
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:1278
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).
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1230
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:436
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
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:570
#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:603
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
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:585
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_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:359
#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:550
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:617
#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...
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:36
#define GNUNET_GNSRECORD_TYPE_GNS2DNS
Delegation to DNS.
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).
Handle to a node in a heap.
Internal representation of the hash map.
A private key for an identity 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.
Definition: identity_api.c:97
Connection to the NAMESTORE service.
An QueueEntry used to store information for a pending NAMESTORE record operation.
Definition: namestore_api.c:49
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.
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.
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....
Some zones may include authoritative records for other zones, such as foo.com.uk or bar....
char * domain
Domain of the zone (i.e.
struct Zone * prev
Kept in a DLL.
struct GNUNET_CRYPTO_PrivateKey key
Private key of the zone.
struct Zone * next
Kept in a DLL.