fixing segv
[oweals/gnunet.git] / src / block / block.c
index cb6837499d210cf21fa557f956a63449cbb4adf6..29382dad193d74665f61aac25c4d41f94a7f5e14 100644 (file)
 #include "gnunet_block_lib.h"
 #include "plugin_block.h"
 
-/**
- * Check if the given KBlock is well-formed.
- *
- * @param kb the kblock data (or at least "dsize" bytes claiming to be one)
- * @param dsize size of "kb" in bytes; check for < sizeof(struct KBlock)!
- * @param query where to store the query that this block answers
- * @return GNUNET_OK if this is actually a well-formed KBlock
- */
-static int
-check_kblock (const struct KBlock *kb,
-             size_t dsize,
-             GNUNET_HashCode *query)
-{
-  if (dsize < sizeof (struct KBlock))
-    {
-      GNUNET_break_op (0);
-      return GNUNET_SYSERR;
-    }
-  if (dsize - sizeof (struct KBlock) !=
-      ntohl (kb->purpose.size) 
-      - sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) 
-      - sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) ) 
-    {
-      GNUNET_break_op (0);
-      return GNUNET_SYSERR;
-    }
-  if (GNUNET_OK !=
-      GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_FS_KBLOCK,
-                               &kb->purpose,
-                               &kb->signature,
-                               &kb->keyspace)) 
-    {
-      GNUNET_break_op (0);
-      return GNUNET_SYSERR;
-    }
-  if (query != NULL)
-    GNUNET_CRYPTO_hash (&kb->keyspace,
-                       sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
-                       query);
-  return GNUNET_OK;
-}
-
-
-/**
- * Check if the given NBlock is well-formed.
- *
- * @param nb the nblock data (or at least "dsize" bytes claiming to be one)
- * @param dsize size of "nb" in bytes; check for < sizeof(struct NBlock)!
- * @param query where to store the query that this block answers
- * @return GNUNET_OK if this is actually a well-formed NBlock
- */
-static int
-check_nblock (const struct NBlock *nb,
-             size_t dsize,
-             GNUNET_HashCode *query)
-{
-  if (dsize < sizeof (struct NBlock))
-    {
-      GNUNET_break_op (0);
-      return GNUNET_SYSERR;
-    }
-  if (dsize - sizeof (struct NBlock) !=
-      ntohl (nb->ns_purpose.size) 
-      - sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) 
-      - sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) ) 
-    {
-      GNUNET_break_op (0);
-      return GNUNET_SYSERR;
-    }
-  if (dsize !=
-      ntohl (nb->ksk_purpose.size) + sizeof (struct GNUNET_CRYPTO_RsaSignature))
-    {
-      GNUNET_break_op (0);
-      return GNUNET_SYSERR;
-    }
-  if (GNUNET_OK !=
-      GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK_KSIG,
-                               &nb->ksk_purpose,
-                               &nb->ksk_signature,
-                               &nb->keyspace)) 
-    {
-      GNUNET_break_op (0);
-      return GNUNET_SYSERR;
-    }
-  if (GNUNET_OK !=
-      GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK,
-                               &nb->ns_purpose,
-                               &nb->ns_signature,
-                               &nb->subspace)) 
-    {
-      GNUNET_break_op (0);
-      return GNUNET_SYSERR;
-    }
-  if (query != NULL)
-    GNUNET_CRYPTO_hash (&nb->keyspace,
-                       sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
-                       query);
-  return GNUNET_OK;
-}
-
-
-/**
- * Check if the given SBlock is well-formed.
- *
- * @param sb the sblock data (or at least "dsize" bytes claiming to be one)
- * @param dsize size of "kb" in bytes; check for < sizeof(struct SBlock)!
- * @param query where to store the query that this block answers
- * @return GNUNET_OK if this is actually a well-formed SBlock
- */
-static int
-check_sblock (const struct SBlock *sb,
-             size_t dsize,
-             GNUNET_HashCode *query)
-{
-  if (dsize < sizeof (struct SBlock))
-    {
-      GNUNET_break_op (0);
-      return GNUNET_SYSERR;
-    }
-  if (dsize !=
-      ntohl (sb->purpose.size) + sizeof (struct GNUNET_CRYPTO_RsaSignature))
-    {
-      GNUNET_break_op (0);
-      return GNUNET_SYSERR;
-    }
-  if (GNUNET_OK !=
-      GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_FS_SBLOCK,
-                               &sb->purpose,
-                               &sb->signature,
-                               &sb->subspace)) 
-    {
-      GNUNET_break_op (0);
-      return GNUNET_SYSERR;
-    }
-  if (query != NULL)
-    *query = sb->identifier;
-  return GNUNET_OK;
-}
-
-
-/**
- * Check if the given block is well-formed (and of the given type).
- *
- * @param type type of the block
- * @param block the block data (or at least "size" bytes claiming to be one)
- * @param size size of "kb" in bytes; check that it is large enough
- * @param query where to store the query that this block answers
- * @return GNUNET_OK if this is actually a well-formed block,
- *         GNUNET_NO if we could not determine the query,
- *         GNUNET_SYSERR if the block is malformed
- */
-int
-GNUNET_BLOCK_check_block (enum GNUNET_BLOCK_Type type,
-                         const void *block,
-                         size_t size,
-                         GNUNET_HashCode *query)
-{
-  /* first, validate! */
-  switch (type)
-    {
-    case GNUNET_BLOCK_TYPE_DBLOCK:
-    case GNUNET_BLOCK_TYPE_IBLOCK:
-      GNUNET_CRYPTO_hash (block, size, query);
-      break;
-    case GNUNET_BLOCK_TYPE_KBLOCK:
-      if (GNUNET_OK !=
-         check_kblock (block,
-                       size,
-                       query))
-       return GNUNET_SYSERR;
-      break;
-    case GNUNET_BLOCK_TYPE_SBLOCK:
-      if (GNUNET_OK !=
-         check_sblock (block,
-                       size,
-                       query))
-       return GNUNET_SYSERR;
-      break;
-    case GNUNET_BLOCK_TYPE_NBLOCK:
-      if (GNUNET_OK !=
-         check_nblock (block,
-                       size,
-                       query))
-       return GNUNET_SYSERR;
-      return GNUNET_OK;
-    case GNUNET_BLOCK_TYPE_ONDEMAND:
-      if (size != sizeof (struct OnDemandBlock))
-       return GNUNET_SYSERR;
-      memset (query, 0, sizeof (GNUNET_HashCode));      
-      return GNUNET_NO;
-    default:
-      /* unknown block type */
-      GNUNET_break_op (0);
-      return GNUNET_SYSERR;
-    }
-  return GNUNET_OK;
-}
-
-/* ***************** NEW API ******************* */
 
 /**
  * Handle for a plugin.
@@ -245,6 +46,7 @@ struct Plugin
   struct GNUNET_BLOCK_PluginFunctions *api;
 };
 
+
 /**
  * Handle to an initialized block library.
  */
