aboutsummaryrefslogtreecommitdiff
path: root/src/zonemaster/gnunet-service-zonemaster.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/zonemaster/gnunet-service-zonemaster.c')
-rw-r--r--src/zonemaster/gnunet-service-zonemaster.c302
1 files changed, 45 insertions, 257 deletions
diff --git a/src/zonemaster/gnunet-service-zonemaster.c b/src/zonemaster/gnunet-service-zonemaster.c
index 7129cf44f..fcc6b4226 100644
--- a/src/zonemaster/gnunet-service-zonemaster.c
+++ b/src/zonemaster/gnunet-service-zonemaster.c
@@ -1,21 +1,19 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012, 2013, 2014, 2017 GNUnet e.V. 3 Copyright (C) 2012, 2013, 2014, 2017, 2018 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
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 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 General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
@@ -29,8 +27,6 @@
29#include "gnunet_dht_service.h" 27#include "gnunet_dht_service.h"
30#include "gnunet_namestore_service.h" 28#include "gnunet_namestore_service.h"
31#include "gnunet_statistics_service.h" 29#include "gnunet_statistics_service.h"
32#include "gnunet_namestore_plugin.h"
33#include "gnunet_signatures.h"
34 30
35 31
36#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) 32#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
@@ -60,6 +56,12 @@
60#define DHT_QUEUE_LIMIT 2000 56#define DHT_QUEUE_LIMIT 2000
61 57
62/** 58/**
59 * How many events may the namestore give us before it has to wait
60 * for us to keep up?
61 */
62#define NAMESTORE_QUEUE_LIMIT 50
63
64/**
63 * The initial interval in milliseconds btween puts in 65 * The initial interval in milliseconds btween puts in
64 * a zone iteration 66 * a zone iteration
65 */ 67 */
@@ -72,23 +74,12 @@
72#define MAXIMUM_ZONE_ITERATION_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15) 74#define MAXIMUM_ZONE_ITERATION_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
73 75
74/** 76/**
75 * The default put interval for the zone iteration. In case
76 * no option is found
77 */
78#define DEFAULT_ZONE_PUBLISH_TIME_WINDOW GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
79
80/**
81 * The factor the current zone iteration interval is divided by for each 77 * The factor the current zone iteration interval is divided by for each
82 * additional new record 78 * additional new record
83 */ 79 */
84#define LATE_ITERATION_SPEEDUP_FACTOR 2 80#define LATE_ITERATION_SPEEDUP_FACTOR 2
85 81
86/** 82/**
87 * How long until a DHT PUT attempt should time out?
88 */
89#define DHT_OPERATION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
90
91/**
92 * What replication level do we use for DHT PUT operations? 83 * What replication level do we use for DHT PUT operations?
93 */ 84 */
94#define DHT_GNS_REPLICATION_LEVEL 5 85#define DHT_GNS_REPLICATION_LEVEL 5
@@ -132,11 +123,6 @@ static struct GNUNET_STATISTICS_Handle *statistics;
132static struct GNUNET_DHT_Handle *dht_handle; 123static struct GNUNET_DHT_Handle *dht_handle;
133 124
134/** 125/**
135 * Active DHT put operation (or NULL)
136 */
137static struct GNUNET_DHT_PutHandle *active_put;
138
139/**
140 * Our handle to the namestore service 126 * Our handle to the namestore service
141 */ 127 */
142static struct GNUNET_NAMESTORE_Handle *namestore_handle; 128static struct GNUNET_NAMESTORE_Handle *namestore_handle;
@@ -147,21 +133,6 @@ static struct GNUNET_NAMESTORE_Handle *namestore_handle;
147static struct GNUNET_NAMESTORE_ZoneIterator *namestore_iter; 133static struct GNUNET_NAMESTORE_ZoneIterator *namestore_iter;
148 134
149/** 135/**
150 * Handle to monitor namestore changes to instant propagation.
151 */
152static struct GNUNET_NAMESTORE_ZoneMonitor *zmon;
153
154/**
155 * Head of monitor activities; kept in a DLL.
156 */
157static struct DhtPutActivity *ma_head;
158
159/**
160 * Tail of monitor activities; kept in a DLL.
161 */
162static struct DhtPutActivity *ma_tail;
163
164/**
165 * Head of iteration put activities; kept in a DLL. 136 * Head of iteration put activities; kept in a DLL.
166 */ 137 */
167static struct DhtPutActivity *it_head; 138static struct DhtPutActivity *it_head;
@@ -177,11 +148,6 @@ static struct DhtPutActivity *it_tail;
177static unsigned int dht_queue_length; 148static unsigned int dht_queue_length;
178 149
179/** 150/**
180 * Number of entries in the DHT queue #ma_head.
181 */
182static unsigned int ma_queue_length;
183
184/**
185 * Useful for zone update for DHT put 151 * Useful for zone update for DHT put
186 */ 152 */
187static unsigned long long num_public_records; 153static unsigned long long num_public_records;
@@ -280,17 +246,10 @@ shutdown_task (void *cls)
280 (void) cls; 246 (void) cls;
281 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 247 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
282 "Shutting down!\n"); 248 "Shutting down!\n");
283 while (NULL != (ma = ma_head))
284 {
285 GNUNET_DHT_put_cancel (ma->ph);
286 GNUNET_CONTAINER_DLL_remove (ma_head,
287 ma_tail,
288 ma);
289 GNUNET_free (ma);
290 }
291 while (NULL != (ma = it_head)) 249 while (NULL != (ma = it_head))
292 { 250 {
293 GNUNET_DHT_put_cancel (ma->ph); 251 GNUNET_DHT_put_cancel (ma->ph);
252 dht_queue_length--;
294 GNUNET_CONTAINER_DLL_remove (it_head, 253 GNUNET_CONTAINER_DLL_remove (it_head,
295 it_tail, 254 it_tail,
296 ma); 255 ma);
@@ -313,21 +272,11 @@ shutdown_task (void *cls)
313 GNUNET_NAMESTORE_zone_iteration_stop (namestore_iter); 272 GNUNET_NAMESTORE_zone_iteration_stop (namestore_iter);
314 namestore_iter = NULL; 273 namestore_iter = NULL;
315 } 274 }
316 if (NULL != zmon)
317 {
318 GNUNET_NAMESTORE_zone_monitor_stop (zmon);
319 zmon = NULL;
320 }
321 if (NULL != namestore_handle) 275 if (NULL != namestore_handle)
322 { 276 {
323 GNUNET_NAMESTORE_disconnect (namestore_handle); 277 GNUNET_NAMESTORE_disconnect (namestore_handle);
324 namestore_handle = NULL; 278 namestore_handle = NULL;
325 } 279 }
326 if (NULL != active_put)
327 {
328 GNUNET_DHT_put_cancel (active_put);
329 active_put = NULL;
330 }
331 if (NULL != dht_handle) 280 if (NULL != dht_handle)
332 { 281 {
333 GNUNET_DHT_disconnect (dht_handle); 282 GNUNET_DHT_disconnect (dht_handle);
@@ -364,25 +313,6 @@ publish_zone_dht_start (void *cls);
364 313
365 314
366/** 315/**
367 * Continuation called from DHT once the PUT operation triggered
368 * by a monitor is done.
369 *
370 * @param cls a `struct DhtPutActivity`
371 */
372static void
373dht_put_monitor_continuation (void *cls)
374{
375 struct DhtPutActivity *ma = cls;
376
377 ma_queue_length--;
378 GNUNET_CONTAINER_DLL_remove (ma_head,
379 ma_tail,
380 ma);
381 GNUNET_free (ma);
382}
383
384
385/**
386 * Calculate #target_iteration_velocity_per_record. 316 * Calculate #target_iteration_velocity_per_record.
387 */ 317 */
388static void 318static void
@@ -521,10 +451,6 @@ update_velocity (unsigned int cnt)
521 dht_queue_length, 451 dht_queue_length,
522 GNUNET_NO); 452 GNUNET_NO);
523 GNUNET_STATISTICS_set (statistics, 453 GNUNET_STATISTICS_set (statistics,
524 "# size of the DHT queue (mon)",
525 ma_queue_length,
526 GNUNET_NO);
527 GNUNET_STATISTICS_set (statistics,
528 "% speed increase needed for target velocity", 454 "% speed increase needed for target velocity",
529 pct, 455 pct,
530 GNUNET_NO); 456 GNUNET_NO);
@@ -558,6 +484,12 @@ check_zone_namestore_next ()
558 GNUNET_NO); 484 GNUNET_NO);
559 delay = GNUNET_TIME_relative_multiply (delay, 485 delay = GNUNET_TIME_relative_multiply (delay,
560 NS_BLOCK_SIZE); 486 NS_BLOCK_SIZE);
487 /* make sure we do not overshoot because of the #NS_BLOCK_SIZE factor */
488 delay = GNUNET_TIME_relative_min (MAXIMUM_ZONE_ITERATION_INTERVAL,
489 delay);
490 /* no delays on first iteration */
491 if (GNUNET_YES == first_zone_iteration)
492 delay = GNUNET_TIME_UNIT_ZERO;
561 GNUNET_assert (NULL == zone_publish_task); 493 GNUNET_assert (NULL == zone_publish_task);
562 zone_publish_task = GNUNET_SCHEDULER_add_delayed (delay, 494 zone_publish_task = GNUNET_SCHEDULER_add_delayed (delay,
563 &publish_zone_namestore_next, 495 &publish_zone_namestore_next,
@@ -606,24 +538,22 @@ convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd,
606 rd_public_count = 0; 538 rd_public_count = 0;
607 now = GNUNET_TIME_absolute_get (); 539 now = GNUNET_TIME_absolute_get ();
608 for (unsigned int i=0;i<rd_count;i++) 540 for (unsigned int i=0;i<rd_count;i++)
609 if (0 == (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) 541 {
542 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE))
543 continue;
544 if ( (0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) &&
545 (rd[i].expiration_time < now.abs_value_us) )
546 continue; /* record already expired, skip it */
547 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
610 { 548 {
611 rd_public[rd_public_count] = rd[i]; 549 /* GNUNET_GNSRECORD_block_create will convert to absolute time;
612 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) 550 we just need to adjust our iteration frequency */
613 { 551 min_relative_record_time.rel_value_us =
614 /* GNUNET_GNSRECORD_block_create will convert to absolute time; 552 GNUNET_MIN (rd[i].expiration_time,
615 we just need to adjust our iteration frequency */ 553 min_relative_record_time.rel_value_us);
616 min_relative_record_time.rel_value_us =
617 GNUNET_MIN (rd_public[rd_public_count].expiration_time,
618 min_relative_record_time.rel_value_us);
619 }
620 else if (rd_public[rd_public_count].expiration_time < now.abs_value_us)
621 {
622 /* record already expired, skip it */
623 continue;
624 }
625 rd_public_count++;
626 } 554 }
555 rd_public[rd_public_count++] = rd[i];
556 }
627 return rd_public_count; 557 return rd_public_count;
628} 558}
629 559
@@ -635,8 +565,7 @@ convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd,
635 * @param label label to store under 565 * @param label label to store under
636 * @param rd_public public record data 566 * @param rd_public public record data
637 * @param rd_public_count number of records in @a rd_public 567 * @param rd_public_count number of records in @a rd_public
638 * @param cont function to call with PUT result 568 * @param ma handle for the put operation
639 * @param cont_cls closure for @a cont
640 * @return DHT PUT handle, NULL on error 569 * @return DHT PUT handle, NULL on error
641 */ 570 */
642static struct GNUNET_DHT_PutHandle * 571static struct GNUNET_DHT_PutHandle *
@@ -644,8 +573,7 @@ perform_dht_put (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
644 const char *label, 573 const char *label,
645 const struct GNUNET_GNSRECORD_Data *rd_public, 574 const struct GNUNET_GNSRECORD_Data *rd_public,
646 unsigned int rd_public_count, 575 unsigned int rd_public_count,
647 GNUNET_SCHEDULER_TaskCallback cont, 576 struct DhtPutActivity *ma)
648 void *cont_cls)
649{ 577{
650 struct GNUNET_GNSRECORD_Block *block; 578 struct GNUNET_GNSRECORD_Block *block;
651 struct GNUNET_HashCode query; 579 struct GNUNET_HashCode query;
@@ -697,8 +625,8 @@ perform_dht_put (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
697 block_size, 625 block_size,
698 block, 626 block,
699 expire, 627 expire,
700 cont, 628 &dht_put_continuation,
701 cont_cls); 629 ma);
702 GNUNET_free (block); 630 GNUNET_free (block);
703 return ret; 631 return ret;
704} 632}
@@ -724,11 +652,6 @@ zone_iteration_error (void *cls)
724 GNUNET_SCHEDULER_cancel (zone_publish_task); 652 GNUNET_SCHEDULER_cancel (zone_publish_task);
725 zone_publish_task = NULL; 653 zone_publish_task = NULL;
726 } 654 }
727 if (NULL != active_put)
728 {
729 GNUNET_DHT_put_cancel (active_put);
730 active_put = NULL;
731 }
732 zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start, 655 zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start,
733 NULL); 656 NULL);
734} 657}
@@ -751,8 +674,7 @@ zone_iteration_finished (void *cls)
751 calculate_put_interval (); 674 calculate_put_interval ();
752 /* reset for next iteration */ 675 /* reset for next iteration */
753 min_relative_record_time 676 min_relative_record_time
754 = GNUNET_TIME_relative_multiply (GNUNET_DHT_DEFAULT_REPUBLISH_FREQUENCY, 677 = GNUNET_TIME_UNIT_FOREVER_REL;
755 PUBLISH_OPS_PER_EXPIRATION);
756 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 678 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
757 "Zone iteration finished. Adjusted zone iteration interval to %s\n", 679 "Zone iteration finished. Adjusted zone iteration interval to %s\n",
758 GNUNET_STRINGS_relative_time_to_string (target_iteration_velocity_per_record, 680 GNUNET_STRINGS_relative_time_to_string (target_iteration_velocity_per_record,
@@ -821,7 +743,6 @@ put_gns_record (void *cls,
821 label, 743 label,
822 rd_public, 744 rd_public,
823 rd_public_count, 745 rd_public_count,
824 &dht_put_continuation,
825 ma); 746 ma);
826 put_cnt++; 747 put_cnt++;
827 if (0 == put_cnt % DELTA_INTERVAL) 748 if (0 == put_cnt % DELTA_INTERVAL)
@@ -889,130 +810,6 @@ publish_zone_dht_start (void *cls)
889 810
890 811
891/** 812/**
892 * Process a record that was stored in the namestore
893 * (invoked by the monitor).
894 *
895 * @param cls closure, NULL
896 * @param zone private key of the zone; NULL on disconnect
897 * @param label label of the records; NULL on disconnect
898 * @param rd_count number of entries in @a rd array, 0 if label was deleted
899 * @param rd array of records with data to store
900 */
901static void
902handle_monitor_event (void *cls,
903 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
904 const char *label,
905 unsigned int rd_count,
906 const struct GNUNET_GNSRECORD_Data *rd)
907{
908 struct GNUNET_GNSRECORD_Data rd_public[rd_count];
909 unsigned int rd_public_count;
910 struct DhtPutActivity *ma;
911
912 (void) cls;
913 GNUNET_STATISTICS_update (statistics,
914 "Namestore monitor events received",
915 1,
916 GNUNET_NO);
917 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
918 "Received %u records for label `%s' via namestore monitor\n",
919 rd_count,
920 label);
921 /* filter out records that are not public, and convert to
922 absolute expiration time. */
923 rd_public_count = convert_records_for_export (rd,
924 rd_count,
925 rd_public);
926 if (0 == rd_public_count)
927 return; /* nothing to do */
928 num_public_records++;
929 ma = GNUNET_new (struct DhtPutActivity);
930 ma->start_date = GNUNET_TIME_absolute_get ();
931 ma->ph = perform_dht_put (zone,
932 label,
933 rd,
934 rd_count,
935 &dht_put_monitor_continuation,
936 ma);
937 if (NULL == ma->ph)
938 {
939 /* PUT failed, do not remember operation */
940 GNUNET_free (ma);
941 return;
942 }
943 GNUNET_CONTAINER_DLL_insert_tail (ma_head,
944 ma_tail,
945 ma);
946 ma_queue_length++;
947 if (ma_queue_length > DHT_QUEUE_LIMIT)
948 {
949 ma = ma_head;
950 GNUNET_CONTAINER_DLL_remove (ma_head,
951 ma_tail,
952 ma);
953 GNUNET_DHT_put_cancel (ma->ph);
954 ma_queue_length--;
955 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
956 "DHT PUT unconfirmed after %s, aborting PUT\n",
957 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (ma->start_date),
958 GNUNET_YES));
959 GNUNET_free (ma);
960 }
961}
962
963
964/**
965 * The zone monitor is now in SYNC with the current state of the
966 * name store. Start to perform periodic iterations.
967 *
968 * @param cls NULL
969 */
970static void
971monitor_sync_event (void *cls)
972{
973 (void) cls;
974 if ( (NULL == zone_publish_task) &&
975 (NULL == namestore_iter) )
976 zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start,
977 NULL);
978}
979
980
981/**
982 * The zone monitor encountered an IPC error trying to to get in
983 * sync. Restart from the beginning.
984 *
985 * @param cls NULL
986 */
987static void
988handle_monitor_error (void *cls)
989{
990 (void) cls;
991 GNUNET_STATISTICS_update (statistics,
992 "Namestore monitor errors encountered",
993 1,
994 GNUNET_NO);
995 if (NULL != zone_publish_task)
996 {
997 GNUNET_SCHEDULER_cancel (zone_publish_task);
998 zone_publish_task = NULL;
999 }
1000 if (NULL != namestore_iter)
1001 {
1002 GNUNET_NAMESTORE_zone_iteration_stop (namestore_iter);
1003 namestore_iter = NULL;
1004 }
1005 if (NULL != active_put)
1006 {
1007 GNUNET_DHT_put_cancel (active_put);
1008 active_put = NULL;
1009 }
1010 zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start,
1011 NULL);
1012}
1013
1014
1015/**
1016 * Performe zonemaster duties: watch namestore, publish records. 813 * Performe zonemaster duties: watch namestore, publish records.
1017 * 814 *
1018 * @param cls closure 815 * @param cls closure
@@ -1030,8 +827,7 @@ run (void *cls,
1030 (void) service; 827 (void) service;
1031 last_put_100 = GNUNET_TIME_absolute_get (); /* first time! */ 828 last_put_100 = GNUNET_TIME_absolute_get (); /* first time! */
1032 min_relative_record_time 829 min_relative_record_time
1033 = GNUNET_TIME_relative_multiply (GNUNET_DHT_DEFAULT_REPUBLISH_FREQUENCY, 830 = GNUNET_TIME_UNIT_FOREVER_REL;
1034 PUBLISH_OPS_PER_EXPIRATION);
1035 target_iteration_velocity_per_record = INITIAL_ZONE_ITERATION_INTERVAL; 831 target_iteration_velocity_per_record = INITIAL_ZONE_ITERATION_INTERVAL;
1036 namestore_handle = GNUNET_NAMESTORE_connect (c); 832 namestore_handle = GNUNET_NAMESTORE_connect (c);
1037 if (NULL == namestore_handle) 833 if (NULL == namestore_handle)
@@ -1044,7 +840,7 @@ run (void *cls,
1044 cache_keys = GNUNET_CONFIGURATION_get_value_yesno (c, 840 cache_keys = GNUNET_CONFIGURATION_get_value_yesno (c,
1045 "namestore", 841 "namestore",
1046 "CACHE_KEYS"); 842 "CACHE_KEYS");
1047 zone_publish_time_window_default = DEFAULT_ZONE_PUBLISH_TIME_WINDOW; 843 zone_publish_time_window_default = GNUNET_DHT_DEFAULT_REPUBLISH_FREQUENCY;
1048 if (GNUNET_OK == 844 if (GNUNET_OK ==
1049 GNUNET_CONFIGURATION_get_value_time (c, 845 GNUNET_CONFIGURATION_get_value_time (c,
1050 "zonemaster", 846 "zonemaster",
@@ -1088,16 +884,8 @@ run (void *cls,
1088 "Target zone iteration velocity (μs)", 884 "Target zone iteration velocity (μs)",
1089 target_iteration_velocity_per_record.rel_value_us, 885 target_iteration_velocity_per_record.rel_value_us,
1090 GNUNET_NO); 886 GNUNET_NO);
1091 zmon = GNUNET_NAMESTORE_zone_monitor_start (c, 887 zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start,
1092 NULL, 888 NULL);
1093 GNUNET_NO,
1094 &handle_monitor_error,
1095 NULL,
1096 &handle_monitor_event,
1097 NULL,
1098 &monitor_sync_event,
1099 NULL);
1100 GNUNET_break (NULL != zmon);
1101 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 889 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1102 NULL); 890 NULL);
1103} 891}