GNUnet  0.11.x
plugin_block_dht.c
Go to the documentation of this file.
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 
28 #include "platform.h"
29 #include "gnunet_constants.h"
30 #include "gnunet_hello_lib.h"
31 #include "gnunet_block_plugin.h"
32 #include "gnunet_block_group_lib.h"
33 
34 #define DEBUG_DHT GNUNET_EXTRA_LOGGING
35 
40 #define BLOOMFILTER_K 16
41 
42 
55 static struct GNUNET_BLOCK_Group *
58  uint32_t nonce,
59  const void *raw_data,
60  size_t raw_data_size,
61  va_list va)
62 {
63  unsigned int bf_size;
64  const char *guard;
65 
66  guard = va_arg (va, const char *);
67  if (0 == strcmp (guard,
68  "seen-set-size"))
69  bf_size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va,
70  unsigned int),
72  else if (0 == strcmp (guard,
73  "filter-size"))
74  bf_size = va_arg (va, unsigned int);
75  else
76  {
77  GNUNET_break (0);
78  bf_size = 8;
79  }
80  GNUNET_break (NULL == va_arg (va, const char *));
81  return GNUNET_BLOCK_GROUP_bf_create (cls,
82  bf_size,
84  type,
85  nonce,
86  raw_data,
87  raw_data_size);
88 }
89 
90 
108 block_plugin_dht_evaluate (void *cls,
109  struct GNUNET_BLOCK_Context *ctx,
110  enum GNUNET_BLOCK_Type type,
111  struct GNUNET_BLOCK_Group *group,
113  const struct GNUNET_HashCode *query,
114  const void *xquery,
115  size_t xquery_size,
116  const void *reply_block,
117  size_t reply_block_size)
118 {
119  const struct GNUNET_HELLO_Message *hello;
120  struct GNUNET_PeerIdentity pid;
121  const struct GNUNET_MessageHeader *msg;
122  struct GNUNET_HashCode phash;
123 
126  if (0 != xquery_size)
127  {
128  GNUNET_break_op (0);
130  }
131  if (NULL == reply_block)
133  if (reply_block_size < sizeof(struct GNUNET_MessageHeader))
134  {
135  GNUNET_break_op (0);
137  }
138  msg = reply_block;
139  if (reply_block_size != ntohs (msg->size))
140  {
141  GNUNET_break_op (0);
143  }
144  hello = reply_block;
145  if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid))
146  {
147  GNUNET_break_op (0);
149  }
151  sizeof(pid),
152  &phash);
153  if (GNUNET_YES ==
155  &phash))
158 }
159 
160 
172 static enum GNUNET_GenericReturnValue
174  enum GNUNET_BLOCK_Type type,
175  const struct GNUNET_HashCode *query,
176  const void *xquery,
177  size_t xquery_size)
178 {
180  return GNUNET_SYSERR;
181  if (0 != xquery_size)
182  {
183  GNUNET_break_op (0);
184  return GNUNET_NO;
185  }
186  return GNUNET_OK;
187 }
188 
189 
200 static enum GNUNET_GenericReturnValue
202  enum GNUNET_BLOCK_Type type,
203  const struct GNUNET_HashCode *query,
204  const void *block,
205  size_t block_size)
206 {
207  const struct GNUNET_HELLO_Message *hello;
208  struct GNUNET_PeerIdentity pid;
209  const struct GNUNET_MessageHeader *msg;
210 
212  return GNUNET_SYSERR;
213  if (block_size < sizeof(struct GNUNET_MessageHeader))
214  {
215  GNUNET_break_op (0);
216  return GNUNET_NO;
217  }
218  msg = block;
219  if (block_size != ntohs (msg->size))
220  {
221  GNUNET_break_op (0);
222  return GNUNET_NO;
223  }
224  hello = block;
225  if (GNUNET_OK !=
226  GNUNET_HELLO_get_id (hello,
227  &pid))
228  {
229  GNUNET_break_op (0);
230  return GNUNET_NO;
231  }
232  return GNUNET_OK;
233 }
234 
235 
254  void *cls,
255  enum GNUNET_BLOCK_Type type,
256  struct GNUNET_BLOCK_Group *group,
257  const struct GNUNET_HashCode *query,
258  const void *xquery,
259  size_t xquery_size,
260  const void *reply_block,
261  size_t reply_block_size)
262 {
263  const struct GNUNET_HELLO_Message *hello;
264  struct GNUNET_PeerIdentity pid;
265  const struct GNUNET_MessageHeader *msg;
266  struct GNUNET_HashCode phash;
267 
270  if (reply_block_size < sizeof(struct GNUNET_MessageHeader))
271  {
272  GNUNET_break_op (0);
274  }
275  msg = reply_block;
276  if (reply_block_size != ntohs (msg->size))
277  {
278  GNUNET_break_op (0);
280  }
281  hello = reply_block;
282  if (GNUNET_OK !=
283  GNUNET_HELLO_get_id (hello,
284  &pid))
285  {
286  GNUNET_break_op (0);
288  }
290  sizeof(pid),
291  &phash);
292  if (GNUNET_YES ==
294  &phash))
297 }
298 
299 
311 static enum GNUNET_GenericReturnValue
312 block_plugin_dht_get_key (void *cls,
313  enum GNUNET_BLOCK_Type type,
314  const void *block,
315  size_t block_size,
316  struct GNUNET_HashCode *key)
317 {
318  const struct GNUNET_MessageHeader *msg;
319  const struct GNUNET_HELLO_Message *hello;
320  struct GNUNET_PeerIdentity *pid;
321 
323  return GNUNET_SYSERR;
324  if (block_size < sizeof(struct GNUNET_MessageHeader))
325  {
327  "block-dht",
328  _ ("Block not of type %u\n"),
330  return GNUNET_NO;
331  }
332  msg = block;
333  if (block_size != ntohs (msg->size))
334  {
336  "block-dht",
337  _ ("Size mismatch for block with type %u\n"),
339  return GNUNET_NO;
340  }
341  hello = block;
342  memset (key, 0, sizeof(*key));
343  pid = (struct GNUNET_PeerIdentity *) key;
344  if (GNUNET_OK != GNUNET_HELLO_get_id (hello, pid))
345  {
347  "block-dht",
348  _ ("Block of type %u is malformed\n"),
350  return GNUNET_NO;
351  }
352  return GNUNET_OK;
353 }
354 
355 
359 void *
361 {
362  static enum GNUNET_BLOCK_Type types[] = {
364  GNUNET_BLOCK_TYPE_ANY /* end of list */
365  };
366  struct GNUNET_BLOCK_PluginFunctions *api;
367 
375  api->types = types;
376  return api;
377 }
378 
379 
383 void *
385 {
386  struct GNUNET_BLOCK_PluginFunctions *api = cls;
387 
388  GNUNET_free (api);
389  return NULL;
390 }
391 
392 
393 /* end of plugin_block_dht.c */
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
#define GNUNET_log_from(kind, comp,...)
GNUNET_GenericReturnValue
Named constants for return values.
Definition: gnunet_common.h:92
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
int GNUNET_BLOCK_GROUP_bf_test_and_set(struct GNUNET_BLOCK_Group *bg, const struct GNUNET_HashCode *hc)
Test if hc is contained in the Bloom filter of bg.
Definition: bg_bf.c:214
size_t GNUNET_BLOCK_GROUP_compute_bloomfilter_size(unsigned int entry_count, unsigned int k)
How many bytes should a bloomfilter be if we have already seen entry_count responses?...
Definition: bg_bf.c:250
GNUNET_BLOCK_ReplyEvaluationResult
Possible ways for how a block may relate to a query.
struct GNUNET_BLOCK_Group * GNUNET_BLOCK_GROUP_bf_create(void *cls, size_t bf_size, unsigned int bf_k, enum GNUNET_BLOCK_Type type, uint32_t nonce, const void *raw_data, size_t raw_data_size)
Create a new block group that filters duplicates using a Bloom filter.
Definition: bg_bf.c:174
GNUNET_BLOCK_EvaluationResult
Possible ways for how a block may relate to a query.
GNUNET_BLOCK_EvaluationOptions
Flags that can be set to control the evaluation.
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
@ GNUNET_BLOCK_REPLY_OK_MORE
Valid result, and there may be more.
@ GNUNET_BLOCK_REPLY_OK_DUPLICATE
Valid result, but suppressed because it is a duplicate.
@ GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED
Specified block type not supported by any plugin.
@ GNUNET_BLOCK_REPLY_INVALID
Block does not match query (invalid result)
@ GNUNET_BLOCK_EVALUATION_RESULT_INVALID
Block does not match query (invalid result)
@ GNUNET_BLOCK_EVALUATION_REQUEST_INVALID
Query format does not match block type (invalid query).
@ GNUNET_BLOCK_EVALUATION_OK_MORE
Valid result, and there may be more.
@ GNUNET_BLOCK_EVALUATION_OK_DUPLICATE
Valid result, but suppressed because it is a duplicate.
@ GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED
Specified block type not supported by this plugin.
@ GNUNET_BLOCK_EVALUATION_REQUEST_VALID
Query is valid, no reply given.
@ GNUNET_BLOCK_TYPE_ANY
Any type of block, used as a wildcard when searching.
@ GNUNET_BLOCK_TYPE_DHT_HELLO
Type of a block that contains a HELLO for a peer (for DHT and CADET find-peer operations).
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
int GNUNET_HELLO_get_id(const struct GNUNET_HELLO_Message *hello, struct GNUNET_PeerIdentity *peer)
Get the peer identity from a HELLO message.
Definition: hello.c:671
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
static enum GNUNET_BLOCK_ReplyEvaluationResult block_plugin_dht_check_reply(void *cls, enum GNUNET_BLOCK_Type type, struct GNUNET_BLOCK_Group *group, const struct GNUNET_HashCode *query, const void *xquery, size_t xquery_size, const void *reply_block, size_t reply_block_size)
Function called to validate a reply to a request.
static enum GNUNET_GenericReturnValue block_plugin_dht_check_block(void *cls, enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode *query, const void *block, size_t block_size)
Function called to validate a block for storage.
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)
Create a new block group.
#define BLOOMFILTER_K
Number of bits we set per entry in the bloomfilter.
static enum GNUNET_GenericReturnValue block_plugin_dht_check_query(void *cls, enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode *query, const void *xquery, size_t xquery_size)
Function called to validate a query.
static enum GNUNET_BLOCK_EvaluationResult block_plugin_dht_evaluate(void *cls, struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, struct GNUNET_BLOCK_Group *group, enum GNUNET_BLOCK_EvaluationOptions eo, const struct GNUNET_HashCode *query, const void *xquery, size_t xquery_size, const void *reply_block, size_t reply_block_size)
Function called to validate a reply or a request.
static enum GNUNET_GenericReturnValue block_plugin_dht_get_key(void *cls, enum GNUNET_BLOCK_Type type, const void *block, size_t block_size, struct GNUNET_HashCode *key)
Function called to obtain the key for a block.
void * libgnunet_plugin_block_dht_init(void *cls)
Entry point for the plugin.
void * libgnunet_plugin_block_dht_done(void *cls)
Exit point from the plugin.
Handle to an initialized block library.
Definition: block.c:55
Block group data.
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
enum GNUNET_BLOCK_Type * types
0-terminated array of block types supported by this plugin.
GNUNET_BLOCK_QueryEvaluationFunction check_query
Check that a query is well-formed.
GNUNET_BLOCK_BlockEvaluationFunction check_block
Check that a block is well-formed.
GNUNET_BLOCK_GetKeyFunction get_key
Obtain the key for a given block (if possible).
GNUNET_BLOCK_ReplyEvaluationFunction check_reply
Check that a reply block matches a query.
GNUNET_BLOCK_GroupCreateFunction create_group
Create a block group to process a bunch of blocks in a shared context (i.e.
void * cls
Closure for all of the callbacks.
GNUNET_BLOCK_EvaluationFunction evaluate
Main function of a block plugin.
A HELLO message is used to exchange information about transports with other peers.
A 512-bit hashcode.
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
The identity of the host (wraps the signing key of the peer).
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model