diff options
Diffstat (limited to 'src/regex/plugin_block_regex.c')
-rw-r--r-- | src/regex/plugin_block_regex.c | 287 |
1 files changed, 20 insertions, 267 deletions
diff --git a/src/regex/plugin_block_regex.c b/src/regex/plugin_block_regex.c index 0953830ab..61442ac10 100644 --- a/src/regex/plugin_block_regex.c +++ b/src/regex/plugin_block_regex.c | |||
@@ -93,242 +93,6 @@ block_plugin_regex_create_group (void *cls, | |||
93 | 93 | ||
94 | 94 | ||
95 | /** | 95 | /** |
96 | * Function called to validate a reply or a request of type | ||
97 | * #GNUNET_BLOCK_TYPE_REGEX. | ||
98 | * For request evaluation, pass "NULL" for the reply_block. | ||
99 | * Note that it is assumed that the reply has already been | ||
100 | * matched to the key (and signatures checked) as it would | ||
101 | * be done with the #GNUNET_BLOCK_get_key() function. | ||
102 | * | ||
103 | * @param cls closure | ||
104 | * @param type block type | ||
105 | * @param bg block group to evaluate against | ||
106 | * @param eo control flags | ||
107 | * @param query original query (hash) | ||
108 | * @param xquery extrended query data (can be NULL, depending on type) | ||
109 | * @param xquery_size number of bytes in @a xquery | ||
110 | * @param reply_block response to validate | ||
111 | * @param reply_block_size number of bytes in @a reply_block | ||
112 | * @return characterization of result | ||
113 | */ | ||
114 | static enum GNUNET_BLOCK_EvaluationResult | ||
115 | evaluate_block_regex (void *cls, | ||
116 | enum GNUNET_BLOCK_Type type, | ||
117 | struct GNUNET_BLOCK_Group *bg, | ||
118 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
119 | const struct GNUNET_HashCode *query, | ||
120 | const void *xquery, | ||
121 | size_t xquery_size, | ||
122 | const void *reply_block, | ||
123 | size_t reply_block_size) | ||
124 | { | ||
125 | struct GNUNET_HashCode chash; | ||
126 | |||
127 | if (NULL == reply_block) | ||
128 | { | ||
129 | if (0 != xquery_size) | ||
130 | { | ||
131 | const char *s; | ||
132 | |||
133 | s = (const char *) xquery; | ||
134 | if ('\0' != s[xquery_size - 1]) /* must be valid 0-terminated string */ | ||
135 | { | ||
136 | GNUNET_break_op (0); | ||
137 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | ||
138 | } | ||
139 | } | ||
140 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
141 | } | ||
142 | if (0 != xquery_size) | ||
143 | { | ||
144 | const char *s; | ||
145 | |||
146 | s = (const char *) xquery; | ||
147 | if ('\0' != s[xquery_size - 1]) /* must be valid 0-terminated string */ | ||
148 | { | ||
149 | GNUNET_break_op (0); | ||
150 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | ||
151 | } | ||
152 | } | ||
153 | else if (NULL != query) | ||
154 | { | ||
155 | /* xquery is required for regex GETs, at least an empty string */ | ||
156 | GNUNET_break_op (0); | ||
157 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "type %d, query %p, xquery %p\n", | ||
158 | type, query, xquery); | ||
159 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | ||
160 | } | ||
161 | switch (REGEX_BLOCK_check (reply_block, | ||
162 | reply_block_size, | ||
163 | query, | ||
164 | xquery)) | ||
165 | { | ||
166 | case GNUNET_SYSERR: | ||
167 | GNUNET_break_op (0); | ||
168 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
169 | |||
170 | case GNUNET_NO: | ||
171 | /* xquery mismatch, can happen */ | ||
172 | return GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT; | ||
173 | |||
174 | default: | ||
175 | break; | ||
176 | } | ||
177 | GNUNET_CRYPTO_hash (reply_block, | ||
178 | reply_block_size, | ||
179 | &chash); | ||
180 | if (GNUNET_YES == | ||
181 | GNUNET_BLOCK_GROUP_bf_test_and_set (bg, | ||
182 | &chash)) | ||
183 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
184 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
185 | } | ||
186 | |||
187 | |||
188 | /** | ||
189 | * Function called to validate a reply or a request of type | ||
190 | * #GNUNET_BLOCK_TYPE_REGEX_ACCEPT. | ||
191 | * For request evaluation, pass "NULL" for the reply_block. | ||
192 | * Note that it is assumed that the reply has already been | ||
193 | * matched to the key (and signatures checked) as it would | ||
194 | * be done with the #GNUNET_BLOCK_get_key() function. | ||
195 | * | ||
196 | * @param cls closure | ||
197 | * @param type block type | ||
198 | * @param bg block group to evaluate against | ||
199 | * @param eo control flags | ||
200 | * @param query original query (hash) | ||
201 | * @param xquery extrended query data (can be NULL, depending on type) | ||
202 | * @param xquery_size number of bytes in @a xquery | ||
203 | * @param reply_block response to validate | ||
204 | * @param reply_block_size number of bytes in @a reply_block | ||
205 | * @return characterization of result | ||
206 | */ | ||
207 | static enum GNUNET_BLOCK_EvaluationResult | ||
208 | evaluate_block_regex_accept (void *cls, | ||
209 | enum GNUNET_BLOCK_Type type, | ||
210 | struct GNUNET_BLOCK_Group *bg, | ||
211 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
212 | const struct GNUNET_HashCode *query, | ||
213 | const void *xquery, | ||
214 | size_t xquery_size, const void *reply_block, | ||
215 | size_t reply_block_size) | ||
216 | { | ||
217 | const struct RegexAcceptBlock *rba; | ||
218 | struct GNUNET_HashCode chash; | ||
219 | |||
220 | if (0 != xquery_size) | ||
221 | { | ||
222 | GNUNET_break_op (0); | ||
223 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | ||
224 | } | ||
225 | if (NULL == reply_block) | ||
226 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
227 | if (sizeof(struct RegexAcceptBlock) != reply_block_size) | ||
228 | { | ||
229 | GNUNET_break_op (0); | ||
230 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
231 | } | ||
232 | rba = reply_block; | ||
233 | if (ntohl (rba->purpose.size) != | ||
234 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | ||
235 | + sizeof(struct GNUNET_TIME_AbsoluteNBO) | ||
236 | + sizeof(struct GNUNET_HashCode)) | ||
237 | { | ||
238 | GNUNET_break_op (0); | ||
239 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
240 | } | ||
241 | if (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh ( | ||
242 | rba->expiration_time)). | ||
243 | rel_value_us) | ||
244 | { | ||
245 | /* technically invalid, but can happen without an error, so | ||
246 | we're nice by reporting it as a 'duplicate' */ | ||
247 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
248 | } | ||
249 | if (GNUNET_OK != | ||
250 | GNUNET_CRYPTO_eddsa_verify_ (GNUNET_SIGNATURE_PURPOSE_REGEX_ACCEPT, | ||
251 | &rba->purpose, | ||
252 | &rba->signature, | ||
253 | &rba->peer.public_key)) | ||
254 | { | ||
255 | GNUNET_break_op (0); | ||
256 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
257 | } | ||
258 | GNUNET_CRYPTO_hash (reply_block, | ||
259 | reply_block_size, | ||
260 | &chash); | ||
261 | if (GNUNET_YES == | ||
262 | GNUNET_BLOCK_GROUP_bf_test_and_set (bg, | ||
263 | &chash)) | ||
264 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
265 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
266 | } | ||
267 | |||
268 | |||
269 | /** | ||
270 | * Function called to validate a reply or a request. For | ||
271 | * request evaluation, simply pass "NULL" for the reply_block. | ||
272 | * Note that it is assumed that the reply has already been | ||
273 | * matched to the key (and signatures checked) as it would | ||
274 | * be done with the #GNUNET_BLOCK_get_key() function. | ||
275 | * | ||
276 | * @param cls closure | ||
277 | * @param ctx block context | ||
278 | * @param type block type | ||
279 | * @param bg group to evaluate against | ||
280 | * @param eo control flags | ||
281 | * @param query original query (hash) | ||
282 | * @param xquery extrended query data (can be NULL, depending on type) | ||
283 | * @param xquery_size number of bytes in xquery | ||
284 | * @param reply_block response to validate | ||
285 | * @param reply_block_size number of bytes in reply block | ||
286 | * @return characterization of result | ||
287 | */ | ||
288 | static enum GNUNET_BLOCK_EvaluationResult | ||
289 | block_plugin_regex_evaluate (void *cls, | ||
290 | struct GNUNET_BLOCK_Context *ctx, | ||
291 | enum GNUNET_BLOCK_Type type, | ||
292 | struct GNUNET_BLOCK_Group *bg, | ||
293 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
294 | const struct GNUNET_HashCode *query, | ||
295 | const void *xquery, | ||
296 | size_t xquery_size, | ||
297 | const void *reply_block, | ||
298 | size_t reply_block_size) | ||
299 | { | ||
300 | enum GNUNET_BLOCK_EvaluationResult result; | ||
301 | |||
302 | switch (type) | ||
303 | { | ||
304 | case GNUNET_BLOCK_TYPE_REGEX: | ||
305 | result = evaluate_block_regex (cls, | ||
306 | type, | ||
307 | bg, | ||
308 | eo, | ||
309 | query, | ||
310 | xquery, xquery_size, | ||
311 | reply_block, reply_block_size); | ||
312 | break; | ||
313 | |||
314 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: | ||
315 | result = evaluate_block_regex_accept (cls, | ||
316 | type, | ||
317 | bg, | ||
318 | eo, | ||
319 | query, | ||
320 | xquery, xquery_size, | ||
321 | reply_block, reply_block_size); | ||
322 | break; | ||
323 | |||
324 | default: | ||
325 | result = GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | ||
326 | } | ||
327 | return result; | ||
328 | } | ||
329 | |||
330 | |||
331 | /** | ||
332 | * Function called to validate a query. | 96 | * Function called to validate a query. |
333 | * | 97 | * |
334 | * @param cls closure | 98 | * @param cls closure |
@@ -341,10 +105,10 @@ block_plugin_regex_evaluate (void *cls, | |||
341 | */ | 105 | */ |
342 | static enum GNUNET_GenericReturnValue | 106 | static enum GNUNET_GenericReturnValue |
343 | block_plugin_regex_check_query (void *cls, | 107 | block_plugin_regex_check_query (void *cls, |
344 | enum GNUNET_BLOCK_Type type, | 108 | enum GNUNET_BLOCK_Type type, |
345 | const struct GNUNET_HashCode *query, | 109 | const struct GNUNET_HashCode *query, |
346 | const void *xquery, | 110 | const void *xquery, |
347 | size_t xquery_size) | 111 | size_t xquery_size) |
348 | { | 112 | { |
349 | switch (type) | 113 | switch (type) |
350 | { | 114 | { |
@@ -380,7 +144,6 @@ block_plugin_regex_check_query (void *cls, | |||
380 | * | 144 | * |
381 | * @param cls closure | 145 | * @param cls closure |
382 | * @param type block type | 146 | * @param type block type |
383 | * @param query key for the block (hash), must match exactly | ||
384 | * @param block block data to validate | 147 | * @param block block data to validate |
385 | * @param block_size number of bytes in @a block | 148 | * @param block_size number of bytes in @a block |
386 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | 149 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not |
@@ -388,7 +151,6 @@ block_plugin_regex_check_query (void *cls, | |||
388 | static enum GNUNET_GenericReturnValue | 151 | static enum GNUNET_GenericReturnValue |
389 | block_plugin_regex_check_block (void *cls, | 152 | block_plugin_regex_check_block (void *cls, |
390 | enum GNUNET_BLOCK_Type type, | 153 | enum GNUNET_BLOCK_Type type, |
391 | const struct GNUNET_HashCode *query, | ||
392 | const void *block, | 154 | const void *block, |
393 | size_t block_size) | 155 | size_t block_size) |
394 | { | 156 | { |
@@ -398,7 +160,7 @@ block_plugin_regex_check_block (void *cls, | |||
398 | if (GNUNET_SYSERR == | 160 | if (GNUNET_SYSERR == |
399 | REGEX_BLOCK_check (block, | 161 | REGEX_BLOCK_check (block, |
400 | block_size, | 162 | block_size, |
401 | query, | 163 | NULL, |
402 | NULL)) | 164 | NULL)) |
403 | return GNUNET_NO; | 165 | return GNUNET_NO; |
404 | return GNUNET_OK; | 166 | return GNUNET_OK; |
@@ -480,12 +242,7 @@ block_plugin_regex_check_reply ( | |||
480 | const char *s; | 242 | const char *s; |
481 | 243 | ||
482 | s = (const char *) xquery; | 244 | s = (const char *) xquery; |
483 | if ('\0' != s[xquery_size - 1]) /* must be valid 0-terminated string */ | 245 | GNUNET_assert ('\0' == s[xquery_size - 1]); |
484 | { | ||
485 | /* Technically, the query is invalid ... */ | ||
486 | GNUNET_break (0); | ||
487 | return GNUNET_BLOCK_REPLY_INVALID; | ||
488 | } | ||
489 | } | 246 | } |
490 | switch (REGEX_BLOCK_check (reply_block, | 247 | switch (REGEX_BLOCK_check (reply_block, |
491 | reply_block_size, | 248 | reply_block_size, |
@@ -493,8 +250,7 @@ block_plugin_regex_check_reply ( | |||
493 | xquery)) | 250 | xquery)) |
494 | { | 251 | { |
495 | case GNUNET_SYSERR: | 252 | case GNUNET_SYSERR: |
496 | GNUNET_break_op (0); | 253 | GNUNET_assert (0); |
497 | return GNUNET_BLOCK_REPLY_INVALID; | ||
498 | case GNUNET_NO: | 254 | case GNUNET_NO: |
499 | /* xquery mismatch, can happen */ | 255 | /* xquery mismatch, can happen */ |
500 | return GNUNET_BLOCK_REPLY_IRRELEVANT; | 256 | return GNUNET_BLOCK_REPLY_IRRELEVANT; |
@@ -513,20 +269,12 @@ block_plugin_regex_check_reply ( | |||
513 | { | 269 | { |
514 | const struct RegexAcceptBlock *rba; | 270 | const struct RegexAcceptBlock *rba; |
515 | 271 | ||
516 | if (sizeof(struct RegexAcceptBlock) != reply_block_size) | 272 | GNUNET_assert (sizeof(struct RegexAcceptBlock) == reply_block_size); |
517 | { | ||
518 | GNUNET_break_op (0); | ||
519 | return GNUNET_BLOCK_REPLY_INVALID; | ||
520 | } | ||
521 | rba = reply_block; | 273 | rba = reply_block; |
522 | if (ntohl (rba->purpose.size) != | 274 | GNUNET_assert (ntohl (rba->purpose.size) == |
523 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | 275 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
524 | + sizeof(struct GNUNET_TIME_AbsoluteNBO) | 276 | + sizeof(struct GNUNET_TIME_AbsoluteNBO) |
525 | + sizeof(struct GNUNET_HashCode)) | 277 | + sizeof(struct GNUNET_HashCode)); |
526 | { | ||
527 | GNUNET_break_op (0); | ||
528 | return GNUNET_BLOCK_REPLY_INVALID; | ||
529 | } | ||
530 | GNUNET_CRYPTO_hash (reply_block, | 278 | GNUNET_CRYPTO_hash (reply_block, |
531 | reply_block_size, | 279 | reply_block_size, |
532 | &chash); | 280 | &chash); |
@@ -552,8 +300,8 @@ block_plugin_regex_check_reply ( | |||
552 | * @param block block to get the key for | 300 | * @param block block to get the key for |
553 | * @param block_size number of bytes in @a block | 301 | * @param block_size number of bytes in @a block |
554 | * @param key set to the key (query) for the given block | 302 | * @param key set to the key (query) for the given block |
555 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 303 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported, |
556 | * (or if extracting a key from a block of this type does not work) | 304 | * #GNUNET_NO if extracting a key from a block of this type does not work |
557 | */ | 305 | */ |
558 | static enum GNUNET_GenericReturnValue | 306 | static enum GNUNET_GenericReturnValue |
559 | block_plugin_regex_get_key (void *cls, | 307 | block_plugin_regex_get_key (void *cls, |
@@ -571,14 +319,20 @@ block_plugin_regex_get_key (void *cls, | |||
571 | key)) | 319 | key)) |
572 | { | 320 | { |
573 | GNUNET_break_op (0); | 321 | GNUNET_break_op (0); |
574 | return GNUNET_NO; | 322 | memset (key, |
323 | 0, | ||
324 | sizeof (*key)); | ||
325 | return GNUNET_OK; | ||
575 | } | 326 | } |
576 | return GNUNET_OK; | 327 | return GNUNET_OK; |
577 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: | 328 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: |
578 | if (sizeof(struct RegexAcceptBlock) != block_size) | 329 | if (sizeof(struct RegexAcceptBlock) != block_size) |
579 | { | 330 | { |
580 | GNUNET_break_op (0); | 331 | GNUNET_break_op (0); |
581 | return GNUNET_NO; | 332 | memset (key, |
333 | 0, | ||
334 | sizeof (*key)); | ||
335 | return GNUNET_OK; | ||
582 | } | 336 | } |
583 | *key = ((struct RegexAcceptBlock *) block)->key; | 337 | *key = ((struct RegexAcceptBlock *) block)->key; |
584 | return GNUNET_OK; | 338 | return GNUNET_OK; |
@@ -603,7 +357,6 @@ libgnunet_plugin_block_regex_init (void *cls) | |||
603 | struct GNUNET_BLOCK_PluginFunctions *api; | 357 | struct GNUNET_BLOCK_PluginFunctions *api; |
604 | 358 | ||
605 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 359 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
606 | api->evaluate = &block_plugin_regex_evaluate; | ||
607 | api->get_key = &block_plugin_regex_get_key; | 360 | api->get_key = &block_plugin_regex_get_key; |
608 | api->check_query = &block_plugin_regex_check_query; | 361 | api->check_query = &block_plugin_regex_check_query; |
609 | api->check_block = &block_plugin_regex_check_block; | 362 | api->check_block = &block_plugin_regex_check_block; |