X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fnamestore%2Fplugin_namestore_flat.c;h=e16fe91b7b88b30f74ae5361436f54632b1add4d;hb=5fb272d662eca0707b1a5c7747ae476f8157d332;hp=b2fd70d923360b48f4f54dca8adf0d31c13c9622;hpb=7fe8782a2beffafb0fa3fadae43d4498335f4472;p=oweals%2Fgnunet.git diff --git a/src/namestore/plugin_namestore_flat.c b/src/namestore/plugin_namestore_flat.c index b2fd70d92..e16fe91b7 100644 --- a/src/namestore/plugin_namestore_flat.c +++ b/src/namestore/plugin_namestore_flat.c @@ -1,27 +1,26 @@ /* * This file is part of GNUnet - * Copyright (C) 2009-2015 Christian Grothoff (and other contributing authors) + * Copyright (C) 2009-2015, 2018 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 - * by the Free Software Foundation; either version 3, or (at your - * option) any later version. + * GNUnet is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. * * GNUnet is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * Affero General Public License for more details. * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ /** * @file namestore/plugin_namestore_flat.c * @brief file-based namestore backend * @author Martin Schanzenbach + * @author Christian Grothoff */ #include "platform.h" @@ -48,54 +47,15 @@ struct Plugin */ struct GNUNET_CONTAINER_MultiHashMap *hm; - /** - * Offset - */ - uint32_t offset; - - /** - * Target Offset - */ - uint32_t target_offset; - - /** - * Iterator closure - */ - void *iter_cls; - - /** - * Iterator - */ - GNUNET_NAMESTORE_RecordIterator iter; - - /** - * Zone to iterate - */ - const struct GNUNET_CRYPTO_EcdsaPrivateKey *iter_zone; - - /** - * PKEY to look for in zone to name - */ - struct GNUNET_CRYPTO_EcdsaPublicKey *iter_pkey; - - /** - * Iteration result found - */ - int iter_result_found; - }; + struct FlatFileEntry { /** * Entry zone */ - struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key; - - /** - * Entry zone pkey - */ - struct GNUNET_CRYPTO_EcdsaPublicKey *pkey; + struct GNUNET_CRYPTO_EcdsaPrivateKey private_key; /** * Record cound @@ -133,10 +93,8 @@ static int database_setup (struct Plugin *plugin) { char *afsdir; - char *key_str; char *record_data; char *zone_private_key; - char *pkey; char *record_data_b64; char *buffer; char *line; @@ -144,23 +102,27 @@ database_setup (struct Plugin *plugin) char *rvalue; char *record_count; size_t record_data_size; - size_t size; + uint64_t size; struct GNUNET_HashCode hkey; struct GNUNET_DISK_FileHandle *fh; - struct FlatFileEntry *entry; + struct FlatFileEntry *entry; if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, + GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "namestore-flat", - "FILENAME", &afsdir)) + "FILENAME", + &afsdir)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "namestore-flat", "FILENAME"); + "namestore-flat", + "FILENAME"); return GNUNET_SYSERR; } - if (GNUNET_OK != GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK != + GNUNET_DISK_file_test (afsdir)) { - if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir)) + if (GNUNET_OK != + GNUNET_DISK_directory_create_for_file (afsdir)) { GNUNET_break (0); GNUNET_free (afsdir); @@ -174,7 +136,8 @@ database_setup (struct Plugin *plugin) plugin->hm = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); fh = GNUNET_DISK_file_open (afsdir, - GNUNET_DISK_OPEN_CREATE, + GNUNET_DISK_OPEN_CREATE | + GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_WRITE | GNUNET_DISK_PERM_USER_READ); if (NULL == fh) @@ -184,78 +147,145 @@ database_setup (struct Plugin *plugin) afsdir); return GNUNET_SYSERR; } - - if (GNUNET_SYSERR == GNUNET_DISK_file_size (afsdir, - &size, - GNUNET_YES, - GNUNET_YES)) + if (GNUNET_SYSERR == + GNUNET_DISK_file_size (afsdir, + &size, + GNUNET_YES, + GNUNET_YES)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to get filesize: %s.\n"), afsdir); + GNUNET_DISK_file_close (fh); return GNUNET_SYSERR; } - buffer = GNUNET_malloc (size); - - if (GNUNET_SYSERR == GNUNET_DISK_file_read (fh, - buffer, - size)) + buffer = GNUNET_malloc (size + 1); + if (GNUNET_SYSERR == + GNUNET_DISK_file_read (fh, + buffer, + size)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to read file: %s.\n"), afsdir); + GNUNET_free (buffer); + GNUNET_DISK_file_close (fh); return GNUNET_SYSERR; } - + buffer[size] = '\0'; GNUNET_DISK_file_close (fh); - line = strtok ("\n", buffer); - while (line != NULL) { - zone_private_key = strtok (",", line); - pkey = strtok (NULL, line); - rvalue = strtok (NULL, line); - record_count = strtok (NULL, line); - record_data_b64 = strtok (NULL, line); - label = strtok (NULL, line); - line = strtok ("\n", buffer); - entry = GNUNET_malloc (sizeof (struct FlatFileEntry)); - GNUNET_CRYPTO_ecdsa_public_key_from_string (pkey, - strlen (pkey), - entry->pkey); - sscanf (rvalue, "%lu", &entry->rvalue); - sscanf (record_count, "%u", &entry->record_count); - entry->label = GNUNET_strdup (label); - record_data_size = GNUNET_STRINGS_base64_decode (record_data_b64, - strlen (record_data_b64), - &record_data); - entry->record_data = - GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Data) * entry->record_count); - GNUNET_GNSRECORD_records_deserialize (record_data_size, - record_data, - entry->record_count, - entry->record_data); - GNUNET_free (record_data); - GNUNET_STRINGS_base64_decode (zone_private_key, - strlen (zone_private_key), - (char**)&entry->private_key); - key_str = GNUNET_malloc (strlen (label) + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); - memcpy (key_str, label, strlen (label)); - memcpy (key_str+strlen(label), - entry->private_key, - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); - GNUNET_CRYPTO_hash (key_str, - strlen (key_str), - &hkey); - GNUNET_free (key_str); - if (GNUNET_OK != - GNUNET_CONTAINER_multihashmap_put (plugin->hm, - &hkey, - entry, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) + if (0 < size) + { + line = strtok (buffer, "\n"); + while (line != NULL) { - GNUNET_free (entry); - GNUNET_break (0); + zone_private_key = strtok (line, ","); + if (NULL == zone_private_key) + break; + rvalue = strtok (NULL, ","); + if (NULL == rvalue) + break; + record_count = strtok (NULL, ","); + if (NULL == record_count) + break; + record_data_b64 = strtok (NULL, ","); + if (NULL == record_data_b64) + break; + label = strtok (NULL, ","); + if (NULL == label) + break; + line = strtok (NULL, "\n"); + entry = GNUNET_new (struct FlatFileEntry); + { + unsigned long long ll; + + if (1 != sscanf (rvalue, + "%llu", + &ll)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Error parsing entry\n"); + GNUNET_free (entry); + break; + } + entry->rvalue = (uint64_t) ll; + } + { + unsigned int ui; + + if (1 != sscanf (record_count, + "%u", + &ui)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Error parsing entry\n"); + GNUNET_free (entry); + break; + } + entry->record_count = (uint32_t) ui; + } + entry->label = GNUNET_strdup (label); + record_data_size + = GNUNET_STRINGS_base64_decode (record_data_b64, + strlen (record_data_b64), + (void **) &record_data); + entry->record_data = + GNUNET_new_array (entry->record_count, + struct GNUNET_GNSRECORD_Data); + if (GNUNET_OK != + GNUNET_GNSRECORD_records_deserialize (record_data_size, + record_data, + entry->record_count, + entry->record_data)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unable to deserialize record %s\n", + label); + GNUNET_free (entry->label); + GNUNET_free (entry); + GNUNET_free (record_data); + break; + } + GNUNET_free (record_data); + + { + struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key; + + GNUNET_STRINGS_base64_decode (zone_private_key, + strlen (zone_private_key), + (void**)&private_key); + entry->private_key = *private_key; + GNUNET_free (private_key); + } + + { + char *key; + size_t key_len; + + key_len = strlen (label) + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey); + key = GNUNET_malloc (strlen (label) + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); + GNUNET_memcpy (key, + label, + strlen (label)); + GNUNET_memcpy (key+strlen(label), + &entry->private_key, + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); + GNUNET_CRYPTO_hash (key, + key_len, + &hkey); + GNUNET_free (key); + } + if (GNUNET_OK != + GNUNET_CONTAINER_multihashmap_put (plugin->hm, + &hkey, + entry, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) + { + GNUNET_free (entry); + GNUNET_break (0); + } } } GNUNET_free (buffer); @@ -267,6 +297,8 @@ database_setup (struct Plugin *plugin) * Store values in hashmap in file and free data * * @param plugin the plugin context + * @param key key in the map + * @param value a `struct FlatFileEntry` */ static int store_and_free_entries (void *cls, @@ -277,59 +309,68 @@ store_and_free_entries (void *cls, struct FlatFileEntry *entry = value; char *line; char *zone_private_key; - char *pkey; - char *rvalue; - char *record_count; - char *record_data_buf; char *record_data_b64; - size_t record_data_len; + ssize_t data_size; - GNUNET_STRINGS_base64_encode ((char*)entry->private_key, + (void) key; + GNUNET_STRINGS_base64_encode (&entry->private_key, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey), &zone_private_key); - pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (entry->pkey); - GNUNET_asprintf (&rvalue, "%hhu", entry->rvalue); - GNUNET_asprintf (&record_count, "%u", entry->record_count); - - record_data_len = GNUNET_GNSRECORD_records_get_size (entry->record_count, - entry->record_data); - - record_data_buf = GNUNET_malloc (record_data_len); - GNUNET_GNSRECORD_records_serialize (entry->record_count, - entry->record_data, - record_data_len, - record_data_buf); - - GNUNET_STRINGS_base64_encode (record_data_buf, - strlen (record_data_buf), - &record_data_b64); - + data_size = GNUNET_GNSRECORD_records_get_size (entry->record_count, + entry->record_data); + if (data_size < 0) + { + GNUNET_break (0); + GNUNET_free (zone_private_key); + return GNUNET_SYSERR; + } + if (data_size >= UINT16_MAX) + { + GNUNET_break (0); + GNUNET_free (zone_private_key); + return GNUNET_SYSERR; + } + { + char data[data_size]; + ssize_t ret; + + ret = GNUNET_GNSRECORD_records_serialize (entry->record_count, + entry->record_data, + data_size, + data); + if ( (ret < 0) || + (data_size != ret) ) + { + GNUNET_break (0); + GNUNET_free (zone_private_key); + return GNUNET_SYSERR; + } + GNUNET_STRINGS_base64_encode (data, + data_size, + &record_data_b64); + } GNUNET_asprintf (&line, - "%s.%s.%s.%s.%s.%s\n", + "%s,%llu,%u,%s,%s\n", zone_private_key, - pkey, - rvalue, - record_count, + (unsigned long long) entry->rvalue, + (unsigned int) entry->record_count, record_data_b64, entry->label); - - GNUNET_free (rvalue); - GNUNET_free (record_count); - GNUNET_free (record_data_buf); GNUNET_free (record_data_b64); + GNUNET_free (zone_private_key); GNUNET_DISK_file_write (fh, line, strlen (line)); - GNUNET_free (entry->private_key); - GNUNET_free (entry->pkey); + GNUNET_free (line); GNUNET_free (entry->label); GNUNET_free (entry->record_data); GNUNET_free (entry); return GNUNET_YES; } + /** * Shutdown database connection and associate data * structures. @@ -339,16 +380,18 @@ static void database_shutdown (struct Plugin *plugin) { struct GNUNET_DISK_FileHandle *fh; + fh = GNUNET_DISK_file_open (plugin->fn, GNUNET_DISK_OPEN_CREATE | - GNUNET_DISK_OPEN_TRUNCATE, + GNUNET_DISK_OPEN_TRUNCATE | + GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_WRITE | GNUNET_DISK_PERM_USER_READ); if (NULL == fh) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Unable to initialize file: %s.\n"), - plugin->fn); + _("Unable to initialize file: %s.\n"), + plugin->fn); return; } @@ -372,79 +415,67 @@ database_shutdown (struct Plugin *plugin) * @return #GNUNET_OK on success, else #GNUNET_SYSERR */ static int -namestore_store_records (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd) +namestore_flat_store_records (void *cls, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const char *label, + unsigned int rd_count, + const struct GNUNET_GNSRECORD_Data *rd) { struct Plugin *plugin = cls; - struct GNUNET_CRYPTO_EcdsaPublicKey pkey; uint64_t rvalue; - size_t data_size; - unsigned int i; - char *key_str; + size_t key_len; + char *key; struct GNUNET_HashCode hkey; struct FlatFileEntry *entry; - memset (&pkey, 0, sizeof (pkey)); - for (i=0;i 64 * 65536) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - char data[data_size]; - - if (data_size != GNUNET_GNSRECORD_records_serialize (rd_count, rd, - data_size, data)) + rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, + UINT64_MAX); + key_len = strlen (label) + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey); + key = GNUNET_malloc (key_len); + GNUNET_memcpy (key, + label, + strlen (label)); + GNUNET_memcpy (key + strlen(label), + zone_key, + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); + GNUNET_CRYPTO_hash (key, + key_len, + &hkey); + GNUNET_CONTAINER_multihashmap_remove_all (plugin->hm, + &hkey); + if (0 == rd_count) { - GNUNET_break (0); - return GNUNET_SYSERR; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, + "sqlite", + "Record deleted\n"); + return GNUNET_OK; } - - key_str = GNUNET_malloc (strlen (label) + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); - memcpy (key_str, label, strlen (label)); - memcpy (key_str+strlen(label), - zone_key, - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); - GNUNET_CRYPTO_hash (key_str, - strlen (key_str), - &hkey); - - GNUNET_CONTAINER_multihashmap_remove_all (plugin->hm, &hkey); - - if (0 != rd_count) + entry = GNUNET_new (struct FlatFileEntry); + GNUNET_asprintf (&entry->label, + label, + strlen (label)); + GNUNET_memcpy (&entry->private_key, + zone_key, + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); + entry->rvalue = rvalue; + entry->record_count = rd_count; + entry->record_data = GNUNET_new_array (rd_count, + struct GNUNET_GNSRECORD_Data); + for (unsigned int i = 0; i < rd_count; i++) { - entry = GNUNET_malloc (sizeof (struct FlatFileEntry)); - entry->private_key = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); - memcpy (&entry->private_key, - zone_key, - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); - entry->pkey = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); - memcpy (entry->pkey, - &pkey, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); - entry->rvalue = rvalue; - entry->record_count = rd_count; - entry->record_data = GNUNET_malloc (data_size); - memcpy (&entry->record_data, data, data_size); - return GNUNET_CONTAINER_multihashmap_put (plugin->hm, - &hkey, - entry, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); + entry->record_data[i].expiration_time = rd[i].expiration_time; + entry->record_data[i].record_type = rd[i].record_type; + entry->record_data[i].flags = rd[i].flags; + entry->record_data[i].data_size = rd[i].data_size; + entry->record_data[i].data = GNUNET_malloc (rd[i].data_size); + GNUNET_memcpy ((char*)entry->record_data[i].data, + rd[i].data, + rd[i].data_size); } - return GNUNET_NO; + return GNUNET_CONTAINER_multihashmap_put (plugin->hm, + &hkey, + entry, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); } @@ -456,134 +487,222 @@ namestore_store_records (void *cls, * @param label name of the record in the zone * @param iter function to call with the result * @param iter_cls closure for @a iter - * @return #GNUNET_OK on success, else #GNUNET_SYSERR + * @return #GNUNET_OK on success, #GNUNET_NO for no results, else #GNUNET_SYSERR */ static int -namestore_lookup_records (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - const char *label, - GNUNET_NAMESTORE_RecordIterator iter, - void *iter_cls) +namestore_flat_lookup_records (void *cls, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const char *label, + GNUNET_NAMESTORE_RecordIterator iter, + void *iter_cls) { struct Plugin *plugin = cls; struct FlatFileEntry *entry; struct GNUNET_HashCode hkey; - char *key_str; + char *key; + size_t key_len; if (NULL == zone) { + GNUNET_break (0); return GNUNET_SYSERR; } - key_str = GNUNET_malloc (strlen (label) + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); - memcpy (key_str, label, strlen (label)); - memcpy (key_str+strlen(label), - zone, - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); - GNUNET_CRYPTO_hash (key_str, - strlen (key_str), + key_len = strlen (label) + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey); + key = GNUNET_malloc (key_len); + GNUNET_memcpy (key, + label, + strlen (label)); + GNUNET_memcpy (key+strlen(label), + zone, + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); + GNUNET_CRYPTO_hash (key, + key_len, &hkey); - GNUNET_free (key_str); + GNUNET_free (key); - entry = GNUNET_CONTAINER_multihashmap_get (plugin->hm, &hkey); + entry = GNUNET_CONTAINER_multihashmap_get (plugin->hm, + &hkey); if (NULL == entry) return GNUNET_NO; if (NULL != iter) - iter (iter_cls, entry->private_key, entry->label, entry->record_count, entry->record_data); + iter (iter_cls, + 0, + &entry->private_key, + entry->label, + entry->record_count, + entry->record_data); return GNUNET_YES; } +/** + * Closure for #iterate_zones. + */ +struct IterateContext +{ + /** + * How many more records should we skip before returning results? + */ + uint64_t offset; + + /** + * How many more records should we return? + */ + uint64_t limit; + + /** + * What is the position of the current entry, counting + * starts from 1. + */ + uint64_t pos; + + /** + * Target zone. + */ + const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone; + + /** + * Function to call on each record. + */ + GNUNET_NAMESTORE_RecordIterator iter; + + /** + * Closure for @e iter. + */ + void *iter_cls; + +}; + + +/** + * Helper function for #namestore_flat_iterate_records(). + * + * @param cls a `struct IterateContext` + * @param key unused + * @param value a `struct FlatFileEntry` + * @return #GNUNET_YES to continue the iteration + */ static int iterate_zones (void *cls, const struct GNUNET_HashCode *key, void *value) { - struct Plugin *plugin = cls; + struct IterateContext *ic = cls; struct FlatFileEntry *entry = value; - - if ((plugin->target_offset > plugin->offset) || - (0 != memcmp (entry->private_key, - plugin->iter_zone, - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)))) { - plugin->offset++; + (void) key; + if (0 == ic->limit) + return GNUNET_NO; + if ( (NULL != ic->zone) && + (0 != memcmp (&entry->private_key, + ic->zone, + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))) ) + return GNUNET_YES; + ic->pos++; + if (ic->offset > 0) + { + ic->offset--; return GNUNET_YES; } - - plugin->iter (plugin->iter_cls, - entry->private_key, - entry->label, - entry->record_count, - entry->record_data); - plugin->iter_result_found = GNUNET_YES; - return GNUNET_NO; + ic->iter (ic->iter_cls, + ic->pos, + &entry->private_key, + entry->label, + entry->record_count, + entry->record_data); + ic->limit--; + if (0 == ic->limit) + return GNUNET_NO; + return GNUNET_YES; } + /** * Iterate over the results for a particular key and zone in the * datastore. Will return at most one result to the iterator. * * @param cls closure (internal context for the plugin) * @param zone hash of public key of the zone, NULL to iterate over all zones - * @param offset offset in the list of all matching records + * @param serial serial number to exclude in the list of all matching records + * @param limit maximum number of results to return to @a iter * @param iter function to call with the result * @param iter_cls closure for @a iter - * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error + * @return #GNUNET_OK on success, #GNUNET_NO if there were no more results, #GNUNET_SYSERR on error */ static int -namestore_iterate_records (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - uint64_t offset, - GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) +namestore_flat_iterate_records (void *cls, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + uint64_t serial, + uint64_t limit, + GNUNET_NAMESTORE_RecordIterator iter, + void *iter_cls) { struct Plugin *plugin = cls; - plugin->target_offset = offset; - plugin->offset = 0; - plugin->iter = iter; - plugin->iter_cls = cls; - plugin->iter_zone = zone; - plugin->iter_result_found = GNUNET_NO; + struct IterateContext ic; + + ic.offset = serial; + ic.pos = 0; + ic.limit = limit; + ic.iter = iter; + ic.iter_cls = iter_cls; + ic.zone = zone; GNUNET_CONTAINER_multihashmap_iterate (plugin->hm, &iterate_zones, - plugin); - return plugin->iter_result_found; + &ic); + return (0 == ic.limit) ? GNUNET_OK : GNUNET_NO; } + +/** + * Closure for #zone_to_name. + */ +struct ZoneToNameContext +{ + const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone; + const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone; + GNUNET_NAMESTORE_RecordIterator iter; + void *iter_cls; + + int result_found; +}; + + static int zone_to_name (void *cls, const struct GNUNET_HashCode *key, void *value) { - struct Plugin *plugin = cls; + struct ZoneToNameContext *ztn = cls; struct FlatFileEntry *entry = value; - int i; - if (0 != memcmp (entry->private_key, - plugin->iter_zone, + (void) key; + if (0 != memcmp (&entry->private_key, + ztn->zone, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))) return GNUNET_YES; - for (i = 0; i < entry->record_count; i++) { + for (unsigned int i = 0; i < entry->record_count; i++) + { if (GNUNET_GNSRECORD_TYPE_PKEY != entry->record_data[i].record_type) continue; - if (0 == memcmp (plugin->iter_pkey, + if (0 == memcmp (ztn->value_zone, entry->record_data[i].data, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) { - plugin->iter (plugin->iter_cls, - entry->private_key, - entry->label, - entry->record_count, - entry->record_data); - plugin->iter_result_found = GNUNET_YES; - + ztn->iter (ztn->iter_cls, + 0, + &entry->private_key, + entry->label, + entry->record_count, + entry->record_data); + ztn->result_found = GNUNET_YES; } } - return GNUNET_YES; } + /** * Look for an existing PKEY delegation record for a given public key. * Returns at most one result to the iterator. @@ -596,23 +715,28 @@ zone_to_name (void *cls, * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error */ static int -namestore_zone_to_name (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone, - GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) +namestore_flat_zone_to_name (void *cls, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone, + GNUNET_NAMESTORE_RecordIterator iter, + void *iter_cls) { struct Plugin *plugin = cls; + struct ZoneToNameContext ztn = { + .iter = iter, + .iter_cls = iter_cls, + .zone = zone, + .value_zone = value_zone, + .result_found = GNUNET_NO + }; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Performing reverse lookup for `%s'\n", - GNUNET_GNSRECORD_z2s (value_zone)); - + "Performing reverse lookup for `%s'\n", + GNUNET_GNSRECORD_z2s (value_zone)); GNUNET_CONTAINER_multihashmap_iterate (plugin->hm, &zone_to_name, - plugin); - - - return plugin->iter_result_found; + &ztn); + return ztn.result_found; } @@ -631,7 +755,9 @@ libgnunet_plugin_namestore_flat_init (void *cls) if (NULL != plugin.cfg) return NULL; /* can only initialize once! */ - memset (&plugin, 0, sizeof (struct Plugin)); + memset (&plugin, + 0, + sizeof (struct Plugin)); plugin.cfg = cfg; if (GNUNET_OK != database_setup (&plugin)) { @@ -640,12 +766,12 @@ libgnunet_plugin_namestore_flat_init (void *cls) } api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions); api->cls = &plugin; - api->store_records = &namestore_store_records; - api->iterate_records = &namestore_iterate_records; - api->zone_to_name = &namestore_zone_to_name; - api->lookup_records = &namestore_lookup_records; + api->store_records = &namestore_flat_store_records; + api->iterate_records = &namestore_flat_iterate_records; + api->zone_to_name = &namestore_flat_zone_to_name; + api->lookup_records = &namestore_flat_lookup_records; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("flat file database running\n")); + _("flat file database running\n")); return api; } @@ -666,7 +792,7 @@ libgnunet_plugin_namestore_flat_done (void *cls) plugin->cfg = NULL; GNUNET_free (api); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "flat file plugin is finished\n"); + "flat file plugin is finished\n"); return NULL; }