aboutsummaryrefslogtreecommitdiff
path: root/src/block
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-02-20 17:19:47 +0100
committerChristian Grothoff <christian@grothoff.org>2017-02-20 17:19:47 +0100
commitf6f7fbbe98c110867febbcca647da8308be123c7 (patch)
treeaf69447cf4f08c417197685855c097c132aea8a1 /src/block
parenta3882b58f1c5976677aa65b0af8a48e8e946b06e (diff)
downloadgnunet-f6f7fbbe98c110867febbcca647da8308be123c7.tar.gz
gnunet-f6f7fbbe98c110867febbcca647da8308be123c7.zip
completed big block refactoring in preparation for SET-BLOCK integration
Diffstat (limited to 'src/block')
-rw-r--r--src/block/Makefile.am6
-rw-r--r--src/block/bg_bf.c64
-rw-r--r--src/block/block.c145
-rw-r--r--src/block/plugin_block_template.c88
-rw-r--r--src/block/plugin_block_test.c80
5 files changed, 259 insertions, 124 deletions
diff --git a/src/block/Makefile.am b/src/block/Makefile.am
index 4a6d8e71e..da1d8257c 100644
--- a/src/block/Makefile.am
+++ b/src/block/Makefile.am
@@ -26,7 +26,7 @@ noinst_LTLIBRARIES = \
26libgnunet_plugin_block_template_la_SOURCES = \ 26libgnunet_plugin_block_template_la_SOURCES = \
27 plugin_block_template.c 27 plugin_block_template.c
28libgnunet_plugin_block_template_la_LIBADD = \ 28libgnunet_plugin_block_template_la_LIBADD = \
29 libgnunetblock.la \ 29 libgnunetblockgroup.la \
30 $(top_builddir)/src/util/libgnunetutil.la \ 30 $(top_builddir)/src/util/libgnunetutil.la \
31 $(LTLIBINTL) 31 $(LTLIBINTL)
32libgnunet_plugin_block_template_la_LDFLAGS = \ 32libgnunet_plugin_block_template_la_LDFLAGS = \
@@ -35,8 +35,8 @@ libgnunet_plugin_block_template_la_LDFLAGS = \
35libgnunet_plugin_block_test_la_SOURCES = \ 35libgnunet_plugin_block_test_la_SOURCES = \
36 plugin_block_test.c 36 plugin_block_test.c
37libgnunet_plugin_block_test_la_LIBADD = \ 37libgnunet_plugin_block_test_la_LIBADD = \
38 libgnunetblock.la \ 38 libgnunetblockgroup.la \
39 $(top_builddir)/src/util/libgnunetutil.la \ 39$(top_builddir)/src/util/libgnunetutil.la \
40 $(LTLIBINTL) 40 $(LTLIBINTL)
41libgnunet_plugin_block_test_la_LDFLAGS = \ 41libgnunet_plugin_block_test_la_LDFLAGS = \
42 $(GN_PLUGIN_LDFLAGS) 42 $(GN_PLUGIN_LDFLAGS)
diff --git a/src/block/bg_bf.c b/src/block/bg_bf.c
index f03ae5247..9c4dc9060 100644
--- a/src/block/bg_bf.c
+++ b/src/block/bg_bf.c
@@ -56,6 +56,7 @@ struct BfGroupInternals
56 * Serialize state of a block group. 56 * Serialize state of a block group.
57 * 57 *
58 * @param bg group to serialize 58 * @param bg group to serialize
59 * @param[out] nonce set to the nonce of the @a bg
59 * @param[out] raw_data set to the serialized state 60 * @param[out] raw_data set to the serialized state
60 * @param[out] raw_data_size set to the number of bytes in @a raw_data 61 * @param[out] raw_data_size set to the number of bytes in @a raw_data
61 * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not 62 * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not
@@ -63,6 +64,7 @@ struct BfGroupInternals
63 */ 64 */
64static int 65static int
65bf_group_serialize_cb (struct GNUNET_BLOCK_Group *bg, 66bf_group_serialize_cb (struct GNUNET_BLOCK_Group *bg,
67 uint32_t *nonce,
66 void **raw_data, 68 void **raw_data,
67 size_t *raw_data_size) 69 size_t *raw_data_size)
68{ 70{
@@ -78,6 +80,7 @@ bf_group_serialize_cb (struct GNUNET_BLOCK_Group *bg,
78 GNUNET_break (0); 80 GNUNET_break (0);
79 return GNUNET_SYSERR; 81 return GNUNET_SYSERR;
80 } 82 }
83 *nonce = gi->bf_mutator;
81 *raw_data = raw; 84 *raw_data = raw;
82 *raw_data_size = gi->bf_size; 85 *raw_data_size = gi->bf_size;
83 return GNUNET_OK; 86 return GNUNET_OK;
@@ -85,6 +88,60 @@ bf_group_serialize_cb (struct GNUNET_BLOCK_Group *bg,
85 88
86 89
87/** 90/**
91 * Mark elements as "seen" using a hash of the element. Not supported
92 * by all block plugins.
93 *
94 * @param bg group to update
95 * @param seen_results results already seen
96 * @param seen_results_count number of entries in @a seen_results
97 */
98static void
99bf_group_mark_seen_cb (struct GNUNET_BLOCK_Group *bg,
100 const struct GNUNET_HashCode *seen_results,
101 unsigned int seen_results_count)
102{
103 struct BfGroupInternals *gi = bg->internal_cls;
104
105 for (unsigned int i=0;i<seen_results_count;i++)
106 {
107 struct GNUNET_HashCode mhash;
108
109 GNUNET_BLOCK_mingle_hash (&seen_results[i],
110 gi->bf_mutator,
111 &mhash);
112 GNUNET_CONTAINER_bloomfilter_add (gi->bf,
113 &mhash);
114 }
115}
116
117
118/**
119 * Merge two groups, if possible. Not supported by all block plugins,
120 * can also fail if the nonces were different.
121 *
122 * @param bg1 group to update
123 * @param bg2 group to merge into @a bg1
124 * @return #GNUNET_OK on success, #GNUNET_NO if the nonces were different and thus
125 * we failed.
126 */
127static int
128bf_group_merge_cb (struct GNUNET_BLOCK_Group *bg1,
129 const struct GNUNET_BLOCK_Group *bg2)
130{
131 struct BfGroupInternals *gi1 = bg1->internal_cls;
132 struct BfGroupInternals *gi2 = bg2->internal_cls;
133
134 if (gi1->bf_mutator != gi2->bf_mutator)
135 return GNUNET_NO;
136 if (gi1->bf_size != gi2->bf_size)
137 return GNUNET_NO;
138 GNUNET_CONTAINER_bloomfilter_or2 (gi1->bf,
139 gi2->bf);
140 return GNUNET_OK;
141}
142
143
144/**
88 * Destroy resources used by a block group. 145 * Destroy resources used by a block group.
89 * 146 *
90 * @param bg group to destroy, NULL is allowed 147 * @param bg group to destroy, NULL is allowed
@@ -134,6 +191,8 @@ GNUNET_BLOCK_GROUP_bf_create (void *cls,
134 bg = GNUNET_new (struct GNUNET_BLOCK_Group); 191 bg = GNUNET_new (struct GNUNET_BLOCK_Group);
135 bg->type = type; 192 bg->type = type;
136 bg->serialize_cb = &bf_group_serialize_cb; 193 bg->serialize_cb = &bf_group_serialize_cb;
194 bg->mark_seen_cb = &bf_group_mark_seen_cb;
195 bg->merge_cb = &bf_group_merge_cb;
137 bg->destroy_cb = &bf_group_destroy_cb; 196 bg->destroy_cb = &bf_group_destroy_cb;
138 bg->internal_cls = gi; 197 bg->internal_cls = gi;
139 return bg; 198 return bg;
@@ -154,9 +213,12 @@ int
154GNUNET_BLOCK_GROUP_bf_test_and_set (struct GNUNET_BLOCK_Group *bg, 213GNUNET_BLOCK_GROUP_bf_test_and_set (struct GNUNET_BLOCK_Group *bg,
155 const struct GNUNET_HashCode *hc) 214 const struct GNUNET_HashCode *hc)
156{ 215{
157 struct BfGroupInternals *gi = bg->internal_cls; 216 struct BfGroupInternals *gi;
158 struct GNUNET_HashCode mhash; 217 struct GNUNET_HashCode mhash;
159 218
219 if (NULL == bg)
220 return GNUNET_NO;
221 gi = bg->internal_cls;
160 GNUNET_BLOCK_mingle_hash (hc, 222 GNUNET_BLOCK_mingle_hash (hc,
161 gi->bf_mutator, 223 gi->bf_mutator,
162 &mhash); 224 &mhash);
diff --git a/src/block/block.c b/src/block/block.c
index d4f5462dd..b7a19ae90 100644
--- a/src/block/block.c
+++ b/src/block/block.c
@@ -162,6 +162,7 @@ GNUNET_BLOCK_context_destroy (struct GNUNET_BLOCK_Context *ctx)
162 * Serialize state of a block group. 162 * Serialize state of a block group.
163 * 163 *
164 * @param bg group to serialize 164 * @param bg group to serialize
165 * @param[out] nonce set to the nonce of the @a bg
165 * @param[out] raw_data set to the serialized state 166 * @param[out] raw_data set to the serialized state
166 * @param[out] raw_data_size set to the number of bytes in @a raw_data 167 * @param[out] raw_data_size set to the number of bytes in @a raw_data
167 * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not 168 * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not
@@ -169,9 +170,11 @@ GNUNET_BLOCK_context_destroy (struct GNUNET_BLOCK_Context *ctx)
169 */ 170 */
170int 171int
171GNUNET_BLOCK_group_serialize (struct GNUNET_BLOCK_Group *bg, 172GNUNET_BLOCK_group_serialize (struct GNUNET_BLOCK_Group *bg,
173 uint32_t *nonce,
172 void **raw_data, 174 void **raw_data,
173 size_t *raw_data_size) 175 size_t *raw_data_size)
174{ 176{
177 *nonce = 0;
175 *raw_data = NULL; 178 *raw_data = NULL;
176 *raw_data_size = 0; 179 *raw_data_size = 0;
177 if (NULL == bg) 180 if (NULL == bg)
@@ -179,6 +182,7 @@ GNUNET_BLOCK_group_serialize (struct GNUNET_BLOCK_Group *bg,
179 if (NULL == bg->serialize_cb) 182 if (NULL == bg->serialize_cb)
180 return GNUNET_NO; 183 return GNUNET_NO;
181 return bg->serialize_cb (bg, 184 return bg->serialize_cb (bg,
185 nonce,
182 raw_data, 186 raw_data,
183 raw_data_size); 187 raw_data_size);
184} 188}
@@ -199,6 +203,41 @@ GNUNET_BLOCK_group_destroy (struct GNUNET_BLOCK_Group *bg)
199 203
200 204
201/** 205/**
206 * Try merging two block groups. Afterwards, @a bg1 should remain
207 * valid and contain the rules from both @a bg1 and @bg2, and
208 * @a bg2 should be destroyed (as part of this call). The latter
209 * should happen even if merging is not supported.
210 *
211 * @param[in,out] bg1 first group to merge, is updated
212 * @param bg2 second group to merge, is destroyed
213 * @return #GNUNET_OK on success,
214 * #GNUNET_NO if merge failed due to different nonce
215 * #GNUNET_SYSERR if merging is not supported
216 */
217int
218GNUNET_BLOCK_group_merge (struct GNUNET_BLOCK_Group *bg1,
219 struct GNUNET_BLOCK_Group *bg2)
220{
221 int ret;
222
223 if (NULL == bg2)
224 return GNUNET_OK;
225 if (NULL == bg1)
226 {
227 bg2->destroy_cb (bg2);
228 return GNUNET_OK;
229 }
230 if (NULL == bg1->merge_cb)
231 return GNUNET_SYSERR;
232 GNUNET_assert (bg1->merge_cb == bg1->merge_cb);
233 ret = bg1->merge_cb (bg1,
234 bg2);
235 bg2->destroy_cb (bg2);
236 return ret;
237}
238
239
240/**
202 * Find a plugin for the given type. 241 * Find a plugin for the given type.
203 * 242 *
204 * @param ctx context to search 243 * @param ctx context to search
@@ -244,19 +283,26 @@ GNUNET_BLOCK_group_create (struct GNUNET_BLOCK_Context *ctx,
244 enum GNUNET_BLOCK_Type type, 283 enum GNUNET_BLOCK_Type type,
245 uint32_t nonce, 284 uint32_t nonce,
246 const void *raw_data, 285 const void *raw_data,
247 size_t raw_data_size) 286 size_t raw_data_size,
287 ...)
248{ 288{
249 struct GNUNET_BLOCK_PluginFunctions *plugin; 289 struct GNUNET_BLOCK_PluginFunctions *plugin;
290 struct GNUNET_BLOCK_Group *bg;
291 va_list ap;
250 292
251 plugin = find_plugin (ctx, 293 plugin = find_plugin (ctx,
252 type); 294 type);
253 if (NULL == plugin->create_group) 295 if (NULL == plugin->create_group)
254 return NULL; 296 return NULL;
255 return plugin->create_group (plugin->cls, 297 va_start (ap, raw_data_size);
256 type, 298 bg = plugin->create_group (plugin->cls,
257 nonce, 299 type,
258 raw_data, 300 nonce,
259 raw_data_size); 301 raw_data,
302 raw_data_size,
303 ap);
304 va_end (ap);
305 return bg;
260} 306}
261 307
262 308
@@ -269,10 +315,9 @@ GNUNET_BLOCK_group_create (struct GNUNET_BLOCK_Context *ctx,
269 * 315 *
270 * @param ctx block contxt 316 * @param ctx block contxt
271 * @param type block type 317 * @param type block type
318 * @param block block group to use
272 * @param eo control flags 319 * @param eo control flags
273 * @param query original query (hash) 320 * @param query original query (hash)
274 * @param bf pointer to bloom filter associated with query; possibly updated (!)
275 * @param bf_mutator mutation value for @a bf
276 * @param xquery extended query data (can be NULL, depending on type) 321 * @param xquery extended query data (can be NULL, depending on type)
277 * @param xquery_size number of bytes in @a xquery 322 * @param xquery_size number of bytes in @a xquery
278 * @param reply_block response to validate 323 * @param reply_block response to validate
@@ -282,25 +327,24 @@ GNUNET_BLOCK_group_create (struct GNUNET_BLOCK_Context *ctx,
282enum GNUNET_BLOCK_EvaluationResult 327enum GNUNET_BLOCK_EvaluationResult
283GNUNET_BLOCK_evaluate (struct GNUNET_BLOCK_Context *ctx, 328GNUNET_BLOCK_evaluate (struct GNUNET_BLOCK_Context *ctx,
284 enum GNUNET_BLOCK_Type type, 329 enum GNUNET_BLOCK_Type type,
330 struct GNUNET_BLOCK_Group *group,
285 enum GNUNET_BLOCK_EvaluationOptions eo, 331 enum GNUNET_BLOCK_EvaluationOptions eo,
286 const struct GNUNET_HashCode *query, 332 const struct GNUNET_HashCode *query,
287 struct GNUNET_CONTAINER_BloomFilter **bf,
288 int32_t bf_mutator,
289 const void *xquery, 333 const void *xquery,
290 size_t xquery_size, 334 size_t xquery_size,
291 const void *reply_block, 335 const void *reply_block,
292 size_t reply_block_size) 336 size_t reply_block_size)
293{ 337{
294 struct GNUNET_BLOCK_PluginFunctions *plugin = find_plugin (ctx, type); 338 struct GNUNET_BLOCK_PluginFunctions *plugin = find_plugin (ctx,
339 type);
295 340
296 if (plugin == NULL) 341 if (NULL == plugin)
297 return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; 342 return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED;
298 return plugin->evaluate (plugin->cls, 343 return plugin->evaluate (plugin->cls,
299 type, 344 type,
345 group,
300 eo, 346 eo,
301 query, 347 query,
302 bf,
303 bf_mutator,
304 xquery, 348 xquery,
305 xquery_size, 349 xquery_size,
306 reply_block, 350 reply_block,
@@ -326,7 +370,8 @@ GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx,
326 size_t block_size, 370 size_t block_size,
327 struct GNUNET_HashCode *key) 371 struct GNUNET_HashCode *key)
328{ 372{
329 struct GNUNET_BLOCK_PluginFunctions *plugin = find_plugin (ctx, type); 373 struct GNUNET_BLOCK_PluginFunctions *plugin = find_plugin (ctx,
374 type);
330 375
331 if (plugin == NULL) 376 if (plugin == NULL)
332 return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; 377 return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED;
@@ -335,65 +380,29 @@ GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx,
335 380
336 381
337/** 382/**
338 * How many bytes should a bloomfilter be if we have already seen 383 * Update block group to filter out the given results. Note that the
339 * entry_count responses? Note that #GNUNET_CONSTANTS_BLOOMFILTER_K 384 * use of a hash for seen results implies that the caller magically
340 * gives us the number of bits set per entry. Furthermore, we should 385 * knows how the specific block engine hashes for filtering
341 * not re-size the filter too often (to keep it cheap). 386 * duplicates, so this API may not always apply.
342 *
343 * Since other peers will also add entries but not resize the filter,
344 * we should generally pick a slightly larger size than what the
345 * strict math would suggest.
346 *
347 * @param entry_count expected number of entries in the Bloom filter
348 * @return must be a power of two and smaller or equal to 2^15.
349 */
350static size_t
351compute_bloomfilter_size (unsigned int entry_count)
352{
353 size_t size;
354 unsigned int ideal = (entry_count * GNUNET_CONSTANTS_BLOOMFILTER_K) / 4;
355 uint16_t max = 1 << 15;
356
357 if (entry_count > max)
358 return max;
359 size = 8;
360 while ((size < max) && (size < ideal))
361 size *= 2;
362 if (size > max)
363 return max;
364 return size;
365}
366
367
368/**
369 * Construct a bloom filter that would filter out the given
370 * results.
371 * 387 *
372 * @param bf_mutator mutation value to use 388 * @param bf_mutator mutation value to use
373 * @param seen_results results already seen 389 * @param seen_results results already seen
374 * @param seen_results_count number of entries in @a seen_results 390 * @param seen_results_count number of entries in @a seen_results
375 * @return NULL if seen_results_count is 0, otherwise a BF 391 * @return #GNUNET_SYSERR if not supported, #GNUNET_OK on success
376 * that would match the given results.
377 */ 392 */
378struct GNUNET_CONTAINER_BloomFilter * 393int
379GNUNET_BLOCK_construct_bloomfilter (int32_t bf_mutator, 394GNUNET_BLOCK_group_set_seen (struct GNUNET_BLOCK_Group *bg,
380 const struct GNUNET_HashCode *seen_results, 395 const struct GNUNET_HashCode *seen_results,
381 unsigned int seen_results_count) 396 unsigned int seen_results_count)
382{ 397{
383 struct GNUNET_CONTAINER_BloomFilter *bf; 398 if (NULL == bg)
384 struct GNUNET_HashCode mhash; 399 return GNUNET_OK;
385 unsigned int i; 400 if (NULL == bg->mark_seen_cb)
386 size_t nsize; 401 return GNUNET_SYSERR;
387 402 bg->mark_seen_cb (bg,
388 nsize = compute_bloomfilter_size (seen_results_count); 403 seen_results,
389 bf = GNUNET_CONTAINER_bloomfilter_init (NULL, nsize, 404 seen_results_count);
390 GNUNET_CONSTANTS_BLOOMFILTER_K); 405 return GNUNET_OK;
391 for (i = 0; i < seen_results_count; i++)
392 {
393 GNUNET_BLOCK_mingle_hash (&seen_results[i], bf_mutator, &mhash);
394 GNUNET_CONTAINER_bloomfilter_add (bf, &mhash);
395 }
396 return bf;
397} 406}
398 407
399 408
diff --git a/src/block/plugin_block_template.c b/src/block/plugin_block_template.c
index 6cb69ef5f..0e8107af2 100644
--- a/src/block/plugin_block_template.c
+++ b/src/block/plugin_block_template.c
@@ -26,9 +26,52 @@
26 26
27#include "platform.h" 27#include "platform.h"
28#include "gnunet_block_plugin.h" 28#include "gnunet_block_plugin.h"
29#include "gnunet_block_group_lib.h"
29 30
30#define DEBUG_TEMPLATE GNUNET_EXTRA_LOGGING 31#define DEBUG_TEMPLATE GNUNET_EXTRA_LOGGING
31 32
33/**
34 * Number of bits we set per entry in the bloomfilter.
35 * Do not change!
36 */
37#define BLOOMFILTER_K 16
38
39
40/**
41 * How big is the BF we use for DHT blocks?
42 */
43#define TEMPLATE_BF_SIZE 8
44
45
46/**
47 * Create a new block group.
48 *
49 * @param ctx block context in which the block group is created
50 * @param type type of the block for which we are creating the group
51 * @param nonce random value used to seed the group creation
52 * @param raw_data optional serialized prior state of the group, NULL if unavailable/fresh
53 * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh
54 * @param va variable arguments specific to @a type
55 * @return block group handle, NULL if block groups are not supported
56 * by this @a type of block (this is not an error)
57 */
58static struct GNUNET_BLOCK_Group *
59block_plugin_template_create_group (void *cls,
60 enum GNUNET_BLOCK_Type type,
61 uint32_t nonce,
62 const void *raw_data,
63 size_t raw_data_size,
64 va_list va)
65{
66 return GNUNET_BLOCK_GROUP_bf_create (cls,
67 TEMPLATE_BF_SIZE,
68 BLOOMFILTER_K,
69 type,
70 nonce,
71 raw_data,
72 raw_data_size);
73}
74
32 75
33/** 76/**
34 * Function called to validate a reply or a request. For 77 * Function called to validate a reply or a request. For
@@ -36,10 +79,9 @@
36 * 79 *
37 * @param cls closure 80 * @param cls closure
38 * @param type block type 81 * @param type block type
82 * @param group block group to use
39 * @param eo control flags 83 * @param eo control flags
40 * @param query original query (hash) 84 * @param query original query (hash)
41 * @param bf pointer to bloom filter associated with query; possibly updated (!)
42 * @param bf_mutator mutation value for bf
43 * @param xquery extrended query data (can be NULL, depending on type) 85 * @param xquery extrended query data (can be NULL, depending on type)
44 * @param xquery_size number of bytes in xquery 86 * @param xquery_size number of bytes in xquery
45 * @param reply_block response to validate 87 * @param reply_block response to validate
@@ -49,36 +91,25 @@
49static enum GNUNET_BLOCK_EvaluationResult 91static enum GNUNET_BLOCK_EvaluationResult
50block_plugin_template_evaluate (void *cls, 92block_plugin_template_evaluate (void *cls,
51 enum GNUNET_BLOCK_Type type, 93 enum GNUNET_BLOCK_Type type,
94 struct GNUNET_BLOCK_Group *group,
52 enum GNUNET_BLOCK_EvaluationOptions eo, 95 enum GNUNET_BLOCK_EvaluationOptions eo,
53 const struct GNUNET_HashCode *query, 96 const struct GNUNET_HashCode *query,
54 struct GNUNET_CONTAINER_BloomFilter **bf,
55 int32_t bf_mutator,
56 const void *xquery, 97 const void *xquery,
57 size_t xquery_size, 98 size_t xquery_size,
58 const void *reply_block, 99 const void *reply_block,
59 size_t reply_block_size) 100 size_t reply_block_size)
60{ 101{
61 struct GNUNET_HashCode chash; 102 struct GNUNET_HashCode chash;
62 struct GNUNET_HashCode mhash;
63 /* FIXME: check validity first... */
64 103
65 /* mandatory duplicate-detection code... */ 104 if (NULL == reply_block)
66 if (NULL != bf) 105 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
67 { 106 GNUNET_CRYPTO_hash (reply_block,
68 GNUNET_CRYPTO_hash (reply_block, reply_block_size, &chash); 107 reply_block_size,
69 GNUNET_BLOCK_mingle_hash (&chash, bf_mutator, &mhash); 108 &chash);
70 if (NULL != *bf) 109 if (GNUNET_YES ==
71 { 110 GNUNET_BLOCK_GROUP_bf_test_and_set (group,
72 if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (*bf, &mhash)) 111 &chash))
73 return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; 112 return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE;
74 }
75 else
76 {
77 *bf = GNUNET_CONTAINER_bloomfilter_init (NULL, 8, 64 /* BLOOMFILTER_K */);
78 }
79 GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash);
80 }
81 /* FIXME: other stuff here... */
82 return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; 113 return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED;
83} 114}
84 115
@@ -91,13 +122,15 @@ block_plugin_template_evaluate (void *cls,
91 * @param block block to get the key for 122 * @param block block to get the key for
92 * @param block_size number of bytes in block 123 * @param block_size number of bytes in block
93 * @param key set to the key (query) for the given block 124 * @param key set to the key (query) for the given block
94 * @return GNUNET_OK on success, GNUNET_SYSERR if type not supported 125 * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported
95 * (or if extracting a key from a block of this type does not work) 126 * (or if extracting a key from a block of this type does not work)
96 */ 127 */
97static int 128static int
98block_plugin_template_get_key (void *cls, enum GNUNET_BLOCK_Type type, 129block_plugin_template_get_key (void *cls,
99 const void *block, size_t block_size, 130 enum GNUNET_BLOCK_Type type,
100 struct GNUNET_HashCode * key) 131 const void *block,
132 size_t block_size,
133 struct GNUNET_HashCode *key)
101{ 134{
102 return GNUNET_SYSERR; 135 return GNUNET_SYSERR;
103} 136}
@@ -119,6 +152,7 @@ libgnunet_plugin_block_template_init (void *cls)
119 api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); 152 api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions);
120 api->evaluate = &block_plugin_template_evaluate; 153 api->evaluate = &block_plugin_template_evaluate;
121 api->get_key = &block_plugin_template_get_key; 154 api->get_key = &block_plugin_template_get_key;
155 api->create_group = &block_plugin_template_create_group;
122 api->types = types; 156 api->types = types;
123 return api; 157 return api;
124} 158}
diff --git a/src/block/plugin_block_test.c b/src/block/plugin_block_test.c
index b692d6230..615f1571b 100644
--- a/src/block/plugin_block_test.c
+++ b/src/block/plugin_block_test.c
@@ -27,7 +27,7 @@
27 27
28#include "platform.h" 28#include "platform.h"
29#include "gnunet_block_plugin.h" 29#include "gnunet_block_plugin.h"
30 30#include "gnunet_block_group_lib.h"
31 31
32/** 32/**
33 * Number of bits we set per entry in the bloomfilter. 33 * Number of bits we set per entry in the bloomfilter.
@@ -36,15 +36,50 @@
36#define BLOOMFILTER_K 16 36#define BLOOMFILTER_K 16
37 37
38/** 38/**
39 * How big is the BF we use for DHT blocks?
40 */
41#define TEST_BF_SIZE 8
42
43
44/**
45 * Create a new block group.
46 *
47 * @param ctx block context in which the block group is created
48 * @param type type of the block for which we are creating the group
49 * @param nonce random value used to seed the group creation
50 * @param raw_data optional serialized prior state of the group, NULL if unavailable/fresh
51 * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh
52 * @param va variable arguments specific to @a type
53 * @return block group handle, NULL if block groups are not supported
54 * by this @a type of block (this is not an error)
55 */
56static struct GNUNET_BLOCK_Group *
57block_plugin_test_create_group (void *cls,
58 enum GNUNET_BLOCK_Type type,
59 uint32_t nonce,
60 const void *raw_data,
61 size_t raw_data_size,
62 va_list va)
63{
64 return GNUNET_BLOCK_GROUP_bf_create (cls,
65 TEST_BF_SIZE,
66 BLOOMFILTER_K,
67 type,
68 nonce,
69 raw_data,
70 raw_data_size);
71}
72
73
74/**
39 * Function called to validate a reply or a request. For 75 * Function called to validate a reply or a request. For
40 * request evaluation, simply pass "NULL" for the reply_block. 76 * request evaluation, simply pass "NULL" for the reply_block.
41 * 77 *
42 * @param cls closure 78 * @param cls closure
43 * @param type block type 79 * @param type block type
80 * @param group group to check against
44 * @param eo control flags 81 * @param eo control flags
45 * @param query original query (hash) 82 * @param query original query (hash)
46 * @param bf pointer to bloom filter associated with query; possibly updated (!)
47 * @param bf_mutator mutation value for @a bf
48 * @param xquery extrended query data (can be NULL, depending on type) 83 * @param xquery extrended query data (can be NULL, depending on type)
49 * @param xquery_size number of bytes in @a xquery 84 * @param xquery_size number of bytes in @a xquery
50 * @param reply_block response to validate 85 * @param reply_block response to validate
@@ -54,20 +89,21 @@
54static enum GNUNET_BLOCK_EvaluationResult 89static enum GNUNET_BLOCK_EvaluationResult
55block_plugin_test_evaluate (void *cls, 90block_plugin_test_evaluate (void *cls,
56 enum GNUNET_BLOCK_Type type, 91 enum GNUNET_BLOCK_Type type,
92 struct GNUNET_BLOCK_Group *group,
57 enum GNUNET_BLOCK_EvaluationOptions eo, 93 enum GNUNET_BLOCK_EvaluationOptions eo,
58 const struct GNUNET_HashCode *query, 94 const struct GNUNET_HashCode *query,
59 struct GNUNET_CONTAINER_BloomFilter **bf,
60 int32_t bf_mutator,
61 const void *xquery, 95 const void *xquery,
62 size_t xquery_size, 96 size_t xquery_size,
63 const void *reply_block, 97 const void *reply_block,
64 size_t reply_block_size) 98 size_t reply_block_size)
65{ 99{
66 struct GNUNET_HashCode chash; 100 struct GNUNET_HashCode chash;
67 struct GNUNET_HashCode mhash;
68 101
69 if ( GNUNET_BLOCK_TYPE_TEST != type) 102 if ( GNUNET_BLOCK_TYPE_TEST != type)
103 {
104 GNUNET_break (0);
70 return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; 105 return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED;
106 }
71 if (0 != xquery_size) 107 if (0 != xquery_size)
72 { 108 {
73 GNUNET_break_op (0); 109 GNUNET_break_op (0);
@@ -75,22 +111,13 @@ block_plugin_test_evaluate (void *cls,
75 } 111 }
76 if (NULL == reply_block) 112 if (NULL == reply_block)
77 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; 113 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
78 114 GNUNET_CRYPTO_hash (reply_block,
79 if (NULL != bf) 115 reply_block_size,
80 { 116 &chash);
81 GNUNET_CRYPTO_hash (reply_block, reply_block_size, &chash); 117 if (GNUNET_YES ==
82 GNUNET_BLOCK_mingle_hash (&chash, bf_mutator, &mhash); 118 GNUNET_BLOCK_GROUP_bf_test_and_set (group,
83 if (NULL != *bf) 119 &chash))
84 { 120 return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE;
85 if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (*bf, &mhash))
86 return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE;
87 }
88 else
89 {
90 *bf = GNUNET_CONTAINER_bloomfilter_init (NULL, 8, BLOOMFILTER_K);
91 }
92 GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash);
93 }
94 return GNUNET_BLOCK_EVALUATION_OK_MORE; 121 return GNUNET_BLOCK_EVALUATION_OK_MORE;
95} 122}
96 123
@@ -107,9 +134,11 @@ block_plugin_test_evaluate (void *cls,
107 * (or if extracting a key from a block of this type does not work) 134 * (or if extracting a key from a block of this type does not work)
108 */ 135 */
109static int 136static int
110block_plugin_test_get_key (void *cls, enum GNUNET_BLOCK_Type type, 137block_plugin_test_get_key (void *cls,
111 const void *block, size_t block_size, 138 enum GNUNET_BLOCK_Type type,
112 struct GNUNET_HashCode * key) 139 const void *block,
140 size_t block_size,
141 struct GNUNET_HashCode *key)
113{ 142{
114 /* always fails since there is no fixed relationship between 143 /* always fails since there is no fixed relationship between
115 * keys and values for test values */ 144 * keys and values for test values */
@@ -136,6 +165,7 @@ libgnunet_plugin_block_test_init (void *cls)
136 api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); 165 api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions);
137 api->evaluate = &block_plugin_test_evaluate; 166 api->evaluate = &block_plugin_test_evaluate;
138 api->get_key = &block_plugin_test_get_key; 167 api->get_key = &block_plugin_test_get_key;
168 api->create_group = &block_plugin_test_create_group;
139 api->types = types; 169 api->types = types;
140 return api; 170 return api;
141} 171}