diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-10-20 15:50:09 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-10-20 15:50:09 +0000 |
commit | e9496ec9ae3115baf1701f50b9438094dfece97f (patch) | |
tree | 8fbc20580c5aa50c05704bce5f4d4947d18fb90e /src/gns/gnunet-service-gns.c | |
parent | 09f4417022e2bfa68751b8ec67347c4ad3a40034 (diff) | |
download | gnunet-e9496ec9ae3115baf1701f50b9438094dfece97f.tar.gz gnunet-e9496ec9ae3115baf1701f50b9438094dfece97f.zip |
-towards implementing #3051
Diffstat (limited to 'src/gns/gnunet-service-gns.c')
-rw-r--r-- | src/gns/gnunet-service-gns.c | 350 |
1 files changed, 269 insertions, 81 deletions
diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c index 53f065037..ca2e80fd0 100644 --- a/src/gns/gnunet-service-gns.c +++ b/src/gns/gnunet-service-gns.c | |||
@@ -107,6 +107,28 @@ struct ClientLookupHandle | |||
107 | 107 | ||
108 | 108 | ||
109 | /** | 109 | /** |
110 | * Handle for DHT PUT activity triggered from the namestore monitor. | ||
111 | */ | ||
112 | struct MonitorActivity | ||
113 | { | ||
114 | /** | ||
115 | * Kept in a DLL. | ||
116 | */ | ||
117 | struct MonitorActivity *next; | ||
118 | |||
119 | /** | ||
120 | * Kept in a DLL. | ||
121 | */ | ||
122 | struct MonitorActivity *prev; | ||
123 | |||
124 | /** | ||
125 | * Handle for the DHT PUT operation. | ||
126 | */ | ||
127 | struct GNUNET_DHT_PutHandle *ph; | ||
128 | }; | ||
129 | |||
130 | |||
131 | /** | ||
110 | * Our handle to the DHT | 132 | * Our handle to the DHT |
111 | */ | 133 | */ |
112 | static struct GNUNET_DHT_Handle *dht_handle; | 134 | static struct GNUNET_DHT_Handle *dht_handle; |
@@ -132,6 +154,11 @@ static struct GNUNET_NAMECACHE_Handle *namecache_handle; | |||
132 | static struct GNUNET_NAMESTORE_ZoneIterator *namestore_iter; | 154 | static struct GNUNET_NAMESTORE_ZoneIterator *namestore_iter; |
133 | 155 | ||
134 | /** | 156 | /** |
157 | * Handle to monitor namestore changes to instant propagation. | ||
158 | */ | ||
159 | static struct GNUNET_NAMESTORE_ZoneMonitor *zmon; | ||
160 | |||
161 | /** | ||
135 | * Our notification context. | 162 | * Our notification context. |
136 | */ | 163 | */ |
137 | static struct GNUNET_SERVER_NotificationContext *nc; | 164 | static struct GNUNET_SERVER_NotificationContext *nc; |
@@ -147,6 +174,16 @@ static struct ClientLookupHandle *clh_head; | |||
147 | static struct ClientLookupHandle *clh_tail; | 174 | static struct ClientLookupHandle *clh_tail; |
148 | 175 | ||
149 | /** | 176 | /** |
177 | * Head of monitor activities; kept in a DLL. | ||
178 | */ | ||
179 | static struct MonitorActivity *ma_head; | ||
180 | |||
181 | /** | ||
182 | * Tail of monitor activities; kept in a DLL. | ||
183 | */ | ||
184 | static struct MonitorActivity *ma_tail; | ||
185 | |||
186 | /** | ||
150 | * Useful for zone update for DHT put | 187 | * Useful for zone update for DHT put |
151 | */ | 188 | */ |
152 | static unsigned long long num_public_records; | 189 | static unsigned long long num_public_records; |
@@ -199,6 +236,15 @@ static int v6_enabled; | |||
199 | static int v4_enabled; | 236 | static int v4_enabled; |
200 | 237 | ||
201 | /** | 238 | /** |
239 | * Did we finish the initial iteration over the namestore? | ||
240 | * (while we do the initial iteration, we do not generate | ||
241 | * DHT PUTs as there might be WAY too many of those). | ||
242 | * TODO: expand namestore monitor API with a way to | ||
243 | * suppress this initial iteration. | ||
244 | */ | ||
245 | static int sync_finished; | ||
246 | |||
247 | /** | ||
202 | * Handle to the statistics service | 248 | * Handle to the statistics service |
203 | */ | 249 | */ |
204 | static struct GNUNET_STATISTICS_Handle *statistics; | 250 | static struct GNUNET_STATISTICS_Handle *statistics; |
@@ -211,9 +257,11 @@ static struct GNUNET_STATISTICS_Handle *statistics; | |||
211 | * @param tc unused | 257 | * @param tc unused |
212 | */ | 258 | */ |
213 | static void | 259 | static void |
214 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 260 | shutdown_task (void *cls, |
261 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
215 | { | 262 | { |
216 | struct ClientLookupHandle *clh; | 263 | struct ClientLookupHandle *clh; |
264 | struct MonitorActivity *ma; | ||
217 | 265 | ||
218 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 266 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
219 | "Shutting down!\n"); | 267 | "Shutting down!\n"); |
@@ -229,6 +277,14 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
229 | GNS_interceptor_done (); | 277 | GNS_interceptor_done (); |
230 | GNS_resolver_done (); | 278 | GNS_resolver_done (); |
231 | GNS_shorten_done (); | 279 | GNS_shorten_done (); |
280 | while (NULL != (ma = ma_head)) | ||
281 | { | ||
282 | GNUNET_DHT_put_cancel (ma->ph); | ||
283 | GNUNET_CONTAINER_DLL_remove (ma_head, | ||
284 | ma_tail, | ||
285 | ma); | ||
286 | GNUNET_free (ma); | ||
287 | } | ||
232 | if (NULL != statistics) | 288 | if (NULL != statistics) |
233 | { | 289 | { |
234 | GNUNET_STATISTICS_destroy (statistics, GNUNET_NO); | 290 | GNUNET_STATISTICS_destroy (statistics, GNUNET_NO); |
@@ -244,6 +300,11 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
244 | GNUNET_NAMESTORE_zone_iteration_stop (namestore_iter); | 300 | GNUNET_NAMESTORE_zone_iteration_stop (namestore_iter); |
245 | namestore_iter = NULL; | 301 | namestore_iter = NULL; |
246 | } | 302 | } |
303 | if (NULL != zmon) | ||
304 | { | ||
305 | GNUNET_NAMESTORE_zone_monitor_stop (zmon); | ||
306 | zmon = NULL; | ||
307 | } | ||
247 | if (NULL != namestore_handle) | 308 | if (NULL != namestore_handle) |
248 | { | 309 | { |
249 | GNUNET_NAMESTORE_disconnect (namestore_handle); | 310 | GNUNET_NAMESTORE_disconnect (namestore_handle); |
@@ -296,37 +357,148 @@ publish_zone_dht_start (void *cls, | |||
296 | /** | 357 | /** |
297 | * Continuation called from DHT once the PUT operation is done. | 358 | * Continuation called from DHT once the PUT operation is done. |
298 | * | 359 | * |
299 | * @param cls closure, NULL | 360 | * @param cls closure, NULL if called from regular iteration, |
361 | * `struct MonitorActivity` if called from #handle_monitor_event. | ||
300 | * @param success #GNUNET_OK on success | 362 | * @param success #GNUNET_OK on success |
301 | */ | 363 | */ |
302 | static void | 364 | static void |
303 | dht_put_continuation (void *cls, | 365 | dht_put_continuation (void *cls, |
304 | int success) | 366 | int success) |
305 | { | 367 | { |
368 | struct MonitorActivity *ma = cls; | ||
306 | struct GNUNET_TIME_Relative next_put_interval; | 369 | struct GNUNET_TIME_Relative next_put_interval; |
307 | 370 | ||
308 | active_put = NULL; | ||
309 | num_public_records++; | 371 | num_public_records++; |
310 | if ( (num_public_records > last_num_public_records) && | 372 | if (NULL == ma) |
311 | (GNUNET_NO == first_zone_iteration) ) | ||
312 | { | 373 | { |
313 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 374 | active_put = NULL; |
314 | "Last record count was lower than current record count. Reducing interval.\n"); | 375 | if ( (num_public_records > last_num_public_records) && |
315 | put_interval = GNUNET_TIME_relative_divide (zone_publish_time_window, | 376 | (GNUNET_NO == first_zone_iteration) ) |
316 | num_public_records); | 377 | { |
317 | next_put_interval = GNUNET_TIME_relative_divide (put_interval, | 378 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
318 | LATE_ITERATION_SPEEDUP_FACTOR); | 379 | "Last record count was lower than current record count. Reducing interval.\n"); |
380 | put_interval = GNUNET_TIME_relative_divide (zone_publish_time_window, | ||
381 | num_public_records); | ||
382 | next_put_interval = GNUNET_TIME_relative_divide (put_interval, | ||
383 | LATE_ITERATION_SPEEDUP_FACTOR); | ||
384 | } | ||
385 | else | ||
386 | next_put_interval = put_interval; | ||
387 | |||
388 | GNUNET_STATISTICS_set (statistics, | ||
389 | "Current zone iteration interval (ms)", | ||
390 | next_put_interval.rel_value_us / 1000LL, | ||
391 | GNUNET_NO); | ||
392 | zone_publish_task = GNUNET_SCHEDULER_add_delayed (next_put_interval, | ||
393 | &publish_zone_dht_next, | ||
394 | NULL); | ||
319 | } | 395 | } |
320 | else | 396 | else |
321 | next_put_interval = put_interval; | 397 | { |
322 | 398 | GNUNET_CONTAINER_DLL_remove (ma_head, | |
323 | GNUNET_STATISTICS_set (statistics, | 399 | ma_tail, |
324 | "Current zone iteration interval (ms)", | 400 | ma); |
325 | next_put_interval.rel_value_us / 1000LL, | 401 | GNUNET_free (ma); |
326 | GNUNET_NO); | 402 | } |
327 | zone_publish_task = GNUNET_SCHEDULER_add_delayed (next_put_interval, | 403 | } |
328 | &publish_zone_dht_next, | 404 | |
329 | NULL); | 405 | |
406 | /** | ||
407 | * Convert namestore records from the internal format to that | ||
408 | * suitable for publication (removes private records, converts | ||
409 | * to absolute expiration time). | ||
410 | * | ||
411 | * @param rd input records | ||
412 | * @param rd_count size of the @a rd and @a rd_public arrays | ||
413 | * @param rd_public where to write the converted records | ||
414 | * @return number of records written to @a rd_public | ||
415 | */ | ||
416 | static unsigned int | ||
417 | convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd, | ||
418 | unsigned int rd_count, | ||
419 | struct GNUNET_GNSRECORD_Data *rd_public) | ||
420 | { | ||
421 | struct GNUNET_TIME_Absolute now; | ||
422 | unsigned int rd_public_count; | ||
423 | unsigned int i; | ||
424 | |||
425 | rd_public_count = 0; | ||
426 | now = GNUNET_TIME_absolute_get (); | ||
427 | for (i=0;i<rd_count;i++) | ||
428 | if (0 == (rd[i].flags & (GNUNET_GNSRECORD_RF_PRIVATE | | ||
429 | GNUNET_GNSRECORD_RF_PENDING))) | ||
430 | { | ||
431 | rd_public[rd_public_count] = rd[i]; | ||
432 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) | ||
433 | { | ||
434 | /* GNUNET_GNSRECORD_block_create will convert to absolute time; | ||
435 | we just need to adjust our iteration frequency */ | ||
436 | min_relative_record_time.rel_value_us = | ||
437 | GNUNET_MIN (rd_public[rd_public_count].expiration_time, | ||
438 | min_relative_record_time.rel_value_us); | ||
439 | } | ||
440 | else if (rd_public[rd_public_count].expiration_time < now.abs_value_us) | ||
441 | { | ||
442 | /* record already expired, skip it */ | ||
443 | continue; | ||
444 | } | ||
445 | rd_public_count++; | ||
446 | } | ||
447 | return rd_public_count; | ||
448 | } | ||
449 | |||
450 | |||
451 | /** | ||
452 | * Store GNS records in the DHT. | ||
453 | * | ||
454 | * @param key key of the zone | ||
455 | * @param label label to store under | ||
456 | * @param rd_public public record data | ||
457 | * @param rd_public_count number of records in @a rd_public | ||
458 | * @param pc_arg closure argument to pass to the #dht_put_continuation | ||
459 | * @return DHT PUT handle, NULL on error | ||
460 | */ | ||
461 | static struct GNUNET_DHT_PutHandle * | ||
462 | perform_dht_put (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | ||
463 | const char *label, | ||
464 | const struct GNUNET_GNSRECORD_Data *rd_public, | ||
465 | unsigned int rd_public_count, | ||
466 | void *pc_arg) | ||
467 | { | ||
468 | struct GNUNET_GNSRECORD_Block *block; | ||
469 | struct GNUNET_HashCode query; | ||
470 | struct GNUNET_TIME_Absolute expire; | ||
471 | size_t block_size; | ||
472 | struct GNUNET_DHT_PutHandle *ret; | ||
473 | |||
474 | expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_public_count, | ||
475 | rd_public); | ||
476 | block = GNUNET_GNSRECORD_block_create (key, | ||
477 | expire, | ||
478 | label, | ||
479 | rd_public, | ||
480 | rd_public_count); | ||
481 | block_size = ntohl (block->purpose.size) | ||
482 | + sizeof (struct GNUNET_CRYPTO_EcdsaSignature) | ||
483 | + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); | ||
484 | GNUNET_GNSRECORD_query_from_private_key (key, | ||
485 | label, | ||
486 | &query); | ||
487 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
488 | "Storing record in DHT with expiration `%s'\n", | ||
489 | GNUNET_STRINGS_absolute_time_to_string (expire)); | ||
490 | ret = GNUNET_DHT_put (dht_handle, &query, | ||
491 | DHT_GNS_REPLICATION_LEVEL, | ||
492 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, | ||
493 | GNUNET_BLOCK_TYPE_GNS_NAMERECORD, | ||
494 | block_size, | ||
495 | block, | ||
496 | expire, | ||
497 | DHT_OPERATION_TIMEOUT, | ||
498 | &dht_put_continuation, | ||
499 | pc_arg); | ||
500 | GNUNET_free (block); | ||
501 | return ret; | ||
330 | } | 502 | } |
331 | 503 | ||
332 | 504 | ||
@@ -346,14 +518,8 @@ put_gns_record (void *cls, | |||
346 | unsigned int rd_count, | 518 | unsigned int rd_count, |
347 | const struct GNUNET_GNSRECORD_Data *rd) | 519 | const struct GNUNET_GNSRECORD_Data *rd) |
348 | { | 520 | { |
349 | struct GNUNET_GNSRECORD_Block *block; | ||
350 | struct GNUNET_HashCode query; | ||
351 | struct GNUNET_TIME_Absolute expire; | ||
352 | struct GNUNET_TIME_Absolute now; | ||
353 | size_t block_size; | ||
354 | struct GNUNET_GNSRECORD_Data rd_public[rd_count]; | 521 | struct GNUNET_GNSRECORD_Data rd_public[rd_count]; |
355 | unsigned int rd_public_count; | 522 | unsigned int rd_public_count; |
356 | unsigned int i; | ||
357 | 523 | ||
358 | if (NULL == name) | 524 | if (NULL == name) |
359 | { | 525 | { |
@@ -411,30 +577,9 @@ put_gns_record (void *cls, | |||
411 | return; | 577 | return; |
412 | } | 578 | } |
413 | 579 | ||
414 | /* filter out records that are not public, and convert to | 580 | rd_public_count = convert_records_for_export (rd, |
415 | absolute expiration time. */ | 581 | rd_count, |
416 | rd_public_count = 0; | 582 | rd_public); |
417 | now = GNUNET_TIME_absolute_get (); | ||
418 | for (i=0;i<rd_count;i++) | ||
419 | if (0 == (rd[i].flags & (GNUNET_GNSRECORD_RF_PRIVATE | | ||
420 | GNUNET_GNSRECORD_RF_PENDING))) | ||
421 | { | ||
422 | rd_public[rd_public_count] = rd[i]; | ||
423 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) | ||
424 | { | ||
425 | /* GNUNET_GNSRECORD_block_create will convert to absolute time; | ||
426 | we just need to adjust our iteration frequency */ | ||
427 | min_relative_record_time.rel_value_us = | ||
428 | GNUNET_MIN (rd_public[rd_public_count].expiration_time, | ||
429 | min_relative_record_time.rel_value_us); | ||
430 | } | ||
431 | else if (rd_public[rd_public_count].expiration_time < now.abs_value_us) | ||
432 | { | ||
433 | /* record already expired, skip it */ | ||
434 | continue; | ||
435 | } | ||
436 | rd_public_count++; | ||
437 | } | ||
438 | 583 | ||
439 | /* We got a set of records to publish */ | 584 | /* We got a set of records to publish */ |
440 | if (0 == rd_public_count) | 585 | if (0 == rd_public_count) |
@@ -443,38 +588,17 @@ put_gns_record (void *cls, | |||
443 | NULL); | 588 | NULL); |
444 | return; | 589 | return; |
445 | } | 590 | } |
446 | expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_public_count, | 591 | |
447 | rd_public); | 592 | active_put = perform_dht_put (key, |
448 | block = GNUNET_GNSRECORD_block_create (key, | 593 | name, |
449 | expire, | 594 | rd_public, |
450 | name, | 595 | rd_public_count, |
451 | rd_public, | 596 | NULL); |
452 | rd_public_count); | ||
453 | block_size = ntohl (block->purpose.size) | ||
454 | + sizeof (struct GNUNET_CRYPTO_EcdsaSignature) | ||
455 | + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); | ||
456 | GNUNET_GNSRECORD_query_from_private_key (key, | ||
457 | name, | ||
458 | &query); | ||
459 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
460 | "Storing record in DHT with expiration `%s'\n", | ||
461 | GNUNET_STRINGS_absolute_time_to_string (expire)); | ||
462 | active_put = GNUNET_DHT_put (dht_handle, &query, | ||
463 | DHT_GNS_REPLICATION_LEVEL, | ||
464 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, | ||
465 | GNUNET_BLOCK_TYPE_GNS_NAMERECORD, | ||
466 | block_size, | ||
467 | block, | ||
468 | expire, | ||
469 | DHT_OPERATION_TIMEOUT, | ||
470 | &dht_put_continuation, | ||
471 | NULL); | ||
472 | if (NULL == active_put) | 597 | if (NULL == active_put) |
473 | { | 598 | { |
474 | GNUNET_break (0); | 599 | GNUNET_break (0); |
475 | dht_put_continuation (NULL, GNUNET_NO); | 600 | dht_put_continuation (NULL, GNUNET_NO); |
476 | } | 601 | } |
477 | GNUNET_free (block); | ||
478 | } | 602 | } |
479 | 603 | ||
480 | 604 | ||
@@ -501,6 +625,52 @@ publish_zone_dht_start (void *cls, | |||
501 | } | 625 | } |
502 | 626 | ||
503 | 627 | ||
628 | /** | ||
629 | * Process a record that was stored in the namestore | ||
630 | * (invoked by the monitor). | ||
631 | * | ||
632 | * @param cls closure, NULL | ||
633 | * @param zone private key of the zone; NULL on disconnect | ||
634 | * @param label label of the records; NULL on disconnect | ||
635 | * @param rd_count number of entries in @a rd array, 0 if label was deleted | ||
636 | * @param rd array of records with data to store | ||
637 | */ | ||
638 | static void | ||
639 | handle_monitor_event (void *cls, | ||
640 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | ||
641 | const char *label, | ||
642 | unsigned int rd_count, | ||
643 | const struct GNUNET_GNSRECORD_Data *rd) | ||
644 | { | ||
645 | struct GNUNET_GNSRECORD_Data rd_public[rd_count]; | ||
646 | unsigned int rd_public_count; | ||
647 | struct MonitorActivity *ma; | ||
648 | |||
649 | if (GNUNET_YES != sync_finished) | ||
650 | return; /* do not do DHT PUTs on initial sync, as that may | ||
651 | create far too many PUTs on startup */ | ||
652 | /* filter out records that are not public, and convert to | ||
653 | absolute expiration time. */ | ||
654 | rd_public_count = convert_records_for_export (rd, rd_count, | ||
655 | rd_public); | ||
656 | if (0 == rd_public_count) | ||
657 | return; /* nothing to do */ | ||
658 | ma = GNUNET_new (struct MonitorActivity); | ||
659 | ma->ph = perform_dht_put (zone, label, | ||
660 | rd, rd_count, | ||
661 | ma); | ||
662 | if (NULL == ma->ph) | ||
663 | { | ||
664 | /* PUT failed, do not remember operation */ | ||
665 | GNUNET_free (ma); | ||
666 | return; | ||
667 | } | ||
668 | GNUNET_CONTAINER_DLL_insert (ma_head, | ||
669 | ma_tail, | ||
670 | ma); | ||
671 | } | ||
672 | |||
673 | |||
504 | /* END DHT ZONE PROPAGATION */ | 674 | /* END DHT ZONE PROPAGATION */ |
505 | 675 | ||
506 | 676 | ||
@@ -655,6 +825,21 @@ notify_client_disconnect (void *cls, | |||
655 | 825 | ||
656 | 826 | ||
657 | /** | 827 | /** |
828 | * The zone monitor is now in SYNC with the current state of the | ||
829 | * name store. Start to perform periodic iterations. | ||
830 | * | ||
831 | * @param cls NULL | ||
832 | */ | ||
833 | static void | ||
834 | monitor_sync_event (void *cls) | ||
835 | { | ||
836 | sync_finished = GNUNET_YES; | ||
837 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start, | ||
838 | NULL); | ||
839 | } | ||
840 | |||
841 | |||
842 | /** | ||
658 | * Process GNS requests. | 843 | * Process GNS requests. |
659 | * | 844 | * |
660 | * @param cls closure | 845 | * @param cls closure |
@@ -732,8 +917,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
732 | { | 917 | { |
733 | if (GNUNET_OK != | 918 | if (GNUNET_OK != |
734 | GNUNET_CRYPTO_ecdsa_public_key_from_string (dns_root_name, | 919 | GNUNET_CRYPTO_ecdsa_public_key_from_string (dns_root_name, |
735 | strlen (dns_root_name), | 920 | strlen (dns_root_name), |
736 | &dns_root)) | 921 | &dns_root)) |
737 | { | 922 | { |
738 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, | 923 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, |
739 | "gns", "DNS_ROOT", | 924 | "gns", "DNS_ROOT", |
@@ -768,8 +953,11 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
768 | GNUNET_SERVER_add_handlers (server, handlers); | 953 | GNUNET_SERVER_add_handlers (server, handlers); |
769 | statistics = GNUNET_STATISTICS_create ("gns", c); | 954 | statistics = GNUNET_STATISTICS_create ("gns", c); |
770 | nc = GNUNET_SERVER_notification_context_create (server, 1); | 955 | nc = GNUNET_SERVER_notification_context_create (server, 1); |
771 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start, | 956 | zmon = GNUNET_NAMESTORE_zone_monitor_start (c, |
772 | NULL); | 957 | NULL, |
958 | &handle_monitor_event, | ||
959 | &monitor_sync_event, | ||
960 | NULL); | ||
773 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | 961 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, |
774 | &shutdown_task, NULL); | 962 | &shutdown_task, NULL); |
775 | } | 963 | } |