GNUnet  0.11.x
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 
59 static struct GNUNET_BLOCK_Group *
62  uint32_t nonce,
63  const void *raw_data,
64  size_t raw_data_size,
65  va_list va)
66 {
67  unsigned int bf_size;
68  const char *guard;
69 
70  guard = va_arg (va, const char *);
71  if (0 == strcmp (guard,
72  "seen-set-size"))
73  bf_size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va, unsigned
74  int),
76  else if (0 == strcmp (guard,
77  "filter-size"))
78  bf_size = va_arg (va, unsigned int);
79  else
80  {
81  GNUNET_break (0);
82  bf_size = REGEX_BF_SIZE;
83  }
84  GNUNET_break (NULL == va_arg (va, const char *));
85  return GNUNET_BLOCK_GROUP_bf_create (cls,
86  bf_size,
88  type,
89  nonce,
90  raw_data,
91  raw_data_size);
92 }
93 
94 
106 static enum GNUNET_GenericReturnValue
108  enum GNUNET_BLOCK_Type type,
109  const struct GNUNET_HashCode *query,
110  const void *xquery,
111  size_t xquery_size)
112 {
113  switch (type)
114  {
116  if (0 != xquery_size)
117  {
118  const char *s;
119 
120  s = (const char *) xquery;
121  if ('\0' != s[xquery_size - 1]) /* must be valid 0-terminated string */
122  {
123  GNUNET_break_op (0);
124  return GNUNET_NO;
125  }
126  }
127  return GNUNET_OK;
129  if (0 != xquery_size)
130  {
131  GNUNET_break_op (0);
132  return GNUNET_NO;
133  }
134  return GNUNET_OK;
135  default:
136  GNUNET_break (0);
137  return GNUNET_SYSERR;
138  }
139 }
140 
141 
151 static enum GNUNET_GenericReturnValue
153  enum GNUNET_BLOCK_Type type,
154  const void *block,
155  size_t block_size)
156 {
157  switch (type)
158  {
160  if (GNUNET_SYSERR ==
161  REGEX_BLOCK_check (block,
162  block_size,
163  NULL,
164  NULL))
165  return GNUNET_NO;
166  return GNUNET_OK;
168  {
169  const struct RegexAcceptBlock *rba;
170 
171  if (sizeof(struct RegexAcceptBlock) != block_size)
172  {
173  GNUNET_break_op (0);
174  return GNUNET_NO;
175  }
176  rba = block;
177  if (ntohl (rba->purpose.size) !=
178  sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
179  + sizeof(struct GNUNET_TIME_AbsoluteNBO)
180  + sizeof(struct GNUNET_HashCode))
181  {
182  GNUNET_break_op (0);
183  return GNUNET_NO;
184  }
186  rba->expiration_time)))
187  {
188  return GNUNET_NO;
189  }
190  if (GNUNET_OK !=
192  &rba->purpose,
193  &rba->signature,
194  &rba->peer.public_key))
195  {
196  GNUNET_break_op (0);
197  return GNUNET_NO;
198  }
199  return GNUNET_OK;
200  }
201  default:
202  GNUNET_break (0);
203  return GNUNET_SYSERR;
204  }
205 }
206 
207 
226  void *cls,
227  enum GNUNET_BLOCK_Type type,
228  struct GNUNET_BLOCK_Group *group,
229  const struct GNUNET_HashCode *query,
230  const void *xquery,
231  size_t xquery_size,
232  const void *reply_block,
233  size_t reply_block_size)
234 {
235  struct GNUNET_HashCode chash;
236 
237  switch (type)
238  {
240  if (0 != xquery_size)
241  {
242  const char *s;
243 
244  s = (const char *) xquery;
245  GNUNET_assert ('\0' == s[xquery_size - 1]);
246  }
247  switch (REGEX_BLOCK_check (reply_block,
248  reply_block_size,
249  query,
250  xquery))
251  {
252  case GNUNET_SYSERR:
253  GNUNET_assert (0);
254  case GNUNET_NO:
255  /* xquery mismatch, can happen */
257  default:
258  break;
259  }
260  GNUNET_CRYPTO_hash (reply_block,
261  reply_block_size,
262  &chash);
263  if (GNUNET_YES ==
265  &chash))
269  {
270  const struct RegexAcceptBlock *rba;
271 
272  GNUNET_assert (sizeof(struct RegexAcceptBlock) == reply_block_size);
273  rba = reply_block;
274  GNUNET_assert (ntohl (rba->purpose.size) ==
275  sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
276  + sizeof(struct GNUNET_TIME_AbsoluteNBO)
277  + sizeof(struct GNUNET_HashCode));
278  GNUNET_CRYPTO_hash (reply_block,
279  reply_block_size,
280  &chash);
281  if (GNUNET_YES ==
283  &chash))
286  }
287  default:
288  GNUNET_break (0);
290  }
292 }
293 
294 
306 static enum GNUNET_GenericReturnValue
307 block_plugin_regex_get_key (void *cls,
308  enum GNUNET_BLOCK_Type type,
309  const void *block,
310  size_t block_size,
311  struct GNUNET_HashCode *key)
312 {
313  switch (type)
314  {
316  if (GNUNET_OK !=
317  REGEX_BLOCK_get_key (block,
318  block_size,
319  key))
320  {
321  GNUNET_break_op (0);
322  memset (key,
323  0,
324  sizeof (*key));
325  return GNUNET_OK;
326  }
327  return GNUNET_OK;
329  if (sizeof(struct RegexAcceptBlock) != block_size)
330  {
331  GNUNET_break_op (0);
332  memset (key,
333  0,
334  sizeof (*key));
335  return GNUNET_OK;
336  }
337  *key = ((struct RegexAcceptBlock *) block)->key;
338  return GNUNET_OK;
339  default:
340  GNUNET_break (0);
341  return GNUNET_SYSERR;
342  }
343 }
344 
345 
349 void *
351 {
352  static const enum GNUNET_BLOCK_Type types[] = {
355  GNUNET_BLOCK_TYPE_ANY /* end of list */
356  };
357  struct GNUNET_BLOCK_PluginFunctions *api;
358 
365  api->types = types;
366  return api;
367 }
368 
369 
373 void *
375 {
376  struct GNUNET_BLOCK_PluginFunctions *api = cls;
377 
378  GNUNET_free (api);
379  return NULL;
380 }
381 
382 
383 /* end of plugin_block_regex.c */
regex block formats
struct GNUNET_HashCode key
The key used in the DHT.
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
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_ANY
Identifier for any block.
@ GNUNET_BLOCK_TYPE_REGEX
Block to store a cadet regex state.
#define GNUNET_SIGNATURE_PURPOSE_REGEX_ACCEPT
Accept state in regex DFA.
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_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:682
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
#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:736
bool GNUNET_TIME_absolute_is_past(struct GNUNET_TIME_Absolute abs)
Test if abs is truly in the past (excluding now).
Definition: time.c:668
static struct GNUNET_BLOCK_Group * block_plugin_regex_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.
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 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:50
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the signature expire?
Definition: block_regex.h:60
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Accept blocks must be signed.
Definition: block_regex.h:55
struct GNUNET_CRYPTO_EddsaSignature signature
The signature.
Definition: block_regex.h:75
struct GNUNET_PeerIdentity peer
Public key of the peer signing.
Definition: block_regex.h:70
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model