diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-01-04 22:11:55 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-01-04 22:11:55 +0100 |
commit | 5672e0e27b671fa878143e5eed8a9b677588b178 (patch) | |
tree | 91a9a5bbeac95a3a65b08484d3295ee3cd03e8b8 /src | |
parent | 60c6dfd1fe22a01a3f7723e7e2bb18d52895c527 (diff) | |
download | gnunet-5672e0e27b671fa878143e5eed8a9b677588b178.tar.gz gnunet-5672e0e27b671fa878143e5eed8a9b677588b178.zip |
move functionality of publishing namestore zone in DHT from GNS service to new zonemaster service
Diffstat (limited to 'src')
-rw-r--r-- | src/gns/gns.conf.in | 4 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns.c | 647 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns_reverser.c | 5 | ||||
-rw-r--r-- | src/vpn/vpn.conf.in | 2 | ||||
-rw-r--r-- | src/zonemaster/Makefile.am | 35 | ||||
-rw-r--r-- | src/zonemaster/gnunet-service-zonemaster.c | 773 | ||||
-rw-r--r-- | src/zonemaster/zonemaster.conf.in | 25 |
7 files changed, 844 insertions, 647 deletions
diff --git a/src/gns/gns.conf.in b/src/gns/gns.conf.in index bf59cac15..b34246cef 100644 --- a/src/gns/gns.conf.in +++ b/src/gns/gns.conf.in | |||
@@ -5,7 +5,6 @@ HOSTNAME = localhost | |||
5 | BINARY = gnunet-service-gns | 5 | BINARY = gnunet-service-gns |
6 | UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-gns.sock | 6 | UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-gns.sock |
7 | @JAVAPORT@PORT = 2102 | 7 | @JAVAPORT@PORT = 2102 |
8 | USER_SERVICE = YES | ||
9 | 8 | ||
10 | # Do we require users that want to access GNS to run this process | 9 | # Do we require users that want to access GNS to run this process |
11 | # (usually not a good idea) | 10 | # (usually not a good idea) |
@@ -17,9 +16,6 @@ UNIX_MATCH_GID = YES | |||
17 | # How many queries is GNS allowed to perform in the background at the same time? | 16 | # How many queries is GNS allowed to perform in the background at the same time? |
18 | MAX_PARALLEL_BACKGROUND_QUERIES = 1000 | 17 | MAX_PARALLEL_BACKGROUND_QUERIES = 1000 |
19 | 18 | ||
20 | # How frequently do we try to publish our full zone? | ||
21 | ZONE_PUBLISH_TIME_WINDOW = 4 h | ||
22 | |||
23 | # Using caching or always ask DHT | 19 | # Using caching or always ask DHT |
24 | # USE_CACHE = YES | 20 | # USE_CACHE = YES |
25 | 21 | ||
diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c index 3e718dac8..7c1dfaba2 100644 --- a/src/gns/gnunet-service-gns.c +++ b/src/gns/gnunet-service-gns.c | |||
@@ -40,43 +40,6 @@ | |||
40 | #include "gnunet-service-gns_interceptor.h" | 40 | #include "gnunet-service-gns_interceptor.h" |
41 | #include "gnunet_protocols.h" | 41 | #include "gnunet_protocols.h" |
42 | 42 | ||
43 | /** | ||
44 | * The initial interval in milliseconds btween puts in | ||
45 | * a zone iteration | ||
46 | */ | ||
47 | #define INITIAL_PUT_INTERVAL GNUNET_TIME_UNIT_MILLISECONDS | ||
48 | |||
49 | /** | ||
50 | * The lower bound for the zone iteration interval | ||
51 | */ | ||
52 | #define MINIMUM_ZONE_ITERATION_INTERVAL GNUNET_TIME_UNIT_SECONDS | ||
53 | |||
54 | /** | ||
55 | * The upper bound for the zone iteration interval | ||
56 | */ | ||
57 | #define MAXIMUM_ZONE_ITERATION_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15) | ||
58 | |||
59 | /** | ||
60 | * The default put interval for the zone iteration. In case | ||
61 | * no option is found | ||
62 | */ | ||
63 | #define DEFAULT_ZONE_PUBLISH_TIME_WINDOW GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4) | ||
64 | |||
65 | /** | ||
66 | * The factor the current zone iteration interval is divided by for each | ||
67 | * additional new record | ||
68 | */ | ||
69 | #define LATE_ITERATION_SPEEDUP_FACTOR 2 | ||
70 | |||
71 | /** | ||
72 | * How long until a DHT PUT attempt should time out? | ||
73 | */ | ||
74 | #define DHT_OPERATION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) | ||
75 | |||
76 | /** | ||
77 | * What replication level do we use for DHT PUT operations? | ||
78 | */ | ||
79 | #define DHT_GNS_REPLICATION_LEVEL 5 | ||
80 | 43 | ||
81 | /** | 44 | /** |
82 | * GnsClient prototype | 45 | * GnsClient prototype |
@@ -146,36 +109,14 @@ struct GnsClient | |||
146 | 109 | ||
147 | 110 | ||
148 | /** | 111 | /** |
149 | * Handle for DHT PUT activity triggered from the namestore monitor. | ||
150 | */ | ||
151 | struct MonitorActivity | ||
152 | { | ||
153 | /** | ||
154 | * Kept in a DLL. | ||
155 | */ | ||
156 | struct MonitorActivity *next; | ||
157 | |||
158 | /** | ||
159 | * Kept in a DLL. | ||
160 | */ | ||
161 | struct MonitorActivity *prev; | ||
162 | |||
163 | /** | ||
164 | * Handle for the DHT PUT operation. | ||
165 | */ | ||
166 | struct GNUNET_DHT_PutHandle *ph; | ||
167 | }; | ||
168 | |||
169 | |||
170 | /** | ||
171 | * Our handle to the DHT | 112 | * Our handle to the DHT |
172 | */ | 113 | */ |
173 | static struct GNUNET_DHT_Handle *dht_handle; | 114 | static struct GNUNET_DHT_Handle *dht_handle; |
174 | 115 | ||
175 | /** | 116 | /** |
176 | * Active DHT put operation (or NULL) | 117 | * Our handle to the namecache service |
177 | */ | 118 | */ |
178 | static struct GNUNET_DHT_PutHandle *active_put; | 119 | static struct GNUNET_NAMECACHE_Handle *namecache_handle; |
179 | 120 | ||
180 | /** | 121 | /** |
181 | * Our handle to the namestore service | 122 | * Our handle to the namestore service |
@@ -183,11 +124,6 @@ static struct GNUNET_DHT_PutHandle *active_put; | |||
183 | static struct GNUNET_NAMESTORE_Handle *namestore_handle; | 124 | static struct GNUNET_NAMESTORE_Handle *namestore_handle; |
184 | 125 | ||
185 | /** | 126 | /** |
186 | * Our handle to the namecache service | ||
187 | */ | ||
188 | static struct GNUNET_NAMECACHE_Handle *namecache_handle; | ||
189 | |||
190 | /** | ||
191 | * Our handle to the identity service | 127 | * Our handle to the identity service |
192 | */ | 128 | */ |
193 | static struct GNUNET_IDENTITY_Handle *identity_handle; | 129 | static struct GNUNET_IDENTITY_Handle *identity_handle; |
@@ -199,68 +135,6 @@ static struct GNUNET_IDENTITY_Handle *identity_handle; | |||
199 | static struct GNUNET_IDENTITY_Operation *identity_op; | 135 | static struct GNUNET_IDENTITY_Operation *identity_op; |
200 | 136 | ||
201 | /** | 137 | /** |
202 | * Handle to iterate over our authoritative zone in namestore | ||
203 | */ | ||
204 | static struct GNUNET_NAMESTORE_ZoneIterator *namestore_iter; | ||
205 | |||
206 | /** | ||
207 | * Handle to monitor namestore changes to instant propagation. | ||
208 | */ | ||
209 | static struct GNUNET_NAMESTORE_ZoneMonitor *zmon; | ||
210 | |||
211 | /** | ||
212 | * Head of monitor activities; kept in a DLL. | ||
213 | */ | ||
214 | static struct MonitorActivity *ma_head; | ||
215 | |||
216 | /** | ||
217 | * Tail of monitor activities; kept in a DLL. | ||
218 | */ | ||
219 | static struct MonitorActivity *ma_tail; | ||
220 | |||
221 | /** | ||
222 | * Useful for zone update for DHT put | ||
223 | */ | ||
224 | static unsigned long long num_public_records; | ||
225 | |||
226 | /** | ||
227 | * Last seen record count | ||
228 | */ | ||
229 | static unsigned long long last_num_public_records; | ||
230 | |||
231 | /** | ||
232 | * Minimum relative expiration time of records seem during the current | ||
233 | * zone iteration. | ||
234 | */ | ||
235 | static struct GNUNET_TIME_Relative min_relative_record_time; | ||
236 | |||
237 | /** | ||
238 | * Zone iteration PUT interval. | ||
239 | */ | ||
240 | static struct GNUNET_TIME_Relative put_interval; | ||
241 | |||
242 | /** | ||
243 | * Default time window for zone iteration | ||
244 | */ | ||
245 | static struct GNUNET_TIME_Relative zone_publish_time_window_default; | ||
246 | |||
247 | /** | ||
248 | * Time window for zone iteration, adjusted based on relative record | ||
249 | * expiration times in our zone. | ||
250 | */ | ||
251 | static struct GNUNET_TIME_Relative zone_publish_time_window; | ||
252 | |||
253 | /** | ||
254 | * zone publish task | ||
255 | */ | ||
256 | static struct GNUNET_SCHEDULER_Task *zone_publish_task; | ||
257 | |||
258 | /** | ||
259 | * #GNUNET_YES if zone has never been published before | ||
260 | */ | ||
261 | static int first_zone_iteration; | ||
262 | |||
263 | /** | ||
264 | * #GNUNET_YES if ipv6 is supported | 138 | * #GNUNET_YES if ipv6 is supported |
265 | */ | 139 | */ |
266 | static int v6_enabled; | 140 | static int v6_enabled; |
@@ -285,8 +159,6 @@ static struct GNUNET_STATISTICS_Handle *statistics; | |||
285 | static void | 159 | static void |
286 | shutdown_task (void *cls) | 160 | shutdown_task (void *cls) |
287 | { | 161 | { |
288 | struct MonitorActivity *ma; | ||
289 | |||
290 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 162 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
291 | "Shutting down!\n"); | 163 | "Shutting down!\n"); |
292 | GNS_interceptor_done (); | 164 | GNS_interceptor_done (); |
@@ -303,35 +175,12 @@ shutdown_task (void *cls) | |||
303 | GNS_resolver_done (); | 175 | GNS_resolver_done (); |
304 | GNS_reverse_done (); | 176 | GNS_reverse_done (); |
305 | GNS_shorten_done (); | 177 | GNS_shorten_done (); |
306 | while (NULL != (ma = ma_head)) | ||
307 | { | ||
308 | GNUNET_DHT_put_cancel (ma->ph); | ||
309 | GNUNET_CONTAINER_DLL_remove (ma_head, | ||
310 | ma_tail, | ||
311 | ma); | ||
312 | GNUNET_free (ma); | ||
313 | } | ||
314 | if (NULL != statistics) | 178 | if (NULL != statistics) |
315 | { | 179 | { |
316 | GNUNET_STATISTICS_destroy (statistics, | 180 | GNUNET_STATISTICS_destroy (statistics, |
317 | GNUNET_NO); | 181 | GNUNET_NO); |
318 | statistics = NULL; | 182 | statistics = NULL; |
319 | } | 183 | } |
320 | if (NULL != zone_publish_task) | ||
321 | { | ||
322 | GNUNET_SCHEDULER_cancel (zone_publish_task); | ||
323 | zone_publish_task = NULL; | ||
324 | } | ||
325 | if (NULL != namestore_iter) | ||
326 | { | ||
327 | GNUNET_NAMESTORE_zone_iteration_stop (namestore_iter); | ||
328 | namestore_iter = NULL; | ||
329 | } | ||
330 | if (NULL != zmon) | ||
331 | { | ||
332 | GNUNET_NAMESTORE_zone_monitor_stop (zmon); | ||
333 | zmon = NULL; | ||
334 | } | ||
335 | if (NULL != namestore_handle) | 184 | if (NULL != namestore_handle) |
336 | { | 185 | { |
337 | GNUNET_NAMESTORE_disconnect (namestore_handle); | 186 | GNUNET_NAMESTORE_disconnect (namestore_handle); |
@@ -342,11 +191,6 @@ shutdown_task (void *cls) | |||
342 | GNUNET_NAMECACHE_disconnect (namecache_handle); | 191 | GNUNET_NAMECACHE_disconnect (namecache_handle); |
343 | namecache_handle = NULL; | 192 | namecache_handle = NULL; |
344 | } | 193 | } |
345 | if (NULL != active_put) | ||
346 | { | ||
347 | GNUNET_DHT_put_cancel (active_put); | ||
348 | active_put = NULL; | ||
349 | } | ||
350 | if (NULL != dht_handle) | 194 | if (NULL != dht_handle) |
351 | { | 195 | { |
352 | GNUNET_DHT_disconnect (dht_handle); | 196 | GNUNET_DHT_disconnect (dht_handle); |
@@ -354,6 +198,7 @@ shutdown_task (void *cls) | |||
354 | } | 198 | } |
355 | } | 199 | } |
356 | 200 | ||
201 | |||
357 | /** | 202 | /** |
358 | * Called whenever a client is disconnected. | 203 | * Called whenever a client is disconnected. |
359 | * | 204 | * |
@@ -413,408 +258,6 @@ client_connect_cb (void *cls, | |||
413 | 258 | ||
414 | 259 | ||
415 | /** | 260 | /** |
416 | * Method called periodically that triggers iteration over authoritative records | ||
417 | * | ||
418 | * @param cls closure | ||
419 | */ | ||
420 | static void | ||
421 | publish_zone_dht_next (void *cls) | ||
422 | { | ||
423 | zone_publish_task = NULL; | ||
424 | GNUNET_assert (NULL != namestore_iter); | ||
425 | GNUNET_NAMESTORE_zone_iterator_next (namestore_iter); | ||
426 | } | ||
427 | |||
428 | |||
429 | /** | ||
430 | * Periodically iterate over our zone and store everything in dht | ||
431 | * | ||
432 | * @param cls NULL | ||
433 | */ | ||
434 | static void | ||
435 | publish_zone_dht_start (void *cls); | ||
436 | |||
437 | |||
438 | /** | ||
439 | * Continuation called from DHT once the PUT operation is done. | ||
440 | * | ||
441 | * @param cls closure, NULL if called from regular iteration, | ||
442 | * `struct MonitorActivity` if called from #handle_monitor_event. | ||
443 | * @param success #GNUNET_OK on success | ||
444 | */ | ||
445 | static void | ||
446 | dht_put_continuation (void *cls, | ||
447 | int success) | ||
448 | { | ||
449 | struct MonitorActivity *ma = cls; | ||
450 | struct GNUNET_TIME_Relative next_put_interval; | ||
451 | |||
452 | num_public_records++; | ||
453 | if (NULL == ma) | ||
454 | { | ||
455 | active_put = NULL; | ||
456 | if ( (num_public_records > last_num_public_records) && | ||
457 | (GNUNET_NO == first_zone_iteration) ) | ||
458 | { | ||
459 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
460 | "Last record count was lower than current record count. Reducing interval.\n"); | ||
461 | put_interval = GNUNET_TIME_relative_divide (zone_publish_time_window, | ||
462 | num_public_records); | ||
463 | next_put_interval = GNUNET_TIME_relative_divide (put_interval, | ||
464 | LATE_ITERATION_SPEEDUP_FACTOR); | ||
465 | } | ||
466 | else | ||
467 | next_put_interval = put_interval; | ||
468 | next_put_interval = GNUNET_TIME_relative_min (next_put_interval, | ||
469 | MAXIMUM_ZONE_ITERATION_INTERVAL); | ||
470 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
471 | "PUT complete, next PUT in %s!\n", | ||
472 | GNUNET_STRINGS_relative_time_to_string (next_put_interval, | ||
473 | GNUNET_YES)); | ||
474 | |||
475 | GNUNET_STATISTICS_set (statistics, | ||
476 | "Current zone iteration interval (ms)", | ||
477 | next_put_interval.rel_value_us / 1000LL, | ||
478 | GNUNET_NO); | ||
479 | GNUNET_assert (NULL == zone_publish_task); | ||
480 | zone_publish_task = GNUNET_SCHEDULER_add_delayed (next_put_interval, | ||
481 | &publish_zone_dht_next, | ||
482 | NULL); | ||
483 | } | ||
484 | else | ||
485 | { | ||
486 | GNUNET_CONTAINER_DLL_remove (ma_head, | ||
487 | ma_tail, | ||
488 | ma); | ||
489 | GNUNET_free (ma); | ||
490 | } | ||
491 | } | ||
492 | |||
493 | |||
494 | /** | ||
495 | * Convert namestore records from the internal format to that | ||
496 | * suitable for publication (removes private records, converts | ||
497 | * to absolute expiration time). | ||
498 | * | ||
499 | * @param rd input records | ||
500 | * @param rd_count size of the @a rd and @a rd_public arrays | ||
501 | * @param rd_public where to write the converted records | ||
502 | * @return number of records written to @a rd_public | ||
503 | */ | ||
504 | static unsigned int | ||
505 | convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd, | ||
506 | unsigned int rd_count, | ||
507 | struct GNUNET_GNSRECORD_Data *rd_public) | ||
508 | { | ||
509 | struct GNUNET_TIME_Absolute now; | ||
510 | unsigned int rd_public_count; | ||
511 | unsigned int i; | ||
512 | |||
513 | rd_public_count = 0; | ||
514 | now = GNUNET_TIME_absolute_get (); | ||
515 | for (i=0;i<rd_count;i++) | ||
516 | if (0 == (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) | ||
517 | { | ||
518 | rd_public[rd_public_count] = rd[i]; | ||
519 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) | ||
520 | { | ||
521 | /* GNUNET_GNSRECORD_block_create will convert to absolute time; | ||
522 | we just need to adjust our iteration frequency */ | ||
523 | min_relative_record_time.rel_value_us = | ||
524 | GNUNET_MIN (rd_public[rd_public_count].expiration_time, | ||
525 | min_relative_record_time.rel_value_us); | ||
526 | } | ||
527 | else if (rd_public[rd_public_count].expiration_time < now.abs_value_us) | ||
528 | { | ||
529 | /* record already expired, skip it */ | ||
530 | continue; | ||
531 | } | ||
532 | rd_public_count++; | ||
533 | } | ||
534 | return rd_public_count; | ||
535 | } | ||
536 | |||
537 | |||
538 | /** | ||
539 | * Store GNS records in the DHT. | ||
540 | * | ||
541 | * @param key key of the zone | ||
542 | * @param label label to store under | ||
543 | * @param rd_public public record data | ||
544 | * @param rd_public_count number of records in @a rd_public | ||
545 | * @param pc_arg closure argument to pass to the #dht_put_continuation | ||
546 | * @return DHT PUT handle, NULL on error | ||
547 | */ | ||
548 | static struct GNUNET_DHT_PutHandle * | ||
549 | perform_dht_put (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | ||
550 | const char *label, | ||
551 | const struct GNUNET_GNSRECORD_Data *rd_public, | ||
552 | unsigned int rd_public_count, | ||
553 | void *pc_arg) | ||
554 | { | ||
555 | struct GNUNET_GNSRECORD_Block *block; | ||
556 | struct GNUNET_HashCode query; | ||
557 | struct GNUNET_TIME_Absolute expire; | ||
558 | size_t block_size; | ||
559 | struct GNUNET_DHT_PutHandle *ret; | ||
560 | |||
561 | expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_public_count, | ||
562 | rd_public); | ||
563 | block = GNUNET_GNSRECORD_block_create (key, | ||
564 | expire, | ||
565 | label, | ||
566 | rd_public, | ||
567 | rd_public_count); | ||
568 | if (NULL == block) | ||
569 | return NULL; /* whoops */ | ||
570 | block_size = ntohl (block->purpose.size) | ||
571 | + sizeof (struct GNUNET_CRYPTO_EcdsaSignature) | ||
572 | + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); | ||
573 | GNUNET_GNSRECORD_query_from_private_key (key, | ||
574 | label, | ||
575 | &query); | ||
576 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
577 | "Storing %u record(s) for label `%s' in DHT with expiration `%s' under key %s\n", | ||
578 | rd_public_count, | ||
579 | label, | ||
580 | GNUNET_STRINGS_absolute_time_to_string (expire), | ||
581 | GNUNET_h2s (&query)); | ||
582 | ret = GNUNET_DHT_put (dht_handle, | ||
583 | &query, | ||
584 | DHT_GNS_REPLICATION_LEVEL, | ||
585 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, | ||
586 | GNUNET_BLOCK_TYPE_GNS_NAMERECORD, | ||
587 | block_size, | ||
588 | block, | ||
589 | expire, | ||
590 | &dht_put_continuation, | ||
591 | pc_arg); | ||
592 | GNUNET_free (block); | ||
593 | return ret; | ||
594 | } | ||
595 | |||
596 | |||
597 | /** | ||
598 | * We encountered an error in our zone iteration. | ||
599 | */ | ||
600 | static void | ||
601 | zone_iteration_error (void *cls) | ||
602 | { | ||
603 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
604 | "Got disconnected from namestore database, retrying.\n"); | ||
605 | namestore_iter = NULL; | ||
606 | /* We end up here on error/disconnect/shutdown, so potentially | ||
607 | while a zone publish task or a DHT put is still running; hence | ||
608 | we need to cancel those. */ | ||
609 | if (NULL != zone_publish_task) | ||
610 | { | ||
611 | GNUNET_SCHEDULER_cancel (zone_publish_task); | ||
612 | zone_publish_task = NULL; | ||
613 | } | ||
614 | if (NULL != active_put) | ||
615 | { | ||
616 | GNUNET_DHT_put_cancel (active_put); | ||
617 | active_put = NULL; | ||
618 | } | ||
619 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start, | ||
620 | NULL); | ||
621 | } | ||
622 | |||
623 | |||
624 | /** | ||
625 | * Zone iteration is completed. | ||
626 | */ | ||
627 | static void | ||
628 | zone_iteration_finished (void *cls) | ||
629 | { | ||
630 | /* we're done with one iteration, calculate when to do the next one */ | ||
631 | namestore_iter = NULL; | ||
632 | last_num_public_records = num_public_records; | ||
633 | first_zone_iteration = GNUNET_NO; | ||
634 | if (0 == num_public_records) | ||
635 | { | ||
636 | /** | ||
637 | * If no records are known (startup) or none present | ||
638 | * we can safely set the interval to the value for a single | ||
639 | * record | ||
640 | */ | ||
641 | put_interval = zone_publish_time_window; | ||
642 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | ||
643 | "No records in namestore database.\n"); | ||
644 | } | ||
645 | else | ||
646 | { | ||
647 | /* If records are present, next publication is based on the minimum | ||
648 | * relative expiration time of the records published divided by 4 | ||
649 | */ | ||
650 | zone_publish_time_window | ||
651 | = GNUNET_TIME_relative_min (GNUNET_TIME_relative_divide (min_relative_record_time, 4), | ||
652 | zone_publish_time_window_default); | ||
653 | put_interval = GNUNET_TIME_relative_divide (zone_publish_time_window, | ||
654 | num_public_records); | ||
655 | } | ||
656 | /* reset for next iteration */ | ||
657 | min_relative_record_time = GNUNET_TIME_UNIT_FOREVER_REL; | ||
658 | put_interval = GNUNET_TIME_relative_max (MINIMUM_ZONE_ITERATION_INTERVAL, | ||
659 | put_interval); | ||
660 | put_interval = GNUNET_TIME_relative_min (put_interval, | ||
661 | MAXIMUM_ZONE_ITERATION_INTERVAL); | ||
662 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
663 | "Zone iteration finished. Adjusted zone iteration interval to %s\n", | ||
664 | GNUNET_STRINGS_relative_time_to_string (put_interval, | ||
665 | GNUNET_YES)); | ||
666 | GNUNET_STATISTICS_set (statistics, | ||
667 | "Current zone iteration interval (in ms)", | ||
668 | put_interval.rel_value_us / 1000LL, | ||
669 | GNUNET_NO); | ||
670 | GNUNET_STATISTICS_update (statistics, | ||
671 | "Number of zone iterations", | ||
672 | 1, | ||
673 | GNUNET_NO); | ||
674 | GNUNET_STATISTICS_set (statistics, | ||
675 | "Number of public records in DHT", | ||
676 | last_num_public_records, | ||
677 | GNUNET_NO); | ||
678 | GNUNET_assert (NULL == zone_publish_task); | ||
679 | if (0 == num_public_records) | ||
680 | zone_publish_task = GNUNET_SCHEDULER_add_delayed (put_interval, | ||
681 | &publish_zone_dht_start, | ||
682 | NULL); | ||
683 | else | ||
684 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start, | ||
685 | NULL); | ||
686 | } | ||
687 | |||
688 | |||
689 | /** | ||
690 | * Function used to put all records successively into the DHT. | ||
691 | * | ||
692 | * @param cls the closure (NULL) | ||
693 | * @param key the private key of the authority (ours) | ||
694 | * @param label the name of the records, NULL once the iteration is done | ||
695 | * @param rd_count the number of records in @a rd | ||
696 | * @param rd the record data | ||
697 | */ | ||
698 | static void | ||
699 | put_gns_record (void *cls, | ||
700 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | ||
701 | const char *label, | ||
702 | unsigned int rd_count, | ||
703 | const struct GNUNET_GNSRECORD_Data *rd) | ||
704 | { | ||
705 | struct GNUNET_GNSRECORD_Data rd_public[rd_count]; | ||
706 | unsigned int rd_public_count; | ||
707 | |||
708 | rd_public_count = convert_records_for_export (rd, | ||
709 | rd_count, | ||
710 | rd_public); | ||
711 | |||
712 | if (0 == rd_public_count) | ||
713 | { | ||
714 | GNUNET_assert (NULL == zone_publish_task); | ||
715 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
716 | "Record set empty, moving to next record set\n"); | ||
717 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_next, | ||
718 | NULL); | ||
719 | return; | ||
720 | } | ||
721 | /* We got a set of records to publish */ | ||
722 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
723 | "Starting DHT PUT\n"); | ||
724 | active_put = perform_dht_put (key, | ||
725 | label, | ||
726 | rd_public, | ||
727 | rd_public_count, | ||
728 | NULL); | ||
729 | if (NULL == active_put) | ||
730 | { | ||
731 | GNUNET_break (0); | ||
732 | dht_put_continuation (NULL, GNUNET_NO); | ||
733 | } | ||
734 | } | ||
735 | |||
736 | |||
737 | /** | ||
738 | * Periodically iterate over all zones and store everything in DHT | ||
739 | * | ||
740 | * @param cls NULL | ||
741 | */ | ||
742 | static void | ||
743 | publish_zone_dht_start (void *cls) | ||
744 | { | ||
745 | zone_publish_task = NULL; | ||
746 | |||
747 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
748 | "Starting DHT zone update!\n"); | ||
749 | /* start counting again */ | ||
750 | num_public_records = 0; | ||
751 | GNUNET_assert (NULL == namestore_iter); | ||
752 | namestore_iter | ||
753 | = GNUNET_NAMESTORE_zone_iteration_start (namestore_handle, | ||
754 | NULL, /* All zones */ | ||
755 | &zone_iteration_error, | ||
756 | NULL, | ||
757 | &put_gns_record, | ||
758 | NULL, | ||
759 | &zone_iteration_finished, | ||
760 | NULL); | ||
761 | } | ||
762 | |||
763 | |||
764 | /** | ||
765 | * Process a record that was stored in the namestore | ||
766 | * (invoked by the monitor). | ||
767 | * | ||
768 | * @param cls closure, NULL | ||
769 | * @param zone private key of the zone; NULL on disconnect | ||
770 | * @param label label of the records; NULL on disconnect | ||
771 | * @param rd_count number of entries in @a rd array, 0 if label was deleted | ||
772 | * @param rd array of records with data to store | ||
773 | */ | ||
774 | static void | ||
775 | handle_monitor_event (void *cls, | ||
776 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | ||
777 | const char *label, | ||
778 | unsigned int rd_count, | ||
779 | const struct GNUNET_GNSRECORD_Data *rd) | ||
780 | { | ||
781 | struct GNUNET_GNSRECORD_Data rd_public[rd_count]; | ||
782 | unsigned int rd_public_count; | ||
783 | struct MonitorActivity *ma; | ||
784 | |||
785 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
786 | "Received %u records for label `%s' via namestore monitor\n", | ||
787 | rd_count, | ||
788 | label); | ||
789 | /* filter out records that are not public, and convert to | ||
790 | absolute expiration time. */ | ||
791 | rd_public_count = convert_records_for_export (rd, | ||
792 | rd_count, | ||
793 | rd_public); | ||
794 | if (0 == rd_public_count) | ||
795 | return; /* nothing to do */ | ||
796 | ma = GNUNET_new (struct MonitorActivity); | ||
797 | ma->ph = perform_dht_put (zone, | ||
798 | label, | ||
799 | rd, | ||
800 | rd_count, | ||
801 | ma); | ||
802 | if (NULL == ma->ph) | ||
803 | { | ||
804 | /* PUT failed, do not remember operation */ | ||
805 | GNUNET_free (ma); | ||
806 | return; | ||
807 | } | ||
808 | GNUNET_CONTAINER_DLL_insert (ma_head, | ||
809 | ma_tail, | ||
810 | ma); | ||
811 | } | ||
812 | |||
813 | |||
814 | /* END DHT ZONE PROPAGATION */ | ||
815 | |||
816 | |||
817 | /** | ||
818 | * Reply to client with the result from our lookup. | 261 | * Reply to client with the result from our lookup. |
819 | * | 262 | * |
820 | * @param cls the closure (our client lookup handle) | 263 | * @param cls the closure (our client lookup handle) |
@@ -1020,49 +463,6 @@ handle_rev_lookup (void *cls, | |||
1020 | 463 | ||
1021 | 464 | ||
1022 | /** | 465 | /** |
1023 | * The zone monitor is now in SYNC with the current state of the | ||
1024 | * name store. Start to perform periodic iterations. | ||
1025 | * | ||
1026 | * @param cls NULL | ||
1027 | */ | ||
1028 | static void | ||
1029 | monitor_sync_event (void *cls) | ||
1030 | { | ||
1031 | GNUNET_assert (NULL == zone_publish_task); | ||
1032 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start, | ||
1033 | NULL); | ||
1034 | } | ||
1035 | |||
1036 | |||
1037 | /** | ||
1038 | * The zone monitor is now in SYNC with the current state of the | ||
1039 | * name store. Start to perform periodic iterations. | ||
1040 | * | ||
1041 | * @param cls NULL | ||
1042 | */ | ||
1043 | static void | ||
1044 | handle_monitor_error (void *cls) | ||
1045 | { | ||
1046 | if (NULL != zone_publish_task) | ||
1047 | { | ||
1048 | GNUNET_SCHEDULER_cancel (zone_publish_task); | ||
1049 | zone_publish_task = NULL; | ||
1050 | } | ||
1051 | if (NULL != namestore_iter) | ||
1052 | { | ||
1053 | GNUNET_NAMESTORE_zone_iteration_stop (namestore_iter); | ||
1054 | namestore_iter = NULL; | ||
1055 | } | ||
1056 | if (NULL != active_put) | ||
1057 | { | ||
1058 | GNUNET_DHT_put_cancel (active_put); | ||
1059 | active_put = NULL; | ||
1060 | } | ||
1061 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start, | ||
1062 | NULL); | ||
1063 | } | ||
1064 | |||
1065 | /** | ||
1066 | * Method called to inform about the ego to be used for the master zone | 466 | * Method called to inform about the ego to be used for the master zone |
1067 | * for DNS interceptions. | 467 | * for DNS interceptions. |
1068 | * | 468 | * |
@@ -1107,7 +507,6 @@ identity_reverse_cb (void *cls, | |||
1107 | } | 507 | } |
1108 | 508 | ||
1109 | 509 | ||
1110 | |||
1111 | /** | 510 | /** |
1112 | * Method called to inform about the ego to be used for the master zone | 511 | * Method called to inform about the ego to be used for the master zone |
1113 | * for DNS interceptions. | 512 | * for DNS interceptions. |
@@ -1178,8 +577,7 @@ run (void *cls, | |||
1178 | unsigned long long max_parallel_bg_queries = 0; | 577 | unsigned long long max_parallel_bg_queries = 0; |
1179 | 578 | ||
1180 | v6_enabled = GNUNET_NETWORK_test_pf (PF_INET6); | 579 | v6_enabled = GNUNET_NETWORK_test_pf (PF_INET6); |
1181 | v4_enabled = GNUNET_NETWORK_test_pf (PF_INET); | 580 | v4_enabled = GNUNET_NETWORK_test_pf (PF_INET); |
1182 | min_relative_record_time = GNUNET_TIME_UNIT_FOREVER_REL; | ||
1183 | namestore_handle = GNUNET_NAMESTORE_connect (c); | 581 | namestore_handle = GNUNET_NAMESTORE_connect (c); |
1184 | if (NULL == namestore_handle) | 582 | if (NULL == namestore_handle) |
1185 | { | 583 | { |
@@ -1188,7 +586,7 @@ run (void *cls, | |||
1188 | GNUNET_SCHEDULER_shutdown (); | 586 | GNUNET_SCHEDULER_shutdown (); |
1189 | return; | 587 | return; |
1190 | } | 588 | } |
1191 | namecache_handle = GNUNET_NAMECACHE_connect (c); | 589 | namecache_handle = GNUNET_NAMECACHE_connect (c); |
1192 | if (NULL == namecache_handle) | 590 | if (NULL == namecache_handle) |
1193 | { | 591 | { |
1194 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 592 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
@@ -1197,29 +595,6 @@ run (void *cls, | |||
1197 | return; | 595 | return; |
1198 | } | 596 | } |
1199 | 597 | ||
1200 | put_interval = INITIAL_PUT_INTERVAL; | ||
1201 | zone_publish_time_window_default = DEFAULT_ZONE_PUBLISH_TIME_WINDOW; | ||
1202 | if (GNUNET_OK == | ||
1203 | GNUNET_CONFIGURATION_get_value_time (c, "gns", | ||
1204 | "ZONE_PUBLISH_TIME_WINDOW", | ||
1205 | &zone_publish_time_window_default)) | ||
1206 | { | ||
1207 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1208 | "Time window for zone iteration: %s\n", | ||
1209 | GNUNET_STRINGS_relative_time_to_string (zone_publish_time_window, | ||
1210 | GNUNET_YES)); | ||
1211 | } | ||
1212 | zone_publish_time_window = zone_publish_time_window_default; | ||
1213 | if (GNUNET_OK == | ||
1214 | GNUNET_CONFIGURATION_get_value_number (c, "gns", | ||
1215 | "MAX_PARALLEL_BACKGROUND_QUERIES", | ||
1216 | &max_parallel_bg_queries)) | ||
1217 | { | ||
1218 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1219 | "Number of allowed parallel background queries: %llu\n", | ||
1220 | max_parallel_bg_queries); | ||
1221 | } | ||
1222 | |||
1223 | dht_handle = GNUNET_DHT_connect (c, | 598 | dht_handle = GNUNET_DHT_connect (c, |
1224 | (unsigned int) max_parallel_bg_queries); | 599 | (unsigned int) max_parallel_bg_queries); |
1225 | if (NULL == dht_handle) | 600 | if (NULL == dht_handle) |
@@ -1254,19 +629,7 @@ run (void *cls, | |||
1254 | GNS_shorten_init (namestore_handle, | 629 | GNS_shorten_init (namestore_handle, |
1255 | namecache_handle, | 630 | namecache_handle, |
1256 | dht_handle); | 631 | dht_handle); |
1257 | /* Schedule periodic put for our records. */ | ||
1258 | first_zone_iteration = GNUNET_YES; | ||
1259 | statistics = GNUNET_STATISTICS_create ("gns", c); | 632 | statistics = GNUNET_STATISTICS_create ("gns", c); |
1260 | zmon = GNUNET_NAMESTORE_zone_monitor_start (c, | ||
1261 | NULL, | ||
1262 | GNUNET_NO, | ||
1263 | &handle_monitor_error, | ||
1264 | NULL, | ||
1265 | &handle_monitor_event, | ||
1266 | NULL, | ||
1267 | &monitor_sync_event, | ||
1268 | NULL); | ||
1269 | GNUNET_break (NULL != zmon); | ||
1270 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); | 633 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); |
1271 | } | 634 | } |
1272 | 635 | ||
diff --git a/src/gns/gnunet-service-gns_reverser.c b/src/gns/gnunet-service-gns_reverser.c index 931dc6809..b5b8b31b7 100644 --- a/src/gns/gnunet-service-gns_reverser.c +++ b/src/gns/gnunet-service-gns_reverser.c | |||
@@ -394,6 +394,7 @@ handle_gns_result_iter (void *cls, | |||
394 | it_task = GNUNET_SCHEDULER_add_now (&next_it, ith); | 394 | it_task = GNUNET_SCHEDULER_add_now (&next_it, ith); |
395 | } | 395 | } |
396 | 396 | ||
397 | |||
397 | static void | 398 | static void |
398 | next_it (void *cls) | 399 | next_it (void *cls) |
399 | { | 400 | { |
@@ -402,6 +403,7 @@ next_it (void *cls) | |||
402 | GNUNET_NAMESTORE_zone_iterator_next (namestore_iter); | 403 | GNUNET_NAMESTORE_zone_iterator_next (namestore_iter); |
403 | } | 404 | } |
404 | 405 | ||
406 | |||
405 | static void | 407 | static void |
406 | iterator_cb (void *cls, | 408 | iterator_cb (void *cls, |
407 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | 409 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, |
@@ -487,6 +489,7 @@ store_reverse (void *cls, | |||
487 | GNUNET_free (ith); | 489 | GNUNET_free (ith); |
488 | } | 490 | } |
489 | 491 | ||
492 | |||
490 | static void | 493 | static void |
491 | finished_cb (void *cls) | 494 | finished_cb (void *cls) |
492 | { | 495 | { |
@@ -522,6 +525,7 @@ finished_cb (void *cls) | |||
522 | 525 | ||
523 | } | 526 | } |
524 | 527 | ||
528 | |||
525 | static void | 529 | static void |
526 | it_error (void *cls) | 530 | it_error (void *cls) |
527 | { | 531 | { |
@@ -529,6 +533,7 @@ it_error (void *cls) | |||
529 | "Error iterating for REVERSE\n"); | 533 | "Error iterating for REVERSE\n"); |
530 | } | 534 | } |
531 | 535 | ||
536 | |||
532 | static void | 537 | static void |
533 | check_reverse_records (void *cls) | 538 | check_reverse_records (void *cls) |
534 | { | 539 | { |
diff --git a/src/vpn/vpn.conf.in b/src/vpn/vpn.conf.in index 000300084..585131554 100644 --- a/src/vpn/vpn.conf.in +++ b/src/vpn/vpn.conf.in | |||
@@ -6,7 +6,7 @@ BINARY = gnunet-service-vpn | |||
6 | ACCEPT_FROM = 127.0.0.1; | 6 | ACCEPT_FROM = 127.0.0.1; |
7 | ACCEPT_FROM6 = ::1; | 7 | ACCEPT_FROM6 = ::1; |
8 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-vpn.sock | 8 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-vpn.sock |
9 | UNIX_MATCH_UID = YES | 9 | UNIX_MATCH_UID = NO |
10 | UNIX_MATCH_GID = YES | 10 | UNIX_MATCH_GID = YES |
11 | 11 | ||
12 | IPV6ADDR = 1234::1 | 12 | IPV6ADDR = 1234::1 |
diff --git a/src/zonemaster/Makefile.am b/src/zonemaster/Makefile.am new file mode 100644 index 000000000..21f986498 --- /dev/null +++ b/src/zonemaster/Makefile.am | |||
@@ -0,0 +1,35 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | AM_CPPFLAGS = -I$(top_srcdir)/src/include | ||
3 | |||
4 | plugindir = $(libdir)/gnunet | ||
5 | |||
6 | pkgcfgdir= $(pkgdatadir)/config.d/ | ||
7 | |||
8 | libexecdir= $(pkglibdir)/libexec/ | ||
9 | |||
10 | pkgcfg_DATA = \ | ||
11 | zonemaster.conf | ||
12 | |||
13 | if MINGW | ||
14 | WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols | ||
15 | endif | ||
16 | |||
17 | if USE_COVERAGE | ||
18 | AM_CFLAGS = --coverage -O0 | ||
19 | XLIBS = -lgcov | ||
20 | endif | ||
21 | |||
22 | libexec_PROGRAMS = \ | ||
23 | gnunet-service-zonemaster | ||
24 | |||
25 | gnunet_service_zonemaster_SOURCES = \ | ||
26 | gnunet-service-zonemaster.c | ||
27 | |||
28 | gnunet_service_zonemaster_LDADD = \ | ||
29 | $(top_builddir)/src/dht/libgnunetdht.la \ | ||
30 | $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ | ||
31 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | ||
32 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
33 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | ||
34 | $(GN_LIBINTL) | ||
35 | |||
diff --git a/src/zonemaster/gnunet-service-zonemaster.c b/src/zonemaster/gnunet-service-zonemaster.c new file mode 100644 index 000000000..d61eb723f --- /dev/null +++ b/src/zonemaster/gnunet-service-zonemaster.c | |||
@@ -0,0 +1,773 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012, 2013, 2014, 2017 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file zonemaster/gnunet-service-zonemaster.c | ||
23 | * @brief publish records from namestore to GNUnet name system | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_dnsparser_lib.h" | ||
29 | #include "gnunet_dht_service.h" | ||
30 | #include "gnunet_namestore_service.h" | ||
31 | #include "gnunet_statistics_service.h" | ||
32 | #include "gnunet_namestore_plugin.h" | ||
33 | #include "gnunet_signatures.h" | ||
34 | |||
35 | |||
36 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | ||
37 | |||
38 | |||
39 | |||
40 | /** | ||
41 | * The initial interval in milliseconds btween puts in | ||
42 | * a zone iteration | ||
43 | */ | ||
44 | #define INITIAL_PUT_INTERVAL GNUNET_TIME_UNIT_MILLISECONDS | ||
45 | |||
46 | /** | ||
47 | * The lower bound for the zone iteration interval | ||
48 | */ | ||
49 | #define MINIMUM_ZONE_ITERATION_INTERVAL GNUNET_TIME_UNIT_SECONDS | ||
50 | |||
51 | /** | ||
52 | * The upper bound for the zone iteration interval | ||
53 | */ | ||
54 | #define MAXIMUM_ZONE_ITERATION_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15) | ||
55 | |||
56 | /** | ||
57 | * The default put interval for the zone iteration. In case | ||
58 | * no option is found | ||
59 | */ | ||
60 | #define DEFAULT_ZONE_PUBLISH_TIME_WINDOW GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4) | ||
61 | |||
62 | /** | ||
63 | * The factor the current zone iteration interval is divided by for each | ||
64 | * additional new record | ||
65 | */ | ||
66 | #define LATE_ITERATION_SPEEDUP_FACTOR 2 | ||
67 | |||
68 | /** | ||
69 | * How long until a DHT PUT attempt should time out? | ||
70 | */ | ||
71 | #define DHT_OPERATION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) | ||
72 | |||
73 | /** | ||
74 | * What replication level do we use for DHT PUT operations? | ||
75 | */ | ||
76 | #define DHT_GNS_REPLICATION_LEVEL 5 | ||
77 | |||
78 | |||
79 | /** | ||
80 | * Handle for DHT PUT activity triggered from the namestore monitor. | ||
81 | */ | ||
82 | struct MonitorActivity | ||
83 | { | ||
84 | /** | ||
85 | * Kept in a DLL. | ||
86 | */ | ||
87 | struct MonitorActivity *next; | ||
88 | |||
89 | /** | ||
90 | * Kept in a DLL. | ||
91 | */ | ||
92 | struct MonitorActivity *prev; | ||
93 | |||
94 | /** | ||
95 | * Handle for the DHT PUT operation. | ||
96 | */ | ||
97 | struct GNUNET_DHT_PutHandle *ph; | ||
98 | }; | ||
99 | |||
100 | |||
101 | /** | ||
102 | * Handle to the statistics service | ||
103 | */ | ||
104 | static struct GNUNET_STATISTICS_Handle *statistics; | ||
105 | |||
106 | /** | ||
107 | * Our handle to the DHT | ||
108 | */ | ||
109 | static struct GNUNET_DHT_Handle *dht_handle; | ||
110 | |||
111 | /** | ||
112 | * Active DHT put operation (or NULL) | ||
113 | */ | ||
114 | static struct GNUNET_DHT_PutHandle *active_put; | ||
115 | |||
116 | /** | ||
117 | * Our handle to the namestore service | ||
118 | */ | ||
119 | static struct GNUNET_NAMESTORE_Handle *namestore_handle; | ||
120 | |||
121 | /** | ||
122 | * Handle to iterate over our authoritative zone in namestore | ||
123 | */ | ||
124 | static struct GNUNET_NAMESTORE_ZoneIterator *namestore_iter; | ||
125 | |||
126 | /** | ||
127 | * Handle to monitor namestore changes to instant propagation. | ||
128 | */ | ||
129 | static struct GNUNET_NAMESTORE_ZoneMonitor *zmon; | ||
130 | |||
131 | /** | ||
132 | * Head of monitor activities; kept in a DLL. | ||
133 | */ | ||
134 | static struct MonitorActivity *ma_head; | ||
135 | |||
136 | /** | ||
137 | * Tail of monitor activities; kept in a DLL. | ||
138 | */ | ||
139 | static struct MonitorActivity *ma_tail; | ||
140 | |||
141 | /** | ||
142 | * Useful for zone update for DHT put | ||
143 | */ | ||
144 | static unsigned long long num_public_records; | ||
145 | |||
146 | /** | ||
147 | * Last seen record count | ||
148 | */ | ||
149 | static unsigned long long last_num_public_records; | ||
150 | |||
151 | /** | ||
152 | * Minimum relative expiration time of records seem during the current | ||
153 | * zone iteration. | ||
154 | */ | ||
155 | static struct GNUNET_TIME_Relative min_relative_record_time; | ||
156 | |||
157 | /** | ||
158 | * Zone iteration PUT interval. | ||
159 | */ | ||
160 | static struct GNUNET_TIME_Relative put_interval; | ||
161 | |||
162 | /** | ||
163 | * Default time window for zone iteration | ||
164 | */ | ||
165 | static struct GNUNET_TIME_Relative zone_publish_time_window_default; | ||
166 | |||
167 | /** | ||
168 | * Time window for zone iteration, adjusted based on relative record | ||
169 | * expiration times in our zone. | ||
170 | */ | ||
171 | static struct GNUNET_TIME_Relative zone_publish_time_window; | ||
172 | |||
173 | /** | ||
174 | * zone publish task | ||
175 | */ | ||
176 | static struct GNUNET_SCHEDULER_Task *zone_publish_task; | ||
177 | |||
178 | /** | ||
179 | * #GNUNET_YES if zone has never been published before | ||
180 | */ | ||
181 | static int first_zone_iteration; | ||
182 | |||
183 | /** | ||
184 | * Task run during shutdown. | ||
185 | * | ||
186 | * @param cls unused | ||
187 | * @param tc unused | ||
188 | */ | ||
189 | static void | ||
190 | shutdown_task (void *cls) | ||
191 | { | ||
192 | struct MonitorActivity *ma; | ||
193 | |||
194 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
195 | "Shutting down!\n"); | ||
196 | while (NULL != (ma = ma_head)) | ||
197 | { | ||
198 | GNUNET_DHT_put_cancel (ma->ph); | ||
199 | GNUNET_CONTAINER_DLL_remove (ma_head, | ||
200 | ma_tail, | ||
201 | ma); | ||
202 | GNUNET_free (ma); | ||
203 | } | ||
204 | if (NULL != statistics) | ||
205 | { | ||
206 | GNUNET_STATISTICS_destroy (statistics, | ||
207 | GNUNET_NO); | ||
208 | statistics = NULL; | ||
209 | } | ||
210 | if (NULL != zone_publish_task) | ||
211 | { | ||
212 | GNUNET_SCHEDULER_cancel (zone_publish_task); | ||
213 | zone_publish_task = NULL; | ||
214 | } | ||
215 | if (NULL != namestore_iter) | ||
216 | { | ||
217 | GNUNET_NAMESTORE_zone_iteration_stop (namestore_iter); | ||
218 | namestore_iter = NULL; | ||
219 | } | ||
220 | if (NULL != zmon) | ||
221 | { | ||
222 | GNUNET_NAMESTORE_zone_monitor_stop (zmon); | ||
223 | zmon = NULL; | ||
224 | } | ||
225 | if (NULL != namestore_handle) | ||
226 | { | ||
227 | GNUNET_NAMESTORE_disconnect (namestore_handle); | ||
228 | namestore_handle = NULL; | ||
229 | } | ||
230 | if (NULL != active_put) | ||
231 | { | ||
232 | GNUNET_DHT_put_cancel (active_put); | ||
233 | active_put = NULL; | ||
234 | } | ||
235 | if (NULL != dht_handle) | ||
236 | { | ||
237 | GNUNET_DHT_disconnect (dht_handle); | ||
238 | dht_handle = NULL; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | |||
243 | /** | ||
244 | * Method called periodically that triggers iteration over authoritative records | ||
245 | * | ||
246 | * @param cls closure | ||
247 | */ | ||
248 | static void | ||
249 | publish_zone_dht_next (void *cls) | ||
250 | { | ||
251 | zone_publish_task = NULL; | ||
252 | GNUNET_assert (NULL != namestore_iter); | ||
253 | GNUNET_NAMESTORE_zone_iterator_next (namestore_iter); | ||
254 | } | ||
255 | |||
256 | |||
257 | /** | ||
258 | * Periodically iterate over our zone and store everything in dht | ||
259 | * | ||
260 | * @param cls NULL | ||
261 | */ | ||
262 | static void | ||
263 | publish_zone_dht_start (void *cls); | ||
264 | |||
265 | |||
266 | /** | ||
267 | * Continuation called from DHT once the PUT operation is done. | ||
268 | * | ||
269 | * @param cls closure, NULL if called from regular iteration, | ||
270 | * `struct MonitorActivity` if called from #handle_monitor_event. | ||
271 | * @param success #GNUNET_OK on success | ||
272 | */ | ||
273 | static void | ||
274 | dht_put_continuation (void *cls, | ||
275 | int success) | ||
276 | { | ||
277 | struct MonitorActivity *ma = cls; | ||
278 | struct GNUNET_TIME_Relative next_put_interval; | ||
279 | |||
280 | num_public_records++; | ||
281 | if (NULL == ma) | ||
282 | { | ||
283 | active_put = NULL; | ||
284 | if ( (num_public_records > last_num_public_records) && | ||
285 | (GNUNET_NO == first_zone_iteration) ) | ||
286 | { | ||
287 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
288 | "Last record count was lower than current record count. Reducing interval.\n"); | ||
289 | put_interval = GNUNET_TIME_relative_divide (zone_publish_time_window, | ||
290 | num_public_records); | ||
291 | next_put_interval = GNUNET_TIME_relative_divide (put_interval, | ||
292 | LATE_ITERATION_SPEEDUP_FACTOR); | ||
293 | } | ||
294 | else | ||
295 | next_put_interval = put_interval; | ||
296 | next_put_interval = GNUNET_TIME_relative_min (next_put_interval, | ||
297 | MAXIMUM_ZONE_ITERATION_INTERVAL); | ||
298 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
299 | "PUT complete, next PUT in %s!\n", | ||
300 | GNUNET_STRINGS_relative_time_to_string (next_put_interval, | ||
301 | GNUNET_YES)); | ||
302 | |||
303 | GNUNET_STATISTICS_set (statistics, | ||
304 | "Current zone iteration interval (ms)", | ||
305 | next_put_interval.rel_value_us / 1000LL, | ||
306 | GNUNET_NO); | ||
307 | GNUNET_assert (NULL == zone_publish_task); | ||
308 | zone_publish_task = GNUNET_SCHEDULER_add_delayed (next_put_interval, | ||
309 | &publish_zone_dht_next, | ||
310 | NULL); | ||
311 | } | ||
312 | else | ||
313 | { | ||
314 | GNUNET_CONTAINER_DLL_remove (ma_head, | ||
315 | ma_tail, | ||
316 | ma); | ||
317 | GNUNET_free (ma); | ||
318 | } | ||
319 | } | ||
320 | |||
321 | |||
322 | /** | ||
323 | * Convert namestore records from the internal format to that | ||
324 | * suitable for publication (removes private records, converts | ||
325 | * to absolute expiration time). | ||
326 | * | ||
327 | * @param rd input records | ||
328 | * @param rd_count size of the @a rd and @a rd_public arrays | ||
329 | * @param rd_public where to write the converted records | ||
330 | * @return number of records written to @a rd_public | ||
331 | */ | ||
332 | static unsigned int | ||
333 | convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd, | ||
334 | unsigned int rd_count, | ||
335 | struct GNUNET_GNSRECORD_Data *rd_public) | ||
336 | { | ||
337 | struct GNUNET_TIME_Absolute now; | ||
338 | unsigned int rd_public_count; | ||
339 | unsigned int i; | ||
340 | |||
341 | rd_public_count = 0; | ||
342 | now = GNUNET_TIME_absolute_get (); | ||
343 | for (i=0;i<rd_count;i++) | ||
344 | if (0 == (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) | ||
345 | { | ||
346 | rd_public[rd_public_count] = rd[i]; | ||
347 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) | ||
348 | { | ||
349 | /* GNUNET_GNSRECORD_block_create will convert to absolute time; | ||
350 | we just need to adjust our iteration frequency */ | ||
351 | min_relative_record_time.rel_value_us = | ||
352 | GNUNET_MIN (rd_public[rd_public_count].expiration_time, | ||
353 | min_relative_record_time.rel_value_us); | ||
354 | } | ||
355 | else if (rd_public[rd_public_count].expiration_time < now.abs_value_us) | ||
356 | { | ||
357 | /* record already expired, skip it */ | ||
358 | continue; | ||
359 | } | ||
360 | rd_public_count++; | ||
361 | } | ||
362 | return rd_public_count; | ||
363 | } | ||
364 | |||
365 | |||
366 | /** | ||
367 | * Store GNS records in the DHT. | ||
368 | * | ||
369 | * @param key key of the zone | ||
370 | * @param label label to store under | ||
371 | * @param rd_public public record data | ||
372 | * @param rd_public_count number of records in @a rd_public | ||
373 | * @param pc_arg closure argument to pass to the #dht_put_continuation | ||
374 | * @return DHT PUT handle, NULL on error | ||
375 | */ | ||
376 | static struct GNUNET_DHT_PutHandle * | ||
377 | perform_dht_put (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | ||
378 | const char *label, | ||
379 | const struct GNUNET_GNSRECORD_Data *rd_public, | ||
380 | unsigned int rd_public_count, | ||
381 | void *pc_arg) | ||
382 | { | ||
383 | struct GNUNET_GNSRECORD_Block *block; | ||
384 | struct GNUNET_HashCode query; | ||
385 | struct GNUNET_TIME_Absolute expire; | ||
386 | size_t block_size; | ||
387 | struct GNUNET_DHT_PutHandle *ret; | ||
388 | |||
389 | expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_public_count, | ||
390 | rd_public); | ||
391 | block = GNUNET_GNSRECORD_block_create (key, | ||
392 | expire, | ||
393 | label, | ||
394 | rd_public, | ||
395 | rd_public_count); | ||
396 | if (NULL == block) | ||
397 | return NULL; /* whoops */ | ||
398 | block_size = ntohl (block->purpose.size) | ||
399 | + sizeof (struct GNUNET_CRYPTO_EcdsaSignature) | ||
400 | + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); | ||
401 | GNUNET_GNSRECORD_query_from_private_key (key, | ||
402 | label, | ||
403 | &query); | ||
404 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
405 | "Storing %u record(s) for label `%s' in DHT with expiration `%s' under key %s\n", | ||
406 | rd_public_count, | ||
407 | label, | ||
408 | GNUNET_STRINGS_absolute_time_to_string (expire), | ||
409 | GNUNET_h2s (&query)); | ||
410 | ret = GNUNET_DHT_put (dht_handle, | ||
411 | &query, | ||
412 | DHT_GNS_REPLICATION_LEVEL, | ||
413 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, | ||
414 | GNUNET_BLOCK_TYPE_GNS_NAMERECORD, | ||
415 | block_size, | ||
416 | block, | ||
417 | expire, | ||
418 | &dht_put_continuation, | ||
419 | pc_arg); | ||
420 | GNUNET_free (block); | ||
421 | return ret; | ||
422 | } | ||
423 | |||
424 | |||
425 | /** | ||
426 | * We encountered an error in our zone iteration. | ||
427 | */ | ||
428 | static void | ||
429 | zone_iteration_error (void *cls) | ||
430 | { | ||
431 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
432 | "Got disconnected from namestore database, retrying.\n"); | ||
433 | namestore_iter = NULL; | ||
434 | /* We end up here on error/disconnect/shutdown, so potentially | ||
435 | while a zone publish task or a DHT put is still running; hence | ||
436 | we need to cancel those. */ | ||
437 | if (NULL != zone_publish_task) | ||
438 | { | ||
439 | GNUNET_SCHEDULER_cancel (zone_publish_task); | ||
440 | zone_publish_task = NULL; | ||
441 | } | ||
442 | if (NULL != active_put) | ||
443 | { | ||
444 | GNUNET_DHT_put_cancel (active_put); | ||
445 | active_put = NULL; | ||
446 | } | ||
447 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start, | ||
448 | NULL); | ||
449 | } | ||
450 | |||
451 | |||
452 | /** | ||
453 | * Zone iteration is completed. | ||
454 | */ | ||
455 | static void | ||
456 | zone_iteration_finished (void *cls) | ||
457 | { | ||
458 | /* we're done with one iteration, calculate when to do the next one */ | ||
459 | namestore_iter = NULL; | ||
460 | last_num_public_records = num_public_records; | ||
461 | first_zone_iteration = GNUNET_NO; | ||
462 | if (0 == num_public_records) | ||
463 | { | ||
464 | /** | ||
465 | * If no records are known (startup) or none present | ||
466 | * we can safely set the interval to the value for a single | ||
467 | * record | ||
468 | */ | ||
469 | put_interval = zone_publish_time_window; | ||
470 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | ||
471 | "No records in namestore database.\n"); | ||
472 | } | ||
473 | else | ||
474 | { | ||
475 | /* If records are present, next publication is based on the minimum | ||
476 | * relative expiration time of the records published divided by 4 | ||
477 | */ | ||
478 | zone_publish_time_window | ||
479 | = GNUNET_TIME_relative_min (GNUNET_TIME_relative_divide (min_relative_record_time, 4), | ||
480 | zone_publish_time_window_default); | ||
481 | put_interval = GNUNET_TIME_relative_divide (zone_publish_time_window, | ||
482 | num_public_records); | ||
483 | } | ||
484 | /* reset for next iteration */ | ||
485 | min_relative_record_time = GNUNET_TIME_UNIT_FOREVER_REL; | ||
486 | put_interval = GNUNET_TIME_relative_max (MINIMUM_ZONE_ITERATION_INTERVAL, | ||
487 | put_interval); | ||
488 | put_interval = GNUNET_TIME_relative_min (put_interval, | ||
489 | MAXIMUM_ZONE_ITERATION_INTERVAL); | ||
490 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
491 | "Zone iteration finished. Adjusted zone iteration interval to %s\n", | ||
492 | GNUNET_STRINGS_relative_time_to_string (put_interval, | ||
493 | GNUNET_YES)); | ||
494 | GNUNET_STATISTICS_set (statistics, | ||
495 | "Current zone iteration interval (in ms)", | ||
496 | put_interval.rel_value_us / 1000LL, | ||
497 | GNUNET_NO); | ||
498 | GNUNET_STATISTICS_update (statistics, | ||
499 | "Number of zone iterations", | ||
500 | 1, | ||
501 | GNUNET_NO); | ||
502 | GNUNET_STATISTICS_set (statistics, | ||
503 | "Number of public records in DHT", | ||
504 | last_num_public_records, | ||
505 | GNUNET_NO); | ||
506 | GNUNET_assert (NULL == zone_publish_task); | ||
507 | if (0 == num_public_records) | ||
508 | zone_publish_task = GNUNET_SCHEDULER_add_delayed (put_interval, | ||
509 | &publish_zone_dht_start, | ||
510 | NULL); | ||
511 | else | ||
512 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start, | ||
513 | NULL); | ||
514 | } | ||
515 | |||
516 | |||
517 | /** | ||
518 | * Function used to put all records successively into the DHT. | ||
519 | * | ||
520 | * @param cls the closure (NULL) | ||
521 | * @param key the private key of the authority (ours) | ||
522 | * @param label the name of the records, NULL once the iteration is done | ||
523 | * @param rd_count the number of records in @a rd | ||
524 | * @param rd the record data | ||
525 | */ | ||
526 | static void | ||
527 | put_gns_record (void *cls, | ||
528 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | ||
529 | const char *label, | ||
530 | unsigned int rd_count, | ||
531 | const struct GNUNET_GNSRECORD_Data *rd) | ||
532 | { | ||
533 | struct GNUNET_GNSRECORD_Data rd_public[rd_count]; | ||
534 | unsigned int rd_public_count; | ||
535 | |||
536 | rd_public_count = convert_records_for_export (rd, | ||
537 | rd_count, | ||
538 | rd_public); | ||
539 | |||
540 | if (0 == rd_public_count) | ||
541 | { | ||
542 | GNUNET_assert (NULL == zone_publish_task); | ||
543 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
544 | "Record set empty, moving to next record set\n"); | ||
545 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_next, | ||
546 | NULL); | ||
547 | return; | ||
548 | } | ||
549 | /* We got a set of records to publish */ | ||
550 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
551 | "Starting DHT PUT\n"); | ||
552 | active_put = perform_dht_put (key, | ||
553 | label, | ||
554 | rd_public, | ||
555 | rd_public_count, | ||
556 | NULL); | ||
557 | if (NULL == active_put) | ||
558 | { | ||
559 | GNUNET_break (0); | ||
560 | dht_put_continuation (NULL, GNUNET_NO); | ||
561 | } | ||
562 | } | ||
563 | |||
564 | |||
565 | /** | ||
566 | * Periodically iterate over all zones and store everything in DHT | ||
567 | * | ||
568 | * @param cls NULL | ||
569 | */ | ||
570 | static void | ||
571 | publish_zone_dht_start (void *cls) | ||
572 | { | ||
573 | zone_publish_task = NULL; | ||
574 | |||
575 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
576 | "Starting DHT zone update!\n"); | ||
577 | /* start counting again */ | ||
578 | num_public_records = 0; | ||
579 | GNUNET_assert (NULL == namestore_iter); | ||
580 | namestore_iter | ||
581 | = GNUNET_NAMESTORE_zone_iteration_start (namestore_handle, | ||
582 | NULL, /* All zones */ | ||
583 | &zone_iteration_error, | ||
584 | NULL, | ||
585 | &put_gns_record, | ||
586 | NULL, | ||
587 | &zone_iteration_finished, | ||
588 | NULL); | ||
589 | } | ||
590 | |||
591 | |||
592 | /** | ||
593 | * Process a record that was stored in the namestore | ||
594 | * (invoked by the monitor). | ||
595 | * | ||
596 | * @param cls closure, NULL | ||
597 | * @param zone private key of the zone; NULL on disconnect | ||
598 | * @param label label of the records; NULL on disconnect | ||
599 | * @param rd_count number of entries in @a rd array, 0 if label was deleted | ||
600 | * @param rd array of records with data to store | ||
601 | */ | ||
602 | static void | ||
603 | handle_monitor_event (void *cls, | ||
604 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | ||
605 | const char *label, | ||
606 | unsigned int rd_count, | ||
607 | const struct GNUNET_GNSRECORD_Data *rd) | ||
608 | { | ||
609 | struct GNUNET_GNSRECORD_Data rd_public[rd_count]; | ||
610 | unsigned int rd_public_count; | ||
611 | struct MonitorActivity *ma; | ||
612 | |||
613 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
614 | "Received %u records for label `%s' via namestore monitor\n", | ||
615 | rd_count, | ||
616 | label); | ||
617 | /* filter out records that are not public, and convert to | ||
618 | absolute expiration time. */ | ||
619 | rd_public_count = convert_records_for_export (rd, | ||
620 | rd_count, | ||
621 | rd_public); | ||
622 | if (0 == rd_public_count) | ||
623 | return; /* nothing to do */ | ||
624 | ma = GNUNET_new (struct MonitorActivity); | ||
625 | ma->ph = perform_dht_put (zone, | ||
626 | label, | ||
627 | rd, | ||
628 | rd_count, | ||
629 | ma); | ||
630 | if (NULL == ma->ph) | ||
631 | { | ||
632 | /* PUT failed, do not remember operation */ | ||
633 | GNUNET_free (ma); | ||
634 | return; | ||
635 | } | ||
636 | GNUNET_CONTAINER_DLL_insert (ma_head, | ||
637 | ma_tail, | ||
638 | ma); | ||
639 | } | ||
640 | |||
641 | |||
642 | /** | ||
643 | * The zone monitor is now in SYNC with the current state of the | ||
644 | * name store. Start to perform periodic iterations. | ||
645 | * | ||
646 | * @param cls NULL | ||
647 | */ | ||
648 | static void | ||
649 | monitor_sync_event (void *cls) | ||
650 | { | ||
651 | GNUNET_assert (NULL == zone_publish_task); | ||
652 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start, | ||
653 | NULL); | ||
654 | } | ||
655 | |||
656 | |||
657 | /** | ||
658 | * The zone monitor is now in SYNC with the current state of the | ||
659 | * name store. Start to perform periodic iterations. | ||
660 | * | ||
661 | * @param cls NULL | ||
662 | */ | ||
663 | static void | ||
664 | handle_monitor_error (void *cls) | ||
665 | { | ||
666 | if (NULL != zone_publish_task) | ||
667 | { | ||
668 | GNUNET_SCHEDULER_cancel (zone_publish_task); | ||
669 | zone_publish_task = NULL; | ||
670 | } | ||
671 | if (NULL != namestore_iter) | ||
672 | { | ||
673 | GNUNET_NAMESTORE_zone_iteration_stop (namestore_iter); | ||
674 | namestore_iter = NULL; | ||
675 | } | ||
676 | if (NULL != active_put) | ||
677 | { | ||
678 | GNUNET_DHT_put_cancel (active_put); | ||
679 | active_put = NULL; | ||
680 | } | ||
681 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start, | ||
682 | NULL); | ||
683 | } | ||
684 | |||
685 | |||
686 | /** | ||
687 | * Performe zonemaster duties: watch namestore, publish records. | ||
688 | * | ||
689 | * @param cls closure | ||
690 | * @param server the initialized server | ||
691 | * @param c configuration to use | ||
692 | */ | ||
693 | static void | ||
694 | run (void *cls, | ||
695 | const struct GNUNET_CONFIGURATION_Handle *c, | ||
696 | struct GNUNET_SERVICE_Handle *service) | ||
697 | { | ||
698 | unsigned long long max_parallel_bg_queries = 0; | ||
699 | |||
700 | min_relative_record_time = GNUNET_TIME_UNIT_FOREVER_REL; | ||
701 | namestore_handle = GNUNET_NAMESTORE_connect (c); | ||
702 | if (NULL == namestore_handle) | ||
703 | { | ||
704 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
705 | _("Failed to connect to the namestore!\n")); | ||
706 | GNUNET_SCHEDULER_shutdown (); | ||
707 | return; | ||
708 | } | ||
709 | |||
710 | put_interval = INITIAL_PUT_INTERVAL; | ||
711 | zone_publish_time_window_default = DEFAULT_ZONE_PUBLISH_TIME_WINDOW; | ||
712 | if (GNUNET_OK == | ||
713 | GNUNET_CONFIGURATION_get_value_time (c, "gns", | ||
714 | "ZONE_PUBLISH_TIME_WINDOW", | ||
715 | &zone_publish_time_window_default)) | ||
716 | { | ||
717 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
718 | "Time window for zone iteration: %s\n", | ||
719 | GNUNET_STRINGS_relative_time_to_string (zone_publish_time_window, | ||
720 | GNUNET_YES)); | ||
721 | } | ||
722 | zone_publish_time_window = zone_publish_time_window_default; | ||
723 | if (GNUNET_OK == | ||
724 | GNUNET_CONFIGURATION_get_value_number (c, "gns", | ||
725 | "MAX_PARALLEL_BACKGROUND_QUERIES", | ||
726 | &max_parallel_bg_queries)) | ||
727 | { | ||
728 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
729 | "Number of allowed parallel background queries: %llu\n", | ||
730 | max_parallel_bg_queries); | ||
731 | } | ||
732 | |||
733 | dht_handle = GNUNET_DHT_connect (c, | ||
734 | (unsigned int) max_parallel_bg_queries); | ||
735 | if (NULL == dht_handle) | ||
736 | { | ||
737 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
738 | _("Could not connect to DHT!\n")); | ||
739 | GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); | ||
740 | return; | ||
741 | } | ||
742 | |||
743 | /* Schedule periodic put for our records. */ | ||
744 | first_zone_iteration = GNUNET_YES;\ | ||
745 | statistics = GNUNET_STATISTICS_create ("zonemaster", c); | ||
746 | zmon = GNUNET_NAMESTORE_zone_monitor_start (c, | ||
747 | NULL, | ||
748 | GNUNET_NO, | ||
749 | &handle_monitor_error, | ||
750 | NULL, | ||
751 | &handle_monitor_event, | ||
752 | NULL, | ||
753 | &monitor_sync_event, | ||
754 | NULL); | ||
755 | GNUNET_break (NULL != zmon); | ||
756 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); | ||
757 | } | ||
758 | |||
759 | |||
760 | /** | ||
761 | * Define "main" method using service macro. | ||
762 | */ | ||
763 | GNUNET_SERVICE_MAIN | ||
764 | ("zonemaster", | ||
765 | GNUNET_SERVICE_OPTION_NONE, | ||
766 | &run, | ||
767 | NULL, | ||
768 | NULL, | ||
769 | NULL, | ||
770 | GNUNET_MQ_handler_end()); | ||
771 | |||
772 | |||
773 | /* end of gnunet-service-zonemaster.c */ | ||
diff --git a/src/zonemaster/zonemaster.conf.in b/src/zonemaster/zonemaster.conf.in new file mode 100644 index 000000000..dda0c7ec4 --- /dev/null +++ b/src/zonemaster/zonemaster.conf.in | |||
@@ -0,0 +1,25 @@ | |||
1 | [gns] | ||
2 | AUTOSTART = @AUTOSTART@ | ||
3 | FORCESTART = YES | ||
4 | HOSTNAME = localhost | ||
5 | BINARY = gnunet-service-zonemaster | ||
6 | UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-zonemaster.sock | ||
7 | @JAVAPORT@PORT = 2123 | ||
8 | |||
9 | # Do we require users that want to access GNS to run this process | ||
10 | # (usually not a good idea) | ||
11 | UNIX_MATCH_UID = NO | ||
12 | |||
13 | # Do we require users that want to access GNS to be in the 'gnunet' group? | ||
14 | UNIX_MATCH_GID = NO | ||
15 | |||
16 | # How many queries is GNS allowed to perform in the background at the same time? | ||
17 | MAX_PARALLEL_BACKGROUND_QUERIES = 1000 | ||
18 | |||
19 | # How frequently do we try to publish our full zone? | ||
20 | ZONE_PUBLISH_TIME_WINDOW = 4 h | ||
21 | |||
22 | # Using caching or always ask DHT | ||
23 | # USE_CACHE = YES | ||
24 | |||
25 | # PREFIX = valgrind --leak-check=full --track-origins=yes | ||