GNUnet  0.20.0
plugin_block_regex.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2013 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 
26 #include "platform.h"
27 #include "gnunet_block_plugin.h"
28 #include "gnunet_block_group_lib.h"
29 #include "block_regex.h"
30 #include "regex_block_lib.h"
31 #include "gnunet_signatures.h"
32 
33 
38 #define BLOOMFILTER_K 16
39 
40 
44 #define REGEX_BF_SIZE 8
45 
46 
58 static struct GNUNET_BLOCK_Group *
61  const void *raw_data,
62  size_t raw_data_size,
63  va_list va)
64 {
65  unsigned int bf_size;
66  const char *guard;
67 
68  guard = va_arg (va, const char *);
69  if (0 == strcmp (guard,
70  "seen-set-size"))
71  bf_size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va, unsigned
72  int),
74  else if (0 == strcmp (guard,
75  "filter-size"))
76  bf_size = va_arg (va, unsigned int);
77  else
78  {
79  GNUNET_break (0);
80  bf_size = REGEX_BF_SIZE;
81  }
82  GNUNET_break (NULL == va_arg (va, const char *));
83  return GNUNET_BLOCK_GROUP_bf_create (cls,
84  bf_size,
86  type,
87  raw_data,
88  raw_data_size);
89 }
90 
91 
103 static enum GNUNET_GenericReturnValue
105  enum GNUNET_BLOCK_Type type,
106  const struct GNUNET_HashCode *query,
107  const void *xquery,
108  size_t xquery_size)
109 {
110  switch (type)
111  {
113  if (0 != xquery_size)
114  {
115  const char *s;
116 
117  s = (const char *) xquery;
118  if ('\0' != s[xquery_size - 1]) /* must be valid 0-terminated string */
119  {
120  GNUNET_break_op (0);
121  return GNUNET_NO;
122  }
123  }
124  return GNUNET_OK;
126  if (0 != xquery_size)
127  {
128  GNUNET_break_op (0);
129  return GNUNET_NO;
130  }
131  return GNUNET_OK;
132  default:
133  GNUNET_break (0);
134  return GNUNET_SYSERR;
135  }
136 }
137 
138 
148 static enum GNUNET_GenericReturnValue
150  enum GNUNET_BLOCK_Type type,
151  const void *block,
152  size_t block_size)
153 {
154  switch (type)
155  {
157  if (GNUNET_SYSERR ==
158  REGEX_BLOCK_check (block,
159  block_size,
160  NULL,
161  NULL))
162  return GNUNET_NO;
163  return GNUNET_OK;
165  {
166  const struct RegexAcceptBlock *rba;
167 
168  if (sizeof(struct RegexAcceptBlock) != block_size)
169  {
170  GNUNET_break_op (0);
171  return GNUNET_NO;
172  }
173  rba = block;
174  if (ntohl (rba->purpose.size) !=
175  sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
176  + sizeof(struct GNUNET_TIME_AbsoluteNBO)
177  + sizeof(struct GNUNET_HashCode))
178  {
179  GNUNET_break_op (0);
180  return GNUNET_NO;
181  }
183  rba->expiration_time)))
184  {
185  return GNUNET_NO;
186  }
187  if (GNUNET_OK !=
189  &rba->purpose,
190  &rba->signature,
191  &rba->peer.public_key))
192  {
193  GNUNET_break_op (0);
194  return GNUNET_NO;
195  }
196  return GNUNET_OK;
197  }
198  default:
199  GNUNET_break (0);
200  return GNUNET_SYSERR;
201  }
202 }
203 
204 
223  void *cls,
224  enum GNUNET_BLOCK_Type type,
225  struct GNUNET_BLOCK_Group *group,
226  const struct GNUNET_HashCode *query,
227  const void *xquery,
228  size_t xquery_size,
229  const void *reply_block,
230  size_t reply_block_size)
231 {
232  struct GNUNET_HashCode chash;
233 
234  switch (type)
235  {
237  if (0 != xquery_size)
238  {
239  const char *s;
240 
241  s = (const char *) xquery;
242  GNUNET_assert ('\0' == s[xquery_size - 1]);
243  }
244  switch (REGEX_BLOCK_check (reply_block,
245  reply_block_size,
246  query,
247  xquery))
248  {
249  case GNUNET_SYSERR:
250  GNUNET_assert (0);
251  case GNUNET_NO:
252  /* xquery mismatch, can happen */
254  default:
255  break;
256  }
257  GNUNET_CRYPTO_hash (reply_block,
258  reply_block_size,
259  &chash);
260  if (GNUNET_YES ==
262  &chash))
266  {
267  const struct RegexAcceptBlock *rba;
268 
269  GNUNET_assert (sizeof(struct RegexAcceptBlock) == reply_block_size);
270  rba = reply_block;
271  GNUNET_assert (ntohl (rba->purpose.size) ==
272  sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
273  + sizeof(struct GNUNET_TIME_AbsoluteNBO)
274  + sizeof(struct GNUNET_HashCode));
275  GNUNET_CRYPTO_hash (reply_block,
276  reply_block_size,
277  &chash);
278  if (GNUNET_YES ==
280  &chash))
283  }
284  default:
285  GNUNET_break (0);
287  }
289 }
290 
291 
303 static enum GNUNET_GenericReturnValue
304 block_plugin_regex_get_key (void *cls,
305  enum GNUNET_BLOCK_Type type,
306  const void *block,
307  size_t block_size,
308  struct GNUNET_HashCode *key)
309 {
310  switch (type)
311  {
313  if (GNUNET_OK !=
314  REGEX_BLOCK_get_key (block,
315  block_size,
316  key))
317  {
318  GNUNET_break_op (0);
319  memset (key,
320  0,
321  sizeof (*key));
322  return GNUNET_OK;
323  }
324  return GNUNET_OK;
326  if (sizeof(struct RegexAcceptBlock) != block_size)
327  {
328  GNUNET_break_op (0);
329  memset (key,
330  0,
331  sizeof (*key));
332  return GNUNET_OK;
333  }
334  *key = ((struct RegexAcceptBlock *) block)->key;
335  return GNUNET_OK;
336  default:
337  GNUNET_break (0);
338  return GNUNET_SYSERR;
339  }
340 }
341 
342 
346 void *
348 {
349  static const enum GNUNET_BLOCK_Type types[] = {
352  GNUNET_BLOCK_TYPE_ANY /* end of list */
353  };
354  struct GNUNET_BLOCK_PluginFunctions *api;
355 
362  api->types = types;
363  return api;
364 }
365 
366 
370 void *
372 {
373  struct GNUNET_BLOCK_PluginFunctions *api = cls;
374 
375  GNUNET_free (api);
376  return NULL;
377 }
378 
379 
380 /* end of plugin_block_regex.c */
regex block formats
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
@ GNUNET_BLOCK_TYPE_REGEX_ACCEPT
Block to store a cadet regex accepting state.
@ GNUNET_BLOCK_TYPE_REGEX
Block to store a cadet regex state.
@ GNUNET_BLOCK_TYPE_ANY
Identifier for any block.
#define GNUNET_SIGNATURE_PURPOSE_REGEX_ACCEPT
Accept state in regex DFA.
struct GNUNET_HashCode key
The key used in the DHT.
API for block plugins.
enum GNUNET_GenericReturnValue 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:232
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:268
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, 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:173
@ 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_IRRELEVANT
Block does not match xquery (valid result, not relevant for the request)
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_verify_(uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EddsaSignature *sig, const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Verify EdDSA signature.
Definition: crypto_ecc.c:690
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
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:737
bool GNUNET_TIME_absolute_is_past(struct GNUNET_TIME_Absolute abs)
Test if abs is truly in the past (excluding now).
Definition: time.c:669
static enum GNUNET_GenericReturnValue block_plugin_regex_check_block(void *cls, enum GNUNET_BLOCK_Type type, const void *block, size_t block_size)
Function called to validate a block for storage.
void * libgnunet_plugin_block_regex_init(void *cls)
Entry point for the plugin.
static struct GNUNET_BLOCK_Group * block_plugin_regex_create_group(void *cls, enum GNUNET_BLOCK_Type type, const void *raw_data, size_t raw_data_size, va_list va)
Create a new block group.
static enum GNUNET_BLOCK_ReplyEvaluationResult block_plugin_regex_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.
#define BLOOMFILTER_K
Number of bits we set per entry in the bloomfilter.
static enum GNUNET_GenericReturnValue block_plugin_regex_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.
static enum GNUNET_GenericReturnValue block_plugin_regex_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.
void * libgnunet_plugin_block_regex_done(void *cls)
Exit point from the plugin.
#define REGEX_BF_SIZE
How big is the BF we use for REGEX blocks?
int REGEX_BLOCK_get_key(const struct RegexBlock *block, size_t block_len, struct GNUNET_HashCode *key)
Obtain the key that a particular block is to be stored under.
int REGEX_BLOCK_check(const struct RegexBlock *block, size_t size, const struct GNUNET_HashCode *query, const char *xquery)
Check if the regex block is well formed, including all edges.
common function to manipulate blocks stored by regex in the DHT
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.
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
A 512-bit hashcode.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Time for absolute time used by GNUnet, in microseconds and in network byte order.
Block to announce a peer accepting a state.
Definition: block_regex.h:51
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the signature expire?
Definition: block_regex.h:61
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Accept blocks must be signed.
Definition: block_regex.h:56
struct GNUNET_CRYPTO_EddsaSignature signature
The signature.
Definition: block_regex.h:76
struct GNUNET_PeerIdentity peer
Public key of the peer signing.
Definition: block_regex.h:71
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model