aboutsummaryrefslogtreecommitdiff
path: root/src/regex/regex_block_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/regex/regex_block_lib.c')
-rw-r--r--src/regex/regex_block_lib.c362
1 files changed, 186 insertions, 176 deletions
diff --git a/src/regex/regex_block_lib.c b/src/regex/regex_block_lib.c
index f0feb3628..2c6752e09 100644
--- a/src/regex/regex_block_lib.c
+++ b/src/regex/regex_block_lib.c
@@ -27,14 +27,15 @@
27#include "regex_block_lib.h" 27#include "regex_block_lib.h"
28#include "gnunet_constants.h" 28#include "gnunet_constants.h"
29 29
30#define LOG(kind, ...) GNUNET_log_from(kind, "regex-bck", __VA_ARGS__) 30#define LOG(kind, ...) GNUNET_log_from (kind, "regex-bck", __VA_ARGS__)
31 31
32GNUNET_NETWORK_STRUCT_BEGIN 32GNUNET_NETWORK_STRUCT_BEGIN
33 33
34/** 34/**
35 * Information for each edge. 35 * Information for each edge.
36 */ 36 */
37struct EdgeInfo { 37struct EdgeInfo
38{
38 /** 39 /**
39 * Index of the destination of this edge in the 40 * Index of the destination of this edge in the
40 * unique destinations array. 41 * unique destinations array.
@@ -52,7 +53,8 @@ struct EdgeInfo {
52/** 53/**
53 * @brief Block to announce a regex state. 54 * @brief Block to announce a regex state.
54 */ 55 */
55struct RegexBlock { 56struct RegexBlock
57{
56 /** 58 /**
57 * Length of the proof regex string. 59 * Length of the proof regex string.
58 */ 60 */
@@ -96,15 +98,15 @@ GNUNET_NETWORK_STRUCT_END
96 * @return #GNUNET_YES if the block is accepting, #GNUNET_NO if not 98 * @return #GNUNET_YES if the block is accepting, #GNUNET_NO if not
97 */ 99 */
98int 100int
99GNUNET_BLOCK_is_accepting(const struct RegexBlock *block, 101GNUNET_BLOCK_is_accepting (const struct RegexBlock *block,
100 size_t size) 102 size_t size)
101{ 103{
102 if (size < sizeof(struct RegexBlock)) 104 if (size < sizeof(struct RegexBlock))
103 { 105 {
104 GNUNET_break_op(0); 106 GNUNET_break_op (0);
105 return GNUNET_SYSERR; 107 return GNUNET_SYSERR;
106 } 108 }
107 return ntohs(block->is_accepting); 109 return ntohs (block->is_accepting);
108} 110}
109 111
110 112
@@ -117,27 +119,28 @@ GNUNET_BLOCK_is_accepting(const struct RegexBlock *block,
117 * @return #GNUNET_OK if the proof is valid for the given key. 119 * @return #GNUNET_OK if the proof is valid for the given key.
118 */ 120 */
119int 121int
120REGEX_BLOCK_check_proof(const char *proof, 122REGEX_BLOCK_check_proof (const char *proof,
121 size_t proof_len, 123 size_t proof_len,
122 const struct GNUNET_HashCode *key) 124 const struct GNUNET_HashCode *key)
123{ 125{
124 struct GNUNET_HashCode key_check; 126 struct GNUNET_HashCode key_check;
125 127
126 if ((NULL == proof) || (NULL == key)) 128 if ((NULL == proof) || (NULL == key))
127 { 129 {
128 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Proof check failed, was NULL.\n"); 130 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Proof check failed, was NULL.\n");
129 return GNUNET_NO; 131 return GNUNET_NO;
130 } 132 }
131 GNUNET_CRYPTO_hash(proof, proof_len, &key_check); 133 GNUNET_CRYPTO_hash (proof, proof_len, &key_check);
132 return (0 == 134 return (0 ==
133 GNUNET_CRYPTO_hash_cmp(key, &key_check)) ? GNUNET_OK : GNUNET_NO; 135 GNUNET_CRYPTO_hash_cmp (key, &key_check)) ? GNUNET_OK : GNUNET_NO;
134} 136}
135 137
136 138
137/** 139/**
138 * Struct to keep track of the xquery while iterating all the edges in a block. 140 * Struct to keep track of the xquery while iterating all the edges in a block.
139 */ 141 */
140struct CheckEdgeContext { 142struct CheckEdgeContext
143{
141 /** 144 /**
142 * Xquery: string we are looking for. 145 * Xquery: string we are looking for.
143 */ 146 */
@@ -161,24 +164,24 @@ struct CheckEdgeContext {
161 * @return #GNUNET_YES, to keep iterating 164 * @return #GNUNET_YES, to keep iterating
162 */ 165 */
163static int 166static int
164check_edge(void *cls, 167check_edge (void *cls,
165 const char *token, 168 const char *token,
166 size_t len, 169 size_t len,
167 const struct GNUNET_HashCode *key) 170 const struct GNUNET_HashCode *key)
168{ 171{
169 struct CheckEdgeContext *ctx = cls; 172 struct CheckEdgeContext *ctx = cls;
170 173
171 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
172 "edge %.*s [%u]: %s\n", 175 "edge %.*s [%u]: %s\n",
173 (int)len, 176 (int) len,
174 token, 177 token,
175 (unsigned int)len, 178 (unsigned int) len,
176 GNUNET_h2s(key)); 179 GNUNET_h2s (key));
177 if (NULL == ctx->xquery) 180 if (NULL == ctx->xquery)
178 return GNUNET_YES; 181 return GNUNET_YES;
179 if (strlen(ctx->xquery) < len) 182 if (strlen (ctx->xquery) < len)
180 return GNUNET_YES; /* too long */ 183 return GNUNET_YES; /* too long */
181 if (0 == strncmp(ctx->xquery, token, len)) 184 if (0 == strncmp (ctx->xquery, token, len))
182 ctx->found = GNUNET_OK; 185 ctx->found = GNUNET_OK;
183 return GNUNET_YES; /* keep checking for malformed data! */ 186 return GNUNET_YES; /* keep checking for malformed data! */
184} 187}
@@ -197,48 +200,48 @@ check_edge(void *cls,
197 * #GNUNET_SYSERR if the block is invalid. 200 * #GNUNET_SYSERR if the block is invalid.
198 */ 201 */
199int 202int
200REGEX_BLOCK_check(const struct RegexBlock *block, 203REGEX_BLOCK_check (const struct RegexBlock *block,
201 size_t size, 204 size_t size,
202 const struct GNUNET_HashCode *query, 205 const struct GNUNET_HashCode *query,
203 const char *xquery) 206 const char *xquery)
204{ 207{
205 struct GNUNET_HashCode key; 208 struct GNUNET_HashCode key;
206 struct CheckEdgeContext ctx; 209 struct CheckEdgeContext ctx;
207 int res; 210 int res;
208 211
209 LOG(GNUNET_ERROR_TYPE_DEBUG, 212 LOG (GNUNET_ERROR_TYPE_DEBUG,
210 "Block check\n"); 213 "Block check\n");
211 if (GNUNET_OK != 214 if (GNUNET_OK !=
212 REGEX_BLOCK_get_key(block, size, 215 REGEX_BLOCK_get_key (block, size,
213 &key)) 216 &key))
214 { 217 {
215 GNUNET_break_op(0); 218 GNUNET_break_op (0);
216 return GNUNET_SYSERR; 219 return GNUNET_SYSERR;
217 } 220 }
218 if (NULL != query && 221 if ((NULL != query)&&
219 0 != GNUNET_memcmp(&key, 222 (0 != GNUNET_memcmp (&key,
220 query)) 223 query)) )
221 { 224 {
222 GNUNET_break_op(0); 225 GNUNET_break_op (0);
223 return GNUNET_SYSERR; 226 return GNUNET_SYSERR;
224 } 227 }
225 if ((GNUNET_YES == ntohs(block->is_accepting)) && 228 if ((GNUNET_YES == ntohs (block->is_accepting)) &&
226 ((NULL == xquery) || ('\0' == xquery[0]))) 229 ((NULL == xquery) || ('\0' == xquery[0])))
227 { 230 {
228 LOG(GNUNET_ERROR_TYPE_DEBUG, 231 LOG (GNUNET_ERROR_TYPE_DEBUG,
229 " out! Is accepting: %u, xquery %p\n", 232 " out! Is accepting: %u, xquery %p\n",
230 ntohs(block->is_accepting), 233 ntohs (block->is_accepting),
231 xquery); 234 xquery);
232 return GNUNET_OK; 235 return GNUNET_OK;
233 } 236 }
234 ctx.xquery = xquery; 237 ctx.xquery = xquery;
235 ctx.found = GNUNET_NO; 238 ctx.found = GNUNET_NO;
236 res = REGEX_BLOCK_iterate(block, size, &check_edge, &ctx); 239 res = REGEX_BLOCK_iterate (block, size, &check_edge, &ctx);
237 if (GNUNET_SYSERR == res) 240 if (GNUNET_SYSERR == res)
238 return GNUNET_SYSERR; 241 return GNUNET_SYSERR;
239 if (NULL == xquery) 242 if (NULL == xquery)
240 return GNUNET_YES; 243 return GNUNET_YES;
241 LOG(GNUNET_ERROR_TYPE_DEBUG, "Result %d\n", ctx.found); 244 LOG (GNUNET_ERROR_TYPE_DEBUG, "Result %d\n", ctx.found);
242 return ctx.found; 245 return ctx.found;
243} 246}
244 247
@@ -252,9 +255,9 @@ REGEX_BLOCK_check(const struct RegexBlock *block,
252 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the block is malformed 255 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the block is malformed
253 */ 256 */
254int 257int
255REGEX_BLOCK_get_key(const struct RegexBlock *block, 258REGEX_BLOCK_get_key (const struct RegexBlock *block,
256 size_t block_len, 259 size_t block_len,
257 struct GNUNET_HashCode *key) 260 struct GNUNET_HashCode *key)
258{ 261{
259 uint16_t len; 262 uint16_t len;
260 const struct GNUNET_HashCode *destinations; 263 const struct GNUNET_HashCode *destinations;
@@ -264,22 +267,24 @@ REGEX_BLOCK_get_key(const struct RegexBlock *block,
264 size_t total; 267 size_t total;
265 268
266 if (block_len < sizeof(struct RegexBlock)) 269 if (block_len < sizeof(struct RegexBlock))
267 { 270 {
268 GNUNET_break_op(0); 271 GNUNET_break_op (0);
269 return GNUNET_SYSERR; 272 return GNUNET_SYSERR;
270 } 273 }
271 num_destinations = ntohs(block->num_destinations); 274 num_destinations = ntohs (block->num_destinations);
272 num_edges = ntohs(block->num_edges); 275 num_edges = ntohs (block->num_edges);
273 len = ntohs(block->proof_len); 276 len = ntohs (block->proof_len);
274 destinations = (const struct GNUNET_HashCode *)&block[1]; 277 destinations = (const struct GNUNET_HashCode *) &block[1];
275 edges = (const struct EdgeInfo *)&destinations[num_destinations]; 278 edges = (const struct EdgeInfo *) &destinations[num_destinations];
276 total = sizeof(struct RegexBlock) + num_destinations * sizeof(struct GNUNET_HashCode) + num_edges * sizeof(struct EdgeInfo) + len; 279 total = sizeof(struct RegexBlock) + num_destinations * sizeof(struct
280 GNUNET_HashCode)
281 + num_edges * sizeof(struct EdgeInfo) + len;
277 if (block_len < total) 282 if (block_len < total)
278 { 283 {
279 GNUNET_break_op(0); 284 GNUNET_break_op (0);
280 return GNUNET_SYSERR; 285 return GNUNET_SYSERR;
281 } 286 }
282 GNUNET_CRYPTO_hash(&edges[num_edges], len, key); 287 GNUNET_CRYPTO_hash (&edges[num_edges], len, key);
283 return GNUNET_OK; 288 return GNUNET_OK;
284} 289}
285 290
@@ -300,10 +305,10 @@ REGEX_BLOCK_get_key(const struct RegexBlock *block,
300 * be errors in further edges. 305 * be errors in further edges.
301 */ 306 */
302int 307int
303REGEX_BLOCK_iterate(const struct RegexBlock *block, 308REGEX_BLOCK_iterate (const struct RegexBlock *block,
304 size_t size, 309 size_t size,
305 REGEX_INTERNAL_EgdeIterator iterator, 310 REGEX_INTERNAL_EgdeIterator iterator,
306 void *iter_cls) 311 void *iter_cls)
307{ 312{
308 uint16_t len; 313 uint16_t len;
309 const struct GNUNET_HashCode *destinations; 314 const struct GNUNET_HashCode *destinations;
@@ -315,54 +320,57 @@ REGEX_BLOCK_iterate(const struct RegexBlock *block,
315 unsigned int n; 320 unsigned int n;
316 size_t off; 321 size_t off;
317 322
318 LOG(GNUNET_ERROR_TYPE_DEBUG, "Block iterate\n"); 323 LOG (GNUNET_ERROR_TYPE_DEBUG, "Block iterate\n");
319 if (size < sizeof(struct RegexBlock)) 324 if (size < sizeof(struct RegexBlock))
320 { 325 {
321 GNUNET_break_op(0); 326 GNUNET_break_op (0);
322 return GNUNET_SYSERR; 327 return GNUNET_SYSERR;
323 } 328 }
324 num_destinations = ntohs(block->num_destinations); 329 num_destinations = ntohs (block->num_destinations);
325 num_edges = ntohs(block->num_edges); 330 num_edges = ntohs (block->num_edges);
326 len = ntohs(block->proof_len); 331 len = ntohs (block->proof_len);
327 destinations = (const struct GNUNET_HashCode *)&block[1]; 332 destinations = (const struct GNUNET_HashCode *) &block[1];
328 edges = (const struct EdgeInfo *)&destinations[num_destinations]; 333 edges = (const struct EdgeInfo *) &destinations[num_destinations];
329 aux = (const char *)&edges[num_edges]; 334 aux = (const char *) &edges[num_edges];
330 total = sizeof(struct RegexBlock) + num_destinations * sizeof(struct GNUNET_HashCode) + num_edges * sizeof(struct EdgeInfo) + len; 335 total = sizeof(struct RegexBlock) + num_destinations * sizeof(struct
336 GNUNET_HashCode)
337 + num_edges * sizeof(struct EdgeInfo) + len;
331 if (size < total) 338 if (size < total)
332 { 339 {
333 GNUNET_break_op(0); 340 GNUNET_break_op (0);
334 return GNUNET_SYSERR; 341 return GNUNET_SYSERR;
335 } 342 }
336 for (n = 0; n < num_edges; n++) 343 for (n = 0; n < num_edges; n++)
337 total += ntohs(edges[n].token_length); 344 total += ntohs (edges[n].token_length);
338 if (size != total) 345 if (size != total)
339 { 346 {
340 fprintf(stderr, "Expected %u, got %u\n", 347 fprintf (stderr, "Expected %u, got %u\n",
341 (unsigned int)size, 348 (unsigned int) size,
342 (unsigned int)total); 349 (unsigned int) total);
343 GNUNET_break_op(0); 350 GNUNET_break_op (0);
344 return GNUNET_SYSERR; 351 return GNUNET_SYSERR;
345 } 352 }
346 off = len; 353 off = len;
347 LOG(GNUNET_ERROR_TYPE_DEBUG, 354 LOG (GNUNET_ERROR_TYPE_DEBUG,
348 "Start iterating block of size %u, proof %u, off %u edges %u\n", 355 "Start iterating block of size %u, proof %u, off %u edges %u\n",
349 size, len, off, n); 356 size, len, off, n);
350 /* &aux[off] always points to our token */ 357 /* &aux[off] always points to our token */
351 for (n = 0; n < num_edges; n++) 358 for (n = 0; n < num_edges; n++)
352 { 359 {
353 LOG(GNUNET_ERROR_TYPE_DEBUG, 360 LOG (GNUNET_ERROR_TYPE_DEBUG,
354 "Edge %u/%u, off %u tokenlen %u (%.*s)\n", 361 "Edge %u/%u, off %u tokenlen %u (%.*s)\n",
355 n + 1, num_edges, off, 362 n + 1, num_edges, off,
356 ntohs(edges[n].token_length), ntohs(edges[n].token_length), 363 ntohs (edges[n].token_length), ntohs (edges[n].token_length),
357 &aux[off]); 364 &aux[off]);
358 if (NULL != iterator) 365 if (NULL != iterator)
359 if (GNUNET_NO == iterator(iter_cls, 366 if (GNUNET_NO == iterator (iter_cls,
360 &aux[off], 367 &aux[off],
361 ntohs(edges[n].token_length), 368 ntohs (edges[n].token_length),
362 &destinations[ntohs(edges[n].destination_index)])) 369 &destinations[ntohs (
363 return GNUNET_OK; 370 edges[n].destination_index)]))
364 off += ntohs(edges[n].token_length); 371 return GNUNET_OK;
365 } 372 off += ntohs (edges[n].token_length);
373 }
366 return GNUNET_OK; 374 return GNUNET_OK;
367} 375}
368 376
@@ -378,11 +386,11 @@ REGEX_BLOCK_iterate(const struct RegexBlock *block,
378 * @return the regex block, NULL on error 386 * @return the regex block, NULL on error
379 */ 387 */
380struct RegexBlock * 388struct RegexBlock *
381REGEX_BLOCK_create(const char *proof, 389REGEX_BLOCK_create (const char *proof,
382 unsigned int num_edges, 390 unsigned int num_edges,
383 const struct REGEX_BLOCK_Edge *edges, 391 const struct REGEX_BLOCK_Edge *edges,
384 int accepting, 392 int accepting,
385 size_t *rsize) 393 size_t *rsize)
386{ 394{
387 struct RegexBlock *block; 395 struct RegexBlock *block;
388 struct GNUNET_HashCode destinations[1024]; /* 1024 = 64k/64 bytes/key == absolute MAX */ 396 struct GNUNET_HashCode destinations[1024]; /* 1024 = 64k/64 bytes/key == absolute MAX */
@@ -398,64 +406,66 @@ REGEX_BLOCK_create(const char *proof,
398 unsigned int i; 406 unsigned int i;
399 char *aux; 407 char *aux;
400 408
401 len = strlen(proof); 409 len = strlen (proof);
402 if (len > UINT16_MAX) 410 if (len > UINT16_MAX)
403 { 411 {
404 GNUNET_break(0); 412 GNUNET_break (0);
405 return NULL; 413 return NULL;
406 } 414 }
407 unique_destinations = 0; 415 unique_destinations = 0;
408 total = sizeof(struct RegexBlock) + len; 416 total = sizeof(struct RegexBlock) + len;
409 for (i = 0; i < num_edges; i++) 417 for (i = 0; i < num_edges; i++)
418 {
419 slen = strlen (edges[i].label);
420 if (slen > UINT16_MAX)
410 { 421 {
411 slen = strlen(edges[i].label); 422 GNUNET_break (0);
412 if (slen > UINT16_MAX) 423 return NULL;
413 {
414 GNUNET_break(0);
415 return NULL;
416 }
417 total += slen;
418 for (j = 0; j < unique_destinations; j++)
419 if (0 == memcmp(&destinations[j],
420 &edges[i].destination,
421 sizeof(struct GNUNET_HashCode)))
422 break;
423 if (j >= 1024)
424 {
425 GNUNET_break(0);
426 return NULL;
427 }
428 destination_indices[i] = j;
429 if (j == unique_destinations)
430 destinations[unique_destinations++] = edges[i].destination;
431 } 424 }
432 total += num_edges * sizeof(struct EdgeInfo) + unique_destinations * sizeof(struct GNUNET_HashCode); 425 total += slen;
433 if (total >= GNUNET_CONSTANTS_MAX_BLOCK_SIZE) 426 for (j = 0; j < unique_destinations; j++)
427 if (0 == memcmp (&destinations[j],
428 &edges[i].destination,
429 sizeof(struct GNUNET_HashCode)))
430 break;
431 if (j >= 1024)
434 { 432 {
435 GNUNET_break(0); 433 GNUNET_break (0);
436 return NULL; 434 return NULL;
437 } 435 }
438 block = GNUNET_malloc(total); 436 destination_indices[i] = j;
439 block->proof_len = htons(len); 437 if (j == unique_destinations)
440 block->is_accepting = htons(accepting); 438 destinations[unique_destinations++] = edges[i].destination;
441 block->num_edges = htons(num_edges); 439 }
442 block->num_destinations = htons(unique_destinations); 440 total += num_edges * sizeof(struct EdgeInfo) + unique_destinations
443 dests = (struct GNUNET_HashCode *)&block[1]; 441 * sizeof(struct GNUNET_HashCode);
444 GNUNET_memcpy(dests, destinations, sizeof(struct GNUNET_HashCode) * unique_destinations); 442 if (total >= GNUNET_CONSTANTS_MAX_BLOCK_SIZE)
445 edgeinfos = (struct EdgeInfo *)&dests[unique_destinations]; 443 {
446 aux = (char *)&edgeinfos[num_edges]; 444 GNUNET_break (0);
445 return NULL;
446 }
447 block = GNUNET_malloc (total);
448 block->proof_len = htons (len);
449 block->is_accepting = htons (accepting);
450 block->num_edges = htons (num_edges);
451 block->num_destinations = htons (unique_destinations);
452 dests = (struct GNUNET_HashCode *) &block[1];
453 GNUNET_memcpy (dests, destinations, sizeof(struct GNUNET_HashCode)
454 * unique_destinations);
455 edgeinfos = (struct EdgeInfo *) &dests[unique_destinations];
456 aux = (char *) &edgeinfos[num_edges];
447 off = len; 457 off = len;
448 GNUNET_memcpy(aux, proof, len); 458 GNUNET_memcpy (aux, proof, len);
449 for (i = 0; i < num_edges; i++) 459 for (i = 0; i < num_edges; i++)
450 { 460 {
451 slen = strlen(edges[i].label); 461 slen = strlen (edges[i].label);
452 edgeinfos[i].token_length = htons((uint16_t)slen); 462 edgeinfos[i].token_length = htons ((uint16_t) slen);
453 edgeinfos[i].destination_index = htons(destination_indices[i]); 463 edgeinfos[i].destination_index = htons (destination_indices[i]);
454 GNUNET_memcpy(&aux[off], 464 GNUNET_memcpy (&aux[off],
455 edges[i].label, 465 edges[i].label,
456 slen); 466 slen);
457 off += slen; 467 off += slen;
458 } 468 }
459 *rsize = total; 469 *rsize = total;
460 return block; 470 return block;
461} 471}