aboutsummaryrefslogtreecommitdiff
path: root/src/namestore/gnunet-namestore.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/namestore/gnunet-namestore.c')
-rw-r--r--src/namestore/gnunet-namestore.c402
1 files changed, 312 insertions, 90 deletions
diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c
index a0d1de1..a79ec5e 100644
--- a/src/namestore/gnunet-namestore.c
+++ b/src/namestore/gnunet-namestore.c
@@ -32,6 +32,12 @@
#include <gnunet_dnsparser_lib.h>
#include <gnunet_namestore_service.h>
+
+/**
+ * Hostkey generation context
+ */
+struct GNUNET_CRYPTO_RsaKeyGenerationContext * keygen;
+
/**
* Handle to the namestore.
*/
@@ -63,6 +69,11 @@ static int add;
static struct GNUNET_NAMESTORE_QueueEntry *add_qe;
/**
+ * Queue entry for the 'add-uri' operation.
+ */
+static struct GNUNET_NAMESTORE_QueueEntry *add_qe_uri;
+
+/**
* Desired action is to list records.
*/
static int list;
@@ -103,6 +114,11 @@ static char *name;
static char *value;
/**
+ * URI to import.
+ */
+static char *uri;
+
+/**
* Type of the record to add/remove, NULL to remove all.
*/
static char *typestring;
@@ -112,6 +128,11 @@ static char *typestring;
*/
static char *expirationstring;
+/**
+ * Global return value
+ */
+static int ret;
+
/**
* Task run on shutdown. Cleans up everything.
@@ -123,9 +144,35 @@ static void
do_shutdown (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
+ if (NULL != keygen)
+ {
+ GNUNET_CRYPTO_rsa_key_create_stop (keygen);
+ keygen = NULL;
+ }
+
+ if (NULL != list_it)
+ {
+ GNUNET_NAMESTORE_zone_iteration_stop (list_it);
+ list_it = NULL;
+ }
+ if (NULL != add_qe)
+ {
+ GNUNET_NAMESTORE_cancel (add_qe);
+ add_qe = NULL;
+ }
+ if (NULL != add_qe_uri)
+ {
+ GNUNET_NAMESTORE_cancel (add_qe_uri);
+ add_qe_uri = NULL;
+ }
+ if (NULL != del_qe)
+ {
+ GNUNET_NAMESTORE_cancel (del_qe);
+ del_qe = NULL;
+ }
if (NULL != ns)
{
- GNUNET_NAMESTORE_disconnect (ns, GNUNET_NO);
+ GNUNET_NAMESTORE_disconnect (ns);
ns = NULL;
}
if (NULL != zone_pkey)
@@ -133,6 +180,11 @@ do_shutdown (void *cls,
GNUNET_CRYPTO_rsa_key_free (zone_pkey);
zone_pkey = NULL;
}
+ if (NULL != uri)
+ {
+ GNUNET_free (uri);
+ uri = NULL;
+ }
}
@@ -140,7 +192,7 @@ do_shutdown (void *cls,
* Continuation called to notify client about result of the
* operation.
*
- * @param cls closure, unused
+ * @param cls closure, location of the QueueEntry pointer to NULL out
* @param success GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate)
* GNUNET_NO if content was already there
* GNUNET_YES (or other positive value) on success
@@ -151,12 +203,20 @@ add_continuation (void *cls,
int32_t success,
const char *emsg)
{
- add_qe = NULL;
- if (success != GNUNET_YES)
+ struct GNUNET_NAMESTORE_QueueEntry **qe = cls;
+
+ *qe = NULL;
+ if (GNUNET_YES != success)
+ {
fprintf (stderr,
_("Adding record failed: %s\n"),
- (success == GNUNET_NO) ? "record exists" : emsg);
- if ( (NULL == del_qe) &&
+ (GNUNET_NO == success) ? "record exists" : emsg);
+ if (GNUNET_NO != success)
+ ret = 1;
+ }
+ if ( (NULL == add_qe) &&
+ (NULL == add_qe_uri) &&
+ (NULL == del_qe) &&
(NULL == list_it) )
GNUNET_SCHEDULER_shutdown ();
}
@@ -183,6 +243,7 @@ del_continuation (void *cls,
_("Deleting record failed: %s\n"),
emsg);
if ( (NULL == add_qe) &&
+ (NULL == add_qe_uri) &&
(NULL == list_it) )
GNUNET_SCHEDULER_shutdown ();
}
@@ -216,11 +277,15 @@ display_record (void *cls,
const char *typestring;
char *s;
unsigned int i;
+ const char *etime;
+ struct GNUNET_TIME_Absolute aex;
+ struct GNUNET_TIME_Relative rex;
if (NULL == name)
{
list_it = NULL;
if ( (NULL == del_qe) &&
+ (NULL == add_qe_uri) &&
(NULL == add_qe) )
GNUNET_SCHEDULER_shutdown ();
return;
@@ -240,51 +305,51 @@ display_record (void *cls,
(unsigned int) rd[i].record_type);
continue;
}
- FPRINTF (stdout, "\t%s: %s\n", typestring, s);
+ if (0 != (rd[i].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION))
+ {
+ rex.rel_value = rd[i].expiration_time;
+ etime = GNUNET_STRINGS_relative_time_to_string (rex, GNUNET_YES);
+ }
+ else
+ {
+ aex.abs_value = rd[i].expiration_time;
+ etime = GNUNET_STRINGS_absolute_time_to_string (aex);
+ }
+ FPRINTF (stdout, "\t%s: %s (%s %s)\n", typestring, s,
+ (0 != (rd[i].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION))
+ ? _(/* what follows is relative expiration */ "for at least")
+ : _(/* what follows is absolute expiration */ "until"),
+ etime);
GNUNET_free (s);
}
FPRINTF (stdout, "%s", "\n");
GNUNET_NAMESTORE_zone_iterator_next (list_it);
}
-
-/**
- * Main function that will be run.
- *
- * @param cls closure
- * @param args remaining command-line arguments
- * @param cfgfile name of the configuration file used (for saving, can be NULL!)
- * @param cfg configuration
- */
static void
-run (void *cls, char *const *args, const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
+key_generation_cb (void *cls,
+ struct GNUNET_CRYPTO_RsaPrivateKey *pk,
+ const char *emsg)
{
+ struct GNUNET_CONFIGURATION_Handle *cfg = cls;
struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
uint32_t type;
void *data = NULL;
size_t data_size = 0;
- struct GNUNET_TIME_Relative etime;
+ struct GNUNET_TIME_Relative etime_rel;
+ struct GNUNET_TIME_Absolute etime_abs;
+ int etime_is_rel = GNUNET_SYSERR;
struct GNUNET_NAMESTORE_RecordData rd;
- if (NULL == keyfile)
+ keygen = NULL;
+ if (NULL == pk)
{
- if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
- "ZONEKEY", &keyfile))
- {
- fprintf (stderr,
- _("Option `%s' not given, but I need a zone key file!\n"),
- "z");
- return;
- }
- fprintf (stderr,
- _("Using default zone file `%s'\n"),
- keyfile);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
}
- zone_pkey = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
- GNUNET_free (keyfile);
- keyfile = NULL;
- if (! (add|del|list))
+ zone_pkey = pk;
+
+ if (! (add|del|list|(NULL != uri)))
{
/* nothing more to be done */
fprintf (stderr,
@@ -296,22 +361,22 @@ run (void *cls, char *const *args, const char *cfgfile,
if (NULL == zone_pkey)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("Failed to read or create private zone key\n"));
+ _("Failed to read or create private zone key\n"));
return;
}
GNUNET_CRYPTO_rsa_key_get_public (zone_pkey,
- &pub);
+ &pub);
GNUNET_CRYPTO_short_hash (&pub, sizeof (pub), &zone);
ns = GNUNET_NAMESTORE_connect (cfg);
if (NULL == ns)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("Failed to connect to namestore\n"));
+ _("Failed to connect to namestore\n"));
return;
}
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
- &do_shutdown, NULL);
+ &do_shutdown, NULL);
if (NULL == typestring)
type = 0;
else
@@ -320,35 +385,39 @@ run (void *cls, char *const *args, const char *cfgfile,
{
fprintf (stderr, _("Unsupported type `%s'\n"), typestring);
GNUNET_SCHEDULER_shutdown ();
+ ret = 1;
return;
}
if ((NULL == typestring) && (add | del))
{
fprintf (stderr,
- _("Missing option `%s' for operation `%s'\n"),
- "-t", _("add/del"));
+ _("Missing option `%s' for operation `%s'\n"),
+ "-t", _("add/del"));
GNUNET_SCHEDULER_shutdown ();
+ ret = 1;
return;
}
if (NULL != value)
{
if (GNUNET_OK !=
- GNUNET_NAMESTORE_string_to_value (type,
- value,
- &data,
- &data_size))
+ GNUNET_NAMESTORE_string_to_value (type,
+ value,
+ &data,
+ &data_size))
{
- fprintf (stderr, _("Value `%s' invalid for record type `%s'\n"),
- value,
- typestring);
- GNUNET_SCHEDULER_shutdown ();
- return;
+ fprintf (stderr, _("Value `%s' invalid for record type `%s'\n"),
+ value,
+ typestring);
+ GNUNET_SCHEDULER_shutdown ();
+ ret = 1;
+ return;
}
} else if (add | del)
{
fprintf (stderr,
- _("Missing option `%s' for operation `%s'\n"),
- "-V", _("add/del"));
+ _("Missing option `%s' for operation `%s'\n"),
+ "-V", _("add/del"));
+ ret = 1;
GNUNET_SCHEDULER_shutdown ();
return;
}
@@ -356,72 +425,115 @@ run (void *cls, char *const *args, const char *cfgfile,
{
if (0 == strcmp (expirationstring, "never"))
{
- etime = GNUNET_TIME_UNIT_FOREVER_REL;
+ etime_abs = GNUNET_TIME_UNIT_FOREVER_ABS;
+ etime_is_rel = GNUNET_NO;
+ }
+ else if (GNUNET_OK ==
+ GNUNET_STRINGS_fancy_time_to_relative (expirationstring,
+ &etime_rel))
+ {
+ etime_is_rel = GNUNET_YES;
+ }
+ else if (GNUNET_OK ==
+ GNUNET_STRINGS_fancy_time_to_absolute (expirationstring,
+ &etime_abs))
+ {
+ etime_is_rel = GNUNET_NO;
}
- else if (GNUNET_OK !=
- GNUNET_STRINGS_fancy_time_to_relative (expirationstring,
- &etime))
+ else
{
fprintf (stderr,
- _("Invalid time format `%s'\n"),
- expirationstring);
+ _("Invalid time format `%s'\n"),
+ expirationstring);
GNUNET_SCHEDULER_shutdown ();
+ ret = 1;
return;
}
- } else if (add)
+ if (etime_is_rel && del)
+ {
+ fprintf (stderr,
+ _("Deletion requires either absolute time, or no time at all. Got relative time `%s' instead.\n"),
+ expirationstring);
+ GNUNET_SCHEDULER_shutdown ();
+ ret = 1;
+ return;
+ }
+ }
+ else if (add)
{
fprintf (stderr,
- _("Missing option `%s' for operation `%s'\n"),
- "-e", _("add"));
+ _("Missing option `%s' for operation `%s'\n"),
+ "-e", _("add"));
GNUNET_SCHEDULER_shutdown ();
+ ret = 1;
return;
}
+ memset (&rd, 0, sizeof (rd));
if (add)
{
if (NULL == name)
{
fprintf (stderr,
- _("Missing option `%s' for operation `%s'\n"),
- "-n", _("add"));
+ _("Missing option `%s' for operation `%s'\n"),
+ "-n", _("add"));
GNUNET_SCHEDULER_shutdown ();
+ ret = 1;
return;
}
rd.data = data;
rd.data_size = data_size;
rd.record_type = type;
- rd.expiration = GNUNET_TIME_relative_to_absolute (etime);
+ if (GNUNET_YES == etime_is_rel)
+ {
+ rd.expiration_time = etime_rel.rel_value;
+ rd.flags |= GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION;
+ }
+ else if (GNUNET_NO == etime_is_rel)
+ rd.expiration_time = etime_abs.abs_value;
+ else
+ {
+ fprintf (stderr,
+ _("No valid expiration time for operation `%s'\n"),
+ _("add"));
+ GNUNET_SCHEDULER_shutdown ();
+ ret = 1;
+ return;
+ }
if (1 != nonauthority)
rd.flags |= GNUNET_NAMESTORE_RF_AUTHORITY;
if (1 != public)
rd.flags |= GNUNET_NAMESTORE_RF_PRIVATE;
add_qe = GNUNET_NAMESTORE_record_create (ns,
- zone_pkey,
- name,
- &rd,
- &add_continuation,
- NULL);
+ zone_pkey,
+ name,
+ &rd,
+ &add_continuation,
+ &add_qe);
}
if (del)
{
if (NULL == name)
{
fprintf (stderr,
- _("Missing option `%s' for operation `%s'\n"),
- "-n", _("del"));
+ _("Missing option `%s' for operation `%s'\n"),
+ "-n", _("del"));
GNUNET_SCHEDULER_shutdown ();
+ ret = 1;
return;
}
rd.data = data;
rd.data_size = data_size;
rd.record_type = type;
- rd.expiration.abs_value = 0;
+ rd.expiration_time = 0;
+ if (!etime_is_rel)
+ rd.expiration_time = etime_abs.abs_value;
rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
del_qe = GNUNET_NAMESTORE_record_remove (ns,
- zone_pkey,
- name,
- &rd,
- &del_continuation,
- NULL);
+ zone_pkey,
+ name,
+ &rd,
+ &del_continuation,
+ NULL);
}
if (list)
{
@@ -434,13 +546,116 @@ run (void *cls, char *const *args, const char *cfgfile,
must_not_flags |= GNUNET_NAMESTORE_RF_PRIVATE;
list_it = GNUNET_NAMESTORE_zone_iteration_start (ns,
- &zone,
- 0,
- must_not_flags,
- &display_record,
- NULL);
+ &zone,
+ GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION,
+ must_not_flags,
+ &display_record,
+ NULL);
+ }
+ if (NULL != uri)
+ {
+ char sh[53];
+ char name[64];
+ struct GNUNET_CRYPTO_ShortHashCode sc;
+
+ if ( (2 != (sscanf (uri,
+ "gnunet://gns/%52s/%63s",
+ sh,
+ name)) ) ||
+ (GNUNET_OK !=
+ GNUNET_CRYPTO_short_hash_from_string (sh, &sc)) )
+ {
+ fprintf (stderr,
+ _("Invalid URI `%s'\n"),
+ uri);
+ GNUNET_SCHEDULER_shutdown ();
+ ret = 1;
+ return;
+ }
+ rd.data = &sc;
+ rd.data_size = sizeof (struct GNUNET_CRYPTO_ShortHashCode);
+ rd.record_type = GNUNET_NAMESTORE_TYPE_PKEY;
+ if (GNUNET_YES == etime_is_rel)
+ {
+ rd.expiration_time = etime_rel.rel_value;
+ rd.flags |= GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION;
+ }
+ else if (GNUNET_NO == etime_is_rel)
+ rd.expiration_time = etime_abs.abs_value;
+ else
+ rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value;
+ if (1 != nonauthority)
+ rd.flags |= GNUNET_NAMESTORE_RF_AUTHORITY;
+
+ add_qe_uri = GNUNET_NAMESTORE_record_create (ns,
+ zone_pkey,
+ name,
+ &rd,
+ &add_continuation,
+ &add_qe_uri);
}
GNUNET_free_non_null (data);
+
+}
+
+
+static void
+testservice_task (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct GNUNET_CONFIGURATION_Handle *cfg = cls;
+
+ if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
+ {
+ FPRINTF (stderr, _("Service `%s' is not running\n"), "namestore");
+ return;
+ }
+
+
+ if (NULL == keyfile)
+ {
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
+ "ZONEKEY", &keyfile))
+ {
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ "gns", "ZONEKEY");
+ return;
+ }
+ fprintf (stderr,
+ _("Using default zone file `%s'\n"),
+ keyfile);
+ }
+ keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, key_generation_cb, cfg);
+ GNUNET_free (keyfile);
+ keyfile = NULL;
+ if (NULL == keygen)
+ {
+ GNUNET_SCHEDULER_shutdown ();
+ ret = 1;
+ }
+}
+
+
+/**
+ * Main function that will be run.
+ *
+ * @param cls closure
+ * @param args remaining command-line arguments
+ * @param cfgfile name of the configuration file used (for saving, can be NULL!)
+ * @param cfg configuration
+ */
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+
+ if ( (NULL != args[0]) && (NULL == uri) )
+ uri = GNUNET_strdup (args[0]);
+
+ GNUNET_CLIENT_service_test ("namestore", cfg,
+ GNUNET_TIME_UNIT_SECONDS,
+ &testservice_task,
+ (void *) cfg);
}
@@ -476,6 +691,9 @@ main (int argc, char *const *argv)
{'t', "type", "TYPE",
gettext_noop ("type of the record to add/delete/display"), 1,
&GNUNET_GETOPT_set_string, &typestring},
+ {'u', "uri", "URI",
+ gettext_noop ("URI to import into our zone"), 1,
+ &GNUNET_GETOPT_set_string, &uri},
{'V', "value", "VALUE",
gettext_noop ("value of the record to add/delete"), 1,
&GNUNET_GETOPT_set_string, &value},
@@ -491,16 +709,20 @@ main (int argc, char *const *argv)
GNUNET_GETOPT_OPTION_END
};
- int ret;
+ if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
+ return 2;
GNUNET_log_setup ("gnunet-namestore", "WARNING", NULL);
- ret =
- (GNUNET_OK ==
- GNUNET_PROGRAM_run (argc, argv, "gnunet-namestore",
- _("GNUnet zone manipulation tool"),
- options,
- &run, NULL)) ? 0 : 1;
-
+ if (GNUNET_OK !=
+ GNUNET_PROGRAM_run (argc, argv, "gnunet-namestore",
+ _("GNUnet zone manipulation tool"),
+ options,
+ &run, NULL))
+ {
+ GNUNET_free ((void*) argv);
+ return 1;
+ }
+ GNUNET_free ((void*) argv);
return ret;
}