GNUnet 0.21.1
regex_block_lib.c File Reference

functions for manipulating non-accept blocks stored for regex in the DHT More...

#include "platform.h"
#include "regex_block_lib.h"
#include "gnunet_constants.h"
Include dependency graph for regex_block_lib.c:

Go to the source code of this file.

Data Structures

struct  EdgeInfo
 Information for each edge. More...
 
struct  RegexBlock
 Block to announce a regex state. More...
 
struct  CheckEdgeContext
 Struct to keep track of the xquery while iterating all the edges in a block. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "regex-bck", __VA_ARGS__)
 

Functions

GNUNET_NETWORK_STRUCT_END int GNUNET_BLOCK_is_accepting (const struct RegexBlock *block, size_t size)
 Test if this block is marked as being an accept state. More...
 
int REGEX_BLOCK_check_proof (const char *proof, size_t proof_len, const struct GNUNET_HashCode *key)
 Check if the given 'proof' matches the given 'key'. More...
 
static int check_edge (void *cls, const char *token, size_t len, const struct GNUNET_HashCode *key)
 Iterator over all edges in a block, checking for a presence of a given query. More...
 
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. More...
 
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. More...
 
int REGEX_BLOCK_iterate (const struct RegexBlock *block, size_t size, REGEX_INTERNAL_EgdeIterator iterator, void *iter_cls)
 Iterate over all edges of a block of a regex state. More...
 
struct RegexBlockREGEX_BLOCK_create (const char *proof, unsigned int num_edges, const struct REGEX_BLOCK_Edge *edges, int accepting, size_t *rsize)
 Construct a regex block to be stored in the DHT. More...
 

Detailed Description

functions for manipulating non-accept blocks stored for regex in the DHT

Author
Bartlomiej Polot

Definition in file regex_block_lib.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "regex-bck", __VA_ARGS__)

Definition at line 30 of file regex_block_lib.c.

Function Documentation

◆ GNUNET_BLOCK_is_accepting()

GNUNET_NETWORK_STRUCT_END int GNUNET_BLOCK_is_accepting ( const struct RegexBlock block,
size_t  size 
)

Test if this block is marked as being an accept state.

Parameters
blockblock to test
sizenumber of bytes in block
Returns
GNUNET_YES if the block is accepting, GNUNET_NO if not

Definition at line 101 of file regex_block_lib.c.

103{
104 if (size < sizeof(struct RegexBlock))
105 {
106 GNUNET_break_op (0);
107 return GNUNET_SYSERR;
108 }
109 return ntohs (block->is_accepting);
110}
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
static unsigned int size
Size of the "table".
Definition: peer.c:68
Block to announce a regex state.
int16_t is_accepting
Is this state an accepting state?

References GNUNET_break_op, GNUNET_SYSERR, RegexBlock::is_accepting, and size.

Referenced by dht_get_string_handler(), and regex_result_iterator().

Here is the caller graph for this function:

◆ REGEX_BLOCK_check_proof()

int REGEX_BLOCK_check_proof ( const char *  proof,
size_t  proof_len,
const struct GNUNET_HashCode key 
)

Check if the given 'proof' matches the given 'key'.

Parameters
proofpartial regex of a state
proof_lennumber of bytes in proof
keyhash of a state.
Returns
GNUNET_OK if the proof is valid for the given key.

Definition at line 114 of file regex_block_lib.c.

