aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht_datacache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dht/gnunet-service-dht_datacache.c')
-rw-r--r--src/dht/gnunet-service-dht_datacache.c388
1 files changed, 197 insertions, 191 deletions
diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c
index e52dc27bf..41b7a3a2b 100644
--- a/src/dht/gnunet-service-dht_datacache.c
+++ b/src/dht/gnunet-service-dht_datacache.c
@@ -30,7 +30,7 @@
30#include "gnunet-service-dht_routing.h" 30#include "gnunet-service-dht_routing.h"
31#include "gnunet-service-dht.h" 31#include "gnunet-service-dht.h"
32 32
33#define LOG(kind, ...) GNUNET_log_from(kind, "dht-dhtcache", __VA_ARGS__) 33#define LOG(kind, ...) GNUNET_log_from (kind, "dht-dhtcache", __VA_ARGS__)
34 34
35/** 35/**
36 * How many "closest" results to we return for migration when 36 * How many "closest" results to we return for migration when
@@ -57,55 +57,56 @@ static struct GNUNET_DATACACHE_Handle *datacache;
57 * @param data application payload data 57 * @param data application payload data
58 */ 58 */
59void 59void
60GDS_DATACACHE_handle_put(struct GNUNET_TIME_Absolute expiration, 60GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
61 const struct GNUNET_HashCode *key, 61 const struct GNUNET_HashCode *key,
62 unsigned int put_path_length, 62 unsigned int put_path_length,
63 const struct GNUNET_PeerIdentity *put_path, 63 const struct GNUNET_PeerIdentity *put_path,
64 enum GNUNET_BLOCK_Type type, 64 enum GNUNET_BLOCK_Type type,
65 size_t data_size, 65 size_t data_size,
66 const void *data) 66 const void *data)
67{ 67{
68 int r; 68 int r;
69 69
70 if (NULL == datacache) 70 if (NULL == datacache)
71 { 71 {
72 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 72 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
73 _("%s request received, but have no datacache!\n"), "PUT"); 73 _ ("%s request received, but have no datacache!\n"), "PUT");
74 return; 74 return;
75 } 75 }
76 if (data_size >= GNUNET_MAX_MESSAGE_SIZE) 76 if (data_size >= GNUNET_MAX_MESSAGE_SIZE)
77 { 77 {
78 GNUNET_break(0); 78 GNUNET_break (0);
79 return; 79 return;
80 } 80 }
81 /* Put size is actual data size plus struct overhead plus path length (if any) */ 81 /* Put size is actual data size plus struct overhead plus path length (if any) */
82 GNUNET_STATISTICS_update(GDS_stats, 82 GNUNET_STATISTICS_update (GDS_stats,
83 gettext_noop("# ITEMS stored in datacache"), 83 gettext_noop ("# ITEMS stored in datacache"),
84 1, 84 1,
85 GNUNET_NO); 85 GNUNET_NO);
86 r = GNUNET_DATACACHE_put(datacache, 86 r = GNUNET_DATACACHE_put (datacache,
87 key, 87 key,
88 GNUNET_CRYPTO_hash_matching_bits(key, 88 GNUNET_CRYPTO_hash_matching_bits (key,
89 &my_identity_hash), 89 &my_identity_hash),
90 data_size, 90 data_size,
91 data, 91 data,
92 type, 92 type,
93 expiration, 93 expiration,
94 put_path_length, 94 put_path_length,
95 put_path); 95 put_path);
96 LOG(GNUNET_ERROR_TYPE_DEBUG, 96 LOG (GNUNET_ERROR_TYPE_DEBUG,
97 "DATACACHE PUT for key %s [%u] completed (%d) after %u hops\n", 97 "DATACACHE PUT for key %s [%u] completed (%d) after %u hops\n",
98 GNUNET_h2s(key), 98 GNUNET_h2s (key),
99 data_size, 99 data_size,
100 r, 100 r,
101 put_path_length); 101 put_path_length);
102} 102}
103 103
104 104
105/** 105/**
106 * Context containing information about a GET request. 106 * Context containing information about a GET request.
107 */ 107 */
108struct GetRequestContext { 108struct GetRequestContext
109{
109 /** 110 /**
110 * extended query (see gnunet_block_lib.h). 111 * extended query (see gnunet_block_lib.h).
111 */ 112 */
@@ -158,100 +159,104 @@ struct GetRequestContext {
158 * to stop iteration. 159 * to stop iteration.
159 */ 160 */
160static int 161static int
161datacache_get_iterator(void *cls, 162datacache_get_iterator (void *cls,
162 const struct GNUNET_HashCode *key, 163 const struct GNUNET_HashCode *key,
163 size_t data_size, 164 size_t data_size,
164 const char *data, 165 const char *data,
165 enum GNUNET_BLOCK_Type type, 166 enum GNUNET_BLOCK_Type type,
166 struct GNUNET_TIME_Absolute exp, 167 struct GNUNET_TIME_Absolute exp,
167 unsigned int put_path_length, 168 unsigned int put_path_length,
168 const struct GNUNET_PeerIdentity *put_path) 169 const struct GNUNET_PeerIdentity *put_path)
169{ 170{
170 static char non_null; 171 static char non_null;
171 struct GetRequestContext *ctx = cls; 172 struct GetRequestContext *ctx = cls;
172 enum GNUNET_BLOCK_EvaluationResult eval; 173 enum GNUNET_BLOCK_EvaluationResult eval;
173 174
174 if (0 == GNUNET_TIME_absolute_get_remaining(exp).rel_value_us) 175 if (0 == GNUNET_TIME_absolute_get_remaining (exp).rel_value_us)
175 { 176 {
176 GNUNET_break(0); /* why does datacache return expired values? */ 177 GNUNET_break (0); /* why does datacache return expired values? */
177 return GNUNET_OK; /* skip expired record */ 178 return GNUNET_OK; /* skip expired record */
178 } 179 }
179 if ((NULL == data) && 180 if ((NULL == data) &&
180 (0 == data_size)) 181 (0 == data_size))
181 data = &non_null; /* point anywhere, but not to NULL */ 182 data = &non_null; /* point anywhere, but not to NULL */
182 183
183 eval 184 eval
184 = GNUNET_BLOCK_evaluate(GDS_block_context, 185 = GNUNET_BLOCK_evaluate (GDS_block_context,
185 type, 186 type,
186 ctx->bg, 187 ctx->bg,
187 GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO, 188 GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO,
188 key, 189 key,
189 ctx->xquery, 190 ctx->xquery,
190 ctx->xquery_size, 191 ctx->xquery_size,
191 data, 192 data,
192 data_size); 193 data_size);
193 LOG(GNUNET_ERROR_TYPE_DEBUG, 194 LOG (GNUNET_ERROR_TYPE_DEBUG,
194 "Found reply for query %s in datacache, evaluation result is %d\n", 195 "Found reply for query %s in datacache, evaluation result is %d\n",
195 GNUNET_h2s(key), 196 GNUNET_h2s (key),
196 (int)eval); 197 (int) eval);
197 ctx->eval = eval; 198 ctx->eval = eval;
198 switch (eval) 199 switch (eval)
199 { 200 {
200 case GNUNET_BLOCK_EVALUATION_OK_MORE: 201 case GNUNET_BLOCK_EVALUATION_OK_MORE:
201 case GNUNET_BLOCK_EVALUATION_OK_LAST: 202 case GNUNET_BLOCK_EVALUATION_OK_LAST:
202 /* forward to local clients */ 203 /* forward to local clients */
203 GNUNET_STATISTICS_update(GDS_stats, 204 GNUNET_STATISTICS_update (GDS_stats,
204 gettext_noop 205 gettext_noop
205 ("# Good RESULTS found in datacache"), 1, 206 ("# Good RESULTS found in datacache"), 1,
206 GNUNET_NO); 207 GNUNET_NO);
207 ctx->gc(ctx->gc_cls, 208 ctx->gc (ctx->gc_cls,
208 type, 209 type,
209 exp, 210 exp,
210 key, 211 key,
211 put_path_length, put_path, 212 put_path_length, put_path,
212 0, NULL, 213 0, NULL,
213 data, data_size); 214 data, data_size);
214 break; 215 break;
215 216
216 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: 217 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
217 GNUNET_STATISTICS_update(GDS_stats, 218 GNUNET_STATISTICS_update (GDS_stats,
218 gettext_noop("# Duplicate RESULTS found in datacache"), 219 gettext_noop (
219 1, 220 "# Duplicate RESULTS found in datacache"),
220 GNUNET_NO); 221 1,
221 break; 222 GNUNET_NO);
222 223 break;
223 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: 224
224 GNUNET_STATISTICS_update(GDS_stats, 225 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
225 gettext_noop("# Invalid RESULTS found in datacache"), 226 GNUNET_STATISTICS_update (GDS_stats,
226 1, 227 gettext_noop (
227 GNUNET_NO); 228 "# Invalid RESULTS found in datacache"),
228 break; 229 1,
229 230 GNUNET_NO);
230 case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: 231 break;
231 GNUNET_STATISTICS_update(GDS_stats, 232
232 gettext_noop("# Irrelevant RESULTS found in datacache"), 233 case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
233 1, 234 GNUNET_STATISTICS_update (GDS_stats,
234 GNUNET_NO); 235 gettext_noop (
235 break; 236 "# Irrelevant RESULTS found in datacache"),
236 237 1,
237 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: 238 GNUNET_NO);
238 GNUNET_break(0); 239 break;
239 break; 240
240 241 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
241 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: 242 GNUNET_break (0);
242 GNUNET_break_op(0); 243 break;
243 return GNUNET_SYSERR; 244
244 245 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
245 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: 246 GNUNET_break_op (0);
246 GNUNET_STATISTICS_update(GDS_stats, 247 return GNUNET_SYSERR;
247 gettext_noop("# Unsupported RESULTS found in datacache"), 248
248 1, 249 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
249 GNUNET_NO); 250 GNUNET_STATISTICS_update (GDS_stats,
250 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 251 gettext_noop (
251 _("Unsupported block type (%u) in local response!\n"), 252 "# Unsupported RESULTS found in datacache"),
252 type); 253 1,
253 break; 254 GNUNET_NO);
254 } 255 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
256 _ ("Unsupported block type (%u) in local response!\n"),
257 type);
258 break;
259 }
255 return (eval == GNUNET_BLOCK_EVALUATION_OK_LAST) ? GNUNET_NO : GNUNET_OK; 260 return (eval == GNUNET_BLOCK_EVALUATION_OK_LAST) ? GNUNET_NO : GNUNET_OK;
256} 261}
257 262
@@ -269,23 +274,23 @@ datacache_get_iterator(void *cls,
269 * @return evaluation result for the local replies 274 * @return evaluation result for the local replies
270 */ 275 */
271enum GNUNET_BLOCK_EvaluationResult 276enum GNUNET_BLOCK_EvaluationResult
272GDS_DATACACHE_handle_get(const struct GNUNET_HashCode *key, 277GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key,
273 enum GNUNET_BLOCK_Type type, 278 enum GNUNET_BLOCK_Type type,
274 const void *xquery, 279 const void *xquery,
275 size_t xquery_size, 280 size_t xquery_size,
276 struct GNUNET_BLOCK_Group *bg, 281 struct GNUNET_BLOCK_Group *bg,
277 GDS_DATACACHE_GetCallback gc, 282 GDS_DATACACHE_GetCallback gc,
278 void *gc_cls) 283 void *gc_cls)
279{ 284{
280 struct GetRequestContext ctx; 285 struct GetRequestContext ctx;
281 unsigned int r; 286 unsigned int r;
282 287
283 if (NULL == datacache) 288 if (NULL == datacache)
284 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; 289 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
285 GNUNET_STATISTICS_update(GDS_stats, 290 GNUNET_STATISTICS_update (GDS_stats,
286 gettext_noop("# GET requests given to datacache"), 291 gettext_noop ("# GET requests given to datacache"),
287 1, 292 1,
288 GNUNET_NO); 293 GNUNET_NO);
289 ctx.eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID; 294 ctx.eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
290 ctx.key = *key; 295 ctx.key = *key;
291 ctx.xquery = xquery; 296 ctx.xquery = xquery;
@@ -293,16 +298,16 @@ GDS_DATACACHE_handle_get(const struct GNUNET_HashCode *key,
293 ctx.bg = bg; 298 ctx.bg = bg;
294 ctx.gc = gc; 299 ctx.gc = gc;
295 ctx.gc_cls = gc_cls; 300 ctx.gc_cls = gc_cls;
296 r = GNUNET_DATACACHE_get(datacache, 301 r = GNUNET_DATACACHE_get (datacache,
297 key, 302 key,
298 type, 303 type,
299 &datacache_get_iterator, 304 &datacache_get_iterator,
300 &ctx); 305 &ctx);
301 LOG(GNUNET_ERROR_TYPE_DEBUG, 306 LOG (GNUNET_ERROR_TYPE_DEBUG,
302 "DATACACHE GET for key %s completed (%d). %u results found.\n", 307 "DATACACHE GET for key %s completed (%d). %u results found.\n",
303 GNUNET_h2s(key), 308 GNUNET_h2s (key),
304 ctx.eval, 309 ctx.eval,
305 r); 310 r);
306 return ctx.eval; 311 return ctx.eval;
307} 312}
308 313
@@ -322,14 +327,14 @@ GDS_DATACACHE_handle_get(const struct GNUNET_HashCode *key,
322 * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort 327 * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort
323 */ 328 */
324static int 329static int
325datacache_random_iterator(void *cls, 330datacache_random_iterator (void *cls,
326 const struct GNUNET_HashCode *key, 331 const struct GNUNET_HashCode *key,
327 size_t data_size, 332 size_t data_size,
328 const char *data, 333 const char *data,
329 enum GNUNET_BLOCK_Type type, 334 enum GNUNET_BLOCK_Type type,
330 struct GNUNET_TIME_Absolute exp, 335 struct GNUNET_TIME_Absolute exp,
331 unsigned int path_info_len, 336 unsigned int path_info_len,
332 const struct GNUNET_PeerIdentity *path_info) 337 const struct GNUNET_PeerIdentity *path_info)
333{ 338{
334 struct GNUNET_HashCode *dest = cls; 339 struct GNUNET_HashCode *dest = cls;
335 340
@@ -347,18 +352,18 @@ datacache_random_iterator(void *cls,
347 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty 352 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty
348 */ 353 */
349int 354int
350GDS_DATACACHE_get_random_key(struct GNUNET_HashCode *key) 355GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key)
351{ 356{
352 if (0 == 357 if (0 ==
353 GNUNET_DATACACHE_get_random(datacache, 358 GNUNET_DATACACHE_get_random (datacache,
354 &datacache_random_iterator, 359 &datacache_random_iterator,
355 key)) 360 key))
356 { 361 {
357 /* randomize key in this case */ 362 /* randomize key in this case */
358 GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_NONCE, 363 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE,
359 key); 364 key);
360 return GNUNET_SYSERR; 365 return GNUNET_SYSERR;
361 } 366 }
362 return GNUNET_OK; 367 return GNUNET_OK;
363} 368}
364 369
@@ -366,7 +371,8 @@ GDS_DATACACHE_get_random_key(struct GNUNET_HashCode *key)
366/** 371/**
367 * Closure for #datacache_get_successors_iterator(). 372 * Closure for #datacache_get_successors_iterator().
368 */ 373 */
369struct SuccContext { 374struct SuccContext
375{
370 /** 376 /**
371 * Function to call on the result 377 * Function to call on the result
372 */ 378 */
@@ -394,14 +400,14 @@ struct SuccContext {
394 * to stop iteration. 400 * to stop iteration.
395 */ 401 */
396static int 402static int
397datacache_get_successors_iterator(void *cls, 403datacache_get_successors_iterator (void *cls,
398 const struct GNUNET_HashCode *key, 404 const struct GNUNET_HashCode *key,
399 size_t size, 405 size_t size,
400 const char *data, 406 const char *data,
401 enum GNUNET_BLOCK_Type type, 407 enum GNUNET_BLOCK_Type type,
402 struct GNUNET_TIME_Absolute exp, 408 struct GNUNET_TIME_Absolute exp,
403 unsigned int put_path_length, 409 unsigned int put_path_length,
404 const struct GNUNET_PeerIdentity *put_path) 410 const struct GNUNET_PeerIdentity *put_path)
405{ 411{
406 const struct SuccContext *sc = cls; 412 const struct SuccContext *sc = cls;
407 413
@@ -409,14 +415,14 @@ datacache_get_successors_iterator(void *cls,
409 the original 'put', so we don't know the 'correct' option 415 the original 'put', so we don't know the 'correct' option
410 at this point anymore. Thus, we conservatively assume 416 at this point anymore. Thus, we conservatively assume
411 that recording is desired (for now). */ 417 that recording is desired (for now). */
412 sc->cb(sc->cb_cls, 418 sc->cb (sc->cb_cls,
413 GNUNET_DHT_RO_RECORD_ROUTE, 419 GNUNET_DHT_RO_RECORD_ROUTE,
414 key, 420 key,
415 type, 421 type,
416 put_path_length, put_path, 422 put_path_length, put_path,
417 exp, 423 exp,
418 data, 424 data,
419 size); 425 size);
420 return GNUNET_OK; 426 return GNUNET_OK;
421} 427}
422 428
@@ -430,19 +436,19 @@ datacache_get_successors_iterator(void *cls,
430 * @param cb_cls closure for @a cb 436 * @param cb_cls closure for @a cb
431 */ 437 */
432void 438void
433GDS_DATACACHE_get_successors(const struct GNUNET_HashCode *key, 439GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *key,
434 GDS_DATACACHE_SuccessorCallback cb, 440 GDS_DATACACHE_SuccessorCallback cb,
435 void *cb_cls) 441 void *cb_cls)
436{ 442{
437 struct SuccContext sc; 443 struct SuccContext sc;
438 444
439 sc.cb = cb; 445 sc.cb = cb;
440 sc.cb_cls = cb_cls; 446 sc.cb_cls = cb_cls;
441 (void)GNUNET_DATACACHE_get_closest(datacache, 447 (void) GNUNET_DATACACHE_get_closest (datacache,
442 key, 448 key,
443 NUM_CLOSEST, 449 NUM_CLOSEST,
444 &datacache_get_successors_iterator, 450 &datacache_get_successors_iterator,
445 &sc); 451 &sc);
446} 452}
447 453
448 454
@@ -450,9 +456,9 @@ GDS_DATACACHE_get_successors(const struct GNUNET_HashCode *key,
450 * Initialize datacache subsystem. 456 * Initialize datacache subsystem.
451 */ 457 */
452void 458void
453GDS_DATACACHE_init() 459GDS_DATACACHE_init ()
454{ 460{
455 datacache = GNUNET_DATACACHE_create(GDS_cfg, "dhtcache"); 461 datacache = GNUNET_DATACACHE_create (GDS_cfg, "dhtcache");
456} 462}
457 463
458 464
@@ -460,13 +466,13 @@ GDS_DATACACHE_init()
460 * Shutdown datacache subsystem. 466 * Shutdown datacache subsystem.
461 */ 467 */
462void 468void
463GDS_DATACACHE_done() 469GDS_DATACACHE_done ()
464{ 470{
465 if (NULL != datacache) 471 if (NULL != datacache)
466 { 472 {
467 GNUNET_DATACACHE_destroy(datacache); 473 GNUNET_DATACACHE_destroy (datacache);
468 datacache = NULL; 474 datacache = NULL;
469 } 475 }
470} 476}
471 477
472 478