2 This file is part of GNUnet.
3 Copyright (C) 2012, 2013, 2014 GNUnet e.V.
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.
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.
16 * @file gnunet-namestore.c
17 * @brief command line tool to manipulate the local zone
18 * @author Christian Grothoff
24 #include <gnunet_util_lib.h>
25 #include <gnunet_dnsparser_lib.h>
26 #include <gnunet_identity_service.h>
27 #include <gnunet_gnsrecord_lib.h>
28 #include <gnunet_gns_service.h>
29 #include <gnunet_namestore_service.h>
33 * Handle to the namestore.
35 static struct GNUNET_NAMESTORE_Handle *ns;
38 * Private key for the our zone.
40 static struct GNUNET_CRYPTO_EcdsaPrivateKey zone_pkey;
43 * Handle to identity lookup.
45 static struct GNUNET_IDENTITY_EgoLookup *el;
48 * Identity service handle
50 static struct GNUNET_IDENTITY_Handle *idh;
55 struct GNUNET_IDENTITY_Operation *get_default;
58 * Name of the ego controlling the zone.
60 static char *ego_name;
63 * Desired action is to add a record.
68 * Queue entry for the 'add-uri' operation.
70 static struct GNUNET_NAMESTORE_QueueEntry *add_qe_uri;
73 * Queue entry for the 'add' operation.
75 static struct GNUNET_NAMESTORE_QueueEntry *add_qe;
78 * Queue entry for the 'lookup' operation.
80 static struct GNUNET_NAMESTORE_QueueEntry *get_qe;
83 * Queue entry for the 'reverse lookup' operation (in combination with a name).
85 static struct GNUNET_NAMESTORE_QueueEntry *reverse_qe;
88 * Desired action is to list records.
93 * List iterator for the 'list' operation.
95 static struct GNUNET_NAMESTORE_ZoneIterator *list_it;
98 * Desired action is to remove a record.
103 * Is record public (opposite of #GNUNET_GNSRECORD_RF_PRIVATE)
105 static int is_public;
108 * Is record a shadow record (#GNUNET_GNSRECORD_RF_SHADOW_RECORD)
110 static int is_shadow;
113 * Queue entry for the 'del' operation.
115 static struct GNUNET_NAMESTORE_QueueEntry *del_qe;
118 * Name of the records to add/list/remove.
123 * Value of the record to add/remove.
133 * Reverse lookup to perform.
135 static char *reverse_pkey;
138 * Type of the record to add/remove, NULL to remove all.
140 static char *typestring;
143 * Desired expiration time.
145 static char *expirationstring;
150 static char *nickstring;
153 * Global return value
158 * Type string converted to DNS type value.
160 static uint32_t type;
163 * Value in binary format.
168 * Number of bytes in #data.
170 static size_t data_size;
173 * Expirationstring converted to relative time.
175 static struct GNUNET_TIME_Relative etime_rel;
178 * Expirationstring converted to absolute time.
180 static struct GNUNET_TIME_Absolute etime_abs;
183 * Is expiration time relative or absolute time?
185 static int etime_is_rel = GNUNET_SYSERR;
190 static struct GNUNET_NAMESTORE_ZoneMonitor *zm;
193 * Enables monitor mode.
199 * Task run on shutdown. Cleans up everything.
204 do_shutdown (void *cls)
207 if (NULL != get_default)
209 GNUNET_IDENTITY_cancel (get_default);
214 GNUNET_IDENTITY_disconnect (idh);
219 GNUNET_IDENTITY_ego_lookup_cancel (el);
224 GNUNET_NAMESTORE_zone_iteration_stop (list_it);
229 GNUNET_NAMESTORE_cancel (add_qe);
232 if (NULL != add_qe_uri)
234 GNUNET_NAMESTORE_cancel (add_qe_uri);
239 GNUNET_NAMESTORE_cancel (get_qe);
244 GNUNET_NAMESTORE_cancel (del_qe);
249 GNUNET_NAMESTORE_disconnect (ns);
252 memset (&zone_pkey, 0, sizeof (zone_pkey));
260 GNUNET_NAMESTORE_zone_monitor_stop (zm);
272 * Check if we are finished, and if so, perform shutdown.
277 if ( (NULL == add_qe) &&
278 (NULL == add_qe_uri) &&
281 (NULL == reverse_qe) &&
283 GNUNET_SCHEDULER_shutdown ();
288 * Continuation called to notify client about result of the
291 * @param cls closure, location of the QueueEntry pointer to NULL out
292 * @param success #GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate)
293 * #GNUNET_NO if content was already there
294 * #GNUNET_YES (or other positive value) on success
295 * @param emsg NULL on success, otherwise an error message
298 add_continuation (void *cls,
302 struct GNUNET_NAMESTORE_QueueEntry **qe = cls;
305 if (GNUNET_YES != success)
308 _("Adding record failed: %s\n"),
309 (GNUNET_NO == success) ? "record exists" : emsg);
310 if (GNUNET_NO != success)
319 * Continuation called to notify client about result of the
322 * @param cls closure, unused
323 * @param success #GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate)
324 * #GNUNET_NO if content was already there
325 * #GNUNET_YES (or other positive value) on success
326 * @param emsg NULL on success, otherwise an error message
329 del_continuation (void *cls,
335 if (GNUNET_NO == success)
338 _("Deleting record failed, record does not exist%s%s\n"),
339 (NULL != emsg) ? ": " : "",
340 (NULL != emsg) ? emsg : "");
342 if (GNUNET_SYSERR == success)
345 _("Deleting record failed%s%s\n"),
346 (NULL != emsg) ? ": " : "",
347 (NULL != emsg) ? emsg : "");
354 * Function called when we are done with a zone iteration.
357 zone_iteration_finished (void *cls)
366 * Function called when we encountered an error in a zone iteration.
369 zone_iteration_error_cb (void *cls)
374 "Error iterating over zone\n");
381 * Process a record that was stored in the namestore.
383 * @param rname name that is being mapped (at most 255 characters long)
384 * @param rd_len number of entries in @a rd array
385 * @param rd array of records with data to store
388 display_record (const char *rname,
390 const struct GNUNET_GNSRECORD_Data *rd)
392 const char *typestring;
395 struct GNUNET_TIME_Absolute at;
396 struct GNUNET_TIME_Relative rt;
398 if ( (NULL != name) &&
399 (0 != strcmp (name, rname)) )
401 GNUNET_NAMESTORE_zone_iterator_next (list_it,
408 for (unsigned int i=0;i<rd_len;i++)
410 if ( (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) &&
412 GNUNET_GNS_EMPTY_LABEL_AT)) )
414 typestring = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type);
415 s = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
421 _("\tCorrupt or unsupported record of type %u\n"),
422 (unsigned int) rd[i].record_type);
425 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
427 rt.rel_value_us = rd[i].expiration_time;
428 ets = GNUNET_STRINGS_relative_time_to_string (rt, GNUNET_YES);
432 at.abs_value_us = rd[i].expiration_time;
433 ets = GNUNET_STRINGS_absolute_time_to_string (at);
436 "\t%s: %s (%s)\t%s\t%s\n",
440 (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) ? "PRIVATE" : "PUBLIC",
441 (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)) ? "SHADOW" : "");
444 FPRINTF (stdout, "%s", "\n");
449 * Process a record that was stored in the namestore.
452 * @param zone_key private key of the zone
453 * @param rname name that is being mapped (at most 255 characters long)
454 * @param rd_len number of entries in @a rd array
455 * @param rd array of records with data to store
458 display_record_iterator (void *cls,
459 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
462 const struct GNUNET_GNSRECORD_Data *rd)
466 display_record (rname,
469 GNUNET_NAMESTORE_zone_iterator_next (list_it,
475 * Process a record that was stored in the namestore.
478 * @param zone_key private key of the zone
479 * @param rname name that is being mapped (at most 255 characters long)
480 * @param rd_len number of entries in @a rd array
481 * @param rd array of records with data to store
484 display_record_monitor (void *cls,
485 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
488 const struct GNUNET_GNSRECORD_Data *rd)
492 display_record (rname,
495 GNUNET_NAMESTORE_zone_monitor_next (zm,
501 * Process a record that was stored in the namestore.
504 * @param zone_key private key of the zone
505 * @param rname name that is being mapped (at most 255 characters long)
506 * @param rd_len number of entries in @a rd array
507 * @param rd array of records with data to store
510 display_record_lookup (void *cls,
511 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
514 const struct GNUNET_GNSRECORD_Data *rd)
517 display_record (rname,
525 * Function called once we are in sync in monitor mode.
535 "Monitor is now in sync.\n");
540 * Function called on errors while monitoring.
545 monitor_error_cb (void *cls)
550 "Monitor disconnected and out of sync.\n");
555 * Function called on errors while monitoring.
560 lookup_error_cb (void *cls)
566 "Failed to lookup record.\n");
572 * Function called if lookup fails.
575 add_error_cb (void *cls)
586 * We're storing a record; this function is given the existing record
587 * so that we can merge the information.
589 * @param cls closure, unused
590 * @param zone_key private key of the zone
591 * @param rec_name name that is being mapped (at most 255 characters long)
592 * @param rd_count number of entries in @a rd array
593 * @param rd array of records with data to store
596 get_existing_record (void *cls,
597 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
598 const char *rec_name,
599 unsigned int rd_count,
600 const struct GNUNET_GNSRECORD_Data *rd)
602 struct GNUNET_GNSRECORD_Data rdn[rd_count + 1];
603 struct GNUNET_GNSRECORD_Data *rde;
608 if (0 != strcmp (rec_name, name))
616 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
617 "Received %u records for name `%s'\n",
619 for (unsigned int i=0;i<rd_count;i++)
621 switch (rd[i].record_type)
623 case GNUNET_DNSPARSER_TYPE_CNAME:
625 _("A %s record exists already under `%s', no other records can be added.\n"),
631 case GNUNET_GNSRECORD_TYPE_PKEY:
633 _("A %s record exists already under `%s', no other records can be added.\n"),
643 case GNUNET_DNSPARSER_TYPE_CNAME:
647 _("Records already exist under `%s', cannot add `%s' record.\n"),
655 case GNUNET_GNSRECORD_TYPE_PKEY:
659 _("Records already exist under `%s', cannot add `%s' record.\n"),
667 case GNUNET_GNSRECORD_TYPE_GNS2DNS:
668 for (unsigned int i=0;i<rd_count;i++)
669 if (GNUNET_GNSRECORD_TYPE_GNS2DNS != rd[i].record_type)
672 _("Non-GNS2DNS records already exist under `%s', cannot add GNS2DNS record.\n"),
682 sizeof (struct GNUNET_GNSRECORD_Data));
683 GNUNET_memcpy (&rdn[1],
685 rd_count * sizeof (struct GNUNET_GNSRECORD_Data));
688 rde->data_size = data_size;
689 rde->record_type = type;
691 rde->flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD;
693 rde->flags |= GNUNET_GNSRECORD_RF_PRIVATE;
694 if (GNUNET_YES == etime_is_rel)
696 rde->expiration_time = etime_rel.rel_value_us;
697 rde->flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
699 else if (GNUNET_NO == etime_is_rel)
700 rde->expiration_time = etime_abs.abs_value_us;
702 rde->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
703 GNUNET_assert (NULL != name);
704 add_qe = GNUNET_NAMESTORE_records_store (ns,
715 * Function called if we encountered an error in zone-to-name.
718 reverse_error_cb (void *cls)
729 * Function called with the result of our attempt to obtain a name for a given
733 * @param zone private key of the zone; NULL on disconnect
734 * @param label label of the records; NULL on disconnect
735 * @param rd_count number of entries in @a rd array, 0 if label was deleted
736 * @param rd array of records with data to store
739 handle_reverse_lookup (void *cls,
740 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
742 unsigned int rd_count,
743 const struct GNUNET_GNSRECORD_Data *rd)
763 * Function called if lookup for deletion fails.
766 del_lookup_error_cb (void *cls)
777 * We were asked to delete something; this function is called with
778 * the existing records. Now we should determine what should be
779 * deleted and then issue the deletion operation.
782 * @param zone private key of the zone we are deleting from
783 * @param label name of the records we are editing
784 * @param rd_count size of the @a rd array
785 * @param rd existing records
788 del_monitor (void *cls,
789 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
791 unsigned int rd_count,
792 const struct GNUNET_GNSRECORD_Data *rd)
794 struct GNUNET_GNSRECORD_Data rdx[rd_count];
795 unsigned int rd_left;
805 _("There are no records under label `%s' that could be deleted.\n"),
811 if ( (NULL == value) &&
812 (NULL == typestring) )
814 /* delete everything */
815 del_qe = GNUNET_NAMESTORE_records_store (ns,
825 if (NULL != typestring)
826 type = GNUNET_GNSRECORD_typename_to_number (typestring);
828 type = GNUNET_GNSRECORD_TYPE_ANY;
829 for (unsigned int i=0;i<rd_count;i++)
832 if (! ( ( (GNUNET_GNSRECORD_TYPE_ANY == type) ||
833 (rd[i].record_type == type) ) &&
835 (NULL == (vs = (GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
837 rd[i].data_size)))) ||
838 (0 == strcmp (vs, value)) ) ) )
839 rdx[rd_left++] = rd[i];
840 GNUNET_free_non_null (vs);
842 if (rd_count == rd_left)
844 /* nothing got deleted */
846 _("There are no records under label `%s' that match the request for deletion.\n"),
851 /* delete everything but what we copied to 'rdx' */
852 del_qe = GNUNET_NAMESTORE_records_store (ns,
863 * Callback invoked from identity service with ego information.
864 * An @a ego of NULL means the ego was not found.
866 * @param cls closure with the configuration
867 * @param ego an ego known to identity service, or NULL
870 identity_cb (void *cls,
871 const struct GNUNET_IDENTITY_Ego *ego)
873 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
874 struct GNUNET_CRYPTO_EcdsaPublicKey pub;
875 struct GNUNET_GNSRECORD_Data rd;
880 if (NULL != ego_name)
883 _("Ego `%s' not known to identity service\n"),
886 GNUNET_SCHEDULER_shutdown ();
890 zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego);
891 GNUNET_free_non_null (ego_name);
894 if (! (add|del|list|(NULL != nickstring)|(NULL != uri)|(NULL != reverse_pkey)) )
896 /* nothing more to be done */
898 _("No options given\n"));
899 GNUNET_SCHEDULER_shutdown ();
902 GNUNET_CRYPTO_ecdsa_key_get_public (&zone_pkey,
905 ns = GNUNET_NAMESTORE_connect (cfg);
908 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
909 _("Failed to connect to namestore\n"));
917 _("Missing option `%s' for operation `%s'\n"),
919 GNUNET_SCHEDULER_shutdown ();
923 if (NULL == typestring)
926 _("Missing option `%s' for operation `%s'\n"),
928 GNUNET_SCHEDULER_shutdown ();
932 type = GNUNET_GNSRECORD_typename_to_number (typestring);
933 if (UINT32_MAX == type)
936 _("Unsupported type `%s'\n"),
938 GNUNET_SCHEDULER_shutdown ();
945 _("Missing option `%s' for operation `%s'\n"),
948 GNUNET_SCHEDULER_shutdown ();
952 GNUNET_GNSRECORD_string_to_value (type,
958 _("Value `%s' invalid for record type `%s'\n"),
961 GNUNET_SCHEDULER_shutdown ();
965 if (NULL == expirationstring)
968 _("Missing option `%s' for operation `%s'\n"),
971 GNUNET_SCHEDULER_shutdown ();
975 if (0 == strcmp (expirationstring,
978 etime_abs = GNUNET_TIME_UNIT_FOREVER_ABS;
979 etime_is_rel = GNUNET_NO;
981 else if (GNUNET_OK ==
982 GNUNET_STRINGS_fancy_time_to_relative (expirationstring,
985 etime_is_rel = GNUNET_YES;
986 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
987 "Storing record with relative expiration time of %s\n",
988 GNUNET_STRINGS_relative_time_to_string (etime_rel,
991 else if (GNUNET_OK ==
992 GNUNET_STRINGS_fancy_time_to_absolute (expirationstring,
995 etime_is_rel = GNUNET_NO;
996 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
997 "Storing record with absolute expiration time of %s\n",
998 GNUNET_STRINGS_absolute_time_to_string (etime_abs));
1003 _("Invalid time format `%s'\n"),
1005 GNUNET_SCHEDULER_shutdown ();
1009 add_qe = GNUNET_NAMESTORE_records_lookup (ns,
1014 &get_existing_record,
1022 _("Missing option `%s' for operation `%s'\n"),
1024 GNUNET_SCHEDULER_shutdown ();
1028 del_qe = GNUNET_NAMESTORE_records_lookup (ns,
1031 &del_lookup_error_cb,
1039 get_qe = GNUNET_NAMESTORE_records_lookup (ns,
1044 &display_record_lookup,
1047 list_it = GNUNET_NAMESTORE_zone_iteration_start (ns,
1049 &zone_iteration_error_cb,
1051 &display_record_iterator,
1053 &zone_iteration_finished,
1056 if (NULL != reverse_pkey)
1058 struct GNUNET_CRYPTO_EcdsaPublicKey pubkey;
1061 GNUNET_CRYPTO_ecdsa_public_key_from_string (reverse_pkey,
1062 strlen (reverse_pkey),
1066 _("Invalid public key for reverse lookup `%s'\n"),
1068 GNUNET_SCHEDULER_shutdown ();
1070 reverse_qe = GNUNET_NAMESTORE_zone_to_name (ns,
1075 &handle_reverse_lookup,
1082 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
1084 GNUNET_STRINGS_utf8_tolower (uri, uri);
1085 if ( (2 != (sscanf (uri,
1086 "gnunet://gns/%52s/%63s",
1090 GNUNET_CRYPTO_ecdsa_public_key_from_string (sh,
1095 _("Invalid URI `%s'\n"),
1097 GNUNET_SCHEDULER_shutdown ();
1101 memset (&rd, 0, sizeof (rd));
1103 rd.data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
1104 rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY;
1105 if (GNUNET_YES == etime_is_rel)
1107 rd.expiration_time = etime_rel.rel_value_us;
1108 rd.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1110 else if (GNUNET_NO == etime_is_rel)
1111 rd.expiration_time = etime_abs.abs_value_us;
1113 rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
1116 rd.flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD;
1117 add_qe_uri = GNUNET_NAMESTORE_records_store (ns,
1125 if (NULL != nickstring)
1127 if (0 == strlen(nickstring))
1130 _("Invalid nick `%s'\n"),
1132 GNUNET_SCHEDULER_shutdown ();
1136 add_qe_uri = GNUNET_NAMESTORE_set_nick (ns,
1144 zm = GNUNET_NAMESTORE_zone_monitor_start (cfg,
1149 &display_record_monitor,
1158 default_ego_cb (void *cls,
1159 struct GNUNET_IDENTITY_Ego *ego,
1170 _("No default ego configured in identity service\n"));
1171 GNUNET_SCHEDULER_shutdown ();
1177 identity_cb (cls, ego);
1183 id_connect_cb (void *cls,
1184 struct GNUNET_IDENTITY_Ego *ego,
1188 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
1195 get_default = GNUNET_IDENTITY_get (idh,
1204 * Main function that will be run.
1206 * @param cls closure
1207 * @param args remaining command-line arguments
1208 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
1209 * @param cfg configuration
1214 const char *cfgfile,
1215 const struct GNUNET_CONFIGURATION_Handle *cfg)
1220 if ( (NULL != args[0]) &&
1222 uri = GNUNET_strdup (args[0]);
1224 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
1227 if (NULL == ego_name)
1229 idh = GNUNET_IDENTITY_connect (cfg,
1234 _("Cannot connect to identity service\n"));
1238 el = GNUNET_IDENTITY_ego_lookup (cfg,
1246 * The main function for gnunet-namestore.
1248 * @param argc number of arguments from the command line
1249 * @param argv command line arguments
1250 * @return 0 ok, 1 on error
1256 struct GNUNET_GETOPT_CommandLineOption options[] = {
1257 GNUNET_GETOPT_option_flag ('a',
1259 gettext_noop ("add record"),
1261 GNUNET_GETOPT_option_flag ('d',
1263 gettext_noop ("delete record"),
1265 GNUNET_GETOPT_option_flag ('D',
1267 gettext_noop ("display records"),
1269 GNUNET_GETOPT_option_string ('e',
1272 gettext_noop ("expiration time for record to use (for adding only), \"never\" is possible"),
1274 GNUNET_GETOPT_option_string ('i',
1277 gettext_noop ("set the desired nick name for the zone"),
1279 GNUNET_GETOPT_option_flag ('m',
1281 gettext_noop ("monitor changes in the namestore"),
1283 GNUNET_GETOPT_option_string ('n',
1286 gettext_noop ("name of the record to add/delete/display"),
1288 GNUNET_GETOPT_option_string ('r',
1291 gettext_noop ("determine our name for the given PKEY"),
1293 GNUNET_GETOPT_option_string ('t',
1296 gettext_noop ("type of the record to add/delete/display"),
1298 GNUNET_GETOPT_option_string ('u',
1301 gettext_noop ("URI to import into our zone"),
1303 GNUNET_GETOPT_option_string ('V',
1306 gettext_noop ("value of the record to add/delete"),
1308 GNUNET_GETOPT_option_flag ('p',
1310 gettext_noop ("create or list public record"),
1312 GNUNET_GETOPT_option_flag ('s',
1314 gettext_noop ("create shadow record (only valid if all other records of the same type have expired"),
1316 GNUNET_GETOPT_option_string ('z',
1319 gettext_noop ("name of the ego controlling the zone"),
1321 GNUNET_GETOPT_OPTION_END
1325 GNUNET_STRINGS_get_utf8_args (argc, argv,
1331 GNUNET_log_setup ("gnunet-namestore",
1335 GNUNET_PROGRAM_run (argc,
1338 _("GNUnet zone manipulation tool"),
1342 GNUNET_free ((void*) argv);
1343 GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey);
1346 GNUNET_free ((void*) argv);
1347 GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey);
1351 /* end of gnunet-namestore.c */