X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fnamestore%2Fgnunet-namestore-fcfsd.c;h=6e45f822779e2853b47fd2ef3725e5809325700e;hb=c15e7951180d954ca584a95206543e8997b3a7d4;hp=14b9f2e8fd4ffda97eb6d1e33be3d5f5e895ae9f;hpb=31ad700d358b04f4bc89fb12d8932ce9cd8cf40a;p=oweals%2Fgnunet.git diff --git a/src/namestore/gnunet-namestore-fcfsd.c b/src/namestore/gnunet-namestore-fcfsd.c index 14b9f2e8f..6e45f8227 100644 --- a/src/namestore/gnunet-namestore-fcfsd.c +++ b/src/namestore/gnunet-namestore-fcfsd.c @@ -1,6 +1,6 @@ /* 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 @@ -14,8 +14,8 @@ 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 @@ -112,7 +112,7 @@ struct Request /** * Associated session. */ - struct Session *session; + // FIXME: struct Session *session; /** * Post processor handling form data (IF this is @@ -194,7 +194,7 @@ static struct MHD_Daemon *httpd; /** * Main HTTP task. */ -static GNUNET_SCHEDULER_TaskIdentifier httpd_task; +static struct GNUNET_SCHEDULER_Task * httpd_task; /** * Handle to the namestore. @@ -226,11 +226,9 @@ static unsigned long long port; * 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); /** @@ -239,64 +237,104 @@ 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; } @@ -304,11 +342,17 @@ iterate_cb (void *cls, 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; @@ -318,12 +362,12 @@ iterate_cb (void *cls, 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. * @@ -342,8 +386,12 @@ serve_zoneinfo_page (struct MHD_Connection *connection) 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; } @@ -436,15 +484,21 @@ post_iterator (void *cls, 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'; @@ -454,7 +508,7 @@ post_iterator (void *cls, { 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'; @@ -499,6 +553,21 @@ put_continuation (void *cls, } +/** + * 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. * @@ -517,8 +586,8 @@ zone_to_name_cb (void *cls, { struct Request *request = cls; struct GNUNET_GNSRECORD_Data r; - request->qe = NULL; + request->qe = NULL; if (0 != rd_count) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -528,16 +597,6 @@ zone_to_name_cb (void *cls, run_httpd_now (); return; } - if (NULL == zone_key) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Error when mapping zone to name\n")); - request->phase = RP_FAIL; - run_httpd_now (); - return; - } - - fprintf (stderr, "PUB %s\n", GNUNET_CRYPTO_ecdsa_public_key_to_string(&request->pub)); r.data = &request->pub; r.data_size = sizeof (request->pub); r.expiration_time = UINT64_MAX; @@ -552,6 +611,20 @@ zone_to_name_cb (void *cls, } +/** + * We encountered an error in the name lookup. + */ +static void +lookup_block_error (void *cls) +{ + struct Request *request = cls; + + request->qe = NULL; + request->phase = RP_FAIL; + run_httpd_now (); +} + + /** * We got a block back from the namestore. Decrypt it * and continue to process the result. @@ -574,7 +647,6 @@ lookup_block_processor (void *cls, request->qe = NULL; if (0 == rd_count) { - if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (request->public_key, strlen (request->public_key), @@ -585,10 +657,11 @@ lookup_block_processor (void *cls, run_httpd_now (); return; } - fprintf (stderr, "PUB1 %s\n", GNUNET_CRYPTO_ecdsa_public_key_to_string(&request->pub)); request->qe = GNUNET_NAMESTORE_zone_to_name (ns, &fcfs_zone_pkey, &request->pub, + &zone_to_name_error, + request, &zone_to_name_cb, request); return; @@ -660,10 +733,12 @@ create_response (void *cls, 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, @@ -706,7 +781,8 @@ create_response (void *cls, _("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) '+')) { @@ -717,11 +793,14 @@ create_response (void *cls, request, connection); } request->phase = RP_LOOKUP; - request->qe = GNUNET_NAMESTORE_records_lookup (ns, - &fcfs_zone_pkey, - request->domain_name, - &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; @@ -744,7 +823,7 @@ create_response (void *cls, (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; @@ -768,6 +847,9 @@ request_completed_callback (void *cls, { struct Request *request = *con_cls; + (void) cls; + (void) connection; + (void) toe; if (NULL == request) return; if (NULL != request->pp) @@ -805,19 +887,34 @@ run_httpd () 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); @@ -828,13 +925,12 @@ run_httpd () * 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 (); } @@ -844,16 +940,15 @@ do_httpd (void *cls, * 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) { @@ -905,6 +1000,9 @@ identity_cb (void *cls, { int options; + (void) cls; + (void) ctx; + (void) name; id_op = NULL; if (NULL == ego) { @@ -952,9 +1050,14 @@ identity_cb (void *cls, * @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", @@ -982,8 +1085,7 @@ run (void *cls, char *const *args, const char *cfgfile, } 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); } @@ -995,21 +1097,27 @@ run (void *cls, char *const *args, const char *cfgfile, * @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;