@@ -262,6 +64,27 @@ struct GNUNET_BLOCK_Context
 };
 
 
+/**
+ * Mingle hash with the mingle_number to produce different bits.
+ * 
+ * @param in original hash code
+ * @param mingle_number number for hash permutation
+ * @param hc where to store the result.
+ */
+void
+GNUNET_BLOCK_mingle_hash (const GNUNET_HashCode * in,
+                         int32_t mingle_number, 
+                         GNUNET_HashCode * hc)
+{
+  GNUNET_HashCode m;
+
+  GNUNET_CRYPTO_hash (&mingle_number, 
+                     sizeof (int32_t), 
+                     &m);
+  GNUNET_CRYPTO_hash_xor (&m, in, hc);
+}
+
+
 /**
  * Create a block context.  Loads the block plugins.
  *
@@ -272,12 +95,47 @@ struct GNUNET_BLOCK_Context *
 GNUNET_BLOCK_context_create (const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
   struct GNUNET_BLOCK_Context *ctx;
+  struct GNUNET_BLOCK_PluginFunctions *api;
+  struct Plugin *plugin;
   unsigned int num_plugins;
+  char *plugs;
+  char *pos;
+  char *libname;
 
   ctx = GNUNET_malloc (sizeof (struct GNUNET_BLOCK_Context));
   ctx->cfg = cfg;
   num_plugins = 0;
-  /* FIXME: actually load plugins... */
+  if (GNUNET_OK ==
+      GNUNET_CONFIGURATION_get_value_string (cfg,
+                                             "block", "PLUGINS", &plugs))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  _("Loading block plugins `%s'\n"), plugs);
+      pos = strtok (plugs, " ");
+      while (pos != NULL)
+        {
+         GNUNET_asprintf (&libname, "libgnunet_plugin_block_%s", pos);
+         api = GNUNET_PLUGIN_load (libname, NULL);
+         if (api == NULL)
+           {
+             GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                         _("Failed to load block plugin `%s'\n"),
+                         pos);
+             GNUNET_free (libname);
+           }
+         else
+           {
+             plugin = GNUNET_malloc (sizeof (struct Plugin));
+             plugin->api = api;
+             plugin->library_name = libname;
+             GNUNET_array_append (ctx->plugins,
+                                  num_plugins,
+                                  plugin);
+           }
+          pos = strtok (NULL, " ");
+        }
+      GNUNET_free (plugs);
+    }
   GNUNET_array_append (ctx->plugins,
                       num_plugins,
                       NULL);