GNUnet 0.22.2
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 (dns_ctx, raw, raw_size, &process_result,
1224 req);
1225 GNUNET_assert (NULL != req->rs);
1226 req->issue_num++;
1227 lookups++;
1228 pending++;
1229 series++;
1230 if (series > MAX_SERIES)
1231 break;
1232 }
1233 if (pending + pending_rs >= THRESH)
1234 {
1236 "Stopped processing queue (%u+%u/%u)]\n",
1237 pending,
1238 pending_rs,
1239 THRESH);
1240 return; /* wait for replies */
1241 }
1243 if (NULL == req)
1244 {
1246 "Stopped processing queue: empty queue\n");
1247 return;
1248 }
1250 {
1252 "Waiting until %s for next record (`%s') to expire\n",
1254 req->hostname);
1255 if (NULL != t)
1259 return;
1260 }
1261 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Throttling\n");
1262 if (NULL != t)
1266}
1267
1268
1278static int
1279free_request_it (void *cls, const struct GNUNET_HashCode *key, void *value)
1280{
1281 struct Request *req = value;
1282
1283 (void) cls;
1284 (void) key;
1285 free_request (req);
1286 return GNUNET_OK;
1287}
1288
1289
1295static void
1296do_shutdown (void *cls)
1297{
1298 struct Request *req;
1299 struct Zone *zone;
1300
1301 (void) cls;
1302 if (NULL != id)
1303 {
1305 id = NULL;
1306 }
1307 if (NULL != t)
1308 {
1310 t = NULL;
1311 }
1312 while (NULL != (req = req_head))
1313 {
1315 if (NULL != req->qe)
1317 free_request (req);
1318 }
1319 while (NULL != (req = GNUNET_CONTAINER_heap_remove_root (req_heap)))
1320 {
1321 req->hn = NULL;
1322 if (NULL != req->qe)
1324 free_request (req);
1325 }
1326 if (NULL != zone_it)
1327 {
1329 zone_it = NULL;
1330 }
1331 if (NULL != ns)
1332 {
1334 ns = NULL;
1335 }
1336 if (NULL != dns_ctx)
1337 {
1339 dns_ctx = NULL;
1340 }
1341 if (NULL != req_heap)
1342 {
1344 req_heap = NULL;
1345 }
1346 if (NULL != ns_pending)
1347 {
1350 ns_pending = NULL;
1351 }
1352 while (NULL != (zone = zone_head))
1353 {
1355 GNUNET_free (zone->domain);
1356 GNUNET_free (zone);
1357 }
1358 if (NULL != stats)
1359 {
1361 stats = NULL;
1362 }
1363}
1364
1365
1372static void
1373iterate_zones (void *cls);
1374
1375
1382static void
1384{
1385 struct Zone *zone = cls;
1386
1388 "Failed to load data from namestore for zone `%s'\n",
1389 zone->domain);
1390 zone_it = NULL;
1392 iterate_zones (NULL);
1393}
1394
1395
1405static void
1407 const struct GNUNET_CRYPTO_PrivateKey *key,
1408 const char *label,
1409 unsigned int rd_count,
1410 const struct GNUNET_GNSRECORD_Data *rd)
1411{
1412 struct Zone *zone = cls;
1413 struct Request *req;
1414 struct GNUNET_HashCode hc;
1415 char *fqdn;
1416
1419 "Obtained NAMESTORE reply, %llu left in round\n",
1420 (unsigned long long) ns_iterator_trigger_next);
1421 if (0 == ns_iterator_trigger_next)
1422 {
1425 "# NAMESTORE records requested from cache",
1427 GNUNET_NO);
1429 }
1430 GNUNET_asprintf (&fqdn, "%s.%s", label, zone->domain);
1431 GNUNET_CRYPTO_hash (fqdn, strlen (fqdn) + 1, &hc);
1432 GNUNET_free (fqdn);
1434 if (NULL == req)
1435 {
1437 "Ignoring record `%s' in zone `%s': not on my list!\n",
1438 label,
1439 zone->domain);
1440 return;
1441 }
1444 GNUNET_break (0 == GNUNET_memcmp (key, &req->zone->key));
1445 GNUNET_break (0 == strcasecmp (label, get_label (req)));
1446 for (unsigned int i = 0; i < rd_count; i++)
1447 {
1448 struct GNUNET_TIME_Absolute at;
1449
1451 {
1452 struct GNUNET_TIME_Relative rel;
1453
1456 }
1457 else
1458 {
1460 }
1461 add_record (req, rd->record_type, at, rd->data, rd->data_size);
1462 }
1463 if (0 == rd_count)
1464 {
1466 "Empty record set in namestore for `%s'\n",
1467 req->hostname);
1468 }
1469 else
1470 {
1471 unsigned int pos = 0;
1472
1473 cached++;
1475 for (struct Record *rec = req->rec_head; NULL != rec; rec = rec->next)
1476 {
1477 struct GNUNET_TIME_Absolute at;
1478
1479 at.abs_value_us = rec->grd.expiration_time;
1480 req->expires = GNUNET_TIME_absolute_min (req->expires, at);
1481 pos++;
1482 }
1483 if (0 == pos)
1486 "Hot-start with %u existing records for `%s'\n",
1487 pos,
1488 req->hostname);
1489 }
1490 free_records (req);
1491
1493 "Adding `%s' to worklist to start at %s\n",
1494 req->hostname,
1496 insert_sorted (req);
1497}
1498
1499
1505static void
1506queue (const char *hostname)
1507{
1508 struct Request *req;
1509 const char *dot;
1510 struct Zone *zone;
1511 size_t hlen;
1512 struct GNUNET_HashCode hc;
1513
1514 if (GNUNET_OK != GNUNET_DNSPARSER_check_name (hostname))
1515 {
1517 "Refusing invalid hostname `%s'\n",
1518 hostname);
1519 rejects++;
1520 return;
1521 }
1522 dot = strchr (hostname, (unsigned char) '.');
1523 if (NULL == dot)
1524 {
1526 "Refusing invalid hostname `%s' (lacks '.')\n",
1527 hostname);
1528 rejects++;
1529 return;
1530 }
1531 for (zone = zone_head; NULL != zone; zone = zone->next)
1532 if (0 == strcmp (zone->domain, dot + 1))
1533 break;
1534 if (NULL == zone)
1535 {
1536 rejects++;
1538 "Domain name `%s' not in ego list!\n",
1539 dot + 1);
1540 return;
1541 }
1542
1543 hlen = strlen (hostname) + 1;
1544 req = GNUNET_malloc (sizeof(struct Request) + hlen);
1545 req->zone = zone;
1546 req->hostname = (char *) &req[1];
1547 GNUNET_memcpy (req->hostname, hostname, hlen);
1549 UINT16_MAX);
1550 GNUNET_CRYPTO_hash (req->hostname, hlen, &hc);
1552 ns_pending,
1553 &hc,
1554 req,
1556 {
1558 "Duplicate hostname `%s' ignored\n",
1559 hostname);
1560 GNUNET_free (req);
1561 return;
1562 }
1563}
1564
1565
1577static int
1578move_to_queue (void *cls, const struct GNUNET_HashCode *key, void *value)
1579{
1580 struct Request *req = value;
1581
1582 (void) cls;
1583 (void) key;
1584 insert_sorted (req);
1585 return GNUNET_OK;
1586}
1587
1588
1595static void
1596iterate_zones (void *cls)
1597{
1598 static struct Zone *last;
1599
1600 (void) cls;
1601 if (NULL != zone_it)
1602 {
1603 zone_it = NULL;
1605 "Finished iteration over zone `%s'!\n",
1606 last->domain);
1607 /* subtract left-overs from previous iteration */
1609 "# NAMESTORE records requested from cache",
1610 (long long) (-ns_iterator_trigger_next),
1611 GNUNET_NO);
1613 }
1614 GNUNET_assert (NULL != zone_tail);
1615 if (zone_tail == last)
1616 {
1617 /* Done iterating over relevant zones in NAMESTORE, move
1618 rest of hash map to work queue as well. */
1620 "Finished all NAMESTORE iterations!\n");
1622 "# Domain names without cached reply",
1624 GNUNET_NO);
1627 ns_pending = NULL;
1631 return;
1632 }
1633 if (NULL == last)
1634 last = zone_head;
1635 else
1636 last = last->next;
1638 "Starting iteration over zone `%s'!\n",
1639 last->domain);
1640 /* subtract left-overs from previous iteration */
1642 "# NAMESTORE records requested from cache",
1643 1,
1644 GNUNET_NO);
1646 GNUNET_STATISTICS_update (stats, "# zones iterated", 1, GNUNET_NO);
1648 &last->key,
1650 NULL,
1652 last,
1654 NULL);
1655}
1656
1657
1663static void
1664process_stdin (void *cls)
1665{
1666 static struct GNUNET_TIME_Absolute last;
1667 static uint64_t idot;
1668 char hn[256];
1669
1670 (void) cls;
1671 t = NULL;
1672 if (NULL != id)
1673 {
1675 id = NULL;
1676 }
1677 while (NULL != fgets (hn, sizeof(hn), stdin))
1678 {
1679 if (strlen (hn) > 0)
1680 hn[strlen (hn) - 1] = '\0'; /* eat newline */
1681 if (0 == idot)
1682 last = GNUNET_TIME_absolute_get ();
1683 idot++;
1684 if (0 == idot % 100000)
1685 {
1687
1689 last = GNUNET_TIME_absolute_get ();
1690 fprintf (stderr,
1691 "Read 100000 domain names in %s\n",
1693 GNUNET_STATISTICS_set (stats, "# domain names provided", idot, GNUNET_NO);
1694 }
1695 queue (hn);
1696 }
1697 fprintf (stderr,
1698 "Done reading %llu domain names\n",
1699 (unsigned long long) idot);
1700 GNUNET_STATISTICS_set (stats, "# domain names provided", idot, GNUNET_NO);
1701 iterate_zones (NULL);
1702}
1703
1704
1738static void
1739identity_cb (void *cls,
1740 struct GNUNET_IDENTITY_Ego *ego,
1741 void **ctx,
1742 const char *name)
1743{
1744 (void) cls;
1745 (void) ctx;
1746
1747 if (NULL == ego)
1748 {
1749 /* end of iteration */
1750 if (NULL == zone_head)
1751 {
1752 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No zone found\n");
1754 return;
1755 }
1756 /* zone_head non-null, process hostnames from stdin */
1758 return;
1759 }
1760 if (NULL != name)
1761 {
1762 struct Zone *zone;
1763
1764 zone = GNUNET_new (struct Zone);
1766 zone->domain = GNUNET_strdup (name);
1768 }
1769}
1770
1771
1781static void
1782run (void *cls,
1783 char *const *args,
1784 const char *cfgfile,
1785 const struct GNUNET_CONFIGURATION_Handle *cfg)
1786{
1787 (void) cls;
1788 (void) args;
1789 (void) cfgfile;
1790 stats = GNUNET_STATISTICS_create ("zoneimport", cfg);
1793 if (NULL == ns_pending)
1794 {
1795 fprintf (stderr, "Failed to allocate memory for main hash map\n");
1796 return;
1797 }
1799 if (NULL == dns_ctx)
1800 {
1801 fprintf (stderr, "Failed to initialize GNUnet DNS STUB\n");
1802 return;
1803 }
1804 if (NULL == args[0])
1805 {
1806 fprintf (stderr,
1807 "You must provide a list of DNS resolvers on the command line\n");
1808 return;
1809 }
1810 for (unsigned int i = 0; NULL != args[i]; i++)
1811 {
1813 {
1814 fprintf (stderr, "Failed to use `%s' for DNS resolver\n", args[i]);
1815 return;
1816 }
1817 }
1818
1819
1822 if (NULL == ns)
1823 {
1825 return;
1826 }
1828}
1829
1830
1838int
1839main (int argc, char *const *argv)
1840{
1843 "size",
1844 "MAPSIZE",
1845 gettext_noop (
1846 "size to use for the main hash map"),
1847 &map_size),
1849 'm',
1850 "minimum-expiration",
1851 "RELATIVETIME",
1852 gettext_noop ("minimum expiration time we assume for imported records"),
1855 int ret;
1856
1857 if (GNUNET_OK !=
1859 argc,
1860 argv,
1861 "gnunet-zoneimport",
1862 "import DNS zone into namestore",
1863 options,
1864 &run,
1865 NULL)))
1866 return 1;
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: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 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
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 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.
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
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.
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:579
#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
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_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:640
#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
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.