aboutsummaryrefslogtreecommitdiff
path: root/src/block
diff options
context:
space:
mode:
Diffstat (limited to 'src/block')
-rw-r--r--src/block/Makefile.am59
-rw-r--r--src/block/bg_bf.c268
-rw-r--r--src/block/block.c425
-rw-r--r--src/block/plugin_block_template.c195
-rw-r--r--src/block/plugin_block_test.c209
5 files changed, 0 insertions, 1156 deletions
diff --git a/src/block/Makefile.am b/src/block/Makefile.am
deleted file mode 100644
index ea796bf8f..000000000
--- a/src/block/Makefile.am
+++ /dev/null
@@ -1,59 +0,0 @@
1# This Makefile.am is in the public domain
2AM_CPPFLAGS = -I$(top_srcdir)/src/include
3
4plugindir = $(libdir)/gnunet
5
6if USE_COVERAGE
7 AM_CFLAGS = --coverage
8endif
9
10lib_LTLIBRARIES = \
11 libgnunetblock.la \
12 libgnunetblockgroup.la
13
14plugin_LTLIBRARIES = \
15 libgnunet_plugin_block_test.la
16
17# Real plugins should of course go into
18# plugin_LTLIBRARIES
19noinst_LTLIBRARIES = \
20 libgnunet_plugin_block_template.la
21
22libgnunet_plugin_block_template_la_SOURCES = \
23 plugin_block_template.c
24libgnunet_plugin_block_template_la_LIBADD = \
25 libgnunetblockgroup.la \
26 libgnunetblock.la \
27 $(top_builddir)/src/util/libgnunetutil.la \
28 $(LTLIBINTL)
29libgnunet_plugin_block_template_la_LDFLAGS = \
30 $(GN_PLUGIN_LDFLAGS)
31
32libgnunet_plugin_block_test_la_SOURCES = \
33 plugin_block_test.c
34libgnunet_plugin_block_test_la_LIBADD = \
35 libgnunetblockgroup.la \
36 libgnunetblock.la \
37 $(top_builddir)/src/util/libgnunetutil.la \
38 $(LTLIBINTL)
39libgnunet_plugin_block_test_la_LDFLAGS = \
40 $(GN_PLUGIN_LDFLAGS)
41
42libgnunetblock_la_SOURCES = \
43 block.c
44libgnunetblock_la_LIBADD = \
45 $(top_builddir)/src/util/libgnunetutil.la
46libgnunetblock_la_LDFLAGS = \
47 $(GN_LIB_LDFLAGS) \
48 $(GN_LIBINTL) \
49 -version-info 0:0:0
50
51libgnunetblockgroup_la_SOURCES = \
52 bg_bf.c
53libgnunetblockgroup_la_LIBADD = \
54 libgnunetblock.la \
55 $(top_builddir)/src/util/libgnunetutil.la
56libgnunetblockgroup_la_LDFLAGS = \
57 $(GN_LIB_LDFLAGS) \
58 $(GN_LIBINTL) \
59 -version-info 0:0:0
diff --git a/src/block/bg_bf.c b/src/block/bg_bf.c
deleted file mode 100644
index ae8ee0e51..000000000
--- a/src/block/bg_bf.c
+++ /dev/null
@@ -1,268 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2017 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file block/bg_bf.c
22 * @brief implementation of a block group using a Bloom filter
23 * to drop duplicate blocks
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_block_group_lib.h"
29#include "gnunet_block_plugin.h"
30
31
32/**
33 * Internal data structure for a block group.
34 */
35struct BfGroupInternals
36{
37 /**
38 * A Bloom filter to weed out duplicate replies probabilistically.
39 */
40 struct GNUNET_CONTAINER_BloomFilter *bf;
41
42 /**
43 * Set from the nonce to mingle the hashes before going into the @e bf.
44 */
45 uint32_t bf_mutator;
46
47 /**
48 * Size of @a bf.
49 */
50 uint32_t bf_size;
51};
52
53
54/**
55 * Serialize state of a block group.
56 *
57 * @param bg group to serialize
58 * @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_size set to the number of bytes in @a raw_data
61 * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not
62 * supported, #GNUNET_SYSERR on error
63 */
64static int
65bf_group_serialize_cb (struct GNUNET_BLOCK_Group *bg,
66 uint32_t *nonce,
67 void **raw_data,
68 size_t *raw_data_size)
69{
70 struct BfGroupInternals *gi = bg->internal_cls;
71 char *raw;
72
73 raw = GNUNET_malloc (gi->bf_size);
74 if (GNUNET_OK !=
75 GNUNET_CONTAINER_bloomfilter_get_raw_data (gi->bf,
76 raw,
77 gi->bf_size))
78 {
79 GNUNET_free (raw);
80 GNUNET_break (0);
81 return GNUNET_SYSERR;
82 }
83 *nonce = gi->bf_mutator;
84 *raw_data = raw;
85 *raw_data_size = gi->bf_size;
86 return GNUNET_OK;
87}
88
89
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/**
145 * Destroy resources used by a block group.
146 *
147 * @param bg group to destroy, NULL is allowed
148 */
149static void
150bf_group_destroy_cb (struct GNUNET_BLOCK_Group *bg)
151{
152 struct BfGroupInternals *gi = bg->internal_cls;
153
154 GNUNET_CONTAINER_bloomfilter_free (gi->bf);
155 GNUNET_free (gi);
156 GNUNET_free (bg);
157}
158
159
160/**
161 * Create a new block group that filters duplicates using a Bloom filter.
162 *
163 * @param ctx block context in which the block group is created
164 * @param bf_size size of the Bloom filter
165 * @param bf_k K-value for the Bloom filter
166 * @param type block type
167 * @param nonce random value used to seed the group creation
168 * @param raw_data optional serialized prior state of the group, NULL if unavailable/fresh
169 * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh
170 * @return block group handle, NULL if block groups are not supported
171 * by this @a type of block (this is not an error)
172 */
173struct GNUNET_BLOCK_Group *
174GNUNET_BLOCK_GROUP_bf_create (void *cls,
175 size_t bf_size,
176 unsigned int bf_k,
177 enum GNUNET_BLOCK_Type type,
178 uint32_t nonce,
179 const void *raw_data,
180 size_t raw_data_size)
181{
182 struct BfGroupInternals *gi;
183 struct GNUNET_BLOCK_Group *bg;
184
185 gi = GNUNET_new (struct BfGroupInternals);
186 gi->bf = GNUNET_CONTAINER_bloomfilter_init ((bf_size != raw_data_size) ?
187 NULL : raw_data,
188 bf_size,
189 bf_k);
190 gi->bf_mutator = nonce;
191 gi->bf_size = bf_size;
192 bg = GNUNET_new (struct GNUNET_BLOCK_Group);
193 bg->type = type;
194 bg->serialize_cb = &bf_group_serialize_cb;
195 bg->mark_seen_cb = &bf_group_mark_seen_cb;
196 bg->merge_cb = &bf_group_merge_cb;
197 bg->destroy_cb = &bf_group_destroy_cb;
198 bg->internal_cls = gi;
199 return bg;
200}
201
202
203/**
204 * Test if @a hc is contained in the Bloom filter of @a bg. If so,
205 * return #GNUNET_YES. If not, add @a hc to the Bloom filter and
206 * return #GNUNET_NO.
207 *
208 * @param bg block group to use for testing
209 * @param hc hash of element to evaluate
210 * @return #GNUNET_YES if @a hc is (likely) a duplicate
211 * #GNUNET_NO if @a hc was definitively not in @bg (but now is)
212 */
213int
214GNUNET_BLOCK_GROUP_bf_test_and_set (struct GNUNET_BLOCK_Group *bg,
215 const struct GNUNET_HashCode *hc)
216{
217 struct BfGroupInternals *gi;
218 struct GNUNET_HashCode mhash;
219
220 if (NULL == bg)
221 return GNUNET_NO;
222 gi = bg->internal_cls;
223 GNUNET_BLOCK_mingle_hash (hc,
224 gi->bf_mutator,
225 &mhash);
226 if (GNUNET_YES ==
227 GNUNET_CONTAINER_bloomfilter_test (gi->bf,
228 &mhash))
229 return GNUNET_YES;
230 GNUNET_CONTAINER_bloomfilter_add (gi->bf,
231 &mhash);
232 return GNUNET_NO;
233}
234
235
236/**
237 * How many bytes should a bloomfilter be if we have already seen
238 * entry_count responses? Sized so that do not have to
239 * re-size the filter too often (to keep it cheap).
240 *
241 * Since other peers will also add entries but not resize the filter,
242 * we should generally pick a slightly larger size than what the
243 * strict math would suggest.
244 *
245 * @param entry_count expected number of entries in the Bloom filter
246 * @param k number of bits set per entry
247 * @return must be a power of two and smaller or equal to 2^15.
248 */
249size_t
250GNUNET_BLOCK_GROUP_compute_bloomfilter_size (unsigned int entry_count,
251 unsigned int k)
252{
253 size_t size;
254 unsigned int ideal = (entry_count * k) / 4;
255 uint16_t max = 1 << 15;
256
257 if (entry_count > max)
258 return max;
259 size = 8;
260 while ((size < max) && (size < ideal))
261 size *= 2;
262 if (size > max)
263 return max;
264 return size;
265}
266
267
268/* end of bg_bf.c */
diff --git a/src/block/block.c b/src/block/block.c
deleted file mode 100644
index 975c0f747..000000000
--- a/src/block/block.c
+++ /dev/null
@@ -1,425 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010, 2017 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file block/block.c
23 * @brief library for data block manipulation
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_constants.h"
29#include "gnunet_signatures.h"
30#include "gnunet_block_lib.h"
31#include "gnunet_block_plugin.h"
32
33
34/**
35 * Handle for a plugin.
36 */
37struct Plugin
38{
39 /**
40 * Name of the shared library.
41 */
42 char *library_name;
43
44 /**
45 * Plugin API.
46 */
47 struct GNUNET_BLOCK_PluginFunctions *api;
48};
49
50
51/**
52 * Handle to an initialized block library.
53 */
54struct GNUNET_BLOCK_Context
55{
56 /**
57 * Array of our plugins.
58 */
59 struct Plugin **plugins;
60
61 /**
62 * Size of the 'plugins' array.
63 */
64 unsigned int num_plugins;
65
66 /**
67 * Our configuration.
68 */
69 const struct GNUNET_CONFIGURATION_Handle *cfg;
70};
71
72
73/**
74 * Mingle hash with the mingle_number to produce different bits.
75 *
76 * @param in original hash code
77 * @param mingle_number number for hash permutation
78 * @param hc where to store the result.
79 */
80void
81GNUNET_BLOCK_mingle_hash (const struct GNUNET_HashCode *in,
82 uint32_t mingle_number,
83 struct GNUNET_HashCode *hc)
84{
85 struct GNUNET_HashCode m;
86
87 GNUNET_CRYPTO_hash (&mingle_number,
88 sizeof(uint32_t),
89 &m);
90 GNUNET_CRYPTO_hash_xor (&m,
91 in,
92 hc);
93}
94
95
96/**
97 * Add a plugin to the list managed by the block library.
98 *
99 * @param cls the block context
100 * @param library_name name of the plugin
101 * @param lib_ret the plugin API
102 */
103static void
104add_plugin (void *cls,
105 const char *library_name,
106 void *lib_ret)
107{
108 struct GNUNET_BLOCK_Context *ctx = cls;
109 struct GNUNET_BLOCK_PluginFunctions *api = lib_ret;
110 struct Plugin *plugin;
111
112 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
113 "Loading block plugin `%s'\n",
114 library_name);
115 plugin = GNUNET_new (struct Plugin);
116 plugin->api = api;
117 plugin->library_name = GNUNET_strdup (library_name);
118 GNUNET_array_append (ctx->plugins,
119 ctx->num_plugins,
120 plugin);
121}
122
123
124/**
125 * Create a block context. Loads the block plugins.
126 *
127 * @param cfg configuration to use
128 * @return NULL on error
129 */
130struct GNUNET_BLOCK_Context *
131GNUNET_BLOCK_context_create (const struct GNUNET_CONFIGURATION_Handle *cfg)
132{
133 struct GNUNET_BLOCK_Context *ctx;
134
135 ctx = GNUNET_new (struct GNUNET_BLOCK_Context);
136 ctx->cfg = cfg;
137 GNUNET_PLUGIN_load_all_in_context (GNUNET_OS_project_data_default (),
138 "libgnunet_plugin_block_",
139 (void *) cfg,
140 &add_plugin,
141 ctx);
142 return ctx;
143}
144
145
146/**
147 * Destroy the block context.
148 *
149 * @param ctx context to destroy
150 */
151void
152GNUNET_BLOCK_context_destroy (struct GNUNET_BLOCK_Context *ctx)
153{
154 struct Plugin *plugin;
155
156 for (unsigned int i = 0; i < ctx->num_plugins; i++)
157 {
158 plugin = ctx->plugins[i];
159 GNUNET_break (NULL ==
160 GNUNET_PLUGIN_unload (plugin->library_name,
161 plugin->api));
162 GNUNET_free (plugin->library_name);
163 GNUNET_free (plugin);
164 }
165 GNUNET_free (ctx->plugins);
166 GNUNET_free (ctx);
167}
168
169
170/**
171 * Serialize state of a block group.
172 *
173 * @param bg group to serialize
174 * @param[out] nonce set to the nonce of the @a bg
175 * @param[out] raw_data set to the serialized state
176 * @param[out] raw_data_size set to the number of bytes in @a raw_data
177 * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not
178 * supported, #GNUNET_SYSERR on error
179 */
180int
181GNUNET_BLOCK_group_serialize (struct GNUNET_BLOCK_Group *bg,
182 uint32_t *nonce,
183 void **raw_data,
184 size_t *raw_data_size)
185{
186 *nonce = 0;
187 *raw_data = NULL;
188 *raw_data_size = 0;
189 if (NULL == bg)
190 return GNUNET_NO;
191 if (NULL == bg->serialize_cb)
192 return GNUNET_NO;
193 return bg->serialize_cb (bg,
194 nonce,
195 raw_data,
196 raw_data_size);
197}
198
199
200/**
201 * Destroy resources used by a block group.
202 *
203 * @param bg group to destroy, NULL is allowed
204 */
205void
206GNUNET_BLOCK_group_destroy (struct GNUNET_BLOCK_Group *bg)
207{
208 if (NULL == bg)
209 return;
210 bg->destroy_cb (bg);
211}
212
213
214/**
215 * Try merging two block groups. Afterwards, @a bg1 should remain
216 * valid and contain the rules from both @a bg1 and @bg2, and
217 * @a bg2 should be destroyed (as part of this call). The latter
218 * should happen even if merging is not supported.
219 *
220 * @param[in,out] bg1 first group to merge, is updated
221 * @param bg2 second group to merge, is destroyed
222 * @return #GNUNET_OK on success,
223 * #GNUNET_NO if merge failed due to different nonce
224 * #GNUNET_SYSERR if merging is not supported
225 */
226int
227GNUNET_BLOCK_group_merge (struct GNUNET_BLOCK_Group *bg1,
228 struct GNUNET_BLOCK_Group *bg2)
229{
230 int ret;
231
232 if (NULL == bg2)
233 return GNUNET_OK;
234 if (NULL == bg1)
235 {
236 bg2->destroy_cb (bg2);
237 return GNUNET_OK;
238 }
239 if (NULL == bg1->merge_cb)
240 return GNUNET_SYSERR;
241 GNUNET_assert (bg1->merge_cb == bg1->merge_cb);
242 ret = bg1->merge_cb (bg1,
243 bg2);
244 bg2->destroy_cb (bg2);
245 return ret;
246}
247
248
249/**
250 * Find a plugin for the given type.
251 *
252 * @param ctx context to search
253 * @param type type to look for
254 * @return NULL if no matching plugin exists
255 */
256static struct GNUNET_BLOCK_PluginFunctions *
257find_plugin (struct GNUNET_BLOCK_Context *ctx,
258 enum GNUNET_BLOCK_Type type)
259{
260 struct Plugin *plugin;
261 unsigned int j;
262
263 for (unsigned i = 0; i < ctx->num_plugins; i++)
264 {
265 plugin = ctx->plugins[i];
266 j = 0;
267 while (0 != (plugin->api->types[j]))
268 {
269 if (type == plugin->api->types[j])
270 return plugin->api;
271 j++;
272 }
273 }
274 return NULL;
275}
276
277
278/**
279 * Create a new block group.
280 *
281 * @param ctx block context in which the block group is created
282 * @param type type of the block for which we are creating the group
283 * @param nonce random value used to seed the group creation
284 * @param raw_data optional serialized prior state of the group, NULL if unavailable/fresh
285 * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh
286 * @return block group handle, NULL if block groups are not supported
287 * by this @a type of block (this is not an error)
288 */
289struct GNUNET_BLOCK_Group *
290GNUNET_BLOCK_group_create (struct GNUNET_BLOCK_Context *ctx,
291 enum GNUNET_BLOCK_Type type,
292 uint32_t nonce,
293 const void *raw_data,
294 size_t raw_data_size,
295 ...)
296{
297 struct GNUNET_BLOCK_PluginFunctions *plugin;
298 struct GNUNET_BLOCK_Group *bg;
299 va_list ap;
300
301 plugin = find_plugin (ctx,
302 type);
303 if (NULL == plugin)
304 return NULL;
305 if (NULL == plugin->create_group)
306 return NULL;
307 va_start (ap,
308 raw_data_size);
309 bg = plugin->create_group (plugin->cls,
310 type,
311 nonce,
312 raw_data,
313 raw_data_size,
314 ap);
315 va_end (ap);
316 return bg;
317}
318
319
320/**
321 * Function called to validate a reply or a request. For
322 * request evaluation, simply pass "NULL" for the reply_block.
323 * Note that it is assumed that the reply has already been
324 * matched to the key (and signatures checked) as it would
325 * be done with the "get_key" function.
326 *
327 * @param ctx block contxt
328 * @param type block type
329 * @param block block group to use
330 * @param eo control flags
331 * @param query original query (hash)
332 * @param xquery extended query data (can be NULL, depending on type)
333 * @param xquery_size number of bytes in @a xquery
334 * @param reply_block response to validate
335 * @param reply_block_size number of bytes in @a reply_block
336 * @return characterization of result
337 */
338enum GNUNET_BLOCK_EvaluationResult
339GNUNET_BLOCK_evaluate (struct GNUNET_BLOCK_Context *ctx,
340 enum GNUNET_BLOCK_Type type,
341 struct GNUNET_BLOCK_Group *group,
342 enum GNUNET_BLOCK_EvaluationOptions eo,
343 const struct GNUNET_HashCode *query,
344 const void *xquery,
345 size_t xquery_size,
346 const void *reply_block,
347 size_t reply_block_size)
348{
349 struct GNUNET_BLOCK_PluginFunctions *plugin = find_plugin (ctx,
350 type);
351
352 if (NULL == plugin)
353 return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED;
354 return plugin->evaluate (plugin->cls,
355 ctx,
356 type,
357 group,
358 eo,
359 query,
360 xquery,
361 xquery_size,
362 reply_block,
363 reply_block_size);
364}
365
366
367/**
368 * Function called to obtain the key for a block.
369 *
370 * @param ctx block context
371 * @param type block type
372 * @param block block to get the key for
373 * @param block_size number of bytes in @a block
374 * @param key set to the key (query) for the given block
375 * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported
376 * (or if extracting a key from a block of this type does not work)
377 */
378int
379GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx,
380 enum GNUNET_BLOCK_Type type,
381 const void *block,
382 size_t block_size,
383 struct GNUNET_HashCode *key)
384{
385 struct GNUNET_BLOCK_PluginFunctions *plugin = find_plugin (ctx,
386 type);
387
388 if (plugin == NULL)
389 return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED;
390 return plugin->get_key (plugin->cls,
391 type,
392 block,
393 block_size,
394 key);
395}
396
397
398/**
399 * Update block group to filter out the given results. Note that the
400 * use of a hash for seen results implies that the caller magically
401 * knows how the specific block engine hashes for filtering
402 * duplicates, so this API may not always apply.
403 *
404 * @param bf_mutator mutation value to use
405 * @param seen_results results already seen
406 * @param seen_results_count number of entries in @a seen_results
407 * @return #GNUNET_SYSERR if not supported, #GNUNET_OK on success
408 */
409int
410GNUNET_BLOCK_group_set_seen (struct GNUNET_BLOCK_Group *bg,
411 const struct GNUNET_HashCode *seen_results,
412 unsigned int seen_results_count)
413{
414 if (NULL == bg)
415 return GNUNET_OK;
416 if (NULL == bg->mark_seen_cb)
417 return GNUNET_SYSERR;
418 bg->mark_seen_cb (bg,
419 seen_results,
420 seen_results_count);
421 return GNUNET_OK;
422}
423
424
425/* end of block.c */
diff --git a/src/block/plugin_block_template.c b/src/block/plugin_block_template.c
deleted file mode 100644
index ecd46e364..000000000
--- a/src/block/plugin_block_template.c
+++ /dev/null
@@ -1,195 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2010 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file block/plugin_block_template.c
23 * @brief template for a block plugin
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_block_plugin.h"
29#include "gnunet_block_group_lib.h"
30
31#define DEBUG_TEMPLATE GNUNET_EXTRA_LOGGING
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 unsigned int bf_size;
67 const char *guard;
68
69 guard = va_arg (va, const char *);
70 if (0 == strcmp (guard,
71 "seen-set-size"))
72 bf_size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va, unsigned
73 int),
74 BLOOMFILTER_K);
75 else if (0 == strcmp (guard,
76 "filter-size"))
77 bf_size = va_arg (va, unsigned int);
78 else
79 {
80 GNUNET_break (0);
81 bf_size = TEMPLATE_BF_SIZE;
82 }
83 GNUNET_break (NULL == va_arg (va, const char *));
84 return GNUNET_BLOCK_GROUP_bf_create (cls,
85 bf_size,
86 BLOOMFILTER_K,
87 type,
88 nonce,
89 raw_data,
90 raw_data_size);
91}
92
93
94/**
95 * Function called to validate a reply or a request. For
96 * request evaluation, simply pass "NULL" for the reply_block.
97 *
98 * @param cls closure
99 * @param ctx context
100 * @param type block type
101 * @param group block group to use
102 * @param eo control flags
103 * @param query original query (hash)
104 * @param xquery extrended query data (can be NULL, depending on type)
105 * @param xquery_size number of bytes in xquery
106 * @param reply_block response to validate
107 * @param reply_block_size number of bytes in reply block
108 * @return characterization of result
109 */
110static enum GNUNET_BLOCK_EvaluationResult
111block_plugin_template_evaluate (void *cls,
112 struct GNUNET_BLOCK_Context *ctx,
113 enum GNUNET_BLOCK_Type type,
114 struct GNUNET_BLOCK_Group *group,
115 enum GNUNET_BLOCK_EvaluationOptions eo,
116 const struct GNUNET_HashCode *query,
117 const void *xquery,
118 size_t xquery_size,
119 const void *reply_block,
120 size_t reply_block_size)
121{
122 struct GNUNET_HashCode chash;
123
124 if (NULL == reply_block)
125 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
126 GNUNET_CRYPTO_hash (reply_block,
127 reply_block_size,
128 &chash);
129 if (GNUNET_YES ==
130 GNUNET_BLOCK_GROUP_bf_test_and_set (group,
131 &chash))
132 return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE;
133 return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED;
134}
135
136
137/**
138 * Function called to obtain the key for a block.
139 *
140 * @param cls closure
141 * @param type block type
142 * @param block block to get the key for
143 * @param block_size number of bytes in block
144 * @param key set to the key (query) for the given block
145 * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported
146 * (or if extracting a key from a block of this type does not work)
147 */
148static int
149block_plugin_template_get_key (void *cls,
150 enum GNUNET_BLOCK_Type type,
151 const void *block,
152 size_t block_size,
153 struct GNUNET_HashCode *key)
154{
155 return GNUNET_SYSERR;
156}
157
158
159/**
160 * Entry point for the plugin.
161 *
162 * @param cls a `const struct GNUNET_CONFIGURATION_Handle`
163 */
164void *
165libgnunet_plugin_block_template_init (void *cls)
166{
167 static enum GNUNET_BLOCK_Type types[] = {
168 /* FIXME: insert supported block types here */
169 GNUNET_BLOCK_TYPE_ANY /* end of list */
170 };
171 struct GNUNET_BLOCK_PluginFunctions *api;
172
173 api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions);
174 api->evaluate = &block_plugin_template_evaluate;
175 api->get_key = &block_plugin_template_get_key;
176 api->create_group = &block_plugin_template_create_group;
177 api->types = types;
178 return api;
179}
180
181
182/**
183 * Exit point from the plugin.
184 */
185void *
186libgnunet_plugin_block_template_done (void *cls)
187{
188 struct GNUNET_BLOCK_PluginFunctions *api = cls;
189
190 GNUNET_free (api);
191 return NULL;
192}
193
194
195/* end of plugin_block_template.c */
diff --git a/src/block/plugin_block_test.c b/src/block/plugin_block_test.c
deleted file mode 100644
index 45d54d339..000000000
--- a/src/block/plugin_block_test.c
+++ /dev/null
@@ -1,209 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2010 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file block/plugin_block_test.c
23 * @brief block plugin to test the DHT as a simple key-value store;
24 * this plugin simply accepts any (new) response for any key
25 * @author Christian Grothoff
26 */
27
28#include "platform.h"
29#include "gnunet_block_plugin.h"
30#include "gnunet_block_group_lib.h"
31
32/**
33 * Number of bits we set per entry in the bloomfilter.
34 * Do not change!
35 */
36#define BLOOMFILTER_K 16
37
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 unsigned int bf_size;
65 const char *guard;
66
67 guard = va_arg (va, const char *);
68 if (0 == strcmp (guard,
69 "seen-set-size"))
70 bf_size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va, unsigned
71 int),
72 BLOOMFILTER_K);
73 else if (0 == strcmp (guard,
74 "filter-size"))
75 bf_size = va_arg (va, unsigned int);
76 else
77 {
78 GNUNET_break (0);
79 bf_size = TEST_BF_SIZE;
80 }
81 GNUNET_break (NULL == va_arg (va, const char *));
82 return GNUNET_BLOCK_GROUP_bf_create (cls,
83 bf_size,
84 BLOOMFILTER_K,
85 type,
86 nonce,
87 raw_data,
88 raw_data_size);
89}
90
91
92/**
93 * Function called to validate a reply or a request. For
94 * request evaluation, simply pass "NULL" for the reply_block.
95 *
96 * @param cls closure
97 * @param ctx block context
98 * @param type block type
99 * @param group group to check against
100 * @param eo control flags
101 * @param query original query (hash)
102 * @param xquery extrended query data (can be NULL, depending on type)
103 * @param xquery_size number of bytes in @a xquery
104 * @param reply_block response to validate
105 * @param reply_block_size number of bytes in @a reply_block
106 * @return characterization of result
107 */
108static enum GNUNET_BLOCK_EvaluationResult
109block_plugin_test_evaluate (void *cls,
110 struct GNUNET_BLOCK_Context *ctx,
111 enum GNUNET_BLOCK_Type type,
112 struct GNUNET_BLOCK_Group *group,
113 enum GNUNET_BLOCK_EvaluationOptions eo,
114 const struct GNUNET_HashCode *query,
115 const void *xquery,
116 size_t xquery_size,
117 const void *reply_block,
118 size_t reply_block_size)
119{
120 struct GNUNET_HashCode chash;
121
122 if (GNUNET_BLOCK_TYPE_TEST != type)
123 {
124 GNUNET_break (0);
125 return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED;
126 }
127 if (0 != xquery_size)
128 {
129 GNUNET_break_op (0);
130 return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID;
131 }
132 if (NULL == reply_block)
133 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
134 GNUNET_CRYPTO_hash (reply_block,
135 reply_block_size,
136 &chash);
137 if (GNUNET_YES ==
138 GNUNET_BLOCK_GROUP_bf_test_and_set (group,
139 &chash))
140 return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE;
141 return GNUNET_BLOCK_EVALUATION_OK_MORE;
142}
143
144
145/**
146 * Function called to obtain the key for a block.
147 *
148 * @param cls closure
149 * @param type block type
150 * @param block block to get the key for
151 * @param block_size number of bytes in @a block
152 * @param key set to the key (query) for the given block
153 * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported
154 * (or if extracting a key from a block of this type does not work)
155 */
156static int
157block_plugin_test_get_key (void *cls,
158 enum GNUNET_BLOCK_Type type,
159 const void *block,
160 size_t block_size,
161 struct GNUNET_HashCode *key)
162{
163 /* always fails since there is no fixed relationship between
164 * keys and values for test values */
165 return GNUNET_SYSERR;
166}
167
168
169/**
170 * Entry point for the plugin.
171 *
172 * @param cls NULL
173 * @return the exported block API
174 */
175void *
176libgnunet_plugin_block_test_init (void *cls)
177{
178 static enum GNUNET_BLOCK_Type types[] = {
179 GNUNET_BLOCK_TYPE_TEST,
180 GNUNET_BLOCK_TYPE_ANY /* end of list */
181 };
182 struct GNUNET_BLOCK_PluginFunctions *api;
183
184 api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions);
185 api->evaluate = &block_plugin_test_evaluate;
186 api->get_key = &block_plugin_test_get_key;
187 api->create_group = &block_plugin_test_create_group;
188 api->types = types;
189 return api;
190}
191
192
193/**
194 * Exit point from the plugin.
195 *
196 * @param cls the return value from #libgnunet_plugin_block_test_init
197 * @return NULL
198 */
199void *
200libgnunet_plugin_block_test_done (void *cls)
201{
202 struct GNUNET_BLOCK_PluginFunctions *api = cls;
203
204 GNUNET_free (api);
205 return NULL;
206}
207
208
209/* end of plugin_block_test.c */