2 This file is part of GNUnet.
3 (C) 2012 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
21 * @author Bartlomiej Polot
22 * @file mesh/mesh_block_lib.c
25 #include "mesh_block_lib.h"
29 * Struct to keep track of the xquery while iterating all the edges in a block.
31 struct mesh_block_xquery_ctx
34 * Xquery: string we are looking for.
39 * Has any edge matched the xquery so far? (GNUNET_OK / GNUNET_NO)
46 * Iterator over all edges in a block, checking for a presence of a given query.
48 * @param cls Closure, (xquery context).
49 * @param token Token that follows to next state.
50 * @param len Lenght of token.
51 * @param key Hash of next state.
53 * @return GNUNET_YES, to keep iterating
56 check_edge (void *cls,
59 const struct GNUNET_HashCode *key)
61 struct mesh_block_xquery_ctx *ctx = cls;
63 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " edge %.*s [%u]\n",
64 (int) len, token, len);
65 if (strlen (ctx->xquery) < len)
67 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " too long!\n");
70 if (0 == strncmp (ctx->xquery, token, len))
72 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " OK!\n");
73 ctx->found = GNUNET_OK;
77 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " KO!\n");
80 return GNUNET_YES; /* keep checking for malformed data! */
85 * Check if the regex block is well formed, including all edges
87 * @param block The start of the block.
88 * @param size The size of the block.
89 * @param xquery String describing the edge we are looking for.
91 * @return GNUNET_OK in case it's fine.
92 * GNUNET_NO in case the xquery is not found.
93 * GNUNET_SYSERR if the block is invalid.
96 GNUNET_MESH_regex_block_check (const struct MeshRegexBlock *block,
101 struct mesh_block_xquery_ctx ctx;
103 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
104 "* Checking block with xquery \"%s\"\n",
106 if ( (GNUNET_YES == ntohl(block->accepting)) && ('\0' == xquery[0]) )
109 ctx.found = GNUNET_NO;
110 res = GNUNET_MESH_regex_block_iterate (block, size, &check_edge, &ctx);
111 if (GNUNET_SYSERR == res)
112 return GNUNET_SYSERR;
118 * Iterate over all edges of a block of a regex state.
120 * @param block Block to iterate over.
121 * @param size Size of block.
122 * @param iterator Function to call on each edge in the block.
123 * @param iter_cls Closure for the iterator.
125 * @return How many bytes of block have been processed
128 GNUNET_MESH_regex_block_iterate (const struct MeshRegexBlock *block,
130 GNUNET_MESH_EgdeIterator iterator,
133 struct MeshRegexEdge *edge;
135 unsigned int n_token;
140 offset = sizeof (struct MeshRegexBlock);
141 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
142 "* Start iterating block of size %u, off %u\n",
144 if (offset > size) // Is it safe to access the regex block?
146 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
147 "* Block is smaller than struct MeshRegexBlock, END\n");
149 return GNUNET_SYSERR;
151 n = ntohl (block->n_proof);
153 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
154 "* Proof length: %u, off %u\n", n, offset);
155 if (offset > size) // Is it safe to access the regex proof?
157 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
158 "* Block is smaller than Block + proof, END\n");
160 return GNUNET_SYSERR;
162 aux = (char *) &block[1]; // Skip regex block
163 aux = &aux[n]; // Skip regex proof
164 n = ntohl (block->n_edges);
165 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* Edges: %u\n", n);
166 for (i = 0; i < n; i++) // aux always points at the end of the previous block
168 offset += sizeof (struct MeshRegexEdge);
169 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* Edge %u, off %u\n", i, offset);
170 if (offset > size) // Is it safe to access the next edge block?
172 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
173 "* Size not enough for MeshRegexEdge, END\n");
175 return GNUNET_SYSERR;
177 edge = (struct MeshRegexEdge *) aux;
178 n_token = ntohl (edge->n_token);
180 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
181 "* Token lenght %u, off %u\n", n_token, offset);
182 if (offset > size) // Is it safe to access the edge token?
184 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
185 "* Size not enough for edge token, END\n");
187 return GNUNET_SYSERR;
189 aux = (char *) &edge[1]; // Skip edge block
190 if (NULL != iterator)
191 if (GNUNET_NO == iterator (iter_cls, aux, n_token, &edge->key))
193 aux = &aux[n_token]; // Skip edge token
195 // The total size should be exactly the size of (regex + all edges) blocks
196 // If size == -1, block is from cache and therefore previously checked and
198 if (offset == size || SIZE_MAX == size)
200 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
201 "* Block processed, END OK\n");
204 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
205 "* Size %u (%d), read %u END KO\n", size, size, offset);
207 return GNUNET_SYSERR;
210 /* end of mesh_block_lib.c */