aboutsummaryrefslogtreecommitdiff
path: root/src/core/gnunet-service-core_typemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/gnunet-service-core_typemap.c')
-rw-r--r--src/core/gnunet-service-core_typemap.c377
1 files changed, 0 insertions, 377 deletions
diff --git a/src/core/gnunet-service-core_typemap.c b/src/core/gnunet-service-core_typemap.c
deleted file mode 100644
index 47235501c..000000000
--- a/src/core/gnunet-service-core_typemap.c
+++ /dev/null
@@ -1,377 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011-2014 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file core/gnunet-service-core_typemap.c
23 * @brief management of map that specifies which message types this peer supports
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_transport_service.h"
29#include "gnunet-service-core.h"
30#include "gnunet-service-core_sessions.h"
31#include "gnunet-service-core_typemap.h"
32#include <zlib.h>
33
34
35/**
36 * A type map describing which messages a given neighbour is able
37 * to process.
38 */
39struct GSC_TypeMap
40{
41 uint32_t bits[(UINT16_MAX + 1) / 32];
42};
43
44/**
45 * Bitmap of message types this peer is able to handle.
46 */
47static struct GSC_TypeMap my_type_map;
48
49/**
50 * Counters for message types this peer is able to handle.
51 */
52static uint8_t map_counters[UINT16_MAX + 1];
53
54/**
55 * Current hash of our (uncompressed) type map.
56 * Lazily computed when needed.
57 */
58static struct GNUNET_HashCode my_tm_hash;
59
60/**
61 * Is #my_tm_hash() current with respect to our type map?
62 */
63static int hash_current;
64
65
66/**
67 * Our type map changed, recompute its hash.
68 */
69static void
70rehash_typemap ()
71{
72 hash_current = GNUNET_NO;
73}
74
75
76/**
77 * Hash the contents of a type map.
78 *
79 * @param tm map to hash
80 * @param hc where to store the hash code
81 */
82void
83GSC_TYPEMAP_hash (const struct GSC_TypeMap *tm, struct GNUNET_HashCode *hc)
84{
85 GNUNET_CRYPTO_hash (tm, sizeof(struct GSC_TypeMap), hc);
86}
87
88
89/**
90 * Check if the given hash matches our current type map.
91 *
92 * @param hc hash code to check if it matches our type map
93 * @return #GNUNET_YES if the hash matches, #GNUNET_NO if not
94 */
95int
96GSC_TYPEMAP_check_hash (const struct GNUNET_HashCode *hc)
97{
98 if (GNUNET_NO == hash_current)
99 {
100 GSC_TYPEMAP_hash (&my_type_map, &my_tm_hash);
101 hash_current = GNUNET_YES;
102 }
103 return (0 == memcmp (hc, &my_tm_hash, sizeof(struct GNUNET_HashCode)))
104 ? GNUNET_YES
105 : GNUNET_NO;
106}
107
108
109/**
110 * Compute a type map message for this peer.
111 *
112 * @return this peers current type map message.
113 */
114struct GNUNET_MessageHeader *
115GSC_TYPEMAP_compute_type_map_message ()
116{
117 char *tmp;
118 uLongf dlen;
119 struct GNUNET_MessageHeader *hdr;
120
121#ifdef compressBound
122 dlen = compressBound (sizeof(my_type_map));
123#else
124 dlen = sizeof(my_type_map) + (sizeof(my_type_map) / 100) + 20;
125 /* documentation says 100.1% oldSize + 12 bytes, but we
126 * should be able to overshoot by more to be safe */
127#endif
128 hdr = GNUNET_malloc (dlen + sizeof(struct GNUNET_MessageHeader));
129 tmp = (char *) &hdr[1];
130 if ((Z_OK != compress2 ((Bytef *) tmp,
131 &dlen,
132 (const Bytef *) &my_type_map,
133 sizeof(my_type_map),
134 9)) ||
135 (dlen >= sizeof(my_type_map)))
136 {
137 /* compression failed, use uncompressed map */
138 dlen = sizeof(my_type_map);
139 GNUNET_memcpy (tmp, &my_type_map, sizeof(my_type_map));
140 hdr->type = htons (GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP);
141 }
142 else
143 {
144 /* compression worked, use compressed map */
145 hdr->type = htons (GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP);
146 }
147 hdr->size = htons ((uint16_t) dlen + sizeof(struct GNUNET_MessageHeader));
148 return hdr;
149}
150
151
152/**
153 * Extract a type map from a TYPE_MAP message.
154 *
155 * @param msg a type map message
156 * @return NULL on error
157 */
158struct GSC_TypeMap *
159GSC_TYPEMAP_get_from_message (const struct GNUNET_MessageHeader *msg)
160{
161 struct GSC_TypeMap *ret;
162 uint16_t size;
163 uLongf dlen;
164
165 size = ntohs (msg->size);
166 switch (ntohs (msg->type))
167 {
168 case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
169 GNUNET_STATISTICS_update (GSC_stats,
170 gettext_noop ("# type maps received"),
171 1,
172 GNUNET_NO);
173 if (size != sizeof(struct GSC_TypeMap))
174 {
175 GNUNET_break_op (0);
176 return NULL;
177 }
178 ret = GNUNET_new (struct GSC_TypeMap);
179 GNUNET_memcpy (ret, &msg[1], sizeof(struct GSC_TypeMap));
180 return ret;
181
182 case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
183 GNUNET_STATISTICS_update (GSC_stats,
184 gettext_noop ("# type maps received"),
185 1,
186 GNUNET_NO);
187 ret = GNUNET_new (struct GSC_TypeMap);
188 dlen = sizeof(struct GSC_TypeMap);
189 if ((Z_OK != uncompress ((Bytef *) ret,
190 &dlen,
191 (const Bytef *) &msg[1],
192 (uLong) size)) ||
193 (dlen != sizeof(struct GSC_TypeMap)))
194 {
195 GNUNET_break_op (0);
196 GNUNET_free (ret);
197 return NULL;
198 }
199 return ret;
200
201 default:
202 GNUNET_break (0);
203 return NULL;
204 }
205}
206
207
208/**
209 * Send my type map to all connected peers (it got changed).
210 */
211static void
212broadcast_my_type_map ()
213{
214 struct GNUNET_MessageHeader *hdr;
215
216 hdr = GSC_TYPEMAP_compute_type_map_message ();
217 GNUNET_STATISTICS_update (GSC_stats,
218 gettext_noop ("# updates to my type map"),
219 1,
220 GNUNET_NO);
221 GSC_SESSIONS_broadcast_typemap (hdr);
222 GNUNET_free (hdr);
223}
224
225
226/**
227 * Add a set of types to our type map.
228 *
229 * @param types array of message types supported by this peer
230 * @param tlen number of entries in @a types
231 */
232void
233GSC_TYPEMAP_add (const uint16_t *types, unsigned int tlen)
234{
235 unsigned int i;
236 int changed;
237
238 changed = GNUNET_NO;
239 for (i = 0; i < tlen; i++)
240 {
241 if (0 == map_counters[types[i]]++)
242 {
243 my_type_map.bits[types[i] / 32] |= (1 << (types[i] % 32));
244 changed = GNUNET_YES;
245 }
246 }
247 if (GNUNET_YES == changed)
248 {
249 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Typemap changed, broadcasting!\n");
250 rehash_typemap ();
251 broadcast_my_type_map ();
252 }
253}
254
255
256/**
257 * Remove a set of types from our type map.
258 *
259 * @param types array of types to remove
260 * @param tlen length of the @a types array
261 */
262void
263GSC_TYPEMAP_remove (const uint16_t *types, unsigned int tlen)
264{
265 int changed;
266
267 changed = GNUNET_NO;
268 for (unsigned int i = 0; i < tlen; i++)
269 {
270 if (0 == --map_counters[types[i]])
271 {
272 my_type_map.bits[types[i] / 32] &= ~(1 << (types[i] % 32));
273 changed = GNUNET_YES;
274 }
275 }
276 if (GNUNET_YES == changed)
277 {
278 rehash_typemap ();
279 broadcast_my_type_map ();
280 }
281}
282
283
284/**
285 * Test if any of the types from the types array is in the
286 * given type map.
287 *
288 * @param tmap map to test
289 * @param types array of types
290 * @param tcnt number of entries in @a types
291 * @return #GNUNET_YES if a type is in the map, #GNUNET_NO if not
292 */
293int
294GSC_TYPEMAP_test_match (const struct GSC_TypeMap *tmap,
295 const uint16_t *types,
296 unsigned int tcnt)
297{
298 if (NULL == tmap)
299 return GNUNET_NO;
300 if (0 == tcnt)
301 return GNUNET_YES; /* matches all */
302 for (unsigned int i = 0; i < tcnt; i++)
303 if (0 != (tmap->bits[types[i] / 32] & (1 << (types[i] % 32))))
304 return GNUNET_YES;
305 return GNUNET_NO;
306}
307
308
309/**
310 * Add additional types to a given typemap.
311 *
312 * @param tmap map to extend (not changed)
313 * @param types array of types to add
314 * @param tcnt number of entries in @a types
315 * @return updated type map (fresh copy)
316 */
317struct GSC_TypeMap *
318GSC_TYPEMAP_extend (const struct GSC_TypeMap *tmap,
319 const uint16_t *types,
320 unsigned int tcnt)
321{
322 struct GSC_TypeMap *ret;
323
324 ret = GNUNET_new (struct GSC_TypeMap);
325 if (NULL != tmap)
326 GNUNET_memcpy (ret, tmap, sizeof(struct GSC_TypeMap));
327 for (unsigned int i = 0; i < tcnt; i++)
328 ret->bits[types[i] / 32] |= (1 << (types[i] % 32));
329 return ret;
330}
331
332
333/**
334 * Create an empty type map.
335 *
336 * @return an empty type map
337 */
338struct GSC_TypeMap *
339GSC_TYPEMAP_create ()
340{
341 return GNUNET_new (struct GSC_TypeMap);
342}
343
344
345/**
346 * Free the given type map.
347 *
348 * @param tmap a type map
349 */
350void
351GSC_TYPEMAP_destroy (struct GSC_TypeMap *tmap)
352{
353 GNUNET_free (tmap);
354}
355
356
357/**
358 * Initialize typemap subsystem.
359 */
360void
361GSC_TYPEMAP_init ()
362{
363 /* nothing to do */
364}
365
366
367/**
368 * Shutdown typemap subsystem.
369 */
370void
371GSC_TYPEMAP_done ()
372{
373 /* nothing to do */
374}
375
376
377/* end of gnunet-service-core_typemap.c */