fix
[oweals/gnunet.git] / src / namestore / plugin_namestore_flat.c
index 88b3ce9b4abed6589eaa361f074f52c207382fb3..e16fe91b7b88b30f74ae5361436f54632b1add4d 100644 (file)
@@ -2,20 +2,18 @@
   * This file is part of GNUnet
   * 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 <http://www.gnu.org/licenses/>.
   */
 
 /**
@@ -49,41 +47,6 @@ 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
-   */
-  const struct GNUNET_CRYPTO_EcdsaPublicKey *iter_pkey;
-
-  /**
-   * Iteration result found
-   */
-  int iter_result_found;
-
 };
 
 
@@ -92,7 +55,7 @@ struct FlatFileEntry
   /**
    * Entry zone
    */
-  struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key;
+  struct GNUNET_CRYPTO_EcdsaPrivateKey private_key;
 
   /**
    * Record cound
@@ -130,7 +93,6 @@ static int
 database_setup (struct Plugin *plugin)
 {
   char *afsdir;
-  char *key;
   char *record_data;
   char *zone_private_key;
   char *record_data_b64;
@@ -140,8 +102,7 @@ database_setup (struct Plugin *plugin)
   char *rvalue;
   char *record_count;
   size_t record_data_size;
-  size_t size;
-  size_t key_len;
+  uint64_t size;
   struct GNUNET_HashCode hkey;
   struct GNUNET_DISK_FileHandle *fh;
   struct FlatFileEntry *entry;
@@ -218,7 +179,8 @@ database_setup (struct Plugin *plugin)
   if (0 < size)
   {
     line = strtok (buffer, "\n");
-    while (line != NULL) {
+    while (line != NULL)
+    {
       zone_private_key = strtok (line, ",");
       if (NULL == zone_private_key)
         break;
@@ -236,29 +198,39 @@ database_setup (struct Plugin *plugin)
         break;
       line = strtok (NULL, "\n");
       entry = GNUNET_new (struct FlatFileEntry);
-      if (1 != sscanf (rvalue,
-                      "%lu",
-                      &entry->rvalue))
       {
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                    "Error parsing entry\n");
-        GNUNET_free (entry);
-        break;
+        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;
       }
-      if (1 != sscanf (record_count,
-                      "%u",
-                      &entry->record_count))
       {
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                    "Error parsing entry\n");
-        GNUNET_free (entry);
-        break;
+        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),
-                                       &record_data);
+                                       (void **) &record_data);
       entry->record_data =
         GNUNET_new_array (entry->record_count,
                          struct GNUNET_GNSRECORD_Data);
@@ -277,21 +249,34 @@ database_setup (struct Plugin *plugin)
         break;
       }
       GNUNET_free (record_data);
-      GNUNET_STRINGS_base64_decode (zone_private_key,
-                                    strlen (zone_private_key),
-                                    (char**)&entry->private_key);
-      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);
+
+      {
+        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,
@@ -325,14 +310,26 @@ store_and_free_entries (void *cls,
   char *line;
   char *zone_private_key;
   char *record_data_b64;
-  size_t data_size;
+  ssize_t data_size;
 
   (void) key;
-  GNUNET_STRINGS_base64_encode ((char*)entry->private_key,
+  GNUNET_STRINGS_base64_encode (&entry->private_key,
                                 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey),
                                 &zone_private_key);
   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;
@@ -342,7 +339,7 @@ store_and_free_entries (void *cls,
                                              data_size,
                                              data);
     if ( (ret < 0) ||
-        (data_size != (size_t) ret) )
+        (data_size != ret) )
     {
       GNUNET_break (0);
       GNUNET_free (zone_private_key);
@@ -353,10 +350,10 @@ store_and_free_entries (void *cls,
                                   &record_data_b64);
   }
   GNUNET_asprintf (&line,
-                   "%s,%lu,%u,%s,%s\n",
+                   "%s,%llu,%u,%s,%s\n",
                    zone_private_key,
-                   entry->rvalue,
-                   entry->record_count,
+                   (unsigned long long) entry->rvalue,
+                   (unsigned int) entry->record_count,
                    record_data_b64,
                    entry->label);
   GNUNET_free (record_data_b64);
@@ -367,7 +364,6 @@ store_and_free_entries (void *cls,
                           strlen (line));
 
   GNUNET_free (line);
-  GNUNET_free (entry->private_key);
   GNUNET_free (entry->label);
   GNUNET_free (entry->record_data);
   GNUNET_free (entry);
@@ -455,11 +451,10 @@ namestore_flat_store_records (void *cls,
     return GNUNET_OK;
   }
   entry = GNUNET_new (struct FlatFileEntry);
-  entry->private_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey);
   GNUNET_asprintf (&entry->label,
                    label,
                    strlen (label));
-  GNUNET_memcpy (entry->private_key,
+  GNUNET_memcpy (&entry->private_key,
                  zone_key,
                  sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
   entry->rvalue = rvalue;
@@ -533,7 +528,7 @@ namestore_flat_lookup_records (void *cls,
   if (NULL != iter)
     iter (iter_cls,
          0,
-         entry->private_key,
+         &entry->private_key,
          entry->label,
          entry->record_count,
          entry->record_data);
@@ -597,14 +592,14 @@ iterate_zones (void *cls,
   struct FlatFileEntry *entry = value;
 
   (void) key;
-  ic->pos++;
   if (0 == ic->limit)
     return GNUNET_NO;
   if ( (NULL != ic->zone) &&
-       (0 != memcmp (entry->private_key,
+       (0 != memcmp (&entry->private_key,
                      ic->zone,
                      sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))) )
     return GNUNET_YES;
+  ic->pos++;
   if (ic->offset > 0)
   {
     ic->offset--;
@@ -612,7 +607,7 @@ iterate_zones (void *cls,
   }
   ic->iter (ic->iter_cls,
            ic->pos,
-            entry->private_key,
+            &entry->private_key,
             entry->label,
             entry->record_count,
             entry->record_data);
@@ -659,17 +654,31 @@ namestore_flat_iterate_records (void *cls,
 }
 
 
+/**
+ * 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;
 
   (void) key;
-  if (0 != memcmp (entry->private_key,
-                   plugin->iter_zone,
+  if (0 != memcmp (&entry->private_key,
+                   ztn->zone,
                    sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)))
     return GNUNET_YES;
 
@@ -677,18 +686,17 @@ zone_to_name (void *cls,
   {
     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,
-                   0,
-                    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;
@@ -714,21 +722,21 @@ namestore_flat_zone_to_name (void *cls,
                              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
+  };
 
-  /* FIXME: maybe use separate closure to better handle
-     recursive calls? */
-  plugin->iter = iter;
-  plugin->iter_cls = iter_cls;
-  plugin->iter_zone = zone;
-  plugin->iter_pkey = value_zone;
-  plugin->iter_result_found = GNUNET_NO;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "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;
 }