GNUnet  0.19.2
gnunet-namestore.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2012, 2013, 2014, 2019 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  */
28 #include "platform.h"
29 #include <gnunet_util_lib.h>
31 #include <gnunet_gnsrecord_lib.h>
32 #include <gnunet_gns_service.h>
34 #include <inttypes.h>
35 
40 #define WARN_RELATIVE_EXPIRATION_LIMIT GNUNET_TIME_relative_multiply ( \
41  GNUNET_TIME_UNIT_MINUTES, 15)
42 
47 {
52 
57 };
58 
63 {
67  struct MarkedRecord *next;
68 
72  struct MarkedRecord *prev;
73 
77  char *name;
78 
83 };
84 
88 struct EgoEntry
89 {
93  struct EgoEntry *next;
94 
98  struct EgoEntry *prev;
99 
103  char *identifier;
104 
108  struct GNUNET_IDENTITY_Ego *ego;
109 };
110 
115 
120 
125 
129 static char *ego_name;
130 
135 
140 
145 
150 
154 static struct MarkedRecord *marked_head;
155 
159 static struct MarkedRecord *marked_tail;
160 
165 
169 static struct EgoEntry *ego_head;
170 
174 static struct EgoEntry *ego_tail;
175 
180 
184 static int read_from_stdin;
185 
189 static int list;
190 
194 static int add;
195 
199 static int del;
200 
204 static int is_public;
205 
209 static int is_shadow;
210 
214 static int omit_private;
215 
219 static int output_recordline;
220 
221 
225 static int purge_zone;
226 
231 
235 static int purge_orphaned;
236 
240 static int list_orphaned;
241 
246 
251 
256 
260 static char *name;
261 
265 static char *value;
266 
270 static char *uri;
271 
275 static char *reverse_pkey;
276 
280 static char *typestring;
281 
285 static char *expirationstring;
286 
290 static char *nickstring;
291 
295 static int ret;
296 
300 static uint32_t type;
301 
305 static void *data;
306 
310 static size_t data_size;
311 
315 static uint64_t etime;
316 
321 
326 
330 static int monitor;
331 
335 static struct RecordSetEntry *recordset;
336 
341 
350 static int
352  int *etime_is_rel,
353  uint64_t *etime)
354 {
355  struct GNUNET_TIME_Relative etime_rel;
356  struct GNUNET_TIME_Absolute etime_abs;
357 
358  if (0 == strcmp (expirationstring, "never"))
359  {
360  *etime = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
362  return GNUNET_OK;
363  }
364  if (GNUNET_OK ==
366  {
368  *etime = etime_rel.rel_value_us;
370  {
372  "Relative expiration times of less than %s are not recommended. To improve availability, consider increasing this value.\n",
375  }
377  "Storing record with relative expiration time of %s\n",
379  return GNUNET_OK;
380  }
381  if (GNUNET_OK ==
383  {
385  *etime = etime_abs.abs_value_us;
387  "Storing record with absolute expiration time of %s\n",
389  return GNUNET_OK;
390  }
391  return GNUNET_SYSERR;
392 }
393 
394 
395 static int
396 parse_recordline (const char *line)
397 {
398  struct RecordSetEntry **head = &recordset;
399  struct RecordSetEntry *r;
401  char *cp;
402  char *tok;
403  char *saveptr;
404  void *raw_data;
405 
406  cp = GNUNET_strdup (line);
407  tok = strtok_r (cp, " ", &saveptr);
408  if (NULL == tok)
409  {
411  _ ("Missing entries in record line `%s'.\n"),
412  line);
413  GNUNET_free (cp);
414  return GNUNET_SYSERR;
415  }
416  record.record_type = GNUNET_GNSRECORD_typename_to_number (tok);
417  if (UINT32_MAX == record.record_type)
418  {
419  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Unknown record type `%s'\n"), tok);
420  GNUNET_free (cp);
421  return GNUNET_SYSERR;
422  }
423  tok = strtok_r (NULL, " ", &saveptr);
424  if (NULL == tok)
425  {
427  _ ("Empty record line argument is not allowed.\n"));
428  GNUNET_free (cp);
429  return GNUNET_SYSERR;
430  }
431  if (1 != sscanf (tok, "%" SCNu64, &record.expiration_time))
432  {
433  fprintf (stderr,
434  _ ("Error parsing expiration time %s.\n"), tok);
435  GNUNET_free (cp);
436  return GNUNET_SYSERR;
437  }
438  tok = strtok_r (NULL, " ", &saveptr);
439  if (NULL == tok)
440  {
442  _ ("Empty record line argument is not allowed.\n"));
443  GNUNET_free (cp);
444  return GNUNET_SYSERR;
445  }
447  if (NULL != strchr (tok, (unsigned char) 'r'))
449  if (NULL == strchr (tok, (unsigned char) 'p')) /* p = public */
451  if (NULL != strchr (tok, (unsigned char) 'S'))
453  if (NULL != strchr (tok, (unsigned char) 's'))
455  if (NULL != strchr (tok, (unsigned char) 'C'))
457  tok += strlen (tok) + 1;
459  tok,
460  &raw_data,
461  &record.data_size))
462  {
464  _ ("Invalid record data for type %s: `%s'.\n"),
466  tok);
467  return GNUNET_SYSERR;
468  }
469 
470  r = GNUNET_malloc (sizeof(struct RecordSetEntry) + record.data_size);
471  r->next = *head;
472  record.data = &r[1];
473  memcpy (&r[1], raw_data, record.data_size);
474  GNUNET_free (raw_data);
475  r->record = record;
476  *head = r;
477  return GNUNET_OK;
478 }
479 
480 static void
482 {
483  struct MarkedRecord *mrec;
484  struct MarkedRecord *mrec_tmp;
485  struct RecordSetEntry *rs_entry;
486 
487  rs_entry = recordset;
488  while (NULL != (rs_entry = recordset))
489  {
491  GNUNET_free (rs_entry);
492  }
493  recordset = NULL;
494  if (NULL != ego_name)
495  {
497  ego_name = NULL;
498  }
499  if (NULL != name)
500  {
501  GNUNET_free (name);
502  name = NULL;
503  }
504  if (NULL != value)
505  {
506  GNUNET_free (value);
507  value = NULL;
508  }
509  if (NULL != uri)
510  {
511  GNUNET_free (uri);
512  uri = NULL;
513  }
514  if (NULL != expirationstring)
515  {
517  expirationstring = NULL;
518  }
519  if (NULL != purge_task)
520  {
522  purge_task = NULL;
523  }
524  for (mrec = marked_head; NULL != mrec;)
525  {
526  mrec_tmp = mrec;
527  mrec = mrec->next;
528  GNUNET_free (mrec_tmp->name);
529  GNUNET_free (mrec_tmp);
530  }
531  if (NULL != list_it)
532  {
534  list_it = NULL;
535  }
536  if (NULL != add_qe)
537  {
539  add_qe = NULL;
540  }
541  if (NULL != set_qe)
542  {
544  set_qe = NULL;
545  }
546  if (NULL != add_qe_uri)
547  {
549  add_qe_uri = NULL;
550  }
551  if (NULL != get_qe)
552  {
554  get_qe = NULL;
555  }
556  if (NULL != del_qe)
557  {
559  del_qe = NULL;
560  }
561  if (NULL != reverse_qe)
562  {
564  reverse_qe = NULL;
565  }
566  memset (&zone_pkey, 0, sizeof(zone_pkey));
567  if (NULL != zm)
568  {
570  zm = NULL;
571  }
572  if (NULL != data)
573  {
574  GNUNET_free (data);
575  data = NULL;
576  }
577  if (NULL != typestring)
578  {
580  typestring = NULL;
581  }
582  list = 0;
583  is_public = 0;
584  is_shadow = 0;
585  purge_zone = 0;
586 }
587 
588 
589 
595 static void
596 do_shutdown (void *cls)
597 {
598  struct EgoEntry *ego_entry;
599  struct EgoEntry *ego_tmp;
600  (void) cls;
601 
602  reset_handles ();
603  if (NULL != ns_qe)
604  {
606  ns_qe = NULL;
607  }
608  if (NULL != ns)
609  {
611  ns = NULL;
612  }
613  if (NULL != idh)
614  {
616  idh = NULL;
617  }
618  for (ego_entry = ego_head; NULL != ego_entry;)
619  {
620  ego_tmp = ego_entry;
621  ego_entry = ego_entry->next;
622  GNUNET_free (ego_tmp->identifier);
623  GNUNET_free (ego_tmp);
624  }
625 }
626 
627 static void
628 commit_cb (void *cls, enum GNUNET_ErrorCode ec)
629 {
630  ns_qe = NULL;
631  if (GNUNET_EC_NONE != ec)
632  {
633  fprintf (stderr, "Failed to commit to namestore: `%s'\n",
635  ret = 1;
636  }
638 }
639 
640 static void
642 
643 
644 static void
646 {
647  reset_handles ();
648  if (read_from_stdin)
649  {
651  return;
652  }
654 }
655 
656 
657 static void
658 add_continuation (void *cls, enum GNUNET_ErrorCode ec)
659 {
660  struct GNUNET_NAMESTORE_QueueEntry **qe = cls;
661 
662  *qe = NULL;
663  if (GNUNET_EC_NONE != ec)
664  {
665  fprintf (stderr,
666  _ ("Adding record failed: %s\n"),
669  ret = 1;
670  }
671  ret = 0;
672  finish_command ();
673 }
674 
675 
676 static void
677 del_continuation (void *cls, enum GNUNET_ErrorCode ec)
678 {
679  (void) cls;
680  del_qe = NULL;
682  {
683  fprintf (stderr,
684  _ ("Deleting record failed: %s\n"), GNUNET_ErrorCode_get_hint (
685  ec));
686  }
687  finish_command ();
688 }
689 
690 static void
691 purge_next_record (void *cls);
692 
693 static void
694 marked_deleted (void *cls, enum GNUNET_ErrorCode ec)
695 {
696  del_qe = NULL;
697  if (GNUNET_EC_NONE != ec)
698  {
699  fprintf (stderr,
700  _ ("Deleting record failed: %s\n"),
702  }
704 }
705 
706 
707 static void
708 purge_next_record (void *cls)
709 {
710  struct MarkedRecord *mrec;
711  purge_task = NULL;
712 
713  if (NULL == marked_head)
714  {
715  ret = 0;
716  finish_command ();
717  return;
718  }
719  mrec = marked_head;
721  marked_tail,
722  mrec);
724  &mrec->key,
725  mrec->name,
726  0, NULL,
728  NULL);
729  GNUNET_free (mrec->name);
730  GNUNET_free (mrec);
731 }
732 
736 static void
738 {
739  (void) cls;
740  list_it = NULL;
741  if (purge_orphaned || purge_zone)
742  {
744  return;
745  }
746  ret = 0;
747  finish_command ();
748 }
749 
750 
754 static void
756 {
757  (void) cls;
758  list_it = NULL;
759  fprintf (stderr, "Error iterating over zone\n");
760  ret = 1;
761  finish_command ();
762 }
763 
764 static void
767  const char *rname,
768  unsigned int rd_len,
769  const struct GNUNET_GNSRECORD_Data *rd)
770 {
771  struct MarkedRecord *mrec;
772 
773  mrec = GNUNET_new (struct MarkedRecord);
774  mrec->key = *zone_key;
775  mrec->name = GNUNET_strdup (rname);
777  marked_tail,
778  mrec);
779 }
780 
781 
782 static void
784  const char *rname,
785  unsigned int rd_len,
786  const struct GNUNET_GNSRECORD_Data *rd)
787 {
788  struct EgoEntry *ego;
789  struct MarkedRecord *orphan;
790  int is_orphaned = 1;
791 
792  for (ego = ego_head; NULL != ego; ego = ego->next)
793  {
794  if (0 == memcmp (GNUNET_IDENTITY_ego_get_private_key (ego->ego),
795  zone_key,
796  sizeof (*zone_key)))
797  {
798  is_orphaned = 0;
799  break;
800  }
801  }
802  if (is_orphaned)
803  {
804  orphan = GNUNET_new (struct MarkedRecord);
805  orphan->key = *zone_key;
806  orphan->name = GNUNET_strdup (rname);
808  marked_tail,
809  orphan);
810  }
811 }
812 
820 static void
822  const char *rname,
823  unsigned int rd_len,
824  const struct GNUNET_GNSRECORD_Data *rd)
825 {
826  const char *typestr;
827  char *s;
828  const char *ets;
829  struct GNUNET_TIME_Absolute at;
830  struct GNUNET_TIME_Relative rt;
831  struct EgoEntry *ego;
832  int have_record;
833  int is_orphaned = 1;
834  char *orphaned_str;
835 
836  if ((NULL != name) && (0 != strcmp (name, rname)))
837  return;
838  have_record = GNUNET_NO;
839  for (unsigned int i = 0; i < rd_len; i++)
840  {
841  if ((GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) &&
842  (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT)))
843  continue;
844  if ((type != rd[i].record_type) && (GNUNET_GNSRECORD_TYPE_ANY != type))
845  continue;
846  have_record = GNUNET_YES;
847  break;
848  }
849  if (GNUNET_NO == have_record)
850  return;
851  for (ego = ego_head; NULL != ego; ego = ego->next)
852  {
853  if (0 == memcmp (GNUNET_IDENTITY_ego_get_private_key (ego->ego),
854  zone_key,
855  sizeof (*zone_key)))
856  {
857  is_orphaned = 0;
858  break;
859  }
860  }
861  if (list_orphaned && ! is_orphaned)
862  return;
863  if (! list_orphaned && is_orphaned)
864  return;
866  fprintf (stdout, "%s.%s:\n", rname, is_orphaned ? orphaned_str :
867  ego->identifier);
868  GNUNET_free (orphaned_str);
869  if (NULL != typestring)
871  else
873  for (unsigned int i = 0; i < rd_len; i++)
874  {
875  if ((GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) &&
876  (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT)))
877  continue;
878  if ((type != rd[i].record_type) && (GNUNET_GNSRECORD_TYPE_ANY != type))
879  continue;
880  typestr = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type);
881  s = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
882  rd[i].data,
883  rd[i].data_size);
884  if (NULL == s)
885  {
886  fprintf (stdout,
887  _ ("\tCorrupt or unsupported record of type %u\n"),
888  (unsigned int) rd[i].record_type);
889  continue;
890  }
891  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
892  {
895  }
896  else
897  {
900  }
901  char flgstr[16];
902  sprintf (flgstr, "[%s%s%s%s%s]",
903  (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE) ? "" : "p",
904  (rd[i].flags & GNUNET_GNSRECORD_RF_SUPPLEMENTAL) ? "S" : "",
905  (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION) ? "r" : "",
906  (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW) ? "S" : "",
907  (rd[i].flags & GNUNET_GNSRECORD_RF_CRITICAL) ? "C" : "");
908  if (output_recordline)
909  fprintf (stdout,
910  " %s %" PRIu64 " %s %s\n",
911  typestr,
912  rd[i].expiration_time,
913  flgstr,
914  s);
915  else
916  fprintf (stdout,
917  "\t%s: %s (%s)\t%s\t%s\n",
918  typestr,
919  s,
920  ets,
921  (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) ? "PRIVATE"
922  : "PUBLIC",
923  (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW)) ? "SHADOW"
924  : "");
925  GNUNET_free (s);
926  }
927  // fprintf (stdout, "%s", "\n");
928 }
929 
930 static void
932  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
933  const char *rname,
934  unsigned int rd_len,
935  const struct GNUNET_GNSRECORD_Data *rd,
936  struct GNUNET_TIME_Absolute expiry)
937 {
938  (void) cls;
939  (void) zone_key;
940  (void) expiry;
941  collect_zone_records_to_purge (zone_key, rname, rd_len, rd);
943 }
944 
945 
946 static void
948  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
949  const char *rname,
950  unsigned int rd_len,
951  const struct GNUNET_GNSRECORD_Data *rd,
952  struct GNUNET_TIME_Absolute expiry)
953 {
954  (void) cls;
955  (void) zone_key;
956  (void) expiry;
957  collect_orphans (zone_key, rname, rd_len, rd);
959 }
960 
961 
971 static void
973  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
974  const char *rname,
975  unsigned int rd_len,
976  const struct GNUNET_GNSRECORD_Data *rd,
977  struct GNUNET_TIME_Absolute expiry)
978 {
979  (void) cls;
980  (void) zone_key;
981  (void) expiry;
982  display_record (zone_key, rname, rd_len, rd);
984 }
985 
986 
996 static void
998  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
999  const char *rname,
1000  unsigned int rd_len,
1001  const struct GNUNET_GNSRECORD_Data *rd,
1002  struct GNUNET_TIME_Absolute expiry)
1003 {
1004  (void) cls;
1005  (void) zone_key;
1006  (void) expiry;
1007  display_record (zone_key, rname, rd_len, rd);
1009 }
1010 
1011 
1021 static void
1023  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
1024  const char *rname,
1025  unsigned int rd_len,
1026  const struct GNUNET_GNSRECORD_Data *rd)
1027 {
1028  (void) cls;
1029  (void) zone_key;
1030  get_qe = NULL;
1031  display_record (zone_key, rname, rd_len, rd);
1032  finish_command ();
1033 }
1034 
1035 
1041 static void
1042 sync_cb (void *cls)
1043 {
1044  (void) cls;
1045  fprintf (stdout, "%s", "Monitor is now in sync.\n");
1046 }
1047 
1048 
1054 static void
1055 monitor_error_cb (void *cls)
1056 {
1057  (void) cls;
1058  fprintf (stderr, "%s", "Monitor disconnected and out of sync.\n");
1059 }
1060 
1061 
1067 static void
1068 lookup_error_cb (void *cls)
1069 {
1070  (void) cls;
1071  get_qe = NULL;
1072  fprintf (stderr, "%s", "Failed to lookup record.\n");
1073  finish_command ();
1074 }
1075 
1076 
1080 static void
1081 add_error_cb (void *cls)
1082 {
1083  (void) cls;
1084  add_qe = NULL;
1085  GNUNET_break (0);
1086  ret = 1;
1087  finish_command ();
1088 }
1089 
1090 
1101 static void
1103  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
1104  const char *rec_name,
1105  unsigned int rd_count,
1106  const struct GNUNET_GNSRECORD_Data *rd)
1107 {
1108  struct GNUNET_GNSRECORD_Data rdn[rd_count + 1];
1109  struct GNUNET_GNSRECORD_Data *rde;
1110 
1111  (void) cls;
1112  (void) zone_key;
1113  add_qe = NULL;
1114  if (0 != strcmp (rec_name, name))
1115  {
1116  GNUNET_break (0);
1117  ret = 1;
1118  finish_command ();
1119  return;
1120  }
1121 
1123  "Received %u records for name `%s'\n",
1124  rd_count,
1125  rec_name);
1126  for (unsigned int i = 0; i < rd_count; i++)
1127  {
1128  switch (rd[i].record_type)
1129  {
1132  {
1133  fprintf (
1134  stderr,
1135  _ (
1136  "A SOA record exists already under `%s', cannot add a second SOA to the same zone.\n"),
1137  rec_name);
1138  ret = 1;
1139  finish_command ();
1140  return;
1141  }
1142  break;
1143  }
1144  }
1145  memset (rdn, 0, sizeof(struct GNUNET_GNSRECORD_Data));
1146  GNUNET_memcpy (&rdn[1], rd, rd_count * sizeof(struct GNUNET_GNSRECORD_Data));
1147  rde = &rdn[0];
1148  rde->data = data;
1149  rde->data_size = data_size;
1150  rde->record_type = type;
1151  if (1 == is_shadow)
1153  if (1 != is_public)
1155  rde->expiration_time = etime;
1156  if (GNUNET_YES == etime_is_rel)
1158  else if (GNUNET_NO != etime_is_rel)
1159  rde->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
1160  GNUNET_assert (NULL != name);
1162  &zone_pkey,
1163  name,
1164  rd_count + 1,
1165  rde,
1167  &add_qe);
1168 }
1169 
1170 
1174 static void
1175 reverse_error_cb (void *cls)
1176 {
1177  (void) cls;
1178  reverse_qe = NULL;
1179  fprintf (stdout, "%s.zkey\n", reverse_pkey);
1180 }
1181 
1182 
1193 static void
1195  const struct GNUNET_IDENTITY_PrivateKey *zone,
1196  const char *label,
1197  unsigned int rd_count,
1198  const struct GNUNET_GNSRECORD_Data *rd)
1199 {
1200  (void) cls;
1201  (void) zone;
1202  (void) rd_count;
1203  (void) rd;
1204  reverse_qe = NULL;
1205  if (NULL == label)
1206  fprintf (stdout, "%s\n", reverse_pkey);
1207  else
1208  fprintf (stdout, "%s.%s\n", label, ego_name);
1209  finish_command ();
1210 }
1211 
1212 
1216 static void
1218 {
1219  (void) cls;
1220  del_qe = NULL;
1221  GNUNET_break (0);
1222  ret = 1;
1223  finish_command ();
1224 }
1225 
1226 
1238 static void
1239 del_monitor (void *cls,
1240  const struct GNUNET_IDENTITY_PrivateKey *zone,
1241  const char *label,
1242  unsigned int rd_count,
1243  const struct GNUNET_GNSRECORD_Data *rd)
1244 {
1245  struct GNUNET_GNSRECORD_Data rdx[rd_count];
1246  unsigned int rd_left;
1247  uint32_t type;
1248  char *vs;
1249 
1250  (void) cls;
1251  (void) zone;
1252  del_qe = NULL;
1253  if (0 == rd_count)
1254  {
1255  fprintf (stderr,
1256  _ (
1257  "There are no records under label `%s' that could be deleted.\n"),
1258  label);
1259  ret = 1;
1260  finish_command ();
1261  return;
1262  }
1263  if ((NULL == value) && (NULL == typestring))
1264  {
1265  /* delete everything */
1267  &zone_pkey,
1268  name,
1269  0,
1270  NULL,
1272  NULL);
1273  return;
1274  }
1275  rd_left = 0;
1276  if (NULL != typestring)
1278  else
1280  for (unsigned int i = 0; i < rd_count; i++)
1281  {
1282  vs = NULL;
1283  if (! (((GNUNET_GNSRECORD_TYPE_ANY == type) ||
1284  (rd[i].record_type == type)) &&
1285  ((NULL == value) ||
1286  (NULL ==
1288  rd[i].data,
1289  rd[i].data_size)))) ||
1290  (0 == strcmp (vs, value)))))
1291  rdx[rd_left++] = rd[i];
1292  GNUNET_free (vs);
1293  }
1294  if (rd_count == rd_left)
1295  {
1296  /* nothing got deleted */
1297  fprintf (
1298  stderr,
1299  _ (
1300  "There are no records under label `%s' that match the request for deletion.\n"),
1301  label);
1302  finish_command ();
1303  return;
1304  }
1305  /* delete everything but what we copied to 'rdx' */
1307  &zone_pkey,
1308  name,
1309  rd_left,
1310  rdx,
1312  NULL);
1313 }
1314 
1315 
1316 static void
1317 replace_cont (void *cls, enum GNUNET_ErrorCode ec)
1318 {
1319  (void) cls;
1320 
1321  set_qe = NULL;
1322  if (GNUNET_EC_NONE != ec)
1323  {
1325  _ ("%s\n"),
1327  ret = 1; /* fail from 'main' */
1328  }
1329  finish_command ();
1330 }
1331 
1332 
1339 static void
1341 {
1342  struct GNUNET_GNSRECORD_Data rd;
1344 
1345  if (omit_private)
1346  filter_flags |= GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE;
1347  if (include_maintenance)
1349  if (! (add | del | list | (NULL != nickstring) | (NULL != uri)
1350  | (NULL != reverse_pkey) | (NULL != recordset) | (monitor)
1351  | (purge_orphaned) | (list_orphaned) | (purge_zone)) )
1352  {
1353  /* nothing more to be done */
1354  fprintf (stderr, _ ("No options given\n"));
1355  finish_command ();
1356  return;
1357  }
1358 
1359  if (NULL != recordset)
1360  {
1361  /* replace entire record set */
1362  unsigned int rd_count;
1363  struct GNUNET_GNSRECORD_Data *rd;
1364 
1365  /* FIXME: We could easily support append and delete with this as well */
1366  if (! add)
1367  {
1368  fprintf (stderr, _ ("Recordlines only work with option `%s'\n"),
1369  "-a");
1370  ret = 1;
1371  finish_command ();
1372  return;
1373  }
1374  if (NULL == name)
1375  {
1376  fprintf (stderr,
1377  _ ("Missing option `%s' for operation `%s'\n"),
1378  "-n",
1379  _ ("name"));
1380  ret = 1;
1381  finish_command ();
1382  return;
1383  }
1384  rd_count = 0;
1385  for (struct RecordSetEntry *e = recordset; NULL != e; e = e->next)
1386  rd_count++;
1388  rd_count = 0;
1389  for (struct RecordSetEntry *e = recordset; NULL != e; e = e->next)
1390  {
1391  rd[rd_count] = e->record;
1392  rd_count++;
1393  }
1395  &zone_pkey,
1396  name,
1397  rd_count,
1398  rd,
1399  &replace_cont,
1400  NULL);
1401  GNUNET_free (rd);
1402  return;
1403  }
1404  if (NULL != nickstring)
1405  {
1406  if (0 == strlen (nickstring))
1407  {
1408  fprintf (stderr, _ ("Invalid nick `%s'\n"), nickstring);
1409  ret = 1;
1410  finish_command ();
1411  return;
1412  }
1413  add = 1;
1418  is_public = 0;
1419  expirationstring = GNUNET_strdup ("never");
1421  nickstring = NULL;
1422  }
1423 
1424  if (add)
1425  {
1426  if (NULL == ego_name)
1427  {
1428  fprintf (stderr,
1429  _ ("Missing option `%s' for operation `%s'\n"),
1430  "-z",
1431  _ ("add"));
1432  ret = 1;
1433  finish_command ();
1434  return;
1435  }
1436  if (NULL == name)
1437  {
1438  fprintf (stderr,
1439  _ ("Missing option `%s' for operation `%s'\n"),
1440  "-n",
1441  _ ("add"));
1442  ret = 1;
1443  finish_command ();
1444  return;
1445  }
1446  if (NULL == typestring)
1447  {
1448  fprintf (stderr,
1449  _ ("Missing option `%s' for operation `%s'\n"),
1450  "-t",
1451  _ ("add"));
1452  ret = 1;
1453  finish_command ();
1454  return;
1455  }
1457  if (UINT32_MAX == type)
1458  {
1459  fprintf (stderr, _ ("Unsupported type `%s'\n"), typestring);
1460  ret = 1;
1461  finish_command ();
1462  return;
1463  }
1464  if ((GNUNET_DNSPARSER_TYPE_SRV == type) ||
1467  {
1468  fprintf (stderr,
1469  _ ("For DNS record types `SRV', `TLSA' and `OPENPGPKEY'"));
1470  fprintf (stderr, ", please use a `BOX' record instead\n");
1471  ret = 1;
1472  finish_command ();
1473  return;
1474  }
1475  if (NULL == value)
1476  {
1477  fprintf (stderr,
1478  _ ("Missing option `%s' for operation `%s'\n"),
1479  "-V",
1480  _ ("add"));
1481  ret = 1;
1482  finish_command ();
1483  return;
1484  }
1485  if (GNUNET_OK !=
1487  {
1488  fprintf (stderr,
1489  _ ("Value `%s' invalid for record type `%s'\n"),
1490  value,
1491  typestring);
1492  ret = 1;
1493  finish_command ();
1494  return;
1495  }
1496  if (NULL == expirationstring)
1497  {
1498  fprintf (stderr,
1499  _ ("Missing option `%s' for operation `%s'\n"),
1500  "-e",
1501  _ ("add"));
1502  ret = 1;
1503  finish_command ();
1504  return;
1505  }
1507  {
1508  fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring);
1509  ret = 1;
1510  finish_command ();
1511  return;
1512  }
1514  &zone_pkey,
1515  name,
1516  &add_error_cb,
1517  NULL,
1519  NULL);
1520  }
1521  if (del)
1522  {
1523  if (NULL == ego_name)
1524  {
1525  fprintf (stderr,
1526  _ ("Missing option `%s' for operation `%s'\n"),
1527  "-z",
1528  _ ("del"));
1529  ret = 1;
1530  finish_command ();
1531  return;
1532  }
1533  if (NULL == name)
1534  {
1535  fprintf (stderr,
1536  _ ("Missing option `%s' for operation `%s'\n"),
1537  "-n",
1538  _ ("del"));
1539  ret = 1;
1540  finish_command ();
1541  return;
1542  }
1544  &zone_pkey,
1545  name,
1547  NULL,
1548  &del_monitor,
1549  NULL);
1550  }
1551  if (purge_orphaned)
1552  {
1554  NULL,
1556  NULL,
1558  NULL,
1560  NULL,
1561  filter_flags);
1562 
1563  }
1564  else if (purge_zone)
1565  {
1566  if (NULL == ego_name)
1567  {
1568  fprintf (stderr,
1569  _ ("Missing option `%s' for operation `%s'\n"),
1570  "-z",
1571  _ ("purge-zone"));
1572  ret = 1;
1573  finish_command ();
1574  return;
1575  }
1577  &zone_pkey,
1579  NULL,
1581  NULL,
1583  NULL,
1584  filter_flags);
1585 
1586  }
1587  else if (list || list_orphaned)
1588  {
1589  if (NULL != name)
1590  {
1591  if (NULL == ego_name)
1592  {
1593  fprintf (stderr,
1594  _ ("Missing option `%s' for operation `%s'\n"),
1595  "-z",
1596  _ ("list"));
1597  ret = 1;
1598  finish_command ();
1599  return;
1600  }
1602  &zone_pkey,
1603  name,
1604  &lookup_error_cb,
1605  NULL,
1607  NULL);
1608  }
1609  else
1611  (NULL == ego_name) ?
1612  NULL : &zone_pkey,
1614  NULL,
1616  NULL,
1618  NULL,
1619  filter_flags);
1620  }
1621  if (NULL != reverse_pkey)
1622  {
1624 
1625  if (NULL == ego_name)
1626  {
1627  fprintf (stderr,
1628  _ ("Missing option `%s' for operation `%s'\n"),
1629  "-z",
1630  _ ("reverse-pkey"));
1631  ret = 1;
1632  finish_command ();
1633  return;
1634  }
1635  if (GNUNET_OK !=
1637  &pubkey))
1638  {
1639  fprintf (stderr,
1640  _ ("Invalid public key for reverse lookup `%s'\n"),
1641  reverse_pkey);
1642  ret = 1;
1643  finish_command ();
1644  return;
1645  }
1647  &zone_pkey,
1648  &pubkey,
1650  NULL,
1652  NULL);
1653  }
1654  if (NULL != uri)
1655  {
1656  char sh[105];
1657  char sname[64];
1659  if (NULL == ego_name)
1660  {
1661  fprintf (stderr,
1662  _ ("Missing option `%s' for operation `%s'\n"),
1663  "-z",
1664  _ ("uri"));
1665  ret = 1;
1666  finish_command ();
1667  return;
1668  }
1669 
1670  memset (sh, 0, 105);
1671  memset (sname, 0, 64);
1672 
1673  if ((2 != (sscanf (uri, "gnunet://gns/%58s/%63s", sh, sname))) ||
1674  (GNUNET_OK !=
1676  {
1677  fprintf (stderr, _ ("Invalid URI `%s'\n"), uri);
1678  ret = 1;
1679  finish_command ();
1680  return;
1681  }
1682  if (NULL == expirationstring)
1683  {
1684  fprintf (stderr,
1685  _ ("Missing option `%s' for operation `%s'\n"),
1686  "-e",
1687  _ ("add"));
1688  ret = 1;
1689  finish_command ();
1690  return;
1691  }
1693  {
1694  fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring);
1695  ret = 1;
1696  finish_command ();
1697  return;
1698  }
1699  memset (&rd, 0, sizeof(rd));
1700  rd.data = &pkey;
1702  rd.record_type = ntohl (pkey.type);
1704  if (GNUNET_YES == etime_is_rel)
1706  if (1 == is_shadow)
1709  &zone_pkey,
1710  sname,
1711  1,
1712  &rd,
1714  &add_qe_uri);
1715  }
1716  if (monitor)
1717  {
1719  (NULL != ego_name) ?
1720  &zone_pkey : NULL,
1721  GNUNET_YES,
1723  NULL,
1725  NULL,
1726  &sync_cb,
1727  NULL,
1728  filter_flags);
1729  }
1730 }
1731 
1732 #define MAX_LINE_LEN 4086
1733 
1734 #define MAX_ARGS 20
1735 
1736 static int
1737 get_identity_for_string (const char *str,
1738  struct GNUNET_IDENTITY_PrivateKey *zk)
1739 {
1740  const struct GNUNET_IDENTITY_PrivateKey *privkey;
1742  struct GNUNET_IDENTITY_PublicKey ego_pubkey;
1743  struct EgoEntry *ego_entry;
1744 
1746  &pubkey))
1747  {
1748  for (ego_entry = ego_head;
1749  NULL != ego_entry; ego_entry = ego_entry->next)
1750  {
1751  privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1752  GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &ego_pubkey);
1753  if (0 == memcmp (&ego_pubkey, &pubkey, sizeof (pubkey)))
1754  {
1755  *zk = *privkey;
1756  return GNUNET_OK;
1757  }
1758  }
1759  }
1760  else
1761  {
1762  for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next)
1763  {
1765  if (0 != strcmp (str, ego_entry->identifier))
1766  continue;
1767  *zk = *GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1768  return GNUNET_OK;
1769  }
1770  }
1771  return GNUNET_NO;
1772 }
1773 
1774 static void
1776 {
1777  char buf[MAX_LINE_LEN];
1778  static struct GNUNET_IDENTITY_PrivateKey next_zone_key;
1779  static char next_name[GNUNET_DNSPARSER_MAX_NAME_LENGTH];
1780  static int finished = GNUNET_NO;
1781  static int have_next_zonekey = GNUNET_NO;
1782  int zonekey_set = GNUNET_NO;
1783  char *tmp;
1784 
1785 
1786  if (GNUNET_YES == have_next_zonekey)
1787  {
1788  zone_pkey = next_zone_key;
1789  if (NULL != name)
1790  GNUNET_free (name);
1791  name = GNUNET_strdup (next_name);
1792  zonekey_set = GNUNET_YES;
1793  }
1794  while (NULL != fgets (buf, sizeof (buf), stdin))
1795  {
1796  if (1 >= strlen (buf))
1797  continue;
1798  if (buf[strlen (buf) - 1] == '\n')
1799  buf[strlen (buf) - 1] = '\0';
1803  if (buf[strlen (buf) - 1] == ':')
1804  {
1805  memset (next_name, 0, sizeof (next_name));
1806  strncpy (next_name, buf, strlen (buf) - 1);
1807  tmp = strchr (next_name, '.');
1808  if (NULL == tmp)
1809  {
1810  fprintf (stderr, "Error parsing name `%s'\n", next_name);
1812  ret = 1;
1813  return;
1814  }
1815  if (GNUNET_OK != get_identity_for_string (tmp + 1, &next_zone_key))
1816  {
1817  fprintf (stderr, "Error parsing zone name `%s'\n", tmp + 1);
1818  ret = 1;
1820  return;
1821  }
1822  *tmp = '\0';
1823  have_next_zonekey = GNUNET_YES;
1824  /* Run a command for the previous record set */
1825  if (NULL != recordset)
1826  {
1828  return;
1829  }
1830  zone_pkey = next_zone_key;
1831  if (NULL != name)
1832  GNUNET_free (name);
1833  name = GNUNET_strdup (next_name);
1834  zonekey_set = GNUNET_YES;
1835  continue;
1836  }
1837  if (GNUNET_NO == zonekey_set)
1838  {
1839  fprintf (stderr, "Warning, encountered recordline without zone\n");
1840  continue;
1841  }
1843  }
1844  if (GNUNET_NO == finished)
1845  {
1846  if (NULL != recordset)
1847  {
1848  if (GNUNET_YES == zonekey_set)
1849  {
1851  finished = GNUNET_YES;
1852  return;
1853  }
1854  fprintf (stderr, "Warning, encountered recordline without zone\n");
1855  }
1856  }
1858  return;
1859 }
1860 
1861 
1862 static void
1863 begin_cb (void *cls, enum GNUNET_ErrorCode ec)
1864 {
1865  ns_qe = NULL;
1866  if (GNUNET_EC_NONE != ec)
1867  {
1869  "Failed to start transaction: %s\n",
1872  return;
1873  }
1874  if (read_from_stdin)
1875  {
1877  return;
1878  }
1880 }
1881 
1882 
1895 static void
1896 id_connect_cb (void *cls,
1897  struct GNUNET_IDENTITY_Ego *ego,
1898  void **ctx,
1899  const char *name)
1900 {
1902  struct EgoEntry *ego_entry;
1903 
1904  (void) ctx;
1905  (void) name;
1906  if ((NULL != name) && (NULL != ego))
1907  {
1908  ego_entry = GNUNET_new (struct EgoEntry);
1910  ego_entry->ego = ego;
1911  ego_entry->identifier = GNUNET_strdup (name);
1913  ego_tail,
1914  ego_entry);
1915  if ((NULL != ego_name) &&
1916  (0 == strcmp (name, ego_name)))
1918  return;
1919  }
1920  if (NULL != ego)
1921  return;
1923 }
1924 
1925 
1926 
1927 
1928 
1937 static void
1938 run (void *cls,
1939  char *const *args,
1940  const char *cfgfile,
1941  const struct GNUNET_CONFIGURATION_Handle *_cfg)
1942 {
1943  (void) cls;
1944  (void) args;
1945  (void) cfgfile;
1946  cfg = _cfg;
1947  if (NULL != args[0])
1948  GNUNET_log (
1950  _ ("Superfluous command line arguments (starting with `%s') ignored\n"),
1951  args[0]);
1952 
1955  if (NULL == ns)
1956  {
1957  fprintf (stderr, _ ("Failed to connect to namestore\n"));
1959  return;
1960  }
1962  if (NULL == idh)
1963  {
1964  ret = -1;
1965  fprintf (stderr, _ ("Cannot connect to identity service\n"));
1967  }
1968 }
1969 
1970 
1971 
1979 int
1980 main (int argc, char *const *argv)
1981 {
1982  int lret;
1984  { GNUNET_GETOPT_option_flag ('a', "add", gettext_noop ("add record"), &add),
1986  "delete",
1987  gettext_noop ("delete record"),
1988  &del),
1990  "display",
1991  gettext_noop ("display records"),
1992  &list),
1994  "from-stdin",
1995  gettext_noop ("read commands from stdin"),
1996  &read_from_stdin),
1998  'e',
1999  "expiration",
2000  "TIME",
2001  gettext_noop (
2002  "expiration time for record to use (for adding only), \"never\" is possible"),
2003  &expirationstring),
2005  "nick",
2006  "NICKNAME",
2007  gettext_noop (
2008  "set the desired nick name for the zone"),
2009  &nickstring),
2011  "monitor",
2012  gettext_noop (
2013  "monitor changes in the namestore"),
2014  &monitor),
2016  "name",
2017  "NAME",
2018  gettext_noop (
2019  "name of the record to add/delete/display"),
2020  &name),
2022  "recordline",
2023  gettext_noop ("Output in recordline format"),
2026  "zone-to-name",
2027  "KEY",
2028  gettext_noop (
2029  "determine our name for the given KEY"),
2030  &reverse_pkey),
2032  "type",
2033  "TYPE",
2034  gettext_noop (
2035  "type of the record to add/delete/display"),
2036  &typestring),
2038  "uri",
2039  "URI",
2040  gettext_noop ("URI to import into our zone"),
2041  &uri),
2043  "value",
2044  "VALUE",
2045  gettext_noop (
2046  "value of the record to add/delete"),
2047  &value),
2049  "public",
2050  gettext_noop ("create or list public record"),
2051  &is_public),
2053  "omit-private",
2054  gettext_noop ("omit private records"),
2055  &omit_private),
2057  "include-maintenance",
2058  gettext_noop (
2059  "do not filter maintenance records"),
2062  "purge-orphans",
2063  gettext_noop (
2064  "purge namestore of all orphans"),
2065  &purge_orphaned),
2067  "list-orphans",
2068  gettext_noop (
2069  "show private key for orphaned records for recovery using `gnunet-identity -C -P <key>'. Use in combination with --display"),
2070  &list_orphaned),
2072  "purge-zone-records",
2073  gettext_noop (
2074  "delete all records in specified zone"),
2075  &purge_zone),
2077  's',
2078  "shadow",
2079  gettext_noop (
2080  "create shadow record (only valid if all other records of the same type have expired"),
2081  &is_shadow),
2083  "zone",
2084  "EGO",
2085  gettext_noop (
2086  "name of the ego controlling the zone"),
2087  &ego_name),
2089 
2090 
2091  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
2092  return 2;
2093 
2094  is_public = -1;
2095  is_shadow = -1;
2096  GNUNET_log_setup ("gnunet-namestore", "WARNING", NULL);
2097  if (GNUNET_OK !=
2098  (lret = GNUNET_PROGRAM_run (argc,
2099  argv,
2100  "gnunet-namestore",
2101  _ ("GNUnet zone manipulation tool"),
2102  options,
2103  &run,
2104  NULL)))
2105  {
2106  GNUNET_free_nz ((void *) argv);
2107  // FIXME
2108  // GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey);
2109  return lret;
2110  }
2111  GNUNET_free_nz ((void *) argv);
2112  // FIXME
2113  // GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey);
2114  return ret;
2115 }
2116 
2117 
2118 /* end of gnunet-namestore.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_NICK
GNS nick names.
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_NAMESTORE_RECORD_EXISTS
Record already exists.
@ GNUNET_EC_NONE
No error (success).
@ GNUNET_EC_NAMESTORE_RECORD_NOT_FOUND
Record not found.
#define gettext_noop(String)
Definition: gettext.h:70
static struct Experiment * e
static struct SolverHandle * sh
static struct PendingResolutions * head
Head of list of pending resolution requests.
Definition: gnunet-ats.c:230
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
static char * line
Desired phone line (string to be converted to a hash).
static struct GNUNET_DATASTORE_QueueEntry * qe
Current operation.
struct GNUNET_IDENTITY_PrivateKey pk
Private key from command line option, or NULL.
static char * pkey
Public key of the zone to look in, in ASCII.
static struct GNUNET_IDENTITY_PublicKey pubkey
Public key of the zone to look in.
static char * zone
Name of the zone being managed.
static const struct GNUNET_IDENTITY_PrivateKey * zone_key
Private key of the zone.
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 struct EgoEntry * ego_tail
Ego list.
static struct GNUNET_NAMESTORE_QueueEntry * ns_qe
Queue entry for begin/commit.
#define MAX_LINE_LEN
static int output_recordline
Output in recordline format.
static int omit_private
Filter private records.
static void zone_iteration_finished(void *cls)
Function called when we are done with a zone iteration.
static void replace_cont(void *cls, enum GNUNET_ErrorCode ec)
static void sync_cb(void *cls)
Function called once we are in sync in monitor mode.
static struct GNUNET_NAMESTORE_QueueEntry * get_qe
Queue entry for the 'lookup' operation.
static void display_record_iterator(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *rname, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd, struct GNUNET_TIME_Absolute expiry)
Process a record that was stored in the namestore.
static void del_lookup_error_cb(void *cls)
Function called if lookup for deletion fails.
static struct GNUNET_NAMESTORE_ZoneMonitor * zm
Monitor handle.
static int parse_recordline(const char *line)
static void del_continuation(void *cls, enum GNUNET_ErrorCode ec)
static struct GNUNET_IDENTITY_PrivateKey zone_pkey
Private key for the our zone.
static int list_orphaned
List records and zone keys of orphaned records.
#define WARN_RELATIVE_EXPIRATION_LIMIT
The upper bound for the zone iteration interval (per record).
static void purge_next_record(void *cls)
static int purge_orphaned
Purge orphaned records.
static struct GNUNET_NAMESTORE_QueueEntry * add_qe
Queue entry for the 'add' operation.
static void display_record(const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *rname, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd)
Process a record that was stored in the namestore.
static void display_record_monitor(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *rname, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd, struct GNUNET_TIME_Absolute expiry)
Process a record that was stored in the namestore.
static char * nickstring
Desired nick name.
static int monitor
Enables monitor mode.
static char * value
Value of the record to add/remove.
static int list
Desired action is to list records.
static void commit_cb(void *cls, enum GNUNET_ErrorCode ec)
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration handle.
static struct GNUNET_NAMESTORE_QueueEntry * del_qe
Queue entry for the 'del' operation.
static int purge_zone
Purge zone contents.
static void collect_zone_records_to_purge(const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *rname, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd)
static char * name
Name of the records to add/list/remove.
static int include_maintenance
Do not filter maintenance records.
static struct GNUNET_NAMESTORE_QueueEntry * set_qe
Queue entry for the 'set/replace' operation.
static int ret
Global return value.
static void reset_handles(void)
static void purge_orphans_iterator(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *rname, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd, struct GNUNET_TIME_Absolute expiry)
static void * data
Value in binary format.
static void lookup_error_cb(void *cls)
Function called on errors while monitoring.
static void do_shutdown(void *cls)
Task run on shutdown.
static void begin_cb(void *cls, enum GNUNET_ErrorCode ec)
static struct GNUNET_IDENTITY_Handle * idh
Identity service handle.
static struct RecordSetEntry * recordset
Entry in record set for processing records in bulk.
static char * ego_name
Name of the ego controlling the zone.
static void reverse_error_cb(void *cls)
Function called if we encountered an error in zone-to-name.
static struct MarkedRecord * marked_head
Marked record list.
static struct EgoEntry * ego_head
Ego list.
static int is_shadow
Is record a shadow record (GNUNET_GNSRECORD_RF_SHADOW)
static void handle_reverse_lookup(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Function called with the result of our attempt to obtain a name for a given public key.
static int get_identity_for_string(const char *str, struct GNUNET_IDENTITY_PrivateKey *zk)
static void add_continuation(void *cls, enum GNUNET_ErrorCode ec)
static struct GNUNET_SCHEDULER_Task * purge_task
Purge task.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *_cfg)
Main function that will be run.
static void finish_command(void)
static void get_existing_record(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *rec_name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
We're storing a record; this function is given the existing record so that we can merge the informati...
static int del
Desired action is to remove a record.
static int etime_is_rel
Is expiration time relative or absolute time?
static void add_error_cb(void *cls)
Function called if lookup fails.
static struct GNUNET_NAMESTORE_Handle * ns
Handle to the namestore.
static int parse_expiration(const char *expirationstring, int *etime_is_rel, uint64_t *etime)
Parse expiration time.
static void marked_deleted(void *cls, enum GNUNET_ErrorCode ec)
static void id_connect_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *name)
Function called with ALL of the egos known to the identity service, used on startup if the user did n...
static struct GNUNET_NAMESTORE_ZoneIterator * list_it
List iterator for the 'list' operation.
static struct MarkedRecord * marked_tail
Marked record list.
static void monitor_error_cb(void *cls)
Function called on errors while monitoring.
static int read_from_stdin
Run in read from stdin mode.
static void run_with_zone_pkey(const struct GNUNET_CONFIGURATION_Handle *cfg)
We have obtained the zone's private key, so now process the main commands using it.
int main(int argc, char *const *argv)
The main function for gnunet-namestore.
static uint32_t type
Type string converted to DNS type value.
static void purge_zone_iterator(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *rname, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd, struct GNUNET_TIME_Absolute expiry)
static size_t data_size
Number of bytes in data.
static void del_monitor(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
We were asked to delete something; this function is called with the existing records.
static char * expirationstring
Desired expiration time.
static struct GNUNET_NAMESTORE_QueueEntry * add_qe_uri
Queue entry for the 'add-uri' operation.
static void display_record_lookup(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *rname, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd)
Process a record that was stored in the namestore.
static void collect_orphans(const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *rname, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd)
static void process_command_stdin()
static int add
Desired action is to add a record.
static struct GNUNET_NAMESTORE_QueueEntry * reverse_qe
Queue entry for the 'reverse lookup' operation (in combination with a name).
static void zone_iteration_error_cb(void *cls)
Function called when we encountered an error in a zone iteration.
static char * typestring
Type of the record to add/remove, NULL to remove all.
static char * uri
URI to import.
static uint64_t etime
Expiration string converted to numeric value.
static char * reverse_pkey
Reverse lookup to perform.
static int is_public
Is record public (opposite of GNUNET_GNSRECORD_RF_PRIVATE)
static char buf[2048]
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
API to the GNS service.
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;.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_DNSPARSER_TYPE_OPENPGPKEY
#define GNUNET_DNSPARSER_TYPE_TLSA
#define GNUNET_DNSPARSER_TYPE_SRV
#define GNUNET_DNSPARSER_TYPE_SOA
#define GNUNET_DNSPARSER_MAX_NAME_LENGTH
Maximum length of a name in DNS.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_flag(char shortName, const char *name, const char *description, int *val)
Allow user to specify a flag (which internally means setting an integer to 1/GNUNET_YES/GNUNET_OK.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_string(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a string.
const char * GNUNET_GNSRECORD_number_to_typename(uint32_t type)
Convert a type number to the corresponding type string (e.g.
Definition: gnsrecord.c:227
@ GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION
This expiration time of the record is a relative time (not an absolute time).
@ GNUNET_GNSRECORD_RF_CRITICAL
This record is critical.
@ GNUNET_GNSRECORD_RF_SUPPLEMENTAL
This is a supplemental record.
@ GNUNET_GNSRECORD_RF_SHADOW
This record should not be used unless all (other) records in the set with an absolute expiration time...
@ GNUNET_GNSRECORD_RF_PRIVATE
This is a private record of this peer and it should thus not be published.
@ GNUNET_GNSRECORD_RF_NONE
Entry for no flags / cleared flags.
char * GNUNET_GNSRECORD_value_to_string(uint32_t type, const void *data, size_t data_size)
Convert the 'value' of a record to a string.
Definition: gnsrecord.c:155
uint32_t GNUNET_GNSRECORD_typename_to_number(const char *dns_typename)
Convert a type name (e.g.
Definition: gnsrecord.c:200
int GNUNET_GNSRECORD_string_to_value(uint32_t type, const char *s, void **data, size_t *data_size)
Convert human-readable version of the value s of a record of type type to the respective binary repre...
Definition: gnsrecord.c:177
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
GNUNET_GNSRECORD_Filter
Filter for GNUNET_GNSRECORD_normalize_record_set().
#define GNUNET_GNSRECORD_TYPE_ANY
Record type indicating any record/'*'.
@ GNUNET_GNSRECORD_FILTER_NONE
No filter flags set.
@ GNUNET_GNSRECORD_FILTER_INCLUDE_MAINTENANCE
Include maintenance records (TOMBSTONE etc).
@ GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE
Filter private records.
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
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_public_key_from_string(const char *str, struct GNUNET_IDENTITY_PublicKey *key)
Parses a (Base32) string representation of the public key.
ssize_t GNUNET_IDENTITY_public_key_get_length(const struct GNUNET_IDENTITY_PublicKey *key)
Get the compacted length of a GNUNET_IDENTITY_PublicKey.
Definition: identity_api.c:830
char * GNUNET_IDENTITY_private_key_to_string(const struct GNUNET_IDENTITY_PrivateKey *key)
Creates a (Base32) string representation of the private key.
void GNUNET_IDENTITY_ego_get_public_key(struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_IDENTITY_PublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:573
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_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
#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_MESSAGE
@ GNUNET_ERROR_TYPE_DEBUG
#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_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#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_QueueEntry * GNUNET_NAMESTORE_records_lookup(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_PrivateKey *pkey, const char *label, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor rm, void *rm_cls)
Lookup an item in the namestore.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_transaction_begin(struct GNUNET_NAMESTORE_Handle *h, GNUNET_NAMESTORE_ContinuationWithStatus cont, void *cont_cls)
New API draft.
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.
void GNUNET_NAMESTORE_zone_monitor_stop(struct GNUNET_NAMESTORE_ZoneMonitor *zm)
Stop monitoring a zone for changes.
struct GNUNET_NAMESTORE_ZoneIterator * GNUNET_NAMESTORE_zone_iteration_start2(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_PrivateKey *zone, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordSetMonitor proc, void *proc_cls, GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls, enum GNUNET_GNSRECORD_Filter filter)
Starts a new zone iteration (used to periodically PUT all of our records into our DHT).
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_ZoneMonitor * GNUNET_NAMESTORE_zone_monitor_start2(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_IDENTITY_PrivateKey *zone, int iterate_first, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordSetMonitor monitor, void *monitor_cls, GNUNET_SCHEDULER_TaskCallback sync_cb, void *sync_cb_cls, enum GNUNET_GNSRECORD_Filter filter)
Begin monitoring a zone for changes.
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namestore service.
void GNUNET_NAMESTORE_zone_monitor_next(struct GNUNET_NAMESTORE_ZoneMonitor *zm, uint64_t limit)
Calls the monitor processor specified in GNUNET_NAMESTORE_zone_monitor_start for the next record(s).
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_transaction_commit(struct GNUNET_NAMESTORE_Handle *h, GNUNET_NAMESTORE_ContinuationWithStatus cont, void *cont_cls)
Commit a namestore transaction.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_zone_to_name(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_PrivateKey *zone, const struct GNUNET_IDENTITY_PublicKey *value_zone, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor proc, void *proc_cls)
Look for an existing PKEY delegation record for a given public key.
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:534
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:1268
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:1303
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:944
enum GNUNET_GenericReturnValue GNUNET_STRINGS_fancy_time_to_relative(const char *fancy_time, struct GNUNET_TIME_Relative *rtime)
Convert a given fancy human-readable time to our internal representation.
Definition: strings.c:260
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
#define GNUNET_TIME_relative_cmp(t1, op, t2)
Compare two relative times.
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:616
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".
enum GNUNET_GenericReturnValue GNUNET_STRINGS_fancy_time_to_absolute(const char *fancy_time, struct GNUNET_TIME_Absolute *atime)
Convert a given fancy human-readable time to our internal representation.
Definition: strings.c:302
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
The ego list.
char * identifier
Ego Identifier.
struct EgoEntry * prev
DLL.
struct EgoEntry * next
DLL.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
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.
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.
An identity key 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.
Handle for a monitoring activity.
Entry in list of pending tasks.
Definition: scheduler.c:136
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.
The record marked for deletion.
struct GNUNET_IDENTITY_PrivateKey key
The zone key.
struct MarkedRecord * next
DLL.
char * name
Ego Identifier.
struct MarkedRecord * prev
DLL.
Entry in record set for bulk processing.
struct GNUNET_GNSRECORD_Data record
The record to add/remove.
struct RecordSetEntry * next
Kept in a linked list.