From d9a610d5d7c6d5c59f7c75385dcc9767c06bd5c3 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 22 Nov 2011 11:53:26 +0000 Subject: moving block plugins to respective subsystem --- TODO | 18 +-- src/block/Makefile.am | 32 ----- src/block/plugin_block_dht.c | 181 ------------------------ src/block/plugin_block_dns.c | 170 ----------------------- src/block/plugin_block_fs.c | 322 ------------------------------------------- src/dht/Makefile.am | 18 ++- src/dht/plugin_block_dht.c | 181 ++++++++++++++++++++++++ src/fs/Makefile.am | 18 +++ src/fs/plugin_block_fs.c | 322 +++++++++++++++++++++++++++++++++++++++++++ src/vpn/Makefile.am | 14 ++ src/vpn/plugin_block_dns.c | 170 +++++++++++++++++++++++ 11 files changed, 728 insertions(+), 718 deletions(-) delete mode 100644 src/block/plugin_block_dht.c delete mode 100644 src/block/plugin_block_dns.c delete mode 100644 src/block/plugin_block_fs.c create mode 100644 src/dht/plugin_block_dht.c create mode 100644 src/fs/plugin_block_fs.c create mode 100644 src/vpn/plugin_block_dns.c diff --git a/TODO b/TODO index 3607193e3..3521304e3 100644 --- a/TODO +++ b/TODO @@ -1,22 +1,12 @@ 0.9.0: -* GNUNET-GTK: [CG] - - provide context menus to allow aborts of downloads/uploads - - provide way to handle errors (search, download, publish errors) * new webpage: - write chapter on DHT/block [Nate] - - make a NICE download page * big code review * Determine RC bugs and fix those (release should have no known real bugs) * Transport: - When receiving SESSION_CONNECT: actually consider switching session (test this!) * FS [CG] - - implement multi-peer FS performance tests + gauger them! - + insert - + download - + search -* blocks: - + should block plugins live in block/ or with fs/dht/vpn? 0.9.1: * TRANSPORT: [MW] @@ -41,8 +31,10 @@ - Remove KBlocks in gnunet-unindex (see discussion with Kenneth Almquist on gnunet-devs in 9/2009) - use different queue prioritization for probe-downloads vs. normal downloads - re-implement gnunet-auto-share - - implement 'GNUNET_FS_file_information_create_from_directory', avoiding - code duplication with gnunet-gtk's similar code (!) + - implement multi-peer FS performance tests + gauger them! + + insert + + download + + search * GNUNET-GTK: [CG] - add tool bar - do meaningful update to status line (starting up, peer running, #connections, shutdown, ...) @@ -56,6 +48,8 @@ + normalize keywords (edit subdialog) - implement download by URI dialog; figure out where to display those downloads! - add combo box to select desired mime type for search + - provide context menus to allow aborts of downloads/uploads + - provide way to handle errors (search, download, publish errors) * ARM: [CG] - better tracking of which config changes actually need to cause process restarts by ARM. - handle gnunet-arm -k in combination with auto-start magic (what is the right thing here?) diff --git a/src/block/Makefile.am b/src/block/Makefile.am index cfbcb797f..39de6edf0 100644 --- a/src/block/Makefile.am +++ b/src/block/Makefile.am @@ -13,41 +13,9 @@ endif lib_LTLIBRARIES = libgnunetblock.la plugin_LTLIBRARIES = \ - libgnunet_plugin_block_dht.la \ - libgnunet_plugin_block_fs.la \ libgnunet_plugin_block_template.la \ - libgnunet_plugin_block_dns.la \ libgnunet_plugin_block_test.la -libgnunet_plugin_block_dht_la_SOURCES = \ - plugin_block_dht.c -libgnunet_plugin_block_dht_la_LIBADD = \ - $(top_builddir)/src/hello/libgnunethello.la \ - $(top_builddir)/src/block/libgnunetblock.la \ - $(top_builddir)/src/util/libgnunetutil.la -libgnunet_plugin_block_dht_la_LDFLAGS = \ - $(GN_PLUGIN_LDFLAGS) -libgnunet_plugin_block_dht_la_DEPENDENCIES = \ - libgnunetblock.la - - -libgnunet_plugin_block_fs_la_SOURCES = \ - plugin_block_fs.c -libgnunet_plugin_block_fs_la_LIBADD = \ - $(top_builddir)/src/block/libgnunetblock.la \ - $(top_builddir)/src/util/libgnunetutil.la -libgnunet_plugin_block_fs_la_LDFLAGS = \ - $(GN_PLUGIN_LDFLAGS) -libgnunet_plugin_block_fs_la_DEPENDENCIES = \ - libgnunetblock.la - - -libgnunet_plugin_block_dns_la_SOURCES = \ - plugin_block_dns.c -libgnunet_plugin_block_dns_la_LIBADD = \ - $(top_builddir)/src/util/libgnunetutil.la -libgnunet_plugin_block_dns_la_LDFLAGS = \ - $(GN_PLUGIN_LDFLAGS) libgnunet_plugin_block_template_la_SOURCES = \ plugin_block_template.c diff --git a/src/block/plugin_block_dht.c b/src/block/plugin_block_dht.c deleted file mode 100644 index f574e6d06..000000000 --- a/src/block/plugin_block_dht.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - 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_dht.c - * @brief block plugin for DHT internals (right now, find-peer requests only); - * other plugins should be used to store "useful" data in the - * DHT (see fs block plugin) - * @author Christian Grothoff - */ - -#include "platform.h" -#include "gnunet_constants.h" -#include "gnunet_hello_lib.h" -#include "gnunet_block_plugin.h" - -#define DEBUG_DHT GNUNET_EXTRA_LOGGING - - -/** - * 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 extended 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_dht_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) -{ - GNUNET_HashCode mhash; - const struct GNUNET_HELLO_Message *hello; - struct GNUNET_PeerIdentity pid; - const struct GNUNET_MessageHeader *msg; - - if (type != GNUNET_BLOCK_TYPE_DHT_HELLO) - return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; - if (xquery_size != 0) - return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; - if (reply_block_size == 0) - return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; - if (reply_block_size < sizeof (struct GNUNET_MessageHeader)) - return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; - msg = reply_block; - if (reply_block_size != ntohs (msg->size)) - return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; - hello = reply_block; - if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid)) - return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; - if (NULL != bf) - { - GNUNET_BLOCK_mingle_hash (&pid.hashPubKey, 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, - GNUNET_CONSTANTS_BLOOMFILTER_K); - } - GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash); - } - return GNUNET_BLOCK_EVALUATION_OK_MORE; -} - - -/** - * 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_dht_get_key (void *cls, enum GNUNET_BLOCK_Type type, - const void *block, size_t block_size, - GNUNET_HashCode * key) -{ - const struct GNUNET_MessageHeader *msg; - const struct GNUNET_HELLO_Message *hello; - struct GNUNET_PeerIdentity *pid; - - if (type != GNUNET_BLOCK_TYPE_DHT_HELLO) - return GNUNET_SYSERR; - if (block_size < sizeof (struct GNUNET_MessageHeader)) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "block-dht", - _("Block not of type %u\n"), GNUNET_BLOCK_TYPE_DHT_HELLO); - return GNUNET_NO; - } - msg = block; - if (block_size != ntohs (msg->size)) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "block-dht", - _("Size mismatch for block\n"), - GNUNET_BLOCK_TYPE_DHT_HELLO); - return GNUNET_NO; - } - hello = block; - pid = (struct GNUNET_PeerIdentity *) key; - if (GNUNET_OK != GNUNET_HELLO_get_id (hello, pid)) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "block-dht", - _("Block of type %u is malformed\n"), - GNUNET_BLOCK_TYPE_DHT_HELLO); - return GNUNET_NO; - } - return GNUNET_OK; -} - - -/** - * Entry point for the plugin. - */ -void * -libgnunet_plugin_block_dht_init (void *cls) -{ - static enum GNUNET_BLOCK_Type types[] = - { - GNUNET_BLOCK_TYPE_DHT_HELLO, - GNUNET_BLOCK_TYPE_ANY /* end of list */ - }; - struct GNUNET_BLOCK_PluginFunctions *api; - - api = GNUNET_malloc (sizeof (struct GNUNET_BLOCK_PluginFunctions)); - api->evaluate = &block_plugin_dht_evaluate; - api->get_key = &block_plugin_dht_get_key; - api->types = types; - return api; -} - - -/** - * Exit point from the plugin. - */ -void * -libgnunet_plugin_block_dht_done (void *cls) -{ - struct GNUNET_TRANSPORT_PluginFunctions *api = cls; - - GNUNET_free (api); - return NULL; -} - -/* end of plugin_block_dht.c */ diff --git a/src/block/plugin_block_dns.c b/src/block/plugin_block_dns.c deleted file mode 100644 index b33b3798a..000000000 --- a/src/block/plugin_block_dns.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - 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_dns.c - * @brief block plugin for storing .gnunet-bindings - * @author Philipp Tölke - */ - -#include "platform.h" -#include "gnunet_block_plugin.h" -#include "block_dns.h" -#include "gnunet_signatures.h" - -#define DEBUG_DHT GNUNET_EXTRA_LOGGING - -/** - * 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 extended 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_dns_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) -{ - switch (type) - { - case GNUNET_BLOCK_TYPE_DNS: - if (xquery_size != 0) - return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; - - if (reply_block_size == 0) - return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; - - if (reply_block_size != sizeof (struct GNUNET_DNS_Record)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "DNS-Block is invalid: reply_block_size=%d != %d\n", - reply_block_size, sizeof (struct GNUNET_DNS_Record)); - return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; - } - - const struct GNUNET_DNS_Record *rec = reply_block; - - if (ntohl (rec->purpose.size) != - sizeof (struct GNUNET_DNS_Record) - - sizeof (struct GNUNET_CRYPTO_RsaSignature)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "DNS-Block is invalid: rec->purpose.size=%d != %d\n", - ntohl (rec->purpose.size), - sizeof (struct GNUNET_DNS_Record) - - sizeof (struct GNUNET_CRYPTO_RsaSignature)); - return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; - } - - if (GNUNET_TIME_relative_get_zero ().rel_value == - GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh - (rec->expiration_time)).rel_value) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "DNS-Block is invalid: Timeout\n"); - return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; - } - - if (GNUNET_OK != - GNUNET_CRYPTO_rsa_verify (htonl (GNUNET_SIGNATURE_PURPOSE_DNS_RECORD), - &rec->purpose, &rec->signature, &rec->peer)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "DNS-Block is invalid: invalid signature\n"); - return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; - } - - /* How to decide whether there are no more? */ - 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_dns_get_key (void *cls, enum GNUNET_BLOCK_Type type, - const void *block, size_t block_size, - GNUNET_HashCode * key) -{ - if (type != GNUNET_BLOCK_TYPE_DNS) - return GNUNET_SYSERR; - const struct GNUNET_DNS_Record *rec = block; - - memcpy (key, &rec->service_descriptor, sizeof (GNUNET_HashCode)); - return GNUNET_OK; -} - -/** - * Entry point for the plugin. - */ -void * -libgnunet_plugin_block_dns_init (void *cls) -{ - static enum GNUNET_BLOCK_Type types[] = - { - GNUNET_BLOCK_TYPE_DNS, - GNUNET_BLOCK_TYPE_ANY /* end of list */ - }; - struct GNUNET_BLOCK_PluginFunctions *api; - - api = GNUNET_malloc (sizeof (struct GNUNET_BLOCK_PluginFunctions)); - api->evaluate = &block_plugin_dns_evaluate; - api->get_key = &block_plugin_dns_get_key; - api->types = types; - return api; -} - - -/** - * Exit point from the plugin. - */ -void * -libgnunet_plugin_block_dns_done (void *cls) -{ - struct GNUNET_TRANSPORT_PluginFunctions *api = cls; - - GNUNET_free (api); - return NULL; -} - -/* end of plugin_block_dns.c */ diff --git a/src/block/plugin_block_fs.c b/src/block/plugin_block_fs.c deleted file mode 100644 index c1b4ad7c8..000000000 --- a/src/block/plugin_block_fs.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - 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 "gnunet_block_plugin.h" -#include "block_fs.h" -#include "gnunet_signatures.h" - -#define DEBUG_FS_BLOCK GNUNET_EXTRA_LOGGING - -/** - * Number of bits we set per entry in the bloomfilter. - * Do not change! - */ -#define BLOOMFILTER_K 16 - -/** - * 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_FS_DBLOCK: - case GNUNET_BLOCK_TYPE_FS_IBLOCK: - if (xquery_size != 0) - { - GNUNET_break_op (0); - return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; - } - if (reply_block == NULL) - return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; - return GNUNET_BLOCK_EVALUATION_OK_LAST; - case GNUNET_BLOCK_TYPE_FS_KBLOCK: - case GNUNET_BLOCK_TYPE_FS_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; - if (NULL != bf) - { - GNUNET_CRYPTO_hash (reply_block, reply_block_size, &chash); - GNUNET_BLOCK_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_FS_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 SBlock)) - { - GNUNET_break_op (0); - 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_from (GNUNET_ERROR_TYPE_WARNING, "block-fs", - _ - ("Reply mismatched in terms of namespace. Discarded.\n")); - return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; - } - if (NULL != bf) - { - GNUNET_CRYPTO_hash (reply_block, reply_block_size, &chash); - GNUNET_BLOCK_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_FS_DBLOCK: - case GNUNET_BLOCK_TYPE_FS_IBLOCK: - GNUNET_CRYPTO_hash (block, block_size, key); - return GNUNET_OK; - case GNUNET_BLOCK_TYPE_FS_KBLOCK: - if (block_size < sizeof (struct KBlock)) - { - GNUNET_break_op (0); - return GNUNET_NO; - } - 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_NO; - } - if (GNUNET_OK != - GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_FS_KBLOCK, - &kb->purpose, &kb->signature, &kb->keyspace)) - { - GNUNET_break_op (0); - return GNUNET_NO; - } - if (key != NULL) - GNUNET_CRYPTO_hash (&kb->keyspace, - sizeof (struct - GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - key); - return GNUNET_OK; - case GNUNET_BLOCK_TYPE_FS_SBLOCK: - if (block_size < sizeof (struct SBlock)) - { - GNUNET_break_op (0); - return GNUNET_NO; - } - sb = block; - if (block_size != - ntohl (sb->purpose.size) + sizeof (struct GNUNET_CRYPTO_RsaSignature)) - { - GNUNET_break_op (0); - return GNUNET_NO; - } - if (GNUNET_OK != - GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_FS_SBLOCK, - &sb->purpose, &sb->signature, &sb->subspace)) - { - GNUNET_break_op (0); - return GNUNET_NO; - } - if (key != NULL) - *key = sb->identifier; - return GNUNET_OK; - case GNUNET_BLOCK_TYPE_FS_NBLOCK: - if (block_size < sizeof (struct NBlock)) - { - GNUNET_break_op (0); - return GNUNET_NO; - } - 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_NO; - } - if (block_size != - ntohl (nb->ksk_purpose.size) + - sizeof (struct GNUNET_CRYPTO_RsaSignature)) - { - GNUNET_break_op (0); - return GNUNET_NO; - } - 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_NO; - } - 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_NO; - } - /* 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 * -libgnunet_plugin_block_fs_init (void *cls) -{ - static enum GNUNET_BLOCK_Type types[] = - { - GNUNET_BLOCK_TYPE_FS_DBLOCK, - GNUNET_BLOCK_TYPE_FS_IBLOCK, - GNUNET_BLOCK_TYPE_FS_KBLOCK, - GNUNET_BLOCK_TYPE_FS_SBLOCK, - GNUNET_BLOCK_TYPE_FS_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 * -libgnunet_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/dht/Makefile.am b/src/dht/Makefile.am index ad1d05d25..b2bbf5897 100644 --- a/src/dht/Makefile.am +++ b/src/dht/Makefile.am @@ -22,7 +22,6 @@ endif lib_LTLIBRARIES = \ libgnunetdht.la - libgnunetdht_la_SOURCES = \ dht_api.c dht.h libgnunetdht_la_LIBADD = \ @@ -32,6 +31,23 @@ libgnunetdht_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ -version-info 0:0:0 + +plugin_LTLIBRARIES = \ + libgnunet_plugin_block_dht.la + +libgnunet_plugin_block_dht_la_SOURCES = \ + plugin_block_dht.c +libgnunet_plugin_block_dht_la_LIBADD = \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/block/libgnunetblock.la \ + $(top_builddir)/src/util/libgnunetutil.la +libgnunet_plugin_block_dht_la_LDFLAGS = \ + $(GN_PLUGIN_LDFLAGS) +libgnunet_plugin_block_dht_la_DEPENDENCIES = \ + $(top_builddir)/src/block/libgnunetblock.la + + + bin_PROGRAMS = \ gnunet-service-dht \ gnunet-dht-get \ diff --git a/src/dht/plugin_block_dht.c b/src/dht/plugin_block_dht.c new file mode 100644 index 000000000..f574e6d06 --- /dev/null +++ b/src/dht/plugin_block_dht.c @@ -0,0 +1,181 @@ +/* + 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_dht.c + * @brief block plugin for DHT internals (right now, find-peer requests only); + * other plugins should be used to store "useful" data in the + * DHT (see fs block plugin) + * @author Christian Grothoff + */ + +#include "platform.h" +#include "gnunet_constants.h" +#include "gnunet_hello_lib.h" +#include "gnunet_block_plugin.h" + +#define DEBUG_DHT GNUNET_EXTRA_LOGGING + + +/** + * 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 extended 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_dht_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) +{ + GNUNET_HashCode mhash; + const struct GNUNET_HELLO_Message *hello; + struct GNUNET_PeerIdentity pid; + const struct GNUNET_MessageHeader *msg; + + if (type != GNUNET_BLOCK_TYPE_DHT_HELLO) + return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; + if (xquery_size != 0) + return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; + if (reply_block_size == 0) + return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; + if (reply_block_size < sizeof (struct GNUNET_MessageHeader)) + return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + msg = reply_block; + if (reply_block_size != ntohs (msg->size)) + return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + hello = reply_block; + if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid)) + return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + if (NULL != bf) + { + GNUNET_BLOCK_mingle_hash (&pid.hashPubKey, 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, + GNUNET_CONSTANTS_BLOOMFILTER_K); + } + GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash); + } + return GNUNET_BLOCK_EVALUATION_OK_MORE; +} + + +/** + * 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_dht_get_key (void *cls, enum GNUNET_BLOCK_Type type, + const void *block, size_t block_size, + GNUNET_HashCode * key) +{ + const struct GNUNET_MessageHeader *msg; + const struct GNUNET_HELLO_Message *hello; + struct GNUNET_PeerIdentity *pid; + + if (type != GNUNET_BLOCK_TYPE_DHT_HELLO) + return GNUNET_SYSERR; + if (block_size < sizeof (struct GNUNET_MessageHeader)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "block-dht", + _("Block not of type %u\n"), GNUNET_BLOCK_TYPE_DHT_HELLO); + return GNUNET_NO; + } + msg = block; + if (block_size != ntohs (msg->size)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "block-dht", + _("Size mismatch for block\n"), + GNUNET_BLOCK_TYPE_DHT_HELLO); + return GNUNET_NO; + } + hello = block; + pid = (struct GNUNET_PeerIdentity *) key; + if (GNUNET_OK != GNUNET_HELLO_get_id (hello, pid)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "block-dht", + _("Block of type %u is malformed\n"), + GNUNET_BLOCK_TYPE_DHT_HELLO); + return GNUNET_NO; + } + return GNUNET_OK; +} + + +/** + * Entry point for the plugin. + */ +void * +libgnunet_plugin_block_dht_init (void *cls) +{ + static enum GNUNET_BLOCK_Type types[] = + { + GNUNET_BLOCK_TYPE_DHT_HELLO, + GNUNET_BLOCK_TYPE_ANY /* end of list */ + }; + struct GNUNET_BLOCK_PluginFunctions *api; + + api = GNUNET_malloc (sizeof (struct GNUNET_BLOCK_PluginFunctions)); + api->evaluate = &block_plugin_dht_evaluate; + api->get_key = &block_plugin_dht_get_key; + api->types = types; + return api; +} + + +/** + * Exit point from the plugin. + */ +void * +libgnunet_plugin_block_dht_done (void *cls) +{ + struct GNUNET_TRANSPORT_PluginFunctions *api = cls; + + GNUNET_free (api); + return NULL; +} + +/* end of plugin_block_dht.c */ diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am index b1f15afa3..22201b45a 100644 --- a/src/fs/Makefile.am +++ b/src/fs/Makefile.am @@ -14,9 +14,14 @@ pkgcfgdir= $(pkgdatadir)/config.d/ dist_pkgcfg_DATA = \ fs.conf +plugindir = $(libdir)/gnunet + lib_LTLIBRARIES = libgnunetfs.la +plugin_LTLIBRARIES = \ + libgnunet_plugin_block_fs.la + noinst_LIBRARIES = libgnunetfstest.a libgnunetfs_la_SOURCES = \ @@ -151,6 +156,19 @@ gnunet_unindex_LDADD = \ gnunet_unindex_DEPENDENCIES = \ libgnunetfs.la + +libgnunet_plugin_block_fs_la_SOURCES = \ + plugin_block_fs.c +libgnunet_plugin_block_fs_la_LIBADD = \ + $(top_builddir)/src/block/libgnunetblock.la \ + $(top_builddir)/src/util/libgnunetutil.la +libgnunet_plugin_block_fs_la_LDFLAGS = \ + $(GN_PLUGIN_LDFLAGS) +libgnunet_plugin_block_fs_la_DEPENDENCIES = \ + $(top_builddir)/src/block/libgnunetblock.la + + + if HAVE_BENCHMARKS FS_BENCHMARKS = \ perf_gnunet_service_fs_p2p \ diff --git a/src/fs/plugin_block_fs.c b/src/fs/plugin_block_fs.c new file mode 100644 index 000000000..c1b4ad7c8 --- /dev/null +++ b/src/fs/plugin_block_fs.c @@ -0,0 +1,322 @@ +/* + 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 "gnunet_block_plugin.h" +#include "block_fs.h" +#include "gnunet_signatures.h" + +#define DEBUG_FS_BLOCK GNUNET_EXTRA_LOGGING + +/** + * Number of bits we set per entry in the bloomfilter. + * Do not change! + */ +#define BLOOMFILTER_K 16 + +/** + * 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_FS_DBLOCK: + case GNUNET_BLOCK_TYPE_FS_IBLOCK: + if (xquery_size != 0) + { + GNUNET_break_op (0); + return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; + } + if (reply_block == NULL) + return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; + return GNUNET_BLOCK_EVALUATION_OK_LAST; + case GNUNET_BLOCK_TYPE_FS_KBLOCK: + case GNUNET_BLOCK_TYPE_FS_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; + if (NULL != bf) + { + GNUNET_CRYPTO_hash (reply_block, reply_block_size, &chash); + GNUNET_BLOCK_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_FS_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 SBlock)) + { + GNUNET_break_op (0); + 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_from (GNUNET_ERROR_TYPE_WARNING, "block-fs", + _ + ("Reply mismatched in terms of namespace. Discarded.\n")); + return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + } + if (NULL != bf) + { + GNUNET_CRYPTO_hash (reply_block, reply_block_size, &chash); + GNUNET_BLOCK_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_FS_DBLOCK: + case GNUNET_BLOCK_TYPE_FS_IBLOCK: + GNUNET_CRYPTO_hash (block, block_size, key); + return GNUNET_OK; + case GNUNET_BLOCK_TYPE_FS_KBLOCK: + if (block_size < sizeof (struct KBlock)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + 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_NO; + } + if (GNUNET_OK != + GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_FS_KBLOCK, + &kb->purpose, &kb->signature, &kb->keyspace)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + if (key != NULL) + GNUNET_CRYPTO_hash (&kb->keyspace, + sizeof (struct + GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + key); + return GNUNET_OK; + case GNUNET_BLOCK_TYPE_FS_SBLOCK: + if (block_size < sizeof (struct SBlock)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + sb = block; + if (block_size != + ntohl (sb->purpose.size) + sizeof (struct GNUNET_CRYPTO_RsaSignature)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + if (GNUNET_OK != + GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_FS_SBLOCK, + &sb->purpose, &sb->signature, &sb->subspace)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + if (key != NULL) + *key = sb->identifier; + return GNUNET_OK; + case GNUNET_BLOCK_TYPE_FS_NBLOCK: + if (block_size < sizeof (struct NBlock)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + 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_NO; + } + if (block_size != + ntohl (nb->ksk_purpose.size) + + sizeof (struct GNUNET_CRYPTO_RsaSignature)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + 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_NO; + } + 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_NO; + } + /* 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 * +libgnunet_plugin_block_fs_init (void *cls) +{ + static enum GNUNET_BLOCK_Type types[] = + { + GNUNET_BLOCK_TYPE_FS_DBLOCK, + GNUNET_BLOCK_TYPE_FS_IBLOCK, + GNUNET_BLOCK_TYPE_FS_KBLOCK, + GNUNET_BLOCK_TYPE_FS_SBLOCK, + GNUNET_BLOCK_TYPE_FS_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 * +libgnunet_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/vpn/Makefile.am b/src/vpn/Makefile.am index c6b390aca..e69c5643e 100644 --- a/src/vpn/Makefile.am +++ b/src/vpn/Makefile.am @@ -10,6 +10,8 @@ endif pkgcfgdir= $(pkgdatadir)/config.d/ +plugindir = $(libdir)/gnunet + dist_pkgcfg_DATA = \ vpn.conf @@ -72,6 +74,18 @@ gnunet_daemon_exit_LDADD = \ $(top_builddir)/src/mesh/libgnunetmesh.la \ $(GN_LIBINTL) + +plugin_LTLIBRARIES = \ + libgnunet_plugin_block_dns.la + +libgnunet_plugin_block_dns_la_SOURCES = \ + plugin_block_dns.c +libgnunet_plugin_block_dns_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la +libgnunet_plugin_block_dns_la_LDFLAGS = \ + $(top_builddir)/src/block/$(GN_PLUGIN_LDFLAGS) + + #check_PROGRAMS = \ # test_XXX diff --git a/src/vpn/plugin_block_dns.c b/src/vpn/plugin_block_dns.c new file mode 100644 index 000000000..b33b3798a --- /dev/null +++ b/src/vpn/plugin_block_dns.c @@ -0,0 +1,170 @@ +/* + 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_dns.c + * @brief block plugin for storing .gnunet-bindings + * @author Philipp Tölke + */ + +#include "platform.h" +#include "gnunet_block_plugin.h" +#include "block_dns.h" +#include "gnunet_signatures.h" + +#define DEBUG_DHT GNUNET_EXTRA_LOGGING + +/** + * 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 extended 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_dns_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) +{ + switch (type) + { + case GNUNET_BLOCK_TYPE_DNS: + if (xquery_size != 0) + return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; + + if (reply_block_size == 0) + return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; + + if (reply_block_size != sizeof (struct GNUNET_DNS_Record)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "DNS-Block is invalid: reply_block_size=%d != %d\n", + reply_block_size, sizeof (struct GNUNET_DNS_Record)); + return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + } + + const struct GNUNET_DNS_Record *rec = reply_block; + + if (ntohl (rec->purpose.size) != + sizeof (struct GNUNET_DNS_Record) - + sizeof (struct GNUNET_CRYPTO_RsaSignature)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "DNS-Block is invalid: rec->purpose.size=%d != %d\n", + ntohl (rec->purpose.size), + sizeof (struct GNUNET_DNS_Record) - + sizeof (struct GNUNET_CRYPTO_RsaSignature)); + return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + } + + if (GNUNET_TIME_relative_get_zero ().rel_value == + GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh + (rec->expiration_time)).rel_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "DNS-Block is invalid: Timeout\n"); + return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + } + + if (GNUNET_OK != + GNUNET_CRYPTO_rsa_verify (htonl (GNUNET_SIGNATURE_PURPOSE_DNS_RECORD), + &rec->purpose, &rec->signature, &rec->peer)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "DNS-Block is invalid: invalid signature\n"); + return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + } + + /* How to decide whether there are no more? */ + 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_dns_get_key (void *cls, enum GNUNET_BLOCK_Type type, + const void *block, size_t block_size, + GNUNET_HashCode * key) +{ + if (type != GNUNET_BLOCK_TYPE_DNS) + return GNUNET_SYSERR; + const struct GNUNET_DNS_Record *rec = block; + + memcpy (key, &rec->service_descriptor, sizeof (GNUNET_HashCode)); + return GNUNET_OK; +} + +/** + * Entry point for the plugin. + */ +void * +libgnunet_plugin_block_dns_init (void *cls) +{ + static enum GNUNET_BLOCK_Type types[] = + { + GNUNET_BLOCK_TYPE_DNS, + GNUNET_BLOCK_TYPE_ANY /* end of list */ + }; + struct GNUNET_BLOCK_PluginFunctions *api; + + api = GNUNET_malloc (sizeof (struct GNUNET_BLOCK_PluginFunctions)); + api->evaluate = &block_plugin_dns_evaluate; + api->get_key = &block_plugin_dns_get_key; + api->types = types; + return api; +} + + +/** + * Exit point from the plugin. + */ +void * +libgnunet_plugin_block_dns_done (void *cls) +{ + struct GNUNET_TRANSPORT_PluginFunctions *api = cls; + + GNUNET_free (api); + return NULL; +} + +/* end of plugin_block_dns.c */ -- cgit v1.2.3