aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-07-07 13:42:52 +0200
committerChristian Grothoff <christian@grothoff.org>2022-07-07 13:42:52 +0200
commit2906241b6a21d6009a0d195199f3a08e8f4d4e2a (patch)
treec9946fd81f343008877b41fc8471d13d0051f48a
parent374e3cf6de48f26f67cf93091a2bfbdab019a6eb (diff)
downloadgnunet-2906241b6a21d6009a0d195199f3a08e8f4d4e2a.tar.gz
gnunet-2906241b6a21d6009a0d195199f3a08e8f4d4e2a.zip
major modification to datacache to store route options (and clean up the API)
-rw-r--r--src/datacache/datacache.c32
-rw-r--r--src/datacache/plugin_datacache_heap.c220
-rw-r--r--src/datacache/plugin_datacache_postgres.c205
-rw-r--r--src/datacache/plugin_datacache_sqlite.c671
-rw-r--r--src/datacache/plugin_datacache_template.c20
-rw-r--r--src/datacache/test_datacache.c74
-rw-r--r--src/datacache/test_datacache_quota.c66
-rw-r--r--src/dht/gnunet-service-dht.h8
-rw-r--r--src/dht/gnunet-service-dht_clients.c36
-rw-r--r--src/dht/gnunet-service-dht_datacache.c53
-rw-r--r--src/dht/gnunet-service-dht_datacache.h47
-rw-r--r--src/dht/gnunet-service-dht_neighbours.c50
-rw-r--r--src/dht/gnunet-service-dht_neighbours.h6
-rw-r--r--src/dht/gnunet-service-dht_routing.c6
-rw-r--r--src/dht/gnunet-service-dht_routing.h2
-rw-r--r--src/gnsrecord/gnunet-gnsrecord-tvg.c4
-rw-r--r--src/include/gnunet_datacache_lib.h83
-rw-r--r--src/include/gnunet_datacache_plugin.h16
-rw-r--r--src/include/gnunet_dht_service.h7
-rw-r--r--src/include/gnunet_sq_lib.h8
20 files changed, 899 insertions, 715 deletions
diff --git a/src/datacache/datacache.c b/src/datacache/datacache.c
index 761ab801f..c93ed58d6 100644
--- a/src/datacache/datacache.c
+++ b/src/datacache/datacache.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2015 GNUnet e.V. 3 Copyright (C) 2004-2010, 2015, 2022 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -259,26 +259,14 @@ GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h)
259 259
260enum GNUNET_GenericReturnValue 260enum GNUNET_GenericReturnValue
261GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h, 261GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
262 const struct GNUNET_HashCode *key,
263 uint32_t xor_distance, 262 uint32_t xor_distance,
264 size_t data_size, 263 const struct GNUNET_DATACACHE_Block *block)
265 const char *data,
266 enum GNUNET_BLOCK_Type type,
267 struct GNUNET_TIME_Absolute discard_time,
268 unsigned int path_info_len,
269 const struct GNUNET_DHT_PathElement *path_info)
270{ 264{
271 ssize_t used; 265 ssize_t used;
272 266
273 used = h->api->put (h->api->cls, 267 used = h->api->put (h->api->cls,
274 key,
275 xor_distance, 268 xor_distance,
276 data_size, 269 block);
277 data,
278 type,
279 discard_time,
280 path_info_len,
281 path_info);
282 if (-1 == used) 270 if (-1 == used)
283 { 271 {
284 GNUNET_break (0); 272 GNUNET_break (0);
@@ -291,10 +279,10 @@ GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
291 } 279 }
292 LOG (GNUNET_ERROR_TYPE_DEBUG, 280 LOG (GNUNET_ERROR_TYPE_DEBUG,
293 "Stored data under key `%s' in cache\n", 281 "Stored data under key `%s' in cache\n",
294 GNUNET_h2s (key)); 282 GNUNET_h2s (&block->key));
295 if (NULL != h->filter) 283 if (NULL != h->filter)
296 GNUNET_CONTAINER_bloomfilter_add (h->filter, 284 GNUNET_CONTAINER_bloomfilter_add (h->filter,
297 key); 285 &block->key);
298 GNUNET_STATISTICS_update (h->stats, 286 GNUNET_STATISTICS_update (h->stats,
299 "# bytes stored", 287 "# bytes stored",
300 used, 288 used,
@@ -325,9 +313,10 @@ GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h,
325 LOG (GNUNET_ERROR_TYPE_DEBUG, 313 LOG (GNUNET_ERROR_TYPE_DEBUG,
326 "Processing request for key `%s'\n", 314 "Processing request for key `%s'\n",
327 GNUNET_h2s (key)); 315 GNUNET_h2s (key));
328 if ((NULL != h->filter) && 316 if ( (NULL != h->filter) &&
329 (GNUNET_OK != 317 (GNUNET_OK !=
330 GNUNET_CONTAINER_bloomfilter_test (h->filter, key))) 318 GNUNET_CONTAINER_bloomfilter_test (h->filter,
319 key)) )
331 { 320 {
332 GNUNET_STATISTICS_update (h->stats, 321 GNUNET_STATISTICS_update (h->stats,
333 "# requests filtered by bloom filter", 322 "# requests filtered by bloom filter",
@@ -364,7 +353,8 @@ GNUNET_DATACACHE_get_closest (struct GNUNET_DATACACHE_Handle *h,
364 key, 353 key,
365 type, 354 type,
366 num_results, 355 num_results,
367 iter, iter_cls); 356 iter,
357 iter_cls);
368} 358}
369 359
370 360
diff --git a/src/datacache/plugin_datacache_heap.c b/src/datacache/plugin_datacache_heap.c
index 5b50468a5..a2b60c8da 100644
--- a/src/datacache/plugin_datacache_heap.c
+++ b/src/datacache/plugin_datacache_heap.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2012, 2015 GNUnet e.V. 3 Copyright (C) 2012, 2015, 2022 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -63,14 +63,9 @@ struct Plugin
63struct Value 63struct Value
64{ 64{
65 /** 65 /**
66 * Key for the entry. 66 * Block data.
67 */ 67 */
68 struct GNUNET_HashCode key; 68 struct GNUNET_DATACACHE_Block block;
69
70 /**
71 * Expiration time.
72 */
73 struct GNUNET_TIME_Absolute discard_time;
74 69
75 /** 70 /**
76 * Corresponding node in the heap. 71 * Corresponding node in the heap.
@@ -78,29 +73,15 @@ struct Value
78 struct GNUNET_CONTAINER_HeapNode *hn; 73 struct GNUNET_CONTAINER_HeapNode *hn;
79 74
80 /** 75 /**
81 * Path information. 76 * Put path as a non-const pointer.
82 */
83 struct GNUNET_DHT_PathElement *path_info;
84
85 /**
86 * Payload (actual payload follows this struct)
87 */
88 size_t size;
89
90 /**
91 * Number of entries in @e path_info.
92 */ 77 */
93 unsigned int path_info_len; 78 struct GNUNET_DHT_PathElement *put_path;
94 79
95 /** 80 /**
96 * How close is the hash to us? Determines which heap we are in! 81 * How close is the hash to us? Determines which heap we are in!
97 */ 82 */
98 uint32_t distance; 83 uint32_t distance;
99 84
100 /**
101 * Type of the block.
102 */
103 enum GNUNET_BLOCK_Type type;
104}; 85};
105 86
106 87
@@ -113,39 +94,14 @@ struct Value
113struct PutContext 94struct PutContext
114{ 95{
115 /** 96 /**
116 * Expiration time for the new value. 97 * Block data.
117 */
118 struct GNUNET_TIME_Absolute discard_time;
119
120 /**
121 * Data for the new value.
122 */
123 const char *data;
124
125 /**
126 * Path information.
127 */ 98 */
128 const struct GNUNET_DHT_PathElement *path_info; 99 const struct GNUNET_DATACACHE_Block *block;
129 100
130 /** 101 /**
131 * Number of bytes in @e data. 102 * Value to set to true if an equivalent block was found.
132 */ 103 */
133 size_t size; 104 bool found;
134
135 /**
136 * Type of the node.
137 */
138 enum GNUNET_BLOCK_Type type;
139
140 /**
141 * Number of entries in @e path_info.
142 */
143 unsigned int path_info_len;
144
145 /**
146 * Value to set to #GNUNET_YES if an equivalent block was found.
147 */
148 int found;
149}; 105};
150 106
151 107
@@ -166,31 +122,31 @@ put_cb (void *cls,
166 struct PutContext *put_ctx = cls; 122 struct PutContext *put_ctx = cls;
167 struct Value *val = value; 123 struct Value *val = value;
168 124
169 if ((val->size == put_ctx->size) && 125 if ((val->block.data_size == put_ctx->block->data_size) &&
170 (val->type == put_ctx->type) && 126 (val->block.type == put_ctx->block->type) &&
171 (0 == memcmp (&val[1], 127 (0 == memcmp (val->block.data,
172 put_ctx->data, 128 put_ctx->block->data,
173 put_ctx->size))) 129 put_ctx->block->data_size)))
174 { 130 {
175 put_ctx->found = GNUNET_YES; 131 put_ctx->found = true;
176 val->discard_time = GNUNET_TIME_absolute_max (val->discard_time, 132 val->block.expiration_time
177 put_ctx->discard_time); 133 = GNUNET_TIME_absolute_max (val->block.expiration_time,
134 put_ctx->block->expiration_time);
178 /* replace old path with new path */ 135 /* replace old path with new path */
179 GNUNET_array_grow (val->path_info, 136 GNUNET_free (val->put_path);
180 val->path_info_len, 137 val->put_path = GNUNET_memdup (put_ctx->block->put_path,
181 put_ctx->path_info_len); 138 put_ctx->block->put_path_length
182 GNUNET_memcpy (val->path_info, 139 * sizeof (struct GNUNET_DHT_PathElement));
183 put_ctx->path_info, 140 val->block.put_path = val->put_path;
184 put_ctx->path_info_len * sizeof(struct 141 val->block.put_path_length = put_ctx->block->put_path_length;
185 GNUNET_DHT_PathElement));
186 GNUNET_CONTAINER_heap_update_cost (val->hn, 142 GNUNET_CONTAINER_heap_update_cost (val->hn,
187 val->discard_time.abs_value_us); 143 val->block.expiration_time.abs_value_us);
188 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 144 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
189 "Got same value for key %s and type %d (size %u vs %u)\n", 145 "Got same value for key %s and type %u (size %u vs %u)\n",
190 GNUNET_h2s (key), 146 GNUNET_h2s (key),
191 val->type, 147 (unsigned int) val->block.type,
192 (unsigned int) val->size, 148 (unsigned int) val->block.data_size,
193 (unsigned int) put_ctx->size); 149 (unsigned int) put_ctx->block->data_size);
194 return GNUNET_NO; 150 return GNUNET_NO;
195 } 151 }
196 return GNUNET_YES; 152 return GNUNET_YES;
@@ -201,75 +157,58 @@ put_cb (void *cls,
201 * Store an item in the datastore. 157 * Store an item in the datastore.
202 * 158 *
203 * @param cls closure (our `struct Plugin`) 159 * @param cls closure (our `struct Plugin`)
204 * @param key key to store data under
205 * @param xor_distance how close is @a key to our PID? 160 * @param xor_distance how close is @a key to our PID?
206 * @param size number of bytes in @a data 161 * @param block data to store
207 * @param data data to store
208 * @param type type of the value
209 * @param discard_time when to discard the value in any case
210 * @param path_info_len number of entries in @a path_info
211 * @param path_info a path through the network
212 * @return 0 if duplicate, -1 on error, number of bytes used otherwise 162 * @return 0 if duplicate, -1 on error, number of bytes used otherwise
213 */ 163 */
214static ssize_t 164static ssize_t
215heap_plugin_put (void *cls, 165heap_plugin_put (void *cls,
216 const struct GNUNET_HashCode *key,
217 uint32_t xor_distance, 166 uint32_t xor_distance,
218 size_t size, 167 const struct GNUNET_DATACACHE_Block *block)
219 const char *data,
220 enum GNUNET_BLOCK_Type type,
221 struct GNUNET_TIME_Absolute discard_time,
222 unsigned int path_info_len,
223 const struct GNUNET_DHT_PathElement *path_info)
224{ 168{
225 struct Plugin *plugin = cls; 169 struct Plugin *plugin = cls;
226 struct Value *val; 170 struct Value *val;
227 struct PutContext put_ctx = { 171 struct PutContext put_ctx = {
228 .data = data, 172 .block = block,
229 .size = size, 173 .found = false
230 .path_info = path_info,
231 .path_info_len = path_info_len,
232 .discard_time = discard_time,
233 .type = type
234 }; 174 };
235 175
236 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 176 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
237 "Storing %u bytes under key %s with path length %u\n", 177 "Storing %u bytes under key %s with path length %u\n",
238 (unsigned int) size, 178 (unsigned int) block->data_size,
239 GNUNET_h2s (key), 179 GNUNET_h2s (&block->key),
240 path_info_len); 180 block->put_path_length);
241 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->map, 181 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->map,
242 key, 182 &block->key,
243 &put_cb, 183 &put_cb,
244 &put_ctx); 184 &put_ctx);
245 if (GNUNET_YES == put_ctx.found) 185 if (GNUNET_YES == put_ctx.found)
246 return 0; 186 return 0;
247 val = GNUNET_malloc (sizeof(struct Value) + size); 187 val = GNUNET_malloc (sizeof(struct Value)
188 + block->data_size);
248 GNUNET_memcpy (&val[1], 189 GNUNET_memcpy (&val[1],
249 data, 190 block->data,
250 size); 191 block->data_size);
251 val->key = *key; 192 val->block = *block;
252 val->type = type; 193 val->block.data = &val[1];
253 val->discard_time = discard_time;
254 val->size = size;
255 if (xor_distance >= NUM_HEAPS) 194 if (xor_distance >= NUM_HEAPS)
256 val->distance = NUM_HEAPS - 1; 195 val->distance = NUM_HEAPS - 1;
257 else 196 else
258 val->distance = xor_distance; 197 val->distance = xor_distance;
259 GNUNET_array_grow (val->path_info, 198 if (0 != block->put_path_length)
260 val->path_info_len, 199 val->block.put_path
261 path_info_len); 200 = GNUNET_memdup (block->put_path,
262 GNUNET_memcpy (val->path_info, 201 block->put_path_length
263 path_info, 202 * sizeof (struct GNUNET_DHT_PathElement));
264 path_info_len * sizeof(struct GNUNET_DHT_PathElement));
265 (void) GNUNET_CONTAINER_multihashmap_put (plugin->map, 203 (void) GNUNET_CONTAINER_multihashmap_put (plugin->map,
266 &val->key, 204 &val->block.key,
267 val, 205 val,
268 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 206 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
269 val->hn = GNUNET_CONTAINER_heap_insert (plugin->heaps[val->distance], 207 val->hn = GNUNET_CONTAINER_heap_insert (
270 val, 208 plugin->heaps[val->distance],
271 val->discard_time.abs_value_us); 209 val,
272 return size + OVERHEAD; 210 val->block.expiration_time.abs_value_us);
211 return val->block.data_size + OVERHEAD;
273} 212}
274 213
275 214
@@ -309,16 +248,16 @@ struct GetContext
309 * @param value an existing value 248 * @param value an existing value
310 * @return #GNUNET_YES to continue to iterate 249 * @return #GNUNET_YES to continue to iterate
311 */ 250 */
312static int 251static enum GNUNET_GenericReturnValue
313get_cb (void *cls, 252get_cb (void *cls,
314 const struct GNUNET_HashCode *key, 253 const struct GNUNET_HashCode *key,
315 void *value) 254 void *value)
316{ 255{
317 struct GetContext *get_ctx = cls; 256 struct GetContext *get_ctx = cls;
318 struct Value *val = value; 257 struct Value *val = value;
319 int ret; 258 enum GNUNET_GenericReturnValue ret;
320 259
321 if ( (get_ctx->type != val->type) && 260 if ( (get_ctx->type != val->block.type) &&
322 (GNUNET_BLOCK_TYPE_ANY != get_ctx->type) ) 261 (GNUNET_BLOCK_TYPE_ANY != get_ctx->type) )
323 { 262 {
324 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 263 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -327,7 +266,7 @@ get_cb (void *cls,
327 get_ctx->type); 266 get_ctx->type);
328 return GNUNET_OK; 267 return GNUNET_OK;
329 } 268 }
330 if (GNUNET_TIME_absolute_is_past (val->discard_time)) 269 if (GNUNET_TIME_absolute_is_past (val->block.expiration_time))
331 { 270 {
332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 271 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
333 "Result for key %s is expired\n", 272 "Result for key %s is expired\n",
@@ -339,13 +278,7 @@ get_cb (void *cls,
339 GNUNET_h2s (key)); 278 GNUNET_h2s (key));
340 if (NULL != get_ctx->iter) 279 if (NULL != get_ctx->iter)
341 ret = get_ctx->iter (get_ctx->iter_cls, 280 ret = get_ctx->iter (get_ctx->iter_cls,
342 key, 281 &val->block);
343 val->size,
344 (const char *) &val[1],
345 val->type,
346 val->discard_time,
347 val->path_info_len,
348 val->path_info);
349 else 282 else
350 ret = GNUNET_YES; 283 ret = GNUNET_YES;
351 get_ctx->cnt++; 284 get_ctx->cnt++;
@@ -393,7 +326,7 @@ heap_plugin_get (void *cls,
393 * @param cls closure (our `struct Plugin`) 326 * @param cls closure (our `struct Plugin`)
394 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 327 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
395 */ 328 */
396static int 329static enum GNUNET_GenericReturnValue
397heap_plugin_del (void *cls) 330heap_plugin_del (void *cls)
398{ 331{
399 struct Plugin *plugin = cls; 332 struct Plugin *plugin = cls;
@@ -409,12 +342,12 @@ heap_plugin_del (void *cls)
409 return GNUNET_SYSERR; 342 return GNUNET_SYSERR;
410 GNUNET_assert (GNUNET_YES == 343 GNUNET_assert (GNUNET_YES ==
411 GNUNET_CONTAINER_multihashmap_remove (plugin->map, 344 GNUNET_CONTAINER_multihashmap_remove (plugin->map,
412 &val->key, 345 &val->block.key,
413 val)); 346 val));
414 plugin->env->delete_notify (plugin->env->cls, 347 plugin->env->delete_notify (plugin->env->cls,
415 &val->key, 348 &val->block.key,
416 val->size + OVERHEAD); 349 val->block.data_size + OVERHEAD);
417 GNUNET_free (val->path_info); 350 GNUNET_free (val->put_path);
418 GNUNET_free (val); 351 GNUNET_free (val);
419 return GNUNET_OK; 352 return GNUNET_OK;
420} 353}
@@ -448,7 +381,7 @@ find_closest (void *cls,
448 if (1 != GNUNET_CRYPTO_hash_cmp (key, 381 if (1 != GNUNET_CRYPTO_hash_cmp (key,
449 gcc->key)) 382 gcc->key))
450 return GNUNET_OK; /* useless */ 383 return GNUNET_OK; /* useless */
451 if ( (val->type != gcc->type) && 384 if ( (val->block.type != gcc->type) &&
452 (GNUNET_BLOCK_TYPE_ANY != gcc->type) ) 385 (GNUNET_BLOCK_TYPE_ANY != gcc->type) )
453 return GNUNET_OK; /* useless */ 386 return GNUNET_OK; /* useless */
454 j = gcc->num_results; 387 j = gcc->num_results;
@@ -460,7 +393,7 @@ find_closest (void *cls,
460 break; 393 break;
461 } 394 }
462 if (1 == 395 if (1 ==
463 GNUNET_CRYPTO_hash_cmp (&gcc->values[i]->key, 396 GNUNET_CRYPTO_hash_cmp (&gcc->values[i]->block.key,
464 key)) 397 key))
465 { 398 {
466 j = i; 399 j = i;
@@ -512,14 +445,15 @@ heap_plugin_get_closest (void *cls,
512 { 445 {
513 if (NULL == values[i]) 446 if (NULL == values[i])
514 return i; 447 return i;
515 iter (iter_cls, 448 if ( (NULL != iter) &&
516 &values[i]->key, 449 (GNUNET_SYSERR ==
517 values[i]->size, 450 iter (iter_cls,
518 (void *) &values[i][1], 451 &values[i]->block)) )
519 values[i]->type, 452 {
520 values[i]->discard_time, 453 LOG (GNUNET_ERROR_TYPE_DEBUG,
521 values[i]->path_info_len, 454 "Ending iteration (client error)\n");
522 values[i]->path_info); 455 return i;
456 }
523 } 457 }
524 return num_results * 2; 458 return num_results * 2;
525} 459}
@@ -576,9 +510,9 @@ libgnunet_plugin_datacache_heap_done (void *cls)
576 { 510 {
577 GNUNET_assert (GNUNET_YES == 511 GNUNET_assert (GNUNET_YES ==
578 GNUNET_CONTAINER_multihashmap_remove (plugin->map, 512 GNUNET_CONTAINER_multihashmap_remove (plugin->map,
579 &val->key, 513 &val->block.key,
580 val)); 514 val));
581 GNUNET_free (val->path_info); 515 GNUNET_free (val->put_path);
582 GNUNET_free (val); 516 GNUNET_free (val);
583 } 517 }
584 GNUNET_CONTAINER_heap_destroy (plugin->heaps[i]); 518 GNUNET_CONTAINER_heap_destroy (plugin->heaps[i]);
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c
index 1a83cda86..d9e25992b 100644
--- a/src/datacache/plugin_datacache_postgres.c
+++ b/src/datacache/plugin_datacache_postgres.c
@@ -63,73 +63,75 @@ struct Plugin
63 * @param plugin global context 63 * @param plugin global context
64 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 64 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
65 */ 65 */
66static int 66static enum GNUNET_GenericReturnValue
67init_connection (struct Plugin *plugin) 67init_connection (struct Plugin *plugin)
68{ 68{
69 struct GNUNET_PQ_ExecuteStatement es[] = { 69 struct GNUNET_PQ_ExecuteStatement es[] = {
70 GNUNET_PQ_make_try_execute ( 70 GNUNET_PQ_make_try_execute (
71 "CREATE TEMPORARY SEQUENCE IF NOT EXISTS gn011dc_oid_seq"), 71 "CREATE TEMPORARY SEQUENCE IF NOT EXISTS gn180dc_oid_seq"),
72 GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS gn011dc (" 72 GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS gn180dc ("
73 " oid OID NOT NULL DEFAULT nextval('gn011dc_oid_seq')," 73 " oid OID NOT NULL DEFAULT nextval('gn180dc_oid_seq'),"
74 " type INTEGER NOT NULL," 74 " type INTEGER NOT NULL,"
75 " ro INTEGER NOT NULL,"
75 " prox INTEGER NOT NULL," 76 " prox INTEGER NOT NULL,"
76 " discard_time BIGINT NOT NULL," 77 " expiration_time BIGINT NOT NULL,"
77 " key BYTEA NOT NULL," 78 " key BYTEA NOT NULL,"
78 " value BYTEA NOT NULL," 79 " value BYTEA NOT NULL,"
79 " path BYTEA DEFAULT NULL)"), 80 " path BYTEA DEFAULT NULL)"),
80 GNUNET_PQ_make_try_execute ( 81 GNUNET_PQ_make_try_execute (
81 "ALTER SEQUENCE gnu011dc_oid_seq OWNED BY gn011dc.oid"), 82 "ALTER SEQUENCE gnu011dc_oid_seq OWNED BY gn180dc.oid"),
82 GNUNET_PQ_make_try_execute ( 83 GNUNET_PQ_make_try_execute (
83 "CREATE INDEX IF NOT EXISTS idx_oid ON gn011dc (oid)"), 84 "CREATE INDEX IF NOT EXISTS idx_oid ON gn180dc (oid)"),
84 GNUNET_PQ_make_try_execute ( 85 GNUNET_PQ_make_try_execute (
85 "CREATE INDEX IF NOT EXISTS idx_key ON gn011dc (key)"), 86 "CREATE INDEX IF NOT EXISTS idx_key ON gn180dc (key)"),
86 GNUNET_PQ_make_try_execute ( 87 GNUNET_PQ_make_try_execute (
87 "CREATE INDEX IF NOT EXISTS idx_dt ON gn011dc (discard_time)"), 88 "CREATE INDEX IF NOT EXISTS idx_dt ON gn180dc (expiration_time)"),
88 GNUNET_PQ_make_execute ( 89 GNUNET_PQ_make_execute (
89 "ALTER TABLE gn011dc ALTER value SET STORAGE EXTERNAL"), 90 "ALTER TABLE gn180dc ALTER value SET STORAGE EXTERNAL"),
90 GNUNET_PQ_make_execute ("ALTER TABLE gn011dc ALTER key SET STORAGE PLAIN"), 91 GNUNET_PQ_make_execute ("ALTER TABLE gn180dc ALTER key SET STORAGE PLAIN"),
91 GNUNET_PQ_EXECUTE_STATEMENT_END 92 GNUNET_PQ_EXECUTE_STATEMENT_END
92 }; 93 };
93 struct GNUNET_PQ_PreparedStatement ps[] = { 94 struct GNUNET_PQ_PreparedStatement ps[] = {
94 GNUNET_PQ_make_prepare ("getkt", 95 GNUNET_PQ_make_prepare ("getkt",
95 "SELECT discard_time,type,value,path FROM gn011dc " 96 "SELECT expiration_time,type,ro,value,path FROM gn180dc "
96 "WHERE key=$1 AND type=$2 AND discard_time >= $3", 97 "WHERE key=$1 AND type=$2 AND expiration_time >= $3",
97 3), 98 3),
98 GNUNET_PQ_make_prepare ("getk", 99 GNUNET_PQ_make_prepare ("getk",
99 "SELECT discard_time,type,value,path FROM gn011dc " 100 "SELECT expiration_time,type,ro,value,path FROM gn180dc "
100 "WHERE key=$1 AND discard_time >= $2", 101 "WHERE key=$1 AND expiration_time >= $2",
101 2), 102 2),
102 GNUNET_PQ_make_prepare ("getex", 103 GNUNET_PQ_make_prepare ("getex",
103 "SELECT length(value) AS len,oid,key FROM gn011dc" 104 "SELECT LENGTH(value) AS len,oid,key FROM gn180dc"
104 " WHERE discard_time < $1" 105 " WHERE expiration_time < $1"
105 " ORDER BY discard_time ASC LIMIT 1", 106 " ORDER BY expiration_time ASC LIMIT 1",
106 1), 107 1),
107 GNUNET_PQ_make_prepare ("getm", 108 GNUNET_PQ_make_prepare ("getm",
108 "SELECT length(value) AS len,oid,key FROM gn011dc" 109 "SELECT LENGTH(value) AS len,oid,key FROM gn180dc"
109 " ORDER BY prox ASC, discard_time ASC LIMIT 1", 110 " ORDER BY prox ASC, expiration_time ASC LIMIT 1",
110 0), 111 0),
111 GNUNET_PQ_make_prepare ("get_closest", 112 GNUNET_PQ_make_prepare ("get_closest",
112 "(SELECT discard_time,type,value,path,key FROM gn011dc" 113 "(SELECT expiration_time,type,ro,value,path,key FROM gn180dc"
113 " WHERE key >= $1" 114 " WHERE key >= $1"
114 " AND discard_time >= $2" 115 " AND expiration_time >= $2"
115 " AND ( (type = $3) OR ( 0 = $3) )" 116 " AND ( (type = $3) OR ( 0 = $3) )"
116 " ORDER BY key ASC" 117 " ORDER BY key ASC"
117 " LIMIT $4)" 118 " LIMIT $4)"
118 " UNION " 119 " UNION "
119 "(SELECT discard_time,type,value,path,key FROM gn011dc" 120 "(SELECT expiration_time,type,ro,value,path,key FROM gn180dc"
120 " WHERE key <= $1" 121 " WHERE key <= $1"
121 " AND discard_time >= $2" 122 " AND expiration_time >= $2"
122 " AND ( (type = $3) OR ( 0 = $3) )" 123 " AND ( (type = $3) OR ( 0 = $3) )"
123 " ORDER BY key DESC" 124 " ORDER BY key DESC"
124 " LIMIT $4)", 125 " LIMIT $4)",
125 4), 126 4),
126 GNUNET_PQ_make_prepare ("delrow", 127 GNUNET_PQ_make_prepare ("delrow",
127 "DELETE FROM gn011dc WHERE oid=$1", 128 "DELETE FROM gn180dc WHERE oid=$1",
128 1), 129 1),
129 GNUNET_PQ_make_prepare ("put", 130 GNUNET_PQ_make_prepare ("put",
130 "INSERT INTO gn011dc (type, prox, discard_time, key, value, path) " 131 "INSERT INTO gn180dc"
131 "VALUES ($1, $2, $3, $4, $5, $6)", 132 " (type, ro, prox, expiration_time, key, value, path) "
132 6), 133 "VALUES ($1, $2, $3, $4, $5, $6, $7)",
134 7),
133 GNUNET_PQ_PREPARED_STATEMENT_END 135 GNUNET_PQ_PREPARED_STATEMENT_END
134 }; 136 };
135 137
@@ -148,38 +150,29 @@ init_connection (struct Plugin *plugin)
148 * Store an item in the datastore. 150 * Store an item in the datastore.
149 * 151 *
150 * @param cls closure (our `struct Plugin`) 152 * @param cls closure (our `struct Plugin`)
151 * @param key key to store @a data under
152 * @param prox proximity of @a key to my PID 153 * @param prox proximity of @a key to my PID
153 * @param data_size number of bytes in @a data 154 * @param block data to store
154 * @param data data to store
155 * @param type type of the value
156 * @param discard_time when to discard the value in any case
157 * @param path_info_len number of entries in @a path_info
158 * @param path_info a path through the network
159 * @return 0 if duplicate, -1 on error, number of bytes used otherwise 155 * @return 0 if duplicate, -1 on error, number of bytes used otherwise
160 */ 156 */
161static ssize_t 157static ssize_t
162postgres_plugin_put (void *cls, 158postgres_plugin_put (void *cls,
163 const struct GNUNET_HashCode *key,
164 uint32_t prox, 159 uint32_t prox,
165 size_t data_size, 160 const struct GNUNET_DATACACHE_Block *block)
166 const char *data,
167 enum GNUNET_BLOCK_Type type,
168 struct GNUNET_TIME_Absolute discard_time,
169 unsigned int path_info_len,
170 const struct GNUNET_DHT_PathElement *path_info)
171{ 161{
172 struct Plugin *plugin = cls; 162 struct Plugin *plugin = cls;
173 uint32_t type32 = (uint32_t) type; 163 uint32_t type32 = (uint32_t) block->type;
164 uint32_t ro32 = (uint32_t) block->type;
174 struct GNUNET_PQ_QueryParam params[] = { 165 struct GNUNET_PQ_QueryParam params[] = {
175 GNUNET_PQ_query_param_uint32 (&type32), 166 GNUNET_PQ_query_param_uint32 (&type32),
167 GNUNET_PQ_query_param_uint32 (&ro32),
176 GNUNET_PQ_query_param_uint32 (&prox), 168 GNUNET_PQ_query_param_uint32 (&prox),
177 GNUNET_PQ_query_param_absolute_time (&discard_time), 169 GNUNET_PQ_query_param_absolute_time (&block->expiration_time),
178 GNUNET_PQ_query_param_auto_from_type (key), 170 GNUNET_PQ_query_param_auto_from_type (&block->key),
179 GNUNET_PQ_query_param_fixed_size (data, data_size), 171 GNUNET_PQ_query_param_fixed_size (block->data,
180 GNUNET_PQ_query_param_fixed_size (path_info, 172 block->data_size),
181 path_info_len * sizeof(struct 173 GNUNET_PQ_query_param_fixed_size (block->put_path,
182 GNUNET_DHT_PathElement)), 174 block->put_path_length
175 * sizeof(struct GNUNET_DHT_PathElement)),
183 GNUNET_PQ_query_param_end 176 GNUNET_PQ_query_param_end
184 }; 177 };
185 enum GNUNET_DB_QueryStatus ret; 178 enum GNUNET_DB_QueryStatus ret;
@@ -190,7 +183,7 @@ postgres_plugin_put (void *cls,
190 if (0 > ret) 183 if (0 > ret)
191 return -1; 184 return -1;
192 plugin->num_items++; 185 plugin->num_items++;
193 return data_size + OVERHEAD; 186 return block->data_size + OVERHEAD;
194} 187}
195 188
196 189
@@ -234,23 +227,25 @@ handle_results (void *cls,
234 227
235 for (unsigned int i = 0; i < num_results; i++) 228 for (unsigned int i = 0; i < num_results; i++)
236 { 229 {
237 struct GNUNET_TIME_Absolute expiration_time; 230 uint32_t type32;
238 uint32_t type; 231 uint32_t bro32;
239 void *data; 232 void *data;
240 size_t data_size; 233 struct GNUNET_DATACACHE_Block block;
241 struct GNUNET_DHT_PathElement *path; 234 void *path;
242 size_t path_len; 235 size_t path_size;
243 struct GNUNET_PQ_ResultSpec rs[] = { 236 struct GNUNET_PQ_ResultSpec rs[] = {
244 GNUNET_PQ_result_spec_absolute_time ("discard_time", 237 GNUNET_PQ_result_spec_absolute_time ("expiration_time",
245 &expiration_time), 238 &block.expiration_time),
246 GNUNET_PQ_result_spec_uint32 ("type", 239 GNUNET_PQ_result_spec_uint32 ("type",
247 &type), 240 &type32),
241 GNUNET_PQ_result_spec_uint32 ("ro",
242 &bro32),
248 GNUNET_PQ_result_spec_variable_size ("value", 243 GNUNET_PQ_result_spec_variable_size ("value",
249 &data, 244 &data,
250 &data_size), 245 &block.data_size),
251 GNUNET_PQ_result_spec_variable_size ("path", 246 GNUNET_PQ_result_spec_variable_size ("path",
252 (void **) &path, 247 &path,
253 &path_len), 248 &path_size),
254 GNUNET_PQ_result_spec_end 249 GNUNET_PQ_result_spec_end
255 }; 250 };
256 251
@@ -262,26 +257,27 @@ handle_results (void *cls,
262 GNUNET_break (0); 257 GNUNET_break (0);
263 return; 258 return;
264 } 259 }
265 if (0 != (path_len % sizeof(struct GNUNET_DHT_PathElement))) 260 if (0 != (path_size % sizeof(struct GNUNET_DHT_PathElement)))
266 { 261 {
267 GNUNET_break (0); 262 GNUNET_break (0);
268 path_len = 0; 263 path_size = 0;
264 path = NULL;
269 } 265 }
270 path_len %= sizeof(struct GNUNET_DHT_PathElement); 266 block.data = data;
267 block.put_path = path;
268 block.put_path_length
269 = path_size / sizeof (struct GNUNET_DHT_PathElement);
270 block.type = (enum GNUNET_BLOCK_Type) type32;
271 block.ro = (enum GNUNET_DHT_RouteOption) bro32;
272 block.key = *hrc->key;
271 LOG (GNUNET_ERROR_TYPE_DEBUG, 273 LOG (GNUNET_ERROR_TYPE_DEBUG,
272 "Found result of size %u bytes and type %u in database\n", 274 "Found result of size %u bytes and type %u in database\n",
273 (unsigned int) data_size, 275 (unsigned int) block.data_size,
274 (unsigned int) type); 276 (unsigned int) block.type);
275 if ((NULL != hrc->iter) && 277 if ( (NULL != hrc->iter) &&
276 (GNUNET_SYSERR == 278 (GNUNET_SYSERR ==
277 hrc->iter (hrc->iter_cls, 279 hrc->iter (hrc->iter_cls,
278 hrc->key, 280 &block)) )
279 data_size,
280 data,
281 (enum GNUNET_BLOCK_Type) type,
282 expiration_time,
283 path_len,
284 path)))
285 { 281 {
286 LOG (GNUNET_ERROR_TYPE_DEBUG, 282 LOG (GNUNET_ERROR_TYPE_DEBUG,
287 "Ending iteration (client error)\n"); 283 "Ending iteration (client error)\n");
@@ -350,7 +346,7 @@ postgres_plugin_get (void *cls,
350 * @param cls closure (our `struct Plugin`) 346 * @param cls closure (our `struct Plugin`)
351 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 347 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
352 */ 348 */
353static int 349static enum GNUNET_GenericReturnValue
354postgres_plugin_del (void *cls) 350postgres_plugin_del (void *cls)
355{ 351{
356 struct Plugin *plugin = cls; 352 struct Plugin *plugin = cls;
@@ -453,26 +449,27 @@ extract_result_cb (void *cls,
453 return; 449 return;
454 for (unsigned int i = 0; i < num_results; i++) 450 for (unsigned int i = 0; i < num_results; i++)
455 { 451 {
456 struct GNUNET_TIME_Absolute expiration_time; 452 uint32_t type32;
457 uint32_t type; 453 uint32_t bro32;
454 struct GNUNET_DATACACHE_Block block;
458 void *data; 455 void *data;
459 size_t data_size; 456 void *path;
460 struct GNUNET_DHT_PathElement *path; 457 size_t path_size;
461 size_t path_len;
462 struct GNUNET_HashCode key;
463 struct GNUNET_PQ_ResultSpec rs[] = { 458 struct GNUNET_PQ_ResultSpec rs[] = {
464 GNUNET_PQ_result_spec_absolute_time ("", 459 GNUNET_PQ_result_spec_absolute_time ("expiration_time",
465 &expiration_time), 460 &block.expiration_time),
466 GNUNET_PQ_result_spec_uint32 ("type", 461 GNUNET_PQ_result_spec_uint32 ("type",
467 &type), 462 &type32),
463 GNUNET_PQ_result_spec_uint32 ("ro",
464 &bro32),
468 GNUNET_PQ_result_spec_variable_size ("value", 465 GNUNET_PQ_result_spec_variable_size ("value",
469 &data, 466 &data,
470 &data_size), 467 &block.data_size),
471 GNUNET_PQ_result_spec_variable_size ("path", 468 GNUNET_PQ_result_spec_variable_size ("path",
472 (void **) &path, 469 &path,
473 &path_len), 470 &path_size),
474 GNUNET_PQ_result_spec_auto_from_type ("key", 471 GNUNET_PQ_result_spec_auto_from_type ("key",
475 &key), 472 &block.key),
476 GNUNET_PQ_result_spec_end 473 GNUNET_PQ_result_spec_end
477 }; 474 };
478 475
@@ -484,25 +481,25 @@ extract_result_cb (void *cls,
484 GNUNET_break (0); 481 GNUNET_break (0);
485 return; 482 return;
486 } 483 }
487 if (0 != (path_len % sizeof(struct GNUNET_DHT_PathElement))) 484 if (0 != (path_size % sizeof(struct GNUNET_DHT_PathElement)))
488 { 485 {
489 GNUNET_break (0); 486 GNUNET_break (0);
490 path_len = 0; 487 path_size = 0;
488 path = NULL;
491 } 489 }
492 path_len %= sizeof(struct GNUNET_DHT_PathElement); 490 block.type = (enum GNUNET_BLOCK_Type) type32;
491 block.ro = (enum GNUNET_DHT_RouteOption) bro32;
492 block.data = data;
493 block.put_path = path;
494 block.put_path_length = path_size / sizeof (struct GNUNET_DHT_PathElement);
493 LOG (GNUNET_ERROR_TYPE_DEBUG, 495 LOG (GNUNET_ERROR_TYPE_DEBUG,
494 "Found result of size %u bytes and type %u in database\n", 496 "Found result of size %u bytes and type %u in database\n",
495 (unsigned int) data_size, 497 (unsigned int) block.data_size,
496 (unsigned int) type); 498 (unsigned int) block.type);
497 if (GNUNET_SYSERR == 499 if ( (NULL != erc->iter) &&
498 erc->iter (erc->iter_cls, 500 (GNUNET_SYSERR ==
499 &key, 501 erc->iter (erc->iter_cls,
500 data_size, 502 &block)) )
501 data,
502 (enum GNUNET_BLOCK_Type) type,
503 expiration_time,
504 path_len,
505 path))
506 { 503 {
507 LOG (GNUNET_ERROR_TYPE_DEBUG, 504 LOG (GNUNET_ERROR_TYPE_DEBUG,
508 "Ending iteration (client error)\n"); 505 "Ending iteration (client error)\n");
diff --git a/src/datacache/plugin_datacache_sqlite.c b/src/datacache/plugin_datacache_sqlite.c
index 6f2165433..22ae5c0f5 100644
--- a/src/datacache/plugin_datacache_sqlite.c
+++ b/src/datacache/plugin_datacache_sqlite.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2006, 2009, 2015 GNUnet e.V. 3 Copyright (C) 2006, 2009, 2015, 2022 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -74,9 +74,19 @@ struct Plugin
74 /** 74 /**
75 * Prepared statement for #sqlite_plugin_get. 75 * Prepared statement for #sqlite_plugin_get.
76 */ 76 */
77 sqlite3_stmt *get_count_any_stmt;
78
79 /**
80 * Prepared statement for #sqlite_plugin_get.
81 */
77 sqlite3_stmt *get_stmt; 82 sqlite3_stmt *get_stmt;
78 83
79 /** 84 /**
85 * Prepared statement for #sqlite_plugin_get.
86 */
87 sqlite3_stmt *get_any_stmt;
88
89 /**
80 * Prepared statement for #sqlite_plugin_del. 90 * Prepared statement for #sqlite_plugin_del.
81 */ 91 */
82 sqlite3_stmt *del_select_stmt; 92 sqlite3_stmt *del_select_stmt;
@@ -133,9 +143,10 @@ struct Plugin
133 do \ 143 do \
134 { \ 144 { \
135 emsg = NULL; \ 145 emsg = NULL; \
136 if (SQLITE_OK != sqlite3_exec (db, cmd, NULL, NULL, &emsg)) \ 146 if (SQLITE_OK != \
147 sqlite3_exec (db, cmd, NULL, NULL, &emsg)) \
137 { \ 148 { \
138 LOG (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, \ 149 LOG (GNUNET_ERROR_TYPE_ERROR, \
139 _ ("`%s' failed at %s:%d with error: %s\n"), \ 150 _ ("`%s' failed at %s:%d with error: %s\n"), \
140 "sqlite3_exec", \ 151 "sqlite3_exec", \
141 __FILE__, \ 152 __FILE__, \
@@ -173,67 +184,222 @@ sq_prepare (sqlite3 *dbh,
173 * Store an item in the datastore. 184 * Store an item in the datastore.
174 * 185 *
175 * @param cls closure (our `struct Plugin`) 186 * @param cls closure (our `struct Plugin`)
176 * @param key key to store @a data under
177 * @param xor_distance how close is @a key to our PID? 187 * @param xor_distance how close is @a key to our PID?
178 * @param size number of bytes in @a data 188 * @param block data to store
179 * @param data data to store
180 * @param type type of the value
181 * @param discard_time when to discard the value in any case
182 * @param path_info_len number of entries in @a path_info
183 * @param path_info array of peers that have processed the request
184 * @return 0 if duplicate, -1 on error, number of bytes used otherwise 189 * @return 0 if duplicate, -1 on error, number of bytes used otherwise
185 */ 190 */
186static ssize_t 191static ssize_t
187sqlite_plugin_put (void *cls, 192sqlite_plugin_put (void *cls,
188 const struct GNUNET_HashCode *key,
189 uint32_t xor_distance, 193 uint32_t xor_distance,
190 size_t size, 194 const struct GNUNET_DATACACHE_Block *block)
191 const char *data,
192 enum GNUNET_BLOCK_Type type,
193 struct GNUNET_TIME_Absolute discard_time,
194 unsigned int path_info_len,
195 const struct GNUNET_DHT_PathElement *path_info)
196{ 195{
197 struct Plugin *plugin = cls; 196 struct Plugin *plugin = cls;
198 uint32_t type32 = type; 197 uint32_t type32 = (uint32_t) block->type;
199 struct GNUNET_SQ_QueryParam params[] = 198 uint32_t ro32 = (uint32_t) block->ro;
200 { GNUNET_SQ_query_param_uint32 (&type32), 199 struct GNUNET_SQ_QueryParam params[] = {
201 GNUNET_SQ_query_param_absolute_time (&discard_time), 200 GNUNET_SQ_query_param_uint32 (&type32),
202 GNUNET_SQ_query_param_auto_from_type (key), 201 GNUNET_SQ_query_param_uint32 (&ro32),
202 GNUNET_SQ_query_param_absolute_time (&block->expiration_time),
203 GNUNET_SQ_query_param_auto_from_type (&block->key),
203 GNUNET_SQ_query_param_uint32 (&xor_distance), 204 GNUNET_SQ_query_param_uint32 (&xor_distance),
204 GNUNET_SQ_query_param_fixed_size (data, size), 205 GNUNET_SQ_query_param_fixed_size (block->data,
205 GNUNET_SQ_query_param_fixed_size (path_info, 206 block->data_size),
206 path_info_len 207 GNUNET_SQ_query_param_fixed_size (block->put_path,
208 block->put_path_length
207 * sizeof(struct GNUNET_DHT_PathElement)), 209 * sizeof(struct GNUNET_DHT_PathElement)),
208 GNUNET_SQ_query_param_end }; 210 GNUNET_SQ_query_param_end
211 };
209 212
210 LOG (GNUNET_ERROR_TYPE_DEBUG, 213 LOG (GNUNET_ERROR_TYPE_DEBUG,
211 "Processing PUT of %u bytes with key `%s' and expiration %s\n", 214 "Processing PUT of %u bytes with key `%s' and expiration %s\n",
212 (unsigned int) size, 215 (unsigned int) block->data_size,
213 GNUNET_h2s (key), 216 GNUNET_h2s (&block->key),
214 GNUNET_STRINGS_relative_time_to_string ( 217 GNUNET_STRINGS_relative_time_to_string (
215 GNUNET_TIME_absolute_get_remaining ( 218 GNUNET_TIME_absolute_get_remaining (
216 discard_time), 219 block->expiration_time),
217 GNUNET_YES)); 220 GNUNET_YES));
218 if (GNUNET_OK != GNUNET_SQ_bind (plugin->insert_stmt, params)) 221 if (GNUNET_OK !=
222 GNUNET_SQ_bind (plugin->insert_stmt,
223 params))
219 { 224 {
220 LOG_SQLITE (plugin->dbh, 225 LOG_SQLITE (plugin->dbh,
221 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 226 GNUNET_ERROR_TYPE_ERROR,
222 "sqlite3_bind_xxx"); 227 "sqlite3_bind_xxx");
223 GNUNET_SQ_reset (plugin->dbh, plugin->insert_stmt); 228 GNUNET_SQ_reset (plugin->dbh,
229 plugin->insert_stmt);
224 return -1; 230 return -1;
225 } 231 }
226 if (SQLITE_DONE != sqlite3_step (plugin->insert_stmt)) 232 if (SQLITE_DONE !=
233 sqlite3_step (plugin->insert_stmt))
227 { 234 {
228 LOG_SQLITE (plugin->dbh, 235 LOG_SQLITE (plugin->dbh,
229 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 236 GNUNET_ERROR_TYPE_ERROR,
230 "sqlite3_step"); 237 "sqlite3_step");
231 GNUNET_SQ_reset (plugin->dbh, plugin->insert_stmt); 238 GNUNET_SQ_reset (plugin->dbh,
239 plugin->insert_stmt);
232 return -1; 240 return -1;
233 } 241 }
234 plugin->num_items++; 242 plugin->num_items++;
235 GNUNET_SQ_reset (plugin->dbh, plugin->insert_stmt); 243 GNUNET_SQ_reset (plugin->dbh,
236 return size + OVERHEAD; 244 plugin->insert_stmt);
245 return block->data_size + OVERHEAD;
246}
247
248
249/**
250 * Iterate over the results for a particular key
251 * in the datastore.
252 *
253 * @param cls closure (our `struct Plugin`)
254 * @param key
255 * @param iter maybe NULL (to just count)
256 * @param iter_cls closure for @a iter
257 * @return the number of results found
258 */
259static unsigned int
260get_any (void *cls,
261 const struct GNUNET_HashCode *key,
262 GNUNET_DATACACHE_Iterator iter,
263 void *iter_cls)
264{
265 struct Plugin *plugin = cls;
266 struct GNUNET_TIME_Absolute now;
267 unsigned int cnt;
268 uint32_t off;
269 uint32_t btype32;
270 uint32_t bro32;
271 unsigned int total;
272 struct GNUNET_DATACACHE_Block block;
273 void *path;
274 void *data;
275 size_t path_size;
276 struct GNUNET_SQ_QueryParam params_count[] = {
277 GNUNET_SQ_query_param_auto_from_type (key),
278 GNUNET_SQ_query_param_absolute_time (&now),
279 GNUNET_SQ_query_param_end
280 };
281 struct GNUNET_SQ_QueryParam params_select[] = {
282 GNUNET_SQ_query_param_auto_from_type (key),
283 GNUNET_SQ_query_param_absolute_time (&now),
284 GNUNET_SQ_query_param_uint32 (&off),
285 GNUNET_SQ_query_param_end
286 };
287 struct GNUNET_SQ_ResultSpec rs[] = {
288 GNUNET_SQ_result_spec_variable_size (&data,
289 &block.data_size),
290 GNUNET_SQ_result_spec_absolute_time (&block.expiration_time),
291 GNUNET_SQ_result_spec_variable_size (&path,
292 &path_size),
293 GNUNET_SQ_result_spec_uint32 (&btype32),
294 GNUNET_SQ_result_spec_uint32 (&bro32),
295 GNUNET_SQ_result_spec_end
296 };
297
298 now = GNUNET_TIME_absolute_get ();
299 LOG (GNUNET_ERROR_TYPE_DEBUG,
300 "Processing GET for key `%s'\n",
301 GNUNET_h2s (key));
302
303 if (GNUNET_OK !=
304 GNUNET_SQ_bind (plugin->get_count_any_stmt,
305 params_count))
306 {
307 LOG_SQLITE (plugin->dbh,
308 GNUNET_ERROR_TYPE_ERROR,
309 "sqlite3_bind_xxx");
310 GNUNET_SQ_reset (plugin->dbh,
311 plugin->get_count_any_stmt);
312 return 0;
313 }
314 if (SQLITE_ROW !=
315 sqlite3_step (plugin->get_count_any_stmt))
316 {
317 LOG_SQLITE (plugin->dbh,
318 GNUNET_ERROR_TYPE_ERROR,
319 "sqlite_step");
320 GNUNET_SQ_reset (plugin->dbh,
321 plugin->get_count_any_stmt);
322 LOG (GNUNET_ERROR_TYPE_DEBUG,
323 "No content found when processing GET for key `%s'\n",
324 GNUNET_h2s (key));
325 return 0;
326 }
327 total = sqlite3_column_int (plugin->get_count_any_stmt,
328 0);
329 GNUNET_SQ_reset (plugin->dbh,
330 plugin->get_count_any_stmt);
331 if ( (0 == total) ||
332 (NULL == iter) )
333 {
334 if (0 == total)
335 LOG (GNUNET_ERROR_TYPE_DEBUG,
336 "No content found when processing GET for key `%s'\n",
337 GNUNET_h2s (key));
338 return total;
339 }
340
341 cnt = 0;
342 block.key = *key;
343 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
344 total);
345 while (cnt < total)
346 {
347 off = (off + 1) % total;
348 if (GNUNET_OK !=
349 GNUNET_SQ_bind (plugin->get_any_stmt,
350 params_select))
351 {
352 LOG_SQLITE (plugin->dbh,
353 GNUNET_ERROR_TYPE_ERROR,
354 "sqlite3_bind_xxx");
355 GNUNET_SQ_reset (plugin->dbh,
356 plugin->get_any_stmt);
357 return cnt;
358 }
359 if (SQLITE_ROW !=
360 sqlite3_step (plugin->get_any_stmt))
361 break;
362 if (GNUNET_OK !=
363 GNUNET_SQ_extract_result (plugin->get_any_stmt,
364 rs))
365 {
366 GNUNET_break (0);
367 GNUNET_SQ_reset (plugin->dbh,
368 plugin->get_any_stmt);
369 break;
370 }
371 if (0 != path_size % sizeof(struct GNUNET_DHT_PathElement))
372 {
373 GNUNET_break (0);
374 path_size = 0;
375 path = NULL;
376 }
377 block.data = data;
378 block.put_path = path;
379 block.put_path_length = path_size / sizeof(struct GNUNET_DHT_PathElement);
380 block.type = (enum GNUNET_BLOCK_Type) btype32;
381 block.ro = (enum GNUNET_DHT_RouteOption) bro32;
382 cnt++;
383 LOG (GNUNET_ERROR_TYPE_DEBUG,
384 "Found %u-byte result when processing GET for key `%s'\n",
385 (unsigned int) block.data_size,
386 GNUNET_h2s (&block.key));
387 if (GNUNET_OK !=
388 iter (iter_cls,
389 &block))
390 {
391 GNUNET_SQ_cleanup_result (rs);
392 GNUNET_SQ_reset (plugin->dbh,
393 plugin->get_any_stmt);
394 break;
395 }
396 GNUNET_SQ_cleanup_result (rs);
397 GNUNET_SQ_reset (plugin->dbh,
398 plugin->get_any_stmt);
399 }
400 GNUNET_SQ_reset (plugin->dbh,
401 plugin->get_any_stmt);
402 return cnt;
237} 403}
238 404
239 405
@@ -249,67 +415,81 @@ sqlite_plugin_put (void *cls,
249 * @return the number of results found 415 * @return the number of results found
250 */ 416 */
251static unsigned int 417static unsigned int
252sqlite_plugin_get (void *cls, 418get_typed (void *cls,
253 const struct GNUNET_HashCode *key, 419 const struct GNUNET_HashCode *key,
254 enum GNUNET_BLOCK_Type type, 420 enum GNUNET_BLOCK_Type type,
255 GNUNET_DATACACHE_Iterator iter, 421 GNUNET_DATACACHE_Iterator iter,
256 void *iter_cls) 422 void *iter_cls)
257{ 423{
258 struct Plugin *plugin = cls; 424 struct Plugin *plugin = cls;
259 uint32_t type32 = type; 425 uint32_t type32 = type;
260 struct GNUNET_TIME_Absolute now; 426 struct GNUNET_TIME_Absolute now;
261 struct GNUNET_TIME_Absolute exp;
262 size_t size;
263 void *dat;
264 unsigned int cnt; 427 unsigned int cnt;
265 uint32_t off; 428 uint32_t off;
429 uint32_t bro32;
266 unsigned int total; 430 unsigned int total;
267 size_t psize; 431 struct GNUNET_DATACACHE_Block block;
268 struct GNUNET_DHT_PathElement *path; 432 void *path;
269 struct GNUNET_SQ_QueryParam params_count[] = 433 void *data;
270 { GNUNET_SQ_query_param_auto_from_type (key), 434 size_t path_size;
435 struct GNUNET_SQ_QueryParam params_count[] = {
436 GNUNET_SQ_query_param_auto_from_type (key),
271 GNUNET_SQ_query_param_uint32 (&type32), 437 GNUNET_SQ_query_param_uint32 (&type32),
272 GNUNET_SQ_query_param_absolute_time (&now), 438 GNUNET_SQ_query_param_absolute_time (&now),
273 GNUNET_SQ_query_param_end }; 439 GNUNET_SQ_query_param_end
274 struct GNUNET_SQ_QueryParam params_select[] = 440 };
275 { GNUNET_SQ_query_param_auto_from_type (key), 441 struct GNUNET_SQ_QueryParam params_select[] = {
442 GNUNET_SQ_query_param_auto_from_type (key),
276 GNUNET_SQ_query_param_uint32 (&type32), 443 GNUNET_SQ_query_param_uint32 (&type32),
277 GNUNET_SQ_query_param_absolute_time (&now), 444 GNUNET_SQ_query_param_absolute_time (&now),
278 GNUNET_SQ_query_param_uint32 (&off), 445 GNUNET_SQ_query_param_uint32 (&off),
279 GNUNET_SQ_query_param_end }; 446 GNUNET_SQ_query_param_end
280 struct GNUNET_SQ_ResultSpec rs[] = 447 };
281 { GNUNET_SQ_result_spec_variable_size (&dat, &size), 448 struct GNUNET_SQ_ResultSpec rs[] = {
282 GNUNET_SQ_result_spec_absolute_time (&exp), 449 GNUNET_SQ_result_spec_variable_size (&data,
283 GNUNET_SQ_result_spec_variable_size ((void **) &path, &psize), 450 &block.data_size),
284 GNUNET_SQ_result_spec_end }; 451 GNUNET_SQ_result_spec_absolute_time (&block.expiration_time),
452 GNUNET_SQ_result_spec_variable_size (&path,
453 &path_size),
454 GNUNET_SQ_result_spec_uint32 (&bro32),
455 GNUNET_SQ_result_spec_end
456 };
285 457
286 now = GNUNET_TIME_absolute_get (); 458 now = GNUNET_TIME_absolute_get ();
287 LOG (GNUNET_ERROR_TYPE_DEBUG, 459 LOG (GNUNET_ERROR_TYPE_DEBUG,
288 "Processing GET for key `%s'\n", 460 "Processing GET for key `%s'\n",
289 GNUNET_h2s (key)); 461 GNUNET_h2s (key));
290 462
291 if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_count_stmt, params_count)) 463 if (GNUNET_OK !=
464 GNUNET_SQ_bind (plugin->get_count_stmt,
465 params_count))
292 { 466 {
293 LOG_SQLITE (plugin->dbh, 467 LOG_SQLITE (plugin->dbh,
294 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 468 GNUNET_ERROR_TYPE_ERROR,
295 "sqlite3_bind_xxx"); 469 "sqlite3_bind_xxx");
296 GNUNET_SQ_reset (plugin->dbh, plugin->get_count_stmt); 470 GNUNET_SQ_reset (plugin->dbh,
471 plugin->get_count_stmt);
297 return 0; 472 return 0;
298 } 473 }
299 if (SQLITE_ROW != sqlite3_step (plugin->get_count_stmt)) 474 if (SQLITE_ROW !=
475 sqlite3_step (plugin->get_count_stmt))
300 { 476 {
301 LOG_SQLITE (plugin->dbh, 477 LOG_SQLITE (plugin->dbh,
302 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 478 GNUNET_ERROR_TYPE_ERROR,
303 "sqlite_step"); 479 "sqlite_step");
304 GNUNET_SQ_reset (plugin->dbh, plugin->get_count_stmt); 480 GNUNET_SQ_reset (plugin->dbh,
481 plugin->get_count_stmt);
305 LOG (GNUNET_ERROR_TYPE_DEBUG, 482 LOG (GNUNET_ERROR_TYPE_DEBUG,
306 "No content found when processing GET for key `%s'\n", 483 "No content found when processing GET for key `%s'\n",
307 GNUNET_h2s (key)); 484 GNUNET_h2s (key));
308 return 0; 485 return 0;
309 } 486 }
310 total = sqlite3_column_int (plugin->get_count_stmt, 0); 487 total = sqlite3_column_int (plugin->get_count_stmt,
311 GNUNET_SQ_reset (plugin->dbh, plugin->get_count_stmt); 488 0);
312 if ((0 == total) || (NULL == iter)) 489 GNUNET_SQ_reset (plugin->dbh,
490 plugin->get_count_stmt);
491 if ( (0 == total) ||
492 (NULL == iter) )
313 { 493 {
314 if (0 == total) 494 if (0 == total)
315 LOG (GNUNET_ERROR_TYPE_DEBUG, 495 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -319,129 +499,206 @@ sqlite_plugin_get (void *cls,
319 } 499 }
320 500
321 cnt = 0; 501 cnt = 0;
322 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, total); 502 block.key = *key;
503 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
504 total);
323 while (cnt < total) 505 while (cnt < total)
324 { 506 {
325 off = (off + 1) % total; 507 off = (off + 1) % total;
326 if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_stmt, params_select)) 508 if (GNUNET_OK !=
509 GNUNET_SQ_bind (plugin->get_stmt,
510 params_select))
327 { 511 {
328 LOG_SQLITE (plugin->dbh, 512 LOG_SQLITE (plugin->dbh,
329 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 513 GNUNET_ERROR_TYPE_ERROR,
330 "sqlite3_bind_xxx"); 514 "sqlite3_bind_xxx");
331 GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt); 515 GNUNET_SQ_reset (plugin->dbh,
516 plugin->get_stmt);
332 return cnt; 517 return cnt;
333 } 518 }
334 if (SQLITE_ROW != sqlite3_step (plugin->get_stmt)) 519 if (SQLITE_ROW !=
520 sqlite3_step (plugin->get_stmt))
335 break; 521 break;
336 if (GNUNET_OK != GNUNET_SQ_extract_result (plugin->get_stmt, rs)) 522 if (GNUNET_OK !=
523 GNUNET_SQ_extract_result (plugin->get_stmt,
524 rs))
337 { 525 {
338 GNUNET_break (0); 526 GNUNET_break (0);
339 GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt); 527 GNUNET_SQ_reset (plugin->dbh,
528 plugin->get_stmt);
340 break; 529 break;
341 } 530 }
342 if (0 != psize % sizeof(struct GNUNET_DHT_PathElement)) 531 if (0 != path_size % sizeof(struct GNUNET_DHT_PathElement))
343 { 532 {
344 GNUNET_break (0); 533 GNUNET_break (0);
345 psize = 0; 534 path_size = 0;
346 path = NULL; 535 path = NULL;
347 } 536 }
348 psize /= sizeof(struct GNUNET_DHT_PathElement); 537 block.data = data;
538 block.put_path = path;
539 block.put_path_length = path_size / sizeof(struct GNUNET_DHT_PathElement);
540 block.type = type;
541 block.ro = (enum GNUNET_DHT_RouteOption) bro32;
349 cnt++; 542 cnt++;
350 LOG (GNUNET_ERROR_TYPE_DEBUG, 543 LOG (GNUNET_ERROR_TYPE_DEBUG,
351 "Found %u-byte result when processing GET for key `%s'\n", 544 "Found %u-byte result when processing GET for key `%s'\n",
352 (unsigned int) size, 545 (unsigned int) block.data_size,
353 GNUNET_h2s (key)); 546 GNUNET_h2s (&block.key));
354 if (GNUNET_OK != iter (iter_cls, key, size, dat, type, exp, psize, path)) 547 if ( (NULL != iter) &&
548 (GNUNET_OK !=
549 iter (iter_cls,
550 &block)) )
355 { 551 {
356 GNUNET_SQ_cleanup_result (rs); 552 GNUNET_SQ_cleanup_result (rs);
357 GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt); 553 GNUNET_SQ_reset (plugin->dbh,
554 plugin->get_stmt);
358 break; 555 break;
359 } 556 }
360 GNUNET_SQ_cleanup_result (rs); 557 GNUNET_SQ_cleanup_result (rs);
361 GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt); 558 GNUNET_SQ_reset (plugin->dbh,
559 plugin->get_stmt);
362 } 560 }
363 GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt); 561 GNUNET_SQ_reset (plugin->dbh,
562 plugin->get_stmt);
364 return cnt; 563 return cnt;
365} 564}
366 565
367 566
368/** 567/**
568 * Iterate over the results for a particular key
569 * in the datastore.
570 *
571 * @param cls closure (our `struct Plugin`)
572 * @param key
573 * @param type entries of which type are relevant?
574 * @param iter maybe NULL (to just count)
575 * @param iter_cls closure for @a iter
576 * @return the number of results found
577 */
578static unsigned int
579sqlite_plugin_get (void *cls,
580 const struct GNUNET_HashCode *key,
581 enum GNUNET_BLOCK_Type type,
582 GNUNET_DATACACHE_Iterator iter,
583 void *iter_cls)
584{
585 if (GNUNET_BLOCK_TYPE_ANY == type)
586 return get_any (cls,
587 key,
588 iter,
589 iter_cls);
590 return get_typed (cls,
591 key,
592 type,
593 iter,
594 iter_cls);
595}
596
597
598/**
369 * Delete the entry with the lowest expiration value 599 * Delete the entry with the lowest expiration value
370 * from the datacache right now. 600 * from the datacache right now.
371 * 601 *
372 * @param cls closure (our `struct Plugin`) 602 * @param cls closure (our `struct Plugin`)
373 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 603 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
374 */ 604 */
375static int 605static enum GNUNET_GenericReturnValue
376sqlite_plugin_del (void *cls) 606sqlite_plugin_del (void *cls)
377{ 607{
378 struct Plugin *plugin = cls; 608 struct Plugin *plugin = cls;
379 uint64_t rowid; 609 uint64_t rowid;
380 void *data; 610 void *data;
381 size_t dsize; 611 size_t data_size;
382 struct GNUNET_HashCode hc; 612 struct GNUNET_HashCode hc;
383 struct GNUNET_TIME_Absolute now; 613 struct GNUNET_TIME_Absolute now;
384 struct GNUNET_SQ_ResultSpec rs[] = 614 struct GNUNET_SQ_ResultSpec rs[] = {
385 { GNUNET_SQ_result_spec_uint64 (&rowid), 615 GNUNET_SQ_result_spec_uint64 (&rowid),
386 GNUNET_SQ_result_spec_auto_from_type (&hc), 616 GNUNET_SQ_result_spec_auto_from_type (&hc),
387 GNUNET_SQ_result_spec_variable_size ((void **) &data, &dsize), 617 GNUNET_SQ_result_spec_variable_size (&data,
388 GNUNET_SQ_result_spec_end }; 618 &data_size),
389 struct GNUNET_SQ_QueryParam params[] = { GNUNET_SQ_query_param_uint64 ( 619 GNUNET_SQ_result_spec_end
390 &rowid), 620 };
391 GNUNET_SQ_query_param_end }; 621 struct GNUNET_SQ_QueryParam params[] = {
392 struct GNUNET_SQ_QueryParam time_params[] = 622 GNUNET_SQ_query_param_uint64 (&rowid),
393 { GNUNET_SQ_query_param_absolute_time (&now), GNUNET_SQ_query_param_end }; 623 GNUNET_SQ_query_param_end
394 624 };
395 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing DEL\n"); 625 struct GNUNET_SQ_QueryParam time_params[] = {
626 GNUNET_SQ_query_param_absolute_time (&now),
627 GNUNET_SQ_query_param_end
628 };
629
630 LOG (GNUNET_ERROR_TYPE_DEBUG,
631 "Processing DEL\n");
396 now = GNUNET_TIME_absolute_get (); 632 now = GNUNET_TIME_absolute_get ();
397 if (GNUNET_OK != GNUNET_SQ_bind (plugin->del_expired_stmt, time_params)) 633 if (GNUNET_OK !=
634 GNUNET_SQ_bind (plugin->del_expired_stmt,
635 time_params))
398 { 636 {
399 LOG_SQLITE (plugin->dbh, 637 LOG_SQLITE (plugin->dbh,
400 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 638 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
401 "sqlite3_bind"); 639 "sqlite3_bind");
402 GNUNET_SQ_reset (plugin->dbh, plugin->del_expired_stmt); 640 GNUNET_SQ_reset (plugin->dbh,
641 plugin->del_expired_stmt);
403 return GNUNET_SYSERR; 642 return GNUNET_SYSERR;
404 } 643 }
405 if ((SQLITE_ROW != sqlite3_step (plugin->del_expired_stmt)) || 644 if ( (SQLITE_ROW !=
406 (GNUNET_OK != GNUNET_SQ_extract_result (plugin->del_expired_stmt, rs))) 645 sqlite3_step (plugin->del_expired_stmt)) ||
646 (GNUNET_OK !=
647 GNUNET_SQ_extract_result (plugin->del_expired_stmt,
648 rs)))
407 { 649 {
408 GNUNET_SQ_reset (plugin->dbh, plugin->del_expired_stmt); 650 GNUNET_SQ_reset (plugin->dbh,
409 if (SQLITE_ROW != sqlite3_step (plugin->del_select_stmt)) 651 plugin->del_expired_stmt);
652 if (SQLITE_ROW !=
653 sqlite3_step (plugin->del_select_stmt))
410 { 654 {
411 LOG_SQLITE (plugin->dbh, 655 LOG_SQLITE (plugin->dbh,
412 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 656 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
413 "sqlite3_step"); 657 "sqlite3_step");
414 GNUNET_SQ_reset (plugin->dbh, plugin->del_select_stmt); 658 GNUNET_SQ_reset (plugin->dbh,
659 plugin->del_select_stmt);
415 return GNUNET_SYSERR; 660 return GNUNET_SYSERR;
416 } 661 }
417 if (GNUNET_OK != GNUNET_SQ_extract_result (plugin->del_select_stmt, rs)) 662 if (GNUNET_OK !=
663 GNUNET_SQ_extract_result (plugin->del_select_stmt,
664 rs))
418 { 665 {
419 GNUNET_SQ_reset (plugin->dbh, plugin->del_select_stmt); 666 GNUNET_SQ_reset (plugin->dbh,
667 plugin->del_select_stmt);
420 GNUNET_break (0); 668 GNUNET_break (0);
421 return GNUNET_SYSERR; 669 return GNUNET_SYSERR;
422 } 670 }
423 } 671 }
424 GNUNET_SQ_cleanup_result (rs); 672 GNUNET_SQ_cleanup_result (rs);
425 GNUNET_SQ_reset (plugin->dbh, plugin->del_select_stmt); 673 GNUNET_SQ_reset (plugin->dbh,
426 if (GNUNET_OK != GNUNET_SQ_bind (plugin->del_stmt, params)) 674 plugin->del_select_stmt);
675 if (GNUNET_OK !=
676 GNUNET_SQ_bind (plugin->del_stmt,
677 params))
427 { 678 {
428 LOG_SQLITE (plugin->dbh, 679 LOG_SQLITE (plugin->dbh,
429 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 680 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
430 "sqlite3_bind"); 681 "sqlite3_bind");
431 GNUNET_SQ_reset (plugin->dbh, plugin->del_stmt); 682 GNUNET_SQ_reset (plugin->dbh,
683 plugin->del_stmt);
432 return GNUNET_SYSERR; 684 return GNUNET_SYSERR;
433 } 685 }
434 if (SQLITE_DONE != sqlite3_step (plugin->del_stmt)) 686 if (SQLITE_DONE !=
687 sqlite3_step (plugin->del_stmt))
435 { 688 {
436 LOG_SQLITE (plugin->dbh, 689 LOG_SQLITE (plugin->dbh,
437 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 690 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
438 "sqlite3_step"); 691 "sqlite3_step");
439 GNUNET_SQ_reset (plugin->dbh, plugin->del_stmt); 692 GNUNET_SQ_reset (plugin->dbh,
693 plugin->del_stmt);
440 return GNUNET_SYSERR; 694 return GNUNET_SYSERR;
441 } 695 }
442 plugin->num_items--; 696 plugin->num_items--;
443 plugin->env->delete_notify (plugin->env->cls, &hc, dsize + OVERHEAD); 697 plugin->env->delete_notify (plugin->env->cls,
444 GNUNET_SQ_reset (plugin->dbh, plugin->del_stmt); 698 &hc,
699 data_size + OVERHEAD);
700 GNUNET_SQ_reset (plugin->dbh,
701 plugin->del_stmt);
445 return GNUNET_OK; 702 return GNUNET_OK;
446} 703}
447 704
@@ -472,14 +729,13 @@ sqlite_plugin_get_closest (void *cls,
472 uint32_t type32 = type; 729 uint32_t type32 = type;
473 uint32_t num_results32 = num_results; 730 uint32_t num_results32 = num_results;
474 struct GNUNET_TIME_Absolute now; 731 struct GNUNET_TIME_Absolute now;
475 struct GNUNET_TIME_Absolute exp; 732 void *data;
476 size_t size; 733 void *path;
477 void *dat; 734 size_t path_size;
478 unsigned int cnt; 735 unsigned int cnt;
479 size_t psize; 736 uint32_t bro32;
480 uint32_t rtype; 737 struct GNUNET_DATACACHE_Block block;
481 struct GNUNET_HashCode hc; 738 uint32_t rtype32;
482 struct GNUNET_DHT_PathElement *path;
483 struct GNUNET_SQ_QueryParam params[] = { 739 struct GNUNET_SQ_QueryParam params[] = {
484 GNUNET_SQ_query_param_auto_from_type (key), 740 GNUNET_SQ_query_param_auto_from_type (key),
485 GNUNET_SQ_query_param_absolute_time (&now), 741 GNUNET_SQ_query_param_absolute_time (&now),
@@ -488,11 +744,14 @@ sqlite_plugin_get_closest (void *cls,
488 GNUNET_SQ_query_param_end 744 GNUNET_SQ_query_param_end
489 }; 745 };
490 struct GNUNET_SQ_ResultSpec rs[] = { 746 struct GNUNET_SQ_ResultSpec rs[] = {
491 GNUNET_SQ_result_spec_variable_size (&dat, &size), 747 GNUNET_SQ_result_spec_variable_size (&data,
492 GNUNET_SQ_result_spec_absolute_time (&exp), 748 &block.data_size),
493 GNUNET_SQ_result_spec_variable_size ((void **) &path, &psize), 749 GNUNET_SQ_result_spec_absolute_time (&block.expiration_time),
494 GNUNET_SQ_result_spec_uint32 (&rtype), 750 GNUNET_SQ_result_spec_variable_size (&path,
495 GNUNET_SQ_result_spec_auto_from_type (&hc), 751 &path_size),
752 GNUNET_SQ_result_spec_uint32 (&rtype32),
753 GNUNET_SQ_result_spec_uint32 (&bro32),
754 GNUNET_SQ_result_spec_auto_from_type (&block.key),
496 GNUNET_SQ_result_spec_end 755 GNUNET_SQ_result_spec_end
497 }; 756 };
498 757
@@ -512,7 +771,8 @@ sqlite_plugin_get_closest (void *cls,
512 return 0; 771 return 0;
513 } 772 }
514 cnt = 0; 773 cnt = 0;
515 while (SQLITE_ROW == sqlite3_step (plugin->get_closest_stmt)) 774 while (SQLITE_ROW ==
775 sqlite3_step (plugin->get_closest_stmt))
516 { 776 {
517 if (GNUNET_OK != 777 if (GNUNET_OK !=
518 GNUNET_SQ_extract_result (plugin->get_closest_stmt, 778 GNUNET_SQ_extract_result (plugin->get_closest_stmt,
@@ -521,26 +781,27 @@ sqlite_plugin_get_closest (void *cls,
521 GNUNET_break (0); 781 GNUNET_break (0);
522 break; 782 break;
523 } 783 }
524 if (0 != psize % sizeof(struct GNUNET_DHT_PathElement)) 784 if (0 != path_size % sizeof(struct GNUNET_DHT_PathElement))
525 { 785 {
526 GNUNET_break (0); 786 GNUNET_break (0);
527 psize = 0; 787 path_size = 0;
528 path = NULL; 788 path = NULL;
529 } 789 }
530 psize /= sizeof(struct GNUNET_DHT_PathElement); 790 block.put_path_length
791 = path_size / sizeof(struct GNUNET_DHT_PathElement);
792 block.put_path = path;
793 block.data = data;
794 block.type = (enum GNUNET_BLOCK_Type) rtype32;
795 block.ro = (enum GNUNET_DHT_RouteOption) bro32;
531 cnt++; 796 cnt++;
532 LOG (GNUNET_ERROR_TYPE_DEBUG, 797 LOG (GNUNET_ERROR_TYPE_DEBUG,
533 "Found %u-byte result at %s when processing GET_CLOSE\n", 798 "Found %u-byte result at %s when processing GET_CLOSE\n",
534 (unsigned int) size, 799 (unsigned int) block.data_size,
535 GNUNET_h2s (&hc)); 800 GNUNET_h2s (&block.key));
536 if (GNUNET_OK != iter (iter_cls, 801
537 &hc, 802 if (GNUNET_OK !=
538 size, 803 iter (iter_cls,
539 dat, 804 &block))
540 rtype,
541 exp,
542 psize,
543 path))
544 { 805 {
545 GNUNET_SQ_cleanup_result (rs); 806 GNUNET_SQ_cleanup_result (rs);
546 break; 807 break;
@@ -570,25 +831,30 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
570 sqlite3 *dbh; 831 sqlite3 *dbh;
571 char *emsg; 832 char *emsg;
572 833
573 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg, 834 if (GNUNET_YES ==
574 "datacache-sqlite", 835 GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
575 "IN_MEMORY")) 836 "datacache-sqlite",
837 "IN_MEMORY"))
576 { 838 {
577 if (SQLITE_OK != sqlite3_open (":memory:", &dbh)) 839 if (SQLITE_OK !=
840 sqlite3_open (":memory:",
841 &dbh))
578 return NULL; 842 return NULL;
579 fn_utf8 = NULL; 843 fn_utf8 = NULL;
580 } 844 }
581 else 845 else
582 { 846 {
583 fn = GNUNET_DISK_mktemp ("gnunet-datacache"); 847 fn = GNUNET_DISK_mktemp ("gnunet-datacache");
584 if (fn == NULL) 848 if (NULL == fn)
585 { 849 {
586 GNUNET_break (0); 850 GNUNET_break (0);
587 return NULL; 851 return NULL;
588 } 852 }
589 /* fn should be UTF-8-encoded. If it isn't, it's a bug. */ 853 /* fn should be UTF-8-encoded. If it isn't, it's a bug. */
590 fn_utf8 = GNUNET_strdup (fn); 854 fn_utf8 = GNUNET_strdup (fn);
591 if (SQLITE_OK != sqlite3_open (fn_utf8, &dbh)) 855 if (SQLITE_OK !=
856 sqlite3_open (fn_utf8,
857 &dbh))
592 { 858 {
593 GNUNET_free (fn); 859 GNUNET_free (fn);
594 GNUNET_free (fn_utf8); 860 GNUNET_free (fn_utf8);
@@ -602,22 +868,30 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
602 SQLITE3_EXEC (dbh, "PRAGMA journal_mode=OFF"); 868 SQLITE3_EXEC (dbh, "PRAGMA journal_mode=OFF");
603 SQLITE3_EXEC (dbh, "PRAGMA synchronous=OFF"); 869 SQLITE3_EXEC (dbh, "PRAGMA synchronous=OFF");
604 SQLITE3_EXEC (dbh, "PRAGMA page_size=4092"); 870 SQLITE3_EXEC (dbh, "PRAGMA page_size=4092");
605 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg, 871 if (GNUNET_YES ==
606 "datacache-sqlite", 872 GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
607 "IN_MEMORY")) 873 "datacache-sqlite",
874 "IN_MEMORY"))
608 SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3"); 875 SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3");
609 876
610 SQLITE3_EXEC (dbh, 877 SQLITE3_EXEC (dbh,
611 "CREATE TABLE ds091 (" 878 "CREATE TABLE ds180 ("
612 " type INTEGER NOT NULL DEFAULT 0," 879 " type INTEGER NOT NULL DEFAULT 0,"
880 " ro INTEGER NOT NULL DEFAULT 0,"
613 " expire INTEGER NOT NULL," 881 " expire INTEGER NOT NULL,"
614 " key BLOB NOT NULL DEFAULT ''," 882 " key BLOB NOT NULL DEFAULT '',"
615 " prox INTEGER NOT NULL," 883 " prox INTEGER NOT NULL,"
616 " value BLOB NOT NULL," 884 " value BLOB NOT NULL,"
617 " path BLOB DEFAULT '')"); 885 " path BLOB DEFAULT '')");
618 SQLITE3_EXEC (dbh, "CREATE INDEX idx_hashidx ON ds091 (key,type,expire)"); 886 SQLITE3_EXEC (dbh,
619 SQLITE3_EXEC (dbh, "CREATE INDEX idx_prox_expire ON ds091 (prox,expire)"); 887 "CREATE INDEX idx_hashidx"
620 SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire_only ON ds091 (expire)"); 888 " ON ds180 (key,type,expire)");
889 SQLITE3_EXEC (dbh,
890 "CREATE INDEX idx_prox_expire"
891 " ON ds180 (prox,expire)");
892 SQLITE3_EXEC (dbh,
893 "CREATE INDEX idx_expire_only"
894 " ON ds180 (expire)");
621 plugin = GNUNET_new (struct Plugin); 895 plugin = GNUNET_new (struct Plugin);
622 plugin->env = env; 896 plugin->env = env;
623 plugin->dbh = dbh; 897 plugin->dbh = dbh;
@@ -625,41 +899,67 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
625 899
626 if ((SQLITE_OK != 900 if ((SQLITE_OK !=
627 sq_prepare (plugin->dbh, 901 sq_prepare (plugin->dbh,
628 "INSERT INTO ds091 (type, expire, key, prox, value, path) " 902 "INSERT INTO ds180"
629 "VALUES (?, ?, ?, ?, ?, ?)", 903 " (type, ro, expire, key, prox, value, path)"
904 " VALUES (?, ?, ?, ?, ?, ?, ?)",
630 &plugin->insert_stmt)) || 905 &plugin->insert_stmt)) ||
631 (SQLITE_OK != sq_prepare (plugin->dbh,
632 "SELECT count(*) FROM ds091 "
633 "WHERE key=? AND type=? AND expire >= ?",
634 &plugin->get_count_stmt)) ||
635 (SQLITE_OK != 906 (SQLITE_OK !=
636 sq_prepare (plugin->dbh, 907 sq_prepare (plugin->dbh,
637 "SELECT value,expire,path FROM ds091" 908 "SELECT COUNT(*) FROM ds180 "
638 " WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?", 909 "WHERE key=?"
910 " AND type=?"
911 " AND expire >= ?",
912 &plugin->get_count_stmt)) ||
913 (SQLITE_OK !=
914 sq_prepare (plugin->dbh,
915 "SELECT COUNT(*) FROM ds180 "
916 "WHERE key=? AND expire >= ?",
917 &plugin->get_count_any_stmt)) ||
918 (SQLITE_OK !=
919 sq_prepare (plugin->dbh,
920 "SELECT value,expire,path,ro"
921 " FROM ds180"
922 " WHERE key=?"
923 " AND type=?"
924 " AND expire >= ?"
925 " LIMIT 1 OFFSET ?",
639 &plugin->get_stmt)) || 926 &plugin->get_stmt)) ||
640 (SQLITE_OK != sq_prepare (plugin->dbh, 927 (SQLITE_OK !=
641 "SELECT _ROWID_,key,value FROM ds091" 928 sq_prepare (plugin->dbh,
642 " WHERE expire < ?1" 929 "SELECT value,expire,path,type,ro"
643 " ORDER BY expire ASC LIMIT 1", 930 " FROM ds180"
644 &plugin->del_expired_stmt)) || 931 " WHERE key=?"
645 (SQLITE_OK != sq_prepare (plugin->dbh, 932 " AND expire >= ?"
646 "SELECT _ROWID_,key,value FROM ds091" 933 " LIMIT 1 OFFSET ?",
647 " ORDER BY prox ASC, expire ASC LIMIT 1", 934 &plugin->get_any_stmt)) ||
648 &plugin->del_select_stmt)) || 935 (SQLITE_OK !=
649 (SQLITE_OK != sq_prepare (plugin->dbh, 936 sq_prepare (plugin->dbh,
650 "DELETE FROM ds091 WHERE _ROWID_=?", 937 "SELECT _ROWID_,key,value FROM ds180"
651 &plugin->del_stmt)) || 938 " WHERE expire < ?1"
939 " ORDER BY expire ASC LIMIT 1",
940 &plugin->del_expired_stmt)) ||
941 (SQLITE_OK !=
942 sq_prepare (plugin->dbh,
943 "SELECT _ROWID_,key,value FROM ds180"
944 " ORDER BY prox ASC, expire ASC LIMIT 1",
945 &plugin->del_select_stmt)) ||
946 (SQLITE_OK !=
947 sq_prepare (plugin->dbh,
948 "DELETE FROM ds180 WHERE _ROWID_=?",
949 &plugin->del_stmt)) ||
652 (SQLITE_OK != 950 (SQLITE_OK !=
653 sq_prepare (plugin->dbh, 951 sq_prepare (plugin->dbh,
654 "SELECT * FROM (" 952 "SELECT * FROM ("
655 " SELECT value,expire,path,type,key FROM ds091 " 953 " SELECT value,expire,path,type,ro,key"
954 " FROM ds180 "
656 " WHERE key>=?1 " 955 " WHERE key>=?1 "
657 " AND expire >= ?2" 956 " AND expire >= ?2"
658 " AND ( (type=?3) or (0 == ?3) )" 957 " AND ( (type=?3) or (0 == ?3) )"
659 " ORDER BY KEY ASC LIMIT ?4)" 958 " ORDER BY KEY ASC LIMIT ?4)"
660 "UNION " 959 "UNION "
661 "SELECT * FROM (" 960 "SELECT * FROM ("
662 " SELECT value,expire,path,type,key FROM ds091 " 961 " SELECT value,expire,path,type,ro,key"
962 " FROM ds180 "
663 " WHERE key<=?1 " 963 " WHERE key<=?1 "
664 " AND expire >= ?2" 964 " AND expire >= ?2"
665 " AND ( (type=?3) or (0 == ?3) )" 965 " AND ( (type=?3) or (0 == ?3) )"
@@ -669,7 +969,8 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
669 LOG_SQLITE (plugin->dbh, 969 LOG_SQLITE (plugin->dbh,
670 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 970 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
671 "sq_prepare"); 971 "sq_prepare");
672 GNUNET_break (SQLITE_OK == sqlite3_close (plugin->dbh)); 972 GNUNET_break (SQLITE_OK ==
973 sqlite3_close (plugin->dbh));
673 GNUNET_free (plugin); 974 GNUNET_free (plugin);
674 return NULL; 975 return NULL;
675 } 976 }
@@ -680,7 +981,8 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
680 api->put = &sqlite_plugin_put; 981 api->put = &sqlite_plugin_put;
681 api->del = &sqlite_plugin_del; 982 api->del = &sqlite_plugin_del;
682 api->get_closest = &sqlite_plugin_get_closest; 983 api->get_closest = &sqlite_plugin_get_closest;
683 LOG (GNUNET_ERROR_TYPE_INFO, "Sqlite datacache running\n"); 984 LOG (GNUNET_ERROR_TYPE_INFO,
985 "Sqlite datacache running\n");
684 return api; 986 return api;
685} 987}
686 988
@@ -703,13 +1005,18 @@ libgnunet_plugin_datacache_sqlite_done (void *cls)
703#endif 1005#endif
704 1006
705#if ! WINDOWS || defined(__CYGWIN__) 1007#if ! WINDOWS || defined(__CYGWIN__)
706 if ((NULL != plugin->fn) && (0 != unlink (plugin->fn))) 1008 if ( (NULL != plugin->fn) &&
707 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", plugin->fn); 1009 (0 != unlink (plugin->fn)) )
1010 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING,
1011 "unlink",
1012 plugin->fn);
708 GNUNET_free (plugin->fn); 1013 GNUNET_free (plugin->fn);
709#endif 1014#endif
710 sqlite3_finalize (plugin->insert_stmt); 1015 sqlite3_finalize (plugin->insert_stmt);
711 sqlite3_finalize (plugin->get_count_stmt); 1016 sqlite3_finalize (plugin->get_count_stmt);
1017 sqlite3_finalize (plugin->get_count_any_stmt);
712 sqlite3_finalize (plugin->get_stmt); 1018 sqlite3_finalize (plugin->get_stmt);
1019 sqlite3_finalize (plugin->get_any_stmt);
713 sqlite3_finalize (plugin->del_select_stmt); 1020 sqlite3_finalize (plugin->del_select_stmt);
714 sqlite3_finalize (plugin->del_expired_stmt); 1021 sqlite3_finalize (plugin->del_expired_stmt);
715 sqlite3_finalize (plugin->del_stmt); 1022 sqlite3_finalize (plugin->del_stmt);
@@ -721,7 +1028,8 @@ libgnunet_plugin_datacache_sqlite_done (void *cls)
721 LOG (GNUNET_ERROR_TYPE_WARNING, 1028 LOG (GNUNET_ERROR_TYPE_WARNING,
722 _ ( 1029 _ (
723 "Tried to close sqlite without finalizing all prepared statements.\n")); 1030 "Tried to close sqlite without finalizing all prepared statements.\n"));
724 stmt = sqlite3_next_stmt (plugin->dbh, NULL); 1031 stmt = sqlite3_next_stmt (plugin->dbh,
1032 NULL);
725 while (NULL != stmt) 1033 while (NULL != stmt)
726 { 1034 {
727 result = sqlite3_finalize (stmt); 1035 result = sqlite3_finalize (stmt);
@@ -730,13 +1038,16 @@ libgnunet_plugin_datacache_sqlite_done (void *cls)
730 "Failed to close statement %p: %d\n", 1038 "Failed to close statement %p: %d\n",
731 stmt, 1039 stmt,
732 result); 1040 result);
733 stmt = sqlite3_next_stmt (plugin->dbh, NULL); 1041 stmt = sqlite3_next_stmt (plugin->dbh,
1042 NULL);
734 } 1043 }
735 result = sqlite3_close (plugin->dbh); 1044 result = sqlite3_close (plugin->dbh);
736 } 1045 }
737#endif 1046#endif
738 if (SQLITE_OK != result) 1047 if (SQLITE_OK != result)
739 LOG_SQLITE (plugin->dbh, GNUNET_ERROR_TYPE_ERROR, "sqlite3_close"); 1048 LOG_SQLITE (plugin->dbh,
1049 GNUNET_ERROR_TYPE_ERROR,
1050 "sqlite3_close");
740 1051
741 GNUNET_free (plugin); 1052 GNUNET_free (plugin);
742 GNUNET_free (api); 1053 GNUNET_free (api);
diff --git a/src/datacache/plugin_datacache_template.c b/src/datacache/plugin_datacache_template.c
index 2f7b41dbe..1bd712d39 100644
--- a/src/datacache/plugin_datacache_template.c
+++ b/src/datacache/plugin_datacache_template.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2006, 2009, 2015 GNUnet e.V. 3 Copyright (C) 2006, 2009, 2015, 2022 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -44,26 +44,14 @@ struct Plugin
44 * Store an item in the datastore. 44 * Store an item in the datastore.
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
48 * @param xor_distance distance of @a key to our PID 47 * @param xor_distance distance of @a key to our PID
49 * @param size number of bytes in @a data 48 * @param block data to store
50 * @param data data to store
51 * @param type type of the value
52 * @param discard_time when to discard the value in any case
53 * @param path_info_len number of entries in @a path_info
54 * @param path_info a path through the network
55 * @return 0 if duplicate, -1 on error, number of bytes used otherwise 49 * @return 0 if duplicate, -1 on error, number of bytes used otherwise
56 */ 50 */
57static ssize_t 51static ssize_t
58template_plugin_put (void *cls, 52template_plugin_put (void *cls,
59 const struct GNUNET_HashCode *key,
60 uint32_t xor_distance, 53 uint32_t xor_distance,
61 size_t size, 54 const struct GNUNET_DATACACHE_Block *block)
62 const char *data,
63 enum GNUNET_BLOCK_Type type,
64 struct GNUNET_TIME_Absolute discard_time,
65 unsigned int path_info_len,
66 const struct GNUNET_DHT_PathElement *path_info)
67{ 55{
68 GNUNET_break (0); 56 GNUNET_break (0);
69 return -1; 57 return -1;
@@ -100,7 +88,7 @@ template_plugin_get (void *cls,
100 * @param cls closure (our `struct Plugin`) 88 * @param cls closure (our `struct Plugin`)
101 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 89 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
102 */ 90 */
103static int 91static enum GNUNET_GenericReturnValue
104template_plugin_del (void *cls) 92template_plugin_del (void *cls)
105{ 93{
106 GNUNET_break (0); 94 GNUNET_break (0);
diff --git a/src/datacache/test_datacache.c b/src/datacache/test_datacache.c
index 5740d2b7d..b5d978995 100644
--- a/src/datacache/test_datacache.c
+++ b/src/datacache/test_datacache.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2006, 2009, 2010 GNUnet e.V. 3 Copyright (C) 2006, 2009, 2010, 2022 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -39,26 +39,18 @@ static int ok;
39static const char *plugin_name; 39static const char *plugin_name;
40 40
41 41
42static int 42static enum GNUNET_GenericReturnValue
43checkIt (void *cls, 43checkIt (void *cls,
44 const struct GNUNET_HashCode *key, 44 const struct GNUNET_DATACACHE_Block *block)
45 size_t size, const char *data,
46 enum GNUNET_BLOCK_Type type,
47 struct GNUNET_TIME_Absolute exp,
48 unsigned int path_len,
49 const struct GNUNET_DHT_PathElement *path)
50{ 45{
51 (void) key; 46 if (block->data_size != sizeof(struct GNUNET_HashCode))
52 (void) type;
53 (void) exp;
54 (void) path_len;
55 (void) path;
56 if (size != sizeof(struct GNUNET_HashCode))
57 { 47 {
58 GNUNET_break (0); 48 GNUNET_break (0);
59 ok = 2; 49 ok = 2;
60 } 50 }
61 if (0 != memcmp (data, cls, size)) 51 if (0 != memcmp (block->data,
52 cls,
53 block->data_size))
62 { 54 {
63 GNUNET_break (0); 55 GNUNET_break (0);
64 ok = 3; 56 ok = 3;
@@ -74,9 +66,9 @@ run (void *cls,
74 const struct GNUNET_CONFIGURATION_Handle *cfg) 66 const struct GNUNET_CONFIGURATION_Handle *cfg)
75{ 67{
76 struct GNUNET_DATACACHE_Handle *h; 68 struct GNUNET_DATACACHE_Handle *h;
69 struct GNUNET_DATACACHE_Block block;
77 struct GNUNET_HashCode k; 70 struct GNUNET_HashCode k;
78 struct GNUNET_HashCode n; 71 struct GNUNET_HashCode n;
79 struct GNUNET_TIME_Absolute exp;
80 72
81 (void) cls; 73 (void) cls;
82 (void) args; 74 (void) args;
@@ -84,7 +76,7 @@ run (void *cls,
84 ok = 0; 76 ok = 0;
85 h = GNUNET_DATACACHE_create (cfg, 77 h = GNUNET_DATACACHE_create (cfg,
86 "testcache"); 78 "testcache");
87 if (h == NULL) 79 if (NULL == h)
88 { 80 {
89 fprintf (stderr, 81 fprintf (stderr,
90 "%s", 82 "%s",
@@ -92,19 +84,28 @@ run (void *cls,
92 ok = 77; /* mark test as skipped */ 84 ok = 77; /* mark test as skipped */
93 return; 85 return;
94 } 86 }
95 exp = GNUNET_TIME_absolute_get (); 87 block.expiration_time = GNUNET_TIME_absolute_get ();
96 exp.abs_value_us += 5 * 60 * 1000 * 1000LL; 88 block.expiration_time.abs_value_us += 5 * 60 * 1000 * 1000LL;
97 memset (&k, 0, sizeof(struct GNUNET_HashCode)); 89 memset (&k,
90 0,
91 sizeof(struct GNUNET_HashCode));
98 for (unsigned int i = 0; i < 100; i++) 92 for (unsigned int i = 0; i < 100; i++)
99 { 93 {
100 GNUNET_CRYPTO_hash (&k, sizeof(struct GNUNET_HashCode), &n); 94 GNUNET_CRYPTO_hash (&k,
95 sizeof(struct GNUNET_HashCode),
96 &n);
97 block.key = k;
98 block.data = &n;
99 block.data_size = sizeof (n);
100 block.ro = 42;
101 block.type = (enum GNUNET_BLOCK_Type) (1 + i % 16);
102 block.put_path = NULL;
103 block.put_path_length = 0;
104 block.ro = GNUNET_DHT_RO_RECORD_ROUTE;
101 ASSERT (GNUNET_OK == 105 ASSERT (GNUNET_OK ==
102 GNUNET_DATACACHE_put (h, 106 GNUNET_DATACACHE_put (h,
103 &k, 107 42,
104 GNUNET_YES, 108 &block));
105 sizeof(struct GNUNET_HashCode),
106 (const char *) &n, 1 + i % 16, exp,
107 0, NULL));
108 k = n; 109 k = n;
109 } 110 }
110 memset (&k, 111 memset (&k,
@@ -117,7 +118,7 @@ run (void *cls,
117 &n); 118 &n);
118 ASSERT (1 == GNUNET_DATACACHE_get (h, 119 ASSERT (1 == GNUNET_DATACACHE_get (h,
119 &k, 120 &k,
120 1 + i % 16, 121 (enum GNUNET_BLOCK_Type) (1 + i % 16),
121 &checkIt, 122 &checkIt,
122 &n)); 123 &n));
123 k = n; 124 k = n;
@@ -129,16 +130,19 @@ run (void *cls,
129 GNUNET_CRYPTO_hash (&k, 130 GNUNET_CRYPTO_hash (&k,
130 sizeof(struct GNUNET_HashCode), 131 sizeof(struct GNUNET_HashCode),
131 &n); 132 &n);
133 block.key = k;
134 block.data = &n;
135 block.data_size = sizeof (n);
136 block.ro = 42;
137 block.type = (enum GNUNET_BLOCK_Type) 792;
138 block.put_path = NULL;
139 block.put_path_length = 0;
140 block.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS;
141 block.ro = GNUNET_DHT_RO_RECORD_ROUTE;
132 ASSERT (GNUNET_OK == 142 ASSERT (GNUNET_OK ==
133 GNUNET_DATACACHE_put (h, 143 GNUNET_DATACACHE_put (h,
134 &k, 144 42,
135 GNUNET_YES, 145 &block));
136 sizeof(struct GNUNET_HashCode),
137 (const char *) &n,
138 792,
139 GNUNET_TIME_UNIT_FOREVER_ABS,
140 0,
141 NULL));
142 ASSERT (0 != GNUNET_DATACACHE_get (h, 146 ASSERT (0 != GNUNET_DATACACHE_get (h,
143 &k, 147 &k,
144 792, 148 792,
diff --git a/src/datacache/test_datacache_quota.c b/src/datacache/test_datacache_quota.c
index 92807fbe2..0b647ee99 100644
--- a/src/datacache/test_datacache_quota.c
+++ b/src/datacache/test_datacache_quota.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2006, 2009, 2010 GNUnet e.V. 3 Copyright (C) 2006, 2009, 2010, 2022 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -53,8 +53,8 @@ run (void *cls,
53 struct GNUNET_DATACACHE_Handle *h; 53 struct GNUNET_DATACACHE_Handle *h;
54 struct GNUNET_HashCode k; 54 struct GNUNET_HashCode k;
55 struct GNUNET_HashCode n; 55 struct GNUNET_HashCode n;
56 struct GNUNET_DATACACHE_Block block;
56 char buf[3200]; 57 char buf[3200];
57 struct GNUNET_TIME_Absolute exp;
58 58
59 (void) cls; 59 (void) cls;
60 (void) args; 60 (void) args;
@@ -70,9 +70,14 @@ run (void *cls,
70 "Failed to initialize datacache. Database likely not setup, skipping test.\n"); 70 "Failed to initialize datacache. Database likely not setup, skipping test.\n");
71 return; 71 return;
72 } 72 }
73 exp = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_HOURS); 73 block.expiration_time = GNUNET_TIME_relative_to_absolute (
74 memset (buf, 1, sizeof(buf)); 74 GNUNET_TIME_UNIT_HOURS);
75 memset (&k, 0, sizeof(struct GNUNET_HashCode)); 75 memset (buf,
76 1,
77 sizeof(buf));
78 memset (&k,
79 0,
80 sizeof(struct GNUNET_HashCode));
76 for (unsigned int i = 0; i < 10; i++) 81 for (unsigned int i = 0; i < 10; i++)
77 { 82 {
78 fprintf (stderr, 83 fprintf (stderr,
@@ -83,35 +88,56 @@ run (void *cls,
83 &n); 88 &n);
84 for (unsigned int j = i; j < sizeof(buf); j += 10) 89 for (unsigned int j = i; j < sizeof(buf); j += 10)
85 { 90 {
86 exp.abs_value_us++;
87 buf[j] = i; 91 buf[j] = i;
92 block.key = k;
93 block.data = buf;
94 block.data_size = j;
95 block.ro = 42;
96 block.type = (enum GNUNET_BLOCK_Type) (1 + i);
97 block.put_path = NULL;
98 block.put_path_length = 0;
99 block.ro = GNUNET_DHT_RO_RECORD_ROUTE;
100 block.expiration_time.abs_value_us++;
88 ASSERT (GNUNET_OK == 101 ASSERT (GNUNET_OK ==
89 GNUNET_DATACACHE_put (h, 102 GNUNET_DATACACHE_put (h,
90 &k, 103 42,
91 GNUNET_YES, 104 &block));
92 j, 105 ASSERT (0 < GNUNET_DATACACHE_get (h,
93 buf, 106 &k,
94 1 + i, 107 1 + i,
95 exp, 108 NULL,
96 0, 109 NULL));
97 NULL));
98 ASSERT (0 < GNUNET_DATACACHE_get (h, &k, 1 + i, NULL, NULL));
99 } 110 }
100 k = n; 111 k = n;
101 } 112 }
102 fprintf (stderr, "%s", "\n"); 113 fprintf (stderr, "%s", "\n");
103 memset (&k, 0, sizeof(struct GNUNET_HashCode)); 114 memset (&k,
115 0,
116 sizeof(struct GNUNET_HashCode));
104 for (unsigned int i = 0; i < 10; i++) 117 for (unsigned int i = 0; i < 10; i++)
105 { 118 {
106 fprintf (stderr, "%s", "."); 119 fprintf (stderr, "%s", ".");
107 GNUNET_CRYPTO_hash (&k, sizeof(struct GNUNET_HashCode), &n); 120 GNUNET_CRYPTO_hash (&k,
121 sizeof(struct GNUNET_HashCode),
122 &n);
108 if (i < 2) 123 if (i < 2)
109 ASSERT (0 == GNUNET_DATACACHE_get (h, &k, 1 + i, NULL, NULL)); 124 ASSERT (0 ==
125 GNUNET_DATACACHE_get (h,
126 &k,
127 1 + i,
128 NULL,
129 NULL));
110 if (i == 9) 130 if (i == 9)
111 ASSERT (0 < GNUNET_DATACACHE_get (h, &k, 1 + i, NULL, NULL)); 131 ASSERT (0 < GNUNET_DATACACHE_get (h,
132 &k,
133 1 + i,
134 NULL,
135 NULL));
112 k = n; 136 k = n;
113 } 137 }
114 fprintf (stderr, "%s", "\n"); 138 fprintf (stderr,
139 "%s",
140 "\n");
115 GNUNET_DATACACHE_destroy (h); 141 GNUNET_DATACACHE_destroy (h);
116 return; 142 return;
117FAILURE: 143FAILURE:
diff --git a/src/dht/gnunet-service-dht.h b/src/dht/gnunet-service-dht.h
index a1513fcce..5507dcea0 100644
--- a/src/dht/gnunet-service-dht.h
+++ b/src/dht/gnunet-service-dht.h
@@ -149,7 +149,7 @@ GDS_u_hold (struct GDS_Underlay *u,
149 * @return true on success, false on failures 149 * @return true on success, false on failures
150 */ 150 */
151bool 151bool
152GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd, 152GDS_CLIENTS_handle_reply (const struct GNUNET_DATACACHE_Block *bd,
153 const struct GNUNET_HashCode *query_hash, 153 const struct GNUNET_HashCode *query_hash,
154 unsigned int get_path_length, 154 unsigned int get_path_length,
155 const struct GNUNET_DHT_PathElement *get_path); 155 const struct GNUNET_DHT_PathElement *get_path);
@@ -186,7 +186,7 @@ GDS_CLIENTS_process_get (enum GNUNET_DHT_RouteOption options,
186 * @param get_path_length number of entries in @a get_path. 186 * @param get_path_length number of entries in @a get_path.
187 */ 187 */
188void 188void
189GDS_CLIENTS_process_get_resp (const struct GDS_DATACACHE_BlockData *bd, 189GDS_CLIENTS_process_get_resp (const struct GNUNET_DATACACHE_Block *bd,
190 const struct GNUNET_DHT_PathElement *get_path, 190 const struct GNUNET_DHT_PathElement *get_path,
191 unsigned int get_path_length); 191 unsigned int get_path_length);
192 192
@@ -196,14 +196,12 @@ GDS_CLIENTS_process_get_resp (const struct GDS_DATACACHE_BlockData *bd,
196 * them in that case. The @a path should include our own 196 * them in that case. The @a path should include our own
197 * peer ID (if recorded). 197 * peer ID (if recorded).
198 * 198 *
199 * @param options routing options to apply
200 * @param bd details about the block 199 * @param bd details about the block
201 * @param hop_count Hop count so far. 200 * @param hop_count Hop count so far.
202 * @param desired_replication_level Desired replication level. 201 * @param desired_replication_level Desired replication level.
203 */ 202 */
204void 203void
205GDS_CLIENTS_process_put (enum GNUNET_DHT_RouteOption options, 204GDS_CLIENTS_process_put (const struct GNUNET_DATACACHE_Block *bd,
206 const struct GDS_DATACACHE_BlockData *bd,
207 uint32_t hop_count, 205 uint32_t hop_count,
208 uint32_t desired_replication_level); 206 uint32_t desired_replication_level);
209 207
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c
index fd65102b3..631c4f68b 100644
--- a/src/dht/gnunet-service-dht_clients.c
+++ b/src/dht/gnunet-service-dht_clients.c
@@ -490,16 +490,15 @@ handle_dht_local_put (void *cls,
490{ 490{
491 struct ClientHandle *ch = cls; 491 struct ClientHandle *ch = cls;
492 uint16_t size = ntohs (dht_msg->header.size); 492 uint16_t size = ntohs (dht_msg->header.size);
493 enum GNUNET_DHT_RouteOption options
494 = (enum GNUNET_DHT_RouteOption) ntohl (dht_msg->options);
495 uint32_t replication_level 493 uint32_t replication_level
496 = ntohl (dht_msg->desired_replication_level); 494 = ntohl (dht_msg->desired_replication_level);
497 struct GDS_DATACACHE_BlockData bd = { 495 struct GNUNET_DATACACHE_Block bd = {
498 .key = dht_msg->key, 496 .key = dht_msg->key,
499 .expiration_time = GNUNET_TIME_absolute_ntoh (dht_msg->expiration), 497 .expiration_time = GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
500 .data = &dht_msg[1], 498 .data = &dht_msg[1],
501 .data_size = size - sizeof (*dht_msg), 499 .data_size = size - sizeof (*dht_msg),
502 .type = ntohl (dht_msg->type) 500 .type = ntohl (dht_msg->type),
501 .ro = (enum GNUNET_DHT_RouteOption) ntohl (dht_msg->options)
503 }; 502 };
504 503
505 LOG (GNUNET_ERROR_TYPE_DEBUG, 504 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -536,14 +535,13 @@ handle_dht_local_put (void *cls,
536 DHT_BLOOM_SIZE, 535 DHT_BLOOM_SIZE,
537 GNUNET_CONSTANTS_BLOOMFILTER_K); 536 GNUNET_CONSTANTS_BLOOMFILTER_K);
538 /* store locally */ 537 /* store locally */
539 if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || 538 if ( (0 != (bd.ro & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) ||
540 (GDS_am_closest_peer (&dht_msg->key, 539 (GDS_am_closest_peer (&dht_msg->key,
541 peer_bf))) 540 peer_bf)))
542 GDS_DATACACHE_handle_put (&bd); 541 GDS_DATACACHE_handle_put (&bd);
543 /* route to other peers */ 542 /* route to other peers */
544 if (GNUNET_OK != 543 if (GNUNET_OK !=
545 GDS_NEIGHBOURS_handle_put (&bd, 544 GDS_NEIGHBOURS_handle_put (&bd,
546 options,
547 replication_level, 545 replication_level,
548 0 /* hop count */, 546 0 /* hop count */,
549 peer_bf)) 547 peer_bf))
@@ -556,7 +554,6 @@ handle_dht_local_put (void *cls,
556 GNUNET_CONTAINER_bloomfilter_free (peer_bf); 554 GNUNET_CONTAINER_bloomfilter_free (peer_bf);
557 } 555 }
558 GDS_CLIENTS_process_put ( 556 GDS_CLIENTS_process_put (
559 options,
560 &bd, 557 &bd,
561 0, /* hop count */ 558 0, /* hop count */
562 replication_level); 559 replication_level);
@@ -572,7 +569,7 @@ handle_dht_local_put (void *cls,
572 */ 569 */
573static void 570static void
574handle_local_result (void *cls, 571handle_local_result (void *cls,
575 const struct GDS_DATACACHE_BlockData *bd) 572 const struct GNUNET_DATACACHE_Block *bd)
576{ 573{
577 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 574 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
578 "Datacache provided result for query key %s\n", 575 "Datacache provided result for query key %s\n",
@@ -877,7 +874,7 @@ struct ForwardReplyContext
877 /** 874 /**
878 * Block details. 875 * Block details.
879 */ 876 */
880 const struct GDS_DATACACHE_BlockData *bd; 877 const struct GNUNET_DATACACHE_Block *bd;
881 878
882 /** 879 /**
883 * GET path taken. 880 * GET path taken.
@@ -1034,7 +1031,7 @@ forward_reply (void *cls,
1034 1031
1035 1032
1036bool 1033bool
1037GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd, 1034GDS_CLIENTS_handle_reply (const struct GNUNET_DATACACHE_Block *bd,
1038 const struct GNUNET_HashCode *query_hash, 1035 const struct GNUNET_HashCode *query_hash,
1039 unsigned int get_path_length, 1036 unsigned int get_path_length,
1040 const struct GNUNET_DHT_PathElement *get_path) 1037 const struct GNUNET_DHT_PathElement *get_path)
@@ -1414,7 +1411,7 @@ GDS_CLIENTS_process_get (enum GNUNET_DHT_RouteOption options,
1414 */ 1411 */
1415struct ResponseActionContext 1412struct ResponseActionContext
1416{ 1413{
1417 const struct GDS_DATACACHE_BlockData *bd; 1414 const struct GNUNET_DATACACHE_Block *bd;
1418 const struct GNUNET_DHT_PathElement *get_path; 1415 const struct GNUNET_DHT_PathElement *get_path;
1419 unsigned int get_path_length; 1416 unsigned int get_path_length;
1420}; 1417};
@@ -1432,7 +1429,7 @@ response_action (void *cls,
1432 struct ClientMonitorRecord *m) 1429 struct ClientMonitorRecord *m)
1433{ 1430{
1434 const struct ResponseActionContext *resp_ctx = cls; 1431 const struct ResponseActionContext *resp_ctx = cls;
1435 const struct GDS_DATACACHE_BlockData *bd = resp_ctx->bd; 1432 const struct GNUNET_DATACACHE_Block *bd = resp_ctx->bd;
1436 1433
1437 struct GNUNET_MQ_Envelope *env; 1434 struct GNUNET_MQ_Envelope *env;
1438 struct GNUNET_DHT_MonitorGetRespMessage *mmsg; 1435 struct GNUNET_DHT_MonitorGetRespMessage *mmsg;
@@ -1467,7 +1464,7 @@ response_action (void *cls,
1467 1464
1468 1465
1469void 1466void
1470GDS_CLIENTS_process_get_resp (const struct GDS_DATACACHE_BlockData *bd, 1467GDS_CLIENTS_process_get_resp (const struct GNUNET_DATACACHE_Block *bd,
1471 const struct GNUNET_DHT_PathElement *get_path, 1468 const struct GNUNET_DHT_PathElement *get_path,
1472 unsigned int get_path_length) 1469 unsigned int get_path_length)
1473{ 1470{
@@ -1489,8 +1486,7 @@ GDS_CLIENTS_process_get_resp (const struct GDS_DATACACHE_BlockData *bd,
1489 */ 1486 */
1490struct PutActionContext 1487struct PutActionContext
1491{ 1488{
1492 const struct GDS_DATACACHE_BlockData *bd; 1489 const struct GNUNET_DATACACHE_Block *bd;
1493 enum GNUNET_DHT_RouteOption options;
1494 uint32_t hop_count; 1490 uint32_t hop_count;
1495 uint32_t desired_replication_level; 1491 uint32_t desired_replication_level;
1496}; 1492};
@@ -1508,7 +1504,7 @@ put_action (void *cls,
1508 struct ClientMonitorRecord *m) 1504 struct ClientMonitorRecord *m)
1509{ 1505{
1510 const struct PutActionContext *put_ctx = cls; 1506 const struct PutActionContext *put_ctx = cls;
1511 const struct GDS_DATACACHE_BlockData *bd = put_ctx->bd; 1507 const struct GNUNET_DATACACHE_Block *bd = put_ctx->bd;
1512 struct GNUNET_MQ_Envelope *env; 1508 struct GNUNET_MQ_Envelope *env;
1513 struct GNUNET_DHT_MonitorPutMessage *mmsg; 1509 struct GNUNET_DHT_MonitorPutMessage *mmsg;
1514 struct GNUNET_DHT_PathElement *msg_path; 1510 struct GNUNET_DHT_PathElement *msg_path;
@@ -1520,7 +1516,7 @@ put_action (void *cls,
1520 env = GNUNET_MQ_msg_extra (mmsg, 1516 env = GNUNET_MQ_msg_extra (mmsg,
1521 msize, 1517 msize,
1522 GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT); 1518 GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT);
1523 mmsg->options = htonl (put_ctx->options); 1519 mmsg->options = htonl (bd->ro);
1524 mmsg->type = htonl (bd->type); 1520 mmsg->type = htonl (bd->type);
1525 mmsg->hop_count = htonl (put_ctx->hop_count); 1521 mmsg->hop_count = htonl (put_ctx->hop_count);
1526 mmsg->desired_replication_level = htonl (put_ctx->desired_replication_level); 1522 mmsg->desired_replication_level = htonl (put_ctx->desired_replication_level);
@@ -1540,16 +1536,14 @@ put_action (void *cls,
1540 1536
1541 1537
1542void 1538void
1543GDS_CLIENTS_process_put (enum GNUNET_DHT_RouteOption options, 1539GDS_CLIENTS_process_put (const struct GNUNET_DATACACHE_Block *bd,
1544 const struct GDS_DATACACHE_BlockData *bd,
1545 uint32_t hop_count, 1540 uint32_t hop_count,
1546 uint32_t desired_replication_level) 1541 uint32_t desired_replication_level)
1547{ 1542{
1548 struct PutActionContext put_ctx = { 1543 struct PutActionContext put_ctx = {
1549 .bd = bd, 1544 .bd = bd,
1550 .hop_count = hop_count, 1545 .hop_count = hop_count,
1551 .desired_replication_level = desired_replication_level, 1546 .desired_replication_level = desired_replication_level
1552 .options = options
1553 }; 1547 };
1554 1548
1555 for_matching_monitors (bd->type, 1549 for_matching_monitors (bd->type,
diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c
index be0a6db81..dcb6308a9 100644
--- a/src/dht/gnunet-service-dht_datacache.c
+++ b/src/dht/gnunet-service-dht_datacache.c
@@ -46,7 +46,7 @@ static struct GNUNET_DATACACHE_Handle *datacache;
46 46
47 47
48void 48void
49GDS_DATACACHE_handle_put (const struct GDS_DATACACHE_BlockData *bd) 49GDS_DATACACHE_handle_put (const struct GNUNET_DATACACHE_Block *bd)
50{ 50{
51 struct GNUNET_HashCode xor; 51 struct GNUNET_HashCode xor;
52 enum GNUNET_GenericReturnValue r; 52 enum GNUNET_GenericReturnValue r;
@@ -71,14 +71,8 @@ GDS_DATACACHE_handle_put (const struct GDS_DATACACHE_BlockData *bd)
71 &GDS_my_identity_hash, 71 &GDS_my_identity_hash,
72 &xor); 72 &xor);
73 r = GNUNET_DATACACHE_put (datacache, 73 r = GNUNET_DATACACHE_put (datacache,
74 &bd->key,
75 GNUNET_CRYPTO_hash_count_leading_zeros (&xor), 74 GNUNET_CRYPTO_hash_count_leading_zeros (&xor),
76 bd->data_size, 75 bd);
77 bd->data,
78 bd->type,
79 bd->expiration_time,
80 bd->put_path_length,
81 bd->put_path);
82 LOG (GNUNET_ERROR_TYPE_DEBUG, 76 LOG (GNUNET_ERROR_TYPE_DEBUG,
83 "DATACACHE PUT for key %s [%lu] completed (%d) after %u hops\n", 77 "DATACACHE PUT for key %s [%lu] completed (%d) after %u hops\n",
84 GNUNET_h2s (&bd->key), 78 GNUNET_h2s (&bd->key),
@@ -134,55 +128,34 @@ struct GetRequestContext
134 * Iterator for local get request results, 128 * Iterator for local get request results,
135 * 129 *
136 * @param cls closure for iterator, a `struct GetRequestContext` 130 * @param cls closure for iterator, a `struct GetRequestContext`
137 * @param exp when does this value expire? 131 * @param bd block data
138 * @param key the key this data is stored under
139 * @param data_size the size of the data identified by key
140 * @param data the actual data
141 * @param type the type of the @a data
142 * @param put_path_length number of peers in @a put_path
143 * @param put_path path the reply took on put
144 * @return #GNUNET_OK to continue iteration, anything else 132 * @return #GNUNET_OK to continue iteration, anything else
145 * to stop iteration. 133 * to stop iteration.
146 */ 134 */
147static enum GNUNET_GenericReturnValue 135static enum GNUNET_GenericReturnValue
148datacache_get_iterator (void *cls, 136datacache_get_iterator (void *cls,
149 const struct GNUNET_HashCode *key, 137 const struct GNUNET_DATACACHE_Block *bd)
150 size_t data_size,
151 const char *data,
152 enum GNUNET_BLOCK_Type type,
153 struct GNUNET_TIME_Absolute exp,
154 unsigned int put_path_length,
155 const struct GNUNET_DHT_PathElement *put_path)
156{ 138{
157 struct GetRequestContext *ctx = cls; 139 struct GetRequestContext *ctx = cls;
158 enum GNUNET_BLOCK_ReplyEvaluationResult eval; 140 enum GNUNET_BLOCK_ReplyEvaluationResult eval;
159 struct GDS_DATACACHE_BlockData bd = {
160 .key = *key,
161 .expiration_time = exp,
162 .put_path = put_path,
163 .data = data,
164 .data_size = data_size,
165 .put_path_length = put_path_length,
166 .type = type
167 };
168 141
169 if (GNUNET_TIME_absolute_is_past (exp)) 142 if (GNUNET_TIME_absolute_is_past (bd->expiration_time))
170 { 143 {
171 GNUNET_break (0); /* why does datacache return expired values? */ 144 GNUNET_break (0); /* why does datacache return expired values? */
172 return GNUNET_OK; /* skip expired record */ 145 return GNUNET_OK; /* skip expired record */
173 } 146 }
174 eval 147 eval
175 = GNUNET_BLOCK_check_reply (GDS_block_context, 148 = GNUNET_BLOCK_check_reply (GDS_block_context,
176 bd.type, 149 bd->type,
177 ctx->bg, 150 ctx->bg,
178 &bd.key, 151 &bd->key,
179 ctx->xquery, 152 ctx->xquery,
180 ctx->xquery_size, 153 ctx->xquery_size,
181 bd.data, 154 bd->data,
182 bd.data_size); 155 bd->data_size);
183 LOG (GNUNET_ERROR_TYPE_DEBUG, 156 LOG (GNUNET_ERROR_TYPE_DEBUG,
184 "Evaluated reply for query %s in datacache, result is %d\n", 157 "Evaluated reply for query %s in datacache, result is %d\n",
185 GNUNET_h2s (key), 158 GNUNET_h2s (&bd->key),
186 (int) eval); 159 (int) eval);
187 ctx->eval = eval; 160 ctx->eval = eval;
188 switch (eval) 161 switch (eval)
@@ -196,7 +169,7 @@ datacache_get_iterator (void *cls,
196 1, 169 1,
197 GNUNET_NO); 170 GNUNET_NO);
198 ctx->gc (ctx->gc_cls, 171 ctx->gc (ctx->gc_cls,
199 &bd); 172 bd);
200 break; 173 break;
201 case GNUNET_BLOCK_REPLY_OK_DUPLICATE: 174 case GNUNET_BLOCK_REPLY_OK_DUPLICATE:
202 GNUNET_STATISTICS_update (GDS_stats, 175 GNUNET_STATISTICS_update (GDS_stats,
@@ -225,7 +198,7 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key,
225 void *gc_cls) 198 void *gc_cls)
226{ 199{
227 struct GetRequestContext ctx = { 200 struct GetRequestContext ctx = {
228 .eval = GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED, 201 .eval = GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED,
229 .key = *key, 202 .key = *key,
230 .xquery = xquery, 203 .xquery = xquery,
231 .xquery_size = xquery_size, 204 .xquery_size = xquery_size,
@@ -265,7 +238,7 @@ GDS_DATACACHE_get_closest (const struct GNUNET_HashCode *key,
265 void *cb_cls) 238 void *cb_cls)
266{ 239{
267 struct GetRequestContext ctx = { 240 struct GetRequestContext ctx = {
268 .eval = GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED, 241 .eval = GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED,
269 .key = *key, 242 .key = *key,
270 .xquery = xquery, 243 .xquery = xquery,
271 .xquery_size = xquery_size, 244 .xquery_size = xquery_size,
diff --git a/src/dht/gnunet-service-dht_datacache.h b/src/dht/gnunet-service-dht_datacache.h
index d860139f5..b15e5378f 100644
--- a/src/dht/gnunet-service-dht_datacache.h
+++ b/src/dht/gnunet-service-dht_datacache.h
@@ -30,48 +30,7 @@
30#include "gnunet_util_lib.h" 30#include "gnunet_util_lib.h"
31#include "gnunet_block_lib.h" 31#include "gnunet_block_lib.h"
32#include "gnunet_dht_service.h" 32#include "gnunet_dht_service.h"
33 33#include "gnunet_datacache_lib.h"
34
35/**
36 * Information about a block stored in the datacache.
37 */
38struct GDS_DATACACHE_BlockData
39{
40 /**
41 * Key of the block.
42 */
43 struct GNUNET_HashCode key;
44
45 /**
46 * When does the block expire?
47 */
48 struct GNUNET_TIME_Absolute expiration_time;
49
50 /**
51 * PUT path taken by the block, array of peer identities.
52 */
53 const struct GNUNET_DHT_PathElement *put_path;
54
55 /**
56 * Actual block data.
57 */
58 const void *data;
59
60 /**
61 * Number of bytes in @a data.
62 */
63 size_t data_size;
64
65 /**
66 * Length of the @e put_path array.
67 */
68 unsigned int put_path_length;
69
70 /**
71 * Type of the block.
72 */
73 enum GNUNET_BLOCK_Type type;
74};
75 34
76 35
77/** 36/**
@@ -81,7 +40,7 @@ struct GDS_DATACACHE_BlockData
81 * @param bd block data to cache 40 * @param bd block data to cache
82 */ 41 */
83void 42void
84GDS_DATACACHE_handle_put (const struct GDS_DATACACHE_BlockData *bd); 43GDS_DATACACHE_handle_put (const struct GNUNET_DATACACHE_Block *bd);
85 44
86 45
87/** 46/**
@@ -92,7 +51,7 @@ GDS_DATACACHE_handle_put (const struct GDS_DATACACHE_BlockData *bd);
92 */ 51 */
93typedef void 52typedef void
94(*GDS_DATACACHE_GetCallback)(void *cls, 53(*GDS_DATACACHE_GetCallback)(void *cls,
95 const struct GDS_DATACACHE_BlockData *bd); 54 const struct GNUNET_DATACACHE_Block *bd);
96 55
97 56
98/** 57/**
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c
index fde25936f..2a54f715a 100644
--- a/src/dht/gnunet-service-dht_neighbours.c
+++ b/src/dht/gnunet-service-dht_neighbours.c
@@ -1285,7 +1285,7 @@ get_target_peers (const struct GNUNET_HashCode *key,
1285 * @param bd block data we got 1285 * @param bd block data we got
1286 */ 1286 */
1287static void 1287static void
1288hello_check (const struct GDS_DATACACHE_BlockData *bd) 1288hello_check (const struct GNUNET_DATACACHE_Block *bd)
1289{ 1289{
1290 struct GNUNET_PeerIdentity pid; 1290 struct GNUNET_PeerIdentity pid;
1291 struct GNUNET_HELLO_Builder *b; 1291 struct GNUNET_HELLO_Builder *b;
@@ -1305,8 +1305,7 @@ hello_check (const struct GDS_DATACACHE_BlockData *bd)
1305 1305
1306 1306
1307enum GNUNET_GenericReturnValue 1307enum GNUNET_GenericReturnValue
1308GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, 1308GDS_NEIGHBOURS_handle_put (const struct GNUNET_DATACACHE_Block *bd,
1309 enum GNUNET_DHT_RouteOption options,
1310 uint16_t desired_replication_level, 1309 uint16_t desired_replication_level,
1311 uint16_t hop_count, 1310 uint16_t hop_count,
1312 struct GNUNET_CONTAINER_BloomFilter *bf) 1311 struct GNUNET_CONTAINER_BloomFilter *bf)
@@ -1336,8 +1335,8 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd,
1336 "Adding myself (%s) to PUT bloomfilter for %s with RO(%s/%s)\n", 1335 "Adding myself (%s) to PUT bloomfilter for %s with RO(%s/%s)\n",
1337 GNUNET_i2s (&GDS_my_identity), 1336 GNUNET_i2s (&GDS_my_identity),
1338 GNUNET_h2s (&bd->key), 1337 GNUNET_h2s (&bd->key),
1339 (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE) ? "x" : "-", 1338 (bd->ro & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE) ? "x" : "-",
1340 (options & GNUNET_DHT_RO_RECORD_ROUTE) ? "R" : "-"); 1339 (bd->ro & GNUNET_DHT_RO_RECORD_ROUTE) ? "R" : "-");
1341 1340
1342 /* if we got a HELLO, consider it for our own routing table */ 1341 /* if we got a HELLO, consider it for our own routing table */
1343 hello_check (bd); 1342 hello_check (bd);
@@ -1394,7 +1393,7 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd,
1394 ppm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_PUT); 1393 ppm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_PUT);
1395 ppm->header.size = htons (sizeof (buf)); 1394 ppm->header.size = htons (sizeof (buf));
1396 ppm->type = htonl (bd->type); 1395 ppm->type = htonl (bd->type);
1397 ppm->options = htons (options); 1396 ppm->options = htons (bd->ro);
1398 ppm->hop_count = htons (hop_count + 1); 1397 ppm->hop_count = htons (hop_count + 1);
1399 ppm->desired_replication_level = htons (desired_replication_level); 1398 ppm->desired_replication_level = htons (desired_replication_level);
1400 ppm->put_path_length = htons (put_path_length); 1399 ppm->put_path_length = htons (put_path_length);
@@ -1565,7 +1564,7 @@ GDS_NEIGHBOURS_lookup_peer (const struct GNUNET_PeerIdentity *target)
1565 1564
1566bool 1565bool
1567GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, 1566GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
1568 const struct GDS_DATACACHE_BlockData *bd, 1567 const struct GNUNET_DATACACHE_Block *bd,
1569 const struct GNUNET_HashCode *query_hash, 1568 const struct GNUNET_HashCode *query_hash,
1570 unsigned int get_path_length, 1569 unsigned int get_path_length,
1571 const struct GNUNET_DHT_PathElement *get_path) 1570 const struct GNUNET_DHT_PathElement *get_path)
@@ -1748,16 +1747,15 @@ handle_dht_p2p_put (void *cls,
1748 struct Target *t = cls; 1747 struct Target *t = cls;
1749 struct PeerInfo *peer = t->pi; 1748 struct PeerInfo *peer = t->pi;
1750 uint16_t msize = ntohs (put->header.size); 1749 uint16_t msize = ntohs (put->header.size);
1751 enum GNUNET_DHT_RouteOption options
1752 = (enum GNUNET_DHT_RouteOption) ntohs (put->options);
1753 const struct GNUNET_DHT_PathElement *put_path 1750 const struct GNUNET_DHT_PathElement *put_path
1754 = (const struct GNUNET_DHT_PathElement *) &put[1]; 1751 = (const struct GNUNET_DHT_PathElement *) &put[1];
1755 uint16_t putlen 1752 uint16_t putlen
1756 = ntohs (put->put_path_length); 1753 = ntohs (put->put_path_length);
1757 struct GDS_DATACACHE_BlockData bd = { 1754 struct GNUNET_DATACACHE_Block bd = {
1758 .key = put->key, 1755 .key = put->key,
1759 .expiration_time = GNUNET_TIME_absolute_ntoh (put->expiration_time), 1756 .expiration_time = GNUNET_TIME_absolute_ntoh (put->expiration_time),
1760 .type = ntohl (put->type), 1757 .type = ntohl (put->type),
1758 .ro = (enum GNUNET_DHT_RouteOption) ntohs (put->options),
1761 .data_size = msize - (sizeof(*put) 1759 .data_size = msize - (sizeof(*put)
1762 + putlen * sizeof(struct GNUNET_DHT_PathElement)), 1760 + putlen * sizeof(struct GNUNET_DHT_PathElement)),
1763 .data = &put_path[putlen] 1761 .data = &put_path[putlen]
@@ -1767,8 +1765,8 @@ handle_dht_p2p_put (void *cls,
1767 "PUT for `%s' from %s with RO (%s/%s)\n", 1765 "PUT for `%s' from %s with RO (%s/%s)\n",
1768 GNUNET_h2s (&put->key), 1766 GNUNET_h2s (&put->key),
1769 GNUNET_i2s (&peer->id), 1767 GNUNET_i2s (&peer->id),
1770 (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE) ? "x" : "-", 1768 (bd.ro & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE) ? "x" : "-",
1771 (options & GNUNET_DHT_RO_RECORD_ROUTE) ? "R" : "-"); 1769 (bd.ro & GNUNET_DHT_RO_RECORD_ROUTE) ? "R" : "-");
1772 if (GNUNET_TIME_absolute_is_past (bd.expiration_time)) 1770 if (GNUNET_TIME_absolute_is_past (bd.expiration_time))
1773 { 1771 {
1774 GNUNET_STATISTICS_update (GDS_stats, 1772 GNUNET_STATISTICS_update (GDS_stats,
@@ -1786,7 +1784,7 @@ handle_dht_p2p_put (void *cls,
1786 GNUNET_break_op (0); 1784 GNUNET_break_op (0);
1787 return; 1785 return;
1788 } 1786 }
1789 if (0 == (options & GNUNET_DHT_RO_RECORD_ROUTE)) 1787 if (0 == (bd.ro & GNUNET_DHT_RO_RECORD_ROUTE))
1790 putlen = 0; 1788 putlen = 0;
1791 GNUNET_STATISTICS_update (GDS_stats, 1789 GNUNET_STATISTICS_update (GDS_stats,
1792 "# P2P PUT requests received", 1790 "# P2P PUT requests received",
@@ -1837,7 +1835,7 @@ handle_dht_p2p_put (void *cls,
1837 /* extend 'put path' by sender */ 1835 /* extend 'put path' by sender */
1838 bd.put_path = (const struct GNUNET_DHT_PathElement *) pp; 1836 bd.put_path = (const struct GNUNET_DHT_PathElement *) pp;
1839 bd.put_path_length = putlen + 1; 1837 bd.put_path_length = putlen + 1;
1840 if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE)) 1838 if (0 != (bd.ro & GNUNET_DHT_RO_RECORD_ROUTE))
1841 { 1839 {
1842 unsigned int failure_offset; 1840 unsigned int failure_offset;
1843 1841
@@ -1884,7 +1882,7 @@ handle_dht_p2p_put (void *cls,
1884 0, NULL /* get path */)); 1882 0, NULL /* get path */));
1885 1883
1886 /* store locally */ 1884 /* store locally */
1887 if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || 1885 if ( (0 != (bd.ro & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) ||
1888 (GDS_am_closest_peer (&put->key, 1886 (GDS_am_closest_peer (&put->key,
1889 bf)) ) 1887 bf)) )
1890 GDS_DATACACHE_handle_put (&bd); 1888 GDS_DATACACHE_handle_put (&bd);
@@ -1894,16 +1892,14 @@ handle_dht_p2p_put (void *cls,
1894 /* route to other peers */ 1892 /* route to other peers */
1895 forwarded 1893 forwarded
1896 = GDS_NEIGHBOURS_handle_put (&bd, 1894 = GDS_NEIGHBOURS_handle_put (&bd,
1897 options,
1898 ntohs (put->desired_replication_level), 1895 ntohs (put->desired_replication_level),
1899 ntohs (put->hop_count), 1896 ntohs (put->hop_count),
1900 bf); 1897 bf);
1901 /* notify monitoring clients */ 1898 /* notify monitoring clients */
1902 GDS_CLIENTS_process_put (options 1899 bd.ro |= ((GNUNET_OK == forwarded)
1903 | ((GNUNET_OK == forwarded) 1900 ? GNUNET_DHT_RO_LAST_HOP
1904 ? GNUNET_DHT_RO_LAST_HOP 1901 : 0);
1905 : 0), 1902 GDS_CLIENTS_process_put (&bd,
1906 &bd,
1907 ntohs (put->hop_count), 1903 ntohs (put->hop_count),
1908 ntohs (put->desired_replication_level)); 1904 ntohs (put->desired_replication_level));
1909 } 1905 }
@@ -1957,7 +1953,7 @@ handle_find_my_hello (struct PeerInfo *pi,
1957 block, 1953 block,
1958 block_size)) 1954 block_size))
1959 { 1955 {
1960 struct GDS_DATACACHE_BlockData bd = { 1956 struct GNUNET_DATACACHE_Block bd = {
1961 .type = GNUNET_BLOCK_TYPE_DHT_URL_HELLO, 1957 .type = GNUNET_BLOCK_TYPE_DHT_URL_HELLO,
1962 .expiration_time 1958 .expiration_time
1963 = GNUNET_TIME_relative_to_absolute ( 1959 = GNUNET_TIME_relative_to_absolute (
@@ -2014,7 +2010,7 @@ handle_find_local_hello (struct PeerInfo *pi,
2014 peer->hello, 2010 peer->hello,
2015 peer->hello_size)) ) 2011 peer->hello_size)) )
2016 { 2012 {
2017 struct GDS_DATACACHE_BlockData bd = { 2013 struct GNUNET_DATACACHE_Block bd = {
2018 .type = GNUNET_BLOCK_TYPE_DHT_URL_HELLO, 2014 .type = GNUNET_BLOCK_TYPE_DHT_URL_HELLO,
2019 .expiration_time = peer->hello_expiration, 2015 .expiration_time = peer->hello_expiration,
2020 .key = peer->phash, 2016 .key = peer->phash,
@@ -2038,7 +2034,7 @@ handle_find_local_hello (struct PeerInfo *pi,
2038 */ 2034 */
2039static void 2035static void
2040handle_local_result (void *cls, 2036handle_local_result (void *cls,
2041 const struct GDS_DATACACHE_BlockData *bd) 2037 const struct GNUNET_DATACACHE_Block *bd)
2042{ 2038{
2043 struct PeerInfo *peer = cls; 2039 struct PeerInfo *peer = cls;
2044 2040
@@ -2242,7 +2238,7 @@ handle_dht_p2p_get (void *cls,
2242 * @return true on success 2238 * @return true on success
2243 */ 2239 */
2244static bool 2240static bool
2245process_reply_with_path (const struct GDS_DATACACHE_BlockData *bd, 2241process_reply_with_path (const struct GNUNET_DATACACHE_Block *bd,
2246 const struct GNUNET_HashCode *query_hash, 2242 const struct GNUNET_HashCode *query_hash,
2247 unsigned int get_path_length, 2243 unsigned int get_path_length,
2248 const struct GNUNET_DHT_PathElement *get_path) 2244 const struct GNUNET_DHT_PathElement *get_path)
@@ -2265,7 +2261,7 @@ process_reply_with_path (const struct GDS_DATACACHE_BlockData *bd,
2265 { 2261 {
2266 struct GNUNET_DHT_PathElement xput_path[GNUNET_NZL (get_path_length 2262 struct GNUNET_DHT_PathElement xput_path[GNUNET_NZL (get_path_length
2267 + bd->put_path_length)]; 2263 + bd->put_path_length)];
2268 struct GDS_DATACACHE_BlockData bdx = *bd; 2264 struct GNUNET_DATACACHE_Block bdx = *bd;
2269 2265
2270 GNUNET_memcpy (xput_path, 2266 GNUNET_memcpy (xput_path,
2271 bd->put_path, 2267 bd->put_path,
@@ -2332,7 +2328,7 @@ handle_dht_p2p_result (void *cls,
2332 struct PeerInfo *peer = t->pi; 2328 struct PeerInfo *peer = t->pi;
2333 uint16_t msize = ntohs (prm->header.size); 2329 uint16_t msize = ntohs (prm->header.size);
2334 uint16_t get_path_length = ntohs (prm->get_path_length); 2330 uint16_t get_path_length = ntohs (prm->get_path_length);
2335 struct GDS_DATACACHE_BlockData bd = { 2331 struct GNUNET_DATACACHE_Block bd = {
2336 .expiration_time = GNUNET_TIME_absolute_ntoh (prm->expiration_time), 2332 .expiration_time = GNUNET_TIME_absolute_ntoh (prm->expiration_time),
2337 .put_path = (const struct GNUNET_DHT_PathElement *) &prm[1], 2333 .put_path = (const struct GNUNET_DHT_PathElement *) &prm[1],
2338 .put_path_length = ntohs (prm->put_path_length), 2334 .put_path_length = ntohs (prm->put_path_length),
diff --git a/src/dht/gnunet-service-dht_neighbours.h b/src/dht/gnunet-service-dht_neighbours.h
index 4f4172f71..96db21b9b 100644
--- a/src/dht/gnunet-service-dht_neighbours.h
+++ b/src/dht/gnunet-service-dht_neighbours.h
@@ -54,15 +54,13 @@ GDS_NEIGHBOURS_lookup_peer (const struct GNUNET_PeerIdentity *target);
54 * network). 54 * network).
55 * 55 *
56 * @param bd data about the block 56 * @param bd data about the block
57 * @param options routing options
58 * @param desired_replication_level desired replication level 57 * @param desired_replication_level desired replication level
59 * @param hop_count how many hops has this message traversed so far 58 * @param hop_count how many hops has this message traversed so far
60 * @param bf Bloom filter of peers this PUT has already traversed 59 * @param bf Bloom filter of peers this PUT has already traversed
61 * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not 60 * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not
62 */ 61 */
63enum GNUNET_GenericReturnValue 62enum GNUNET_GenericReturnValue
64GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, 63GDS_NEIGHBOURS_handle_put (const struct GNUNET_DATACACHE_Block *bd,
65 enum GNUNET_DHT_RouteOption options,
66 uint16_t desired_replication_level, 64 uint16_t desired_replication_level,
67 uint16_t hop_count, 65 uint16_t hop_count,
68 struct GNUNET_CONTAINER_BloomFilter *bf); 66 struct GNUNET_CONTAINER_BloomFilter *bf);
@@ -112,7 +110,7 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
112 */ 110 */
113bool 111bool
114GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, 112GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
115 const struct GDS_DATACACHE_BlockData *bd, 113 const struct GNUNET_DATACACHE_Block *bd,
116 const struct GNUNET_HashCode *query_hash, 114 const struct GNUNET_HashCode *query_hash,
117 unsigned int get_path_length, 115 unsigned int get_path_length,
118 const struct GNUNET_DHT_PathElement *get_path); 116 const struct GNUNET_DHT_PathElement *get_path);
diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c
index 6deb5fa16..8f87751bb 100644
--- a/src/dht/gnunet-service-dht_routing.c
+++ b/src/dht/gnunet-service-dht_routing.c
@@ -105,7 +105,7 @@ struct ProcessContext
105 /** 105 /**
106 * Block data. 106 * Block data.
107 */ 107 */
108 const struct GDS_DATACACHE_BlockData *bd; 108 const struct GNUNET_DATACACHE_Block *bd;
109 109
110 /** 110 /**
111 * Path of the reply. 111 * Path of the reply.
@@ -137,7 +137,7 @@ process (void *cls,
137 struct RecentRequest *rr = value; 137 struct RecentRequest *rr = value;
138 enum GNUNET_BLOCK_ReplyEvaluationResult eval; 138 enum GNUNET_BLOCK_ReplyEvaluationResult eval;
139 unsigned int get_path_length; 139 unsigned int get_path_length;
140 struct GDS_DATACACHE_BlockData bdx = *pc->bd; 140 struct GNUNET_DATACACHE_Block bdx = *pc->bd;
141 141
142 if ( (rr->type != GNUNET_BLOCK_TYPE_ANY) && 142 if ( (rr->type != GNUNET_BLOCK_TYPE_ANY) &&
143 (rr->type != pc->bd->type) ) 143 (rr->type != pc->bd->type) )
@@ -252,7 +252,7 @@ process (void *cls,
252 * @param get_path peers this reply has traversed so far (if tracked) 252 * @param get_path peers this reply has traversed so far (if tracked)
253 */ 253 */
254void 254void
255GDS_ROUTING_process (const struct GDS_DATACACHE_BlockData *bd, 255GDS_ROUTING_process (const struct GNUNET_DATACACHE_Block *bd,
256 const struct GNUNET_HashCode *query_hash, 256 const struct GNUNET_HashCode *query_hash,
257 unsigned int get_path_length, 257 unsigned int get_path_length,
258 const struct GNUNET_DHT_PathElement *get_path) 258 const struct GNUNET_DHT_PathElement *get_path)
diff --git a/src/dht/gnunet-service-dht_routing.h b/src/dht/gnunet-service-dht_routing.h
index 1e35f3dc0..08c7de870 100644
--- a/src/dht/gnunet-service-dht_routing.h
+++ b/src/dht/gnunet-service-dht_routing.h
@@ -44,7 +44,7 @@
44 * @param get_path peers this reply has traversed so far (if tracked) 44 * @param get_path peers this reply has traversed so far (if tracked)
45 */ 45 */
46void 46void
47GDS_ROUTING_process (const struct GDS_DATACACHE_BlockData *bd, 47GDS_ROUTING_process (const struct GNUNET_DATACACHE_Block *bd,
48 const struct GNUNET_HashCode *query_hash, 48 const struct GNUNET_HashCode *query_hash,
49 unsigned int get_path_length, 49 unsigned int get_path_length,
50 const struct GNUNET_DHT_PathElement *get_path); 50 const struct GNUNET_DHT_PathElement *get_path);
diff --git a/src/gnsrecord/gnunet-gnsrecord-tvg.c b/src/gnsrecord/gnunet-gnsrecord-tvg.c
index d45b3a5d8..4d5eb73b3 100644
--- a/src/gnsrecord/gnunet-gnsrecord-tvg.c
+++ b/src/gnsrecord/gnunet-gnsrecord-tvg.c
@@ -173,7 +173,7 @@ run_pkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char *label)
173 printf ("Label:\n"); 173 printf ("Label:\n");
174 print_bytes (conv_lbl, strlen (conv_lbl), 8); 174 print_bytes (conv_lbl, strlen (conv_lbl), 8);
175 GNUNET_free (conv_lbl); 175 GNUNET_free (conv_lbl);
176 printf ("\Number of records (integer): %d\n\n", rd_count); 176 printf ("\nNumber of records (integer): %d\n\n", rd_count);
177 177
178 for (int i = 0; i < rd_count; i++) 178 for (int i = 0; i < rd_count; i++)
179 { 179 {
@@ -300,7 +300,7 @@ run_edkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char*label)
300 print_bytes (conv_lbl, strlen (conv_lbl), 8); 300 print_bytes (conv_lbl, strlen (conv_lbl), 8);
301 GNUNET_free (conv_lbl); 301 GNUNET_free (conv_lbl);
302 fprintf (stdout, 302 fprintf (stdout,
303 "\Number of records (integer): %d\n\n", rd_count); 303 "\nNumber of records (integer): %d\n\n", rd_count);
304 304
305 for (int i = 0; i < rd_count; i++) 305 for (int i = 0; i < rd_count; i++)
306 { 306 {
diff --git a/src/include/gnunet_datacache_lib.h b/src/include/gnunet_datacache_lib.h
index 737a5c845..c4d74524a 100644
--- a/src/include/gnunet_datacache_lib.h
+++ b/src/include/gnunet_datacache_lib.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2006, 2009, 2015 GNUnet e.V. 3 Copyright (C) 2006, 2009, 2015, 2022 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -51,6 +51,53 @@ extern "C"
51 51
52 52
53/** 53/**
54 * Information about a block stored in the datacache.
55 */
56struct GNUNET_DATACACHE_Block
57{
58 /**
59 * Key of the block.
60 */
61 struct GNUNET_HashCode key;
62
63 /**
64 * When does the block expire?
65 */
66 struct GNUNET_TIME_Absolute expiration_time;
67
68 /**
69 * PUT path taken by the block, array of peer identities.
70 */
71 const struct GNUNET_DHT_PathElement *put_path;
72
73 /**
74 * Actual block data.
75 */
76 const void *data;
77
78 /**
79 * Number of bytes in @a data.
80 */
81 size_t data_size;
82
83 /**
84 * Length of the @e put_path array.
85 */
86 unsigned int put_path_length;
87
88 /**
89 * Type of the block.
90 */
91 enum GNUNET_BLOCK_Type type;
92
93 /**
94 * Options for routing for the block.
95 */
96 enum GNUNET_DHT_RouteOption ro;
97};
98
99
100/**
54 * Handle to the cache. 101 * Handle to the cache.
55 */ 102 */
56struct GNUNET_DATACACHE_Handle; 103struct GNUNET_DATACACHE_Handle;
@@ -81,50 +128,26 @@ GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h);
81 * An iterator over a set of items stored in the datacache. 128 * An iterator over a set of items stored in the datacache.
82 * 129 *
83 * @param cls closure 130 * @param cls closure
84 * @param key key for the content 131 * @param block a block from the datacache
85 * @param data_size number of bytes in @a data
86 * @param data content stored
87 * @param type type of the content
88 * @param exp when will the content expire?
89 * @param path_info_len number of entries in @a path_info
90 * @param path_info a path through the network
91 * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort 132 * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort
92 */ 133 */
93typedef enum GNUNET_GenericReturnValue 134typedef enum GNUNET_GenericReturnValue
94(*GNUNET_DATACACHE_Iterator)(void *cls, 135(*GNUNET_DATACACHE_Iterator)(void *cls,
95 const struct GNUNET_HashCode *key, 136 const struct GNUNET_DATACACHE_Block *block);
96 size_t data_size,
97 const char *data,
98 enum GNUNET_BLOCK_Type type,
99 struct GNUNET_TIME_Absolute exp,
100 unsigned int path_info_len,
101 const struct GNUNET_DHT_PathElement *path_info);
102 137
103 138
104/** 139/**
105 * Store an item in the datacache. 140 * Store an item in the datacache.
106 * 141 *
107 * @param h handle to the datacache 142 * @param h handle to the datacache
108 * @param key key to store data under 143 * @param xor_distance how close is the block's key to our pid?
109 * @param how close is @a key to our pid? 144 * @param block actual block data to store
110 * @param data_size number of bytes in @a data
111 * @param data data to store
112 * @param type type of the value
113 * @param discard_time when to discard the value in any case
114 * @param path_info_len number of entries in @a path_info
115 * @param path_info a path through the network
116 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error, #GNUNET_NO if duplicate 145 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error, #GNUNET_NO if duplicate
117 */ 146 */
118enum GNUNET_GenericReturnValue 147enum GNUNET_GenericReturnValue
119GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h, 148GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
120 const struct GNUNET_HashCode *key,
121 uint32_t xor_distance, 149 uint32_t xor_distance,
122 size_t data_size, 150 const struct GNUNET_DATACACHE_Block *block);
123 const char *data,
124 enum GNUNET_BLOCK_Type type,
125 struct GNUNET_TIME_Absolute discard_time,
126 unsigned int path_info_len,
127 const struct GNUNET_DHT_PathElement *path_info);
128 151
129 152
130/** 153/**
diff --git a/src/include/gnunet_datacache_plugin.h b/src/include/gnunet_datacache_plugin.h
index 34bf5f277..7e63d87d9 100644
--- a/src/include/gnunet_datacache_plugin.h
+++ b/src/include/gnunet_datacache_plugin.h
@@ -105,26 +105,14 @@ struct GNUNET_DATACACHE_PluginFunctions
105 * Store an item in the datastore. 105 * Store an item in the datastore.
106 * 106 *
107 * @param cls closure (internal context for the plugin) 107 * @param cls closure (internal context for the plugin)
108 * @param key key to store the value under
109 * @param xor_distance how close is @a key to our PID? 108 * @param xor_distance how close is @a key to our PID?
110 * @param size number of bytes in @a data 109 * @param block data to store
111 * @param data data to store
112 * @param type type of the value
113 * @param discard_time when to discard the value in any case
114 * @param path_info_len number of entries in @a path_info
115 * @param path_info a path through the network
116 * @return 0 if duplicate, -1 on error, number of bytes used otherwise 110 * @return 0 if duplicate, -1 on error, number of bytes used otherwise
117 */ 111 */
118 ssize_t 112 ssize_t
119 (*put) (void *cls, 113 (*put) (void *cls,
120 const struct GNUNET_HashCode *key,
121 uint32_t xor_distance, 114 uint32_t xor_distance,
122 size_t size, 115 const struct GNUNET_DATACACHE_Block *block);
123 const char *data,
124 enum GNUNET_BLOCK_Type type,
125 struct GNUNET_TIME_Absolute discard_time,
126 unsigned int path_info_len,
127 const struct GNUNET_DHT_PathElement *path_info);
128 116
129 117
130 /** 118 /**
diff --git a/src/include/gnunet_dht_service.h b/src/include/gnunet_dht_service.h
index 22b659d66..d683ae0bf 100644
--- a/src/include/gnunet_dht_service.h
+++ b/src/include/gnunet_dht_service.h
@@ -106,10 +106,15 @@ enum GNUNET_DHT_RouteOption
106 GNUNET_DHT_RO_FIND_APPROXIMATE = 4, 106 GNUNET_DHT_RO_FIND_APPROXIMATE = 4,
107 107
108 /** 108 /**
109 * Flag set if the path was truncated.
110 */
111 GNUNET_DHT_RO_TRUNCATED = 8,
112
113 /**
109 * Flag given to monitors if this was the last hop for a GET/PUT. 114 * Flag given to monitors if this was the last hop for a GET/PUT.
110 * This is only used for internal processing. 115 * This is only used for internal processing.
111 */ 116 */
112 GNUNET_DHT_RO_LAST_HOP = 65535 117 GNUNET_DHT_RO_LAST_HOP = 32768
113}; 118};
114 119
115 120
diff --git a/src/include/gnunet_sq_lib.h b/src/include/gnunet_sq_lib.h
index e89ded07e..51713e755 100644
--- a/src/include/gnunet_sq_lib.h
+++ b/src/include/gnunet_sq_lib.h
@@ -194,7 +194,7 @@ GNUNET_SQ_query_param_uint64 (const uint64_t *x);
194 * @param params parameters to the statement 194 * @param params parameters to the statement
195 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 195 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
196 */ 196 */
197int 197enum GNUNET_GenericReturnValue
198GNUNET_SQ_bind (sqlite3_stmt *stmt, 198GNUNET_SQ_bind (sqlite3_stmt *stmt,
199 const struct GNUNET_SQ_QueryParam *params); 199 const struct GNUNET_SQ_QueryParam *params);
200 200
@@ -498,7 +498,7 @@ GNUNET_SQ_make_prepare (const char *sql,
498 * @param ps array of statements to prepare 498 * @param ps array of statements to prepare
499 * @return #GNUNET_OK on success 499 * @return #GNUNET_OK on success
500 */ 500 */
501int 501enum GNUNET_GenericReturnValue
502GNUNET_SQ_prepare (sqlite3 *dbh, 502GNUNET_SQ_prepare (sqlite3 *dbh,
503 const struct GNUNET_SQ_PrepareStatement *ps); 503 const struct GNUNET_SQ_PrepareStatement *ps);
504 504
@@ -520,7 +520,7 @@ struct GNUNET_SQ_ExecuteStatement
520 /** 520 /**
521 * Should we ignore errors? 521 * Should we ignore errors?
522 */ 522 */
523 int ignore_errors; 523 bool ignore_errors;
524}; 524};
525 525
526 526
@@ -560,7 +560,7 @@ GNUNET_SQ_make_try_execute (const char *sql);
560 * @return #GNUNET_OK on success (modulo statements where errors can be ignored) 560 * @return #GNUNET_OK on success (modulo statements where errors can be ignored)
561 * #GNUNET_SYSERR on error 561 * #GNUNET_SYSERR on error
562 */ 562 */
563int 563enum GNUNET_GenericReturnValue
564GNUNET_SQ_exec_statements (sqlite3 *dbh, 564GNUNET_SQ_exec_statements (sqlite3 *dbh,
565 const struct GNUNET_SQ_ExecuteStatement *es); 565 const struct GNUNET_SQ_ExecuteStatement *es);
566 566