GNUnet  0.11.x
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_dnsstub_lib.h>
28 #include <gnunet_dnsparser_lib.h>
29 #include <gnunet_gnsrecord_lib.h>
33 
34 
38 #define THRESH 100
39 
44 #define TIME_THRESH 10
45 
49 #define MAX_RETRIES 5
50 
54 #define MAX_SERIES 10
55 
59 #define SERIES_DELAY \
60  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS, 10)
61 
66 
71 #define NS_BATCH_SIZE 1024
72 
79 struct Zone
80 {
84  struct Zone *next;
85 
89  struct Zone *prev;
90 
94  char *domain;
95 
100 };
101 
102 
106 struct Record
107 {
111  struct Record *next;
112 
116  struct Record *prev;
117 
121  struct GNUNET_GNSRECORD_Data grd;
122 };
123 
124 
130 struct Request
131 {
136 
140  struct Request *next;
141 
145  struct Request *prev;
146 
151  struct Record *rec_head;
152 
157  struct Record *rec_tail;
158 
163 
169  char *hostname;
170 
175 
179  const struct Zone *zone;
180 
187 
195 
200  unsigned int issue_num;
201 
205  uint16_t id;
206 };
207 
208 
215 static unsigned int map_size = 1024;
216 
220 static struct GNUNET_IDENTITY_Handle *id;
221 
226 
231 
236 
240 static unsigned int pending;
241 
245 static unsigned int pending_rs;
246 
250 static unsigned int lookups;
251 
255 static unsigned int cached;
256 
260 static unsigned int rejects;
261 
265 static unsigned int failures;
266 
270 static unsigned int records;
271 
275 static unsigned int record_sets;
276 
282 
286 static struct Request *req_head;
287 
291 static struct Request *req_tail;
292 
296 static struct GNUNET_SCHEDULER_Task *t;
297 
304 
309 
313 static struct Zone *zone_head;
314 
318 static struct Zone *zone_tail;
319 
324 static uint64_t ns_iterator_trigger_next;
325 
329 static uint64_t total_dns_latency_cnt;
330 
335 
339 static uint64_t total_reg_proc_dns;
340 
344 static uint64_t total_reg_proc_dns_ns;
345 
350 
355 
359 static struct GNUNET_TIME_Relative idle_time;
360 
361 
368 typedef void (*RecordProcessor) (void *cls,
369  const struct GNUNET_DNSPARSER_Record *rec);
370 
371 
380 static void
383  void *rp_cls)
384 {
385  for (unsigned int i = 0; i < p->num_answers; i++)
386  {
387  struct GNUNET_DNSPARSER_Record *rs = &p->answers[i];
388 
389  rp (rp_cls, rs);
390  }
391  for (unsigned int i = 0; i < p->num_authority_records; i++)
392  {
393  struct GNUNET_DNSPARSER_Record *rs = &p->authority_records[i];
394 
395  rp (rp_cls, rs);
396  }
397  for (unsigned int i = 0; i < p->num_additional_records; i++)
398  {
399  struct GNUNET_DNSPARSER_Record *rs = &p->additional_records[i];
400 
401  rp (rp_cls, rs);
402  }
403 }
404 
405 
413 static const char *
414 get_label (struct Request *req)
415 {
416  static char label[64];
417  const char *dot;
418 
419  dot = strchr (req->hostname, (unsigned char) '.');
420  if (NULL == dot)
421  {
422  GNUNET_break (0);
423  return NULL;
424  }
425  if (((size_t) (dot - req->hostname)) >= sizeof(label))
426  {
427  GNUNET_break (0);
428  return NULL;
429  }
430  GNUNET_memcpy (label, req->hostname, dot - req->hostname);
431  label[dot - req->hostname] = '\0';
432  return label;
433 }
434 
435 
444 static void *
445 build_dns_query (struct Request *req, size_t *raw_size)
446 {
447  static char raw[512];
448  char *rawp;
449  struct GNUNET_DNSPARSER_Packet p;
450  struct GNUNET_DNSPARSER_Query q;
451  int ret;
452 
453  q.name = (char *) req->hostname;
455  q.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
456 
457  memset (&p, 0, sizeof(p));
458  p.num_queries = 1;
459  p.queries = &q;
460  p.id = req->id;
461  ret = GNUNET_DNSPARSER_pack (&p, UINT16_MAX, &rawp, raw_size);
462  if (GNUNET_OK != ret)
463  {
464  if (GNUNET_NO == ret)
465  GNUNET_free (rawp);
467  "Failed to pack query for hostname `%s'\n",
468  req->hostname);
469  rejects++;
470  return NULL;
471  }
472  if (*raw_size > sizeof(raw))
473  {
475  "Failed to pack query for hostname `%s'\n",
476  req->hostname);
477  rejects++;
478  GNUNET_break (0);
479  GNUNET_free (rawp);
480  return NULL;
481  }
482  GNUNET_memcpy (raw, rawp, *raw_size);
483  GNUNET_free (rawp);
484  return raw;
485 }
486 
487 
493 static void
494 free_records (struct Request *req)
495 {
496  struct Record *rec;
497 
498  /* Free records */
499  while (NULL != (rec = req->rec_head))
500  {
502  GNUNET_free (rec);
503  }
504 }
505 
506 
512 static void
513 free_request (struct Request *req)
514 {
515  free_records (req);
516  GNUNET_free (req);
517 }
518 
519 
525 static void
526 process_queue (void *cls);
527 
528 
534 static void
535 insert_sorted (struct Request *req)
536 {
537  req->hn =
540  {
541  if (NULL != t)
545  }
546 }
547 
548 
558 static void
559 add_record (struct Request *req,
560  uint32_t type,
561  struct GNUNET_TIME_Absolute expiration_time,
562  const void *data,
563  size_t data_len)
564 {
565  struct Record *rec;
566 
567  rec = GNUNET_malloc (sizeof(struct Record) + data_len);
568  rec->grd.data = &rec[1];
569  rec->grd.expiration_time = expiration_time.abs_value_us;
570  rec->grd.data_size = data_len;
571  rec->grd.record_type = type;
573  GNUNET_memcpy (&rec[1], data, data_len);
575 }
576 
577 
582 {
586  struct Request *req;
587 
591  const char *ns;
592 
596  int found;
597 };
598 
599 
606 static void
607 check_for_glue (void *cls, const struct GNUNET_DNSPARSER_Record *rec)
608 {
609  struct GlueClosure *gc = cls;
610  char dst[65536];
611  size_t dst_len;
612  size_t off;
613  char ip[INET6_ADDRSTRLEN + 1];
614  socklen_t ip_size = (socklen_t) sizeof(ip);
615  struct GNUNET_TIME_Absolute expiration_time;
616  struct GNUNET_TIME_Relative left;
617 
618  if (0 != strcasecmp (rec->name, gc->ns))
619  return;
620  expiration_time = rec->expiration_time;
621  left = GNUNET_TIME_absolute_get_remaining (expiration_time);
622  if (0 == left.rel_value_us)
623  return; /* ignore expired glue records */
624  /* if expiration window is too short, bump it to configured minimum */
626  expiration_time =
628  dst_len = sizeof(dst);
629  off = 0;
630  switch (rec->type)
631  {
633  if (sizeof(struct in_addr) != rec->data.raw.data_len)
634  {
635  GNUNET_break (0);
636  return;
637  }
638  if (NULL == inet_ntop (AF_INET, rec->data.raw.data, ip, ip_size))
639  {
640  GNUNET_break (0);
641  return;
642  }
644  dst_len,
645  &off,
646  gc->req->hostname)) &&
647  (GNUNET_OK ==
648  GNUNET_DNSPARSER_builder_add_name (dst, dst_len, &off, ip)))
649  {
650  add_record (gc->req,
652  expiration_time,
653  dst,
654  off);
655  gc->found = GNUNET_YES;
656  }
657  break;
658 
660  if (sizeof(struct in6_addr) != rec->data.raw.data_len)
661  {
662  GNUNET_break (0);
663  return;
664  }
665  if (NULL == inet_ntop (AF_INET6, rec->data.raw.data, ip, ip_size))
666  {
667  GNUNET_break (0);
668  return;
669  }
671  dst_len,
672  &off,
673  gc->req->hostname)) &&
674  (GNUNET_OK ==
675  GNUNET_DNSPARSER_builder_add_name (dst, dst_len, &off, ip)))
676  {
677  add_record (gc->req,
679  expiration_time,
680  dst,
681  off);
682  gc->found = GNUNET_YES;
683  }
684  break;
685 
688  dst_len,
689  &off,
690  gc->req->hostname)) &&
692  dst_len,
693  &off,
694  rec->data.hostname)))
695  {
696  add_record (gc->req,
698  expiration_time,
699  dst,
700  off);
701  gc->found = GNUNET_YES;
702  }
703  break;
704 
705  default:
706  /* useless, do nothing */
707  break;
708  }
709 }
710 
711 
716 {
722 
726  struct Request *req;
727 };
728 
729 
736 static void
737 process_record (void *cls, const struct GNUNET_DNSPARSER_Record *rec)
738 {
739  struct ProcessRecordContext *prc = cls;
740  struct Request *req = prc->req;
741  char dst[65536];
742  size_t dst_len;
743  size_t off;
744  struct GNUNET_TIME_Absolute expiration_time;
745  struct GNUNET_TIME_Relative left;
746 
747  dst_len = sizeof(dst);
748  off = 0;
749  records++;
750  if (0 != strcasecmp (rec->name, req->hostname))
751  {
752  GNUNET_log (
754  "DNS returned record from zone `%s' of type %u while resolving `%s'\n",
755  rec->name,
756  (unsigned int) rec->type,
757  req->hostname);
758  return; /* does not match hostname, might be glue, but
759  not useful for this pass! */
760  }
761  expiration_time = rec->expiration_time;
762  left = GNUNET_TIME_absolute_get_remaining (expiration_time);
763  if (0 == left.rel_value_us)
764  {
766  "DNS returned expired record for `%s'\n",
767  req->hostname);
769  "# expired records obtained from DNS",
770  1,
771  GNUNET_NO);
772  return; /* record expired */
773  }
774 
776  "DNS returned record that expires at %s for `%s'\n",
777  GNUNET_STRINGS_absolute_time_to_string (expiration_time),
778  req->hostname);
779  /* if expiration window is too short, bump it to configured minimum */
781  expiration_time =
783  switch (rec->type)
784  {
786  struct GlueClosure gc;
787 
788  /* check for glue */
789  gc.req = req;
790  gc.ns = rec->data.hostname;
791  gc.found = GNUNET_NO;
792  for_all_records (prc->p, &check_for_glue, &gc);
793  if ((GNUNET_NO == gc.found) &&
795  dst_len,
796  &off,
797  req->hostname)) &&
799  dst_len,
800  &off,
801  rec->data.hostname)))
802  {
803  /* FIXME: actually check if this is out-of-bailiwick,
804  and if not request explicit resolution... */
806  "Converted OOB (`%s') NS record for `%s'\n",
807  rec->data.hostname,
808  rec->name);
809  add_record (req,
811  expiration_time,
812  dst,
813  off);
814  }
815  else
816  {
818  "Converted NS record for `%s' using glue\n",
819  rec->name);
820  }
821  break;
822  }
823 
826  dst_len,
827  &off,
828  rec->data.hostname))
829  {
831  "Converting CNAME (`%s') record for `%s'\n",
832  rec->data.hostname,
833  rec->name);
834  add_record (req, rec->type, expiration_time, dst, off);
835  }
836  break;
837 
839  /* No support for DNAME in GNS yet! FIXME: support later! */
841  "FIXME: not supported: %s DNAME %s\n",
842  rec->name,
843  rec->data.hostname);
844  break;
845 
847  if (GNUNET_OK ==
848  GNUNET_DNSPARSER_builder_add_mx (dst, dst_len, &off, rec->data.mx))
849  {
851  "Converting MX (`%s') record for `%s'\n",
852  rec->data.mx->mxhost,
853  rec->name);
854  add_record (req, rec->type, expiration_time, dst, off);
855  }
856  break;
857 
859  if (GNUNET_OK ==
860  GNUNET_DNSPARSER_builder_add_soa (dst, dst_len, &off, rec->data.soa))
861  {
862  /* NOTE: GNS does not really use SOAs */
864  "Converting SOA record for `%s'\n",
865  rec->name);
866  add_record (req, rec->type, expiration_time, dst, off);
867  }
868  break;
869 
871  if (GNUNET_OK ==
872  GNUNET_DNSPARSER_builder_add_srv (dst, dst_len, &off, rec->data.srv))
873  {
875  "Converting SRV record for `%s'\n",
876  rec->name);
877  add_record (req, rec->type, expiration_time, dst, off);
878  }
879  break;
880 
883  dst_len,
884  &off,
885  rec->data.hostname))
886  {
887  /* !?: what does a PTR record do in a regular TLD??? */
889  "Converting PTR record for `%s' (weird)\n",
890  rec->name);
891  add_record (req, rec->type, expiration_time, dst, off);
892  }
893  break;
894 
896  if (GNUNET_OK ==
897  GNUNET_DNSPARSER_builder_add_cert (dst, dst_len, &off, rec->data.cert))
898  {
900  "Converting CERT record for `%s'\n",
901  rec->name);
902  add_record (req, rec->type, expiration_time, dst, off);
903  }
904  break;
905 
906  /* Rest is 'raw' encoded and just needs to be copied IF
907  the hostname matches the requested name; otherwise we
908  simply cannot use it. */
912  default:
914  "Converting record of type %u for `%s'\n",
915  (unsigned int) rec->type,
916  rec->name);
917  add_record (req,
918  rec->type,
919  expiration_time,
920  rec->data.raw.data,
921  rec->data.raw.data_len);
922  break;
923  }
924 }
925 
926 
937 static void
938 store_completed_cb (void *cls, int32_t success, const char *emsg)
939 {
940  static struct GNUNET_TIME_Absolute last;
941  struct Request *req = cls;
942 
943  req->qe = NULL;
944  if (GNUNET_SYSERR == success)
945  {
947  "Failed to store zone data for `%s': %s\n",
948  req->hostname,
949  emsg);
950  }
951  else
952  {
954  "Stored records under `%s' (%d)\n",
955  req->hostname,
956  success);
957  }
958  total_reg_proc_dns_ns++; /* finished regular processing */
959  pending_rs--;
960  free_records (req);
961  /* compute NAMESTORE statistics */
962  {
963  static uint64_t total_ns_latency_cnt;
964  static struct GNUNET_TIME_Relative total_ns_latency;
965  struct GNUNET_TIME_Relative ns_latency;
966 
968  total_ns_latency = GNUNET_TIME_relative_add (total_ns_latency, ns_latency);
969  if (0 == total_ns_latency_cnt)
970  last = GNUNET_TIME_absolute_get ();
971  total_ns_latency_cnt++;
972  if (0 == (total_ns_latency_cnt % 1000))
973  {
975 
977  last = GNUNET_TIME_absolute_get ();
978  fprintf (stderr,
979  "Processed 1000 records in %s\n",
982  "# average NAMESTORE PUT latency (μs)",
983  total_ns_latency.rel_value_us
984  / total_ns_latency_cnt,
985  GNUNET_NO);
986  }
987  }
988  /* compute and publish overall velocity */
989  if (0 == (total_reg_proc_dns_ns % 100))
990  {
991  struct GNUNET_TIME_Relative runtime;
992 
994  runtime = GNUNET_TIME_relative_subtract (runtime, idle_time);
995  runtime =
999  "# Regular processing completed without NAMESTORE",
1001  GNUNET_NO);
1003  "# Regular processing completed with NAMESTORE PUT",
1005  GNUNET_NO);
1007  "# average request processing latency (μs)",
1008  runtime.rel_value_us,
1009  GNUNET_NO);
1011  "# total time spent idle (μs)",
1013  GNUNET_NO);
1014  }
1015 
1016  if (NULL == t)
1017  {
1020  }
1021 }
1022 
1023 
1031 static void
1032 process_result (void *cls,
1033  const struct GNUNET_TUN_DnsHeader *dns,
1034  size_t dns_len)
1035 {
1036  struct Request *req = cls;
1037  struct Record *rec;
1038  struct GNUNET_DNSPARSER_Packet *p;
1039  unsigned int rd_count;
1040 
1041  GNUNET_assert (NULL == req->hn);
1042  if (NULL == dns)
1043  {
1044  /* stub gave up */
1046  pending--;
1047  if (NULL == t)
1048  {
1051  }
1053  "Stub gave up on DNS reply for `%s'\n",
1054  req->hostname);
1055  GNUNET_STATISTICS_update (stats, "# DNS lookups timed out", 1, GNUNET_NO);
1056  if (req->issue_num > MAX_RETRIES)
1057  {
1058  failures++;
1059  free_request (req);
1060  GNUNET_STATISTICS_update (stats, "# requests given up on", 1, GNUNET_NO);
1061  return;
1062  }
1064  req->rs = NULL;
1065  insert_sorted (req);
1066  return;
1067  }
1068  if (req->id != dns->id)
1069  {
1071  "DNS ID did not match request, ignoring reply\n");
1072  GNUNET_STATISTICS_update (stats, "# DNS ID mismatches", 1, GNUNET_NO);
1073  return;
1074  }
1077  req->rs = NULL;
1078  pending--;
1079  p = GNUNET_DNSPARSER_parse ((const char *) dns, dns_len);
1080  if (NULL == p)
1081  {
1083  "Failed to parse DNS reply for `%s'\n",
1084  req->hostname);
1085  GNUNET_STATISTICS_update (stats, "# DNS parser errors", 1, GNUNET_NO);
1086  if (NULL == t)
1087  {
1090  }
1091  if (req->issue_num > MAX_RETRIES)
1092  {
1093  failures++;
1094  free_request (req);
1095  GNUNET_STATISTICS_update (stats, "# requests given up on", 1, GNUNET_NO);
1096  return;
1097  }
1098  insert_sorted (req);
1099  return;
1100  }
1101  /* import new records */
1102  req->issue_num = 0; /* success, reset counter! */
1103  {
1104  struct ProcessRecordContext prc = { .req = req, .p = p };
1105 
1106  for_all_records (p, &process_record, &prc);
1107  }
1109  /* count records found, determine minimum expiration time */
1111  {
1112  struct GNUNET_TIME_Relative dns_latency;
1113 
1114  dns_latency = GNUNET_TIME_absolute_get_duration (req->op_start_time);
1118  if (0 == (total_dns_latency_cnt % 1000))
1119  {
1121  "# average DNS lookup latency (μs)",
1124  GNUNET_NO);
1125  }
1126  }
1127  rd_count = 0;
1128  for (rec = req->rec_head; NULL != rec; rec = rec->next)
1129  {
1130  struct GNUNET_TIME_Absolute at;
1131 
1132  at.abs_value_us = rec->grd.expiration_time;
1133  req->expires = GNUNET_TIME_absolute_min (req->expires, at);
1134  rd_count++;
1135  }
1137  "Obtained %u records for `%s'\n",
1138  rd_count,
1139  req->hostname);
1140  /* Instead of going for SOA, simplified for now to look each
1141  day in case we got an empty response */
1142  if (0 == rd_count)
1143  {
1146  "# empty DNS replies (usually NXDOMAIN)",
1147  1,
1148  GNUNET_NO);
1149  }
1150  else
1151  {
1152  record_sets++;
1153  }
1154  /* convert records to namestore import format */
1155  {
1156  struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
1157  unsigned int off = 0;
1158 
1159  /* convert linked list into array */
1160  for (rec = req->rec_head; NULL != rec; rec = rec->next)
1161  rd[off++] = rec->grd;
1162  pending_rs++;
1165  &req->zone->key,
1166  get_label (req),
1167  rd_count,
1168  rd,
1170  req);
1171  GNUNET_assert (NULL != req->qe);
1172  }
1173  insert_sorted (req);
1174 }
1175 
1176 
1182 static void
1183 process_queue (void *cls)
1184 {
1185  struct Request *req;
1186  unsigned int series;
1187  void *raw;
1188  size_t raw_size;
1189  struct GNUNET_TIME_Relative delay;
1190 
1191  (void) cls;
1194  series = 0;
1195  t = NULL;
1196  while (pending + pending_rs < THRESH)
1197  {
1199  if (NULL == req)
1200  break;
1201  if (NULL != req->qe)
1202  return; /* namestore op still pending */
1203  if (NULL != req->rs)
1204  {
1205  GNUNET_break (0);
1206  return; /* already submitted */
1207  }
1209  break;
1211  req->hn = NULL;
1213  GNUNET_assert (NULL == req->rs);
1215  "Requesting resolution for `%s'\n",
1216  req->hostname);
1217  raw = build_dns_query (req, &raw_size);
1218  if (NULL == raw)
1219  {
1220  GNUNET_break (0);
1221  free_request (req);
1222  continue;
1223  }
1225  req->rs = GNUNET_DNSSTUB_resolve (ctx, raw, raw_size, &process_result, req);
1226  GNUNET_assert (NULL != req->rs);
1227  req->issue_num++;
1228  lookups++;
1229  pending++;
1230  series++;
1231  if (series > MAX_SERIES)
1232  break;
1233  }
1234  if (pending + pending_rs >= THRESH)
1235  {
1237  "Stopped processing queue (%u+%u/%u)]\n",
1238  pending,
1239  pending_rs,
1240  THRESH);
1241  return; /* wait for replies */
1242  }
1244  if (NULL == req)
1245  {
1247  "Stopped processing queue: empty queue\n");
1248  return;
1249  }
1251  {
1253  "Waiting until %s for next record (`%s') to expire\n",
1255  req->hostname);
1256  if (NULL != t)
1260  return;
1261  }
1262  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Throttling\n");
1263  if (NULL != t)
1267 }
1268 
1269 
1279 static int
1280 free_request_it (void *cls, const struct GNUNET_HashCode *key, void *value)
1281 {
1282  struct Request *req = value;
1283 
1284  (void) cls;
1285  (void) key;
1286  free_request (req);
1287  return GNUNET_OK;
1288 }
1289 
1290 
1296 static void
1297 do_shutdown (void *cls)
1298 {
1299  struct Request *req;
1300  struct Zone *zone;
1301 
1302  (void) cls;
1303  if (NULL != id)
1304  {
1306  id = NULL;
1307  }
1308  if (NULL != t)
1309  {
1311  t = NULL;
1312  }
1313  while (NULL != (req = req_head))
1314  {
1316  if (NULL != req->qe)
1317  GNUNET_NAMESTORE_cancel (req->qe);
1318  free_request (req);
1319  }
1320  while (NULL != (req = GNUNET_CONTAINER_heap_remove_root (req_heap)))
1321  {
1322  req->hn = NULL;
1323  if (NULL != req->qe)
1324  GNUNET_NAMESTORE_cancel (req->qe);
1325  free_request (req);
1326  }
1327  if (NULL != zone_it)
1328  {
1330  zone_it = NULL;
1331  }
1332  if (NULL != ns)
1333  {
1335  ns = NULL;
1336  }
1337  if (NULL != ctx)
1338  {
1340  ctx = NULL;
1341  }
1342  if (NULL != req_heap)
1343  {
1345  req_heap = NULL;
1346  }
1347  if (NULL != ns_pending)
1348  {
1351  ns_pending = NULL;
1352  }
1353  while (NULL != (zone = zone_head))
1354  {
1356  GNUNET_free (zone->domain);
1357  GNUNET_free (zone);
1358  }
1359  if (NULL != stats)
1360  {
1362  stats = NULL;
1363  }
1364 }
1365 
1366 
1373 static void
1374 iterate_zones (void *cls);
1375 
1376 
1383 static void
1385 {
1386  struct Zone *zone = cls;
1387 
1389  "Failed to load data from namestore for zone `%s'\n",
1390  zone->domain);
1391  zone_it = NULL;
1393  iterate_zones (NULL);
1394 }
1395 
1396 
1406 static void
1408  const struct GNUNET_IDENTITY_PrivateKey *key,
1409  const char *label,
1410  unsigned int rd_count,
1411  const struct GNUNET_GNSRECORD_Data *rd)
1412 {
1413  struct Zone *zone = cls;
1414  struct Request *req;
1415  struct GNUNET_HashCode hc;
1416  char *fqdn;
1417 
1420  "Obtained NAMESTORE reply, %llu left in round\n",
1421  (unsigned long long) ns_iterator_trigger_next);
1422  if (0 == ns_iterator_trigger_next)
1423  {
1426  "# NAMESTORE records requested from cache",
1428  GNUNET_NO);
1430  }
1431  GNUNET_asprintf (&fqdn, "%s.%s", label, zone->domain);
1432  GNUNET_CRYPTO_hash (fqdn, strlen (fqdn) + 1, &hc);
1433  GNUNET_free (fqdn);
1435  if (NULL == req)
1436  {
1438  "Ignoring record `%s' in zone `%s': not on my list!\n",
1439  label,
1440  zone->domain);
1441  return;
1442  }
1445  GNUNET_break (0 == GNUNET_memcmp (key, &req->zone->key));
1446  GNUNET_break (0 == strcasecmp (label, get_label (req)));
1447  for (unsigned int i = 0; i < rd_count; i++)
1448  {
1449  struct GNUNET_TIME_Absolute at;
1450 
1452  {
1453  struct GNUNET_TIME_Relative rel;
1454 
1455  rel.rel_value_us = rd->expiration_time;
1457  }
1458  else
1459  {
1460  at.abs_value_us = rd->expiration_time;
1461  }
1462  add_record (req, rd->record_type, at, rd->data, rd->data_size);
1463  }
1464  if (0 == rd_count)
1465  {
1467  "Empty record set in namestore for `%s'\n",
1468  req->hostname);
1469  }
1470  else
1471  {
1472  unsigned int pos = 0;
1473 
1474  cached++;
1476  for (struct Record *rec = req->rec_head; NULL != rec; rec = rec->next)
1477  {
1478  struct GNUNET_TIME_Absolute at;
1479 
1480  at.abs_value_us = rec->grd.expiration_time;
1481  req->expires = GNUNET_TIME_absolute_min (req->expires, at);
1482  pos++;
1483  }
1484  if (0 == pos)
1487  "Hot-start with %u existing records for `%s'\n",
1488  pos,
1489  req->hostname);
1490  }
1491  free_records (req);
1492 
1494  "Adding `%s' to worklist to start at %s\n",
1495  req->hostname,
1497  insert_sorted (req);
1498 }
1499 
1500 
1506 static void
1507 queue (const char *hostname)
1508 {
1509  struct Request *req;
1510  const char *dot;
1511  struct Zone *zone;
1512  size_t hlen;
1513  struct GNUNET_HashCode hc;
1514 
1516  {
1518  "Refusing invalid hostname `%s'\n",
1519  hostname);
1520  rejects++;
1521  return;
1522  }
1523  dot = strchr (hostname, (unsigned char) '.');
1524  if (NULL == dot)
1525  {
1527  "Refusing invalid hostname `%s' (lacks '.')\n",
1528  hostname);
1529  rejects++;
1530  return;
1531  }
1532  for (zone = zone_head; NULL != zone; zone = zone->next)
1533  if (0 == strcmp (zone->domain, dot + 1))
1534  break;
1535  if (NULL == zone)
1536  {
1537  rejects++;
1539  "Domain name `%s' not in ego list!\n",
1540  dot + 1);
1541  return;
1542  }
1543 
1544  hlen = strlen (hostname) + 1;
1545  req = GNUNET_malloc (sizeof(struct Request) + hlen);
1546  req->zone = zone;
1547  req->hostname = (char *) &req[1];
1548  GNUNET_memcpy (req->hostname, hostname, hlen);
1550  UINT16_MAX);
1551  GNUNET_CRYPTO_hash (req->hostname, hlen, &hc);
1553  ns_pending,
1554  &hc,
1555  req,
1557  {
1559  "Duplicate hostname `%s' ignored\n",
1560  hostname);
1561  GNUNET_free (req);
1562  return;
1563  }
1564 }
1565 
1566 
1578 static int
1579 move_to_queue (void *cls, const struct GNUNET_HashCode *key, void *value)
1580 {
1581  struct Request *req = value;
1582 
1583  (void) cls;
1584  (void) key;
1585  insert_sorted (req);
1586  return GNUNET_OK;
1587 }
1588 
1589 
1596 static void
1597 iterate_zones (void *cls)
1598 {
1599  static struct Zone *last;
1600 
1601  (void) cls;
1602  if (NULL != zone_it)
1603  {
1604  zone_it = NULL;
1606  "Finished iteration over zone `%s'!\n",
1607  last->domain);
1608  /* subtract left-overs from previous iteration */
1610  "# NAMESTORE records requested from cache",
1611  (long long) (-ns_iterator_trigger_next),
1612  GNUNET_NO);
1614  }
1615  GNUNET_assert (NULL != zone_tail);
1616  if (zone_tail == last)
1617  {
1618  /* Done iterating over relevant zones in NAMESTORE, move
1619  rest of hash map to work queue as well. */
1621  "Finished all NAMESTORE iterations!\n");
1623  "# Domain names without cached reply",
1625  GNUNET_NO);
1628  ns_pending = NULL;
1630  total_reg_proc_dns = 0;
1632  return;
1633  }
1634  if (NULL == last)
1635  last = zone_head;
1636  else
1637  last = last->next;
1639  "Starting iteration over zone `%s'!\n",
1640  last->domain);
1641  /* subtract left-overs from previous iteration */
1643  "# NAMESTORE records requested from cache",
1644  1,
1645  GNUNET_NO);
1647  GNUNET_STATISTICS_update (stats, "# zones iterated", 1, GNUNET_NO);
1649  &last->key,
1651  NULL,
1653  last,
1654  &iterate_zones,
1655  NULL);
1656 }
1657 
1658 
1664 static void
1665 process_stdin (void *cls)
1666 {
1667  static struct GNUNET_TIME_Absolute last;
1668  static uint64_t idot;
1669  char hn[256];
1670 
1671  (void) cls;
1672  t = NULL;
1673  if (NULL != id)
1674  {
1676  id = NULL;
1677  }
1678  while (NULL != fgets (hn, sizeof(hn), stdin))
1679  {
1680  if (strlen (hn) > 0)
1681  hn[strlen (hn) - 1] = '\0'; /* eat newline */
1682  if (0 == idot)
1683  last = GNUNET_TIME_absolute_get ();
1684  idot++;
1685  if (0 == idot % 100000)
1686  {
1687  struct GNUNET_TIME_Relative delta;
1688 
1690  last = GNUNET_TIME_absolute_get ();
1691  fprintf (stderr,
1692  "Read 100000 domain names in %s\n",
1694  GNUNET_STATISTICS_set (stats, "# domain names provided", idot, GNUNET_NO);
1695  }
1696  queue (hn);
1697  }
1698  fprintf (stderr,
1699  "Done reading %llu domain names\n",
1700  (unsigned long long) idot);
1701  GNUNET_STATISTICS_set (stats, "# domain names provided", idot, GNUNET_NO);
1702  iterate_zones (NULL);
1703 }
1704 
1705 
1739 static void
1740 identity_cb (void *cls,
1741  struct GNUNET_IDENTITY_Ego *ego,
1742  void **ctx,
1743  const char *name)
1744 {
1745  (void) cls;
1746  (void) ctx;
1747 
1748  if (NULL == ego)
1749  {
1750  /* end of iteration */
1751  if (NULL == zone_head)
1752  {
1753  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No zone found\n");
1755  return;
1756  }
1757  /* zone_head non-null, process hostnames from stdin */
1759  return;
1760  }
1761  if (NULL != name)
1762  {
1763  struct Zone *zone;
1764 
1765  zone = GNUNET_new (struct Zone);
1767  zone->domain = GNUNET_strdup (name);
1769  }
1770 }
1771 
1772 
1782 static void
1783 run (void *cls,
1784  char *const *args,
1785  const char *cfgfile,
1786  const struct GNUNET_CONFIGURATION_Handle *cfg)
1787 {
1788  (void) cls;
1789  (void) args;
1790  (void) cfgfile;
1791  stats = GNUNET_STATISTICS_create ("zoneimport", cfg);
1794  if (NULL == ns_pending)
1795  {
1796  fprintf (stderr, "Failed to allocate memory for main hash map\n");
1797  return;
1798  }
1799  ctx = GNUNET_DNSSTUB_start (256);
1800  if (NULL == ctx)
1801  {
1802  fprintf (stderr, "Failed to initialize GNUnet DNS STUB\n");
1803  return;
1804  }
1805  if (NULL == args[0])
1806  {
1807  fprintf (stderr,
1808  "You must provide a list of DNS resolvers on the command line\n");
1809  return;
1810  }
1811  for (unsigned int i = 0; NULL != args[i]; i++)
1812  {
1814  {
1815  fprintf (stderr, "Failed to use `%s' for DNS resolver\n", args[i]);
1816  return;
1817  }
1818  }
1819 
1820 
1823  if (NULL == ns)
1824  {
1826  return;
1827  }
1828  id = GNUNET_IDENTITY_connect (cfg, &identity_cb, NULL);
1829 }
1830 
1831 
1839 int
1840 main (int argc, char *const *argv)
1841 {
1844  "size",
1845  "MAPSIZE",
1846  gettext_noop (
1847  "size to use for the main hash map"),
1848  &map_size),
1850  'm',
1851  "minimum-expiration",
1852  "RELATIVETIME",
1853  gettext_noop ("minimum expiration time we assume for imported records"),
1856  int ret;
1857 
1858  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1859  return 2;
1860  if (GNUNET_OK != (ret = GNUNET_PROGRAM_run (argc,
1861  argv,
1862  "gnunet-zoneimport",
1863  "import DNS zone into namestore",
1864  options,
1865  &run,
1866  NULL)))
1867  return ret;
1868  GNUNET_free_nz ((void *) argv);
1869  fprintf (stderr,
1870  "Rejected %u names, had %u cached, did %u lookups, stored %u record sets\n"
1871  "Found %u records, %u lookups failed, %u/%u pending on shutdown\n",
1872  rejects,
1873  cached,
1874  lookups,
1875  record_sets,
1876  records,
1877  failures,
1878  pending,
1879  pending_rs);
1880  return 0;
1881 }
1882 
1883 
1884 /* 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:69
#define GNUNET_GNSRECORD_TYPE_GNS2DNS
Delegation to DNS.
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:79
uint32_t data
The data value.
static char * zone
Name of the zone being managed.
static char * value
Value of the record to add/remove.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
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 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 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 void store_completed_cb(void *cls, int32_t success, const char *emsg)
Continuation called to notify client about result of the operation.
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?
#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
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
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:1030
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:1077
#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:1001
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:1118
#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:1257
#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:591
void GNUNET_DNSSTUB_stop(struct GNUNET_DNSSTUB_Context *ctx)
Cleanup DNSSTUB resolver.
Definition: dnsstub.c:690
struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Definition: dnsstub.c:564
void GNUNET_DNSSTUB_resolve_cancel(struct GNUNET_DNSSTUB_RequestSocket *rs)
Cancel DNS resolution.
Definition: dnsstub.c:540
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:504
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
No special options.
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_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
int 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.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash 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:639
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:610
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:921
#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)
Starts a new zone iteration (used to periodically PUT all of our records into our DHT).
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:364
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:531
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:1296
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:1331
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:1246
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
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:1269
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:1209
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:263
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:232
#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:429
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:86
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:604
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:411
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:181
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:216
#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:376
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:557
#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:35
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:124
UDP socket we are using for sending DNS requests to the Internet.
Definition: dnsstub.c:45
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:96
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:54
Handle for a zone iterator operation.
Entry in list of pending tasks.
Definition: scheduler.c:135
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