From: Christian Grothoff Date: Sun, 12 Sep 2010 13:08:54 +0000 (+0000) Subject: towards pluggable block library X-Git-Tag: initial-import-from-subversion-38251~20350 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=a42b4e0ed22b65631caea4bb456f3d8fc21f11b1;hp=dd253b7f7591f0869f8ea14ee111b7d3b3e480b6;p=oweals%2Fgnunet.git towards pluggable block library --- diff --git a/TODO b/TODO index 8ac9a592c..9349189b3 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,15 @@ 0.9.0pre2: +* BLOCK: + - implement FS plugin + - design new block-lib API + - move FS serivce to new block API +* FS: + - integrate with DHT + - measure latencies (core, datastore) => trust economy + - refuse content migration message (or solicit?) + - FS performance benchmarking +* DHT: + - use new block lib * CORE: - derived key generation [Nils] - Jun 27 11:51:54 core-7670 ERROR Assertion failed at gnunet-service-core.c:3616. @@ -23,7 +34,7 @@ - needs more testing (especially F2F topology) & transport blacklisting * TRANSPORT-TCP [MW]: - should use hash map to look up sessions -* NAT/UPNP: [MW] +* NAT/UPNP: [Milan] - finalize API design - code clean up - testing diff --git a/src/block/Makefile.am b/src/block/Makefile.am index b9585c260..238c48af3 100644 --- a/src/block/Makefile.am +++ b/src/block/Makefile.am @@ -1,5 +1,7 @@ INCLUDES = -I$(top_srcdir)/src/include +plugindir = $(libdir)/gnunet + if MINGW WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols endif @@ -10,8 +12,27 @@ endif lib_LTLIBRARIES = libgnunetblock.la +plugin_LTLIBRARIES = \ + libgnunet_plugin_block_fs.la \ + libgnunet_plugin_block_template.la + +libgnunet_plugin_block_fs_la_SOURCES = \ + plugin_block_fs.c +libgnunet_plugin_block_fs_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la +libgnunet_plugin_block_fs_la_LDFLAGS = \ + $(GN_PLUGIN_LDFLAGS) + +libgnunet_plugin_block_template_la_SOURCES = \ + plugin_block_template.c +libgnunet_plugin_block_template_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la +libgnunet_plugin_block_template_la_LDFLAGS = \ + $(GN_PLUGIN_LDFLAGS) + + libgnunetblock_la_SOURCES = \ - block.c + block.c plugin_block.h libgnunetblock_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la diff --git a/src/block/block.c b/src/block/block.c index 72dedd7be..cb6837499 100644 --- a/src/block/block.c +++ b/src/block/block.c @@ -27,6 +27,7 @@ #include "gnunet_util_lib.h" #include "gnunet_signatures.h" #include "gnunet_block_lib.h" +#include "plugin_block.h" /** * Check if the given KBlock is well-formed. @@ -226,5 +227,185 @@ GNUNET_BLOCK_check_block (enum GNUNET_BLOCK_Type type, return GNUNET_OK; } +/* ***************** NEW API ******************* */ + +/** + * Handle for a plugin. + */ +struct Plugin +{ + /** + * Name of the shared library. + */ + char *library_name; + + /** + * Plugin API. + */ + struct GNUNET_BLOCK_PluginFunctions *api; +}; + +/** + * Handle to an initialized block library. + */ +struct GNUNET_BLOCK_Context +{ + /** + * NULL-terminated array of our plugins. + */ + struct Plugin **plugins; + + /** + * Our configuration. + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; +}; + + +/** + * Create a block context. Loads the block plugins. + * + * @param cfg configuration to use + * @return NULL on error + */ +struct GNUNET_BLOCK_Context * +GNUNET_BLOCK_context_create (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct GNUNET_BLOCK_Context *ctx; + unsigned int num_plugins; + + ctx = GNUNET_malloc (sizeof (struct GNUNET_BLOCK_Context)); + ctx->cfg = cfg; + num_plugins = 0; + /* FIXME: actually load plugins... */ + GNUNET_array_append (ctx->plugins, + num_plugins, + NULL); + return ctx; +} + + +/** + * Destroy the block context. + * + * @param ctx context to destroy + */ +void +GNUNET_BLOCK_context_destroy (struct GNUNET_BLOCK_Context *ctx) +{ + unsigned int i; + struct Plugin *plugin; + + i = 0; + while (NULL != (plugin = ctx->plugins[i])) + { + GNUNET_break (NULL == + GNUNET_PLUGIN_unload (plugin->library_name, + plugin->api)); + GNUNET_free (plugin->library_name); + GNUNET_free (plugin); + i++; + } + GNUNET_free (ctx->plugins); + GNUNET_free (ctx); +} + + +/** + * Find a plugin for the given type. + * + * @param ctx context to search + * @param type type to look for + * @return NULL if no matching plugin exists + */ +static struct GNUNET_BLOCK_PluginFunctions * +find_plugin (struct GNUNET_BLOCK_Context *ctx, + enum GNUNET_BLOCK_Type type) +{ + struct Plugin *plugin; + unsigned int i; + unsigned int j; + + i = 0; + while (NULL != (plugin = ctx->plugins[i])) + { + j = 0; + while (0 != (plugin->api->types[j])) + { + if (type == plugin->api->types[j]) + return plugin->api; + j++; + } + i++; + } + return NULL; +} + + +/** + * Function called to validate a reply or a request. For + * request evaluation, simply pass "NULL" for the reply_block. + * Note that it is assumed that the reply has already been + * matched to the key (and signatures checked) as it would + * be done with the "get_key" function. + * + * @param ctx block contxt + * @param type block type + * @param query original query (hash) + * @param bf pointer to bloom filter associated with query; possibly updated (!) + * @param bf_mutator mutation value for bf + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in xquery + * @param reply_block response to validate + * @param reply_block_size number of bytes in reply block + * @return characterization of result + */ +enum GNUNET_BLOCK_EvaluationResult +GNUNET_BLOCK_evaluate (struct GNUNET_BLOCK_Context *ctx, + enum GNUNET_BLOCK_Type type, + const GNUNET_HashCode *query, + struct GNUNET_CONTAINER_BloomFilter **bf, + int32_t bf_mutator, + const void *xquery, + size_t xquery_size, + const void *reply_block, + size_t reply_block_size) +{ + struct GNUNET_BLOCK_PluginFunctions *plugin = find_plugin (ctx, type); + + if (plugin == NULL) + return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; + return plugin->evaluate (plugin->cls, + type, query, bf, bf_mutator, + xquery, xquery_size, reply_block, reply_block_size); +} + + +/** + * Function called to obtain the key for a block. + * + * @param ctx block context + * @param type block type + * @param block block to get the key for + * @param block_size number of bytes in block + * @param key set to the key (query) for the given block + * @return GNUNET_OK on success, GNUNET_SYSERR if type not supported + * (or if extracting a key from a block of this type does not work) + */ +int +GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx, + enum GNUNET_BLOCK_Type type, + const void *block, + size_t block_size, + GNUNET_HashCode *key) +{ + struct GNUNET_BLOCK_PluginFunctions *plugin = find_plugin (ctx, type); + + if (plugin == NULL) + return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; + return plugin->get_key (plugin->cls, + type, block, block_size, key); +} + /* end of block.c */ diff --git a/src/block/plugin_block.h b/src/block/plugin_block.h new file mode 100644 index 000000000..671f83aad --- /dev/null +++ b/src/block/plugin_block.h @@ -0,0 +1,117 @@ +/* + This file is part of GNUnet + (C) 2010 Christian Grothoff (and other contributing authors) + + 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 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. + + 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. +*/ + +/** + * @file block/plugin_block.h + * @brief API for block plugins. Each block plugin must conform to + * the API specified by this header. + * @author Christian Grothoff + */ +#ifndef PLUGIN_BLOCK_H +#define PLUGIN_BLOCK_H + +#include "gnunet_util_lib.h" +#include "gnunet_container_lib.h" +#include "gnunet_block_lib.h" + + + +/** + * Function called to validate a reply or a request. For + * request evaluation, simply pass "NULL" for the reply_block. + * Note that it is assumed that the reply has already been + * matched to the key (and signatures checked) as it would + * be done with the "get_key" function. + * + * @param cls closure + * @param type block type + * @param query original query (hash) + * @param bf pointer to bloom filter associated with query; possibly updated (!) + * @param bf_mutator mutation value for bf + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in xquery + * @param reply_block response to validate + * @param reply_block_size number of bytes in reply block + * @return characterization of result + */ +typedef enum GNUNET_BLOCK_EvaluationResult + (*GNUNET_BLOCK_EvaluationFunction) (void *cls, + enum GNUNET_BLOCK_Type type, + const GNUNET_HashCode *query, + struct GNUNET_CONTAINER_BloomFilter **bf, + int32_t bf_mutator, + const void *xquery, + size_t xquery_size, + const void *reply_block, + size_t reply_block_size); + + +/** + * Function called to obtain the key for a block. + * + * @param cls closure + * @param type block type + * @param block block to get the key for + * @param block_size number of bytes in block + * @param key set to the key (query) for the given block + * @return GNUNET_OK on success, GNUNET_SYSERR if type not supported + * (or if extracting a key from a block of this type does not work) + */ +typedef int + (*GNUNET_BLOCK_GetKeyFunction) (void *cls, + enum GNUNET_BLOCK_Type type, + const void *block, + size_t block_size, + GNUNET_HashCode *key); + + + +/** + * Each plugin is required to return a pointer to a struct of this + * type as the return value from its entry point. + */ +struct GNUNET_BLOCK_PluginFunctions +{ + + /** + * Closure for all of the callbacks. + */ + void *cls; + + /** + * 0-terminated array of block types supported by this plugin. + */ + const enum GNUNET_BLOCK_Type *types; + + /** + * Main function of a block plugin. Allows us to check if a + * block matches a query. + */ + GNUNET_BLOCK_EvaluationFunction evaluate; + + /** + * Obtain the key for a given block (if possible). + */ + GNUNET_BLOCK_GetKeyFunction get_key; + +}; + + +#endif diff --git a/src/block/plugin_block_fs.c b/src/block/plugin_block_fs.c new file mode 100644 index 000000000..362932991 --- /dev/null +++ b/src/block/plugin_block_fs.c @@ -0,0 +1,346 @@ +/* + This file is part of GNUnet + (C) 2010 Christian Grothoff (and other contributing authors) + + 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 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. + + 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. +*/ + +/** + * @file block/plugin_block_fs.c + * @brief blocks used for file-sharing + * @author Christian Grothoff + */ + +#include "platform.h" +#include "plugin_block.h" +#include "gnunet_signatures.h" + +#define DEBUG_FS_BLOCK GNUNET_NO + +/** + * Number of bits we set per entry in the bloomfilter. + * Do not change! + */ +#define BLOOMFILTER_K 16 + +/** + * Mingle hash with the mingle_number to produce different bits. + */ +static void +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); +} + + +/** + * Function called to validate a reply or a request. For + * request evaluation, simply pass "NULL" for the reply_block. + * Note that it is assumed that the reply has already been + * matched to the key (and signatures checked) as it would + * be done with the "get_key" function. + * + * @param cls closure + * @param type block type + * @param query original query (hash) + * @param bf pointer to bloom filter associated with query; possibly updated (!) + * @param bf_mutator mutation value for bf + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in xquery + * @param reply_block response to validate + * @param reply_block_size number of bytes in reply block + * @return characterization of result + */ +static enum GNUNET_BLOCK_EvaluationResult +block_plugin_fs_evaluate (void *cls, + enum GNUNET_BLOCK_Type type, + const GNUNET_HashCode *query, + struct GNUNET_CONTAINER_BloomFilter **bf, + int32_t bf_mutator, + const void *xquery, + size_t xquery_size, + const void *reply_block, + size_t reply_block_size) +{ + const struct SBlock *sb; + GNUNET_HashCode chash; + GNUNET_HashCode mhash; + const GNUNET_HashCode *nsid; + GNUNET_HashCode sh; + + switch (type) + { + case GNUNET_BLOCK_TYPE_DBLOCK: + case GNUNET_BLOCK_TYPE_IBLOCK: + if (xquery_size != 0) + { + GNUNET_break_op (0); + return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; + } + return GNUNET_BLOCK_EVALUATION_OK_LAST; + case GNUNET_BLOCK_TYPE_KBLOCK: + case GNUNET_BLOCK_TYPE_NBLOCK: + if (xquery_size != 0) + { + GNUNET_break_op (0); + return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; + } + if (reply_block == NULL) + return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; + GNUNET_CRYPTO_hash (reply_block, + reply_block_size, + &chash); + mingle_hash (&chash, bf_mutator, &mhash); + if (NULL != *bf) + { + if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (*bf, + &mhash)) + return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; + } + else + { + *bf = GNUNET_CONTAINER_bloomfilter_init (NULL, + 8, + BLOOMFILTER_K); + } + GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash); + return GNUNET_BLOCK_EVALUATION_OK_MORE; + case GNUNET_BLOCK_TYPE_SBLOCK: + if (xquery_size != sizeof (GNUNET_HashCode)) + { + GNUNET_break_op (0); + return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; + } + if (reply_block == NULL) + return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; + nsid = xquery; + if (reply_block_size < sizeof (struct NBlock)) + return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + sb = reply_block; + GNUNET_CRYPTO_hash (&sb->subspace, + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &sh); + if (0 != memcmp (nsid, + &sh, + sizeof (GNUNET_HashCode))) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Reply mismatched in terms of namespace. Discarded.\n")); + return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + } + GNUNET_CRYPTO_hash (reply_block, + reply_block_size, + &chash); + mingle_hash (&chash, bf_mutator, &mhash); + if (NULL != *bf) + { + if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (*bf, + &mhash)) + return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; + } + else + { + *bf = GNUNET_CONTAINER_bloomfilter_init (NULL, + 8, + BLOOMFILTER_K); + } + GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash); + return GNUNET_BLOCK_EVALUATION_OK_MORE; + default: + return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; + } +} + + +/** + * Function called to obtain the key for a block. + * + * @param cls closure + * @param type block type + * @param block block to get the key for + * @param block_size number of bytes in block + * @param key set to the key (query) for the given block + * @return GNUNET_OK on success, GNUNET_SYSERR if type not supported + * (or if extracting a key from a block of this type does not work) + */ +static int +block_plugin_fs_get_key (void *cls, + enum GNUNET_BLOCK_Type type, + const void *block, + size_t block_size, + GNUNET_HashCode *key) +{ + const struct KBlock *kb; + const struct SBlock *sb; + const struct NBlock *nb; + + switch (type) + { + case GNUNET_BLOCK_TYPE_DBLOCK: + case GNUNET_BLOCK_TYPE_IBLOCK: + GNUNET_CRYPTO_hash (block, block_size, key); + return GNUNET_OK; + case GNUNET_BLOCK_TYPE_KBLOCK: + if (block_size < sizeof (struct KBlock)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + kb = block; + if (block_size - 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 (key != NULL) + GNUNET_CRYPTO_hash (&kb->keyspace, + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + key); + return GNUNET_OK; + case GNUNET_BLOCK_TYPE_SBLOCK: + if (block_size < sizeof (struct SBlock)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + sb = block; + if (block_size != + 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 (key != NULL) + *key = sb->identifier; + return GNUNET_OK; + case GNUNET_BLOCK_TYPE_NBLOCK: + if (block_size < sizeof (struct NBlock)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + nb = block; + if (block_size - 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 (block_size != + 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; + } + /* FIXME: we used to xor ID with NSID, + why not here? */ + if (key != NULL) + GNUNET_CRYPTO_hash (&nb->keyspace, + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + key); + return GNUNET_OK; + default: + return GNUNET_SYSERR; + } +} + + +/** + * Entry point for the plugin. + */ +void * +gnunet_plugin_block_fs_init (void *cls) +{ + static enum GNUNET_BLOCK_Type types[] = + { + GNUNET_BLOCK_TYPE_DBLOCK, + GNUNET_BLOCK_TYPE_IBLOCK, + GNUNET_BLOCK_TYPE_KBLOCK, + GNUNET_BLOCK_TYPE_SBLOCK, + GNUNET_BLOCK_TYPE_NBLOCK, + GNUNET_BLOCK_TYPE_ANY /* end of list */ + }; + struct GNUNET_BLOCK_PluginFunctions *api; + + api = GNUNET_malloc (sizeof (struct GNUNET_BLOCK_PluginFunctions)); + api->evaluate = &block_plugin_fs_evaluate; + api->get_key = &block_plugin_fs_get_key; + api->types = types; + return api; +} + + +/** + * Exit point from the plugin. + */ +void * +gnunet_plugin_block_fs_done (void *cls) +{ + struct GNUNET_TRANSPORT_PluginFunctions *api = cls; + + GNUNET_free (api); + return NULL; +} + +/* end of plugin_block_fs.c */ diff --git a/src/block/plugin_block_template.c b/src/block/plugin_block_template.c new file mode 100644 index 000000000..016a3fc8f --- /dev/null +++ b/src/block/plugin_block_template.c @@ -0,0 +1,118 @@ +/* + This file is part of GNUnet + (C) 2010 Christian Grothoff (and other contributing authors) + + 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 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. + + 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. +*/ + +/** + * @file block/plugin_block_template.c + * @brief template for a block plugin + * @author Christian Grothoff + */ + +#include "platform.h" +#include "plugin_block.h" + +#define DEBUG_TEMPLATE GNUNET_NO + + +/** + * Function called to validate a reply or a request. For + * request evaluation, simply pass "NULL" for the reply_block. + * + * @param cls closure + * @param type block type + * @param query original query (hash) + * @param bf pointer to bloom filter associated with query; possibly updated (!) + * @param bf_mutator mutation value for bf + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in xquery + * @param reply_block response to validate + * @param reply_block_size number of bytes in reply block + * @return characterization of result + */ +static enum GNUNET_BLOCK_EvaluationResult +block_plugin_template_evaluate (void *cls, + enum GNUNET_BLOCK_Type type, + const GNUNET_HashCode *query, + struct GNUNET_CONTAINER_BloomFilter **bf, + int32_t bf_mutator, + const void *xquery, + size_t xquery_size, + const void *reply_block, + size_t reply_block_size) +{ + return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; +} + + +/** + * Function called to obtain the key for a block. + * + * @param cls closure + * @param type block type + * @param block block to get the key for + * @param block_size number of bytes in block + * @param key set to the key (query) for the given block + * @return GNUNET_OK on success, GNUNET_SYSERR if type not supported + * (or if extracting a key from a block of this type does not work) + */ +static int +block_plugin_template_get_key (void *cls, + enum GNUNET_BLOCK_Type type, + const void *block, + size_t block_size, + GNUNET_HashCode *key) +{ + return GNUNET_SYSERR; +} + + +/** + * Entry point for the plugin. + */ +void * +gnunet_plugin_block_template_init (void *cls) +{ + static enum GNUNET_BLOCK_Type types[] = + { + /* FIXME: insert supported block types here */ + GNUNET_BLOCK_TYPE_ANY /* end of list */ + }; + struct GNUNET_BLOCK_PluginFunctions *api; + + api = GNUNET_malloc (sizeof (struct GNUNET_BLOCK_PluginFunctions)); + api->evaluate = &block_plugin_template_evaluate; + api->get_key = &block_plugin_template_get_key; + api->types = types; + return api; +} + + +/** + * Exit point from the plugin. + */ +void * +gnunet_plugin_block_template_done (void *cls) +{ + struct GNUNET_TRANSPORT_PluginFunctions *api = cls; + + GNUNET_free (api); + return NULL; +} + +/* end of plugin_block_template.c */ diff --git a/src/include/gnunet_block_lib.h b/src/include/gnunet_block_lib.h index 0bd9848d7..ace4f23bb 100644 --- a/src/include/gnunet_block_lib.h +++ b/src/include/gnunet_block_lib.h @@ -35,6 +35,7 @@ extern "C" #endif #endif + /** * Blocks in the datastore and the datacache must have a unique type. */ @@ -82,6 +83,8 @@ enum GNUNET_BLOCK_Type }; +/* **************** FIXME: move these to block_fs.h or so ***************** */ + /** * @brief keyword block (advertising data under a keyword) */ @@ -216,6 +219,8 @@ struct OnDemandBlock }; +/* **************** OLD API ***************** */ + /** * Check if the given block is well-formed (and of the given type). * @@ -234,6 +239,126 @@ GNUNET_BLOCK_check_block (enum GNUNET_BLOCK_Type type, GNUNET_HashCode *query); +/* **************** NEW API ***************** */ + +/** + * Possible ways for how a block may relate to a query. + */ +enum GNUNET_BLOCK_EvaluationResult + { + /** + * Valid result, and there may be more. + */ + GNUNET_BLOCK_EVALUATION_OK_MORE = 0, + + /** + * Last possible valid result. + */ + GNUNET_BLOCK_EVALUATION_OK_LAST = 1, + + /** + * Valid result, but suppressed because it is a duplicate. + */ + GNUNET_BLOCK_EVALUATION_OK_DUPLICATE = 2, + + /** + * Block does not match query (invalid result) + */ + GNUNET_BLOCK_EVALUATION_RESULT_INVALID = 3, + + /** + * Query is valid, no reply given. + */ + GNUNET_BLOCK_EVALUATION_REQUEST_VALID = 4, + + /** + * Query format does not match block type (invalid query). For + * example, xquery not given or xquery_size not appropriate for + * type. + */ + GNUNET_BLOCK_EVALUATION_REQUEST_INVALID = 5, + + /** + * Specified block type not supported by this plugin. + */ + GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED = 6 + }; + + +/** + * Handle to an initialized block library. + */ +struct GNUNET_BLOCK_Context; + + +/** + * Create a block context. Loads the block plugins. + * + * @param cfg configuration to use + * @return NULL on error + */ +struct GNUNET_BLOCK_Context * +GNUNET_BLOCK_context_create (const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Destroy the block context. + * + * @param ctx context to destroy + */ +void +GNUNET_BLOCK_context_destroy (struct GNUNET_BLOCK_Context *ctx); + + +/** + * Function called to validate a reply or a request. For + * request evaluation, simply pass "NULL" for the reply_block. + * Note that it is assumed that the reply has already been + * matched to the key (and signatures checked) as it would + * be done with the "get_key" function. + * + * @param ctx block contxt + * @param type block type + * @param query original query (hash) + * @param bf pointer to bloom filter associated with query; possibly updated (!) + * @param bf_mutator mutation value for bf + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in xquery + * @param reply_block response to validate + * @param reply_block_size number of bytes in reply block + * @return characterization of result + */ +enum GNUNET_BLOCK_EvaluationResult +GNUNET_BLOCK_evaluate (struct GNUNET_BLOCK_Context *ctx, + enum GNUNET_BLOCK_Type type, + const GNUNET_HashCode *query, + struct GNUNET_CONTAINER_BloomFilter **bf, + int32_t bf_mutator, + const void *xquery, + size_t xquery_size, + const void *reply_block, + size_t reply_block_size); + + +/** + * Function called to obtain the key for a block. + * + * @param ctx block context + * @param type block type + * @param block block to get the key for + * @param block_size number of bytes in block + * @param key set to the key (query) for the given block + * @return GNUNET_OK on success, GNUNET_SYSERR if type not supported + * (or if extracting a key from a block of this type does not work) + */ +int +GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx, + enum GNUNET_BLOCK_Type type, + const void *block, + size_t block_size, + GNUNET_HashCode *key); + + #if 0 /* keep Emacsens' auto-indent happy */ { #endif diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index cb258a125..d0187af8b 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am @@ -73,7 +73,7 @@ bin_SCRIPTS = \ gnunet_nat_server_SOURCES = \ $(NATSERVER) - + gnunet_transport_wlan_helper_SOURCES = \ gnunet-transport-wlan-helper.c gnunet_transport_wlan_helper_LDADD = \ @@ -296,13 +296,13 @@ test_transport_api_https_SOURCES = \ test_transport_api_https_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/util/libgnunetutil.la - + test_transport_api_reliability_https_SOURCES = \ test_transport_api_reliability.c test_transport_api_reliability_https_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/util/libgnunetutil.la - + endif EXTRA_DIST = \