aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-05-30 18:47:17 +0200
committerChristian Grothoff <christian@grothoff.org>2018-05-30 18:47:17 +0200
commitadef29b3ed00afd42669ae35a73951c59f08a41b (patch)
treec8d6c7f60716c551b587aed7a1efe0d6e756833f
parentf5a18b7466f342ac9624adcdb65f104aef8ecb5e (diff)
downloadgnunet-adef29b3ed00afd42669ae35a73951c59f08a41b.tar.gz
gnunet-adef29b3ed00afd42669ae35a73951c59f08a41b.zip
add proximity considerations to datacache
-rw-r--r--src/datacache/datacache.c3
-rw-r--r--src/datacache/plugin_datacache_heap.c117
-rw-r--r--src/datacache/plugin_datacache_postgres.c2
-rw-r--r--src/datacache/plugin_datacache_sqlite.c61
-rw-r--r--src/datacache/plugin_datacache_template.c2
-rw-r--r--src/datacache/test_datacache.c10
-rw-r--r--src/datacache/test_datacache_quota.c10
-rw-r--r--src/dht/gnunet-dht-get.c22
-rw-r--r--src/dht/gnunet-dht-monitor.c27
-rw-r--r--src/dht/gnunet-service-dht_datacache.c6
-rw-r--r--src/dht/gnunet-service-dht_neighbours.c12
-rw-r--r--src/dht/gnunet-service-dht_neighbours.h16
-rw-r--r--src/gns/gnunet-gns-benchmark.c2
-rw-r--r--src/gns/gnunet-service-gns_resolver.c2
-rw-r--r--src/include/gnunet_datacache_lib.h2
-rw-r--r--src/include/gnunet_datacache_plugin.h2
16 files changed, 245 insertions, 51 deletions
diff --git a/src/datacache/datacache.c b/src/datacache/datacache.c
index 0646019bd..18a2ed228 100644
--- a/src/datacache/datacache.c
+++ b/src/datacache/datacache.c
@@ -260,6 +260,7 @@ GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h)
260 * 260 *
261 * @param h handle to the datacache 261 * @param h handle to the datacache
262 * @param key key to store data under 262 * @param key key to store data under
263 * @param am_closest are we the closest peer?
263 * @param data_size number of bytes in @a data 264 * @param data_size number of bytes in @a data
264 * @param data data to store 265 * @param data data to store
265 * @param type type of the value 266 * @param type type of the value
@@ -271,6 +272,7 @@ GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h)
271int 272int
272GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h, 273GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
273 const struct GNUNET_HashCode *key, 274 const struct GNUNET_HashCode *key,
275 int am_closest,
274 size_t data_size, 276 size_t data_size,
275 const char *data, 277 const char *data,
276 enum GNUNET_BLOCK_Type type, 278 enum GNUNET_BLOCK_Type type,
@@ -282,6 +284,7 @@ GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
282 284
283 used = h->api->put (h->api->cls, 285 used = h->api->put (h->api->cls,
284 key, 286 key,
287 am_closest,
285 data_size, 288 data_size,
286 data, 289 data,
287 type, 290 type,
diff --git a/src/datacache/plugin_datacache_heap.c b/src/datacache/plugin_datacache_heap.c
index 49e60bca1..c32edf8e2 100644
--- a/src/datacache/plugin_datacache_heap.c
+++ b/src/datacache/plugin_datacache_heap.c
@@ -53,6 +53,11 @@ struct Plugin
53 */ 53 */
54 struct GNUNET_CONTAINER_Heap *heap; 54 struct GNUNET_CONTAINER_Heap *heap;
55 55
56 /**
57 * Heap from the plugin for "closest" values.
58 */
59 struct GNUNET_CONTAINER_Heap *cheap;
60
56}; 61};
57 62
58 63
@@ -92,6 +97,11 @@ struct Value
92 unsigned int path_info_len; 97 unsigned int path_info_len;
93 98
94 /** 99 /**
100 * Am I the closest peer? Determines which heap we are in!
101 */
102 int am_closest;
103
104 /**
95 * Type of the block. 105 * Type of the block.
96 */ 106 */
97 enum GNUNET_BLOCK_Type type; 107 enum GNUNET_BLOCK_Type type;
@@ -118,6 +128,11 @@ struct PutContext
118 const char *data; 128 const char *data;
119 129
120 /** 130 /**
131 * Heap from the plugin for "closest" values.
132 */
133 struct GNUNET_CONTAINER_Heap *cheap;
134
135 /**
121 * Heap from the plugin. 136 * Heap from the plugin.
122 */ 137 */
123 struct GNUNET_CONTAINER_Heap *heap; 138 struct GNUNET_CONTAINER_Heap *heap;
@@ -168,7 +183,9 @@ put_cb (void *cls,
168 183
169 if ( (val->size == put_ctx->size) && 184 if ( (val->size == put_ctx->size) &&
170 (val->type == put_ctx->type) && 185 (val->type == put_ctx->type) &&
171 (0 == memcmp (&val[1], put_ctx->data, put_ctx->size)) ) 186 (0 == memcmp (&val[1],
187 put_ctx->data,
188 put_ctx->size)) )
172 { 189 {
173 put_ctx->found = GNUNET_YES; 190 put_ctx->found = GNUNET_YES;
174 val->discard_time = GNUNET_TIME_absolute_max (val->discard_time, 191 val->discard_time = GNUNET_TIME_absolute_max (val->discard_time,
@@ -199,6 +216,7 @@ put_cb (void *cls,
199 * 216 *
200 * @param cls closure (our `struct Plugin`) 217 * @param cls closure (our `struct Plugin`)
201 * @param key key to store data under 218 * @param key key to store data under
219 * @param am_closest are we the closest peer?
202 * @param size number of bytes in @a data 220 * @param size number of bytes in @a data
203 * @param data data to store 221 * @param data data to store
204 * @param type type of the value 222 * @param type type of the value
@@ -210,6 +228,7 @@ put_cb (void *cls,
210static ssize_t 228static ssize_t
211heap_plugin_put (void *cls, 229heap_plugin_put (void *cls,
212 const struct GNUNET_HashCode *key, 230 const struct GNUNET_HashCode *key,
231 int am_closest,
213 size_t size, 232 size_t size,
214 const char *data, 233 const char *data,
215 enum GNUNET_BLOCK_Type type, 234 enum GNUNET_BLOCK_Type type,
@@ -223,6 +242,7 @@ heap_plugin_put (void *cls,
223 242
224 put_ctx.found = GNUNET_NO; 243 put_ctx.found = GNUNET_NO;
225 put_ctx.heap = plugin->heap; 244 put_ctx.heap = plugin->heap;
245 put_ctx.cheap = plugin->cheap;
226 put_ctx.data = data; 246 put_ctx.data = data;
227 put_ctx.size = size; 247 put_ctx.size = size;
228 put_ctx.path_info = path_info; 248 put_ctx.path_info = path_info;
@@ -241,17 +261,20 @@ heap_plugin_put (void *cls,
241 val->type = type; 261 val->type = type;
242 val->discard_time = discard_time; 262 val->discard_time = discard_time;
243 val->size = size; 263 val->size = size;
264 val->am_closest = am_closest;
244 GNUNET_array_grow (val->path_info, 265 GNUNET_array_grow (val->path_info,
245 val->path_info_len, 266 val->path_info_len,
246 path_info_len); 267 path_info_len);
247 GNUNET_memcpy (val->path_info, 268 GNUNET_memcpy (val->path_info,
248 path_info, 269 path_info,
249 path_info_len * sizeof (struct GNUNET_PeerIdentity)); 270 path_info_len * sizeof (struct GNUNET_PeerIdentity));
250 (void) GNUNET_CONTAINER_multihashmap_put (plugin->map, 271 (void) GNUNET_CONTAINER_multihashmap_put (plugin->map,
251 &val->key, 272 &val->key,
252 val, 273 val,
253 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 274 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
254 val->hn = GNUNET_CONTAINER_heap_insert (plugin->heap, 275 val->hn = GNUNET_CONTAINER_heap_insert (am_closest
276 ? plugin->cheap
277 : plugin->heap,
255 val, 278 val,
256 val->discard_time.abs_value_us); 279 val->discard_time.abs_value_us);
257 return size + OVERHEAD; 280 return size + OVERHEAD;
@@ -371,6 +394,8 @@ heap_plugin_del (void *cls)
371 394
372 val = GNUNET_CONTAINER_heap_remove_root (plugin->heap); 395 val = GNUNET_CONTAINER_heap_remove_root (plugin->heap);
373 if (NULL == val) 396 if (NULL == val)
397 val = GNUNET_CONTAINER_heap_remove_root (plugin->cheap);
398 if (NULL == val)
374 return GNUNET_SYSERR; 399 return GNUNET_SYSERR;
375 GNUNET_assert (GNUNET_YES == 400 GNUNET_assert (GNUNET_YES ==
376 GNUNET_CONTAINER_multihashmap_remove (plugin->map, 401 GNUNET_CONTAINER_multihashmap_remove (plugin->map,
@@ -413,6 +438,53 @@ heap_plugin_get_random (void *cls,
413 438
414 439
415/** 440/**
441 * Closure for #find_closest().
442 */
443struct GetClosestContext
444{
445 struct Value **values;
446
447 unsigned int num_results;
448
449 const struct GNUNET_HashCode *key;
450};
451
452
453static int
454find_closest (void *cls,
455 const struct GNUNET_HashCode *key,
456 void *value)
457{
458 struct GetClosestContext *gcc = cls;
459 struct Value *val = value;
460 unsigned int j;
461
462 if (1 != GNUNET_CRYPTO_hash_cmp (key,
463 gcc->key))
464 return GNUNET_OK; /* useless */
465 j = gcc->num_results;
466 for (unsigned int i=0;i<gcc->num_results;i++)
467 {
468 if (NULL == gcc->values[i])
469 {
470 j = i;
471 break;
472 }
473 if (1 == GNUNET_CRYPTO_hash_cmp (&gcc->values[i]->key,
474 key))
475 {
476 j = i;
477 break;
478 }
479 }
480 if (j == gcc->num_results)
481 return GNUNET_OK;
482 gcc->values[j] = val;
483 return GNUNET_OK;
484}
485
486
487/**
416 * Iterate over the results that are "close" to a particular key in 488 * Iterate over the results that are "close" to a particular key in
417 * the datacache. "close" is defined as numerically larger than @a 489 * the datacache. "close" is defined as numerically larger than @a
418 * key (when interpreted as a circular address space), with small 490 * key (when interpreted as a circular address space), with small
@@ -432,8 +504,30 @@ heap_plugin_get_closest (void *cls,
432 GNUNET_DATACACHE_Iterator iter, 504 GNUNET_DATACACHE_Iterator iter,
433 void *iter_cls) 505 void *iter_cls)
434{ 506{
435 GNUNET_break (0); // not implemented! 507 struct Plugin *plugin = cls;
436 return 0; 508 struct Value *values[num_results];
509 struct GetClosestContext gcc = {
510 .values = values,
511 .num_results = num_results,
512 .key = key
513 };
514 GNUNET_CONTAINER_multihashmap_iterate (plugin->map,
515 &find_closest,
516 &gcc);
517 for (unsigned int i=0;i<num_results;i++)
518 {
519 if (NULL == values[i])
520 return i;
521 iter (iter_cls,
522 &values[i]->key,
523 values[i]->size,
524 (void *) &values[i][1],
525 values[i]->type,
526 values[i]->discard_time,
527 values[i]->path_info_len,
528 values[i]->path_info);
529 }
530 return num_results;
437} 531}
438 532
439 533
@@ -454,6 +548,7 @@ libgnunet_plugin_datacache_heap_init (void *cls)
454 plugin->map = GNUNET_CONTAINER_multihashmap_create (1024, /* FIXME: base on quota! */ 548 plugin->map = GNUNET_CONTAINER_multihashmap_create (1024, /* FIXME: base on quota! */
455 GNUNET_YES); 549 GNUNET_YES);
456 plugin->heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 550 plugin->heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
551 plugin->cheap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
457 plugin->env = env; 552 plugin->env = env;
458 api = GNUNET_new (struct GNUNET_DATACACHE_PluginFunctions); 553 api = GNUNET_new (struct GNUNET_DATACACHE_PluginFunctions);
459 api->cls = plugin; 554 api->cls = plugin;
@@ -490,7 +585,17 @@ libgnunet_plugin_datacache_heap_done (void *cls)
490 GNUNET_free_non_null (val->path_info); 585 GNUNET_free_non_null (val->path_info);
491 GNUNET_free (val); 586 GNUNET_free (val);
492 } 587 }
588 while (NULL != (val = GNUNET_CONTAINER_heap_remove_root (plugin->cheap)))
589 {
590 GNUNET_assert (GNUNET_YES ==
591 GNUNET_CONTAINER_multihashmap_remove (plugin->map,
592 &val->key,
593 val));
594 GNUNET_free_non_null (val->path_info);
595 GNUNET_free (val);
596 }
493 GNUNET_CONTAINER_heap_destroy (plugin->heap); 597 GNUNET_CONTAINER_heap_destroy (plugin->heap);
598 GNUNET_CONTAINER_heap_destroy (plugin->cheap);
494 GNUNET_CONTAINER_multihashmap_destroy (plugin->map); 599 GNUNET_CONTAINER_multihashmap_destroy (plugin->map);
495 GNUNET_free (plugin); 600 GNUNET_free (plugin);
496 GNUNET_free (api); 601 GNUNET_free (api);
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c
index 2c233c4c2..c6ccfb210 100644
--- a/src/datacache/plugin_datacache_postgres.c
+++ b/src/datacache/plugin_datacache_postgres.c
@@ -141,6 +141,7 @@ init_connection (struct Plugin *plugin)
141 * 141 *
142 * @param cls closure (our `struct Plugin`) 142 * @param cls closure (our `struct Plugin`)
143 * @param key key to store @a data under 143 * @param key key to store @a data under
144 * @param am_closest are we the closest peer?
144 * @param data_size number of bytes in @a data 145 * @param data_size number of bytes in @a data
145 * @param data data to store 146 * @param data data to store
146 * @param type type of the value 147 * @param type type of the value
@@ -152,6 +153,7 @@ init_connection (struct Plugin *plugin)
152static ssize_t 153static ssize_t
153postgres_plugin_put (void *cls, 154postgres_plugin_put (void *cls,
154 const struct GNUNET_HashCode *key, 155 const struct GNUNET_HashCode *key,
156 int am_closest,
155 size_t data_size, 157 size_t data_size,
156 const char *data, 158 const char *data,
157 enum GNUNET_BLOCK_Type type, 159 enum GNUNET_BLOCK_Type type,
diff --git a/src/datacache/plugin_datacache_sqlite.c b/src/datacache/plugin_datacache_sqlite.c
index 15438b29b..455dcab0b 100644
--- a/src/datacache/plugin_datacache_sqlite.c
+++ b/src/datacache/plugin_datacache_sqlite.c
@@ -38,7 +38,7 @@
38 * How much overhead do we assume per entry in the 38 * How much overhead do we assume per entry in the
39 * datacache? 39 * datacache?
40 */ 40 */
41#define OVERHEAD (sizeof(struct GNUNET_HashCode) + 32) 41#define OVERHEAD (sizeof(struct GNUNET_HashCode) + 36)
42 42
43/** 43/**
44 * Context for all functions in this plugin. 44 * Context for all functions in this plugin.
@@ -150,6 +150,7 @@ sq_prepare (sqlite3 *dbh,
150 * 150 *
151 * @param cls closure (our `struct Plugin`) 151 * @param cls closure (our `struct Plugin`)
152 * @param key key to store @a data under 152 * @param key key to store @a data under
153 * @param am_closest are we the closest peer?
153 * @param size number of bytes in @a data 154 * @param size number of bytes in @a data
154 * @param data data to store 155 * @param data data to store
155 * @param type type of the value 156 * @param type type of the value
@@ -161,6 +162,7 @@ sq_prepare (sqlite3 *dbh,
161static ssize_t 162static ssize_t
162sqlite_plugin_put (void *cls, 163sqlite_plugin_put (void *cls,
163 const struct GNUNET_HashCode *key, 164 const struct GNUNET_HashCode *key,
165 int am_closest,
164 size_t size, 166 size_t size,
165 const char *data, 167 const char *data,
166 enum GNUNET_BLOCK_Type type, 168 enum GNUNET_BLOCK_Type type,
@@ -170,10 +172,12 @@ sqlite_plugin_put (void *cls,
170{ 172{
171 struct Plugin *plugin = cls; 173 struct Plugin *plugin = cls;
172 uint32_t type32 = type; 174 uint32_t type32 = type;
175 uint32_t prox = am_closest;
173 struct GNUNET_SQ_QueryParam params[] = { 176 struct GNUNET_SQ_QueryParam params[] = {
174 GNUNET_SQ_query_param_uint32 (&type32), 177 GNUNET_SQ_query_param_uint32 (&type32),
175 GNUNET_SQ_query_param_absolute_time (&discard_time), 178 GNUNET_SQ_query_param_absolute_time (&discard_time),
176 GNUNET_SQ_query_param_auto_from_type (key), 179 GNUNET_SQ_query_param_auto_from_type (key),
180 GNUNET_SQ_query_param_uint32 (&prox),
177 GNUNET_SQ_query_param_fixed_size (data, size), 181 GNUNET_SQ_query_param_fixed_size (data, size),
178 GNUNET_SQ_query_param_fixed_size (path_info, 182 GNUNET_SQ_query_param_fixed_size (path_info,
179 path_info_len * sizeof (struct GNUNET_PeerIdentity)), 183 path_info_len * sizeof (struct GNUNET_PeerIdentity)),
@@ -386,6 +390,7 @@ sqlite_plugin_del (void *cls)
386 uint64_t rowid; 390 uint64_t rowid;
387 void *data; 391 void *data;
388 size_t dsize; 392 size_t dsize;
393 uint32_t prox;
389 struct GNUNET_HashCode hc; 394 struct GNUNET_HashCode hc;
390 struct GNUNET_SQ_ResultSpec rs[] = { 395 struct GNUNET_SQ_ResultSpec rs[] = {
391 GNUNET_SQ_result_spec_uint64 (&rowid), 396 GNUNET_SQ_result_spec_uint64 (&rowid),
@@ -398,9 +403,26 @@ sqlite_plugin_del (void *cls)
398 GNUNET_SQ_query_param_uint64 (&rowid), 403 GNUNET_SQ_query_param_uint64 (&rowid),
399 GNUNET_SQ_query_param_end 404 GNUNET_SQ_query_param_end
400 }; 405 };
406 struct GNUNET_SQ_QueryParam prox_params[] = {
407 GNUNET_SQ_query_param_uint32 (&prox),
408 GNUNET_SQ_query_param_end
409 };
401 410
402 LOG (GNUNET_ERROR_TYPE_DEBUG, 411 LOG (GNUNET_ERROR_TYPE_DEBUG,
403 "Processing DEL\n"); 412 "Processing DEL\n");
413 prox = GNUNET_NO;
414 again:
415 if (GNUNET_OK !=
416 GNUNET_SQ_bind (plugin->del_select_stmt,
417 prox_params))
418 {
419 LOG_SQLITE (plugin->dbh,
420 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
421 "sqlite3_bind");
422 GNUNET_SQ_reset (plugin->dbh,
423 plugin->del_stmt);
424 return GNUNET_SYSERR;
425 }
404 if (SQLITE_ROW != 426 if (SQLITE_ROW !=
405 sqlite3_step (plugin->del_select_stmt)) 427 sqlite3_step (plugin->del_select_stmt))
406 { 428 {
@@ -409,15 +431,25 @@ sqlite_plugin_del (void *cls)
409 "sqlite3_step"); 431 "sqlite3_step");
410 GNUNET_SQ_reset (plugin->dbh, 432 GNUNET_SQ_reset (plugin->dbh,
411 plugin->del_select_stmt); 433 plugin->del_select_stmt);
434 if (GNUNET_NO == prox)
435 {
436 prox = GNUNET_YES;
437 goto again;
438 }
412 return GNUNET_SYSERR; 439 return GNUNET_SYSERR;
413 } 440 }
414 if (GNUNET_OK != 441 if (GNUNET_OK !=
415 GNUNET_SQ_extract_result (plugin->del_select_stmt, 442 GNUNET_SQ_extract_result (plugin->del_select_stmt,
416 rs)) 443 rs))
417 { 444 {
418 GNUNET_break (0);
419 GNUNET_SQ_reset (plugin->dbh, 445 GNUNET_SQ_reset (plugin->dbh,
420 plugin->del_select_stmt); 446 plugin->del_select_stmt);
447 if (GNUNET_NO == prox)
448 {
449 prox = GNUNET_YES;
450 goto again;
451 }
452 GNUNET_break (0);
421 return GNUNET_SYSERR; 453 return GNUNET_SYSERR;
422 } 454 }
423 GNUNET_SQ_cleanup_result (rs); 455 GNUNET_SQ_cleanup_result (rs);
@@ -709,13 +741,14 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
709 SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3"); 741 SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3");
710 742
711 SQLITE3_EXEC (dbh, 743 SQLITE3_EXEC (dbh,
712 "CREATE TABLE ds090 (" " type INTEGER NOT NULL DEFAULT 0," 744 "CREATE TABLE ds091 (" " type INTEGER NOT NULL DEFAULT 0,"
713 " expire INTEGER NOT NULL DEFAULT 0," 745 " expire INTEGER NOT NULL,"
714 " key BLOB NOT NULL DEFAULT ''," 746 " key BLOB NOT NULL DEFAULT '',"
715 " value BLOB NOT NULL DEFAULT ''," 747 " prox INTEGER NOT NULL,"
748 " value BLOB NOT NULL,"
716 " path BLOB DEFAULT '')"); 749 " path BLOB DEFAULT '')");
717 SQLITE3_EXEC (dbh, "CREATE INDEX idx_hashidx ON ds090 (key,type,expire)"); 750 SQLITE3_EXEC (dbh, "CREATE INDEX idx_hashidx ON ds090 (key,type,expire)");
718 SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire ON ds090 (expire)"); 751 SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire ON ds090 (prox,expire)");
719 plugin = GNUNET_new (struct Plugin); 752 plugin = GNUNET_new (struct Plugin);
720 plugin->env = env; 753 plugin->env = env;
721 plugin->dbh = dbh; 754 plugin->dbh = dbh;
@@ -723,35 +756,35 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
723 756
724 if ( (SQLITE_OK != 757 if ( (SQLITE_OK !=
725 sq_prepare (plugin->dbh, 758 sq_prepare (plugin->dbh,
726 "INSERT INTO ds090 (type, expire, key, value, path) " 759 "INSERT INTO ds091 (type, expire, key, prox, value, path) "
727 "VALUES (?, ?, ?, ?, ?)", 760 "VALUES (?, ?, ?, ?, ?, ?)",
728 &plugin->insert_stmt)) || 761 &plugin->insert_stmt)) ||
729 (SQLITE_OK != 762 (SQLITE_OK !=
730 sq_prepare (plugin->dbh, 763 sq_prepare (plugin->dbh,
731 "SELECT count(*) FROM ds090 " 764 "SELECT count(*) FROM ds091 "
732 "WHERE key=? AND type=? AND expire >= ?", 765 "WHERE key=? AND type=? AND expire >= ?",
733 &plugin->get_count_stmt)) || 766 &plugin->get_count_stmt)) ||
734 (SQLITE_OK != 767 (SQLITE_OK !=
735 sq_prepare (plugin->dbh, 768 sq_prepare (plugin->dbh,
736 "SELECT value,expire,path FROM ds090 " 769 "SELECT value,expire,path FROM ds091 "
737 "WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?", 770 "WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?",
738 &plugin->get_stmt)) || 771 &plugin->get_stmt)) ||
739 (SQLITE_OK != 772 (SQLITE_OK !=
740 sq_prepare (plugin->dbh, 773 sq_prepare (plugin->dbh,
741 "SELECT _ROWID_,key,value FROM ds090 ORDER BY expire ASC LIMIT 1", 774 "SELECT _ROWID_,key,value FROM ds091 WHERE prox=? ORDER BY expire ASC LIMIT 1",
742 &plugin->del_select_stmt)) || 775 &plugin->del_select_stmt)) ||
743 (SQLITE_OK != 776 (SQLITE_OK !=
744 sq_prepare (plugin->dbh, 777 sq_prepare (plugin->dbh,
745 "DELETE FROM ds090 WHERE _ROWID_=?", 778 "DELETE FROM ds091 WHERE _ROWID_=?",
746 &plugin->del_stmt)) || 779 &plugin->del_stmt)) ||
747 (SQLITE_OK != 780 (SQLITE_OK !=
748 sq_prepare (plugin->dbh, 781 sq_prepare (plugin->dbh,
749 "SELECT value,expire,path,key,type FROM ds090 " 782 "SELECT value,expire,path,key,type FROM ds091 "
750 "ORDER BY key LIMIT 1 OFFSET ?", 783 "ORDER BY key LIMIT 1 OFFSET ?",
751 &plugin->get_random_stmt)) || 784 &plugin->get_random_stmt)) ||
752 (SQLITE_OK != 785 (SQLITE_OK !=
753 sq_prepare (plugin->dbh, 786 sq_prepare (plugin->dbh,
754 "SELECT value,expire,path,type,key FROM ds090 " 787 "SELECT value,expire,path,type,key FROM ds091 "
755 "WHERE key>=? AND expire >= ? ORDER BY KEY ASC LIMIT ?", 788 "WHERE key>=? AND expire >= ? ORDER BY KEY ASC LIMIT ?",
756 &plugin->get_closest_stmt)) 789 &plugin->get_closest_stmt))
757 ) 790 )
diff --git a/src/datacache/plugin_datacache_template.c b/src/datacache/plugin_datacache_template.c
index b9baa64d3..28bcbcd26 100644
--- a/src/datacache/plugin_datacache_template.c
+++ b/src/datacache/plugin_datacache_template.c
@@ -45,6 +45,7 @@ struct Plugin
45 * 45 *
46 * @param cls closure (our `struct Plugin`) 46 * @param cls closure (our `struct Plugin`)
47 * @param key key to store @a data under 47 * @param key key to store @a data under
48 * @param am_closest are we the closest peer?
48 * @param size number of bytes in @a data 49 * @param size number of bytes in @a data
49 * @param data data to store 50 * @param data data to store
50 * @param type type of the value 51 * @param type type of the value
@@ -56,6 +57,7 @@ struct Plugin
56static ssize_t 57static ssize_t
57template_plugin_put (void *cls, 58template_plugin_put (void *cls,
58 const struct GNUNET_HashCode *key, 59 const struct GNUNET_HashCode *key,
60 int am_closest,
59 size_t size, 61 size_t size,
60 const char *data, 62 const char *data,
61 enum GNUNET_BLOCK_Type type, 63 enum GNUNET_BLOCK_Type type,
diff --git a/src/datacache/test_datacache.c b/src/datacache/test_datacache.c
index 79e6b6d74..c4d59c3cc 100644
--- a/src/datacache/test_datacache.c
+++ b/src/datacache/test_datacache.c
@@ -87,7 +87,10 @@ run (void *cls, char *const *args, const char *cfgfile,
87 { 87 {
88 GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n); 88 GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n);
89 ASSERT (GNUNET_OK == 89 ASSERT (GNUNET_OK ==
90 GNUNET_DATACACHE_put (h, &k, sizeof (struct GNUNET_HashCode), 90 GNUNET_DATACACHE_put (h,
91 &k,
92 GNUNET_YES,
93 sizeof (struct GNUNET_HashCode),
91 (const char *) &n, 1 + i % 16, exp, 94 (const char *) &n, 1 + i % 16, exp,
92 0, NULL)); 95 0, NULL));
93 k = n; 96 k = n;
@@ -103,7 +106,10 @@ run (void *cls, char *const *args, const char *cfgfile,
103 memset (&k, 42, sizeof (struct GNUNET_HashCode)); 106 memset (&k, 42, sizeof (struct GNUNET_HashCode));
104 GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n); 107 GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n);
105 ASSERT (GNUNET_OK == 108 ASSERT (GNUNET_OK ==
106 GNUNET_DATACACHE_put (h, &k, sizeof (struct GNUNET_HashCode), 109 GNUNET_DATACACHE_put (h,
110 &k,
111 GNUNET_YES,
112 sizeof (struct GNUNET_HashCode),
107 (const char *) &n, 792, 113 (const char *) &n, 792,
108 GNUNET_TIME_UNIT_FOREVER_ABS, 114 GNUNET_TIME_UNIT_FOREVER_ABS,
109 0, NULL)); 115 0, NULL));
diff --git a/src/datacache/test_datacache_quota.c b/src/datacache/test_datacache_quota.c
index 78b56ce42..35357a8d2 100644
--- a/src/datacache/test_datacache_quota.c
+++ b/src/datacache/test_datacache_quota.c
@@ -73,7 +73,15 @@ run (void *cls, char *const *args, const char *cfgfile,
73 { 73 {
74 exp.abs_value_us++; 74 exp.abs_value_us++;
75 buf[j] = i; 75 buf[j] = i;
76 ASSERT (GNUNET_OK == GNUNET_DATACACHE_put (h, &k, j, buf, 1 + i, exp, 0, NULL)); 76 ASSERT (GNUNET_OK == GNUNET_DATACACHE_put (h,
77 &k,
78 GNUNET_YES,
79 j,
80 buf,
81 1 + i,
82 exp,
83 0,
84 NULL));
77 ASSERT (0 < GNUNET_DATACACHE_get (h, &k, 1 + i, NULL, NULL)); 85 ASSERT (0 < GNUNET_DATACACHE_get (h, &k, 1 + i, NULL, NULL));
78 } 86 }
79 k = n; 87 k = n;
diff --git a/src/dht/gnunet-dht-get.c b/src/dht/gnunet-dht-get.c
index 842ec6270..afcd5422c 100644
--- a/src/dht/gnunet-dht-get.c
+++ b/src/dht/gnunet-dht-get.c
@@ -154,7 +154,9 @@ get_result_iterator (void *cls, struct GNUNET_TIME_Absolute exp,
154 const void *data) 154 const void *data)
155{ 155{
156 FPRINTF (stdout, 156 FPRINTF (stdout,
157 _("Result %d, type %d:\n%.*s\n"), 157 (GNUNET_BLOCK_TYPE_TEST == type)
158 ? _("Result %d, type %d:\n%.*s\n")
159 : _("Result %d, type %d:\n"),
158 result_count, 160 result_count,
159 type, 161 type,
160 (unsigned int) size, 162 (unsigned int) size,
@@ -196,8 +198,6 @@ run (void *cls, char *const *args, const char *cfgfile,
196{ 198{
197 struct GNUNET_HashCode key; 199 struct GNUNET_HashCode key;
198 200
199
200
201 cfg = c; 201 cfg = c;
202 if (NULL == query_key) 202 if (NULL == query_key)
203 { 203 {
@@ -215,17 +215,22 @@ run (void *cls, char *const *args, const char *cfgfile,
215 query_type = GNUNET_BLOCK_TYPE_TEST; 215 query_type = GNUNET_BLOCK_TYPE_TEST;
216 GNUNET_CRYPTO_hash (query_key, strlen (query_key), &key); 216 GNUNET_CRYPTO_hash (query_key, strlen (query_key), &key);
217 if (verbose) 217 if (verbose)
218 FPRINTF (stderr, "%s `%s' \n", _("Issueing DHT GET with key"), GNUNET_h2s_full (&key)); 218 FPRINTF (stderr, "%s `%s' \n",
219 _("Issueing DHT GET with key"),
220 GNUNET_h2s_full (&key));
219 GNUNET_SCHEDULER_add_shutdown (&cleanup_task, NULL); 221 GNUNET_SCHEDULER_add_shutdown (&cleanup_task, NULL);
220 tt = GNUNET_SCHEDULER_add_delayed (timeout_request, 222 tt = GNUNET_SCHEDULER_add_delayed (timeout_request,
221 &timeout_task, NULL); 223 &timeout_task,
224 NULL);
222 get_handle = 225 get_handle =
223 GNUNET_DHT_get_start (dht_handle, query_type, &key, replication, 226 GNUNET_DHT_get_start (dht_handle, query_type, &key, replication,
224 (demultixplex_everywhere) ? GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE : GNUNET_DHT_RO_NONE, 227 (demultixplex_everywhere) ? GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE : GNUNET_DHT_RO_NONE,
225 NULL, 0, &get_result_iterator, NULL); 228 NULL, 0,
226 229 &get_result_iterator,
230 NULL);
227} 231}
228 232
233
229/** 234/**
230 * Entry point for gnunet-dht-get 235 * Entry point for gnunet-dht-get
231 * 236 *
@@ -236,15 +241,12 @@ run (void *cls, char *const *args, const char *cfgfile,
236int 241int
237main (int argc, char *const *argv) 242main (int argc, char *const *argv)
238{ 243{
239
240 struct GNUNET_GETOPT_CommandLineOption options[] = { 244 struct GNUNET_GETOPT_CommandLineOption options[] = {
241
242 GNUNET_GETOPT_option_string ('k', 245 GNUNET_GETOPT_option_string ('k',
243 "key", 246 "key",
244 "KEY", 247 "KEY",
245 gettext_noop ("the query key"), 248 gettext_noop ("the query key"),
246 &query_key), 249 &query_key),
247
248 GNUNET_GETOPT_option_uint ('r', 250 GNUNET_GETOPT_option_uint ('r',
249 "replication", 251 "replication",
250 "LEVEL", 252 "LEVEL",
diff --git a/src/dht/gnunet-dht-monitor.c b/src/dht/gnunet-dht-monitor.c
index b7360bbab..a699b3d17 100644
--- a/src/dht/gnunet-dht-monitor.c
+++ b/src/dht/gnunet-dht-monitor.c
@@ -141,7 +141,8 @@ get_callback (void *cls,
141 const struct GNUNET_PeerIdentity *path, 141 const struct GNUNET_PeerIdentity *path,
142 const struct GNUNET_HashCode * key) 142 const struct GNUNET_HashCode * key)
143{ 143{
144 FPRINTF (stdout, "GET #%u: type %d, key `%s'\n", 144 FPRINTF (stdout,
145 "GET #%u: type %d, key `%s'\n",
145 result_count, 146 result_count,
146 (int) type, 147 (int) type,
147 GNUNET_h2s_full(key)); 148 GNUNET_h2s_full(key));
@@ -176,8 +177,11 @@ get_resp_callback (void *cls,
176 size_t size) 177 size_t size)
177{ 178{
178 FPRINTF (stdout, 179 FPRINTF (stdout,
179 "RESPONSE #%u: type %d, key `%s', data `%.*s'\n", 180 (GNUNET_BLOCK_TYPE_TEST == type)
181 ? "RESPONSE #%u (%s): type %d, key `%s', data `%.*s'\n"
182 : "RESPONSE #%u (%s): type %d, key `%s'\n",
180 result_count, 183 result_count,
184 GNUNET_STRINGS_absolute_time_to_string (exp),
181 (int) type, 185 (int) type,
182 GNUNET_h2s_full (key), 186 GNUNET_h2s_full (key),
183 (unsigned int) size, 187 (unsigned int) size,
@@ -215,8 +219,11 @@ put_callback (void *cls,
215 size_t size) 219 size_t size)
216{ 220{
217 FPRINTF (stdout, 221 FPRINTF (stdout,
218 "PUT %u: type %d, key `%s', data `%.*s'\n", 222 (GNUNET_BLOCK_TYPE_TEST == type)
223 ? "PUT %u (%s): type %d, key `%s', data `%.*s'\n"
224 : "PUT %u (%s): type %d, key `%s'\n",
219 result_count, 225 result_count,
226 GNUNET_STRINGS_absolute_time_to_string (exp),
220 (int) type, 227 (int) type,
221 GNUNET_h2s_full(key), 228 GNUNET_h2s_full(key),
222 (unsigned int) size, 229 (unsigned int) size,
@@ -234,7 +241,9 @@ put_callback (void *cls,
234 * @param c configuration 241 * @param c configuration
235 */ 242 */
236static void 243static void
237run (void *cls, char *const *args, const char *cfgfile, 244run (void *cls,
245 char *const *args,
246 const char *cfgfile,
238 const struct GNUNET_CONFIGURATION_Handle *c) 247 const struct GNUNET_CONFIGURATION_Handle *c)
239{ 248{
240 struct GNUNET_HashCode *key; 249 struct GNUNET_HashCode *key;
@@ -291,30 +300,30 @@ int
291main (int argc, char *const *argv) 300main (int argc, char *const *argv)
292{ 301{
293 struct GNUNET_GETOPT_CommandLineOption options[] = { 302 struct GNUNET_GETOPT_CommandLineOption options[] = {
294 303
295 GNUNET_GETOPT_option_string ('k', 304 GNUNET_GETOPT_option_string ('k',
296 "key", 305 "key",
297 "KEY", 306 "KEY",
298 gettext_noop ("the query key"), 307 gettext_noop ("the query key"),
299 &query_key), 308 &query_key),
300 309
301 GNUNET_GETOPT_option_uint ('t', 310 GNUNET_GETOPT_option_uint ('t',
302 "type", 311 "type",
303 "TYPE", 312 "TYPE",
304 gettext_noop ("the type of data to look for"), 313 gettext_noop ("the type of data to look for"),
305 &block_type), 314 &block_type),
306 315
307 GNUNET_GETOPT_option_relative_time ('T', 316 GNUNET_GETOPT_option_relative_time ('T',
308 "timeout", 317 "timeout",
309 "TIMEOUT", 318 "TIMEOUT",
310 gettext_noop ("how long should the monitor command run"), 319 gettext_noop ("how long should the monitor command run"),
311 &timeout_request), 320 &timeout_request),
312 321
313 GNUNET_GETOPT_option_flag ('V', 322 GNUNET_GETOPT_option_flag ('V',
314 "verbose", 323 "verbose",
315 gettext_noop ("be verbose (print progress information)"), 324 gettext_noop ("be verbose (print progress information)"),
316 &verbose), 325 &verbose),
317 326
318 GNUNET_GETOPT_OPTION_END 327 GNUNET_GETOPT_OPTION_END
319 }; 328 };
320 329
diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c
index 36047d561..81b7184ed 100644
--- a/src/dht/gnunet-service-dht_datacache.c
+++ b/src/dht/gnunet-service-dht_datacache.c
@@ -26,6 +26,7 @@
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_datacache_lib.h" 27#include "gnunet_datacache_lib.h"
28#include "gnunet-service-dht_datacache.h" 28#include "gnunet-service-dht_datacache.h"
29#include "gnunet-service-dht_neighbours.h"
29#include "gnunet-service-dht_routing.h" 30#include "gnunet-service-dht_routing.h"
30#include "gnunet-service-dht.h" 31#include "gnunet-service-dht.h"
31 32
@@ -79,10 +80,13 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
79 } 80 }
80 /* 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) */
81 GNUNET_STATISTICS_update (GDS_stats, 82 GNUNET_STATISTICS_update (GDS_stats,
82 gettext_noop ("# ITEMS stored in datacache"), 1, 83 gettext_noop ("# ITEMS stored in datacache"),
84 1,
83 GNUNET_NO); 85 GNUNET_NO);
84 r = GNUNET_DATACACHE_put (datacache, 86 r = GNUNET_DATACACHE_put (datacache,
85 key, 87 key,
88 GDS_am_closest_peer (key,
89 NULL),
86 data_size, 90 data_size,
87 data, 91 data,
88 type, 92 type,
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c
index 0309bea88..b120091af 100644
--- a/src/dht/gnunet-service-dht_neighbours.c
+++ b/src/dht/gnunet-service-dht_neighbours.c
@@ -421,7 +421,7 @@ static struct GNUNET_ATS_ConnectivityHandle *ats_ch;
421 * Find the optimal bucket for this key. 421 * Find the optimal bucket for this key.
422 * 422 *
423 * @param hc the hashcode to compare our identity to 423 * @param hc the hashcode to compare our identity to
424 * @return the proper bucket index, or GNUNET_SYSERR 424 * @return the proper bucket index, or #GNUNET_SYSERR
425 * on error (same hashcode) 425 * on error (same hashcode)
426 */ 426 */
427static int 427static int
@@ -941,9 +941,9 @@ get_distance (const struct GNUNET_HashCode *target,
941 * @return #GNUNET_YES if node location is closest, 941 * @return #GNUNET_YES if node location is closest,
942 * #GNUNET_NO otherwise. 942 * #GNUNET_NO otherwise.
943 */ 943 */
944static int 944int
945am_closest_peer (const struct GNUNET_HashCode *key, 945GDS_am_closest_peer (const struct GNUNET_HashCode *key,
946 const struct GNUNET_CONTAINER_BloomFilter *bloom) 946 const struct GNUNET_CONTAINER_BloomFilter *bloom)
947{ 947{
948 int bits; 948 int bits;
949 int other_bits; 949 int other_bits;
@@ -1803,7 +1803,7 @@ handle_dht_p2p_put (void *cls,
1803 payload); 1803 payload);
1804 /* store locally */ 1804 /* store locally */
1805 if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || 1805 if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) ||
1806 (am_closest_peer (&put->key, bf))) 1806 (GDS_am_closest_peer (&put->key, bf)))
1807 GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put->expiration_time), 1807 GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put->expiration_time),
1808 &put->key, 1808 &put->key,
1809 putlen, 1809 putlen,
@@ -2122,7 +2122,7 @@ handle_dht_p2p_get (void *cls,
2122 (unsigned int) ntohl (get->hop_count)); 2122 (unsigned int) ntohl (get->hop_count));
2123 /* local lookup (this may update the reply_bf) */ 2123 /* local lookup (this may update the reply_bf) */
2124 if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || 2124 if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) ||
2125 (am_closest_peer (&get->key, 2125 (GDS_am_closest_peer (&get->key,
2126 peer_bf))) 2126 peer_bf)))
2127 { 2127 {
2128 if ((0 != (options & GNUNET_DHT_RO_FIND_PEER))) 2128 if ((0 != (options & GNUNET_DHT_RO_FIND_PEER)))
diff --git a/src/dht/gnunet-service-dht_neighbours.h b/src/dht/gnunet-service-dht_neighbours.h
index 34b76ee8a..bb1867fe9 100644
--- a/src/dht/gnunet-service-dht_neighbours.h
+++ b/src/dht/gnunet-service-dht_neighbours.h
@@ -123,6 +123,22 @@ GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target,
123 123
124 124
125/** 125/**
126 * Check whether my identity is closer than any known peers. If a
127 * non-null bloomfilter is given, check if this is the closest peer
128 * that hasn't already been routed to.
129 *
130 * @param key hash code to check closeness to
131 * @param bloom bloomfilter, exclude these entries from the decision
132 * @return #GNUNET_YES if node location is closest,
133 * #GNUNET_NO otherwise.
134 */
135int
136GDS_am_closest_peer (const struct GNUNET_HashCode *key,
137 const struct GNUNET_CONTAINER_BloomFilter *bloom);
138
139
140
141/**
126 * Initialize neighbours subsystem. 142 * Initialize neighbours subsystem.
127 * 143 *
128 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 144 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
diff --git a/src/gns/gnunet-gns-benchmark.c b/src/gns/gnunet-gns-benchmark.c
index 0ab6cefd5..414c84495 100644
--- a/src/gns/gnunet-gns-benchmark.c
+++ b/src/gns/gnunet-gns-benchmark.c
@@ -294,7 +294,7 @@ process_queue (void *cls)
294 active_cnt); 294 active_cnt);
295 req->lr = GNUNET_GNS_lookup_with_tld (gns, 295 req->lr = GNUNET_GNS_lookup_with_tld (gns,
296 req->hostname, 296 req->hostname,
297 GNUNET_GNSRECORD_TYPE_ANY, 297 GNUNET_GNSRECORD_TYPE_GNS2DNS,
298 GNUNET_GNS_LO_DEFAULT, 298 GNUNET_GNS_LO_DEFAULT,
299 &process_result, 299 &process_result,
300 req); 300 req);
diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c
index 8b20f2ae3..0d04fc6b9 100644
--- a/src/gns/gnunet-service-gns_resolver.c
+++ b/src/gns/gnunet-service-gns_resolver.c
@@ -60,7 +60,7 @@
60/** 60/**
61 * DHT replication level 61 * DHT replication level
62 */ 62 */
63#define DHT_GNS_REPLICATION_LEVEL 5 63#define DHT_GNS_REPLICATION_LEVEL 10
64 64
65/** 65/**
66 * How deep do we allow recursions to go before we abort? 66 * How deep do we allow recursions to go before we abort?
diff --git a/src/include/gnunet_datacache_lib.h b/src/include/gnunet_datacache_lib.h
index 39a312b17..066b02ca9 100644
--- a/src/include/gnunet_datacache_lib.h
+++ b/src/include/gnunet_datacache_lib.h
@@ -105,6 +105,7 @@ typedef int
105 * 105 *
106 * @param h handle to the datacache 106 * @param h handle to the datacache
107 * @param key key to store data under 107 * @param key key to store data under
108 * @param am_closest am I the closest peer?
108 * @param data_size number of bytes in @a data 109 * @param data_size number of bytes in @a data
109 * @param data data to store 110 * @param data data to store
110 * @param type type of the value 111 * @param type type of the value
@@ -116,6 +117,7 @@ typedef int
116int 117int
117GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h, 118GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
118 const struct GNUNET_HashCode *key, 119 const struct GNUNET_HashCode *key,
120 int am_closest,
119 size_t data_size, 121 size_t data_size,
120 const char *data, 122 const char *data,
121 enum GNUNET_BLOCK_Type type, 123 enum GNUNET_BLOCK_Type type,
diff --git a/src/include/gnunet_datacache_plugin.h b/src/include/gnunet_datacache_plugin.h
index 166c7bc3b..9746b6493 100644
--- a/src/include/gnunet_datacache_plugin.h
+++ b/src/include/gnunet_datacache_plugin.h
@@ -109,6 +109,7 @@ struct GNUNET_DATACACHE_PluginFunctions
109 * 109 *
110 * @param cls closure (internal context for the plugin) 110 * @param cls closure (internal context for the plugin)
111 * @param key key to store the value under 111 * @param key key to store the value under
112 * @param am_closest are we the closest peer?
112 * @param size number of bytes in @a data 113 * @param size number of bytes in @a data
113 * @param data data to store 114 * @param data data to store
114 * @param type type of the value 115 * @param type type of the value
@@ -119,6 +120,7 @@ struct GNUNET_DATACACHE_PluginFunctions
119 */ 120 */
120 ssize_t (*put) (void *cls, 121 ssize_t (*put) (void *cls,
121 const struct GNUNET_HashCode *key, 122 const struct GNUNET_HashCode *key,
123 int am_closest,
122 size_t size, 124 size_t size,
123 const char *data, 125 const char *data,
124 enum GNUNET_BLOCK_Type type, 126 enum GNUNET_BLOCK_Type type,