diff options
author | Bart Polot <bart@net.in.tum.de> | 2013-03-11 14:51:21 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2013-03-11 14:51:21 +0000 |
commit | 2b869471ca92027e0ffa1d8180585055d7698762 (patch) | |
tree | ce773e8bea6c65d9d8095b4efd6792267abb2025 /src/regex | |
parent | f5c90ebc3dcaf15ec375016bd628717b92461d76 (diff) | |
download | gnunet-2b869471ca92027e0ffa1d8180585055d7698762.tar.gz gnunet-2b869471ca92027e0ffa1d8180585055d7698762.zip |
- allow GNUNET_BLOCK_evaluate on PUT requests for regex blocks
Diffstat (limited to 'src/regex')
-rw-r--r-- | src/regex/gnunet-regex-profiler.c | 2 | ||||
-rw-r--r-- | src/regex/plugin_block_regex.c | 252 | ||||
-rw-r--r-- | src/regex/regex_block_lib.c | 74 | ||||
-rw-r--r-- | src/regex/regex_block_lib.h | 13 |
4 files changed, 203 insertions, 138 deletions
diff --git a/src/regex/gnunet-regex-profiler.c b/src/regex/gnunet-regex-profiler.c index 41e454bbf..139092686 100644 --- a/src/regex/gnunet-regex-profiler.c +++ b/src/regex/gnunet-regex-profiler.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include "gnunet_testbed_service.h" | 37 | #include "gnunet_testbed_service.h" |
38 | 38 | ||
39 | #define FIND_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 90) | 39 | #define FIND_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 90) |
40 | #define SEARCHES_IN_PARALLEL 1 | 40 | #define SEARCHES_IN_PARALLEL 2 |
41 | 41 | ||
42 | /** | 42 | /** |
43 | * DLL of operations | 43 | * DLL of operations |
diff --git a/src/regex/plugin_block_regex.c b/src/regex/plugin_block_regex.c index d3c973560..bfee12d7f 100644 --- a/src/regex/plugin_block_regex.c +++ b/src/regex/plugin_block_regex.c | |||
@@ -59,6 +59,157 @@ rdebug (void *cls, | |||
59 | 59 | ||
60 | 60 | ||
61 | /** | 61 | /** |
62 | * Function called to validate a reply or a request of type | ||
63 | * GNUNET_BLOCK_TYPE_REGEX. | ||
64 | * For request evaluation, pass "NULL" for the reply_block. | ||
65 | * Note that it is assumed that the reply has already been | ||
66 | * matched to the key (and signatures checked) as it would | ||
67 | * be done with the "get_key" function. | ||
68 | * | ||
69 | * @param cls closure | ||
70 | * @param type block type | ||
71 | * @param query original query (hash) | ||
72 | * @param bf pointer to bloom filter associated with query; possibly updated (!) | ||
73 | * @param bf_mutator mutation value for bf | ||
74 | * @param xquery extrended query data (can be NULL, depending on type) | ||
75 | * @param xquery_size number of bytes in xquery | ||
76 | * @param reply_block response to validate | ||
77 | * @param reply_block_size number of bytes in reply block | ||
78 | * @return characterization of result | ||
79 | */ | ||
80 | static enum GNUNET_BLOCK_EvaluationResult | ||
81 | evaluate_block_regex (void *cls, enum GNUNET_BLOCK_Type type, | ||
82 | const struct GNUNET_HashCode * query, | ||
83 | struct GNUNET_CONTAINER_BloomFilter **bf, | ||
84 | int32_t bf_mutator, const void *xquery, | ||
85 | size_t xquery_size, const void *reply_block, | ||
86 | size_t reply_block_size) | ||
87 | { | ||
88 | if (NULL == reply_block) /* queries (GET) are always valid */ | ||
89 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
90 | if (0 != xquery_size) | ||
91 | { | ||
92 | const char *query; | ||
93 | |||
94 | query = (const char *) xquery; | ||
95 | if ('\0' != query[xquery_size - 1]) /* must be valid string */ | ||
96 | { | ||
97 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
98 | "Block xquery not a valid string\n"); | ||
99 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
100 | } | ||
101 | } | ||
102 | else if (NULL != query) /* PUTs don't need xquery */ | ||
103 | { | ||
104 | const struct RegexBlock *rblock = reply_block; | ||
105 | |||
106 | GNUNET_break_op (0); | ||
107 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Block with no xquery\n"); | ||
108 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " key: %s, %u edges\n", | ||
109 | GNUNET_h2s (&rblock->key), ntohl (rblock->n_edges)); | ||
110 | GNUNET_REGEX_block_iterate (rblock, reply_block_size, &rdebug, NULL); | ||
111 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
112 | } | ||
113 | switch (GNUNET_REGEX_block_check (reply_block, | ||
114 | reply_block_size, | ||
115 | xquery)) | ||
116 | { | ||
117 | case GNUNET_SYSERR: | ||
118 | GNUNET_break_op(0); | ||
119 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
120 | case GNUNET_NO: | ||
121 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
122 | "BLOCK XQUERY %s not accepted\n", xquery); | ||
123 | return GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT; | ||
124 | default: | ||
125 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
126 | "BLOCK XQUERY %s accepted\n", xquery); | ||
127 | break; | ||
128 | } | ||
129 | if (NULL != bf) | ||
130 | { | ||
131 | struct GNUNET_HashCode chash; | ||
132 | struct GNUNET_HashCode mhash; | ||
133 | |||
134 | GNUNET_CRYPTO_hash (reply_block, reply_block_size, &chash); | ||
135 | GNUNET_BLOCK_mingle_hash (&chash, bf_mutator, &mhash); | ||
136 | if (NULL != *bf) | ||
137 | { | ||
138 | if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (*bf, &mhash)) | ||
139 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
140 | } | ||
141 | else | ||
142 | { | ||
143 | *bf = GNUNET_CONTAINER_bloomfilter_init (NULL, 8, BLOOMFILTER_K); | ||
144 | } | ||
145 | GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash); | ||
146 | } | ||
147 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
148 | } | ||
149 | |||
150 | |||
151 | /** | ||
152 | * Function called to validate a reply or a request of type | ||
153 | * GNUNET_BLOCK_TYPE_REGEX_ACCEPT. | ||
154 | * For request evaluation, pass "NULL" for the reply_block. | ||
155 | * Note that it is assumed that the reply has already been | ||
156 | * matched to the key (and signatures checked) as it would | ||
157 | * be done with the "get_key" function. | ||
158 | * | ||
159 | * @param cls closure | ||
160 | * @param type block type | ||
161 | * @param query original query (hash) | ||
162 | * @param bf pointer to bloom filter associated with query; possibly updated (!) | ||
163 | * @param bf_mutator mutation value for bf | ||
164 | * @param xquery extrended query data (can be NULL, depending on type) | ||
165 | * @param xquery_size number of bytes in xquery | ||
166 | * @param reply_block response to validate | ||
167 | * @param reply_block_size number of bytes in reply block | ||
168 | * @return characterization of result | ||
169 | */ | ||
170 | static enum GNUNET_BLOCK_EvaluationResult | ||
171 | evaluate_block_regex_accept (void *cls, enum GNUNET_BLOCK_Type type, | ||
172 | const struct GNUNET_HashCode * query, | ||
173 | struct GNUNET_CONTAINER_BloomFilter **bf, | ||
174 | int32_t bf_mutator, const void *xquery, | ||
175 | size_t xquery_size, const void *reply_block, | ||
176 | size_t reply_block_size) | ||
177 | { | ||
178 | if (0 != xquery_size) | ||
179 | { | ||
180 | GNUNET_break_op (0); | ||
181 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | ||
182 | } | ||
183 | if (NULL == reply_block) | ||
184 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
185 | if (sizeof (struct RegexAccept) != reply_block_size) | ||
186 | { | ||
187 | GNUNET_break_op(0); | ||
188 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
189 | } | ||
190 | if (NULL != bf) | ||
191 | { | ||
192 | struct GNUNET_HashCode chash; | ||
193 | struct GNUNET_HashCode mhash; | ||
194 | |||
195 | GNUNET_CRYPTO_hash (reply_block, reply_block_size, &chash); | ||
196 | GNUNET_BLOCK_mingle_hash (&chash, bf_mutator, &mhash); | ||
197 | if (NULL != *bf) | ||
198 | { | ||
199 | if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (*bf, &mhash)) | ||
200 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
201 | } | ||
202 | else | ||
203 | { | ||
204 | *bf = GNUNET_CONTAINER_bloomfilter_init (NULL, 8, BLOOMFILTER_K); | ||
205 | } | ||
206 | GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash); | ||
207 | } | ||
208 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
209 | } | ||
210 | |||
211 | |||
212 | /** | ||
62 | * Function called to validate a reply or a request. For | 213 | * Function called to validate a reply or a request. For |
63 | * request evaluation, simply pass "NULL" for the reply_block. | 214 | * request evaluation, simply pass "NULL" for the reply_block. |
64 | * Note that it is assumed that the reply has already been | 215 | * Note that it is assumed that the reply has already been |
@@ -84,105 +235,26 @@ block_plugin_regex_evaluate (void *cls, enum GNUNET_BLOCK_Type type, | |||
84 | size_t xquery_size, const void *reply_block, | 235 | size_t xquery_size, const void *reply_block, |
85 | size_t reply_block_size) | 236 | size_t reply_block_size) |
86 | { | 237 | { |
87 | struct GNUNET_HashCode chash; | 238 | enum GNUNET_BLOCK_EvaluationResult result; |
88 | struct GNUNET_HashCode mhash; | ||
89 | 239 | ||
90 | switch (type) | 240 | switch (type) |
91 | { | 241 | { |
92 | case GNUNET_BLOCK_TYPE_REGEX: | 242 | case GNUNET_BLOCK_TYPE_REGEX: |
93 | if (NULL == reply_block) | 243 | result = evaluate_block_regex (cls, type, query, bf, bf_mutator, |
94 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | 244 | xquery, xquery_size, |
95 | if (0 != xquery_size) | 245 | reply_block, reply_block_size); |
96 | { | 246 | break; |
97 | const char *query; | ||
98 | |||
99 | query = (const char *) xquery; | ||
100 | if ('\0' != query[xquery_size - 1]) /* must be valid string */ | ||
101 | { | ||
102 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
103 | "Block xquery not a valid string\n"); | ||
104 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
105 | } | ||
106 | } | ||
107 | else | ||
108 | { | ||
109 | const struct RegexBlock *rblock = reply_block; | ||
110 | |||
111 | GNUNET_break_op (0); | ||
112 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Block with no xquery\n"); | ||
113 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " key: %s, %u edges\n", | ||
114 | GNUNET_h2s (&rblock->key), ntohl (rblock->n_edges)); | ||
115 | GNUNET_REGEX_block_iterate (rblock, reply_block_size, &rdebug, NULL); | ||
116 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
117 | } | ||
118 | switch (GNUNET_REGEX_block_check (reply_block, | ||
119 | reply_block_size, | ||
120 | xquery)) | ||
121 | { | ||
122 | case GNUNET_SYSERR: | ||
123 | GNUNET_break_op(0); | ||
124 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
125 | case GNUNET_NO: | ||
126 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
127 | "BLOCK XQUERY %s not accepted\n", xquery); | ||
128 | return GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT; | ||
129 | default: | ||
130 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
131 | "BLOCK XQUERY %s accepted\n", xquery); | ||
132 | break; | ||
133 | } | ||
134 | if (NULL != bf) | ||
135 | { | ||
136 | GNUNET_CRYPTO_hash (reply_block, reply_block_size, &chash); | ||
137 | GNUNET_BLOCK_mingle_hash (&chash, bf_mutator, &mhash); | ||
138 | if (NULL != *bf) | ||
139 | { | ||
140 | if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (*bf, &mhash)) | ||
141 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
142 | } | ||
143 | else | ||
144 | { | ||
145 | *bf = GNUNET_CONTAINER_bloomfilter_init (NULL, 8, BLOOMFILTER_K); | ||
146 | } | ||
147 | GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash); | ||
148 | } | ||
149 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
150 | |||
151 | 247 | ||
152 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: | 248 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: |
153 | if (0 != xquery_size) | 249 | result = evaluate_block_regex_accept (cls, type, query, bf, bf_mutator, |
154 | { | 250 | xquery, xquery_size, |
155 | GNUNET_break_op (0); | 251 | reply_block, reply_block_size); |
156 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | 252 | break; |
157 | } | ||
158 | if (NULL == reply_block) | ||
159 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
160 | if (sizeof (struct RegexAccept) != reply_block_size) | ||
161 | { | ||
162 | GNUNET_break_op(0); | ||
163 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
164 | } | ||
165 | if (NULL != bf) | ||
166 | { | ||
167 | GNUNET_CRYPTO_hash (reply_block, reply_block_size, &chash); | ||
168 | GNUNET_BLOCK_mingle_hash (&chash, bf_mutator, &mhash); | ||
169 | if (NULL != *bf) | ||
170 | { | ||
171 | if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (*bf, &mhash)) | ||
172 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
173 | } | ||
174 | else | ||
175 | { | ||
176 | *bf = GNUNET_CONTAINER_bloomfilter_init (NULL, 8, BLOOMFILTER_K); | ||
177 | } | ||
178 | GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash); | ||
179 | } | ||
180 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
181 | |||
182 | 253 | ||
183 | default: | 254 | default: |
184 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | 255 | result = GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; |
185 | } | 256 | } |
257 | return result; | ||
186 | } | 258 | } |
187 | 259 | ||
188 | 260 | ||
diff --git a/src/regex/regex_block_lib.c b/src/regex/regex_block_lib.c index deb496fd9..3f7c9473a 100644 --- a/src/regex/regex_block_lib.c +++ b/src/regex/regex_block_lib.c | |||
@@ -62,7 +62,9 @@ check_edge (void *cls, | |||
62 | struct regex_block_xquery_ctx *ctx = cls; | 62 | struct regex_block_xquery_ctx *ctx = cls; |
63 | 63 | ||
64 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " edge %.*s [%u]\n", | 64 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " edge %.*s [%u]\n", |
65 | (int) len, token, len); | 65 | (int) len, token, len); |
66 | if (NULL == ctx->xquery) | ||
67 | return GNUNET_YES; | ||
66 | if (strlen (ctx->xquery) < len) | 68 | if (strlen (ctx->xquery) < len) |
67 | { | 69 | { |
68 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " too long!\n"); | 70 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " too long!\n"); |
@@ -82,54 +84,37 @@ check_edge (void *cls, | |||
82 | } | 84 | } |
83 | 85 | ||
84 | 86 | ||
85 | /** | ||
86 | * Check if the regex block is well formed, including all edges | ||
87 | * | ||
88 | * @param block The start of the block. | ||
89 | * @param size The size of the block. | ||
90 | * @param xquery String describing the edge we are looking for. | ||
91 | * | ||
92 | * @return GNUNET_OK in case it's fine. | ||
93 | * GNUNET_NO in case the xquery is not found. | ||
94 | * GNUNET_SYSERR if the block is invalid. | ||
95 | */ | ||
96 | int | 87 | int |
97 | GNUNET_REGEX_block_check (const struct RegexBlock *block, | 88 | GNUNET_REGEX_block_check (const struct RegexBlock *block, |
98 | size_t size, | 89 | size_t size, |
99 | const char *xquery) | 90 | const char *xquery) |
100 | { | 91 | { |
101 | int res; | 92 | int res; |
102 | struct regex_block_xquery_ctx ctx; | 93 | struct regex_block_xquery_ctx ctx; |
103 | 94 | ||
104 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 95 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
105 | "* Checking block with xquery \"%s\"\n", | 96 | "* Checking block with xquery \"%s\"\n", |
106 | xquery); | 97 | NULL != xquery ? xquery : "NULL"); |
107 | if ( (GNUNET_YES == ntohl(block->accepting)) && ('\0' == xquery[0]) ) | 98 | if ( (GNUNET_YES == ntohl (block->accepting)) && |
99 | ( (NULL == xquery) || ('\0' == xquery[0]) ) | ||
100 | ) | ||
108 | return GNUNET_OK; | 101 | return GNUNET_OK; |
109 | ctx.xquery = xquery; | 102 | ctx.xquery = xquery; |
110 | ctx.found = GNUNET_NO; | 103 | ctx.found = GNUNET_NO; |
111 | res = GNUNET_REGEX_block_iterate (block, size, &check_edge, &ctx); | 104 | res = GNUNET_REGEX_block_iterate (block, size, &check_edge, &ctx); |
112 | if (GNUNET_SYSERR == res) | 105 | if (GNUNET_SYSERR == res) |
113 | return GNUNET_SYSERR; | 106 | return GNUNET_SYSERR; |
107 | if (NULL == xquery) | ||
108 | return GNUNET_YES; | ||
114 | return ctx.found; | 109 | return ctx.found; |
115 | } | 110 | } |
116 | 111 | ||
117 | 112 | ||
118 | /** | ||
119 | * Iterate over all edges of a block of a regex state. | ||
120 | * | ||
121 | * @param block Block to iterate over. | ||
122 | * @param size Size of block. | ||
123 | * @param iterator Function to call on each edge in the block. | ||
124 | * @param iter_cls Closure for the iterator. | ||
125 | * | ||
126 | * @return How many bytes of block have been processed | ||
127 | */ | ||
128 | int | 113 | int |
129 | GNUNET_REGEX_block_iterate (const struct RegexBlock *block, | 114 | GNUNET_REGEX_block_iterate (const struct RegexBlock *block, |
130 | size_t size, | 115 | size_t size, |
131 | GNUNET_REGEX_EgdeIterator iterator, | 116 | GNUNET_REGEX_EgdeIterator iterator, |
132 | void *iter_cls) | 117 | void *iter_cls) |
133 | { | 118 | { |
134 | struct RegexEdge *edge; | 119 | struct RegexEdge *edge; |
135 | unsigned int n; | 120 | unsigned int n; |
@@ -142,7 +127,7 @@ GNUNET_REGEX_block_iterate (const struct RegexBlock *block, | |||
142 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 127 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
143 | "* Start iterating block of size %u, off %u\n", | 128 | "* Start iterating block of size %u, off %u\n", |
144 | size, offset); | 129 | size, offset); |
145 | if (offset > size) // Is it safe to access the regex block? | 130 | if (offset >= size) /* Is it safe to access the regex block? */ |
146 | { | 131 | { |
147 | LOG (GNUNET_ERROR_TYPE_WARNING, | 132 | LOG (GNUNET_ERROR_TYPE_WARNING, |
148 | "* Block is smaller than struct RegexBlock, END\n"); | 133 | "* Block is smaller than struct RegexBlock, END\n"); |
@@ -153,22 +138,23 @@ GNUNET_REGEX_block_iterate (const struct RegexBlock *block, | |||
153 | offset += n; | 138 | offset += n; |
154 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 139 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
155 | "* Proof length: %u, off %u\n", n, offset); | 140 | "* Proof length: %u, off %u\n", n, offset); |
156 | if (offset > size) // Is it safe to access the regex proof? | 141 | if (offset >= size) /* Is it safe to access the regex proof? */ |
157 | { | 142 | { |
158 | LOG (GNUNET_ERROR_TYPE_WARNING, | 143 | LOG (GNUNET_ERROR_TYPE_WARNING, |
159 | "* Block is smaller than Block + proof, END\n"); | 144 | "* Block is smaller than Block + proof, END\n"); |
160 | GNUNET_break_op (0); | 145 | GNUNET_break_op (0); |
161 | return GNUNET_SYSERR; | 146 | return GNUNET_SYSERR; |
162 | } | 147 | } |
163 | aux = (char *) &block[1]; // Skip regex block | 148 | aux = (char *) &block[1]; /* Skip regex block */ |
164 | aux = &aux[n]; // Skip regex proof | 149 | aux = &aux[n]; /* Skip regex proof */ |
165 | n = ntohl (block->n_edges); | 150 | n = ntohl (block->n_edges); |
166 | LOG (GNUNET_ERROR_TYPE_DEBUG, "* Edges: %u\n", n); | 151 | LOG (GNUNET_ERROR_TYPE_DEBUG, "* Edges: %u\n", n); |
167 | for (i = 0; i < n; i++) // aux always points at the end of the previous block | 152 | /* aux always points at the end of the previous block */ |
153 | for (i = 0; i < n; i++) | ||
168 | { | 154 | { |
169 | offset += sizeof (struct RegexEdge); | 155 | offset += sizeof (struct RegexEdge); |
170 | LOG (GNUNET_ERROR_TYPE_DEBUG, "* Edge %u, off %u\n", i, offset); | 156 | LOG (GNUNET_ERROR_TYPE_DEBUG, "* Edge %u, off %u\n", i, offset); |
171 | if (offset > size) // Is it safe to access the next edge block? | 157 | if (offset >= size) /* Is it safe to access the next edge block? */ |
172 | { | 158 | { |
173 | LOG (GNUNET_ERROR_TYPE_WARNING, | 159 | LOG (GNUNET_ERROR_TYPE_WARNING, |
174 | "* Size not enough for RegexEdge, END\n"); | 160 | "* Size not enough for RegexEdge, END\n"); |
@@ -179,23 +165,23 @@ GNUNET_REGEX_block_iterate (const struct RegexBlock *block, | |||
179 | n_token = ntohl (edge->n_token); | 165 | n_token = ntohl (edge->n_token); |
180 | offset += n_token; | 166 | offset += n_token; |
181 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 167 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
182 | "* Token lenght %u, off %u\n", n_token, offset); | 168 | "* Token length %u, off %u\n", n_token, offset); |
183 | if (offset > size) // Is it safe to access the edge token? | 169 | if (offset > size) /* Is it safe to access the edge token? */ |
184 | { | 170 | { |
185 | LOG (GNUNET_ERROR_TYPE_WARNING, | 171 | LOG (GNUNET_ERROR_TYPE_WARNING, |
186 | "* Size not enough for edge token, END\n"); | 172 | "* Size not enough for edge token, END\n"); |
187 | GNUNET_break_op (0); | 173 | GNUNET_break_op (0); |
188 | return GNUNET_SYSERR; | 174 | return GNUNET_SYSERR; |
189 | } | 175 | } |
190 | aux = (char *) &edge[1]; // Skip edge block | 176 | aux = (char *) &edge[1]; /* Skip edge block */ |
191 | if (NULL != iterator) | 177 | if (NULL != iterator) |
192 | if (GNUNET_NO == iterator (iter_cls, aux, n_token, &edge->key)) | 178 | if (GNUNET_NO == iterator (iter_cls, aux, n_token, &edge->key)) |
193 | return GNUNET_OK; | 179 | return GNUNET_OK; |
194 | aux = &aux[n_token]; // Skip edge token | 180 | aux = &aux[n_token]; /* Skip edge token */ |
195 | } | 181 | } |
196 | // The total size should be exactly the size of (regex + all edges) blocks | 182 | /* The total size should be exactly the size of (regex + all edges) blocks |
197 | // If size == -1, block is from cache and therefore previously checked and | 183 | * If size == -1, block is from cache and therefore previously checked and |
198 | // assumed correct. | 184 | * assumed correct. */ |
199 | if (offset == size || SIZE_MAX == size) | 185 | if (offset == size || SIZE_MAX == size) |
200 | { | 186 | { |
201 | LOG (GNUNET_ERROR_TYPE_DEBUG, "* Block processed, END OK\n"); | 187 | LOG (GNUNET_ERROR_TYPE_DEBUG, "* Block processed, END OK\n"); |
diff --git a/src/regex/regex_block_lib.h b/src/regex/regex_block_lib.h index f591f5f61..ca7a2ee22 100644 --- a/src/regex/regex_block_lib.h +++ b/src/regex/regex_block_lib.h | |||
@@ -39,14 +39,15 @@ extern "C" | |||
39 | #include "block_regex.h" | 39 | #include "block_regex.h" |
40 | 40 | ||
41 | /** | 41 | /** |
42 | * Check if the regex block is well formed, including all edges | 42 | * Check if the regex block is well formed, including all edges. |
43 | * | 43 | * |
44 | * @param block The start of the block. | 44 | * @param block The start of the block. |
45 | * @param size The size of the block. | 45 | * @param size The size of the block. |
46 | * @param xquery String describing the edge we are looking for. | 46 | * @param xquery String describing the edge we are looking for. |
47 | * Can be NULL in case this is a put block. | ||
47 | * | 48 | * |
48 | * @return GNUNET_OK in case it's fine. | 49 | * @return GNUNET_OK in case it's fine. |
49 | * GNUNET_NO in case the xquery is not found. | 50 | * GNUNET_NO in case the xquery exists and is not found (IRRELEVANT). |
50 | * GNUNET_SYSERR if the block is invalid. | 51 | * GNUNET_SYSERR if the block is invalid. |
51 | */ | 52 | */ |
52 | int | 53 | int |
@@ -78,7 +79,13 @@ typedef int (*GNUNET_REGEX_EgdeIterator)(void *cls, | |||
78 | * @param iterator Function to call on each edge in the block. | 79 | * @param iterator Function to call on each edge in the block. |
79 | * @param iter_cls Closure for the iterator. | 80 | * @param iter_cls Closure for the iterator. |
80 | * | 81 | * |
81 | * @return GNUNET_SYSERR if an error has been encountered, GNUNET_OK otherwise | 82 | * @return GNUNET_SYSERR if an error has been encountered. |
83 | * GNUNET_OK if no error has been encountered. | ||
84 | * Note that if the iterator stops the iteration by returning | ||
85 | * GNUNET_NO, the block will no longer be checked for further errors. | ||
86 | * The return value will be GNUNET_OK meaning that no errors were | ||
87 | * found until the edge last notified to the iterator, but there might | ||
88 | * be errors in further edges. | ||
82 | */ | 89 | */ |
83 | int | 90 | int |
84 | GNUNET_REGEX_block_iterate (const struct RegexBlock *block, | 91 | GNUNET_REGEX_block_iterate (const struct RegexBlock *block, |