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/regex_block_lib.c | |
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/regex_block_lib.c')
-rw-r--r-- | src/regex/regex_block_lib.c | 74 |
1 files changed, 30 insertions, 44 deletions
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"); |