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