aboutsummaryrefslogtreecommitdiff
path: root/src/zonemaster
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2023-10-19 11:33:18 +0200
committerMartin Schanzenbach <schanzen@gnunet.org>2023-10-19 11:33:18 +0200
commit7c7d819e8e03dadb91935d5ae91aa921cc7b86c7 (patch)
tree9327ae110e5e64c99901cd853d3d36e23f39aaee /src/zonemaster
parentdf59c19d712a4339f7c75c76942c1a4f86bf2e5b (diff)
downloadgnunet-7c7d819e8e03dadb91935d5ae91aa921cc7b86c7.tar.gz
gnunet-7c7d819e8e03dadb91935d5ae91aa921cc7b86c7.zip
BUILD: Move gns/zonemaster to service
Diffstat (limited to 'src/zonemaster')
-rw-r--r--src/zonemaster/.gitignore2
-rw-r--r--src/zonemaster/Makefile.am32
-rw-r--r--src/zonemaster/gnunet-service-zonemaster.c1469
-rw-r--r--src/zonemaster/meson.build30
-rw-r--r--src/zonemaster/zonemaster.conf.in27
5 files changed, 0 insertions, 1560 deletions
diff --git a/src/zonemaster/.gitignore b/src/zonemaster/.gitignore
deleted file mode 100644
index cde57fa0a..000000000
--- a/src/zonemaster/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
1gnunet-service-zonemaster
2gnunet-service-zonemaster-monitor
diff --git a/src/zonemaster/Makefile.am b/src/zonemaster/Makefile.am
deleted file mode 100644
index 5a96afa83..000000000
--- a/src/zonemaster/Makefile.am
+++ /dev/null
@@ -1,32 +0,0 @@
1# This Makefile.am is in the public domain
2AM_CPPFLAGS = -I$(top_srcdir)/src/include
3
4plugindir = $(libdir)/gnunet
5
6pkgcfgdir= $(pkgdatadir)/config.d/
7
8libexecdir= $(pkglibdir)/libexec/
9
10pkgcfg_DATA = \
11 zonemaster.conf
12
13if USE_COVERAGE
14 AM_CFLAGS = --coverage -O0
15 XLIBS = -lgcov
16endif
17
18libexec_PROGRAMS = \
19 gnunet-service-zonemaster
20
21gnunet_service_zonemaster_SOURCES = \
22 gnunet-service-zonemaster.c
23gnunet_service_zonemaster_LDADD = \
24 $(top_builddir)/src/service/dht/libgnunetdht.la \
25 $(top_builddir)/src/lib/gnsrecord/libgnunetgnsrecord.la \
26 $(top_builddir)/src/service/identity/libgnunetidentity.la \
27 $(top_builddir)/src/service/statistics/libgnunetstatistics.la \
28 $(top_builddir)/src/lib/util/libgnunetutil.la \
29 $(top_builddir)/src/service/namestore/libgnunetnamestore.la \
30 $(top_builddir)/src/service/namecache/libgnunetnamecache.la \
31 $(GN_LIBINTL) \
32 -lpthread
diff --git a/src/zonemaster/gnunet-service-zonemaster.c b/src/zonemaster/gnunet-service-zonemaster.c
deleted file mode 100644
index 7c763576d..000000000
--- a/src/zonemaster/gnunet-service-zonemaster.c
+++ /dev/null
@@ -1,1469 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012, 2013, 2014, 2017, 2018 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
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 <pthread.h>
28#include "gnunet_util_lib.h"
29#include "gnunet_dht_service.h"
30#include "gnunet_namestore_service.h"
31#include "gnunet_namecache_service.h"
32#include "gnunet_statistics_service.h"
33
34#define LOG_STRERROR_FILE(kind, syscall, \
35 filename) GNUNET_log_from_strerror_file (kind, "util", \
36 syscall, \
37 filename)
38
39
40/**
41 * How often should we (re)publish each record before
42 * it expires?
43 */
44#define PUBLISH_OPS_PER_EXPIRATION 4
45
46/**
47 * How often do we measure the delta between desired zone
48 * iteration speed and actual speed, and tell statistics
49 * service about it?
50 */
51#define DELTA_INTERVAL 100
52
53/**
54 * How many records do we fetch in one shot from the namestore?
55 */
56#define NS_BLOCK_SIZE 1000
57
58/**
59 * How many open jobs (and with it maximum amount of pending DHT operations) do we allow at most
60 */
61#define JOB_QUEUE_LIMIT 5000
62
63/**
64 * How many events may the namestore give us before it has to wait
65 * for us to keep up?
66 */
67#define NAMESTORE_MONITOR_QUEUE_LIMIT 5
68
69/**
70 * The initial interval in milliseconds btween puts in
71 * a zone iteration
72 */
73#define INITIAL_ZONE_ITERATION_INTERVAL GNUNET_TIME_UNIT_MILLISECONDS
74
75/**
76 * The upper bound for the zone iteration interval
77 * (per record).
78 */
79#define MAXIMUM_ZONE_ITERATION_INTERVAL GNUNET_TIME_relative_multiply ( \
80 GNUNET_TIME_UNIT_MINUTES, 15)
81
82/**
83 * The factor the current zone iteration interval is divided by for each
84 * additional new record
85 */
86#define LATE_ITERATION_SPEEDUP_FACTOR 2
87
88/**
89 * What replication level do we use for DHT PUT operations?
90 */
91#define DHT_GNS_REPLICATION_LEVEL 5
92
93/**
94 * Our workers
95 */
96static pthread_t * worker;
97
98/**
99 * Lock for the sign jobs queue.
100 */
101static pthread_mutex_t sign_jobs_lock;
102
103/**
104 * Lock for the DHT put jobs queue.
105 */
106static pthread_mutex_t sign_results_lock;
107
108/**
109 * Wait condition on new sign jobs
110 */
111static pthread_cond_t sign_jobs_cond;
112
113/**
114 * For threads to know we are shutting down
115 */
116static int in_shutdown = GNUNET_NO;
117
118/**
119 * Monitor halted?
120 */
121static int monitor_halted = GNUNET_NO;
122
123/**
124 * Our notification pipe
125 */
126static struct GNUNET_DISK_PipeHandle *notification_pipe;
127
128/**
129 * Pipe read task
130 */
131static struct GNUNET_SCHEDULER_Task *pipe_read_task;
132
133struct RecordPublicationJob
134{
135
136 /**
137 * DLL
138 */
139 struct RecordPublicationJob *next;
140
141 /**
142 * DLL
143 */
144 struct RecordPublicationJob *prev;
145
146 /**
147 * The zone key to sign the block with
148 */
149 struct GNUNET_CRYPTO_PrivateKey zone;
150
151 /**
152 * The block to sign
153 */
154 struct GNUNET_GNSRECORD_Block *block;
155
156 /**
157 * The private block to sign, may point to block in case
158 * the public and private blocks are the same.
159 */
160 struct GNUNET_GNSRECORD_Block *block_priv;
161
162 /**
163 * The size of the public block for the DHT put.
164 */
165 size_t block_size;
166
167 /**
168 * The expiration time of the public block for the DHT put.
169 */
170 struct GNUNET_TIME_Absolute expire_pub;
171
172 /**
173 * The label of the block needed for signing
174 */
175 char *label;
176
177 /**
178 * Handle for the DHT PUT operation.
179 */
180 struct GNUNET_DHT_PutHandle *ph;
181
182 /**
183 * When was this PUT initiated?
184 */
185 struct GNUNET_TIME_Absolute start_date;
186};
187
188
189/**
190 * The DLL for workers to retrieve open jobs that require
191 * signing of blocks.
192 */
193static struct RecordPublicationJob *sign_jobs_head;
194
195/**
196 * See above
197 */
198static struct RecordPublicationJob *sign_jobs_tail;
199
200/**
201 * The DLL for workers to place jobs that are signed.
202 */
203static struct RecordPublicationJob *sign_results_head;
204
205/**
206 * See above
207 */
208static struct RecordPublicationJob *sign_results_tail;
209
210
211/**
212 * The DLL for jobs currently in the process of being dispatched into the DHT.
213 */
214static struct RecordPublicationJob *dht_jobs_head;
215
216/**
217 * See above
218 */
219static struct RecordPublicationJob *dht_jobs_tail;
220
221
222/**
223 * Pending operation on the namecache.
224 */
225struct CacheOperation
226{
227 /**
228 * Kept in a DLL.
229 */
230 struct CacheOperation *prev;
231
232 /**
233 * Kept in a DLL.
234 */
235 struct CacheOperation *next;
236
237 /**
238 * Handle to namecache queue.
239 */
240 struct GNUNET_NAMECACHE_QueueEntry *qe;
241
242};
243
244
245/**
246 * Handle to the statistics service
247 */
248static struct GNUNET_STATISTICS_Handle *statistics;
249
250/**
251 * Our handle to the DHT
252 */
253static struct GNUNET_DHT_Handle *dht_handle;
254
255/**
256 * Our handle to the namestore service
257 */
258static struct GNUNET_NAMESTORE_Handle *namestore_handle;
259
260/**
261 * Handle to monitor namestore changes to instant propagation.
262 */
263static struct GNUNET_NAMESTORE_ZoneMonitor *zmon;
264
265/**
266 * Our handle to the namecache service
267 */
268static struct GNUNET_NAMECACHE_Handle *namecache;
269
270/**
271 * Use the namecache? Doing so creates additional cryptographic
272 * operations whenever we touch a record.
273 */
274static int disable_namecache;
275
276/**
277 * Handle to iterate over our authoritative zone in namestore
278 */
279static struct GNUNET_NAMESTORE_ZoneIterator *namestore_iter;
280
281/**
282 * Number of entries in the job queue #jobs_head.
283 */
284static unsigned int job_queue_length;
285
286/**
287 * Useful for zone update for DHT put
288 */
289static unsigned long long num_public_records;
290
291/**
292 * Last seen record count
293 */
294static unsigned long long last_num_public_records;
295
296/**
297 * Number of successful put operations performed in the current
298 * measurement cycle (as measured in #check_zone_namestore_next()).
299 */
300static unsigned long long put_cnt;
301
302/**
303 * What is the frequency at which we currently would like
304 * to perform DHT puts (per record)? Calculated in
305 * update_velocity() from the #zone_publish_time_window()
306 * and the total number of record sets we have (so far)
307 * observed in the zone.
308 */
309static struct GNUNET_TIME_Relative target_iteration_velocity_per_record;
310
311/**
312 * Minimum relative expiration time of records seem during the current
313 * zone iteration.
314 */
315static struct GNUNET_TIME_Relative min_relative_record_time;
316
317/**
318 * Minimum relative expiration time of records seem during the last
319 * zone iteration.
320 */
321static struct GNUNET_TIME_Relative last_min_relative_record_time;
322
323/**
324 * Default time window for zone iteration
325 */
326static struct GNUNET_TIME_Relative zone_publish_time_window_default;
327
328/**
329 * Time window for zone iteration, adjusted based on relative record
330 * expiration times in our zone.
331 */
332static struct GNUNET_TIME_Relative zone_publish_time_window;
333
334/**
335 * When did we last start measuring the #DELTA_INTERVAL successful
336 * DHT puts? Used for velocity calculations.
337 */
338static struct GNUNET_TIME_Absolute last_put_100;
339
340/**
341 * By how much should we try to increase our per-record iteration speed
342 * (over the desired speed calculated directly from the #put_interval)?
343 * Basically this value corresponds to the per-record CPU time overhead
344 * we have.
345 */
346static struct GNUNET_TIME_Relative sub_delta;
347
348/**
349 * zone publish task
350 */
351static struct GNUNET_SCHEDULER_Task *zone_publish_task;
352
353/**
354 * How many more values are left for the current query before we need
355 * to explicitly ask the namestore for more?
356 */
357static unsigned int ns_iteration_left;
358
359/**
360 * #GNUNET_YES if zone has never been published before
361 */
362static int first_zone_iteration;
363
364/**
365 * Optimize block insertion by caching map of private keys to
366 * public keys in memory?
367 */
368static int cache_keys;
369
370/**
371 * Head of cop DLL.
372 */
373static struct CacheOperation *cop_head;
374
375/**
376 * Tail of cop DLL.
377 */
378static struct CacheOperation *cop_tail;
379
380
381static void
382free_job (struct RecordPublicationJob *job)
383{
384 if (job->block != job->block_priv)
385 GNUNET_free (job->block_priv);
386 GNUNET_free (job->block);
387 if (NULL != job->label)
388 GNUNET_free (job->label);
389 GNUNET_free (job);
390}
391
392/**
393 * Task run during shutdown.
394 *
395 * @param cls unused
396 * @param tc unused
397 */
398static void
399shutdown_task (void *cls)
400{
401 struct CacheOperation *cop;
402 struct RecordPublicationJob *job;
403
404 (void) cls;
405 in_shutdown = GNUNET_YES;
406 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
407 "Shutting down!\n");
408 if (NULL != notification_pipe)
409 GNUNET_DISK_pipe_close (notification_pipe);
410 if (NULL != pipe_read_task)
411 GNUNET_SCHEDULER_cancel (pipe_read_task);
412 while (NULL != (cop = cop_head))
413 {
414 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
415 "Aborting incomplete namecache operation\n");
416 GNUNET_NAMECACHE_cancel (cop->qe);
417 GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop);
418 GNUNET_free (cop);
419 }
420 GNUNET_assert (0 == pthread_mutex_lock (&sign_jobs_lock));
421 while (NULL != (job = sign_jobs_head))
422 {
423 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
424 "Removing incomplete jobs\n");
425 GNUNET_CONTAINER_DLL_remove (sign_jobs_head, sign_jobs_tail, job);
426 job_queue_length--;
427 free_job (job);
428 }
429 GNUNET_assert (0 == pthread_mutex_unlock (&sign_jobs_lock));
430 GNUNET_assert (0 == pthread_mutex_lock (&sign_results_lock));
431 while (NULL != (job = sign_results_head))
432 {
433 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
434 "Removing incomplete jobs\n");
435 GNUNET_CONTAINER_DLL_remove (sign_results_head, sign_results_tail, job);
436 free_job (job);
437 }
438 GNUNET_assert (0 == pthread_mutex_unlock (&sign_results_lock));
439 while (NULL != (job = dht_jobs_head))
440 {
441 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
442 "Removing incomplete jobs\n");
443 GNUNET_CONTAINER_DLL_remove (dht_jobs_head, dht_jobs_tail, job);
444 if (NULL != job->ph)
445 GNUNET_DHT_put_cancel (job->ph);
446 free_job (job);
447 }
448 if (NULL != statistics)
449 {
450 GNUNET_STATISTICS_destroy (statistics,
451 GNUNET_NO);
452 statistics = NULL;
453 }
454 if (NULL != zone_publish_task)
455 {
456 GNUNET_SCHEDULER_cancel (zone_publish_task);
457 zone_publish_task = NULL;
458 }
459 if (NULL != namestore_iter)
460 {
461 GNUNET_NAMESTORE_zone_iteration_stop (namestore_iter);
462 namestore_iter = NULL;
463 }
464 if (NULL != zmon)
465 {
466 GNUNET_NAMESTORE_zone_monitor_stop (zmon);
467 zmon = NULL;
468 }
469 if (NULL != namestore_handle)
470 {
471 GNUNET_NAMESTORE_disconnect (namestore_handle);
472 namestore_handle = NULL;
473 }
474 if (NULL != namecache)
475 {
476 GNUNET_NAMECACHE_disconnect (namecache);
477 namecache = NULL;
478 }
479 if (NULL != dht_handle)
480 {
481 GNUNET_DHT_disconnect (dht_handle);
482 dht_handle = NULL;
483 }
484}
485
486
487/**
488 * Cache operation complete, clean up.
489 *
490 * @param cls the `struct CacheOperation`
491 * @param success success
492 * @param emsg error messages
493 */
494static void
495finish_cache_operation (void *cls, int32_t success, const char *emsg)
496{
497 struct CacheOperation *cop = cls;
498
499 if (NULL != emsg)
500 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
501 _ ("Failed to replicate block in namecache: %s\n"),
502 emsg);
503 else
504 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n");
505 GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop);
506 GNUNET_free (cop);
507}
508
509
510/**
511 * Refresh the (encrypted) block in the namecache.
512 *
513 * @param zone_key private key of the zone
514 * @param name label for the records
515 * @param rd_count number of records
516 * @param rd records stored under the given @a name
517 */
518static void
519refresh_block (const struct GNUNET_GNSRECORD_Block *block)
520{
521 struct CacheOperation *cop;
522
523 if (GNUNET_YES == disable_namecache)
524 {
525 GNUNET_STATISTICS_update (statistics,
526 "Namecache updates skipped (NC disabled)",
527 1,
528 GNUNET_NO);
529 return;
530 }
531 GNUNET_assert (NULL != block);
532 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Caching block in namecache\n");
533 GNUNET_STATISTICS_update (statistics,
534 "Namecache updates pushed",
535 1,
536 GNUNET_NO);
537 cop = GNUNET_new (struct CacheOperation);
538 GNUNET_CONTAINER_DLL_insert (cop_head, cop_tail, cop);
539 cop->qe = GNUNET_NAMECACHE_block_cache (namecache,
540 block,
541 &finish_cache_operation,
542 cop);
543}
544
545
546/**
547 * Method called periodically that triggers iteration over authoritative records
548 *
549 * @param cls NULL
550 */
551static void
552publish_zone_namestore_next (void *cls)
553{
554 (void) cls;
555 zone_publish_task = NULL;
556 GNUNET_assert (NULL != namestore_iter);
557 GNUNET_assert (0 == ns_iteration_left);
558 ns_iteration_left = NS_BLOCK_SIZE;
559 GNUNET_NAMESTORE_zone_iterator_next (namestore_iter,
560 NS_BLOCK_SIZE);
561}
562
563
564/**
565 * Periodically iterate over our zone and store everything in dht
566 *
567 * @param cls NULL
568 */
569static void
570publish_zone_dht_start (void *cls);
571
572
573/**
574 * Calculate #target_iteration_velocity_per_record.
575 */
576static void
577calculate_put_interval ()
578{
579 if (0 == num_public_records)
580 {
581 /**
582 * If no records are known (startup) or none present
583 * we can safely set the interval to the value for a single
584 * record
585 */target_iteration_velocity_per_record = zone_publish_time_window;
586 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
587 "No records in namestore database.\n");
588 }
589 else
590 {
591 last_min_relative_record_time
592 = GNUNET_TIME_relative_min (last_min_relative_record_time,
593 min_relative_record_time);
594 zone_publish_time_window
595 = GNUNET_TIME_relative_min (GNUNET_TIME_relative_divide (
596 last_min_relative_record_time,
597 PUBLISH_OPS_PER_EXPIRATION),
598 zone_publish_time_window_default);
599 target_iteration_velocity_per_record
600 = GNUNET_TIME_relative_divide (zone_publish_time_window,
601 last_num_public_records);
602 }
603 target_iteration_velocity_per_record
604 = GNUNET_TIME_relative_min (target_iteration_velocity_per_record,
605 MAXIMUM_ZONE_ITERATION_INTERVAL);
606 GNUNET_STATISTICS_set (statistics,
607 "Minimum relative record expiration (in μs)",
608 last_min_relative_record_time.rel_value_us,
609 GNUNET_NO);
610 GNUNET_STATISTICS_set (statistics,
611 "Zone publication time window (in μs)",
612 zone_publish_time_window.rel_value_us,
613 GNUNET_NO);
614 GNUNET_STATISTICS_set (statistics,
615 "Target zone iteration velocity (μs)",
616 target_iteration_velocity_per_record.rel_value_us,
617 GNUNET_NO);
618}
619
620
621/**
622 * Re-calculate our velocity and the desired velocity.
623 * We have succeeded in making #DELTA_INTERVAL puts, so
624 * now calculate the new desired delay between puts.
625 *
626 * @param cnt how many records were processed since the last call?
627 */
628static void
629update_velocity (unsigned int cnt)
630{
631 struct GNUNET_TIME_Relative delta;
632 unsigned long long pct = 0;
633
634 if (0 == cnt)
635 return;
636 /* How fast were we really? */
637 delta = GNUNET_TIME_absolute_get_duration (last_put_100);
638 delta.rel_value_us /= cnt;
639 last_put_100 = GNUNET_TIME_absolute_get ();
640
641 /* calculate expected frequency */
642 if ((num_public_records > last_num_public_records) &&
643 (GNUNET_NO == first_zone_iteration))
644 {
645 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
646 "Last record count was lower than current record count. Reducing interval.\n");
647 last_num_public_records = num_public_records
648 * LATE_ITERATION_SPEEDUP_FACTOR;
649 calculate_put_interval ();
650 }
651 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
652 "Desired global zone iteration interval is %s/record!\n",
653 GNUNET_STRINGS_relative_time_to_string (
654 target_iteration_velocity_per_record,
655 GNUNET_YES));
656
657 /* Tell statistics actual vs. desired speed */
658 GNUNET_STATISTICS_set (statistics,
659 "Current zone iteration velocity (μs/record)",
660 delta.rel_value_us,
661 GNUNET_NO);
662 /* update "sub_delta" based on difference, taking
663 previous sub_delta into account! */
664 if (target_iteration_velocity_per_record.rel_value_us > delta.rel_value_us)
665 {
666 /* We were too fast, reduce sub_delta! */
667 struct GNUNET_TIME_Relative corr;
668
669 corr = GNUNET_TIME_relative_subtract (target_iteration_velocity_per_record,
670 delta);
671 if (sub_delta.rel_value_us > delta.rel_value_us)
672 {
673 /* Reduce sub_delta by corr */
674 sub_delta = GNUNET_TIME_relative_subtract (sub_delta,
675 corr);
676 }
677 else
678 {
679 /* We're doing fine with waiting the full time, this
680 should theoretically only happen if we run at
681 infinite speed. */
682 sub_delta = GNUNET_TIME_UNIT_ZERO;
683 }
684 }
685 else if (target_iteration_velocity_per_record.rel_value_us <
686 delta.rel_value_us)
687 {
688 /* We were too slow, increase sub_delta! */
689 struct GNUNET_TIME_Relative corr;
690
691 corr = GNUNET_TIME_relative_subtract (delta,
692 target_iteration_velocity_per_record);
693 sub_delta = GNUNET_TIME_relative_add (sub_delta,
694 corr);
695 if (sub_delta.rel_value_us >
696 target_iteration_velocity_per_record.rel_value_us)
697 {
698 /* CPU overload detected, we cannot go at desired speed,
699 as this would mean using a negative delay. */
700 /* compute how much faster we would want to be for
701 the desired velocity */
702 if (0 == target_iteration_velocity_per_record.rel_value_us)
703 pct = UINT64_MAX; /* desired speed is infinity ... */
704 else
705 pct = (sub_delta.rel_value_us
706 - target_iteration_velocity_per_record.rel_value_us) * 100LLU
707 / target_iteration_velocity_per_record.rel_value_us;
708 sub_delta = target_iteration_velocity_per_record;
709 }
710 }
711 GNUNET_STATISTICS_set (statistics,
712 "# dispatched jobs",
713 job_queue_length,
714 GNUNET_NO);
715 GNUNET_STATISTICS_set (statistics,
716 "% speed increase needed for target velocity",
717 pct,
718 GNUNET_NO);
719 GNUNET_STATISTICS_set (statistics,
720 "# records processed in current iteration",
721 num_public_records,
722 GNUNET_NO);
723}
724
725
726/**
727 * Check if the current zone iteration needs to be continued
728 * by calling #publish_zone_namestore_next(), and if so with what delay.
729 */
730static void
731check_zone_namestore_next ()
732{
733 struct GNUNET_TIME_Relative delay;
734
735 if (0 != ns_iteration_left)
736 return; /* current NAMESTORE iteration not yet done */
737 if (job_queue_length >= JOB_QUEUE_LIMIT)
738 {
739 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
740 "Job queue length exceeded (%u/%u). Pausing namestore iteration.\n",
741 job_queue_length,
742 JOB_QUEUE_LIMIT);
743 return;
744 }
745 update_velocity (put_cnt);
746 put_cnt = 0;
747 delay = GNUNET_TIME_relative_subtract (target_iteration_velocity_per_record,
748 sub_delta);
749 /* We delay *once* per #NS_BLOCK_SIZE, so we need to multiply the
750 per-record delay calculated so far with the #NS_BLOCK_SIZE */
751 GNUNET_STATISTICS_set (statistics,
752 "Current artificial NAMESTORE delay (μs/record)",
753 delay.rel_value_us,
754 GNUNET_NO);
755 delay = GNUNET_TIME_relative_multiply (delay,
756 NS_BLOCK_SIZE);
757 /* make sure we do not overshoot because of the #NS_BLOCK_SIZE factor */
758 delay = GNUNET_TIME_relative_min (MAXIMUM_ZONE_ITERATION_INTERVAL,
759 delay);
760 /* no delays on first iteration */
761 if (GNUNET_YES == first_zone_iteration)
762 delay = GNUNET_TIME_UNIT_ZERO;
763 GNUNET_assert (NULL == zone_publish_task);
764 zone_publish_task = GNUNET_SCHEDULER_add_delayed (delay,
765 &publish_zone_namestore_next,
766 NULL);
767}
768
769
770/**
771 * Continuation called from DHT once the PUT operation is done.
772 *
773 */
774static void
775dht_put_continuation (void *cls)
776{
777 struct RecordPublicationJob *job = cls;
778
779 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
780 "PUT complete; Pending jobs: %u\n", job_queue_length - 1);
781 /* When we just fall under the limit, trigger monitor/iterator again
782 * if halted. We can only safely trigger one, prefer iterator. */
783 if (NULL == zone_publish_task)
784 check_zone_namestore_next ();
785 if (job_queue_length <= JOB_QUEUE_LIMIT)
786 {
787 if (GNUNET_YES == monitor_halted)
788 {
789 GNUNET_NAMESTORE_zone_monitor_next (zmon, 1);
790 monitor_halted = GNUNET_NO;
791 }
792 }
793 job_queue_length--;
794 GNUNET_CONTAINER_DLL_remove (dht_jobs_head,
795 dht_jobs_tail,
796 job);
797 free_job (job);
798}
799
800
801/**
802 * Store GNS records in the DHT.
803 *
804 * @param key key of the zone
805 * @param label label to store under
806 * @param rd_public public record data
807 * @param rd_public_count number of records in @a rd_public
808 * @param ma handle for the put operation
809 * @return DHT PUT handle, NULL on error
810 */
811static void
812dispatch_job (const struct GNUNET_CRYPTO_PrivateKey *key,
813 const char *label,
814 const struct GNUNET_GNSRECORD_Data *rd,
815 unsigned int rd_count,
816 const struct GNUNET_TIME_Absolute expire)
817{
818 struct GNUNET_GNSRECORD_Data rd_public[rd_count];
819 struct GNUNET_GNSRECORD_Block *block;
820 struct GNUNET_GNSRECORD_Block *block_priv;
821 struct GNUNET_TIME_Absolute expire_pub;
822 size_t block_size;
823 unsigned int rd_public_count = 0;
824 char *emsg;
825
826 if (GNUNET_OK !=
827 GNUNET_GNSRECORD_normalize_record_set (label,
828 rd,
829 rd_count,
830 rd_public,
831 &rd_public_count,
832 &expire_pub,
833 GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE,
834 &emsg))
835 {
836 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
837 "%s\n", emsg);
838 GNUNET_free (emsg);
839 }
840
841 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create_unsigned (key,
842 expire_pub,
843 label,
844 rd_public,
845 rd_public_count,
846 &block));
847 if (NULL == block)
848 {
849 GNUNET_break (0);
850 return; /* whoops */
851 }
852 if (rd_count != rd_public_count)
853 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create_unsigned (key,
854 expire,
855 label,
856 rd,
857 rd_count,
858 &
859 block_priv));
860 else
861 block_priv = block;
862 block_size = GNUNET_GNSRECORD_block_get_size (block);
863 GNUNET_assert (0 == pthread_mutex_lock (&sign_jobs_lock));
864 struct RecordPublicationJob *job = GNUNET_new (struct RecordPublicationJob);
865 job->block = block;
866 job->block_size = block_size;
867 job->block_priv = block_priv;
868 job->zone = *key;
869 job->label = GNUNET_strdup (label);
870 job->expire_pub = expire_pub;
871 GNUNET_CONTAINER_DLL_insert (sign_jobs_head, sign_jobs_tail, job);
872 GNUNET_assert (0 == pthread_cond_signal (&sign_jobs_cond));
873 GNUNET_assert (0 == pthread_mutex_unlock (&sign_jobs_lock));
874 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
875 "Creating job with %u record(s) for label `%s', expiration `%s'\n",
876 rd_public_count,
877 label,
878 GNUNET_STRINGS_absolute_time_to_string (expire));
879 num_public_records++;
880 return;
881}
882
883
884static void
885notification_pipe_cb (void *cls);
886
887static void
888initiate_put_from_pipe_trigger (void *cls)
889{
890 struct GNUNET_HashCode query;
891 struct RecordPublicationJob *job;
892 const struct GNUNET_DISK_FileHandle *np_fh;
893 char buf[100];
894 ssize_t nf_count;
895
896 pipe_read_task = NULL;
897 np_fh = GNUNET_DISK_pipe_handle (notification_pipe,
898 GNUNET_DISK_PIPE_END_READ);
899 pipe_read_task =
900 GNUNET_SCHEDULER_add_read_file (
901 GNUNET_TIME_UNIT_FOREVER_REL,
902 np_fh,
903 notification_pipe_cb,
904 NULL);
905 /* empty queue */
906 nf_count = GNUNET_DISK_file_read (np_fh, buf, sizeof (buf));
907 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Read %lld notifications from pipe\n",
908 (long long) nf_count);
909 while (true)
910 {
911 GNUNET_assert (0 == pthread_mutex_lock (&sign_results_lock));
912 if (NULL == sign_results_head)
913 {
914 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
915 "No more results. Back to sleep.\n");
916 GNUNET_assert (0 == pthread_mutex_unlock (&sign_results_lock));
917 return;
918 }
919 job = sign_results_head;
920 GNUNET_CONTAINER_DLL_remove (sign_results_head, sign_results_tail, job);
921 GNUNET_assert (0 == pthread_mutex_unlock (&sign_results_lock));
922 GNUNET_GNSRECORD_query_from_private_key (&job->zone,
923 job->label,
924 &query);
925 job->ph = GNUNET_DHT_put (dht_handle,
926 &query,
927 DHT_GNS_REPLICATION_LEVEL,
928 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
929 GNUNET_BLOCK_TYPE_GNS_NAMERECORD,
930 job->block_size,
931 job->block,
932 job->expire_pub,
933 &dht_put_continuation,
934 job);
935 if (NULL == job->ph)
936 {
937 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
938 "Could not perform DHT PUT, is the DHT running?\n");
939 free_job (job);
940 return;
941 }
942 GNUNET_STATISTICS_update (statistics,
943 "DHT put operations initiated",
944 1,
945 GNUNET_NO);
946 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
947 "Storing record(s) for label `%s' in DHT under key %s\n",
948 job->label,
949 GNUNET_h2s (&query));
950 refresh_block (job->block_priv);
951 GNUNET_CONTAINER_DLL_insert (dht_jobs_head, dht_jobs_tail, job);
952 }
953}
954
955
956/**
957 * We encountered an error in our zone iteration.
958 *
959 * @param cls NULL
960 */
961static void
962zone_iteration_error (void *cls)
963{
964 (void) cls;
965 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
966 "Got disconnected from namestore database, retrying.\n");
967 namestore_iter = NULL;
968 /* We end up here on error/disconnect/shutdown, so potentially
969 while a zone publish task or a DHT put is still running; hence
970 we need to cancel those. */
971 if (NULL != zone_publish_task)
972 {
973 GNUNET_SCHEDULER_cancel (zone_publish_task);
974 zone_publish_task = NULL;
975 }
976 zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start,
977 NULL);
978}
979
980
981/**
982 * Zone iteration is completed.
983 *
984 * @param cls NULL
985 */
986static void
987zone_iteration_finished (void *cls)
988{
989 (void) cls;
990 /* we're done with one iteration, calculate when to do the next one */
991 namestore_iter = NULL;
992 last_num_public_records = num_public_records;
993 first_zone_iteration = GNUNET_NO;
994 last_min_relative_record_time = min_relative_record_time;
995 calculate_put_interval ();
996 /* reset for next iteration */
997 min_relative_record_time
998 = GNUNET_TIME_UNIT_FOREVER_REL;
999 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1000 "Zone iteration finished. Adjusted zone iteration interval to %s\n",
1001 GNUNET_STRINGS_relative_time_to_string (
1002 target_iteration_velocity_per_record,
1003 GNUNET_YES));
1004 GNUNET_STATISTICS_set (statistics,
1005 "Target zone iteration velocity (μs)",
1006 target_iteration_velocity_per_record.rel_value_us,
1007 GNUNET_NO);
1008 GNUNET_STATISTICS_set (statistics,
1009 "Number of public records in DHT",
1010 last_num_public_records,
1011 GNUNET_NO);
1012 GNUNET_assert (NULL == zone_publish_task);
1013 if (0 == last_num_public_records)
1014 {
1015 zone_publish_task = GNUNET_SCHEDULER_add_delayed (
1016 target_iteration_velocity_per_record,
1017 &publish_zone_dht_start,
1018 NULL);
1019 }
1020 else
1021 {
1022 zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start,
1023 NULL);
1024 }
1025}
1026
1027
1028/**
1029 * Function used to put all records successively into the DHT.
1030 *
1031 * @param cls the closure (NULL)
1032 * @param key the private key of the authority (ours)
1033 * @param label the name of the records, NULL once the iteration is done
1034 * @param rd_count the number of records in @a rd
1035 * @param rd the record data
1036 */
1037static void
1038handle_record (void *cls,
1039 const struct GNUNET_CRYPTO_PrivateKey *key,
1040 const char *label,
1041 unsigned int rd_count,
1042 const struct GNUNET_GNSRECORD_Data *rd,
1043 struct GNUNET_TIME_Absolute expire)
1044{
1045 (void) cls;
1046 ns_iteration_left--;
1047 if (0 == rd_count)
1048 {
1049 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1050 "Record set empty, moving to next record set\n");
1051 check_zone_namestore_next ();
1052 return;
1053 }
1054 for (unsigned int i = 0; i < rd_count; i++)
1055 {
1056 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
1057 {
1058 /* GNUNET_GNSRECORD_block_create will convert to absolute time;
1059 we just need to adjust our iteration frequency */
1060 min_relative_record_time.rel_value_us =
1061 GNUNET_MIN (rd[i].expiration_time,
1062 min_relative_record_time.rel_value_us);
1063 }
1064 }
1065
1066
1067 /* We got a set of records to publish */
1068 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1069 "Starting DHT PUT\n");
1070 put_cnt++;
1071 if (0 == put_cnt % DELTA_INTERVAL)
1072 update_velocity (DELTA_INTERVAL);
1073 dispatch_job (key,
1074 label,
1075 rd,
1076 rd_count,
1077 expire);
1078 job_queue_length++;
1079 check_zone_namestore_next ();
1080}
1081
1082
1083/**
1084 * Periodically iterate over all zones and store everything in DHT
1085 *
1086 * @param cls NULL
1087 */
1088static void
1089publish_zone_dht_start (void *cls)
1090{
1091 (void) cls;
1092 zone_publish_task = NULL;
1093 GNUNET_STATISTICS_update (statistics,
1094 "Full zone iterations launched",
1095 1,
1096 GNUNET_NO);
1097 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1098 "Starting DHT zone update!\n");
1099 /* start counting again */
1100 num_public_records = 0;
1101 GNUNET_assert (NULL == namestore_iter);
1102 ns_iteration_left = 1;
1103 namestore_iter
1104 = GNUNET_NAMESTORE_zone_iteration_start2 (namestore_handle,
1105 NULL, /* All zones */
1106 &zone_iteration_error,
1107 NULL,
1108 &handle_record,
1109 NULL,
1110 &zone_iteration_finished,
1111 NULL,
1112 GNUNET_GNSRECORD_FILTER_NONE);
1113 GNUNET_assert (NULL != namestore_iter);
1114}
1115
1116
1117/**
1118 * Store GNS records in the DHT.
1119 *
1120 * @param key key of the zone
1121 * @param label label to store under
1122 * @param rd_public public record data
1123 * @param rd_public_count number of records in @a rd_public
1124 */
1125static void
1126dispatch_job_monitor (const struct GNUNET_CRYPTO_PrivateKey *key,
1127 const char *label,
1128 const struct GNUNET_GNSRECORD_Data *rd,
1129 unsigned int rd_count,
1130 struct GNUNET_TIME_Absolute expire)
1131{
1132 struct GNUNET_GNSRECORD_Data rd_public[rd_count];
1133 struct GNUNET_GNSRECORD_Block *block;
1134 struct GNUNET_GNSRECORD_Block *block_priv;
1135 struct GNUNET_TIME_Absolute expire_pub;
1136 size_t block_size;
1137 unsigned int rd_public_count = 0;
1138 char *emsg;
1139
1140 if (GNUNET_OK !=
1141 GNUNET_GNSRECORD_normalize_record_set (label,
1142 rd,
1143 rd_count,
1144 rd_public,
1145 &rd_public_count,
1146 &expire_pub,
1147 GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE,
1148 &emsg))
1149 {
1150 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1151 "%s\n", emsg);
1152 GNUNET_free (emsg);
1153 }
1154
1155 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create_unsigned (key,
1156 expire_pub,
1157 label,
1158 rd_public,
1159 rd_public_count,
1160 &block));
1161 if (NULL == block)
1162 {
1163 GNUNET_break (0);
1164 return; /* whoops */
1165 }
1166 if (rd_count != rd_public_count)
1167 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create_unsigned (key,
1168 expire,
1169 label,
1170 rd,
1171 rd_count,
1172 &
1173 block_priv));
1174 else
1175 block_priv = block;
1176 block_size = GNUNET_GNSRECORD_block_get_size (block);
1177 GNUNET_assert (0 == pthread_mutex_lock (&sign_jobs_lock));
1178 struct RecordPublicationJob *job = GNUNET_new (struct RecordPublicationJob);
1179 job->block = block;
1180 job->block_size = block_size;
1181 job->block_priv = block_priv;
1182 job->zone = *key;
1183 job->label = GNUNET_strdup (label);
1184 job->expire_pub = expire_pub;
1185 GNUNET_CONTAINER_DLL_insert (sign_jobs_head, sign_jobs_tail, job);
1186 GNUNET_assert (0 == pthread_cond_signal (&sign_jobs_cond));
1187 GNUNET_assert (0 == pthread_mutex_unlock (&sign_jobs_lock));
1188}
1189
1190
1191/**
1192 * Process a record that was stored in the namestore
1193 * (invoked by the monitor).
1194 *
1195 * @param cls closure, NULL
1196 * @param zone private key of the zone; NULL on disconnect
1197 * @param label label of the records; NULL on disconnect
1198 * @param rd_count number of entries in @a rd array, 0 if label was deleted
1199 * @param rd array of records with data to store
1200 * @param expire expiration of this record set
1201 */
1202static void
1203handle_monitor_event (void *cls,
1204 const struct GNUNET_CRYPTO_PrivateKey *zone,
1205 const char *label,
1206 unsigned int rd_count,
1207 const struct GNUNET_GNSRECORD_Data *rd,
1208 struct GNUNET_TIME_Absolute expire)
1209{
1210 (void) cls;
1211 GNUNET_STATISTICS_update (statistics,
1212 "Namestore monitor events received",
1213 1,
1214 GNUNET_NO);
1215 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1216 "Received %u records for label `%s' via namestore monitor\n",
1217 rd_count,
1218 label);
1219 if (0 == rd_count)
1220 {
1221 GNUNET_NAMESTORE_zone_monitor_next (zmon,
1222 1);
1223 return; /* nothing to do */
1224 }
1225 dispatch_job_monitor (zone,
1226 label,
1227 rd,
1228 rd_count,
1229 expire);
1230 job_queue_length++;
1231 if (job_queue_length >= JOB_QUEUE_LIMIT)
1232 {
1233 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1234 "Job queue length exceeded (%u/%u). Halting monitor.\n",
1235 job_queue_length,
1236 JOB_QUEUE_LIMIT);
1237 monitor_halted = GNUNET_YES;
1238 return;
1239 }
1240 GNUNET_NAMESTORE_zone_monitor_next (zmon,
1241 1);
1242}
1243
1244
1245/**
1246 * The zone monitor encountered an IPC error trying to to get in
1247 * sync. Restart from the beginning.
1248 *
1249 * @param cls NULL
1250 */
1251static void
1252handle_monitor_error (void *cls)
1253{
1254 (void) cls;
1255 GNUNET_STATISTICS_update (statistics,
1256 "Namestore monitor errors encountered",
1257 1,
1258 GNUNET_NO);
1259}
1260
1261
1262static void*
1263sign_worker (void *cls)
1264{
1265 struct RecordPublicationJob *job;
1266 const struct GNUNET_DISK_FileHandle *fh;
1267
1268 fh = GNUNET_DISK_pipe_handle (notification_pipe, GNUNET_DISK_PIPE_END_WRITE);
1269 while (GNUNET_YES != in_shutdown)
1270 {
1271 GNUNET_assert (0 == pthread_mutex_lock (&sign_jobs_lock));
1272 while (NULL == sign_jobs_head)
1273 GNUNET_assert (0 == pthread_cond_wait (&sign_jobs_cond, &sign_jobs_lock));
1274 if (GNUNET_YES == in_shutdown)
1275 {
1276 GNUNET_assert (0 == pthread_mutex_unlock (&sign_jobs_lock));
1277 return NULL;
1278 }
1279 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1280 "Taking on Job for %s\n", sign_jobs_head->label);
1281 job = sign_jobs_head;
1282 GNUNET_CONTAINER_DLL_remove (sign_jobs_head, sign_jobs_tail, job);
1283 GNUNET_assert (0 == pthread_mutex_unlock (&sign_jobs_lock));
1284 GNUNET_GNSRECORD_block_sign (&job->zone, job->label, job->block);
1285 if (job->block != job->block_priv)
1286 GNUNET_GNSRECORD_block_sign (&job->zone, job->label, job->block_priv);
1287 GNUNET_assert (0 == pthread_mutex_lock (&sign_results_lock));
1288 GNUNET_CONTAINER_DLL_insert (sign_results_head, sign_results_tail, job);
1289 GNUNET_assert (0 == pthread_mutex_unlock (&sign_results_lock));
1290 job = NULL;
1291 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1292 "Done, notifying main thread through pipe!\n");
1293 GNUNET_DISK_file_write (fh, "!", 1);
1294 }
1295 return NULL;
1296}
1297
1298
1299static void
1300notification_pipe_cb (void *cls)
1301{
1302 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1303 "Received wake up notification through pipe, checking results\n");
1304 GNUNET_SCHEDULER_add_now (&initiate_put_from_pipe_trigger, NULL);
1305}
1306
1307
1308/**
1309 * Perform zonemaster duties: watch namestore, publish records.
1310 *
1311 * @param cls closure
1312 * @param server the initialized server
1313 * @param c configuration to use
1314 */
1315static void
1316run (void *cls,
1317 const struct GNUNET_CONFIGURATION_Handle *c,
1318 struct GNUNET_SERVICE_Handle *service)
1319{
1320 unsigned long long max_parallel_bg_queries = 128;
1321
1322 (void) cls;
1323 (void) service;
1324 pthread_mutex_init (&sign_jobs_lock, NULL);
1325 pthread_mutex_init (&sign_results_lock, NULL);
1326 pthread_cond_init (&sign_jobs_cond, NULL);
1327 last_put_100 = GNUNET_TIME_absolute_get (); /* first time! */
1328 min_relative_record_time
1329 = GNUNET_TIME_UNIT_FOREVER_REL;
1330 target_iteration_velocity_per_record = INITIAL_ZONE_ITERATION_INTERVAL;
1331 namestore_handle = GNUNET_NAMESTORE_connect (c);
1332 if (NULL == namestore_handle)
1333 {
1334 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1335 _ ("Failed to connect to the namestore!\n"));
1336 GNUNET_SCHEDULER_shutdown ();
1337 return;
1338 }
1339 disable_namecache = GNUNET_CONFIGURATION_get_value_yesno (c,
1340 "namecache",
1341 "DISABLE");
1342 if (GNUNET_NO == disable_namecache)
1343 {
1344 namecache = GNUNET_NAMECACHE_connect (c);
1345 if (NULL == namecache)
1346 {
1347 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1348 _ ("Failed to connect to the namecache!\n"));
1349 GNUNET_SCHEDULER_shutdown ();
1350 return;
1351 }
1352 }
1353 cache_keys = GNUNET_CONFIGURATION_get_value_yesno (c,
1354 "namestore",
1355 "CACHE_KEYS");
1356 zone_publish_time_window_default = GNUNET_DHT_DEFAULT_REPUBLISH_FREQUENCY;
1357 if (GNUNET_OK ==
1358 GNUNET_CONFIGURATION_get_value_time (c,
1359 "zonemaster",
1360 "ZONE_PUBLISH_TIME_WINDOW",
1361 &zone_publish_time_window_default))
1362 {
1363 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1364 "Time window for zone iteration: %s\n",
1365 GNUNET_STRINGS_relative_time_to_string (
1366 zone_publish_time_window,
1367 GNUNET_YES));
1368 }
1369 zone_publish_time_window = zone_publish_time_window_default;
1370 if (GNUNET_OK ==
1371 GNUNET_CONFIGURATION_get_value_number (c,
1372 "zonemaster",
1373 "MAX_PARALLEL_BACKGROUND_QUERIES",
1374 &max_parallel_bg_queries))
1375 {
1376 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1377 "Number of allowed parallel background queries: %llu\n",
1378 max_parallel_bg_queries);
1379 }
1380 if (0 == max_parallel_bg_queries)
1381 max_parallel_bg_queries = 1;
1382 dht_handle = GNUNET_DHT_connect (c,
1383 (unsigned int) max_parallel_bg_queries);
1384 if (NULL == dht_handle)
1385 {
1386 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1387 _ ("Could not connect to DHT!\n"));
1388 GNUNET_SCHEDULER_add_now (&shutdown_task,
1389 NULL);
1390 return;
1391 }
1392
1393 /* Schedule periodic put for our records. */
1394 first_zone_iteration = GNUNET_YES;
1395 statistics = GNUNET_STATISTICS_create ("zonemaster",
1396 c);
1397 GNUNET_STATISTICS_set (statistics,
1398 "Target zone iteration velocity (μs)",
1399 target_iteration_velocity_per_record.rel_value_us,
1400 GNUNET_NO);
1401 zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start,
1402 NULL);
1403 zmon = GNUNET_NAMESTORE_zone_monitor_start2 (c,
1404 NULL,
1405 GNUNET_NO,
1406 &handle_monitor_error,
1407 NULL,
1408 &handle_monitor_event,
1409 NULL,
1410 NULL /* sync_cb */,
1411 NULL,
1412 GNUNET_GNSRECORD_FILTER_NONE);
1413 GNUNET_NAMESTORE_zone_monitor_next (zmon,
1414 NAMESTORE_MONITOR_QUEUE_LIMIT - 1);
1415 GNUNET_break (NULL != zmon);
1416
1417 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1418 NULL);
1419
1420 notification_pipe = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE);
1421 const struct GNUNET_DISK_FileHandle *np_fh = GNUNET_DISK_pipe_handle (
1422 notification_pipe,
1423 GNUNET_DISK_PIPE_END_READ);
1424 pipe_read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1425 np_fh,
1426 notification_pipe_cb, NULL);
1427
1428 long long unsigned int worker_count = 1;
1429 if (GNUNET_OK !=
1430 GNUNET_CONFIGURATION_get_value_number (c,
1431 "zonemaster",
1432 "WORKER_COUNT",
1433 &worker_count))
1434 {
1435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1436 "Number of workers not defined falling back to 1\n");
1437 }
1438 worker = GNUNET_malloc (sizeof (pthread_t) * worker_count);
1439 /** Start worker */
1440 for (int i = 0; i < worker_count; i++)
1441 {
1442 if (0 !=
1443 pthread_create (&worker[i],
1444 NULL,
1445 &sign_worker,
1446 NULL))
1447 {
1448 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1449 "pthread_create");
1450 GNUNET_SCHEDULER_shutdown ();
1451 }
1452 }
1453}
1454
1455
1456/**
1457 * Define "main" method using service macro.
1458 */
1459GNUNET_SERVICE_MAIN
1460 ("zonemaster",
1461 GNUNET_SERVICE_OPTION_NONE,
1462 &run,
1463 NULL,
1464 NULL,
1465 NULL,
1466 GNUNET_MQ_handler_end ());
1467
1468
1469/* end of gnunet-service-zonemaster.c */
diff --git a/src/zonemaster/meson.build b/src/zonemaster/meson.build
deleted file mode 100644
index 44c67edf2..000000000
--- a/src/zonemaster/meson.build
+++ /dev/null
@@ -1,30 +0,0 @@
1gnunetservicezonemaster_src = ['gnunet-service-zonemaster.c']
2
3configure_file(input : 'zonemaster.conf.in',
4 output : 'zonemaster.conf',
5 configuration : cdata,
6 install: true,
7 install_dir: pkgcfgdir)
8
9
10if get_option('monolith')
11 foreach p : gnunetservicezonemaster_src
12 gnunet_src += 'zonemaster/' + p
13 endforeach
14 subdir_done()
15endif
16
17executable ('gnunet-service-zonemaster',
18 gnunetservicezonemaster_src,
19 dependencies: [
20 libgnunetutil_dep,
21 libgnunetdht_dep,
22 libgnunetidentity_dep,
23 libgnunetstatistics_dep,
24 libgnunetnamecache_dep,
25 libgnunetnamestore_dep,
26 libgnunetgnsrecord_dep],
27 include_directories: [incdir, configuration_inc],
28 install: true,
29 install_dir: get_option('libdir')/'gnunet'/'libexec')
30
diff --git a/src/zonemaster/zonemaster.conf.in b/src/zonemaster/zonemaster.conf.in
deleted file mode 100644
index 549394d6c..000000000
--- a/src/zonemaster/zonemaster.conf.in
+++ /dev/null
@@ -1,27 +0,0 @@
1[zonemaster]
2START_ON_DEMAND = @START_ON_DEMAND@
3RUN_PER_USER = YES
4IMMEDIATE_START = YES
5HOSTNAME = localhost
6BINARY = gnunet-service-zonemaster
7UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-zonemaster.sock
8@JAVAPORT@PORT = 2123
9WORKER_COUNT = 4
10
11# Do we require users that want to access GNS to run this process
12# (usually not a good idea)
13UNIX_MATCH_UID = NO
14
15# Do we require users that want to access GNS to be in the 'gnunet' group?
16UNIX_MATCH_GID = NO
17
18# How many queries is GNS allowed to perform in the background at the same time?
19MAX_PARALLEL_BACKGROUND_QUERIES = 1000
20
21# How frequently do we try to publish our full zone?
22ZONE_PUBLISH_TIME_WINDOW = 4 h
23
24# Using caching or always ask DHT
25# USE_CACHE = YES
26
27# PREFIX = valgrind --leak-check=full --track-origins=yes