/*
This file is part of GNUnet.
- (C) 2012-2013 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2012-2014 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
*/
/**
* @file gnunet-namestore-fcfsd.c
/**
* Associated session.
*/
- struct Session *session;
+ // FIXME: struct Session *session;
/**
* Post processor handling form data (IF this is
*/
struct GNUNET_NAMESTORE_QueueEntry *qe;
+ /**
+ * Active iteration with the namestore.
+ */
+ struct GNUNET_NAMESTORE_ZoneIterator *zi;
+
/**
* Current processing phase.
*/
*/
char public_key[128];
+ struct GNUNET_CRYPTO_EcdsaPublicKey pub;
+
};
/**
/**
* Main HTTP task.
*/
-static GNUNET_SCHEDULER_TaskIdentifier httpd_task;
+static struct GNUNET_SCHEDULER_Task * httpd_task;
/**
* Handle to the namestore.
* Task run whenever HTTP server operations are pending.
*
* @param cls unused
- * @param tc scheduler context
*/
static void
-do_httpd (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc);
+do_httpd (void *cls);
/**
static void
run_httpd_now ()
{
- if (GNUNET_SCHEDULER_NO_TASK != httpd_task)
+ if (NULL != httpd_task)
{
GNUNET_SCHEDULER_cancel (httpd_task);
- httpd_task = GNUNET_SCHEDULER_NO_TASK;
+ httpd_task = NULL;
}
httpd_task = GNUNET_SCHEDULER_add_now (&do_httpd, NULL);
}
+/**
+ * Function called on error in zone iteration.
+ */
static void
-iterate_cb (void *cls,
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
- const char *name,
- unsigned int rd_len,
- const struct GNUNET_GNSRECORD_Data *rd)
+zone_iteration_error (void *cls)
+{
+ struct ZoneinfoRequest *zr = cls;
+ struct MHD_Response *response;
+
+ zr->list_it = NULL;
+ response = MHD_create_response_from_buffer (strlen ("internal error"),
+ (void *) "internal error",
+ MHD_RESPMEM_PERSISTENT);
+ MHD_queue_response (zr->connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ response);
+ MHD_destroy_response (response);
+ GNUNET_free (zr->zoneinfo);
+ GNUNET_free (zr);
+ run_httpd_now ();
+}
+
+
+/**
+ * Function called once the zone iteration is done.
+ */
+static void
+zone_iteration_end (void *cls)
{
struct ZoneinfoRequest *zr = cls;
struct MHD_Response *response;
char* full_page;
- size_t bytes_free;
- char* pkey;
- char* new_buf;
+ zr->list_it = NULL;
- if (NULL == name)
- {
- zr->list_it = NULL;
-
- /* return static form */
- GNUNET_asprintf (&full_page,
- ZONEINFO_PAGE,
- zr->zoneinfo,
- zr->zoneinfo);
- response = MHD_create_response_from_buffer (strlen (full_page),
+ /* return static form */
+ GNUNET_asprintf (&full_page,
+ ZONEINFO_PAGE,
+ zr->zoneinfo,
+ zr->zoneinfo);
+ response = MHD_create_response_from_buffer (strlen (full_page),
(void *) full_page,
MHD_RESPMEM_MUST_FREE);
- MHD_add_response_header (response,
+ MHD_add_response_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
MIME_HTML);
- MHD_queue_response (zr->connection,
- MHD_HTTP_OK,
- response);
- MHD_destroy_response (response);
- GNUNET_free (zr->zoneinfo);
- GNUNET_free (zr);
- run_httpd_now ();
- return;
- }
+ MHD_queue_response (zr->connection,
+ MHD_HTTP_OK,
+ response);
+ MHD_destroy_response (response);
+ GNUNET_free (zr->zoneinfo);
+ GNUNET_free (zr);
+ run_httpd_now ();
+}
+
+
+/**
+ * Process a record that was stored in the namestore, adding
+ * the information to the HTML.
+ *
+ * @param cls closure with the `struct ZoneinfoRequest *`
+ * @param zone_key private key of the zone; NULL on disconnect
+ * @param name label of the records; NULL on disconnect
+ * @param rd_len number of entries in @a rd array, 0 if label was deleted
+ * @param rd array of records with data to store
+ */
+static void
+iterate_cb (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
+ const char *name,
+ unsigned int rd_len,
+ const struct GNUNET_GNSRECORD_Data *rd)
+{
+ struct ZoneinfoRequest *zr = cls;
+ size_t bytes_free;
+ char* pkey;
+ char* new_buf;
if (1 != rd_len)
{
- GNUNET_NAMESTORE_zone_iterator_next (zr->list_it);
+ GNUNET_NAMESTORE_zone_iterator_next (zr->list_it,
+ 1);
return;
}
if (GNUNET_GNSRECORD_TYPE_PKEY != rd->record_type)
{
- GNUNET_NAMESTORE_zone_iterator_next (zr->list_it);
+ GNUNET_NAMESTORE_zone_iterator_next (zr->list_it,
+ 1);
return;
}
pkey = GNUNET_GNSRECORD_value_to_string (rd->record_type,
rd->data,
rd->data_size);
-
+ if (NULL == pkey)
+ {
+ GNUNET_break (0);
+ GNUNET_NAMESTORE_zone_iterator_next (zr->list_it,
+ 1);
+ return;
+ }
if (bytes_free < (strlen (name) + strlen (pkey) + 40))
{
new_buf = GNUNET_malloc (zr->buf_len * 2);
- memcpy (new_buf, zr->zoneinfo, zr->write_offset);
+ GNUNET_memcpy (new_buf, zr->zoneinfo, zr->write_offset);
GNUNET_free (zr->zoneinfo);
zr->zoneinfo = new_buf;
zr->buf_len *= 2;
name,
pkey);
zr->write_offset = strlen (zr->zoneinfo);
- GNUNET_NAMESTORE_zone_iterator_next (zr->list_it);
+ GNUNET_NAMESTORE_zone_iterator_next (zr->list_it,
+ 1);
GNUNET_free (pkey);
}
-
/**
* Handler that returns FCFS zoneinfo page.
*
zr->write_offset = 0;
zr->list_it = GNUNET_NAMESTORE_zone_iteration_start (ns,
&fcfs_zone_pkey,
+ &zone_iteration_error,
+ zr,
&iterate_cb,
- zr);
+ zr,
+ &zone_iteration_end,
+ zr);
return MHD_YES;
}
const char *filename,
const char *content_type,
const char *transfer_encoding,
- const char *data, uint64_t off, size_t size)
+ const char *data,
+ uint64_t off,
+ size_t size)
{
struct Request *request = cls;
+ (void) kind;
+ (void) filename;
+ (void) content_type;
+ (void) transfer_encoding;
if (0 == strcmp ("domain", key))
{
if (size + off >= sizeof(request->domain_name))
size = sizeof (request->domain_name) - off - 1;
- memcpy (&request->domain_name[off],
+ GNUNET_memcpy (&request->domain_name[off],
data,
size);
request->domain_name[size+off] = '\0';
{
if (size + off >= sizeof(request->public_key))
size = sizeof (request->public_key) - off - 1;
- memcpy (&request->public_key[off],
+ GNUNET_memcpy (&request->public_key[off],
data,
size);
request->public_key[size+off] = '\0';
}
-
-
/**
* Continuation called to notify client about result of the
* operation.
*
* @param cls closure
- * @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
+ * @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
* @param emsg NULL on success, otherwise an error message
*/
static void
}
+/**
+ * Function called if we had an error in zone-to-name mapping.
+ */
+static void
+zone_to_name_error (void *cls)
+{
+ struct Request *request = cls;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Error when mapping zone to name\n"));
+ request->phase = RP_FAIL;
+ run_httpd_now ();
+}
+
+
/**
* Test if a name mapping was found, if so, refuse. If not, initiate storing of the record.
*
* @param cls closure
* @param zone_key public key of the zone
* @param name name that is being mapped (at most 255 characters long)
- * @param rd_count number of entries in 'rd' array
+ * @param rd_count number of entries in @a rd array
* @param rd array of records with data to store
*/
static void
{
struct Request *request = cls;
struct GNUNET_GNSRECORD_Data r;
- struct GNUNET_CRYPTO_EcdsaPublicKey pub;
request->qe = NULL;
- if (NULL != name)
+ if (0 != rd_count)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
_("Found existing name `%s' for the given key\n"),
run_httpd_now ();
return;
}
- GNUNET_CRYPTO_ecdsa_key_get_public (zone_key,
- &pub);
- r.data = &pub;
- r.data_size = sizeof (pub);
+ r.data = &request->pub;
+ r.data_size = sizeof (request->pub);
r.expiration_time = UINT64_MAX;
r.record_type = GNUNET_GNSRECORD_TYPE_PKEY;
r.flags = GNUNET_GNSRECORD_RF_NONE;
/**
- * Process a record that was stored in the namestore. Used to check if
- * the requested name already exists in the namestore. If not,
- * proceed to check if the requested key already exists.
- *
- * @param cls closure
- * @param rd_count number of entries in 'rd' array
- * @param rd array of records with data to store
+ * We encountered an error in the name lookup.
*/
static void
-lookup_result_processor (void *cls,
- unsigned int rd_count,
- const struct GNUNET_GNSRECORD_Data *rd)
+lookup_block_error (void *cls)
{
struct Request *request = cls;
- struct GNUNET_CRYPTO_EcdsaPublicKey pub;
- if (0 != rd_count)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _("Found %u existing records for domain `%s'\n"),
- rd_count,
- request->domain_name);
- request->phase = RP_FAIL;
- run_httpd_now ();
- return;
- }
- if (GNUNET_OK !=
- GNUNET_CRYPTO_ecdsa_public_key_from_string (request->public_key,
- strlen (request->public_key),
- &pub))
- {
- GNUNET_break (0);
- request->phase = RP_FAIL;
- run_httpd_now ();
- return;
- }
- request->qe = GNUNET_NAMESTORE_zone_to_name (ns,
- &fcfs_zone_pkey,
- &pub,
- &zone_to_name_cb,
- request);
+ request->qe = NULL;
+ request->phase = RP_FAIL;
+ run_httpd_now ();
}
* and continue to process the result.
*
* @param cls the 'struct Request' we are processing
- * @param block block returned form namestore, NULL on error
+ * @param zone private key of the zone; NULL on disconnect
+ * @param label label of the records; NULL on disconnect
+ * @param rd_count number of entries in @a rd array, 0 if label was deleted
+ * @param rd array of records with data to store
*/
static void
lookup_block_processor (void *cls,
- const struct GNUNET_GNSRECORD_Block *block)
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+ const char *label,
+ unsigned int rd_count,
+ const struct GNUNET_GNSRECORD_Data *rd)
{
struct Request *request = cls;
- struct GNUNET_CRYPTO_EcdsaPublicKey pub;
request->qe = NULL;
- if (NULL == block)
- {
- lookup_result_processor (request, 0, NULL);
- return;
- }
- GNUNET_CRYPTO_ecdsa_key_get_public (&fcfs_zone_pkey,
- &pub);
- if (GNUNET_OK !=
- GNUNET_GNSRECORD_block_decrypt (block,
- &pub,
- request->domain_name,
- &lookup_result_processor,
- request))
+ if (0 == rd_count)
{
- GNUNET_break (0);
- request->phase = RP_FAIL;
- run_httpd_now ();
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_ecdsa_public_key_from_string (request->public_key,
+ strlen (request->public_key),
+ &request->pub))
+ {
+ GNUNET_break (0);
+ request->phase = RP_FAIL;
+ run_httpd_now ();
+ return;
+ }
+ request->qe = GNUNET_NAMESTORE_zone_to_name (ns,
+ &fcfs_zone_pkey,
+ &request->pub,
+ &zone_to_name_error,
+ request,
+ &zone_to_name_cb,
+ request);
return;
}
+ GNUNET_break (0 != rd_count);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ _("Found %u existing records for domain `%s'\n"),
+ rd_count,
+ request->domain_name);
+ request->phase = RP_FAIL;
+ run_httpd_now ();
+ return;
}
* data *will* be made available incrementally in
* upload_data)
* @param upload_data_size set initially to the size of the
- * upload_data provided; the method must update this
+ * @a upload_data provided; the method must update this
* value to the number of bytes NOT processed;
* @param ptr pointer to location where we store the 'struct Request'
* @return MHD_YES if the connection was handled successfully,
{
struct MHD_Response *response;
struct Request *request;
- int ret;
struct GNUNET_CRYPTO_EcdsaPublicKey pub;
- struct GNUNET_HashCode query;
+ int ret;
if ( (0 == strcmp (method, MHD_HTTP_METHOD_GET)) ||
(0 == strcmp (method, MHD_HTTP_METHOD_HEAD)) )
request = *ptr;
if (NULL == request)
{
- request = GNUNET_malloc (sizeof (struct Request));
+ request = GNUNET_new (struct Request);
*ptr = request;
- request->pp = MHD_create_post_processor (connection, 1024,
- &post_iterator, request);
+ request->pp = MHD_create_post_processor (connection,
+ 1024,
+ &post_iterator,
+ request);
if (NULL == request->pp)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
}
if (GNUNET_OK !=
GNUNET_CRYPTO_ecdsa_public_key_from_string (request->public_key,
- strlen (request->public_key),
- &pub))
+ strlen (request->public_key),
+ &pub))
{
/* parse error */
return fill_s_reply ("Failed to parse given public key",
_("Domain name must not contain `.'\n"));
request->phase = RP_FAIL;
return fill_s_reply ("Domain name must not contain `.', sorry.",
- request, connection);
+ request,
+ connection);
}
if (NULL != strchr (request->domain_name, (int) '+'))
{
request, connection);
}
request->phase = RP_LOOKUP;
- GNUNET_CRYPTO_ecdsa_key_get_public (&fcfs_zone_pkey,
- &pub);
- GNUNET_GNSRECORD_query_from_public_key (&pub,
- request->domain_name,
- &query);
- request->qe = GNUNET_NAMESTORE_lookup_block (ns,
- &query,
- &lookup_block_processor,
- request);
+ request->qe
+ = GNUNET_NAMESTORE_records_lookup (ns,
+ &fcfs_zone_pkey,
+ request->domain_name,
+ &lookup_block_error,
+ request,
+ &lookup_block_processor,
+ request);
break;
case RP_LOOKUP:
break;
(void *) METHOD_ERROR,
MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection,
- MHD_HTTP_METHOD_NOT_ACCEPTABLE,
+ MHD_HTTP_NOT_ACCEPTABLE,
response);
MHD_destroy_response (response);
return ret;
{
struct Request *request = *con_cls;
+ (void) cls;
+ (void) connection;
+ (void) toe;
if (NULL == request)
return;
if (NULL != request->pp)
wes = GNUNET_NETWORK_fdset_create ();
wws = GNUNET_NETWORK_fdset_create ();
max = -1;
- GNUNET_assert (MHD_YES == MHD_get_fdset (httpd, &rs, &ws, &es, &max));
- haveto = MHD_get_timeout (httpd, &timeout);
+ GNUNET_assert (MHD_YES ==
+ MHD_get_fdset (httpd,
+ &rs,
+ &ws,
+ &es,
+ &max));
+ haveto = MHD_get_timeout (httpd,
+ &timeout);
if (haveto == MHD_YES)
tv.rel_value_us = (uint64_t) timeout * 1000LL;
else
tv = GNUNET_TIME_UNIT_FOREVER_REL;
- GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1);
- GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1);
- GNUNET_NETWORK_fdset_copy_native (wes, &es, max + 1);
+ GNUNET_NETWORK_fdset_copy_native (wrs,
+ &rs,
+ max + 1);
+ GNUNET_NETWORK_fdset_copy_native (wws,
+ &ws,
+ max + 1);
+ GNUNET_NETWORK_fdset_copy_native (wes,
+ &es,
+ max + 1);
httpd_task =
GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
- tv, wrs, wws,
- &do_httpd, NULL);
+ tv,
+ wrs,
+ wws,
+ &do_httpd,
+ NULL);
GNUNET_NETWORK_fdset_destroy (wrs);
GNUNET_NETWORK_fdset_destroy (wws);
GNUNET_NETWORK_fdset_destroy (wes);
* Task run whenever HTTP server operations are pending.
*
* @param cls unused
- * @param tc scheduler context
*/
static void
-do_httpd (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+do_httpd (void *cls)
{
- httpd_task = GNUNET_SCHEDULER_NO_TASK;
+ (void) cls;
+ httpd_task = NULL;
MHD_run (httpd);
run_httpd ();
}
* Task run on shutdown. Cleans up everything.
*
* @param cls unused
- * @param tc scheduler context
*/
static void
-do_shutdown (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+do_shutdown (void *cls)
{
- if (GNUNET_SCHEDULER_NO_TASK != httpd_task)
+ (void) cls;
+ if (NULL != httpd_task)
{
GNUNET_SCHEDULER_cancel (httpd_task);
- httpd_task = GNUNET_SCHEDULER_NO_TASK;
+ httpd_task = NULL;
}
if (NULL != ns)
{
{
int options;
+ (void) cls;
+ (void) ctx;
+ (void) name;
id_op = NULL;
if (NULL == ego)
{
* @param cfg configuration
*/
static void
-run (void *cls, char *const *args, const char *cfgfile,
+run (void *cls,
+ char *const *args,
+ const char *cfgfile,
const struct GNUNET_CONFIGURATION_Handle *cfg)
{
+ (void) cls;
+ (void) args;
+ (void) cfgfile;
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_number (cfg,
"fcfsd",
}
identity = GNUNET_IDENTITY_connect (cfg,
NULL, NULL);
+ if (NULL == identity)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Failed to connect to identity\n"));
+ return;
+ }
id_op = GNUNET_IDENTITY_get (identity, "fcfsd",
&identity_cb, NULL);
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
- &do_shutdown, NULL);
+ GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
}
* @return 0 ok, 1 on error
*/
int
-main (int argc, char *const *argv)
+main (int argc,
+ char *const *argv)
{
static const struct GNUNET_GETOPT_CommandLineOption options[] = {
GNUNET_GETOPT_OPTION_END
};
-
int ret;
- if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_get_utf8_args (argc, argv,
+ &argc, &argv))
return 2;
- GNUNET_log_setup ("fcfsd", "WARNING", NULL);
+ GNUNET_log_setup ("fcfsd",
+ "WARNING",
+ NULL);
ret =
(GNUNET_OK ==
- GNUNET_PROGRAM_run (argc, argv, "fcfsd",
+ GNUNET_PROGRAM_run (argc,
+ argv,
+ "gnunet-namestore-fcfsd",
_("GNU Name System First Come First Serve name registration service"),
options,
&run, NULL)) ? 0 : 1;