X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fdht%2Fplugin_block_dht.c;h=72480536cef73a826d8f3d1c3d696f33583a0da0;hb=4ba0fa6ba9f9be044c8c96ddd4d909e7d84403b5;hp=5613034f50f51ab87b206f3f80478fabb8cef2ef;hpb=f27338992f0a5915ee974faea05f764c2df6f584;p=oweals%2Fgnunet.git diff --git a/src/dht/plugin_block_dht.c b/src/dht/plugin_block_dht.c index 5613034f5..72480536c 100644 --- a/src/dht/plugin_block_dht.c +++ b/src/dht/plugin_block_dht.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet - Copyright (C) 2010 Christian Grothoff (and other contributing authors) + Copyright (C) 2010, 2017 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 @@ -25,14 +25,99 @@ * 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" +#include "gnunet_block_group_lib.h" #define DEBUG_DHT GNUNET_EXTRA_LOGGING +/** + * Number of bits we set per entry in the bloomfilter. + * Do not change! + */ +#define BLOOMFILTER_K 16 + + +/** + * How many bytes should a bloomfilter be if we have already seen + * entry_count responses? Note that #GNUNET_CONSTANTS_BLOOMFILTER_K + * gives us the number of bits set per entry. Furthermore, we should + * not re-size the filter too often (to keep it cheap). + * + * Since other peers will also add entries but not resize the filter, + * we should generally pick a slightly larger size than what the + * strict math would suggest. + * + * @param entry_count expected number of entries in the Bloom filter + * @return must be a power of two and smaller or equal to 2^15. + */ +static size_t +compute_bloomfilter_size (unsigned int entry_count) +{ + size_t size; + unsigned int ideal = (entry_count * BLOOMFILTER_K) / 4; + uint16_t max = 1 << 15; + + if (entry_count > max) + return max; + size = 8; + while ((size < max) && (size < ideal)) + size *= 2; + if (size > max) + return max; + return size; +} + + +/** + * Create a new block group. + * + * @param ctx block context in which the block group is created + * @param type type of the block for which we are creating the group + * @param nonce random value used to seed the group creation + * @param raw_data optional serialized prior state of the group, NULL if unavailable/fresh + * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh + * @param va variable arguments specific to @a type + * @return block group handle, NULL if block groups are not supported + * by this @a type of block (this is not an error) + */ +static struct GNUNET_BLOCK_Group * +block_plugin_dht_create_group (void *cls, + enum GNUNET_BLOCK_Type type, + uint32_t nonce, + const void *raw_data, + size_t raw_data_size, + va_list va) +{ + unsigned int bf_size; + const char *guard; + + guard = va_arg (va, const char *); + if (0 == memcmp (guard, + "seen-set-size", + strlen ("seen-set-size"))) + bf_size = compute_bloomfilter_size (va_arg (va, unsigned int)); + else if (0 == memcmp (guard, + "filter-size", + strlen ("filter-size"))) + bf_size = va_arg (va, unsigned int); + else + { + GNUNET_break (0); + bf_size = 8; + } + GNUNET_break (NULL == va_arg (va, const char *)); + return GNUNET_BLOCK_GROUP_bf_create (cls, + bf_size, + BLOOMFILTER_K, + type, + nonce, + raw_data, + raw_data_size); +} + /** * Function called to validate a reply or a request. For @@ -40,10 +125,9 @@ * * @param cls closure * @param type block type + * @param group block group to check against * @param eo control flags * @param query original query (hash) - * @param bf pointer to bloom filter associated with query; possibly updated (!) - * @param bf_mutator mutation value for @a bf * @param xquery extended query data (can be NULL, depending on type) * @param xquery_size number of bytes in @a xquery * @param reply_block response to validate @@ -53,16 +137,14 @@ static enum GNUNET_BLOCK_EvaluationResult block_plugin_dht_evaluate (void *cls, enum GNUNET_BLOCK_Type type, + struct GNUNET_BLOCK_Group *group, enum GNUNET_BLOCK_EvaluationOptions eo, const struct 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_HashCode mhash; const struct GNUNET_HELLO_Message *hello; struct GNUNET_PeerIdentity pid; const struct GNUNET_MessageHeader *msg; @@ -70,7 +152,7 @@ block_plugin_dht_evaluate (void *cls, if (type != GNUNET_BLOCK_TYPE_DHT_HELLO) return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; - if (xquery_size != 0) + if (0 != xquery_size) { GNUNET_break_op (0); return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; @@ -94,22 +176,13 @@ block_plugin_dht_evaluate (void *cls, GNUNET_break_op (0); return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; } - if (NULL != bf) - { - GNUNET_CRYPTO_hash (&pid, sizeof (pid), &phash); - GNUNET_BLOCK_mingle_hash (&phash, 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); - } + GNUNET_CRYPTO_hash (&pid, + sizeof (pid), + &phash); + if (GNUNET_YES == + GNUNET_BLOCK_GROUP_bf_test_and_set (group, + &phash)) + return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; return GNUNET_BLOCK_EVALUATION_OK_MORE; } @@ -121,14 +194,16 @@ block_plugin_dht_evaluate (void *cls, * @param type block type * @param block block to get the key for * @param block_size number of bytes @a block - * @param key set to the key (query) for the given block + * @param[out] 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, - struct GNUNET_HashCode * key) +block_plugin_dht_get_key (void *cls, + enum GNUNET_BLOCK_Type type, + const void *block, + size_t block_size, + struct GNUNET_HashCode *key) { const struct GNUNET_MessageHeader *msg; const struct GNUNET_HELLO_Message *hello; @@ -180,6 +255,7 @@ libgnunet_plugin_block_dht_init (void *cls) api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); api->evaluate = &block_plugin_dht_evaluate; api->get_key = &block_plugin_dht_get_key; + api->create_group = &block_plugin_dht_create_group; api->types = types; return api; }