aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-wdht_datacache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dht/gnunet-service-wdht_datacache.c')
-rw-r--r--src/dht/gnunet-service-wdht_datacache.c459
1 files changed, 0 insertions, 459 deletions
diff --git a/src/dht/gnunet-service-wdht_datacache.c b/src/dht/gnunet-service-wdht_datacache.c
deleted file mode 100644
index 40d54bf5a..000000000
--- a/src/dht/gnunet-service-wdht_datacache.c
+++ /dev/null
@@ -1,459 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2011, 2015 GNUnet e.V.
4
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.
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 General Public License for more details.
14
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., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file dht/gnunet-service-wdht_datacache.c
23 * @brief GNUnet DHT service's datacache integration
24 * @author Christian Grothoff
25 * @author Nathan Evans
26 */
27#include "platform.h"
28#include "gnunet_datacache_lib.h"
29#include "gnunet-service-wdht_clients.h"
30#include "gnunet-service-wdht_datacache.h"
31#include "gnunet-service-wdht_neighbours.h"
32#include "gnunet-service-dht.h"
33
34#define LOG(kind,...) GNUNET_log_from (kind, "dht-dtcache",__VA_ARGS__)
35
36#define DEBUG(...) \
37 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
38
39/**
40 * How many "closest" results to we return for migration when
41 * asked (at most)?
42 */
43#define NUM_CLOSEST 42
44
45/**
46 * Handle to the datacache service (for inserting/retrieving data)
47 */
48static struct GNUNET_DATACACHE_Handle *datacache;
49
50
51/**
52 * Handle a datum we've received from another peer. Cache if
53 * possible.
54 *
55 * @param expiration when will the reply expire
56 * @param key the query this reply is for
57 * @param put_path_length number of peers in @a put_path
58 * @param put_path path the reply took on put
59 * @param get_path_length number of peers in @a get_path
60 * @param get_path path the reply took on get
61 * @param type type of the reply
62 * @param data_size number of bytes in @a data
63 * @param data application payload data
64 */
65void
66GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
67 const struct GNUNET_HashCode *key,
68 unsigned int put_path_length,
69 const struct GNUNET_PeerIdentity *put_path,
70 unsigned int get_path_length,
71 const struct GNUNET_PeerIdentity *get_path,
72 enum GNUNET_BLOCK_Type type,
73 size_t data_size,
74 const void *data)
75{
76 int r;
77 struct GNUNET_PeerIdentity path[get_path_length + put_path_length];
78
79 if (NULL == datacache)
80 {
81 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
82 _("PUT request received, but have no datacache!\n"));
83 return;
84 }
85 if (data_size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
86 {
87 GNUNET_break (0);
88 return;
89 }
90 GNUNET_memcpy (path,
91 put_path,
92 put_path_length * sizeof (struct GNUNET_PeerIdentity));
93 GNUNET_memcpy (&path[put_path_length],
94 get_path,
95 get_path_length * sizeof (struct GNUNET_PeerIdentity));
96 /* Put size is actual data size plus struct overhead plus path length (if any) */
97 r = GNUNET_DATACACHE_put (datacache,
98 key,
99 data_size,
100 data,
101 type,
102 expiration,
103 get_path_length + put_path_length,
104 path);
105 if (GNUNET_OK == r)
106 GNUNET_STATISTICS_update (GDS_stats,
107 gettext_noop ("# ITEMS stored in datacache"), 1,
108 GNUNET_NO);
109 LOG (GNUNET_ERROR_TYPE_DEBUG,
110 "DATACACHE PUT for key %s [%u] completed (%d) after %u hops\n",
111 GNUNET_h2s (key),
112 data_size,
113 r,
114 put_path_length + get_path_length);
115}
116
117
118/**
119 * Context containing information about a GET request.
120 */
121struct GetRequestContext
122{
123 /**
124 * extended query (see gnunet_block_lib.h).
125 */
126 const void *xquery;
127
128 /**
129 * Bloomfilter to filter out duplicate replies (updated)
130 */
131 struct GNUNET_CONTAINER_BloomFilter **reply_bf;
132
133 /**
134 * The key this request was about
135 */
136 struct GNUNET_HashCode key;
137
138 /**
139 * The trail this request was for
140 */
141 const struct GNUNET_HashCode *trail_id;
142
143 /**
144 * Number of bytes in @e xquery.
145 */
146 size_t xquery_size;
147
148 /**
149 * Mutator value for the @e reply_bf, see gnunet_block_lib.h
150 */
151 uint32_t reply_bf_mutator;
152
153 /**
154 * Return value to give back.
155 */
156 enum GNUNET_BLOCK_EvaluationResult eval;
157
158 /**
159 * Routing options of the GET.
160 */
161 enum GNUNET_DHT_RouteOption options;
162
163};
164
165
166/**
167 * Iterator for local get request results,
168 *
169 * @param cls closure for iterator, a `struct GetRequestContext`
170 * @param key the key this data is stored under
171 * @param size the size of the data identified by key
172 * @param data the actual data
173 * @param type the type of the data
174 * @param exp when does this value expire?
175 * @param put_path_length number of peers in @a put_path
176 * @param put_path path the reply took on put
177 * @return #GNUNET_OK to continue iteration, anything else
178 * to stop iteration.
179 */
180static int
181datacache_get_iterator (void *cls,
182 const struct GNUNET_HashCode *key,
183 size_t size,
184 const char *data,
185 enum GNUNET_BLOCK_Type type,
186 struct GNUNET_TIME_Absolute exp,
187 unsigned int put_path_length,
188 const struct GNUNET_PeerIdentity *put_path)
189{
190 struct GetRequestContext *ctx = cls;
191 enum GNUNET_BLOCK_EvaluationResult eval;
192
193 eval =
194 GNUNET_BLOCK_evaluate (GDS_block_context,
195 type,
196 GNUNET_BLOCK_EO_NONE,
197 key,
198 ctx->reply_bf,
199 ctx->reply_bf_mutator,
200 ctx->xquery,
201 ctx->xquery_size,
202 data,
203 size);
204 LOG (GNUNET_ERROR_TYPE_DEBUG,
205 "Found reply for query %s in datacache, evaluation result is %d\n",
206 GNUNET_h2s (key), (int) eval);
207 ctx->eval = eval;
208
209 switch (eval)
210 {
211 case GNUNET_BLOCK_EVALUATION_OK_MORE:
212 case GNUNET_BLOCK_EVALUATION_OK_LAST:
213 /* forward to local clients */
214 GNUNET_STATISTICS_update (GDS_stats,
215 gettext_noop
216 ("# Good RESULTS found in datacache"), 1,
217 GNUNET_NO);
218 GDS_NEIGHBOURS_send_get_result (ctx->trail_id,
219 ctx->options,
220 key,
221 type,
222 put_path_length,
223 put_path,
224 exp,
225 data,
226 size);
227 break;
228 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
229 GNUNET_STATISTICS_update (GDS_stats,
230 gettext_noop
231 ("# Duplicate RESULTS found in datacache"), 1,
232 GNUNET_NO);
233 break;
234 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
235 GNUNET_STATISTICS_update (GDS_stats,
236 gettext_noop
237 ("# Invalid RESULTS found in datacache"), 1,
238 GNUNET_NO);
239 break;
240 case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
241 GNUNET_STATISTICS_update (GDS_stats,
242 gettext_noop
243 ("# Irrelevant RESULTS found in datacache"), 1,
244 GNUNET_NO);
245 break;
246 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
247 GNUNET_break (0);
248 break;
249 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
250 GNUNET_break_op (0);
251 return GNUNET_SYSERR;
252 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
253 GNUNET_STATISTICS_update (GDS_stats,
254 gettext_noop
255 ("# Unsupported RESULTS found in datacache"), 1,
256 GNUNET_NO);
257 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
258 _("Unsupported block type (%u) in local response!\n"), type);
259 break;
260 }
261
262 return (eval == GNUNET_BLOCK_EVALUATION_OK_LAST) ? GNUNET_NO : GNUNET_OK;
263}
264
265
266/**
267 * Handle a GET request we've received from another peer.
268 *
269 * @param trail_id trail identifying where to send the result to, NULL for us
270 * @param options routing options (to be passed along)
271 * @param key the query
272 * @param type requested data type
273 * @param xquery extended query
274 * @param xquery_size number of bytes in @a xquery
275 * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL
276 * @param reply_bf_mutator mutation value for @a reply_bf
277 * @return evaluation result for the local replies
278 */
279enum GNUNET_BLOCK_EvaluationResult
280GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *trail_id,
281 enum GNUNET_DHT_RouteOption options,
282 const struct GNUNET_HashCode *key,
283 enum GNUNET_BLOCK_Type type,
284 const void *xquery,
285 size_t xquery_size,
286 struct GNUNET_CONTAINER_BloomFilter **reply_bf,
287 uint32_t reply_bf_mutator)
288{
289 struct GetRequestContext ctx;
290 unsigned int r;
291
292 if (NULL == datacache)
293 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
294 GNUNET_STATISTICS_update (GDS_stats,
295 gettext_noop ("# GET requests given to datacache"),
296 1, GNUNET_NO);
297 ctx.eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
298 ctx.trail_id = trail_id;
299 ctx.options = options;
300 ctx.key = *key;
301 ctx.xquery = xquery;
302 ctx.xquery_size = xquery_size;
303 ctx.reply_bf = reply_bf;
304 ctx.reply_bf_mutator = reply_bf_mutator;
305 r = GNUNET_DATACACHE_get (datacache,
306 key,
307 type,
308 &datacache_get_iterator,
309 &ctx);
310 DEBUG ("DATACACHE_GET for key %s completed (%d). %u results found.\n",
311 GNUNET_h2s (key),
312 ctx.eval,
313 r);
314 return ctx.eval;
315}
316
317
318/**
319 * Function called with a random element from the datacache.
320 * Stores the key in the closure.
321 *
322 * @param cls a `struct GNUNET_HashCode *`, where to store the @a key
323 * @param key key for the content
324 * @param data_size number of bytes in @a data
325 * @param data content stored
326 * @param type type of the content
327 * @param exp when will the content expire?
328 * @param path_info_len number of entries in @a path_info
329 * @param path_info a path through the network
330 * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort
331 */
332static int
333datacache_random_iterator (void *cls,
334 const struct GNUNET_HashCode *key,
335 size_t data_size,
336 const char *data,
337 enum GNUNET_BLOCK_Type type,
338 struct GNUNET_TIME_Absolute exp,
339 unsigned int path_info_len,
340 const struct GNUNET_PeerIdentity *path_info)
341{
342 struct GNUNET_HashCode *dest = cls;
343
344 *dest = *key;
345 return GNUNET_OK; /* should actually not matter which we return */
346}
347
348
349/**
350 * Obtain a random key from the datacache.
351 * Used by Whanau for load-balancing.
352 *
353 * @param[out] key where to store the key of a random element,
354 * randomized by PRNG if datacache is empty
355 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty
356 */
357int
358GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key)
359{
360 if (0 ==
361 GNUNET_DATACACHE_get_random (datacache,
362 &datacache_random_iterator,
363 key))
364 {
365 /* randomize key in this case */
366 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE,
367 key);
368 return GNUNET_SYSERR;
369 }
370 return GNUNET_OK;
371}
372
373
374/**
375 * Iterator for local get request results,
376 *
377 * @param cls closure with the `struct GNUNET_HashCode *` with the trail ID
378 * @param key the key this data is stored under
379 * @param size the size of the data identified by key
380 * @param data the actual data
381 * @param type the type of the data
382 * @param exp when does this value expire?
383 * @param put_path_length number of peers in @a put_path
384 * @param put_path path the reply took on put
385 * @return #GNUNET_OK to continue iteration, anything else
386 * to stop iteration.
387 */
388static int
389datacache_get_successors_iterator (void *cls,
390 const struct GNUNET_HashCode *key,
391 size_t size,
392 const char *data,
393 enum GNUNET_BLOCK_Type type,
394 struct GNUNET_TIME_Absolute exp,
395 unsigned int put_path_length,
396 const struct GNUNET_PeerIdentity *put_path)
397{
398 const struct GNUNET_HashCode *trail_id = cls;
399
400 /* NOTE: The datacache currently does not store the RO from
401 the original 'put', so we don't know the 'correct' option
402 at this point anymore. Thus, we conservatively assume
403 that recording is desired (for now). */
404 GDS_NEIGHBOURS_send_get_result (trail_id,
405 GNUNET_DHT_RO_RECORD_ROUTE,
406 key,
407 type,
408 put_path_length, put_path,
409 exp,
410 data,
411 size);
412 return GNUNET_OK;
413}
414
415
416/**
417 * Handle a request for data close to a key that we have received from
418 * another peer.
419 *
420 * @param trail_id trail where the reply needs to be send to
421 * @param key the location at which the peer is looking for data that is close
422 */
423void
424GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *trail_id,
425 const struct GNUNET_HashCode *key)
426{
427 (void) GNUNET_DATACACHE_get_closest (datacache,
428 key,
429 NUM_CLOSEST,
430 &datacache_get_successors_iterator,
431 (void *) trail_id);
432}
433
434
435/**
436 * Initialize datacache subsystem.
437 */
438void
439GDS_DATACACHE_init ()
440{
441 datacache = GNUNET_DATACACHE_create (GDS_cfg, "dhtcache");
442}
443
444
445/**
446 * Shutdown datacache subsystem.
447 */
448void
449GDS_DATACACHE_done ()
450{
451 if (NULL != datacache)
452 {
453 GNUNET_DATACACHE_destroy (datacache);
454 datacache = NULL;
455 }
456}
457
458
459/* end of gnunet-service-wdht_datacache.c */