aboutsummaryrefslogtreecommitdiff
path: root/src/namestore
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2022-10-19 00:17:15 +0900
committerMartin Schanzenbach <schanzen@gnunet.org>2022-10-19 00:17:15 +0900
commit282b9d3694d2b3052dc0c5a971dec85e7158faca (patch)
treee52075d753f5f16d817ed476f913bf80f453c4dd /src/namestore
parent37f81821bc98f2342185a4bec3de044000be3596 (diff)
downloadgnunet-282b9d3694d2b3052dc0c5a971dec85e7158faca.tar.gz
gnunet-282b9d3694d2b3052dc0c5a971dec85e7158faca.zip
NAMESTORE: Do not return orphaned zones to clients. Issue #7201
Diffstat (limited to 'src/namestore')
-rw-r--r--src/namestore/gnunet-service-namestore.c277
1 files changed, 258 insertions, 19 deletions
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c
index 9b6428872..b2cc826fd 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -243,6 +243,11 @@ struct ZoneMonitor
243 int in_first_iteration; 243 int in_first_iteration;
244 244
245 /** 245 /**
246 * Run again because we skipped an orphan
247 */
248 int run_again;
249
250 /**
246 * Is there a store activity waiting for this monitor? We only raise the 251 * Is there a store activity waiting for this monitor? We only raise the
247 * flag when it happens and search the DLL for the store activity when we 252 * flag when it happens and search the DLL for the store activity when we
248 * had a limit increase. If we cannot find any waiting store activity at 253 * had a limit increase. If we cannot find any waiting store activity at
@@ -335,6 +340,36 @@ struct NickCache
335 struct GNUNET_TIME_Absolute last_used; 340 struct GNUNET_TIME_Absolute last_used;
336}; 341};
337 342
343/**
344 * The default namestore ego
345 */
346struct EgoEntry
347{
348 /**
349 * DLL
350 */
351 struct EgoEntry *next;
352
353 /**
354 * DLL
355 */
356 struct EgoEntry *prev;
357
358 /**
359 * Ego Identifier
360 */
361 char *identifier;
362
363 /**
364 * Public key string
365 */
366 char *keystring;
367
368 /**
369 * The Ego
370 */
371 struct GNUNET_IDENTITY_Ego *ego;
372};
338 373
339/** 374/**
340 * We cache nick records to reduce DB load. 375 * We cache nick records to reduce DB load.
@@ -357,6 +392,27 @@ static const struct GNUNET_CONFIGURATION_Handle *GSN_cfg;
357static struct GNUNET_STATISTICS_Handle *statistics; 392static struct GNUNET_STATISTICS_Handle *statistics;
358 393
359/** 394/**
395 * Handle to the identity service
396 */
397static struct GNUNET_IDENTITY_Handle *identity_handle;
398
399/**
400 * Indicator if we already have passed the first iteration if egos
401 */
402static int egos_collected = GNUNET_NO;
403
404/**
405 * Ego list
406 */
407static struct EgoEntry *ego_head;
408
409/**
410 * Ego list
411 */
412static struct EgoEntry *ego_tail;
413
414
415/**
360 * Name of the database plugin 416 * Name of the database plugin
361 */ 417 */
362static char *db_lib_name; 418static char *db_lib_name;
@@ -406,6 +462,9 @@ static int cache_keys;
406static void 462static void
407cleanup_task (void *cls) 463cleanup_task (void *cls)
408{ 464{
465 struct EgoEntry *ego_entry;
466 struct EgoEntry *ego_tmp;
467
409 (void) cls; 468 (void) cls;
410 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n"); 469 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n");
411 if (NULL != monitor_nc) 470 if (NULL != monitor_nc)
@@ -418,6 +477,20 @@ cleanup_task (void *cls)
418 GNUNET_STATISTICS_destroy (statistics, GNUNET_NO); 477 GNUNET_STATISTICS_destroy (statistics, GNUNET_NO);
419 statistics = NULL; 478 statistics = NULL;
420 } 479 }
480 if (NULL != identity_handle)
481 {
482 GNUNET_IDENTITY_disconnect (identity_handle);
483 identity_handle = NULL;
484 // FIXME cleanup EgoEntries
485 }
486 for (ego_entry = ego_head; NULL != ego_entry;)
487 {
488 ego_tmp = ego_entry;
489 ego_entry = ego_entry->next;
490 GNUNET_free (ego_tmp->identifier);
491 GNUNET_free (ego_tmp->keystring);
492 GNUNET_free (ego_tmp);
493 }
421 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, GSN_database)); 494 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, GSN_database));
422 GNUNET_free (db_lib_name); 495 GNUNET_free (db_lib_name);
423 db_lib_name = NULL; 496 db_lib_name = NULL;
@@ -436,6 +509,48 @@ free_store_activity (struct StoreActivity *sa)
436 GNUNET_free (sa); 509 GNUNET_free (sa);
437} 510}
438 511
512static enum GNUNET_GenericReturnValue
513is_orphaned (const struct GNUNET_IDENTITY_PrivateKey *zone)
514{
515 struct EgoEntry *ego_entry;
516 struct GNUNET_IDENTITY_PublicKey pk;
517 char *keystring;
518
519 GNUNET_IDENTITY_key_get_public (zone, &pk);
520 keystring = GNUNET_IDENTITY_public_key_to_string (&pk);
521
522 for (ego_entry = ego_head; NULL != ego_entry;
523 ego_entry = ego_entry->next)
524 {
525 if (0 == strcmp (ego_entry->keystring, keystring))
526 break;
527 }
528 if (NULL != ego_entry)
529 {
530 GNUNET_free (keystring);
531 return GNUNET_NO;
532 }
533 /*if (purge_orphans)
534 {
535 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
536 "Removing orphaned zone data for ego %s\n",
537 ego_entry->keystring);
538 res = GSN_database->delete_records (GSN_database->cls,
539 zone,
540 &emsg);
541 if (GNUNET_SYSERR == res)
542 {
543 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
544 "Error removing orphaned zone data: %s\n", emsg);
545 }
546 }*/
547 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
548 "Found orphaned zone data for zone key %s\n",
549 keystring);
550 GNUNET_free (keystring);
551 return GNUNET_YES;
552}
553
439 554
440/** 555/**
441 * Function called with the records for the #GNUNET_GNS_EMPTY_LABEL_AT 556 * Function called with the records for the #GNUNET_GNS_EMPTY_LABEL_AT
@@ -1958,6 +2073,11 @@ struct ZoneIterationProcResult
1958 * Number of results left to be returned in this iteration. 2073 * Number of results left to be returned in this iteration.
1959 */ 2074 */
1960 uint64_t limit; 2075 uint64_t limit;
2076
2077 /**
2078 * Skip a result and run again unless GNUNET_NO
2079 */
2080 int run_again;
1961}; 2081};
1962 2082
1963 2083
@@ -1999,8 +2119,15 @@ zone_iterate_proc (void *cls,
1999 GNUNET_break (0); 2119 GNUNET_break (0);
2000 return; 2120 return;
2001 } 2121 }
2002 proc->limit--;
2003 proc->zi->seq = seq; 2122 proc->zi->seq = seq;
2123 if (GNUNET_YES == is_orphaned (zone_key))
2124 {
2125 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2126 "Skipping orphaned zone data\n");
2127 proc->run_again = GNUNET_YES;
2128 return;
2129 }
2130 proc->limit--;
2004 send_lookup_response_with_filter (proc->zi->nc, 2131 send_lookup_response_with_filter (proc->zi->nc,
2005 proc->zi->request_id, 2132 proc->zi->request_id,
2006 zone_key, 2133 zone_key,
@@ -2032,18 +2159,23 @@ run_zone_iteration_round (struct ZoneIteration *zi, uint64_t limit)
2032 (unsigned long long) zi->seq); 2159 (unsigned long long) zi->seq);
2033 proc.zi = zi; 2160 proc.zi = zi;
2034 proc.limit = limit; 2161 proc.limit = limit;
2162 proc.run_again = GNUNET_YES;
2035 start = GNUNET_TIME_absolute_get (); 2163 start = GNUNET_TIME_absolute_get ();
2036 GNUNET_break (GNUNET_SYSERR != 2164 while (GNUNET_YES == proc.run_again)
2037 nc->GSN_database->iterate_records (nc->GSN_database->cls, 2165 {
2038 (GNUNET_YES == 2166 proc.run_again = GNUNET_NO;
2039 GNUNET_is_zero ( 2167 GNUNET_break (GNUNET_SYSERR !=
2040 &zi->zone)) 2168 nc->GSN_database->iterate_records (nc->GSN_database->cls,
2169 (GNUNET_YES ==
2170 GNUNET_is_zero (
2171 &zi->zone))
2041 ? NULL 2172 ? NULL
2042 : &zi->zone, 2173 : &zi->zone,
2043 zi->seq, 2174 zi->seq,
2044 limit, 2175 proc.limit,
2045 &zone_iterate_proc, 2176 &zone_iterate_proc,
2046 &proc)); 2177 &proc));
2178 }
2047 duration = GNUNET_TIME_absolute_get_duration (start); 2179 duration = GNUNET_TIME_absolute_get_duration (start);
2048 duration = GNUNET_TIME_relative_divide (duration, limit - proc.limit); 2180 duration = GNUNET_TIME_relative_divide (duration, limit - proc.limit);
2049 GNUNET_STATISTICS_set (statistics, 2181 GNUNET_STATISTICS_set (statistics,
@@ -2256,6 +2388,13 @@ monitor_iterate_cb (void *cls,
2256 "Monitor notifications sent", 2388 "Monitor notifications sent",
2257 1, 2389 1,
2258 GNUNET_NO); 2390 GNUNET_NO);
2391 if (GNUNET_YES == is_orphaned (zone_key))
2392 {
2393 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2394 "Skipping orphaned zone data\n");
2395 zm->run_again = GNUNET_YES;
2396 return;
2397 }
2259 zm->limit--; 2398 zm->limit--;
2260 zm->iteration_cnt--; 2399 zm->iteration_cnt--;
2261 send_lookup_response (zm->nc, 0, zone_key, name, rd_count, rd); 2400 send_lookup_response (zm->nc, 0, zone_key, name, rd_count, rd);
@@ -2319,13 +2458,18 @@ monitor_iteration_next (void *cls)
2319 zm->iteration_cnt = zm->limit / 2; /* leave half for monitor events */ 2458 zm->iteration_cnt = zm->limit / 2; /* leave half for monitor events */
2320 else 2459 else
2321 zm->iteration_cnt = zm->limit; /* use it all */ 2460 zm->iteration_cnt = zm->limit; /* use it all */
2322 ret = nc->GSN_database->iterate_records (nc->GSN_database->cls, 2461 zm->run_again = GNUNET_YES;
2323 (GNUNET_YES == GNUNET_is_zero ( 2462 while (GNUNET_YES == zm->run_again)
2324 &zm->zone)) ? NULL : &zm->zone, 2463 {
2325 zm->seq, 2464 zm->run_again = GNUNET_NO;
2326 zm->iteration_cnt, 2465 ret = nc->GSN_database->iterate_records (nc->GSN_database->cls,
2327 &monitor_iterate_cb, 2466 (GNUNET_YES == GNUNET_is_zero (
2328 zm); 2467 &zm->zone)) ? NULL : &zm->zone,
2468 zm->seq,
2469 zm->iteration_cnt,
2470 &monitor_iterate_cb,
2471 zm);
2472 }
2329 if (GNUNET_SYSERR == ret) 2473 if (GNUNET_SYSERR == ret)
2330 { 2474 {
2331 GNUNET_SERVICE_client_drop (zm->nc->client); 2475 GNUNET_SERVICE_client_drop (zm->nc->client);
@@ -2339,7 +2483,6 @@ monitor_iteration_next (void *cls)
2339 } 2483 }
2340} 2484}
2341 2485
2342
2343/** 2486/**
2344 * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_NEXT message 2487 * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_NEXT message
2345 * 2488 *
@@ -2398,6 +2541,99 @@ handle_monitor_next (void *cls, const struct ZoneMonitorNextMessage *nm)
2398 } 2541 }
2399} 2542}
2400 2543
2544static void
2545ego_callback (void *cls,
2546 struct GNUNET_IDENTITY_Ego *ego,
2547 void **ctx,
2548 const char *identifier)
2549{
2550 struct EgoEntry *ego_entry;
2551 struct GNUNET_SERVICE_Handle *service = cls;
2552 struct GNUNET_IDENTITY_PublicKey pk;
2553
2554 if ((NULL == ego) && (GNUNET_NO == egos_collected))
2555 {
2556 egos_collected = GNUNET_YES;
2557 GNUNET_SERVICE_resume (service);
2558 return;
2559 }
2560 if (NULL == ego)
2561 {
2562 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2563 "Called with NULL ego\n");
2564 return;
2565 }
2566 if ((GNUNET_NO == egos_collected) &&
2567 (NULL != identifier))
2568 {
2569 ego_entry = GNUNET_new (struct EgoEntry);
2570 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
2571 ego_entry->keystring = GNUNET_IDENTITY_public_key_to_string (&pk);
2572 ego_entry->ego = ego;
2573 ego_entry->identifier = GNUNET_strdup (identifier);
2574 GNUNET_CONTAINER_DLL_insert_tail (ego_head,
2575 ego_tail,
2576 ego_entry);
2577 return;
2578 }
2579 /* Ego renamed or added */
2580 if (identifier != NULL)
2581 {
2582 for (ego_entry = ego_head; NULL != ego_entry;
2583 ego_entry = ego_entry->next)
2584 {
2585 if (ego_entry->ego == ego)
2586 {
2587 /* Rename */
2588 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2589 "Renaming ego %s->%s\n", ego_entry->identifier,
2590 identifier);
2591 GNUNET_free (ego_entry->identifier);
2592 ego_entry->identifier = GNUNET_strdup (identifier);
2593 break;
2594 }
2595 }
2596 if (NULL == ego_entry)
2597 {
2598 /* Add */
2599 ego_entry = GNUNET_new (struct EgoEntry);
2600 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
2601 ego_entry->keystring = GNUNET_IDENTITY_public_key_to_string (&pk);
2602 ego_entry->ego = ego;
2603 ego_entry->identifier = GNUNET_strdup (identifier);
2604 GNUNET_CONTAINER_DLL_insert_tail (ego_head,
2605 ego_tail,
2606 ego_entry);
2607 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2608 "Added ego %s\n", ego_entry->identifier);
2609 }
2610 }
2611 else
2612 {
2613 /* Delete */
2614 for (ego_entry = ego_head; NULL != ego_entry;
2615 ego_entry = ego_entry->next)
2616 {
2617 if (ego_entry->ego == ego)
2618 break;
2619 }
2620 if (NULL == ego_entry)
2621 return; /* Not found */
2622
2623 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2624 "Removing ego %s\n", ego_entry->identifier);
2625 GNUNET_CONTAINER_DLL_remove (ego_head,
2626 ego_tail,
2627 ego_entry);
2628 GNUNET_free (ego_entry->identifier);
2629 GNUNET_free (ego_entry->keystring);
2630 GNUNET_free (ego_entry);
2631 return;
2632 }
2633
2634}
2635
2636
2401 2637
2402/** 2638/**
2403 * Process namestore requests. 2639 * Process namestore requests.
@@ -2413,7 +2649,6 @@ run (void *cls,
2413{ 2649{
2414 char *database; 2650 char *database;
2415 (void) cls; 2651 (void) cls;
2416 (void) service;
2417 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n"); 2652 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n");
2418 cache_keys = 2653 cache_keys =
2419 GNUNET_CONFIGURATION_get_value_yesno (cfg, "namestore", "CACHE_KEYS"); 2654 GNUNET_CONFIGURATION_get_value_yesno (cfg, "namestore", "CACHE_KEYS");
@@ -2443,6 +2678,10 @@ run (void *cls,
2443 GNUNET_SCHEDULER_add_now (&cleanup_task, NULL); 2678 GNUNET_SCHEDULER_add_now (&cleanup_task, NULL);
2444 return; 2679 return;
2445 } 2680 }
2681 egos_collected = GNUNET_NO;
2682 /** Suspend until we have all egos */
2683 GNUNET_SERVICE_suspend (service);
2684 identity_handle = GNUNET_IDENTITY_connect (cfg, &ego_callback, service);
2446 GNUNET_SCHEDULER_add_shutdown (&cleanup_task, NULL); 2685 GNUNET_SCHEDULER_add_shutdown (&cleanup_task, NULL);
2447} 2686}
2448 2687