GNUnet  0.19.4
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  GNUNET_free (cp);
468  return GNUNET_SYSERR;
469  }
470  GNUNET_free (cp);
471 
472  r = GNUNET_malloc (sizeof(struct RecordSetEntry) + record.data_size);
473  r->next = *head;
474  record.data = &r[1];
475  memcpy (&r[1], raw_data, record.data_size);
476  GNUNET_free (raw_data);
477  r->record = record;
478  *head = r;
479  return GNUNET_OK;
480 }
481 
482 static void
484 {
485  struct MarkedRecord *mrec;
486  struct MarkedRecord *mrec_tmp;
487  struct RecordSetEntry *rs_entry;
488 
489  rs_entry = recordset;
490  while (NULL != (rs_entry = recordset))
491  {
493  GNUNET_free (rs_entry);
494  }
495  recordset = NULL;
496  if (NULL != ego_name)
497  {
499  ego_name = NULL;
500  }
501  if (NULL != name)
502  {
503  GNUNET_free (name);
504  name = NULL;
505  }
506  if (NULL != value)
507  {
508  GNUNET_free (value);
509  value = NULL;
510  }
511  if (NULL != uri)
512  {
513  GNUNET_free (uri);
514  uri = NULL;
515  }
516  if (NULL != expirationstring)
517  {
519  expirationstring = NULL;
520  }
521  if (NULL != purge_task)
522  {
524  purge_task = NULL;
525  }
526  for (mrec = marked_head; NULL != mrec;)
527  {
528  mrec_tmp = mrec;
529  mrec = mrec->next;
530  GNUNET_free (mrec_tmp->name);
531  GNUNET_free (mrec_tmp);
532  }
533  if (NULL != list_it)
534  {
536  list_it = NULL;
537  }
538  if (NULL != add_qe)
539  {
541  add_qe = NULL;
542  }
543  if (NULL != set_qe)
544  {
546  set_qe = NULL;
547  }
548  if (NULL != add_qe_uri)
549  {
551  add_qe_uri = NULL;
552  }
553  if (NULL != get_qe)
554  {
556  get_qe = NULL;
557  }
558  if (NULL != del_qe)
559  {
561  del_qe = NULL;
562  }
563  if (NULL != reverse_qe)
564  {
566  reverse_qe = NULL;
567  }
568  memset (&zone_pkey, 0, sizeof(zone_pkey));
569  if (NULL != zm)
570  {
572  zm = NULL;
573  }
574  if (NULL != data)
575  {
576  GNUNET_free (data);
577  data = NULL;
578  }
579  if (NULL != typestring)
580  {
582  typestring = NULL;
583  }
584  list = 0;
585  is_public = 0;
586  is_shadow = 0;
587  purge_zone = 0;
588 }
589 
590 
591 
597 static void
598 do_shutdown (void *cls)
599 {
600  struct EgoEntry *ego_entry;
601  struct EgoEntry *ego_tmp;
602  (void) cls;
603 
604  reset_handles ();
605  if (NULL != ns_qe)
606  {
608  ns_qe = NULL;
609  }
610  if (NULL != ns)
611  {
613  ns = NULL;
614  }
615  if (NULL != idh)
616  {
618  idh = NULL;
619  }
620  for (ego_entry = ego_head; NULL != ego_entry;)
621  {
622  ego_tmp = ego_entry;
623  ego_entry = ego_entry->next;
624  GNUNET_free (ego_tmp->identifier);
625  GNUNET_free (ego_tmp);
626  }
627 }
628 
629 static void
630 commit_cb (void *cls, enum GNUNET_ErrorCode ec)
631 {
632  ns_qe = NULL;
633  if (GNUNET_EC_NONE != ec)
634  {
635  fprintf (stderr, "Failed to commit to namestore: `%s'\n",
637  ret = 1;
638  }
640 }
641 
642 static void
644 
645 
646 static void
648 {
649  reset_handles ();
650  if (read_from_stdin)
651  {
653  return;
654  }
656 }
657 
658 
659 static void
660 add_continuation (void *cls, enum GNUNET_ErrorCode ec)
661 {
662  struct GNUNET_NAMESTORE_QueueEntry **qe = cls;
663 
664  *qe = NULL;
665  if (GNUNET_EC_NONE != ec)
666  {
667  fprintf (stderr,
668  _ ("Adding record failed: %s\n"),
671  ret = 1;
672  }
673  ret = 0;
674  finish_command ();
675 }
676 
677 
678 static void
679 del_continuation (void *cls, enum GNUNET_ErrorCode ec)
680 {
681  (void) cls;
682  del_qe = NULL;
684  {
685  fprintf (stderr,
686  _ ("Deleting record failed: %s\n"), GNUNET_ErrorCode_get_hint (
687  ec));
688  }
689  finish_command ();
690 }
691 
692 static void
693 purge_next_record (void *cls);
694 
695 static void
696 marked_deleted (void *cls, enum GNUNET_ErrorCode ec)
697 {
698  del_qe = NULL;
699  if (GNUNET_EC_NONE != ec)
700  {
701  fprintf (stderr,
702  _ ("Deleting record failed: %s\n"),
704  }
706 }
707 
708 
709 static void
710 purge_next_record (void *cls)
711 {
712  struct MarkedRecord *mrec;
713  purge_task = NULL;
714 
715  if (NULL == marked_head)
716  {
717  ret = 0;
718  finish_command ();
719  return;
720  }
721  mrec = marked_head;
723  marked_tail,
724  mrec);
726  &mrec->key,
727  mrec->name,
728  0, NULL,
730  NULL);
731  GNUNET_free (mrec->name);
732  GNUNET_free (mrec);
733 }
734 
738 static void
740 {
741  (void) cls;
742  list_it = NULL;
743  if (purge_orphaned || purge_zone)
744  {
746  return;
747  }
748  ret = 0;
749  finish_command ();
750 }
751 
752 
756 static void
758 {
759  (void) cls;
760  list_it = NULL;
761  fprintf (stderr, "Error iterating over zone\n");
762  ret = 1;
763  finish_command ();
764 }
765 
766 static void
769  const char *rname,
770  unsigned int rd_len,
771  const struct GNUNET_GNSRECORD_Data *rd)
772 {
773  struct MarkedRecord *mrec;
774 
775  mrec = GNUNET_new (struct MarkedRecord);
776  mrec->key = *zone_key;
777  mrec->name = GNUNET_strdup (rname);
779  marked_tail,
780  mrec);
781 }
782 
783 
784 static void
786  const char *rname,
787  unsigned int rd_len,
788  const struct GNUNET_GNSRECORD_Data *rd)
789 {
790  struct EgoEntry *ego;
791  struct MarkedRecord *orphan;
792  int is_orphaned = 1;
793 
794  for (ego = ego_head; NULL != ego; ego = ego->next)
795  {
796  if (0 == memcmp (GNUNET_IDENTITY_ego_get_private_key (ego->ego),
797  zone_key,
798  sizeof (*zone_key)))
799  {
800  is_orphaned = 0;
801  break;
802  }
803  }
804  if (is_orphaned)
805  {
806  orphan = GNUNET_new (struct MarkedRecord);
807  orphan->key = *zone_key;
808  orphan->name = GNUNET_strdup (rname);
810  marked_tail,
811  orphan);
812  }
813 }
814 
822 static void
824  const char *rname,
825  unsigned int rd_len,
826  const struct GNUNET_GNSRECORD_Data *rd)
827 {
828  const char *typestr;
829  char *s;
830  const char *ets;
831  struct GNUNET_TIME_Absolute at;
832  struct GNUNET_TIME_Relative rt;
833  struct EgoEntry *ego;
834  int have_record;
835  int is_orphaned = 1;
836  char *orphaned_str;
837 
838  if ((NULL != name) && (0 != strcmp (name, rname)))
839  return;
840  have_record = GNUNET_NO;
841  for (unsigned int i = 0; i < rd_len; i++)
842  {
843  if ((GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) &&
844  (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT)))
845  continue;
846  if ((type != rd[i].record_type) && (GNUNET_GNSRECORD_TYPE_ANY != type))
847  continue;
848  have_record = GNUNET_YES;
849  break;
850  }
851  if (GNUNET_NO == have_record)
852  return;
853  for (ego = ego_head; NULL != ego; ego = ego->next)
854  {
855  if (0 == memcmp (GNUNET_IDENTITY_ego_get_private_key (ego->ego),
856  zone_key,
857  sizeof (*zone_key)))
858  {
859  is_orphaned = 0;
860  break;
861  }
862  }
863  if (list_orphaned && ! is_orphaned)
864  return;
865  if (! list_orphaned && is_orphaned)
866  return;
868  fprintf (stdout, "%s.%s:\n", rname, is_orphaned ? orphaned_str :
869  ego->identifier);
870  GNUNET_free (orphaned_str);
871  if (NULL != typestring)
873  else
875  for (unsigned int i = 0; i < rd_len; i++)
876  {
877  if ((GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) &&
878  (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT)))
879  continue;
880  if ((type != rd[i].record_type) && (GNUNET_GNSRECORD_TYPE_ANY != type))
881  continue;
882  typestr = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type);
883  s = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
884  rd[i].data,
885  rd[i].data_size);
886  if (NULL == s)
887  {
888  fprintf (stdout,
889  _ ("\tCorrupt or unsupported record of type %u\n"),
890  (unsigned int) rd[i].record_type);
891  continue;
892  }
893  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
894  {
897  }
898  else
899  {
902  }
903  char flgstr[16];
904  sprintf (flgstr, "[%s%s%s%s%s]",
905  (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE) ? "" : "p",
906  (rd[i].flags & GNUNET_GNSRECORD_RF_SUPPLEMENTAL) ? "S" : "",
907  (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION) ? "r" : "",
908  (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW) ? "S" : "",
909  (rd[i].flags & GNUNET_GNSRECORD_RF_CRITICAL) ? "C" : "");
910  if (output_recordline)
911  fprintf (stdout,
912  " %s %" PRIu64 " %s %s\n",
913  typestr,
914  rd[i].expiration_time,
915  flgstr,
916  s);
917  else
918  fprintf (stdout,
919  "\t%s: %s (%s)\t%s\t%s\n",
920  typestr,
921  s,
922  ets,
923  (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) ? "PRIVATE"
924  : "PUBLIC",
925  (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW)) ? "SHADOW"
926  : "");
927  GNUNET_free (s);
928  }
929  // fprintf (stdout, "%s", "\n");
930 }
931 
932 static void
934  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
935  const char *rname,
936  unsigned int rd_len,
937  const struct GNUNET_GNSRECORD_Data *rd,
938  struct GNUNET_TIME_Absolute expiry)
939 {
940  (void) cls;
941  (void) zone_key;
942  (void) expiry;
943  collect_zone_records_to_purge (zone_key, rname, rd_len, rd);
945 }
946 
947 
948 static void
950  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
951  const char *rname,
952  unsigned int rd_len,
953  const struct GNUNET_GNSRECORD_Data *rd,
954  struct GNUNET_TIME_Absolute expiry)
955 {
956  (void) cls;
957  (void) zone_key;
958  (void) expiry;
959  collect_orphans (zone_key, rname, rd_len, rd);
961 }
962 
963 
973 static void
975  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
976  const char *rname,
977  unsigned int rd_len,
978  const struct GNUNET_GNSRECORD_Data *rd,
979  struct GNUNET_TIME_Absolute expiry)
980 {
981  (void) cls;
982  (void) zone_key;
983  (void) expiry;
984  display_record (zone_key, rname, rd_len, rd);
986 }
987 
988 
998 static void
1000  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
1001  const char *rname,
1002  unsigned int rd_len,
1003  const struct GNUNET_GNSRECORD_Data *rd,
1004  struct GNUNET_TIME_Absolute expiry)
1005 {
1006  (void) cls;
1007  (void) zone_key;
1008  (void) expiry;
1009  display_record (zone_key, rname, rd_len, rd);
1011 }
1012 
1013 
1023 static void
1025  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
1026  const char *rname,
1027  unsigned int rd_len,
1028  const struct GNUNET_GNSRECORD_Data *rd)
1029 {
1030  (void) cls;
1031  (void) zone_key;
1032  get_qe = NULL;
1033  display_record (zone_key, rname, rd_len, rd);
1034  finish_command ();
1035 }
1036 
1037 
1043 static void
1044 sync_cb (void *cls)
1045 {
1046  (void) cls;
1047  fprintf (stdout, "%s", "Monitor is now in sync.\n");
1048 }
1049 
1050 
1056 static void
1057 monitor_error_cb (void *cls)
1058 {
1059  (void) cls;
1060  fprintf (stderr, "%s", "Monitor disconnected and out of sync.\n");
1061 }
1062 
1063 
1069 static void
1070 lookup_error_cb (void *cls)
1071 {
1072  (void) cls;
1073  get_qe = NULL;
1074  fprintf (stderr, "%s", "Failed to lookup record.\n");
1075  finish_command ();
1076 }
1077 
1078 
1082 static void
1083 add_error_cb (void *cls)
1084 {
1085  (void) cls;
1086  add_qe = NULL;
1087  GNUNET_break (0);
1088  ret = 1;
1089  finish_command ();
1090 }
1091 
1092 
1103 static void
1105  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
1106  const char *rec_name,
1107  unsigned int rd_count,
1108  const struct GNUNET_GNSRECORD_Data *rd)
1109 {
1110  struct GNUNET_GNSRECORD_Data rdn[rd_count + 1];
1111  struct GNUNET_GNSRECORD_Data *rde;
1112 
1113  (void) cls;
1114  (void) zone_key;
1115  add_qe = NULL;
1116  if (0 != strcmp (rec_name, name))
1117  {
1118  GNUNET_break (0);
1119  ret = 1;
1120  finish_command ();
1121  return;
1122  }
1123 
1125  "Received %u records for name `%s'\n",
1126  rd_count,
1127  rec_name);
1128  for (unsigned int i = 0; i < rd_count; i++)
1129  {
1130  switch (rd[i].record_type)
1131  {
1134  {
1135  fprintf (
1136  stderr,
1137  _ (
1138  "A SOA record exists already under `%s', cannot add a second SOA to the same zone.\n"),
1139  rec_name);
1140  ret = 1;
1141  finish_command ();
1142  return;
1143  }
1144  break;
1145  }
1146  }
1147  memset (rdn, 0, sizeof(struct GNUNET_GNSRECORD_Data));
1148  GNUNET_memcpy (&rdn[1], rd, rd_count * sizeof(struct GNUNET_GNSRECORD_Data));
1149  rde = &rdn[0];
1150  rde->data = data;
1151  rde->data_size = data_size;
1152  rde->record_type = type;
1153  if (1 == is_shadow)
1155  if (1 != is_public)
1157  rde->expiration_time = etime;
1158  if (GNUNET_YES == etime_is_rel)
1160  else if (GNUNET_NO != etime_is_rel)
1161  rde->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
1162  GNUNET_assert (NULL != name);
1164  &zone_pkey,
1165  name,
1166  rd_count + 1,
1167  rde,
1169  &add_qe);
1170 }
1171 
1172 
1176 static void
1177 reverse_error_cb (void *cls)
1178 {
1179  (void) cls;
1180  reverse_qe = NULL;
1181  fprintf (stdout, "%s.zkey\n", reverse_pkey);
1182 }
1183 
1184 
1195 static void
1197  const struct GNUNET_IDENTITY_PrivateKey *zone,
1198  const char *label,
1199  unsigned int rd_count,
1200  const struct GNUNET_GNSRECORD_Data *rd)
1201 {
1202  (void) cls;
1203  (void) zone;
1204  (void) rd_count;
1205  (void) rd;
1206  reverse_qe = NULL;
1207  if (NULL == label)
1208  fprintf (stdout, "%s\n", reverse_pkey);
1209  else
1210  fprintf (stdout, "%s.%s\n", label, ego_name);
1211  finish_command ();
1212 }
1213 
1214 
1218 static void
1220 {
1221  (void) cls;
1222  del_qe = NULL;
1223  GNUNET_break (0);
1224  ret = 1;
1225  finish_command ();
1226 }
1227 
1228 
1240 static void
1241 del_monitor (void *cls,
1242  const struct GNUNET_IDENTITY_PrivateKey *zone,
1243  const char *label,
1244  unsigned int rd_count,
1245  const struct GNUNET_GNSRECORD_Data *rd)
1246 {
1247  struct GNUNET_GNSRECORD_Data rdx[rd_count];
1248  unsigned int rd_left;
1249  uint32_t type;
1250  char *vs;
1251 
1252  (void) cls;
1253  (void) zone;
1254  del_qe = NULL;
1255  if (0 == rd_count)
1256  {
1257  fprintf (stderr,
1258  _ (
1259  "There are no records under label `%s' that could be deleted.\n"),
1260  label);
1261  ret = 1;
1262  finish_command ();
1263  return;
1264  }
1265  if ((NULL == value) && (NULL == typestring))
1266  {
1267  /* delete everything */
1269  &zone_pkey,
1270  name,
1271  0,
1272  NULL,
1274  NULL);
1275  return;
1276  }
1277  rd_left = 0;
1278  if (NULL != typestring)
1280  else
1282  for (unsigned int i = 0; i < rd_count; i++)
1283  {
1284  vs = NULL;
1285  if (! (((GNUNET_GNSRECORD_TYPE_ANY == type) ||
1286  (rd[i].record_type == type)) &&
1287  ((NULL == value) ||
1288  (NULL ==
1290  rd[i].data,
1291  rd[i].data_size)))) ||
1292  (0 == strcmp (vs, value)))))
1293  rdx[rd_left++] = rd[i];
1294  GNUNET_free (vs);
1295  }
1296  if (rd_count == rd_left)
1297  {
1298  /* nothing got deleted */
1299  fprintf (
1300  stderr,
1301  _ (
1302  "There are no records under label `%s' that match the request for deletion.\n"),
1303  label);
1304  finish_command ();
1305  return;
1306  }
1307  /* delete everything but what we copied to 'rdx' */
1309  &zone_pkey,
1310  name,
1311  rd_left,
1312  rdx,
1314  NULL);
1315 }
1316 
1317 
1318 static void
1319 replace_cont (void *cls, enum GNUNET_ErrorCode ec)
1320 {
1321  (void) cls;
1322 
1323  set_qe = NULL;
1324  if (GNUNET_EC_NONE != ec)
1325  {
1327  _ ("%s\n"),
1329  ret = 1; /* fail from 'main' */
1330  }
1331  finish_command ();
1332 }
1333 
1334 
1341 static void
1343 {
1344  struct GNUNET_GNSRECORD_Data rd;
1346 
1347  if (omit_private)
1348  filter_flags |= GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE;
1349  if (include_maintenance)
1351  if (! (add | del | list | (NULL != nickstring) | (NULL != uri)
1352  | (NULL != reverse_pkey) | (NULL != recordset) | (monitor)
1353  | (purge_orphaned) | (list_orphaned) | (purge_zone)) )
1354  {
1355  /* nothing more to be done */
1356  fprintf (stderr, _ ("No options given\n"));
1357  finish_command ();
1358  return;
1359  }
1360 
1361  if (NULL != recordset)
1362  {
1363  /* replace entire record set */
1364  unsigned int rd_count;
1365  struct GNUNET_GNSRECORD_Data *rd;
1366 
1367  /* FIXME: We could easily support append and delete with this as well */
1368  if (! add)
1369  {
1370  fprintf (stderr, _ ("Recordlines only work with option `%s'\n"),
1371  "-a");
1372  ret = 1;
1373  finish_command ();
1374  return;
1375  }
1376  if (NULL == name)
1377  {
1378  fprintf (stderr,
1379  _ ("Missing option `%s' for operation `%s'\n"),
1380  "-n",
1381  _ ("name"));
1382  ret = 1;
1383  finish_command ();
1384  return;
1385  }
1386  rd_count = 0;
1387  for (struct RecordSetEntry *e = recordset; NULL != e; e = e->next)
1388  rd_count++;
1390  rd_count = 0;
1391  for (struct RecordSetEntry *e = recordset; NULL != e; e = e->next)
1392  {
1393  rd[rd_count] = e->record;
1394  rd_count++;
1395  }
1397  &zone_pkey,
1398  name,
1399  rd_count,
1400  rd,
1401  &replace_cont,
1402  NULL);
1403  GNUNET_free (rd);
1404  return;
1405  }
1406  if (NULL != nickstring)
1407  {
1408  if (0 == strlen (nickstring))
1409  {
1410  fprintf (stderr, _ ("Invalid nick `%s'\n"), nickstring);
1411  ret = 1;
1412  finish_command ();
1413  return;
1414  }
1415  add = 1;
1420  is_public = 0;
1421  expirationstring = GNUNET_strdup ("never");
1423  nickstring = NULL;
1424  }
1425 
1426  if (add)
1427  {
1428  if (NULL == ego_name)
1429  {
1430  fprintf (stderr,
1431  _ ("Missing option `%s' for operation `%s'\n"),
1432  "-z",
1433  _ ("add"));
1434  ret = 1;
1435  finish_command ();
1436  return;
1437  }
1438  if (NULL == name)
1439  {
1440  fprintf (stderr,
1441  _ ("Missing option `%s' for operation `%s'\n"),
1442  "-n",
1443  _ ("add"));
1444  ret = 1;
1445  finish_command ();
1446  return;
1447  }
1448  if (NULL == typestring)
1449  {
1450  fprintf (stderr,
1451  _ ("Missing option `%s' for operation `%s'\n"),
1452  "-t",
1453  _ ("add"));
1454  ret = 1;
1455  finish_command ();
1456  return;
1457  }
1459  if (UINT32_MAX == type)
1460  {
1461  fprintf (stderr, _ ("Unsupported type `%s'\n"), typestring);
1462  ret = 1;
1463  finish_command ();
1464  return;
1465  }
1466  if ((GNUNET_DNSPARSER_TYPE_SRV == type) ||
1469  {
1470  fprintf (stderr,
1471  _ ("For DNS record types `SRV', `TLSA' and `OPENPGPKEY'"));
1472  fprintf (stderr, ", please use a `BOX' record instead\n");
1473  ret = 1;
1474  finish_command ();
1475  return;
1476  }
1477  if (NULL == value)
1478  {
1479  fprintf (stderr,
1480  _ ("Missing option `%s' for operation `%s'\n"),
1481  "-V",
1482  _ ("add"));
1483  ret = 1;
1484  finish_command ();
1485  return;
1486  }
1487  if (GNUNET_OK !=
1489  {
1490  fprintf (stderr,
1491  _ ("Value `%s' invalid for record type `%s'\n"),
1492  value,
1493  typestring);
1494  ret = 1;
1495  finish_command ();
1496  return;
1497  }
1498  if (NULL == expirationstring)
1499  {
1500  fprintf (stderr,
1501  _ ("Missing option `%s' for operation `%s'\n"),
1502  "-e",
1503  _ ("add"));
1504  ret = 1;
1505  finish_command ();
1506  return;
1507  }
1509  {
1510  fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring);
1511  ret = 1;
1512  finish_command ();
1513  return;
1514  }
1516  &zone_pkey,
1517  name,
1518  &add_error_cb,
1519  NULL,
1521  NULL);
1522  }
1523  if (del)
1524  {
1525  if (NULL == ego_name)
1526  {
1527  fprintf (stderr,
1528  _ ("Missing option `%s' for operation `%s'\n"),
1529  "-z",
1530  _ ("del"));
1531  ret = 1;
1532  finish_command ();
1533  return;
1534  }
1535  if (NULL == name)
1536  {
1537  fprintf (stderr,
1538  _ ("Missing option `%s' for operation `%s'\n"),
1539  "-n",
1540  _ ("del"));
1541  ret = 1;
1542  finish_command ();
1543  return;
1544  }
1546  &zone_pkey,
1547  name,
1549  NULL,
1550  &del_monitor,
1551  NULL);
1552  }
1553  if (purge_orphaned)
1554  {
1556  NULL,
1558  NULL,
1560  NULL,
1562  NULL,
1563  filter_flags);
1564 
1565  }
1566  else if (purge_zone)
1567  {
1568  if (NULL == ego_name)
1569  {
1570  fprintf (stderr,
1571  _ ("Missing option `%s' for operation `%s'\n"),
1572  "-z",
1573  _ ("purge-zone"));
1574  ret = 1;
1575  finish_command ();
1576  return;
1577  }
1579  &zone_pkey,
1581  NULL,
1583  NULL,
1585  NULL,
1586  filter_flags);
1587 
1588  }
1589  else if (list || list_orphaned)
1590  {
1591  if (NULL != name)
1592  {
1593  if (NULL == ego_name)
1594  {
1595  fprintf (stderr,
1596  _ ("Missing option `%s' for operation `%s'\n"),
1597  "-z",
1598  _ ("list"));
1599  ret = 1;
1600  finish_command ();
1601  return;
1602  }
1604  &zone_pkey,
1605  name,
1606  &lookup_error_cb,
1607  NULL,
1609  NULL);
1610  }
1611  else
1613  (NULL == ego_name) ?
1614  NULL : &zone_pkey,
1616  NULL,
1618  NULL,
1620  NULL,
1621  filter_flags);
1622  }
1623  if (NULL != reverse_pkey)
1624  {
1626 
1627  if (NULL == ego_name)
1628  {
1629  fprintf (stderr,
1630  _ ("Missing option `%s' for operation `%s'\n"),
1631  "-z",
1632  _ ("reverse-pkey"));
1633  ret = 1;
1634  finish_command ();
1635  return;
1636  }
1637  if (GNUNET_OK !=
1639  &pubkey))
1640  {
1641  fprintf (stderr,
1642  _ ("Invalid public key for reverse lookup `%s'\n"),
1643  reverse_pkey);
1644  ret = 1;
1645  finish_command ();
1646  return;
1647  }
1649  &zone_pkey,
1650  &pubkey,
1652  NULL,
1654  NULL);
1655  }
1656  if (NULL != uri)
1657  {
1658  char sh[105];
1659  char sname[64];
1661  if (NULL == ego_name)
1662  {
1663  fprintf (stderr,
1664  _ ("Missing option `%s' for operation `%s'\n"),
1665  "-z",
1666  _ ("uri"));
1667  ret = 1;
1668  finish_command ();
1669  return;
1670  }
1671 
1672  memset (sh, 0, 105);
1673  memset (sname, 0, 64);
1674 
1675  if ((2 != (sscanf (uri, "gnunet://gns/%58s/%63s", sh, sname))) ||
1676  (GNUNET_OK !=
1678  {
1679  fprintf (stderr, _ ("Invalid URI `%s'\n"), uri);
1680  ret = 1;
1681  finish_command ();
1682  return;
1683  }
1684  if (NULL == expirationstring)
1685  {
1686  fprintf (stderr,
1687  _ ("Missing option `%s' for operation `%s'\n"),
1688  "-e",
1689  _ ("add"));
1690  ret = 1;
1691  finish_command ();
1692  return;
1693  }
1695  {
1696  fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring);
1697  ret = 1;
1698  finish_command ();
1699  return;
1700  }
1701  memset (&rd, 0, sizeof(rd));
1702  rd.data = &pkey;
1704  rd.record_type = ntohl (pkey.type);
1706  if (GNUNET_YES == etime_is_rel)
1708  if (1 == is_shadow)
1711  &zone_pkey,
1712  sname,
1713  1,
1714  &rd,
1716  &add_qe_uri);
1717  }
1718  if (monitor)
1719  {
1721  (NULL != ego_name) ?
1722  &zone_pkey : NULL,
1723  GNUNET_YES,
1725  NULL,
1727  NULL,
1728  &sync_cb,
1729  NULL,
1730  filter_flags);
1731  }
1732 }
1733 
1734 #define MAX_LINE_LEN 4086
1735 
1736 #define MAX_ARGS 20
1737 
1738 static int
1739 get_identity_for_string (const char *str,
1740  struct GNUNET_IDENTITY_PrivateKey *zk)
1741 {
1742  const struct GNUNET_IDENTITY_PrivateKey *privkey;
1744  struct GNUNET_IDENTITY_PublicKey ego_pubkey;
1745  struct EgoEntry *ego_entry;
1746 
1748  &pubkey))
1749  {
1750  for (ego_entry = ego_head;
1751  NULL != ego_entry; ego_entry = ego_entry->next)
1752  {
1753  privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1754  GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &ego_pubkey);
1755  if (0 == memcmp (&ego_pubkey, &pubkey, sizeof (pubkey)))
1756  {
1757  *zk = *privkey;
1758  return GNUNET_OK;
1759  }
1760  }
1761  }
1762  else
1763  {
1764  for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next)
1765  {
1767  if (0 != strcmp (str, ego_entry->identifier))
1768  continue;
1769  *zk = *GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1770  return GNUNET_OK;
1771  }
1772  }
1773  return GNUNET_NO;
1774 }
1775 
1776 static void
1778 {
1779  char buf[MAX_LINE_LEN];
1780  static struct GNUNET_IDENTITY_PrivateKey next_zone_key;
1781  static char next_name[GNUNET_DNSPARSER_MAX_NAME_LENGTH];
1782  static int finished = GNUNET_NO;
1783  static int have_next_zonekey = GNUNET_NO;
1784  int zonekey_set = GNUNET_NO;
1785  char *tmp;
1786 
1787 
1788  if (GNUNET_YES == have_next_zonekey)
1789  {
1790  zone_pkey = next_zone_key;
1791  if (NULL != name)
1792  GNUNET_free (name);
1793  name = GNUNET_strdup (next_name);
1794  zonekey_set = GNUNET_YES;
1795  }
1796  while (NULL != fgets (buf, sizeof (buf), stdin))
1797  {
1798  if (1 >= strlen (buf))
1799  continue;
1800  if (buf[strlen (buf) - 1] == '\n')
1801  buf[strlen (buf) - 1] = '\0';
1805  if (buf[strlen (buf) - 1] == ':')
1806  {
1807  memset (next_name, 0, sizeof (next_name));
1808  strncpy (next_name, buf, strlen (buf) - 1);
1809  tmp = strchr (next_name, '.');
1810  if (NULL == tmp)
1811  {
1812  fprintf (stderr, "Error parsing name `%s'\n", next_name);
1814  ret = 1;
1815  return;
1816  }
1817  if (GNUNET_OK != get_identity_for_string (tmp + 1, &next_zone_key))
1818  {
1819  fprintf (stderr, "Error parsing zone name `%s'\n", tmp + 1);
1820  ret = 1;
1822  return;
1823  }
1824  *tmp = '\0';
1825  have_next_zonekey = GNUNET_YES;
1826  /* Run a command for the previous record set */
1827  if (NULL != recordset)
1828  {
1830  return;
1831  }
1832  zone_pkey = next_zone_key;
1833  if (NULL != name)
1834  GNUNET_free (name);
1835  name = GNUNET_strdup (next_name);
1836  zonekey_set = GNUNET_YES;
1837  continue;
1838  }
1839  if (GNUNET_NO == zonekey_set)
1840  {
1841  fprintf (stderr, "Warning, encountered recordline without zone\n");
1842  continue;
1843  }
1845  }
1846  if (GNUNET_NO == finished)
1847  {
1848  if (NULL != recordset)
1849  {
1850  if (GNUNET_YES == zonekey_set)
1851  {
1853  finished = GNUNET_YES;
1854  return;
1855  }
1856  fprintf (stderr, "Warning, encountered recordline without zone\n");
1857  }
1858  }
1860  return;
1861 }
1862 
1863 
1864 static void
1865 begin_cb (void *cls, enum GNUNET_ErrorCode ec)
1866 {
1867  ns_qe = NULL;
1868  if (GNUNET_EC_NONE != ec)
1869  {
1871  "Failed to start transaction: %s\n",
1874  return;
1875  }
1876  if (read_from_stdin)
1877  {
1879  return;
1880  }
1882 }
1883 
1884 
1897 static void
1898 id_connect_cb (void *cls,
1899  struct GNUNET_IDENTITY_Ego *ego,
1900  void **ctx,
1901  const char *name)
1902 {
1904  struct EgoEntry *ego_entry;
1905 
1906  (void) ctx;
1907  (void) name;
1908  if ((NULL != name) && (NULL != ego))
1909  {
1910  ego_entry = GNUNET_new (struct EgoEntry);
1912  ego_entry->ego = ego;
1913  ego_entry->identifier = GNUNET_strdup (name);
1915  ego_tail,
1916  ego_entry);
1917  if ((NULL != ego_name) &&
1918  (0 == strcmp (name, ego_name)))
1920  return;
1921  }
1922  if (NULL != ego)
1923  return;
1925 }
1926 
1927 
1928 
1929 
1930 
1939 static void
1940 run (void *cls,
1941  char *const *args,
1942  const char *cfgfile,
1943  const struct GNUNET_CONFIGURATION_Handle *_cfg)
1944 {
1945  (void) cls;
1946  (void) args;
1947  (void) cfgfile;
1948  cfg = _cfg;
1949  if (NULL != args[0])
1950  GNUNET_log (
1952  _ ("Superfluous command line arguments (starting with `%s') ignored\n"),
1953  args[0]);
1954 
1957  if (NULL == ns)
1958  {
1959  fprintf (stderr, _ ("Failed to connect to namestore\n"));
1961  return;
1962  }
1964  if (NULL == idh)
1965  {
1966  ret = -1;
1967  fprintf (stderr, _ ("Cannot connect to identity service\n"));
1969  }
1970 }
1971 
1972 
1973 
1981 int
1982 main (int argc, char *const *argv)
1983 {
1984  int lret;
1986  { GNUNET_GETOPT_option_flag ('a', "add", gettext_noop ("add record"), &add),
1988  "delete",
1989  gettext_noop ("delete record"),
1990  &del),
1992  "display",
1993  gettext_noop ("display records"),
1994  &list),
1996  "from-stdin",
1997  gettext_noop ("read commands from stdin"),
1998  &read_from_stdin),
2000  'e',
2001  "expiration",
2002  "TIME",
2003  gettext_noop (
2004  "expiration time for record to use (for adding only), \"never\" is possible"),
2005  &expirationstring),
2007  "nick",
2008  "NICKNAME",
2009  gettext_noop (
2010  "set the desired nick name for the zone"),
2011  &nickstring),
2013  "monitor",
2014  gettext_noop (
2015  "monitor changes in the namestore"),
2016  &monitor),
2018  "name",
2019  "NAME",
2020  gettext_noop (
2021  "name of the record to add/delete/display"),
2022  &name),
2024  "recordline",
2025  gettext_noop ("Output in recordline format"),
2028  "zone-to-name",
2029  "KEY",
2030  gettext_noop (
2031  "determine our name for the given KEY"),
2032  &reverse_pkey),
2034  "type",
2035  "TYPE",
2036  gettext_noop (
2037  "type of the record to add/delete/display"),
2038  &typestring),
2040  "uri",
2041  "URI",
2042  gettext_noop ("URI to import into our zone"),
2043  &uri),
2045  "value",
2046  "VALUE",
2047  gettext_noop (
2048  "value of the record to add/delete"),
2049  &value),
2051  "public",
2052  gettext_noop ("create or list public record"),
2053  &is_public),
2055  "omit-private",
2056  gettext_noop ("omit private records"),
2057  &omit_private),
2059  "include-maintenance",
2060  gettext_noop (
2061  "do not filter maintenance records"),
2064  "purge-orphans",
2065  gettext_noop (
2066  "purge namestore of all orphans"),
2067  &purge_orphaned),
2069  "list-orphans",
2070  gettext_noop (
2071  "show private key for orphaned records for recovery using `gnunet-identity -C -P <key>'. Use in combination with --display"),
2072  &list_orphaned),
2074  "purge-zone-records",
2075  gettext_noop (
2076  "delete all records in specified zone"),
2077  &purge_zone),
2079  's',
2080  "shadow",
2081  gettext_noop (
2082  "create shadow record (only valid if all other records of the same type have expired"),
2083  &is_shadow),
2085  "zone",
2086  "EGO",
2087  gettext_noop (
2088  "name of the ego controlling the zone"),
2089  &ego_name),
2091 
2092 
2093  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
2094  return 2;
2095 
2096  is_public = -1;
2097  is_shadow = -1;
2098  GNUNET_log_setup ("gnunet-namestore", "WARNING", NULL);
2099  if (GNUNET_OK !=
2100  (lret = GNUNET_PROGRAM_run (argc,
2101  argv,
2102  "gnunet-namestore",
2103  _ ("GNUnet zone manipulation tool"),
2104  options,
2105  &run,
2106  NULL)))
2107  {
2108  GNUNET_free_nz ((void *) argv);
2109  // FIXME
2110  // GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey);
2111  return lret;
2112  }
2113  GNUNET_free_nz ((void *) argv);
2114  // FIXME
2115  // GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey);
2116  return ret;
2117 }
2118 
2119 
2120 /* 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:562
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1299
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1334
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
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:178
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.