117{
118 struct GNUNET_HashCode key_check;
119
120 if ((NULL == proof) || (NULL == key))
121 {
122 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Proof check failed, was NULL.\n");
123 return GNUNET_NO;
124 }
125 GNUNET_CRYPTO_hash (proof, proof_len, &key_check);
126 return (0 ==
128}
struct GNUNET_HashCode key
The key used in the DHT.
static uint64_t proof
Definition: gnunet-scrypt.c:49
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_CRYPTO_hash_cmp(const struct GNUNET_HashCode *h1, const struct GNUNET_HashCode *h2)
Compare function for HashCodes, producing a total ordering of all hashcodes.
Definition: crypto_hash.c:221
#define GNUNET_log(kind,...)
@ GNUNET_OK
@ GNUNET_NO
@ GNUNET_ERROR_TYPE_ERROR
A 512-bit hashcode.

References GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_hash_cmp(), GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_NO, GNUNET_OK, key, and proof.

Here is the call graph for this function:

◆ check_edge()

static int check_edge ( void *  cls,
const char *  token,
size_t  len,
const struct GNUNET_HashCode key 
)
static

Iterator over all edges in a block, checking for a presence of a given query.

Parameters
clsClosure, (xquery context).
tokenToken that follows to next state.
lenLength of token.
keyHash of next state.
Returns
GNUNET_YES, to keep iterating

Definition at line 159 of file regex_block_lib.c.

163{
164 struct CheckEdgeContext *ctx = cls;
165
167 "edge %.*s [%u]: %s\n",
168 (int) len,
169 token,
170 (unsigned int) len,
171 GNUNET_h2s (key));
172 if (NULL == ctx->xquery)
173 return GNUNET_YES;
174 if (strlen (ctx->xquery) < len)
175 return GNUNET_YES; /* too long */
176 if (0 == strncmp (ctx->xquery, token, len))
177 ctx->found = GNUNET_OK;
178 return GNUNET_YES; /* keep checking for malformed data! */
179}
static struct GNUNET_FS_Handle * ctx
@ GNUNET_YES
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_DEBUG
Struct to keep track of the xquery while iterating all the edges in a block.

References ctx, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_OK, GNUNET_YES, and key.

Referenced by REGEX_BLOCK_check().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ REGEX_BLOCK_check()

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.

Parameters
blockThe start of the block.
sizeThe size of the block.
querythe query for the block
xqueryString describing the edge we are looking for. Can be NULL in case this is a put block.
Returns
GNUNET_OK in case it's fine. GNUNET_NO in case the xquery exists and is not found (IRRELEVANT). GNUNET_SYSERR if the block is invalid.

Definition at line 183 of file regex_block_lib.c.

187{
188 struct GNUNET_HashCode key;
189 struct CheckEdgeContext ctx;
190 int res;
191
193 "Block check\n");
194 if (GNUNET_OK !=
196 &key))
197 {
198 GNUNET_break_op (0);
199 return GNUNET_SYSERR;
200 }
201 if ((NULL != query) &&
202 (0 != GNUNET_memcmp (&key,
203 query)) )
204 {
205 GNUNET_break_op (0);
206 return GNUNET_SYSERR;
207 }
208 if ((GNUNET_YES == ntohs (block->is_accepting)) &&
209 ((NULL == xquery) || ('\0' == xquery[0])))
210 {
212 " out! Is accepting: %u, xquery %p\n",
213 ntohs (block->is_accepting),
214 xquery);
215 return GNUNET_OK;
216 }
217 ctx.xquery = xquery;
218 ctx.found = GNUNET_NO;
220 if (GNUNET_SYSERR == res)
221 return GNUNET_SYSERR;
222 if (NULL == xquery)
223 return GNUNET_YES;
224 LOG (GNUNET_ERROR_TYPE_DEBUG, "Result %d\n", ctx.found);
225 return ctx.found;
226}
static char * res
Currently read line or NULL on EOF.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
static int check_edge(void *cls, const char *token, size_t len, const struct GNUNET_HashCode *key)
Iterator over all edges in a block, checking for a presence of a given query.
int REGEX_BLOCK_iterate(const struct RegexBlock *block, size_t size, REGEX_INTERNAL_EgdeIterator iterator, void *iter_cls)
Iterate over all edges of a block of a regex state.
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.
#define LOG(kind,...)
const char * xquery
Xquery: string we are looking for.

References check_edge(), ctx, GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_memcmp, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, RegexBlock::is_accepting, key, LOG, REGEX_BLOCK_get_key(), REGEX_BLOCK_iterate(), res, size, and CheckEdgeContext::xquery.

Referenced by block_plugin_regex_check_block(), and block_plugin_regex_check_reply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ REGEX_BLOCK_get_key()

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.

Parameters
blockblock to get the key from
block_lennumber of bytes in block
keywhere to store the key
Returns
GNUNET_OK on success, GNUNET_SYSERR if the block is malformed

Definition at line 230 of file regex_block_lib.c.

