GNUnet  0.20.0
gnunet-zoneimport.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2018 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
25 #include "platform.h"
26 #include <gnunet_util_lib.h>
27 #include <gnunet_gnsrecord_lib.h>
31 
32 
36 #define THRESH 100
37 
42 #define TIME_THRESH 10
43 
47 #define MAX_RETRIES 5
48 
52 #define MAX_SERIES 10
53 
57 #define SERIES_DELAY \
58  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS, 10)
59 
64 
69 #define NS_BATCH_SIZE 1024
70 
77 struct Zone
78 {
82  struct Zone *next;
83 
87  struct Zone *prev;
88 
92  char *domain;
93 
98 };
99 
100 
104 struct Record
105 {
109  struct Record *next;
110 
114  struct Record *prev;
115 
119  struct GNUNET_GNSRECORD_Data grd;
120 };
121 
122 
128 struct Request
129 {
134 
138  struct Request *next;
139 
143  struct Request *prev;
144 
149  struct Record *rec_head;
150 
155  struct Record *rec_tail;
156 
161 
167  char *hostname;
168 
173 
177  const struct Zone *zone;
178 
185 
193 
198  unsigned int issue_num;
199 
203  uint16_t id;
204 };
205 
206 
213 static unsigned int map_size = 1024;
214 
218 static struct GNUNET_IDENTITY_Handle *id;
219 
224 
229 
234 
238 static unsigned int pending;
239 
243 static unsigned int pending_rs;
244 
248 static unsigned int lookups;
249 
253 static unsigned int cached;
254 
258 static unsigned int rejects;
259 
263 static unsigned int failures;
264 
268 static unsigned int records;
269 
273 static unsigned int record_sets;
274 
280 
284 static struct Request *req_head;
285 
289 static struct Request *req_tail;
290 
294 static struct GNUNET_SCHEDULER_Task *t;
295 
302 
307 
311 static struct Zone *zone_head;
312 
316 static struct Zone *zone_tail;
317 
322 static uint64_t ns_iterator_trigger_next;
323 
327 static uint64_t total_dns_latency_cnt;
328 
333 
337 static uint64_t total_reg_proc_dns;
338 
342 static uint64_t total_reg_proc_dns_ns;
343 
348 
353 
357 static struct GNUNET_TIME_Relative idle_time;
358 
359 
366 typedef void (*RecordProcessor) (void *cls,
367  const struct GNUNET_DNSPARSER_Record *rec);
368 
369 
378 static void
381  void *rp_cls)
382 {
383  for (unsigned int i = 0; i < p->num_answers; i++)
384  {
385  struct GNUNET_DNSPARSER_Record *rs = &p->answers[i];
386 
387  rp (rp_cls, rs);
388  }
389  for (unsigned int i = 0; i < p->num_authority_records; i++)
390  {
391  struct GNUNET_DNSPARSER_Record *rs = &p->authority_records[i];
392 
393  rp (rp_cls, rs);
394  }
395  for (unsigned int i = 0; i < p->num_additional_records; i++)
396  {
397  struct GNUNET_DNSPARSER_Record *rs = &p->additional_records[i];
398 
399  rp (rp_cls, rs);
400  }
401 }
402 
403 
411 static const char *
412 get_label (struct Request *req)
413 {
414  static char label[64];
415  const char *dot;
416 
417  dot = strchr (req->hostname, (unsigned char) '.');
418  if (NULL == dot)
419  {
420  GNUNET_break (0);
421  return NULL;
422  }
423  if (((size_t) (dot - req->hostname)) >= sizeof(label))
424  {
425  GNUNET_break (0);
426  return NULL;
427  }
428  GNUNET_memcpy (label, req->hostname, dot - req->hostname);
429  label[dot - req->hostname] = '\0';
430  return label;
431 }
432 
433 
442 static void *
443 build_dns_query (struct Request *req, size_t *raw_size)
444 {
445  static char raw[512];
446  char *rawp;
447  struct GNUNET_DNSPARSER_Packet p;
448  struct GNUNET_DNSPARSER_Query q;
449  int ret;
450 
451  q.name = (char *) req->hostname;
453  q.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
454 
455  memset (&p, 0, sizeof(p));
456  p.num_queries = 1;
457  p.queries = &q;
458  p.id = req->id;
459  ret = GNUNET_DNSPARSER_pack (&p, UINT16_MAX, &rawp, raw_size);
460  if (GNUNET_OK != ret)
461  {
462  if (GNUNET_NO == ret)
463  GNUNET_free (rawp);
465  "Failed to pack query for hostname `%s'\n",
466  req->hostname);
467  rejects++;
468  return NULL;
469  }
470  if (*raw_size > sizeof(raw))
471  {
473  "Failed to pack query for hostname `%s'\n",
474  req->hostname);
475  rejects++;
476  GNUNET_break (0);
477  GNUNET_free (rawp);
478  return NULL;
479  }
480  GNUNET_memcpy (raw, rawp, *raw_size);
481  GNUNET_free (rawp);
482  return raw;
483 }
484 
485 
491 static void
492 free_records (struct Request *req)
493 {
494  struct Record *rec;
495 
496  /* Free records */
497  while (NULL != (rec = req->rec_head))
498  {
500  GNUNET_free (rec);
501  }
502 }
503 
504 
510 static void
511 free_request (struct Request *req)
512 {
513  free_records (req);
514  GNUNET_free (req);
515 }
516 
517 
523 static void
524 process_queue (void *cls);
525 
526 
532 static void
533 insert_sorted (struct Request *req)
534 {
535  req->hn =
538  {
539  if (NULL != t)
543  }
544 }
545 
546 
556 static void
557 add_record (struct Request *req,
558  uint32_t type,
559  struct GNUNET_TIME_Absolute expiration_time,
560  const void *data,
561  size_t data_len)
562 {
563  struct Record *rec;
564 
565  rec = GNUNET_malloc (sizeof(struct Record) + data_len);
566  rec->grd.data = &rec[1];
567  rec->grd.expiration_time = expiration_time.abs_value_us;
568  rec->grd.data_size = data_len;
569  rec->grd.record_type = type;
571  GNUNET_memcpy (&rec[1], data, data_len);
573 }
574 
575 
580 {
584  struct Request *req;
585 
589  const char *ns;
590 
594  int found;
595 };
596 
597 
604 static void
605 check_for_glue (void *cls, const struct GNUNET_DNSPARSER_Record *rec)
606 {
607  struct GlueClosure *gc = cls;
608  char dst[65536];
609  size_t dst_len;
610  size_t off;
611  char ip[INET6_ADDRSTRLEN + 1];
612  socklen_t ip_size = (socklen_t) sizeof(ip);
613  struct GNUNET_TIME_Absolute expiration_time;
614  struct GNUNET_TIME_Relative left;
615 
616  if (0 != strcasecmp (rec->name, gc->ns))
617  return;
618  expiration_time = rec->expiration_time;
619  left = GNUNET_TIME_absolute_get_remaining (expiration_time);
620  if (0 == left.rel_value_us)
621  return; /* ignore expired glue records */
622  /* if expiration window is too short, bump it to configured minimum */
624  expiration_time =
626  dst_len = sizeof(dst);
627  off = 0;
628  switch (rec->type)
629  {
631  if (sizeof(struct in_addr) != rec->data.raw.data_len)
632  {
633  GNUNET_break (0);
634  return;
635  }
636  if (NULL == inet_ntop (AF_INET, rec->data.raw.data, ip, ip_size))
637  {
638  GNUNET_break (0);
639  return;
640  }
642  dst_len,
643  &off,
644  gc->req->hostname)) &&
645  (GNUNET_OK ==
646  GNUNET_DNSPARSER_builder_add_name (dst, dst_len, &off, ip)))
647  {
648  add_record (gc->req,
650  expiration_time,
651  dst,
652  off);
653  gc->found = GNUNET_YES;
654  }
655  break;
656 
658  if (sizeof(struct in6_addr) != rec->data.raw.data_len)
659  {
660  GNUNET_break (0);
661  return;
662  }
663  if (NULL == inet_ntop (AF_INET6, rec->data.raw.data, ip, ip_size))
664  {
665  GNUNET_break (0);
666  return;
667  }
669  dst_len,
670  &off,
671  gc->req->hostname)) &&
672  (GNUNET_OK ==
673  GNUNET_DNSPARSER_builder_add_name (dst, dst_len, &off, ip)))
674  {
675  add_record (gc->req,
677  expiration_time,
678  dst,
679  off);
680  gc->found = GNUNET_YES;
681  }
682  break;
683 
686  dst_len,
687  &off,
688  gc->req->hostname)) &&
690  dst_len,
691  &off,
692  rec->data.hostname)))
693  {
694  add_record (gc->req,
696  expiration_time,
697  dst,
698  off);
699  gc->found = GNUNET_YES;
700  }
701  break;
702 
703  default:
704  /* useless, do nothing */
705  break;
706  }
707 }
708 
709 
714 {
720 
724  struct Request *req;
725 };
726 
727 
734 static void
735 process_record (void *cls, const struct GNUNET_DNSPARSER_Record *rec)
736 {
737  struct ProcessRecordContext *prc = cls;
738  struct Request *req = prc->req;
739  char dst[65536];
740  size_t dst_len;
741  size_t off;
742  struct GNUNET_TIME_Absolute expiration_time;
743  struct GNUNET_TIME_Relative left;
744 
745  dst_len = sizeof(dst);
746  off = 0;
747  records++;
748  if (0 != strcasecmp (rec->name, req->hostname))
749  {
750  GNUNET_log (
752  "DNS returned record from zone `%s' of type %u while resolving `%s'\n",
753  rec->name,
754  (unsigned int) rec->type,
755  req->hostname);
756  return; /* does not match hostname, might be glue, but
757  not useful for this pass! */
758  }
759  expiration_time = rec->expiration_time;
760  left = GNUNET_TIME_absolute_get_remaining (expiration_time);
761  if (0 == left.rel_value_us)
762  {
764  "DNS returned expired record for `%s'\n",
765  req->hostname);
767  "# expired records obtained from DNS",
768  1,
769  GNUNET_NO);
770  return; /* record expired */
771  }
772 
774  "DNS returned record that expires at %s for `%s'\n",
775  GNUNET_STRINGS_absolute_time_to_string (expiration_time),
776  req->hostname);
777  /* if expiration window is too short, bump it to configured minimum */
779  expiration_time =
781  switch (rec->type)
782  {
784  struct GlueClosure gc;
785 
786  /* check for glue */
787  gc.req = req;
788  gc.ns = rec->data.hostname;
789  gc.found = GNUNET_NO;
790  for_all_records (prc->p, &check_for_glue, &gc);
791  if ((GNUNET_NO == gc.found) &&
793  dst_len,
794  &off,
795  req->hostname)) &&
797  dst_len,
798  &off,
799  rec->data.hostname)))
800  {
801  /* FIXME: actually check if this is out-of-bailiwick,
802  and if not request explicit resolution... */
804  "Converted OOB (`%s') NS record for `%s'\n",
805  rec->data.hostname,
806  rec->name);
807  add_record (req,
809  expiration_time,
810  dst,
811  off);
812  }
813  else
814  {
816  "Converted NS record for `%s' using glue\n",
817  rec->name);
818  }
819  break;
820  }
821 
824  dst_len,
825  &off,
826  rec->data.hostname))
827  {
829  "Converting CNAME (`%s') record for `%s'\n",
830  rec->data.hostname,
831  rec->name);
832  add_record (req, rec->type, expiration_time, dst, off);
833  }
834  break;
835 
837  /* No support for DNAME in GNS yet! FIXME: support later! */
839  "FIXME: not supported: %s DNAME %s\n",
840  rec->name,
841  rec->data.hostname);
842  break;
843 
845  if (GNUNET_OK ==
846  GNUNET_DNSPARSER_builder_add_mx (dst, dst_len, &off, rec->data.mx))
847  {
849  "Converting MX (`%s') record for `%s'\n",
850  rec->data.mx->mxhost,
851  rec->name);
852  add_record (req, rec->type, expiration_time, dst, off);
853  }
854  break;
855 
857  if (GNUNET_OK ==
858  GNUNET_DNSPARSER_builder_add_soa (dst, dst_len, &off, rec->data.soa))
859  {
860  /* NOTE: GNS does not really use SOAs */
862  "Converting SOA record for `%s'\n",
863  rec->name);
864  add_record (req, rec->type, expiration_time, dst, off);
865  }
866  break;
867 
869  if (GNUNET_OK ==
870  GNUNET_DNSPARSER_builder_add_srv (dst, dst_len, &off, rec->data.srv))
871  {
873  "Converting SRV record for `%s'\n",
874  rec->name);
875  add_record (req, rec->type, expiration_time, dst, off);
876  }
877  break;
878 
881  dst_len,
882  &off,
883  rec->data.hostname))
884  {
885  /* !?: what does a PTR record do in a regular TLD??? */
887  "Converting PTR record for `%s' (weird)\n",
888  rec->name);
889  add_record (req, rec->type, expiration_time, dst, off);
890  }
891  break;
892 
894  if (GNUNET_OK ==
895  GNUNET_DNSPARSER_builder_add_cert (dst, dst_len, &off, rec->data.cert))
896  {
898  "Converting CERT record for `%s'\n",
899  rec->name);
900  add_record (req, rec->type, expiration_time, dst, off);
901  }
902  break;
903 
904  /* Rest is 'raw' encoded and just needs to be copied IF
905  the hostname matches the requested name; otherwise we
906  simply cannot use it. */
910  default:
912  "Converting record of type %u for `%s'\n",
913  (unsigned int) rec->type,
914  rec->name);
915  add_record (req,
916  rec->type,
917  expiration_time,
918  rec->data.raw.data,
919  rec->data.raw.data_len);
920  break;
921  }
922 }
923 
924 
925 static void
927 {
928  static struct GNUNET_TIME_Absolute last;
929  struct Request *req = cls;
930 
931  req->qe = NULL;
932  if (GNUNET_EC_NONE != ec)
933  {
935  "Failed to store zone data for `%s': %s\n",
936  req->hostname,
938  }
939  else
940  {
942  "Stored records under `%s' (%d)\n",
943  req->hostname,
944  ec);
945  }
946  total_reg_proc_dns_ns++; /* finished regular processing */
947  pending_rs--;
948  free_records (req);
949  /* compute NAMESTORE statistics */
950  {
951  static uint64_t total_ns_latency_cnt;
952  static struct GNUNET_TIME_Relative total_ns_latency;
953  struct GNUNET_TIME_Relative ns_latency;
954 
956  total_ns_latency = GNUNET_TIME_relative_add (total_ns_latency, ns_latency);
957  if (0 == total_ns_latency_cnt)
958  last = GNUNET_TIME_absolute_get ();
959  total_ns_latency_cnt++;
960  if (0 == (total_ns_latency_cnt % 1000))
961  {
963 
965  last = GNUNET_TIME_absolute_get ();
966  fprintf (stderr,
967  "Processed 1000 records in %s\n",
970  "# average NAMESTORE PUT latency (μs)",
971  total_ns_latency.rel_value_us
972  / total_ns_latency_cnt,
973  GNUNET_NO);
974  }
975  }
976  /* compute and publish overall velocity */
977  if (0 == (total_reg_proc_dns_ns % 100))
978  {
979  struct GNUNET_TIME_Relative runtime;
980 
982  runtime = GNUNET_TIME_relative_subtract (runtime, idle_time);
983  runtime =
987  "# Regular processing completed without NAMESTORE",
989  GNUNET_NO);
991  "# Regular processing completed with NAMESTORE PUT",
993  GNUNET_NO);
995  "# average request processing latency (μs)",
996  runtime.rel_value_us,
997  GNUNET_NO);
999  "# total time spent idle (μs)",
1001  GNUNET_NO);
1002  }
1003 
1004  if (NULL == t)
1005  {
1008  }
1009 }
1010 
1011 
1019 static void
1020 process_result (void *cls,
1021  const struct GNUNET_TUN_DnsHeader *dns,
1022  size_t dns_len)
1023 {
1024  struct Request *req = cls;
1025  struct Record *rec;
1026  struct GNUNET_DNSPARSER_Packet *p;
1027  unsigned int rd_count;
1028 
1029  GNUNET_assert (NULL == req->hn);
1030  if (NULL == dns)
1031  {
1032  /* stub gave up */
1034  pending--;
1035  if (NULL == t)
1036  {
1039  }
1041  "Stub gave up on DNS reply for `%s'\n",
1042  req->hostname);
1043  GNUNET_STATISTICS_update (stats, "# DNS lookups timed out", 1, GNUNET_NO);
1044  if (req->issue_num > MAX_RETRIES)
1045  {
1046  failures++;
1047  free_request (req);
1048  GNUNET_STATISTICS_update (stats, "# requests given up on", 1, GNUNET_NO);
1049  return;
1050  }
1052  req->rs = NULL;
1053  insert_sorted (req);
1054  return;
1055  }
1056  if (req->id != dns->id)
1057  {
1059  "DNS ID did not match request, ignoring reply\n");
1060  GNUNET_STATISTICS_update (stats, "# DNS ID mismatches", 1, GNUNET_NO);
1061  return;
1062  }
1065  req->rs = NULL;
1066  pending--;
1067  p = GNUNET_DNSPARSER_parse ((const char *) dns, dns_len);
1068  if (NULL == p)
1069  {
1071  "Failed to parse DNS reply for `%s'\n",
1072  req->hostname);
1073  GNUNET_STATISTICS_update (stats, "# DNS parser errors", 1, GNUNET_NO);
1074  if (NULL == t)
1075  {
1078  }
1079  if (req->issue_num > MAX_RETRIES)
1080  {
1081  failures++;
1082  free_request (req);
1083  GNUNET_STATISTICS_update (stats, "# requests given up on", 1, GNUNET_NO);
1084  return;
1085  }
1086  insert_sorted (req);
1087  return;
1088  }
1089  /* import new records */
1090  req->issue_num = 0; /* success, reset counter! */
1091  {
1092  struct ProcessRecordContext prc = { .req = req, .p = p };
1093 
1094  for_all_records (p, &process_record, &prc);
1095  }
1097  /* count records found, determine minimum expiration time */
1099  {
1100  struct GNUNET_TIME_Relative dns_latency;
1101 
1102  dns_latency = GNUNET_TIME_absolute_get_duration (req->op_start_time);
1106  if (0 == (total_dns_latency_cnt % 1000))
1107  {
1109  "# average DNS lookup latency (μs)",
1112  GNUNET_NO);
1113  }
1114  }
1115  rd_count = 0;
1116  for (rec = req->rec_head; NULL != rec; rec = rec->next)
1117  {
1118  struct GNUNET_TIME_Absolute at;
1119 
1120  at.abs_value_us = rec->grd.expiration_time;
1121  req->expires = GNUNET_TIME_absolute_min (req->expires, at);
1122  rd_count++;
1123  }
1125  "Obtained %u records for `%s'\n",
1126  rd_count,
1127  req->hostname);
1128  /* Instead of going for SOA, simplified for now to look each
1129  day in case we got an empty response */
1130  if (0 == rd_count)
1131  {
1134  "# empty DNS replies (usually NXDOMAIN)",
1135  1,
1136  GNUNET_NO);
1137  }
1138  else
1139  {
1140  record_sets++;
1141  }
1142  /* convert records to namestore import format */
1143  {
1145  unsigned int off = 0;
1146 
1147  /* convert linked list into array */
1148  for (rec = req->rec_head; NULL != rec; rec = rec->next)
1149  rd[off++] = rec->grd;
1150  pending_rs++;
1153  &req->zone->key,
1154  get_label (req),
1155  rd_count,
1156  rd,
1158  req);
1159  GNUNET_assert (NULL != req->qe);
1160  }
1161  insert_sorted (req);
1162 }
1163 
1164 
1170 static void
1171 process_queue (void *cls)
1172 {
1173  struct Request *req;
1174  unsigned int series;
1175  void *raw;
1176  size_t raw_size;
1177  struct GNUNET_TIME_Relative delay;
1178 
1179  (void) cls;
1182  series = 0;
1183  t = NULL;
1184  while (pending + pending_rs < THRESH)
1185  {
1187  if (NULL == req)
1188  break;
1189  if (NULL != req->qe)
1190  return; /* namestore op still pending */
1191  if (NULL != req->rs)
1192  {
1193  GNUNET_break (0);
1194  return; /* already submitted */
1195  }
1197  break;
1199  req->hn = NULL;
1201  GNUNET_assert (NULL == req->rs);
1203  "Requesting resolution for `%s'\n",
1204  req->hostname);
1205  raw = build_dns_query (req, &raw_size);
1206  if (NULL == raw)
1207  {
1208  GNUNET_break (0);
1209  free_request (req);
1210  continue;
1211  }
1213  req->rs = GNUNET_DNSSTUB_resolve (ctx, raw, raw_size, &process_result, req);
1214  GNUNET_assert (NULL != req->rs);
1215  req->issue_num++;
1216  lookups++;
1217  pending++;
1218  series++;
1219  if (series > MAX_SERIES)
1220  break;
1221  }
1222  if (pending + pending_rs >= THRESH)
1223  {
1225  "Stopped processing queue (%u+%u/%u)]\n",
1226  pending,
1227  pending_rs,
1228  THRESH);
1229  return; /* wait for replies */
1230  }
1232  if (NULL == req)
1233  {
1235  "Stopped processing queue: empty queue\n");
1236  return;
1237  }
1239  {
1241  "Waiting until %s for next record (`%s') to expire\n",
1243  req->hostname);
1244  if (NULL != t)
1248  return;
1249  }
1250  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Throttling\n");
1251  if (NULL != t)
1255 }
1256 
1257 
1267 static int
1268 free_request_it (void *cls, const struct GNUNET_HashCode *key, void *value)
1269 {
1270  struct Request *req = value;
1271 
1272  (void) cls;
1273  (void) key;
1274  free_request (req);
1275  return GNUNET_OK;
1276 }
1277 
1278 
1284 static void
1285 do_shutdown (void *cls)
1286 {
1287  struct Request *req;
1288  struct Zone *zone;
1289 
1290  (void) cls;
1291  if (NULL != id)
1292  {
1294  id = NULL;
1295  }
1296  if (NULL != t)
1297  {
1299  t = NULL;
1300  }
1301  while (NULL != (req = req_head))
1302  {
1304  if (NULL != req->qe)
1305  GNUNET_NAMESTORE_cancel (req->qe);
1306  free_request (req);
1307  }
1308  while (NULL != (req = GNUNET_CONTAINER_heap_remove_root (req_heap)))
1309  {
1310  req->hn = NULL;
1311  if (NULL != req->qe)
1312  GNUNET_NAMESTORE_cancel (req->qe);
1313  free_request (req);
1314  }
1315  if (NULL != zone_it)
1316  {
1318  zone_it = NULL;
1319  }
1320  if (NULL != ns)
1321  {
1323  ns = NULL;
1324  }
1325  if (NULL != ctx)
1326  {
1328  ctx = NULL;
1329  }
1330  if (NULL != req_heap)
1331  {
1333  req_heap = NULL;
1334  }
1335  if (NULL != ns_pending)
1336  {
1339  ns_pending = NULL;
1340  }
1341  while (NULL != (zone = zone_head))
1342  {
1344  GNUNET_free (zone->domain);
1345  GNUNET_free (zone);
1346  }
1347  if (NULL != stats)
1348  {
1350  stats = NULL;
1351  }
1352 }
1353 
1354 
1361 static void
1362 iterate_zones (void *cls);
1363 
1364 
1371 static void
1373 {
1374  struct Zone *zone = cls;
1375 
1377  "Failed to load data from namestore for zone `%s'\n",
1378  zone->domain);
1379  zone_it = NULL;
1381  iterate_zones (NULL);
1382 }
1383 
1384 
1394 static void
1396  const struct GNUNET_IDENTITY_PrivateKey *key,
1397  const char *label,
1398  unsigned int rd_count,
1399  const struct GNUNET_GNSRECORD_Data *rd)
1400 {
1401  struct Zone *zone = cls;
1402  struct Request *req;
1403  struct GNUNET_HashCode hc;
1404  char *fqdn;
1405 
1408  "Obtained NAMESTORE reply, %llu left in round\n",
1409  (unsigned long long) ns_iterator_trigger_next);
1410  if (0 == ns_iterator_trigger_next)
1411  {
1414  "# NAMESTORE records requested from cache",
1416  GNUNET_NO);
1418  }
1419  GNUNET_asprintf (&fqdn, "%s.%s", label, zone->domain);
1420  GNUNET_CRYPTO_hash (fqdn, strlen (fqdn) + 1, &hc);
1421  GNUNET_free (fqdn);
1423  if (NULL == req)
1424  {
1426  "Ignoring record `%s' in zone `%s': not on my list!\n",
1427  label,
1428  zone->domain);
1429  return;
1430  }
1433  GNUNET_break (0 == GNUNET_memcmp (key, &req->zone->key));
1434  GNUNET_break (0 == strcasecmp (label, get_label (req)));
1435  for (unsigned int i = 0; i < rd_count; i++)
1436  {
1437  struct GNUNET_TIME_Absolute at;
1438 
1440  {
1441  struct GNUNET_TIME_Relative rel;
1442 
1445  }
1446  else
1447  {
1449  }
1450  add_record (req, rd->record_type, at, rd->data, rd->data_size);
1451  }
1452  if (0 == rd_count)
1453  {
1455  "Empty record set in namestore for `%s'\n",
1456  req->hostname);
1457  }
1458  else
1459  {
1460  unsigned int pos = 0;
1461 
1462  cached++;
1464  for (struct Record *rec = req->rec_head; NULL != rec; rec = rec->next)
1465  {
1466  struct GNUNET_TIME_Absolute at;
1467 
1468  at.abs_value_us = rec->grd.expiration_time;
1469  req->expires = GNUNET_TIME_absolute_min (req->expires, at);
1470  pos++;
1471  }
1472  if (0 == pos)
1475  "Hot-start with %u existing records for `%s'\n",
1476  pos,
1477  req->hostname);
1478  }
1479  free_records (req);
1480 
1482  "Adding `%s' to worklist to start at %s\n",
1483  req->hostname,
1485  insert_sorted (req);
1486 }
1487 
1488 
1494 static void
1495 queue (const char *hostname)
1496 {
1497  struct Request *req;
1498  const char *dot;
1499  struct Zone *zone;
1500  size_t hlen;
1501  struct GNUNET_HashCode hc;
1502 
1504  {
1506  "Refusing invalid hostname `%s'\n",
1507  hostname);
1508  rejects++;
1509  return;
1510  }
1511  dot = strchr (hostname, (unsigned char) '.');
1512  if (NULL == dot)
1513  {
1515  "Refusing invalid hostname `%s' (lacks '.')\n",
1516  hostname);
1517  rejects++;
1518  return;
1519  }
1520  for (zone = zone_head; NULL != zone; zone = zone->next)
1521  if (0 == strcmp (zone->domain, dot + 1))
1522  break;
1523  if (NULL == zone)
1524  {
1525  rejects++;
1527  "Domain name `%s' not in ego list!\n",
1528  dot + 1);
1529  return;
1530  }
1531 
1532  hlen = strlen (hostname) + 1;
1533  req = GNUNET_malloc (sizeof(struct Request) + hlen);
1534  req->zone = zone;
1535  req->hostname = (char *) &req[1];
1536  GNUNET_memcpy (req->hostname, hostname, hlen);
1538  UINT16_MAX);
1539  GNUNET_CRYPTO_hash (req->hostname, hlen, &hc);
1541  ns_pending,
1542  &hc,
1543  req,
1545  {
1547  "Duplicate hostname `%s' ignored\n",
1548  hostname);
1549  GNUNET_free (req);
1550  return;
1551  }
1552 }
1553 
1554 
1566 static int
1567 move_to_queue (void *cls, const struct GNUNET_HashCode *key, void *value)
1568 {
1569  struct Request *req = value;
1570 
1571  (void) cls;
1572  (void) key;
1573  insert_sorted (req);
1574  return GNUNET_OK;
1575 }
1576 
1577 
1584 static void
1585 iterate_zones (void *cls)
1586 {
1587  static struct Zone *last;
1588 
1589  (void) cls;
1590  if (NULL != zone_it)
1591  {
1592  zone_it = NULL;
1594  "Finished iteration over zone `%s'!\n",
1595  last->domain);
1596  /* subtract left-overs from previous iteration */
1598  "# NAMESTORE records requested from cache",
1599  (long long) (-ns_iterator_trigger_next),
1600  GNUNET_NO);
1602  }
1603  GNUNET_assert (NULL != zone_tail);
1604  if (zone_tail == last)
1605  {
1606  /* Done iterating over relevant zones in NAMESTORE, move
1607  rest of hash map to work queue as well. */
1609  "Finished all NAMESTORE iterations!\n");
1611  "# Domain names without cached reply",
1613  GNUNET_NO);
1616  ns_pending = NULL;
1618  total_reg_proc_dns = 0;
1620  return;
1621  }
1622  if (NULL == last)
1623  last = zone_head;
1624  else
1625  last = last->next;
1627  "Starting iteration over zone `%s'!\n",
1628  last->domain);
1629  /* subtract left-overs from previous iteration */
1631  "# NAMESTORE records requested from cache",
1632  1,
1633  GNUNET_NO);
1635  GNUNET_STATISTICS_update (stats, "# zones iterated", 1, GNUNET_NO);
1637  &last->key,
1639  NULL,
1641  last,
1642  &iterate_zones,
1643  NULL);
1644 }
1645 
1646 
1652 static void
1653 process_stdin (void *cls)
1654 {
1655  static struct GNUNET_TIME_Absolute last;
1656  static uint64_t idot;
1657  char hn[256];
1658 
1659  (void) cls;
1660  t = NULL;
1661  if (NULL != id)
1662  {
1664  id = NULL;
1665  }
1666  while (NULL != fgets (hn, sizeof(hn), stdin))
1667  {
1668  if (strlen (hn) > 0)
1669  hn[strlen (hn) - 1] = '\0'; /* eat newline */
1670  if (0 == idot)
1671  last = GNUNET_TIME_absolute_get ();
1672  idot++;
1673  if (0 == idot % 100000)
1674  {
1675  struct GNUNET_TIME_Relative delta;
1676 
1678  last = GNUNET_TIME_absolute_get ();
1679  fprintf (stderr,
1680  "Read 100000 domain names in %s\n",
1682  GNUNET_STATISTICS_set (stats, "# domain names provided", idot, GNUNET_NO);
1683  }
1684  queue (hn);
1685  }
1686  fprintf (stderr,
1687  "Done reading %llu domain names\n",
1688  (unsigned long long) idot);
1689  GNUNET_STATISTICS_set (stats, "# domain names provided", idot, GNUNET_NO);
1690  iterate_zones (NULL);
1691 }
1692 
1693 
1727 static void
1728 identity_cb (void *cls,
1729  struct GNUNET_IDENTITY_Ego *ego,
1730  void **ctx,
1731  const char *name)
1732 {
1733  (void) cls;
1734  (void) ctx;
1735 
1736  if (NULL == ego)
1737  {
1738  /* end of iteration */
1739  if (NULL == zone_head)
1740  {
1741  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No zone found\n");
1743  return;
1744  }
1745  /* zone_head non-null, process hostnames from stdin */
1747  return;
1748  }
1749  if (NULL != name)
1750  {
1751  struct Zone *zone;
1752 
1753  zone = GNUNET_new (struct Zone);
1755  zone->domain = GNUNET_strdup (name);
1757  }
1758 }
1759 
1760 
1770 static void
1771 run (void *cls,
1772  char *const *args,
1773  const char *cfgfile,
1774  const struct GNUNET_CONFIGURATION_Handle *cfg)
1775 {
1776  (void) cls;
1777  (void) args;
1778  (void) cfgfile;
1779  stats = GNUNET_STATISTICS_create ("zoneimport", cfg);
1782  if (NULL == ns_pending)
1783  {
1784  fprintf (stderr, "Failed to allocate memory for main hash map\n");
1785  return;
1786  }
1787  ctx = GNUNET_DNSSTUB_start (256);
1788  if (NULL == ctx)
1789  {
1790  fprintf (stderr, "Failed to initialize GNUnet DNS STUB\n");
1791  return;
1792  }
1793  if (NULL == args[0])
1794  {
1795  fprintf (stderr,
1796  "You must provide a list of DNS resolvers on the command line\n");
1797  return;
1798  }
1799  for (unsigned int i = 0; NULL != args[i]; i++)
1800  {
1802  {
1803  fprintf (stderr, "Failed to use `%s' for DNS resolver\n", args[i]);
1804  return;
1805  }
1806  }
1807 
1808 
1811  if (NULL == ns)
1812  {
1814  return;
1815  }
1816  id = GNUNET_IDENTITY_connect (cfg, &identity_cb, NULL);
1817 }
1818 
1819 
1827 int
1828 main (int argc, char *const *argv)
1829 {
1832  "size",
1833  "MAPSIZE",
1834  gettext_noop (
1835  "size to use for the main hash map"),
1836  &map_size),
1838  'm',
1839  "minimum-expiration",
1840  "RELATIVETIME",
1841  gettext_noop ("minimum expiration time we assume for imported records"),
1844  int ret;
1845 
1846  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1847  return 2;
1848  if (GNUNET_OK != (ret = GNUNET_PROGRAM_run (argc,
1849  argv,
1850  "gnunet-zoneimport",
1851  "import DNS zone into namestore",
1852  options,
1853  &run,
1854  NULL)))
1855  return ret;
1856  GNUNET_free_nz ((void *) argv);
1857  fprintf (stderr,
1858  "Rejected %u names, had %u cached, did %u lookups, stored %u record sets\n"
1859  "Found %u records, %u lookups failed, %u/%u pending on shutdown\n",
1860  rejects,
1861  cached,
1862  lookups,
1863  record_sets,
1864  records,
1865  failures,
1866  pending,
1867  pending_rs);
1868  return 0;
1869 }
1870 
1871 
1872 /* 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 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).
#define gettext_noop(String)
Definition: gettext.h:70
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
struct GNUNET_HashCode key
The key used in the DHT.
static int raw
raw output
Definition: gnunet-gns.c:78
uint32_t data
The data value.
static char * zone
Name of the zone being managed.
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 char * rp
Relying party.
static struct GNUNET_REVOCATION_Query * q
Handle for revocation query.
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
static char * hostname
Our hostname; we give this to all the peers we start.
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 const char * get_label(struct Request *req)
Return just the label of the hostname in req.
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 ns_lookup_result_cb(void *cls, const struct GNUNET_IDENTITY_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 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 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 * build_dns_query(struct Request *req, size_t *raw_size)
Build DNS query for hostname.
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 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?
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.
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:889
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:1032
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition: dnsparser.c:854
#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
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:656
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:1079
#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:1003
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:1120
#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:1259
#define GNUNET_DNSPARSER_TYPE_MX
#define GNUNET_DNSPARSER_TYPE_TXT
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_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Definition: dnsstub.c:586
void GNUNET_DNSSTUB_resolve_cancel(struct GNUNET_DNSSTUB_RequestSocket *rs)
Cancel DNS resolution.
Definition: dnsstub.c:562
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
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
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.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash 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.
enum GNUNET_GenericReturnValue 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.
@ 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_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.
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of 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_IDENTITY_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:560
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:531
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:757
#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.
void GNUNET_NAMESTORE_disconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from the namestore service (and free associated resources).
struct GNUNET_NAMESTORE_ZoneIterator * GNUNET_NAMESTORE_zone_iteration_start(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_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)
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_QueueEntry * GNUNET_NAMESTORE_records_store(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_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.
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:562
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:1299
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:1334
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:1249
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
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:1272
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:1222
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
#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
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:616
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_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:569
#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...
const char * name
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:36
Handle to a node in a heap.
Internal representation of the hash map.
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?
union GNUNET_DNSPARSER_Record::@24 data
Payload of the record (which one of these is valid depends on the 'type').
char * name
Name of the record that the query is for (0-terminated).
struct GNUNET_DNSPARSER_RawRecord raw
Raw data for all other types.
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
A private key for an identity as per LSD0001.
Connection to the NAMESTORE service.
An QueueEntry used to store information for a pending NAMESTORE record operation.
Definition: namestore_api.c:53
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.
struct Request * next
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.
int issue_num
How often did we issue this query?
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 GNS operation.
uint16_t id
random 16-bit DNS query identifier.
struct Request * prev
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_IDENTITY_PrivateKey key
Private key of the zone.
struct Zone * next
Kept in a DLL.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model