233{
234 uint16_t len;
235 const struct GNUNET_HashCode *destinations;
236 const struct EdgeInfo *edges;
237 uint16_t num_destinations;
238 uint16_t num_edges;
239 size_t total;
240
241 if (block_len < sizeof(struct RegexBlock))
242 {
243 GNUNET_break_op (0);
244 return GNUNET_SYSERR;
245 }
246 num_destinations = ntohs (block->num_destinations);
247 num_edges = ntohs (block->num_edges);
248 len = ntohs (block->proof_len);
249 destinations = (const struct GNUNET_HashCode *) &block[1];
250 edges = (const struct EdgeInfo *) &destinations[num_destinations];
251 total = sizeof(struct RegexBlock) + num_destinations * sizeof(struct
253 + num_edges * sizeof(struct EdgeInfo) + len;
254 if (block_len < total)
255 {
256 GNUNET_break_op (0);
257 return GNUNET_SYSERR;
258 }
259 GNUNET_CRYPTO_hash (&edges[num_edges], len, key);
260 return GNUNET_OK;
261}
Information for each edge.
uint16_t num_destinations
Number of unique destinations reachable from this state.
uint16_t proof_len
Length of the proof regex string.
uint16_t num_edges
Number of edges parting from this state.

References GNUNET_break_op, GNUNET_CRYPTO_hash(), GNUNET_OK, GNUNET_SYSERR, key, RegexBlock::num_destinations, RegexBlock::num_edges, and RegexBlock::proof_len.

Referenced by block_plugin_regex_get_key(), and REGEX_BLOCK_check().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ REGEX_BLOCK_iterate()

int REGEX_BLOCK_iterate ( const struct RegexBlock block,
size_t  size,
REGEX_INTERNAL_EgdeIterator  iterator,
void *  iter_cls 
)

Iterate over all edges of a block of a regex state.

Parameters
blockBlock to iterate over.
sizeSize of block.
iteratorFunction to call on each edge in the block.
iter_clsClosure for the iterator.
Returns
GNUNET_SYSERR if an error has been encountered. GNUNET_OK if no error has been encountered. Note that if the iterator stops the iteration by returning GNUNET_NO, the block will no longer be checked for further errors. The return value will be GNUNET_OK meaning that no errors were found until the edge last notified to the iterator, but there might be errors in further edges.

Definition at line 265 of file regex_block_lib.c.

269{
270 uint16_t len;
271 const struct GNUNET_HashCode *destinations;
272 const struct EdgeInfo *edges;
273 const char *aux;
274 uint16_t num_destinations;
275 uint16_t num_edges;
276 size_t total;
277 unsigned int n;
278 size_t off;
279
280 LOG (GNUNET_ERROR_TYPE_DEBUG, "Block iterate\n");
281 if (size < sizeof(struct RegexBlock))
282 {
283 GNUNET_break_op (0);
284 return GNUNET_SYSERR;
285 }
286 num_destinations = ntohs (block->num_destinations);
287 num_edges = ntohs (block->num_edges);
288 len = ntohs (block->proof_len);
289 destinations = (const struct GNUNET_HashCode *) &block[1];
290 edges = (const struct EdgeInfo *) &destinations[num_destinations];
291 aux = (const char *) &edges[num_edges];
292 total = sizeof(struct RegexBlock) + num_destinations * sizeof(struct
294 + num_edges * sizeof(struct EdgeInfo) + len;
295 if (size < total)
296 {
297 GNUNET_break_op (0);
298 return GNUNET_SYSERR;
299 }
300 for (n = 0; n < num_edges; n++)
301 total += ntohs (edges[n].token_length);
302 if (size != total)
303 {
304 fprintf (stderr, "Expected %u, got %u\n",
305 (unsigned int) size,
306 (unsigned int) total);
307 GNUNET_break_op (0);
308 return GNUNET_SYSERR;
309 }
310 off = len;
312 "Start iterating block of size %lu, proof %u, off %lu edges %u\n",
313 (unsigned long) size, len, (unsigned long) off, n);
314 /* &aux[off] always points to our token */
315 for (n = 0; n < num_edges; n++)
316 {
318 "Edge %u/%u, off %lu tokenlen %u (%.*s)\n",
319 n + 1, num_edges, (unsigned long) off,
320 ntohs (edges[n].token_length), ntohs (edges[n].token_length),
321 &aux[off]);
322 if (NULL != iterator)
323 if (GNUNET_NO == iterator (iter_cls,
324 &aux[off],
325 ntohs (edges[n].token_length),
326 &destinations[ntohs (
327 edges[n].destination_index)]))
328 return GNUNET_OK;
329 off += ntohs (edges[n].token_length);
330 }
331 return GNUNET_OK;
332}

References GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, LOG, RegexBlock::num_destinations, RegexBlock::num_edges, RegexBlock::proof_len, and size.

Referenced by REGEX_BLOCK_check(), and regex_next_edge().

Here is the caller graph for this function:

◆ REGEX_BLOCK_create()

struct RegexBlock * REGEX_BLOCK_create ( const char *  proof,
unsigned int  num_edges,
const struct REGEX_BLOCK_Edge edges,
int  accepting,
size_t *  rsize 
)

Construct a regex block to be stored in the DHT.

Parameters
proofproof string for the block
num_edgesnumber of edges in the block
edgesthe edges of the block
acceptingis this an accepting state
rsizeset to the size of the returned block (OUT-only)
Returns
the regex block, NULL on error

Definition at line 346 of file regex_block_lib.c.

351{
352 struct RegexBlock *block;
353 struct GNUNET_HashCode destinations[1024]; /* 1024 = 64k/64 bytes/key == absolute MAX */
354 uint16_t destination_indices[num_edges];
355 struct GNUNET_HashCode *dests;
356 struct EdgeInfo *edgeinfos;
357 size_t off;
358 size_t len;
359 size_t total;
360 size_t slen;
361 unsigned int unique_destinations;
362 unsigned int j;
363 unsigned int i;
364 char *aux;
365
366 len = strlen (proof);
367 if (len > UINT16_MAX)
368 {
369 GNUNET_break (0);
370 return NULL;
371 }
372 unique_destinations = 0;
373 total = sizeof(struct RegexBlock) + len;
374 for (i = 0; i < num_edges; i++)
375 {
376 slen = strlen (edges[i].label);
377 if (slen > UINT16_MAX)
378 {
379 GNUNET_break (0);
380 return NULL;
381 }
382 total += slen;
383 for (j = 0; j < unique_destinations; j++)
384 if (0 == memcmp (&destinations[j],
385 &edges[i].destination,
386 sizeof(struct GNUNET_HashCode)))
387 break;
388 if (j >= 1024)
389 {
390 GNUNET_break (0);
391 return NULL;
392 }
393 destination_indices[i] = j;
394 if (j == unique_destinations)
395 destinations[unique_destinations++] = edges[i].destination;
396 }
397 total += num_edges * sizeof(struct EdgeInfo) + unique_destinations
398 * sizeof(struct GNUNET_HashCode);
400 {
401 GNUNET_break (0);
402 return NULL;
403 }
404 block = GNUNET_malloc (total);
405 block->proof_len = htons (len);
406 block->is_accepting = htons (accepting);
407 block->num_edges = htons (num_edges);
408 block->num_destinations = htons (unique_destinations);
409 dests = (struct GNUNET_HashCode *) &block[1];
410 GNUNET_memcpy (dests, destinations, sizeof(struct GNUNET_HashCode)
411 * unique_destinations);
412 edgeinfos = (struct EdgeInfo *) &dests[unique_destinations];
413 aux = (char *) &edgeinfos[num_edges];
414 off = len;
415 GNUNET_memcpy (aux, proof, len);
416 for (i = 0; i < num_edges; i++)
417 {
418 slen = strlen (edges[i].label);
419 edgeinfos[i].token_length = htons ((uint16_t) slen);
420 edgeinfos[i].destination_index = htons (destination_indices[i]);
421 GNUNET_memcpy (&aux[off],
422 edges[i].label,
423 slen);
424 off += slen;
425 }
426 *rsize = total;
427 return block;
428}
#define GNUNET_CONSTANTS_MAX_BLOCK_SIZE
Largest block that can be stored in the DHT.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#define GNUNET_malloc(size)
Wrapper around malloc.
uint16_t destination_index
Index of the destination of this edge in the unique destinations array.
uint16_t token_length
Number of bytes the token for this edge takes in the token area.
struct GNUNET_HashCode destination
Destination of the edge.

References REGEX_BLOCK_Edge::destination, EdgeInfo::destination_index, GNUNET_break, GNUNET_CONSTANTS_MAX_BLOCK_SIZE, GNUNET_malloc, GNUNET_memcpy, RegexBlock::is_accepting, RegexBlock::num_destinations, RegexBlock::num_edges, proof, RegexBlock::proof_len, and EdgeInfo::token_length.

Referenced by regex_iterator().

Here is the caller graph for this function: