GNUnet 0.28.1-dev.5-1-gae1c02d74
 
Loading...
Searching...
No Matches
gnunet-service-zonemaster.c File Reference

publish records from namestore to GNUnet name system More...

#include "platform.h"
#include <pthread.h>
#include "gnunet_util_lib.h"
#include "gnunet_dht_service.h"
#include "gnunet_namestore_service.h"
#include "gnunet_namecache_service.h"
#include "gnunet_statistics_service.h"
Include dependency graph for gnunet-service-zonemaster.c:

Go to the source code of this file.

Data Structures

struct  RecordPublicationJob
 
struct  CacheOperation
 Pending operation on the namecache. More...
 

Macros

#define LOG_STRERROR_FILE(kind, syscall, filename)
 
#define PUBLISH_OPS_PER_EXPIRATION   4
 How often should we (re)publish each record before it expires?
 
#define DELTA_INTERVAL   100
 How often do we measure the delta between desired zone iteration speed and actual speed, and tell statistics service about it?
 
#define NS_BLOCK_SIZE   1000
 How many records do we fetch in one shot from the namestore?
 
#define JOB_QUEUE_LIMIT   5000
 How many open jobs (and with it maximum amount of pending DHT operations) do we allow at most.
 
#define NAMESTORE_MONITOR_QUEUE_LIMIT   5
 How many events may the namestore give us before it has to wait for us to keep up?
 
#define INITIAL_ZONE_ITERATION_INTERVAL   GNUNET_TIME_UNIT_MILLISECONDS
 The initial interval in milliseconds btween puts in a zone iteration.
 
#define MAXIMUM_ZONE_ITERATION_INTERVAL
 The upper bound for the zone iteration interval (per record).
 
#define LATE_ITERATION_SPEEDUP_FACTOR   2
 The factor the current zone iteration interval is divided by for each additional new record.
 
#define DHT_GNS_REPLICATION_LEVEL   5
 What replication level do we use for DHT PUT operations?
 

Functions

static void free_job (struct RecordPublicationJob *job)
 
static void shutdown_task (void *cls)
 Task run during shutdown.
 
static void finish_cache_operation (void *cls, int32_t success, const char *emsg)
 Cache operation complete, clean up.
 
static void refresh_block (const struct GNUNET_GNSRECORD_Block *block)
 Refresh the (encrypted) block in the namecache.
 
static void publish_zone_namestore_next (void *cls)
 Method called periodically that triggers iteration over authoritative records.
 
static void publish_zone_dht_start (void *cls)
 Periodically iterate over our zone and store everything in dht.
 
static void calculate_put_interval ()
 Calculate target_iteration_velocity_per_record.
 
static void note_relative_expiration (const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count)
 Note the relative expiration times in rd, they determine how often the zone has to be republished.
 
static void update_velocity (unsigned int cnt)
 Re-calculate our velocity and the desired velocity.
 
static void check_zone_namestore_next ()
 Check if the current zone iteration needs to be continued by calling publish_zone_namestore_next(), and if so with what delay.
 
static void cleanup_job (struct RecordPublicationJob *job)
 
static void dht_put_continuation (void *cls)
 Continuation called from DHT once the PUT operation is done.
 
static void dispatch_job (const struct GNUNET_CRYPTO_BlindablePrivateKey *key, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, const struct GNUNET_TIME_Absolute expire)
 Store GNS records in the DHT.
 
static void notification_pipe_cb (void *cls)
 
static void initiate_put_from_pipe_trigger (void *cls)
 
static void zone_iteration_error (void *cls)
 We encountered an error in our zone iteration.
 
static void zone_iteration_finished (void *cls)
 Zone iteration is completed.
 
static void handle_record (void *cls, const struct GNUNET_CRYPTO_BlindablePrivateKey *key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, struct GNUNET_TIME_Absolute expire)
 Function used to put all records successively into the DHT.
 
static void dispatch_job_monitor (const struct GNUNET_CRYPTO_BlindablePrivateKey *key, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, struct GNUNET_TIME_Absolute expire)
 Store GNS records in the DHT.
 
static void handle_monitor_event (void *cls, const struct GNUNET_CRYPTO_BlindablePrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, struct GNUNET_TIME_Absolute expire)
 Process a record that was stored in the namestore (invoked by the monitor).
 
static void handle_monitor_error (void *cls)
 The zone monitor encountered an IPC error trying to to get in sync.
 
static void * sign_worker (void *cls)
 
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
 Perform zonemaster duties: watch namestore, publish records.
 
 GNUNET_SERVICE_MAIN (GNUNET_OS_project_data_gnunet(), "zonemaster", GNUNET_SERVICE_OPTION_NONE, &run, NULL, NULL, NULL, GNUNET_MQ_handler_end())
 Define "main" method using service macro.
 

Variables

static pthread_t * worker
 Our workers.
 
static pthread_mutex_t sign_jobs_lock
 Lock for the sign jobs queue.
 
static pthread_mutex_t sign_results_lock
 Lock for the DHT put jobs queue.
 
static pthread_cond_t sign_jobs_cond
 Wait condition on new sign jobs.
 
static int in_shutdown = GNUNET_NO
 For threads to know we are shutting down.
 
static int monitor_halted = GNUNET_NO
 Monitor halted?
 
static struct GNUNET_DISK_PipeHandlenotification_pipe
 Our notification pipe.
 
static struct GNUNET_SCHEDULER_Taskpipe_read_task
 Pipe read task.
 
static struct RecordPublicationJobsign_jobs_head
 The DLL for workers to retrieve open jobs that require signing of blocks.
 
static struct RecordPublicationJobsign_jobs_tail
 See above.
 
static struct RecordPublicationJobsign_results_head
 The DLL for workers to place jobs that are signed.
 
static struct RecordPublicationJobsign_results_tail
 See above.
 
static struct RecordPublicationJobdht_jobs_head
 The DLL for jobs currently in the process of being dispatched into the DHT.
 
static struct RecordPublicationJobdht_jobs_tail
 See above.
 
static struct GNUNET_STATISTICS_Handlestatistics
 Handle to the statistics service.
 
static struct GNUNET_DHT_Handledht_handle
 Our handle to the DHT.
 
static struct GNUNET_NAMESTORE_Handlenamestore_handle
 Our handle to the namestore service.
 
static struct GNUNET_NAMESTORE_ZoneMonitorzmon
 Handle to monitor namestore changes to instant propagation.
 
static struct GNUNET_NAMECACHE_Handlenamecache
 Our handle to the namecache service.
 
static int disable_namecache
 Use the namecache? Doing so creates additional cryptographic operations whenever we touch a record.
 
static struct GNUNET_NAMESTORE_ZoneIteratornamestore_iter
 Handle to iterate over our authoritative zone in namestore.
 
static unsigned int job_queue_length
 Number of entries in the job queue #jobs_head.
 
static unsigned long long num_public_records
 Useful for zone update for DHT put.
 
static unsigned long long last_num_public_records
 Last seen record count.
 
static unsigned long long put_cnt
 Number of successful put operations performed in the current measurement cycle (as measured in check_zone_namestore_next()).
 
static struct GNUNET_TIME_Relative target_iteration_velocity_per_record
 What is the frequency at which we currently would like to perform DHT puts (per record)? Calculated in update_velocity() from the zone_publish_time_window() and the total number of record sets we have (so far) observed in the zone.
 
static struct GNUNET_TIME_Relative min_relative_record_time
 Minimum relative expiration time of records seem during the current zone iteration.
 
static struct GNUNET_TIME_Relative last_min_relative_record_time
 Minimum relative expiration time of records seem during the last zone iteration.
 
static struct GNUNET_TIME_Relative zone_publish_time_window_default
 Default time window for zone iteration.
 
static struct GNUNET_TIME_Relative zone_publish_time_window
 Time window for zone iteration, adjusted based on relative record expiration times in our zone.
 
static struct GNUNET_TIME_Absolute last_put_100
 When did we last start measuring the DELTA_INTERVAL successful DHT puts? Used for velocity calculations.
 
static struct GNUNET_TIME_Relative sub_delta
 By how much should we try to increase our per-record iteration speed (over the desired speed calculated directly from the #put_interval)? Basically this value corresponds to the per-record CPU time overhead we have.
 
static struct GNUNET_SCHEDULER_Taskzone_publish_task
 zone publish task
 
static unsigned int ns_iteration_left
 How many more values are left for the current query before we need to explicitly ask the namestore for more?
 
static int first_zone_iteration
 GNUNET_YES if zone has never been published before
 
static int cache_keys
 Optimize block insertion by caching map of private keys to public keys in memory?
 
static struct CacheOperationcop_head
 Head of cop DLL.
 
static struct CacheOperationcop_tail
 Tail of cop DLL.
 

Detailed Description

publish records from namestore to GNUnet name system

Author
Christian Grothoff

Definition in file gnunet-service-zonemaster.c.

Macro Definition Documentation

◆ LOG_STRERROR_FILE

#define LOG_STRERROR_FILE (   kind,
  syscall,
  filename 
)
Value:
syscall, \
static char * filename
#define GNUNET_log_from_strerror_file(level, component, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...

Definition at line 34 of file gnunet-service-zonemaster.c.

133{
134
139
144
149
153 struct GNUNET_GNSRECORD_Block *block_pub;
154
158 struct GNUNET_GNSRECORD_Block *block_priv;
159
163 unsigned char *rdata_pub;
164
169 unsigned char *rdata_priv;
170
174 size_t rdata_pub_len;
175
179 size_t rdata_priv_len;
180
184 struct GNUNET_TIME_Absolute expire_pub;
185
189 struct GNUNET_TIME_Absolute expire_priv;
190
194 char *label;
195
199 struct GNUNET_DHT_PutHandle *ph;
200
204 struct GNUNET_TIME_Absolute start_date;
205
210
214 int have_public_records;
215};
216
217
223
228
233
238
239
244
249
250
254struct CacheOperation
255{
259 struct CacheOperation *prev;
260
264 struct CacheOperation *next;
265
270
271};
272
273
278
282static struct GNUNET_DHT_Handle *dht_handle;
283
288
293
298
303static int disable_namecache;
304
309
313static unsigned int job_queue_length;
314
318static unsigned long long num_public_records;
319
323static unsigned long long last_num_public_records;
324
329static unsigned long long put_cnt;
330
339
345
351
356
362
368
375static struct GNUNET_TIME_Relative sub_delta;
376
381
386static unsigned int ns_iteration_left;
387
391static int first_zone_iteration;
392
397static int cache_keys;
398
402static struct CacheOperation *cop_head;
403
407static struct CacheOperation *cop_tail;
408
409
410static void
412{
413 if (job->rdata_pub != job->rdata_priv)
414 GNUNET_free (job->rdata_priv);
415 GNUNET_free (job->rdata_pub);
416 if (job->block_pub != job->block_priv)
417 GNUNET_free (job->block_priv);
418 GNUNET_free (job->block_pub);
419 if (NULL != job->label)
420 GNUNET_free (job->label);
421 if (NULL != job->ec)
422 {
424 job->ec = NULL;
425 }
427}
428
429
436static void
437shutdown_task (void *cls)
438{
439 struct CacheOperation *cop;
441
442 (void) cls;
445 "Shutting down!\n");
446 if (NULL != notification_pipe)
448 if (NULL != pipe_read_task)
450 while (NULL != (cop = cop_head))
451 {
453 "Aborting incomplete namecache operation\n");
456 GNUNET_free (cop);
457 }
458 GNUNET_assert (0 == pthread_mutex_lock (&sign_jobs_lock));
459 while (NULL != (job = sign_jobs_head))
460 {
462 "Removing incomplete jobs\n");
465 free_job (job);
466 }
467 GNUNET_assert (0 == pthread_mutex_unlock (&sign_jobs_lock));
468 GNUNET_assert (0 == pthread_mutex_lock (&sign_results_lock));
469 while (NULL != (job = sign_results_head))
470 {
472 "Removing incomplete jobs\n");
474 free_job (job);
475 }
476 GNUNET_assert (0 == pthread_mutex_unlock (&sign_results_lock));
477 while (NULL != (job = dht_jobs_head))
478 {
480 "Removing incomplete jobs\n");
482 if (NULL != job->ph)
484 free_job (job);
485 }
486 if (NULL != statistics)
487 {
489 GNUNET_NO);
490 statistics = NULL;
491 }
492 if (NULL != zone_publish_task)
493 {
495 zone_publish_task = NULL;
496 }
497 if (NULL != namestore_iter)
498 {
500 namestore_iter = NULL;
501 }
502 if (NULL != zmon)
503 {
505 zmon = NULL;
506 }
507 if (NULL != namestore_handle)
508 {
510 namestore_handle = NULL;
511 }
512 if (NULL != namecache)
513 {
515 namecache = NULL;
516 }
517 if (NULL != dht_handle)
518 {
520 dht_handle = NULL;
521 }
522}
523
524
532static void
533finish_cache_operation (void *cls, int32_t success, const char *emsg)
534{
535 struct CacheOperation *cop = cls;
536
537 if (NULL != emsg)
539 _ ("Failed to replicate block in namecache: %s\n"),
540 emsg);
541 else
542 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n");
544 GNUNET_free (cop);
545}
546
547
556static void
557refresh_block (const struct GNUNET_GNSRECORD_Block *block)
558{
559 struct CacheOperation *cop;
560
562 {
564 "Namecache updates skipped (NC disabled)",
565 1,
566 GNUNET_NO);
567 return;
568 }
569 GNUNET_assert (NULL != block);
570 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Caching block in namecache\n");
572 "Namecache updates pushed",
573 1,
574 GNUNET_NO);
575 cop = GNUNET_new (struct CacheOperation);
578 block,
580 cop);
581}
582
583
589static void
591{
592 (void) cls;
593 zone_publish_task = NULL;
599}
600
601
607static void
608publish_zone_dht_start (void *cls);
609
610
614static void
616{
617 /* The window follows from the record lifetimes alone: a record set has
618 to be republished #PUBLISH_OPS_PER_EXPIRATION times before it
619 expires, whether or not we have counted the zone yet. */
628 if (0 == num_public_records)
629 {
target_iteration_velocity_per_record = zone_publish_time_window;
636 "No records in namestore database.\n");
637 }
638 else
639 {
643 }
648 "Minimum relative record expiration (in μs)",
650 GNUNET_NO);
652 "Zone publication time window (in μs)",
654 GNUNET_NO);
656 "Target zone iteration velocity (μs)",
658 GNUNET_NO);
659}
660
661
669static void
671 unsigned int rd_count)
672{
673 for (unsigned int i = 0; i < rd_count; i++)
674 {
675 if (0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
676 continue;
677 /* GNUNET_GNSRECORD_block_create will convert to absolute time;
678 we just need to adjust our iteration frequency */
680 = GNUNET_MIN (rd[i].expiration_time,
682 }
683}
684
685
693static void
694update_velocity (unsigned int cnt)
695{
697 unsigned long long pct = 0;
698
699 if (0 == cnt)
700 return;
701 /* How fast were we really? */
703 delta.rel_value_us /= cnt;
705
706 /* calculate expected frequency */
709 {
711 "Last record count was lower than current record count. Reducing interval.\n");
715 }
717 "Desired global zone iteration interval is %s/record!\n",
720 GNUNET_YES));
721
722 /* Tell statistics actual vs. desired speed */
724 "Current zone iteration velocity (μs/record)",
726 GNUNET_NO);
727 /* update "sub_delta" based on difference, taking
728 previous sub_delta into account! */
730 {
731 /* We were too fast, reduce sub_delta! */
732 struct GNUNET_TIME_Relative corr;
733
735 delta);
737 {
738 /* Reduce sub_delta by corr */
740 corr);
741 }
742 else
743 {
744 /* We're doing fine with waiting the full time, this
745 should theoretically only happen if we run at
746 infinite speed. */
748 }
749 }
752 {
753 /* We were too slow, increase sub_delta! */
754 struct GNUNET_TIME_Relative corr;
755
759 corr);
762 {
763 /* CPU overload detected, we cannot go at desired speed,
764 as this would mean using a negative delay. */
765 /* compute how much faster we would want to be for
766 the desired velocity */
768 pct = UINT64_MAX; /* desired speed is infinity ... */
769 else
774 }
775 }
777 "# dispatched jobs",
779 GNUNET_NO);
781 "% speed increase needed for target velocity",
782 pct,
783 GNUNET_NO);
785 "# records processed in current iteration",
787 GNUNET_NO);
788}
789
790
795static void
797{
798 struct GNUNET_TIME_Relative delay;
799
800 if (0 != ns_iteration_left)
801 return; /* current NAMESTORE iteration not yet done */
803 {
805 "Job queue length exceeded (%u/%u). Pausing namestore iteration.\n",
808 return;
809 }
811 put_cnt = 0;
813 sub_delta);
814 /* We delay *once* per #NS_BLOCK_SIZE, so we need to multiply the
815 per-record delay calculated so far with the #NS_BLOCK_SIZE */
817 "Current artificial NAMESTORE delay (μs/record)",
818 delay.rel_value_us,
819 GNUNET_NO);
820 delay = GNUNET_TIME_relative_multiply (delay,
822 GNUNET_MAX (
823 1,
825 );
826 /* make sure we do not overshoot because of the #NS_BLOCK_SIZE factor.
827 The pause is part of one pass over the zone, so it may never exceed
828 the window that pass has to fit into: a record set has to be
829 republished #PUBLISH_OPS_PER_EXPIRATION times before it expires, and
830 with a short expiration time the whole window is shorter than
831 #MAXIMUM_ZONE_ITERATION_INTERVAL. */
832 delay = GNUNET_TIME_relative_min (delay,
836 /* no delays on first iteration */
838 delay = GNUNET_TIME_UNIT_ZERO;
842 ,
843 NULL);
844}
845
846
847static void
849{
852 if (NULL == zone_publish_task)
855 {
857 {
859 "Job queue emptied (%u/%u). Resuming monitor.\n",
864 }
865 }
866 free_job (job);
867}
868
869
874static void
875dht_put_continuation (void *cls)
876{
877 struct RecordPublicationJob *job = cls;
878
880 "PUT complete; Pending jobs: %u\n", job_queue_length - 1);
881 /* When we just fall under the limit, trigger monitor/iterator again
882 * if halted. We can only safely trigger one, prefer iterator. */
885 job);
887}
888
889
900static void
902 const char *label,
903 const struct GNUNET_GNSRECORD_Data *rd,
904 unsigned int rd_count,
905 const struct GNUNET_TIME_Absolute expire)
906{
907 struct GNUNET_GNSRECORD_Data rd_public[rd_count];
908 struct GNUNET_TIME_Absolute expire_pub;
910 unsigned char *rdata_public;
911 unsigned char *rdata_priv;
912 size_t rdata_public_len;
913 size_t rdata_private_len;
914 unsigned int rd_public_count = 0;
915 char *emsg;
916
917 if (GNUNET_OK !=
919 rd,
920 rd_count,
921 rd_public,
922 &rd_public_count,
923 &expire_pub,
925 &emsg))
926 {
928 "%s\n", emsg);
929 GNUNET_free (emsg);
930 }
931
932 rdata_public_len = GNUNET_GNSRECORD_records_get_size (rd_public_count,
933 rd_public);
934
935 rdata_private_len = GNUNET_GNSRECORD_records_get_size (rd_count,
936 rd);
937
938 rdata_public = GNUNET_malloc (rdata_public_len);
940 rd_public_count,
941 rd_public,
942 rdata_public,
943 rdata_public_len));
944 if (rd_count != rd_public_count)
945 {
946 rdata_priv = GNUNET_malloc (rdata_private_len);
948 rd_count,
949 rd,
951 rdata_private_len));
952 }
953 else
954 {
955 rdata_priv = rdata_public;
956 }
957 GNUNET_assert (0 == pthread_mutex_lock (&sign_jobs_lock));
959 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Public record count: %d\n",
960 rd_public_count);
961 job->have_public_records = (rd_public_count > 0);
962 job->rdata_pub = rdata_public;
963 job->rdata_pub_len = rdata_public_len;
964 job->rdata_priv = rdata_priv;
965 job->rdata_priv_len = rdata_private_len;
966 job->zone = *key;
967 job->label = GNUNET_strdup (label);
968 job->expire_pub = expire_pub;
969 job->expire_priv = expire;
972 GNUNET_assert (0 == pthread_cond_signal (&sign_jobs_cond));
973 GNUNET_assert (0 == pthread_mutex_unlock (&sign_jobs_lock));
975 "Creating job with %u record(s) for label `%s', expiration `%s'\n",
976 rd_public_count,
977 label,
980 return;
981}
982
983
984static void
985notification_pipe_cb (void *cls);
986
987static void
989{
990 struct GNUNET_HashCode query;
992 const struct GNUNET_DISK_FileHandle *np_fh;
993 char buf[100];
994 ssize_t nf_count;
995
996 pipe_read_task = NULL;
1002 np_fh,
1004 NULL);
1005 /* empty queue */
1006 nf_count = GNUNET_DISK_file_read (np_fh, buf, sizeof (buf));
1007 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Read %lld notifications from pipe\n",
1008 (long long) nf_count);
1009 while (true)
1010 {
1011 GNUNET_assert (0 == pthread_mutex_lock (&sign_results_lock));
1012 if (NULL == sign_results_head)
1013 {
1015 "No more results. Back to sleep.\n");
1016 GNUNET_assert (0 == pthread_mutex_unlock (&sign_results_lock));
1017 return;
1018 }
1021 GNUNET_assert (0 == pthread_mutex_unlock (&sign_results_lock));
1023 job->label,
1024 &query);
1025 // It is possible that the public block size is 0 (no public blocks)
1026 // Do not bother with the DHT in that case
1027 if (job->have_public_records)
1028 {
1029 size_t block_size = GNUNET_GNSRECORD_block_get_size (job->block_pub);
1031 &query,
1035 block_size,
1036 job->block_pub,
1037 job->expire_pub,
1039 job);
1040 if (NULL == job->ph)
1041 {
1042 /* Drop this job, but keep draining the queue: returning here
1043 leaves every block the workers already signed stranded, and
1044 losing the job_queue_length slot eventually halts both the
1045 zone iteration and the monitor for good. */
1047 "Could not perform DHT PUT, is the DHT running?\n");
1048 cleanup_job (job);
1049 continue;
1050 }
1052 "DHT put operations initiated",
1053 1,
1054 GNUNET_NO);
1056 "Storing record(s) for label `%s' in DHT under key %s\n",
1057 job->label,
1058 GNUNET_h2s (&query));
1059 refresh_block (job->block_priv);
1061 }
1062 else
1063 {
1064 // Private blocks may still be available and must be updated
1065 // in the cache
1066 refresh_block (job->block_priv);
1067 cleanup_job (job);
1068 }
1069 }
1070}
1071
1072
1078static void
1079zone_iteration_error (void *cls)
1080{
1081 (void) cls;
1083 "Got disconnected from namestore database, retrying.\n");
1084 namestore_iter = NULL;
1085 /* We end up here on error/disconnect/shutdown, so potentially
1086 while a zone publish task or a DHT put is still running; hence
1087 we need to cancel those. */
1088 if (NULL != zone_publish_task)
1089 {
1091 zone_publish_task = NULL;
1092 }
1094 NULL);
1095}
1096
1097
1103static void
1104zone_iteration_finished (void *cls)
1105{
1106 (void) cls;
1107 /* we're done with one iteration, calculate when to do the next one */
1108 namestore_iter = NULL;
1113 /* reset for next iteration */
1117 "Zone iteration finished. Adjusted zone iteration interval to %s\n",
1120 GNUNET_YES));
1122 "Target zone iteration velocity (μs)",
1124 GNUNET_NO);
1126 "Number of public records in DHT",
1128 GNUNET_NO);
1130 if (0 == last_num_public_records)
1131 {
1135 NULL);
1136 }
1137 else
1138 {
1140 NULL);
1141 }
1142}
1143
1144
1154static void
1155handle_record (void *cls,
1157 const char *label,
1158 unsigned int rd_count,
1159 const struct GNUNET_GNSRECORD_Data *rd,
1161{
1162 (void) cls;
1164 if (0 == rd_count)
1165 {
1167 "Record set empty, moving to next record set\n");
1169 return;
1170 }
1172 rd_count);
1173
1174 /* We got a set of records to publish */
1176 "Starting DHT PUT\n");
1177 put_cnt++;
1178 if (0 == put_cnt % DELTA_INTERVAL)
1181 label,
1182 rd,
1183 rd_count,
1184 expire);
1187}
1188
1189
1195static void
1196publish_zone_dht_start (void *cls)
1197{
1198 (void) cls;
1199 zone_publish_task = NULL;
1201 "Full zone iterations launched",
1202 1,
1203 GNUNET_NO);
1205 "Starting DHT zone update!\n");
1206 /* start counting again */
1208 GNUNET_assert (NULL == namestore_iter);
1212 NULL, /* All zones */
1214 NULL,
1216 NULL,
1218 NULL,
1220 GNUNET_assert (NULL != namestore_iter);
1221}
1222
1223
1232static void
1234 const char *label,
1235 const struct GNUNET_GNSRECORD_Data *rd,
1236 unsigned int rd_count,
1238{
1239 dispatch_job (key, label, rd, rd_count, expire);
1240}
1241
1242
1254static void
1255handle_monitor_event (void *cls,
1256 const struct GNUNET_CRYPTO_BlindablePrivateKey *zone,
1257 const char *label,
1258 unsigned int rd_count,
1259 const struct GNUNET_GNSRECORD_Data *rd,
1261{
1262 (void) cls;
1264 "Namestore monitor events received",
1265 1,
1266 GNUNET_NO);
1268 "Received %u records for label `%s' via namestore monitor\n",
1269 rd_count,
1270 label);
1271 if (0 == rd_count)
1272 {
1274 1);
1275 return; /* nothing to do */
1276 }
1278 rd_count);
1280 <,
1282 (NULL == namestore_iter) &&
1283 (NULL != zone_publish_task) )
1284 {
1285 /* This record set expires sooner than anything we saw while
1286 iterating, so the next iteration -- which is what republishes it --
1287 has to happen sooner than the one we scheduled back then. Without
1288 this a record with a lifetime below
1289 #MAXIMUM_ZONE_ITERATION_INTERVAL is gone from the DHT long before
1290 it is put there again. */
1297 NULL);
1298 }
1300 label,
1301 rd,
1302 rd_count,
1303 expire);
1306 {
1308 "Job queue length exceeded (%u/%u). Halting monitor.\n",
1312 return;
1313 }
1315 1);
1316}
1317
1318
1325static void
1326handle_monitor_error (void *cls)
1327{
1328 (void) cls;
1330 "Namestore monitor errors encountered",
1331 1,
1332 GNUNET_NO);
1333}
1334
1335
1336static void*
1337sign_worker (void *cls)
1338{
1339 struct RecordPublicationJob *job;
1340 const struct GNUNET_DISK_FileHandle *fh;
1341
1343 while (GNUNET_YES != in_shutdown)
1344 {
1345 GNUNET_assert (0 == pthread_mutex_lock (&sign_jobs_lock));
1346 while (NULL == sign_jobs_head)
1347 GNUNET_assert (0 == pthread_cond_wait (&sign_jobs_cond, &sign_jobs_lock));
1348 if (GNUNET_YES == in_shutdown)
1349 {
1350 GNUNET_assert (0 == pthread_mutex_unlock (&sign_jobs_lock));
1351 return NULL;
1352 }
1354 "Taking on Job for %s\n", sign_jobs_head->label);
1357 GNUNET_assert (0 == pthread_mutex_unlock (&sign_jobs_lock));
1358 job->ec->seal (job->ec->cls,
1359 job->label,
1360 job->expire_pub,
1361 job->rdata_pub,
1362 job->rdata_pub_len,
1363 &job->block_pub);
1364 if (job->rdata_pub != job->rdata_priv)
1365 job->ec->seal (job->ec->cls,
1366 job->label,
1367 job->expire_priv,
1368 job->rdata_priv,
1369 job->rdata_priv_len,
1370 &job->block_priv);
1371 else
1372 job->block_priv = job->block_pub;
1373 GNUNET_assert (0 == pthread_mutex_lock (&sign_results_lock));
1375 GNUNET_assert (0 == pthread_mutex_unlock (&sign_results_lock));
1377 "Done, notifying main thread through pipe!\n");
1378 GNUNET_DISK_file_write (fh, "!", 1);
1379 }
1380 return NULL;
1381}
1382
1383
1384static void
1385notification_pipe_cb (void *cls)
1386{
1388 "Received wake up notification through pipe, checking results\n");
1390}
1391
1392
1400static void
1401run (void *cls,
1402 const struct GNUNET_CONFIGURATION_Handle *c,
1404{
1405 unsigned long long max_parallel_bg_queries = 128;
1406 const struct GNUNET_DISK_FileHandle *np_fh;
1407
1408 (void) cls;
1409 (void) service;
1410 pthread_mutex_init (&sign_jobs_lock, NULL);
1411 pthread_mutex_init (&sign_results_lock, NULL);
1412 pthread_cond_init (&sign_jobs_cond, NULL);
1413 last_put_100 = GNUNET_TIME_absolute_get (); /* first time! */
1418 if (NULL == namestore_handle)
1419 {
1421 _ ("Failed to connect to the namestore!\n"));
1423 return;
1424 }
1426 "namecache",
1427 "DISABLE");
1429 {
1431 if (NULL == namecache)
1432 {
1434 _ ("Failed to connect to the namecache!\n"));
1436 return;
1437 }
1438 }
1440 "namestore",
1441 "CACHE_KEYS");
1443 if (GNUNET_OK ==
1445 "zonemaster",
1446 "ZONE_PUBLISH_TIME_WINDOW",
1448 {
1450 "Time window for zone iteration: %s\n",
1453 GNUNET_YES));
1454 }
1456 if (GNUNET_OK ==
1458 "zonemaster",
1459 "MAX_PARALLEL_BACKGROUND_QUERIES",
1460 &max_parallel_bg_queries))
1461 {
1463 "Number of allowed parallel background queries: %llu\n",
1464 max_parallel_bg_queries);
1465 }
1466 if (0 == max_parallel_bg_queries)
1467 max_parallel_bg_queries = 1;
1469 (unsigned int) max_parallel_bg_queries);
1470 if (NULL == dht_handle)
1471 {
1473 _ ("Could not connect to DHT!\n"));
1475 NULL);
1476 return;
1477 }
1478
1479 /* Schedule periodic put for our records. */
1481 statistics = GNUNET_STATISTICS_create ("zonemaster",
1482 c);
1484 "Target zone iteration velocity (μs)",
1486 GNUNET_NO);
1488 NULL);
1490 NULL,
1491 GNUNET_NO,
1493 NULL,
1495 NULL,
1496 NULL /* sync_cb */,
1497 NULL,
1501 GNUNET_break (NULL != zmon);
1502
1504 NULL);
1505
1507 np_fh = GNUNET_DISK_pipe_handle (
1511 np_fh,
1512 notification_pipe_cb, NULL);
1513
1514 {
1515 long long unsigned int worker_count = 1;
1516 if (GNUNET_OK !=
1518 "zonemaster",
1519 "WORKER_COUNT",
1520 &worker_count))
1521 {
1523 "Number of workers not defined falling back to 1\n");
1524 }
1525 worker = GNUNET_malloc (sizeof (pthread_t) * worker_count);
1527 for (int i = 0; i < worker_count; i++)
1528 {
1529 if (0 !=
1530 pthread_create (&worker[i],
1531 NULL,
1532 &sign_worker,
1533 NULL))
1534 {
1536 "pthread_create");
1538 }
1540 "Workers running",
1541 1,
1542 GNUNET_NO);
1543 }
1544 }
1545}
1546
1547
1553 "zonemaster",
1555 &run,
1556 NULL,
1557 NULL,
1558 NULL,
1560
1561
1562/* end of gnunet-service-zonemaster.c */
static struct GNUNET_SCHEDULER_Task * job
Task for main job.
struct GNUNET_HashCode key
The key used in the DHT.
static char * expire
DID Document expiration Date Attribute String.
Definition gnunet-did.c:98
struct GNUNET_SCHEDULER_Task * shutdown_task
static unsigned int rd_count
Number of records for currently parsed set.
static struct GNUNET_GNSRECORD_Data rd[50]
The record data under a single label.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static pthread_mutex_t sign_results_lock
Lock for the DHT put jobs queue.
#define PUBLISH_OPS_PER_EXPIRATION
How often should we (re)publish each record before it expires?
static int disable_namecache
Use the namecache? Doing so creates additional cryptographic operations whenever we touch a record.
static struct CacheOperation * cop_head
Head of cop DLL.
static struct RecordPublicationJob * sign_results_tail
See above.
static void handle_record(void *cls, const struct GNUNET_CRYPTO_BlindablePrivateKey *key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, struct GNUNET_TIME_Absolute expire)
Function used to put all records successively into the DHT.
static void zone_iteration_finished(void *cls)
Zone iteration is completed.
static unsigned int ns_iteration_left
How many more values are left for the current query before we need to explicitly ask the namestore fo...
static void notification_pipe_cb(void *cls)
static void refresh_block(const struct GNUNET_GNSRECORD_Block *block)
Refresh the (encrypted) block in the namecache.
static struct GNUNET_TIME_Relative target_iteration_velocity_per_record
What is the frequency at which we currently would like to perform DHT puts (per record)?...
static void cleanup_job(struct RecordPublicationJob *job)
static unsigned long long put_cnt
Number of successful put operations performed in the current measurement cycle (as measured in check_...
static struct GNUNET_NAMECACHE_Handle * namecache
Our handle to the namecache service.
static unsigned long long last_num_public_records
Last seen record count.
static void dispatch_job_monitor(const struct GNUNET_CRYPTO_BlindablePrivateKey *key, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, struct GNUNET_TIME_Absolute expire)
Store GNS records in the DHT.
static unsigned int job_queue_length
Number of entries in the job queue #jobs_head.
static void check_zone_namestore_next()
Check if the current zone iteration needs to be continued by calling publish_zone_namestore_next(),...
static struct RecordPublicationJob * sign_results_head
The DLL for workers to place jobs that are signed.
static struct GNUNET_TIME_Relative sub_delta
By how much should we try to increase our per-record iteration speed (over the desired speed calculat...
static struct GNUNET_TIME_Relative zone_publish_time_window
Time window for zone iteration, adjusted based on relative record expiration times in our zone.
#define DELTA_INTERVAL
How often do we measure the delta between desired zone iteration speed and actual speed,...
static void initiate_put_from_pipe_trigger(void *cls)
static struct RecordPublicationJob * dht_jobs_tail
See above.
static void handle_monitor_error(void *cls)
The zone monitor encountered an IPC error trying to to get in sync.
static void calculate_put_interval()
Calculate target_iteration_velocity_per_record.
#define NAMESTORE_MONITOR_QUEUE_LIMIT
How many events may the namestore give us before it has to wait for us to keep up?
static void dispatch_job(const struct GNUNET_CRYPTO_BlindablePrivateKey *key, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, const struct GNUNET_TIME_Absolute expire)
Store GNS records in the DHT.
static void publish_zone_namestore_next(void *cls)
Method called periodically that triggers iteration over authoritative records.
static struct CacheOperation * cop_tail
Tail of cop DLL.
static void finish_cache_operation(void *cls, int32_t success, const char *emsg)
Cache operation complete, clean up.
static struct GNUNET_NAMESTORE_Handle * namestore_handle
Our handle to the namestore service.
static int in_shutdown
For threads to know we are shutting down.
#define NS_BLOCK_SIZE
How many records do we fetch in one shot from the namestore?
static struct GNUNET_TIME_Relative min_relative_record_time
Minimum relative expiration time of records seem during the current zone iteration.
static struct GNUNET_STATISTICS_Handle * statistics
Handle to the statistics service.
static struct GNUNET_DISK_PipeHandle * notification_pipe
Our notification pipe.
static struct GNUNET_DHT_Handle * dht_handle
Our handle to the DHT.
#define LATE_ITERATION_SPEEDUP_FACTOR
The factor the current zone iteration interval is divided by for each additional new record.
static int monitor_halted
Monitor halted?
static void publish_zone_dht_start(void *cls)
Periodically iterate over our zone and store everything in dht.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
Perform zonemaster duties: watch namestore, publish records.
static void handle_monitor_event(void *cls, const struct GNUNET_CRYPTO_BlindablePrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, struct GNUNET_TIME_Absolute expire)
Process a record that was stored in the namestore (invoked by the monitor).
#define JOB_QUEUE_LIMIT
How many open jobs (and with it maximum amount of pending DHT operations) do we allow at most.
static unsigned long long num_public_records
Useful for zone update for DHT put.
static struct RecordPublicationJob * dht_jobs_head
The DLL for jobs currently in the process of being dispatched into the DHT.
#define INITIAL_ZONE_ITERATION_INTERVAL
The initial interval in milliseconds btween puts in a zone iteration.
static int first_zone_iteration
GNUNET_YES if zone has never been published before
static int cache_keys
Optimize block insertion by caching map of private keys to public keys in memory?
static struct GNUNET_TIME_Absolute last_put_100
When did we last start measuring the DELTA_INTERVAL successful DHT puts? Used for velocity calculatio...
static struct GNUNET_SCHEDULER_Task * zone_publish_task
zone publish task
static void * sign_worker(void *cls)
static struct GNUNET_SCHEDULER_Task * pipe_read_task
Pipe read task.
static struct GNUNET_NAMESTORE_ZoneIterator * namestore_iter
Handle to iterate over our authoritative zone in namestore.
static void free_job(struct RecordPublicationJob *job)
static struct GNUNET_TIME_Relative zone_publish_time_window_default
Default time window for zone iteration.
#define DHT_GNS_REPLICATION_LEVEL
What replication level do we use for DHT PUT operations?
static pthread_t * worker
Our workers.
static void note_relative_expiration(const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count)
Note the relative expiration times in rd, they determine how often the zone has to be republished.
static struct RecordPublicationJob * sign_jobs_head
The DLL for workers to retrieve open jobs that require signing of blocks.
static struct GNUNET_TIME_Relative last_min_relative_record_time
Minimum relative expiration time of records seem during the last zone iteration.
static void update_velocity(unsigned int cnt)
Re-calculate our velocity and the desired velocity.
static pthread_cond_t sign_jobs_cond
Wait condition on new sign jobs.
static void dht_put_continuation(void *cls)
Continuation called from DHT once the PUT operation is done.
static struct GNUNET_NAMESTORE_ZoneMonitor * zmon
Handle to monitor namestore changes to instant propagation.
static struct RecordPublicationJob * sign_jobs_tail
See above.
#define MAXIMUM_ZONE_ITERATION_INTERVAL
The upper bound for the zone iteration interval (per record).
static pthread_mutex_t sign_jobs_lock
Lock for the sign jobs queue.
static void zone_iteration_error(void *cls)
We encountered an error in our zone iteration.
@ GNUNET_BLOCK_TYPE_GNS_NAMERECORD
Block for storing GNS record data.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
void GNUNET_DHT_put_cancel(struct GNUNET_DHT_PutHandle *ph)
Cancels a DHT PUT operation.
Definition dht_api.c:1149
struct GNUNET_DHT_PutHandle * GNUNET_DHT_put(struct GNUNET_DHT_Handle *handle, const struct GNUNET_HashCode *key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, size_t size, const void *data, struct GNUNET_TIME_Absolute exp, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
Perform a PUT operation storing data in the DHT.
Definition dht_api.c:1086
struct GNUNET_DHT_Handle * GNUNET_DHT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int ht_len)
Initialize the connection with the DHT service.
Definition dht_api.c:1036
#define GNUNET_DHT_DEFAULT_REPUBLISH_FREQUENCY
Default republication frequency for stored data in the DHT.
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition dht_api.c:1058
@ GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE
Each peer along the way should process the request (otherwise only peers locally closest to the key w...
const struct GNUNET_DISK_FileHandle * GNUNET_DISK_pipe_handle(const struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd n)
Get the handle to a particular pipe end.
Definition disk.c:1703
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition disk.c:745
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(enum GNUNET_DISK_PipeFlags pf)
Creates an interprocess channel.
Definition disk.c:1524
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
Definition disk.c:1671
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition disk.c:704
@ GNUNET_DISK_PF_NONE
No special options, use non-blocking read/write operations.
@ GNUNET_DISK_PIPE_END_WRITE
The writing-end of a pipe.
@ GNUNET_DISK_PIPE_END_READ
The reading-end of a pipe.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_GNSRECORD_query_from_private_key(const struct GNUNET_CRYPTO_BlindablePrivateKey *zone, const char *label, struct GNUNET_HashCode *query)
Calculate the DHT query for a given label in a given zone.
void GNUNET_GNSRECORD_encryption_context_destroy(struct GNUNET_GNSRECORD_EncryptionContext *ec)
Cleanup and free the encryption context.
size_t GNUNET_GNSRECORD_block_get_size(const struct GNUNET_GNSRECORD_Block *block)
Returns the length of this block in bytes.
ssize_t GNUNET_GNSRECORD_records_get_size(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Calculate how many bytes we will need to serialize the given records.
struct GNUNET_GNSRECORD_EncryptionContext * GNUNET_GNSRECORD_encryption_context_setup_owner(const struct GNUNET_CRYPTO_BlindablePrivateKey *sk)
Create a new encryption context for the zone owner.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_record_data_to_rdata(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data rd[rd_count], unsigned char *rdata, size_t rdata_len)
Serialize the record set into an RFC9498-compliant RDATA octet string.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_normalize_record_set(const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *rd_public, unsigned int *rd_count_public, struct GNUNET_TIME_Absolute *min_expiry, enum GNUNET_GNSRECORD_Filter filter, char **emsg)
Normalize namestore records: Check for consistency and expirations.
@ GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION
This expiration time of the record is a relative time (not an absolute time).
@ GNUNET_GNSRECORD_FILTER_NONE
No filter flags set.
@ GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE
Filter private records.
#define GNUNET_log(kind,...)
#define GNUNET_MAX(a, b)
#define GNUNET_MIN(a, b)
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
struct GNUNET_NAMECACHE_Handle * GNUNET_NAMECACHE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namecache service.
void GNUNET_NAMECACHE_disconnect(struct GNUNET_NAMECACHE_Handle *h)
Disconnect from the namecache service (and free associated resources).
void GNUNET_NAMECACHE_cancel(struct GNUNET_NAMECACHE_QueueEntry *qe)
Cancel a namecache operation.
struct GNUNET_NAMECACHE_QueueEntry * GNUNET_NAMECACHE_block_cache(struct GNUNET_NAMECACHE_Handle *h, const struct GNUNET_GNSRECORD_Block *block, GNUNET_NAMECACHE_ContinuationWithStatus cont, void *cont_cls)
Store an item in the namecache.
struct GNUNET_NAMESTORE_ZoneMonitor * GNUNET_NAMESTORE_zone_monitor_start2(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_CRYPTO_BlindablePrivateKey *zone, int iterate_first, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordSetMonitor monitor, void *monitor_cls, GNUNET_SCHEDULER_TaskCallback sync_cb, void *sync_cb_cls, enum GNUNET_GNSRECORD_Filter filter)
Begin monitoring a zone for changes.
void GNUNET_NAMESTORE_disconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from the namestore service (and free associated resources).
void GNUNET_NAMESTORE_zone_iterator_next(struct GNUNET_NAMESTORE_ZoneIterator *it, uint64_t limit)
Calls the record processor specified in GNUNET_NAMESTORE_zone_iteration_start for the next record.
void GNUNET_NAMESTORE_zone_monitor_stop(struct GNUNET_NAMESTORE_ZoneMonitor *zm)
Stop monitoring a zone for changes.
struct GNUNET_NAMESTORE_ZoneIterator * GNUNET_NAMESTORE_zone_iteration_start2(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_BlindablePrivateKey *zone, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordSetMonitor proc, void *proc_cls, GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls, enum GNUNET_GNSRECORD_Filter filter)
Starts a new zone iteration (used to periodically PUT all of our records into our DHT).
void GNUNET_NAMESTORE_zone_monitor_next(struct GNUNET_NAMESTORE_ZoneMonitor *zm, uint64_t limit)
Calls the monitor processor specified in GNUNET_NAMESTORE_zone_monitor_start for the next record(s).
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namestore service.
void GNUNET_NAMESTORE_zone_iteration_stop(struct GNUNET_NAMESTORE_ZoneIterator *it)
Stops iteration and releases the namestore handle for further calls.
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:572
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_file(struct GNUNET_TIME_Relative delay, const struct GNUNET_DISK_FileHandle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition scheduler.c:1667
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition scheduler.c:1345
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1283
#define GNUNET_SERVICE_MAIN(pd, service_name, service_options, init_cb, connect_cb, disconnect_cb, cls,...)
Creates the "main" function for a GNUnet service.
@ GNUNET_SERVICE_OPTION_NONE
Use defaults.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
struct GNUNET_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition time.c:344
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition time.c:438
#define GNUNET_TIME_relative_cmp(t1, op, t2)
Compare two relative times.
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition strings.c:610
struct GNUNET_TIME_Relative GNUNET_TIME_relative_subtract(struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative a2)
Subtract relative timestamp from the other.
Definition time.c:601
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
struct GNUNET_TIME_Relative GNUNET_TIME_relative_add(struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative a2)
Add relative times together.
Definition time.c:583
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition time.c:486
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_divide(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Divide relative time by a given factor.
Definition time.c:548
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition strings.c:671
#define _(String)
GNU gettext support macro.
Definition platform.h:179
static struct GNUNET_TIME_Relative delta
Definition speedup.c:36
Pending operation on the namecache.
struct CacheOperation * next
Kept in a DLL.
struct GNUNET_NAMECACHE_QueueEntry * qe
Handle to namecache queue.
struct CacheOperation * prev
Kept in a DLL.
A private key for an identity as per LSD0001.
Connection to the DHT service.
Definition dht_api.c:235
Handle to a PUT request.
Definition dht_api.c:43
Handle used to access files (and pipes).
The GNSRECORD encryption context.
A 512-bit hashcode.
Connection to the NAMECACHE service.
An QueueEntry used to store information for a pending NAMECACHE record operation.
Connection to the NAMESTORE service.
Handle for a zone iterator operation.
Handle for a monitoring activity.
Entry in list of pending tasks.
Definition scheduler.c:141
Handle to a service.
Definition service.c:116
Handle for the service.
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
struct RecordPublicationJob * next
DLL.
unsigned char * rdata_priv
The private RDATA to sign, may point to block in case the public and private blocks are the same.
struct RecordPublicationJob * prev
DLL.
char * label
The label of the block needed for signing.
struct GNUNET_TIME_Absolute expire_pub
The expiration time of the public RDATA for the DHT put.

◆ PUBLISH_OPS_PER_EXPIRATION

#define PUBLISH_OPS_PER_EXPIRATION   4

How often should we (re)publish each record before it expires?

Definition at line 44 of file gnunet-service-zonemaster.c.

◆ DELTA_INTERVAL

#define DELTA_INTERVAL   100

How often do we measure the delta between desired zone iteration speed and actual speed, and tell statistics service about it?

Definition at line 51 of file gnunet-service-zonemaster.c.

◆ NS_BLOCK_SIZE

#define NS_BLOCK_SIZE   1000

How many records do we fetch in one shot from the namestore?

Definition at line 56 of file gnunet-service-zonemaster.c.

◆ JOB_QUEUE_LIMIT

#define JOB_QUEUE_LIMIT   5000

How many open jobs (and with it maximum amount of pending DHT operations) do we allow at most.

Definition at line 61 of file gnunet-service-zonemaster.c.

◆ NAMESTORE_MONITOR_QUEUE_LIMIT

#define NAMESTORE_MONITOR_QUEUE_LIMIT   5

How many events may the namestore give us before it has to wait for us to keep up?

Definition at line 67 of file gnunet-service-zonemaster.c.

◆ INITIAL_ZONE_ITERATION_INTERVAL

#define INITIAL_ZONE_ITERATION_INTERVAL   GNUNET_TIME_UNIT_MILLISECONDS

The initial interval in milliseconds btween puts in a zone iteration.

Definition at line 73 of file gnunet-service-zonemaster.c.

◆ MAXIMUM_ZONE_ITERATION_INTERVAL

#define MAXIMUM_ZONE_ITERATION_INTERVAL
Value:
#define GNUNET_TIME_UNIT_MINUTES
One minute.

The upper bound for the zone iteration interval (per record).

Definition at line 79 of file gnunet-service-zonemaster.c.

◆ LATE_ITERATION_SPEEDUP_FACTOR

#define LATE_ITERATION_SPEEDUP_FACTOR   2

The factor the current zone iteration interval is divided by for each additional new record.

Definition at line 86 of file gnunet-service-zonemaster.c.

◆ DHT_GNS_REPLICATION_LEVEL

#define DHT_GNS_REPLICATION_LEVEL   5

What replication level do we use for DHT PUT operations?

Definition at line 91 of file gnunet-service-zonemaster.c.

Function Documentation

◆ free_job()

static void free_job ( struct RecordPublicationJob job)
static

Definition at line 412 of file gnunet-service-zonemaster.c.

413{
414 if (job->rdata_pub != job->rdata_priv)
415 GNUNET_free (job->rdata_priv);
416 GNUNET_free (job->rdata_pub);
417 if (job->block_pub != job->block_priv)
418 GNUNET_free (job->block_priv);
419 GNUNET_free (job->block_pub);
420 if (NULL != job->label)
421 GNUNET_free (job->label);
422 if (NULL != job->ec)
423 {
425 job->ec = NULL;
426 }
428}

References GNUNET_free, GNUNET_GNSRECORD_encryption_context_destroy(), and job.

Referenced by cleanup_job(), and shutdown_task().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ shutdown_task()

static void shutdown_task ( void *  cls)
static

Task run during shutdown.

Parameters
clsunused
tcunused

Definition at line 438 of file gnunet-service-zonemaster.c.

439{
440 struct CacheOperation *cop;
442
443 (void) cls;
446 "Shutting down!\n");
447 if (NULL != notification_pipe)
449 if (NULL != pipe_read_task)
451 while (NULL != (cop = cop_head))
452 {
454 "Aborting incomplete namecache operation\n");
457 GNUNET_free (cop);
458 }
459 GNUNET_assert (0 == pthread_mutex_lock (&sign_jobs_lock));
460 while (NULL != (job = sign_jobs_head))
461 {
463 "Removing incomplete jobs\n");
466 free_job (job);
467 }
468 GNUNET_assert (0 == pthread_mutex_unlock (&sign_jobs_lock));
469 GNUNET_assert (0 == pthread_mutex_lock (&sign_results_lock));
470 while (NULL != (job = sign_results_head))
471 {
473 "Removing incomplete jobs\n");
475 free_job (job);
476 }
477 GNUNET_assert (0 == pthread_mutex_unlock (&sign_results_lock));
478 while (NULL != (job = dht_jobs_head))
479 {
481 "Removing incomplete jobs\n");
483 if (NULL != job->ph)
485 free_job (job);
486 }
487 if (NULL != statistics)
488 {
490 GNUNET_NO);
491 statistics = NULL;
492 }
493 if (NULL != zone_publish_task)
494 {
496 zone_publish_task = NULL;
497 }
498 if (NULL != namestore_iter)
499 {
501 namestore_iter = NULL;
502 }
503 if (NULL != zmon)
504 {
506 zmon = NULL;
507 }
508 if (NULL != namestore_handle)
509 {
511 namestore_handle = NULL;
512 }
513 if (NULL != namecache)
514 {
516 namecache = NULL;
517 }
518 if (NULL != dht_handle)
519 {
521 dht_handle = NULL;
522 }
523}

References cop_head, cop_tail, dht_handle, dht_jobs_head, dht_jobs_tail, free_job(), GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_DHT_disconnect(), GNUNET_DHT_put_cancel(), GNUNET_DISK_pipe_close(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_NAMECACHE_cancel(), GNUNET_NAMECACHE_disconnect(), GNUNET_NAMESTORE_disconnect(), GNUNET_NAMESTORE_zone_iteration_stop(), GNUNET_NAMESTORE_zone_monitor_stop(), GNUNET_NO, GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_destroy(), GNUNET_YES, in_shutdown, job, job_queue_length, namecache, namestore_handle, namestore_iter, notification_pipe, pipe_read_task, CacheOperation::qe, sign_jobs_head, sign_jobs_lock, sign_jobs_tail, sign_results_head, sign_results_lock, sign_results_tail, statistics, zmon, and zone_publish_task.

Here is the call graph for this function:

◆ finish_cache_operation()

static void finish_cache_operation ( void *  cls,
int32_t  success,
const char *  emsg 
)
static

Cache operation complete, clean up.

Parameters
clsthe struct CacheOperation
successsuccess
emsgerror messages

Definition at line 534 of file gnunet-service-zonemaster.c.

535{
536 struct CacheOperation *cop = cls;
537
538 if (NULL != emsg)
540 _ ("Failed to replicate block in namecache: %s\n"),
541 emsg);
542 else
543 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n");
545 GNUNET_free (cop);
546}

References _, cop_head, cop_tail, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, and GNUNET_log.

Referenced by refresh_block().

Here is the caller graph for this function:

◆ refresh_block()

static void refresh_block ( const struct GNUNET_GNSRECORD_Block block)
static

Refresh the (encrypted) block in the namecache.

Parameters
zone_keyprivate key of the zone
namelabel for the records
rd_countnumber of records
rdrecords stored under the given name

Definition at line 558 of file gnunet-service-zonemaster.c.

559{
560 struct CacheOperation *cop;
561
563 {
565 "Namecache updates skipped (NC disabled)",
566 1,
567 GNUNET_NO);
568 return;
569 }
570 GNUNET_assert (NULL != block);
571 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Caching block in namecache\n");
573 "Namecache updates pushed",
574 1,
575 GNUNET_NO);
576 cop = GNUNET_new (struct CacheOperation);
579 block,
581 cop);
582}

References cop_head, cop_tail, disable_namecache, finish_cache_operation(), GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NAMECACHE_block_cache(), GNUNET_new, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_YES, namecache, CacheOperation::qe, and statistics.

Referenced by initiate_put_from_pipe_trigger().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ publish_zone_namestore_next()

static void publish_zone_namestore_next ( void *  cls)
static

Method called periodically that triggers iteration over authoritative records.

Parameters
clsNULL

Definition at line 591 of file gnunet-service-zonemaster.c.

References GNUNET_assert, GNUNET_NAMESTORE_zone_iterator_next(), namestore_iter, NS_BLOCK_SIZE, ns_iteration_left, and zone_publish_task.

Referenced by check_zone_namestore_next().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ publish_zone_dht_start()

static void publish_zone_dht_start ( void *  cls)
static

Periodically iterate over our zone and store everything in dht.

Periodically iterate over all zones and store everything in DHT.

Parameters
clsNULL

Definition at line 1197 of file gnunet-service-zonemaster.c.

1198{
1199 (void) cls;
1200 zone_publish_task = NULL;
1202 "Full zone iterations launched",
1203 1,
1204 GNUNET_NO);
1206 "Starting DHT zone update!\n");
1207 /* start counting again */
1209 GNUNET_assert (NULL == namestore_iter);
1213 NULL, /* All zones */
1215 NULL,
1217 NULL,
1219 NULL,
1221 GNUNET_assert (NULL != namestore_iter);
1222}

References GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_GNSRECORD_FILTER_NONE, GNUNET_log, GNUNET_NAMESTORE_zone_iteration_start2(), GNUNET_NO, GNUNET_STATISTICS_update(), handle_record(), namestore_handle, namestore_iter, ns_iteration_left, num_public_records, statistics, zone_iteration_error(), zone_iteration_finished(), and zone_publish_task.

Referenced by handle_monitor_event(), run(), zone_iteration_error(), and zone_iteration_finished().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculate_put_interval()

static void calculate_put_interval ( )
static

Calculate target_iteration_velocity_per_record.

If no records are known (startup) or none present we can safely set the interval to the value for a single record

Definition at line 616 of file gnunet-service-zonemaster.c.

617{
618 /* The window follows from the record lifetimes alone: a record set has
619 to be republished #PUBLISH_OPS_PER_EXPIRATION times before it
620 expires, whether or not we have counted the zone yet. */
629 if (0 == num_public_records)
630 {
target_iteration_velocity_per_record = zone_publish_time_window;
637 "No records in namestore database.\n");
638 }
639 else
640 {
644 }
649 "Minimum relative record expiration (in μs)",
651 GNUNET_NO);
653 "Zone publication time window (in μs)",
655 GNUNET_NO);
657 "Target zone iteration velocity (μs)",
659 GNUNET_NO);
660}

References GNUNET_ERROR_TYPE_BULK, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_set(), GNUNET_TIME_relative_divide(), GNUNET_TIME_relative_min(), last_min_relative_record_time, last_num_public_records, MAXIMUM_ZONE_ITERATION_INTERVAL, min_relative_record_time, num_public_records, PUBLISH_OPS_PER_EXPIRATION, GNUNET_TIME_Relative::rel_value_us, statistics, target_iteration_velocity_per_record, zone_publish_time_window, and zone_publish_time_window_default.

Referenced by handle_monitor_event(), update_velocity(), and zone_iteration_finished().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ note_relative_expiration()

static void note_relative_expiration ( const struct GNUNET_GNSRECORD_Data rd,
unsigned int  rd_count 
)
static

Note the relative expiration times in rd, they determine how often the zone has to be republished.

Parameters
rdrecord set
rd_countnumber of records in rd

Definition at line 671 of file gnunet-service-zonemaster.c.

673{
674 for (unsigned int i = 0; i < rd_count; i++)
675 {
676 if (0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
677 continue;
678 /* GNUNET_GNSRECORD_block_create will convert to absolute time;
679 we just need to adjust our iteration frequency */
681 = GNUNET_MIN (rd[i].expiration_time,
683 }
684}

References GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION, GNUNET_MIN, min_relative_record_time, rd, rd_count, and GNUNET_TIME_Relative::rel_value_us.

Referenced by handle_monitor_event(), and handle_record().

Here is the caller graph for this function:

◆ update_velocity()

static void update_velocity ( unsigned int  cnt)
static

Re-calculate our velocity and the desired velocity.

We have succeeded in making DELTA_INTERVAL puts, so now calculate the new desired delay between puts.

Parameters
cnthow many records were processed since the last call?

Definition at line 695 of file gnunet-service-zonemaster.c.

696{
698 unsigned long long pct = 0;
699
700 if (0 == cnt)
701 return;
702 /* How fast were we really? */
704 delta.rel_value_us /= cnt;
706
707 /* calculate expected frequency */
710 {
712 "Last record count was lower than current record count. Reducing interval.\n");
716 }
718 "Desired global zone iteration interval is %s/record!\n",
721 GNUNET_YES));
722
723 /* Tell statistics actual vs. desired speed */
725 "Current zone iteration velocity (μs/record)",
727 GNUNET_NO);
728 /* update "sub_delta" based on difference, taking
729 previous sub_delta into account! */
731 {
732 /* We were too fast, reduce sub_delta! */
733 struct GNUNET_TIME_Relative corr;
734
736 delta);
738 {
739 /* Reduce sub_delta by corr */
741 corr);
742 }
743 else
744 {
745 /* We're doing fine with waiting the full time, this
746 should theoretically only happen if we run at
747 infinite speed. */
749 }
750 }
753 {
754 /* We were too slow, increase sub_delta! */
755 struct GNUNET_TIME_Relative corr;
756
760 corr);
763 {
764 /* CPU overload detected, we cannot go at desired speed,
765 as this would mean using a negative delay. */
766 /* compute how much faster we would want to be for
767 the desired velocity */
769 pct = UINT64_MAX; /* desired speed is infinity ... */
770 else
775 }
776 }
778 "# dispatched jobs",
780 GNUNET_NO);
782 "% speed increase needed for target velocity",
783 pct,
784 GNUNET_NO);
786 "# records processed in current iteration",
788 GNUNET_NO);
789}

References calculate_put_interval(), delta, first_zone_iteration, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_set(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_get_duration(), GNUNET_TIME_relative_add(), GNUNET_TIME_relative_subtract(), GNUNET_TIME_UNIT_ZERO, GNUNET_YES, job_queue_length, last_num_public_records, last_put_100, LATE_ITERATION_SPEEDUP_FACTOR, num_public_records, GNUNET_TIME_Relative::rel_value_us, statistics, sub_delta, and target_iteration_velocity_per_record.

Referenced by check_zone_namestore_next(), and handle_record().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_zone_namestore_next()

static void check_zone_namestore_next ( )
static

Check if the current zone iteration needs to be continued by calling publish_zone_namestore_next(), and if so with what delay.

Definition at line 797 of file gnunet-service-zonemaster.c.

798{
799 struct GNUNET_TIME_Relative delay;
800
801 if (0 != ns_iteration_left)
802 return; /* current NAMESTORE iteration not yet done */
804 {
806 "Job queue length exceeded (%u/%u). Pausing namestore iteration.\n",
809 return;
810 }
812 put_cnt = 0;
814 sub_delta);
815 /* We delay *once* per #NS_BLOCK_SIZE, so we need to multiply the
816 per-record delay calculated so far with the #NS_BLOCK_SIZE */
818 "Current artificial NAMESTORE delay (μs/record)",
819 delay.rel_value_us,
820 GNUNET_NO);
821 delay = GNUNET_TIME_relative_multiply (delay,
823 GNUNET_MAX (
824 1,
826 );
827 /* make sure we do not overshoot because of the #NS_BLOCK_SIZE factor.
828 The pause is part of one pass over the zone, so it may never exceed
829 the window that pass has to fit into: a record set has to be
830 republished #PUBLISH_OPS_PER_EXPIRATION times before it expires, and
831 with a short expiration time the whole window is shorter than
832 #MAXIMUM_ZONE_ITERATION_INTERVAL. */
833 delay = GNUNET_TIME_relative_min (delay,
837 /* no delays on first iteration */
839 delay = GNUNET_TIME_UNIT_ZERO;
843 ,
844 NULL);
845}

References first_zone_iteration, GNUNET_assert, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_MAX, GNUNET_MIN, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_STATISTICS_set(), GNUNET_TIME_relative_min(), GNUNET_TIME_relative_multiply(), GNUNET_TIME_relative_subtract(), GNUNET_TIME_UNIT_ZERO, GNUNET_YES, job_queue_length, JOB_QUEUE_LIMIT, last_num_public_records, MAXIMUM_ZONE_ITERATION_INTERVAL, NS_BLOCK_SIZE, ns_iteration_left, publish_zone_namestore_next(), put_cnt, GNUNET_TIME_Relative::rel_value_us, statistics, sub_delta, target_iteration_velocity_per_record, update_velocity(), zone_publish_task, and zone_publish_time_window.

Referenced by cleanup_job(), and handle_record().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cleanup_job()

static void cleanup_job ( struct RecordPublicationJob job)
static

Definition at line 849 of file gnunet-service-zonemaster.c.

850{
853 if (NULL == zone_publish_task)
856 {
858 {
860 "Job queue emptied (%u/%u). Resuming monitor.\n",
865 }
866 }
867 free_job (job);
868}

References check_zone_namestore_next(), free_job(), GNUNET_assert, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_NAMESTORE_zone_monitor_next(), GNUNET_NO, GNUNET_YES, job, job_queue_length, JOB_QUEUE_LIMIT, monitor_halted, zmon, and zone_publish_task.

Referenced by dht_put_continuation(), and initiate_put_from_pipe_trigger().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dht_put_continuation()

static void dht_put_continuation ( void *  cls)
static

Continuation called from DHT once the PUT operation is done.

Definition at line 876 of file gnunet-service-zonemaster.c.

877{
878 struct RecordPublicationJob *job = cls;
879
881 "PUT complete; Pending jobs: %u\n", job_queue_length - 1);
882 /* When we just fall under the limit, trigger monitor/iterator again
883 * if halted. We can only safely trigger one, prefer iterator. */
886 job);
888}

References cleanup_job(), dht_jobs_head, dht_jobs_tail, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, job, and job_queue_length.

Referenced by initiate_put_from_pipe_trigger().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dispatch_job()

static void dispatch_job ( const struct GNUNET_CRYPTO_BlindablePrivateKey key,
const char *  label,
const struct GNUNET_GNSRECORD_Data rd,
unsigned int  rd_count,
const struct GNUNET_TIME_Absolute  expire 
)
static

Store GNS records in the DHT.

Parameters
keykey of the zone
labellabel to store under
rd_publicpublic record data
rd_public_countnumber of records in rd_public
mahandle for the put operation
Returns
DHT PUT handle, NULL on error

Definition at line 902 of file gnunet-service-zonemaster.c.

907{
908 struct GNUNET_GNSRECORD_Data rd_public[rd_count];
909 struct GNUNET_TIME_Absolute expire_pub;
911 unsigned char *rdata_public;
912 unsigned char *rdata_priv;
913 size_t rdata_public_len;
914 size_t rdata_private_len;
915 unsigned int rd_public_count = 0;
916 char *emsg;
917
918 if (GNUNET_OK !=
920 rd,
921 rd_count,
922 rd_public,
923 &rd_public_count,
924 &expire_pub,
926 &emsg))
927 {
929 "%s\n", emsg);
930 GNUNET_free (emsg);
931 }
932
933 rdata_public_len = GNUNET_GNSRECORD_records_get_size (rd_public_count,
934 rd_public);
935
936 rdata_private_len = GNUNET_GNSRECORD_records_get_size (rd_count,
937 rd);
938
939 rdata_public = GNUNET_malloc (rdata_public_len);
941 rd_public_count,
942 rd_public,
943 rdata_public,
944 rdata_public_len));
945 if (rd_count != rd_public_count)
946 {
947 rdata_priv = GNUNET_malloc (rdata_private_len);
949 rd_count,
950 rd,
952 rdata_private_len));
953 }
954 else
955 {
956 rdata_priv = rdata_public;
957 }
958 GNUNET_assert (0 == pthread_mutex_lock (&sign_jobs_lock));
960 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Public record count: %d\n",
961 rd_public_count);
962 job->have_public_records = (rd_public_count > 0);
963 job->rdata_pub = rdata_public;
964 job->rdata_pub_len = rdata_public_len;
965 job->rdata_priv = rdata_priv;
966 job->rdata_priv_len = rdata_private_len;
967 job->zone = *key;
968 job->label = GNUNET_strdup (label);
969 job->expire_pub = expire_pub;
970 job->expire_priv = expire;
973 GNUNET_assert (0 == pthread_cond_signal (&sign_jobs_cond));
974 GNUNET_assert (0 == pthread_mutex_unlock (&sign_jobs_lock));
976 "Creating job with %u record(s) for label `%s', expiration `%s'\n",
977 rd_public_count,
978 label,
981 return;
982}

References expire, RecordPublicationJob::expire_pub, GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_GNSRECORD_encryption_context_setup_owner(), GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE, GNUNET_GNSRECORD_normalize_record_set(), GNUNET_GNSRECORD_record_data_to_rdata(), GNUNET_GNSRECORD_records_get_size(), GNUNET_log, GNUNET_malloc, GNUNET_new, GNUNET_OK, GNUNET_strdup, GNUNET_STRINGS_absolute_time_to_string(), job, key, RecordPublicationJob::label, num_public_records, rd, rd_count, RecordPublicationJob::rdata_priv, sign_jobs_cond, sign_jobs_head, sign_jobs_lock, and sign_jobs_tail.

Referenced by dispatch_job_monitor(), and handle_record().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ notification_pipe_cb()

static void notification_pipe_cb ( void *  cls)
static

Definition at line 1386 of file gnunet-service-zonemaster.c.

1387{
1389 "Received wake up notification through pipe, checking results\n");
1391}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_SCHEDULER_add_now(), and initiate_put_from_pipe_trigger().

Referenced by initiate_put_from_pipe_trigger(), and run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initiate_put_from_pipe_trigger()

static void initiate_put_from_pipe_trigger ( void *  cls)
static

Definition at line 989 of file gnunet-service-zonemaster.c.

990{
991 struct GNUNET_HashCode query;
993 const struct GNUNET_DISK_FileHandle *np_fh;
994 char buf[100];
995 ssize_t nf_count;
996
997 pipe_read_task = NULL;
1003 np_fh,
1005 NULL);
1006 /* empty queue */
1007 nf_count = GNUNET_DISK_file_read (np_fh, buf, sizeof (buf));
1008 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Read %lld notifications from pipe\n",
1009 (long long) nf_count);
1010 while (true)
1011 {
1012 GNUNET_assert (0 == pthread_mutex_lock (&sign_results_lock));
1013 if (NULL == sign_results_head)
1014 {
1016 "No more results. Back to sleep.\n");
1017 GNUNET_assert (0 == pthread_mutex_unlock (&sign_results_lock));
1018 return;
1019 }
1022 GNUNET_assert (0 == pthread_mutex_unlock (&sign_results_lock));
1024 job->label,
1025 &query);
1026 // It is possible that the public block size is 0 (no public blocks)
1027 // Do not bother with the DHT in that case
1028 if (job->have_public_records)
1029 {
1030 size_t block_size = GNUNET_GNSRECORD_block_get_size (job->block_pub);
1032 &query,
1036 block_size,
1037 job->block_pub,
1038 job->expire_pub,
1040 job);
1041 if (NULL == job->ph)
1042 {
1043 /* Drop this job, but keep draining the queue: returning here
1044 leaves every block the workers already signed stranded, and
1045 losing the job_queue_length slot eventually halts both the
1046 zone iteration and the monitor for good. */
1048 "Could not perform DHT PUT, is the DHT running?\n");
1049 cleanup_job (job);
1050 continue;
1051 }
1053 "DHT put operations initiated",
1054 1,
1055 GNUNET_NO);
1057 "Storing record(s) for label `%s' in DHT under key %s\n",
1058 job->label,
1059 GNUNET_h2s (&query));
1060 refresh_block (job->block_priv);
1062 }
1063 else
1064 {
1065 // Private blocks may still be available and must be updated
1066 // in the cache
1067 refresh_block (job->block_priv);
1068 cleanup_job (job);
1069 }
1070 }
1071}

References cleanup_job(), DHT_GNS_REPLICATION_LEVEL, dht_handle, dht_jobs_head, dht_jobs_tail, dht_put_continuation(), GNUNET_assert, GNUNET_BLOCK_TYPE_GNS_NAMERECORD, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_DHT_put(), GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, GNUNET_DISK_file_read(), GNUNET_DISK_PIPE_END_READ, GNUNET_DISK_pipe_handle(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_GNSRECORD_block_get_size(), GNUNET_GNSRECORD_query_from_private_key(), GNUNET_h2s(), GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_add_read_file(), GNUNET_STATISTICS_update(), GNUNET_TIME_UNIT_FOREVER_REL, job, notification_pipe, notification_pipe_cb(), pipe_read_task, refresh_block(), sign_results_head, sign_results_lock, sign_results_tail, and statistics.

Referenced by notification_pipe_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ zone_iteration_error()

static void zone_iteration_error ( void *  cls)
static

We encountered an error in our zone iteration.

Parameters
clsNULL

Definition at line 1080 of file gnunet-service-zonemaster.c.

1081{
1082 (void) cls;
1084 "Got disconnected from namestore database, retrying.\n");
1085 namestore_iter = NULL;
1086 /* We end up here on error/disconnect/shutdown, so potentially
1087 while a zone publish task or a DHT put is still running; hence
1088 we need to cancel those. */
1089 if (NULL != zone_publish_task)
1090 {
1092 zone_publish_task = NULL;
1093 }
1095 NULL);
1096}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), namestore_iter, publish_zone_dht_start(), and zone_publish_task.

Referenced by publish_zone_dht_start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ zone_iteration_finished()

static void zone_iteration_finished ( void *  cls)
static

Zone iteration is completed.

Parameters
clsNULL

Definition at line 1105 of file gnunet-service-zonemaster.c.

1106{
1107 (void) cls;
1108 /* we're done with one iteration, calculate when to do the next one */
1109 namestore_iter = NULL;
1114 /* reset for next iteration */
1118 "Zone iteration finished. Adjusted zone iteration interval to %s\n",
1121 GNUNET_YES));
1123 "Target zone iteration velocity (μs)",
1125 GNUNET_NO);
1127 "Number of public records in DHT",
1129 GNUNET_NO);
1131 if (0 == last_num_public_records)
1132 {
1136 NULL);
1137 }
1138 else
1139 {
1141 NULL);
1142 }
1143}

References calculate_put_interval(), first_zone_iteration, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_add_now(), GNUNET_STATISTICS_set(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, last_min_relative_record_time, last_num_public_records, min_relative_record_time, namestore_iter, num_public_records, publish_zone_dht_start(), GNUNET_TIME_Relative::rel_value_us, statistics, target_iteration_velocity_per_record, and zone_publish_task.

Referenced by publish_zone_dht_start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_record()

static void handle_record ( void *  cls,
const struct GNUNET_CRYPTO_BlindablePrivateKey key,
const char *  label,
unsigned int  rd_count,
const struct GNUNET_GNSRECORD_Data rd,
struct GNUNET_TIME_Absolute  expire 
)
static

Function used to put all records successively into the DHT.

Parameters
clsthe closure (NULL)
keythe private key of the authority (ours)
labelthe name of the records, NULL once the iteration is done
rd_countthe number of records in rd
rdthe record data

Definition at line 1156 of file gnunet-service-zonemaster.c.

1162{
1163 (void) cls;
1165 if (0 == rd_count)
1166 {
1168 "Record set empty, moving to next record set\n");
1170 return;
1171 }
1173 rd_count);
1174
1175 /* We got a set of records to publish */
1177 "Starting DHT PUT\n");
1178 put_cnt++;
1179 if (0 == put_cnt % DELTA_INTERVAL)
1182 label,
1183 rd,
1184 rd_count,
1185 expire);
1188}

References check_zone_namestore_next(), DELTA_INTERVAL, dispatch_job(), expire, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, job_queue_length, key, note_relative_expiration(), ns_iteration_left, put_cnt, rd, rd_count, and update_velocity().

Referenced by publish_zone_dht_start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dispatch_job_monitor()

static void dispatch_job_monitor ( const struct GNUNET_CRYPTO_BlindablePrivateKey key,
const char *  label,
const struct GNUNET_GNSRECORD_Data rd,
unsigned int  rd_count,
struct GNUNET_TIME_Absolute  expire 
)
static

Store GNS records in the DHT.

Parameters
keykey of the zone
labellabel to store under
rd_publicpublic record data
rd_public_countnumber of records in rd_public

Definition at line 1234 of file gnunet-service-zonemaster.c.

1239{
1240 dispatch_job (key, label, rd, rd_count, expire);
1241}

References dispatch_job(), expire, key, rd, and rd_count.

Referenced by handle_monitor_event().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_monitor_event()

static void handle_monitor_event ( void *  cls,
const struct GNUNET_CRYPTO_BlindablePrivateKey zone,
const char *  label,
unsigned int  rd_count,
const struct GNUNET_GNSRECORD_Data rd,
struct GNUNET_TIME_Absolute  expire 
)
static

Process a record that was stored in the namestore (invoked by the monitor).

Parameters
clsclosure, NULL
zoneprivate key of the zone; NULL on disconnect
labellabel of the records; NULL on disconnect
rd_countnumber of entries in rd array, 0 if label was deleted
rdarray of records with data to store
expireexpiration of this record set

Definition at line 1256 of file gnunet-service-zonemaster.c.

1262{
1263 (void) cls;
1265 "Namestore monitor events received",
1266 1,
1267 GNUNET_NO);
1269 "Received %u records for label `%s' via namestore monitor\n",
1270 rd_count,
1271 label);
1272 if (0 == rd_count)
1273 {
1275 1);
1276 return; /* nothing to do */
1277 }
1279 rd_count);
1281 <,
1283 (NULL == namestore_iter) &&
1284 (NULL != zone_publish_task) )
1285 {
1286 /* This record set expires sooner than anything we saw while
1287 iterating, so the next iteration -- which is what republishes it --
1288 has to happen sooner than the one we scheduled back then. Without
1289 this a record with a lifetime below
1290 #MAXIMUM_ZONE_ITERATION_INTERVAL is gone from the DHT long before
1291 it is put there again. */
1298 NULL);
1299 }
1301 label,
1302 rd,
1303 rd_count,
1304 expire);
1307 {
1309 "Job queue length exceeded (%u/%u). Halting monitor.\n",
1313 return;
1314 }
1316 1);
1317}

References calculate_put_interval(), dispatch_job_monitor(), expire, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_NAMESTORE_zone_monitor_next(), GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), GNUNET_TIME_relative_cmp, GNUNET_YES, job_queue_length, JOB_QUEUE_LIMIT, last_min_relative_record_time, min_relative_record_time, monitor_halted, namestore_iter, note_relative_expiration(), publish_zone_dht_start(), rd, rd_count, statistics, target_iteration_velocity_per_record, zmon, and zone_publish_task.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_monitor_error()

static void handle_monitor_error ( void *  cls)
static

The zone monitor encountered an IPC error trying to to get in sync.

Restart from the beginning.

Parameters
clsNULL

Definition at line 1327 of file gnunet-service-zonemaster.c.

1328{
1329 (void) cls;
1331 "Namestore monitor errors encountered",
1332 1,
1333 GNUNET_NO);
1334}

References GNUNET_NO, GNUNET_STATISTICS_update(), and statistics.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sign_worker()

static void * sign_worker ( void *  cls)
static

Definition at line 1338 of file gnunet-service-zonemaster.c.

1339{
1340 struct RecordPublicationJob *job;
1341 const struct GNUNET_DISK_FileHandle *fh;
1342
1344 while (GNUNET_YES != in_shutdown)
1345 {
1346 GNUNET_assert (0 == pthread_mutex_lock (&sign_jobs_lock));
1347 while (NULL == sign_jobs_head)
1348 GNUNET_assert (0 == pthread_cond_wait (&sign_jobs_cond, &sign_jobs_lock));
1349 if (GNUNET_YES == in_shutdown)
1350 {
1351 GNUNET_assert (0 == pthread_mutex_unlock (&sign_jobs_lock));
1352 return NULL;
1353 }
1355 "Taking on Job for %s\n", sign_jobs_head->label);
1358 GNUNET_assert (0 == pthread_mutex_unlock (&sign_jobs_lock));
1359 job->ec->seal (job->ec->cls,
1360 job->label,
1361 job->expire_pub,
1362 job->rdata_pub,
1363 job->rdata_pub_len,
1364 &job->block_pub);
1365 if (job->rdata_pub != job->rdata_priv)
1366 job->ec->seal (job->ec->cls,
1367 job->label,
1368 job->expire_priv,
1369 job->rdata_priv,
1370 job->rdata_priv_len,
1371 &job->block_priv);
1372 else
1373 job->block_priv = job->block_pub;
1374 GNUNET_assert (0 == pthread_mutex_lock (&sign_results_lock));
1376 GNUNET_assert (0 == pthread_mutex_unlock (&sign_results_lock));
1378 "Done, notifying main thread through pipe!\n");
1379 GNUNET_DISK_file_write (fh, "!", 1);
1380 }
1381 return NULL;
1382}

References GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_DISK_file_write(), GNUNET_DISK_PIPE_END_WRITE, GNUNET_DISK_pipe_handle(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_YES, in_shutdown, job, RecordPublicationJob::label, notification_pipe, sign_jobs_cond, sign_jobs_head, sign_jobs_lock, sign_jobs_tail, sign_results_head, sign_results_lock, and sign_results_tail.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ run()

static void run ( void *  cls,
const struct GNUNET_CONFIGURATION_Handle c,
struct GNUNET_SERVICE_Handle service 
)
static

Perform zonemaster duties: watch namestore, publish records.

Parameters
clsclosure
serverthe initialized server
cconfiguration to use

Start worker

Definition at line 1402 of file gnunet-service-zonemaster.c.

1405{
1406 unsigned long long max_parallel_bg_queries = 128;
1407 const struct GNUNET_DISK_FileHandle *np_fh;
1408
1409 (void) cls;
1410 (void) service;
1411 pthread_mutex_init (&sign_jobs_lock, NULL);
1412 pthread_mutex_init (&sign_results_lock, NULL);
1413 pthread_cond_init (&sign_jobs_cond, NULL);
1414 last_put_100 = GNUNET_TIME_absolute_get (); /* first time! */
1419 if (NULL == namestore_handle)
1420 {
1422 _ ("Failed to connect to the namestore!\n"));
1424 return;
1425 }
1427 "namecache",
1428 "DISABLE");
1430 {
1432 if (NULL == namecache)
1433 {
1435 _ ("Failed to connect to the namecache!\n"));
1437 return;
1438 }
1439 }
1441 "namestore",
1442 "CACHE_KEYS");
1444 if (GNUNET_OK ==
1446 "zonemaster",
1447 "ZONE_PUBLISH_TIME_WINDOW",
1449 {
1451 "Time window for zone iteration: %s\n",
1454 GNUNET_YES));
1455 }
1457 if (GNUNET_OK ==
1459 "zonemaster",
1460 "MAX_PARALLEL_BACKGROUND_QUERIES",
1461 &max_parallel_bg_queries))
1462 {
1464 "Number of allowed parallel background queries: %llu\n",
1465 max_parallel_bg_queries);
1466 }
1467 if (0 == max_parallel_bg_queries)
1468 max_parallel_bg_queries = 1;
1470 (unsigned int) max_parallel_bg_queries);
1471 if (NULL == dht_handle)
1472 {
1474 _ ("Could not connect to DHT!\n"));
1476 NULL);
1477 return;
1478 }
1479
1480 /* Schedule periodic put for our records. */
1482 statistics = GNUNET_STATISTICS_create ("zonemaster",
1483 c);
1485 "Target zone iteration velocity (μs)",
1487 GNUNET_NO);
1489 NULL);
1491 NULL,
1492 GNUNET_NO,
1494 NULL,
1496 NULL,
1497 NULL /* sync_cb */,
1498 NULL,
1502 GNUNET_break (NULL != zmon);
1503
1505 NULL);
1506
1508 np_fh = GNUNET_DISK_pipe_handle (
1512 np_fh,
1513 notification_pipe_cb, NULL);
1514
1515 {
1516 long long unsigned int worker_count = 1;
1517 if (GNUNET_OK !=
1519 "zonemaster",
1520 "WORKER_COUNT",
1521 &worker_count))
1522 {
1524 "Number of workers not defined falling back to 1\n");
1525 }
1526 worker = GNUNET_malloc (sizeof (pthread_t) * worker_count);
1528 for (int i = 0; i < worker_count; i++)
1529 {
1530 if (0 !=
1531 pthread_create (&worker[i],
1532 NULL,
1533 &sign_worker,
1534 NULL))
1535 {
1537 "pthread_create");
1539 }
1541 "Workers running",
1542 1,
1543 GNUNET_NO);
1544 }
1545 }
1546}

References _, cache_keys, dht_handle, disable_namecache, first_zone_iteration, GNUNET_break, GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_time(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_DHT_connect(), GNUNET_DHT_DEFAULT_REPUBLISH_FREQUENCY, GNUNET_DISK_PF_NONE, GNUNET_DISK_pipe(), GNUNET_DISK_PIPE_END_READ, GNUNET_DISK_pipe_handle(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_GNSRECORD_FILTER_NONE, GNUNET_log, GNUNET_log_strerror, GNUNET_malloc, GNUNET_NAMECACHE_connect(), GNUNET_NAMESTORE_connect(), GNUNET_NAMESTORE_zone_monitor_next(), GNUNET_NAMESTORE_zone_monitor_start2(), GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_add_read_file(), GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), GNUNET_STATISTICS_create(), GNUNET_STATISTICS_set(), GNUNET_STATISTICS_update(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, handle_monitor_error(), handle_monitor_event(), INITIAL_ZONE_ITERATION_INTERVAL, last_put_100, min_relative_record_time, namecache, namestore_handle, NAMESTORE_MONITOR_QUEUE_LIMIT, notification_pipe, notification_pipe_cb(), pipe_read_task, publish_zone_dht_start(), GNUNET_TIME_Relative::rel_value_us, service, shutdown_task, sign_jobs_cond, sign_jobs_lock, sign_results_lock, sign_worker(), statistics, target_iteration_velocity_per_record, worker, zmon, zone_publish_task, zone_publish_time_window, and zone_publish_time_window_default.

Here is the call graph for this function:

◆ GNUNET_SERVICE_MAIN()

GNUNET_SERVICE_MAIN ( GNUNET_OS_project_data_gnunet()  ,
"zonemaster"  ,
GNUNET_SERVICE_OPTION_NONE  ,
run,
NULL  ,
NULL  ,
NULL  ,
GNUNET_MQ_handler_end()   
)

Define "main" method using service macro.

Variable Documentation

◆ worker

pthread_t* worker
static

Our workers.

Definition at line 96 of file gnunet-service-zonemaster.c.

Referenced by run().

◆ sign_jobs_lock

pthread_mutex_t sign_jobs_lock
static

Lock for the sign jobs queue.

Definition at line 101 of file gnunet-service-zonemaster.c.

Referenced by dispatch_job(), run(), shutdown_task(), and sign_worker().

◆ sign_results_lock

pthread_mutex_t sign_results_lock
static

Lock for the DHT put jobs queue.

Definition at line 106 of file gnunet-service-zonemaster.c.

Referenced by initiate_put_from_pipe_trigger(), run(), shutdown_task(), and sign_worker().

◆ sign_jobs_cond

pthread_cond_t sign_jobs_cond
static

Wait condition on new sign jobs.

Definition at line 111 of file gnunet-service-zonemaster.c.

Referenced by dispatch_job(), run(), and sign_worker().

◆ in_shutdown

int in_shutdown = GNUNET_NO
static

For threads to know we are shutting down.

Definition at line 116 of file gnunet-service-zonemaster.c.

Referenced by shutdown_task(), and sign_worker().

◆ monitor_halted

int monitor_halted = GNUNET_NO
static

Monitor halted?

Definition at line 121 of file gnunet-service-zonemaster.c.

Referenced by cleanup_job(), and handle_monitor_event().

◆ notification_pipe

struct GNUNET_DISK_PipeHandle* notification_pipe
static

Our notification pipe.

Definition at line 126 of file gnunet-service-zonemaster.c.

Referenced by initiate_put_from_pipe_trigger(), run(), shutdown_task(), and sign_worker().

◆ pipe_read_task

struct GNUNET_SCHEDULER_Task* pipe_read_task
static

Pipe read task.

Definition at line 131 of file gnunet-service-zonemaster.c.

Referenced by initiate_put_from_pipe_trigger(), run(), and shutdown_task().

◆ sign_jobs_head

struct RecordPublicationJob* sign_jobs_head
static

The DLL for workers to retrieve open jobs that require signing of blocks.

Definition at line 223 of file gnunet-service-zonemaster.c.

Referenced by dispatch_job(), shutdown_task(), and sign_worker().

◆ sign_jobs_tail

struct RecordPublicationJob* sign_jobs_tail
static

See above.

Definition at line 228 of file gnunet-service-zonemaster.c.

Referenced by dispatch_job(), shutdown_task(), and sign_worker().

◆ sign_results_head

struct RecordPublicationJob* sign_results_head
static

The DLL for workers to place jobs that are signed.

Definition at line 233 of file gnunet-service-zonemaster.c.

Referenced by initiate_put_from_pipe_trigger(), shutdown_task(), and sign_worker().

◆ sign_results_tail

struct RecordPublicationJob* sign_results_tail
static

See above.

Definition at line 238 of file gnunet-service-zonemaster.c.

Referenced by initiate_put_from_pipe_trigger(), shutdown_task(), and sign_worker().

◆ dht_jobs_head

struct RecordPublicationJob* dht_jobs_head
static

The DLL for jobs currently in the process of being dispatched into the DHT.

Definition at line 244 of file gnunet-service-zonemaster.c.

Referenced by dht_put_continuation(), initiate_put_from_pipe_trigger(), and shutdown_task().

◆ dht_jobs_tail

struct RecordPublicationJob* dht_jobs_tail
static

See above.

Definition at line 249 of file gnunet-service-zonemaster.c.

Referenced by dht_put_continuation(), initiate_put_from_pipe_trigger(), and shutdown_task().

◆ statistics

◆ dht_handle

struct GNUNET_DHT_Handle* dht_handle
static

Our handle to the DHT.

Definition at line 283 of file gnunet-service-zonemaster.c.

Referenced by initiate_put_from_pipe_trigger(), run(), and shutdown_task().

◆ namestore_handle

struct GNUNET_NAMESTORE_Handle* namestore_handle
static

Our handle to the namestore service.

Definition at line 288 of file gnunet-service-zonemaster.c.

Referenced by publish_zone_dht_start(), run(), and shutdown_task().

◆ zmon

struct GNUNET_NAMESTORE_ZoneMonitor* zmon
static

Handle to monitor namestore changes to instant propagation.

Definition at line 293 of file gnunet-service-zonemaster.c.

Referenced by cleanup_job(), handle_monitor_event(), run(), and shutdown_task().

◆ namecache

struct GNUNET_NAMECACHE_Handle* namecache
static

Our handle to the namecache service.

Definition at line 298 of file gnunet-service-zonemaster.c.

Referenced by refresh_block(), run(), and shutdown_task().

◆ disable_namecache

int disable_namecache
static

Use the namecache? Doing so creates additional cryptographic operations whenever we touch a record.

Definition at line 304 of file gnunet-service-zonemaster.c.

Referenced by refresh_block(), and run().

◆ namestore_iter

struct GNUNET_NAMESTORE_ZoneIterator* namestore_iter
static

Handle to iterate over our authoritative zone in namestore.

Definition at line 309 of file gnunet-service-zonemaster.c.

Referenced by handle_monitor_event(), publish_zone_dht_start(), publish_zone_namestore_next(), shutdown_task(), zone_iteration_error(), and zone_iteration_finished().

◆ job_queue_length

unsigned int job_queue_length
static

Number of entries in the job queue #jobs_head.

Definition at line 314 of file gnunet-service-zonemaster.c.

Referenced by check_zone_namestore_next(), cleanup_job(), dht_put_continuation(), handle_monitor_event(), handle_record(), shutdown_task(), and update_velocity().

◆ num_public_records

unsigned long long num_public_records
static

Useful for zone update for DHT put.

Definition at line 319 of file gnunet-service-zonemaster.c.

Referenced by calculate_put_interval(), dispatch_job(), publish_zone_dht_start(), update_velocity(), and zone_iteration_finished().

◆ last_num_public_records

unsigned long long last_num_public_records
static

◆ put_cnt

unsigned long long put_cnt
static

Number of successful put operations performed in the current measurement cycle (as measured in check_zone_namestore_next()).

Definition at line 330 of file gnunet-service-zonemaster.c.

Referenced by check_zone_namestore_next(), and handle_record().

◆ target_iteration_velocity_per_record

struct GNUNET_TIME_Relative target_iteration_velocity_per_record
static

What is the frequency at which we currently would like to perform DHT puts (per record)? Calculated in update_velocity() from the zone_publish_time_window() and the total number of record sets we have (so far) observed in the zone.

Definition at line 339 of file gnunet-service-zonemaster.c.

Referenced by calculate_put_interval(), check_zone_namestore_next(), handle_monitor_event(), run(), update_velocity(), and zone_iteration_finished().

◆ min_relative_record_time

struct GNUNET_TIME_Relative min_relative_record_time
static

Minimum relative expiration time of records seem during the current zone iteration.

Definition at line 345 of file gnunet-service-zonemaster.c.

Referenced by calculate_put_interval(), handle_monitor_event(), note_relative_expiration(), run(), and zone_iteration_finished().

◆ last_min_relative_record_time

struct GNUNET_TIME_Relative last_min_relative_record_time
static

Minimum relative expiration time of records seem during the last zone iteration.

Definition at line 351 of file gnunet-service-zonemaster.c.

Referenced by calculate_put_interval(), handle_monitor_event(), and zone_iteration_finished().

◆ zone_publish_time_window_default

struct GNUNET_TIME_Relative zone_publish_time_window_default
static

Default time window for zone iteration.

Definition at line 356 of file gnunet-service-zonemaster.c.

Referenced by calculate_put_interval(), and run().

◆ zone_publish_time_window

struct GNUNET_TIME_Relative zone_publish_time_window
static

Time window for zone iteration, adjusted based on relative record expiration times in our zone.

Definition at line 362 of file gnunet-service-zonemaster.c.

Referenced by calculate_put_interval(), check_zone_namestore_next(), and run().

◆ last_put_100

struct GNUNET_TIME_Absolute last_put_100
static

When did we last start measuring the DELTA_INTERVAL successful DHT puts? Used for velocity calculations.

Definition at line 368 of file gnunet-service-zonemaster.c.

Referenced by run(), and update_velocity().

◆ sub_delta

struct GNUNET_TIME_Relative sub_delta
static

By how much should we try to increase our per-record iteration speed (over the desired speed calculated directly from the #put_interval)? Basically this value corresponds to the per-record CPU time overhead we have.

Definition at line 376 of file gnunet-service-zonemaster.c.

Referenced by check_zone_namestore_next(), and update_velocity().

◆ zone_publish_task

◆ ns_iteration_left

unsigned int ns_iteration_left
static

How many more values are left for the current query before we need to explicitly ask the namestore for more?

Definition at line 387 of file gnunet-service-zonemaster.c.

Referenced by check_zone_namestore_next(), handle_record(), publish_zone_dht_start(), and publish_zone_namestore_next().

◆ first_zone_iteration

int first_zone_iteration
static

GNUNET_YES if zone has never been published before

Definition at line 392 of file gnunet-service-zonemaster.c.

Referenced by check_zone_namestore_next(), run(), update_velocity(), and zone_iteration_finished().

◆ cache_keys

int cache_keys
static

Optimize block insertion by caching map of private keys to public keys in memory?

Definition at line 398 of file gnunet-service-zonemaster.c.

Referenced by run().

◆ cop_head

struct CacheOperation* cop_head
static

Head of cop DLL.

Definition at line 403 of file gnunet-service-zonemaster.c.

Referenced by finish_cache_operation(), refresh_block(), and shutdown_task().

◆ cop_tail

struct CacheOperation* cop_tail
static

Tail of cop DLL.

Definition at line 408 of file gnunet-service-zonemaster.c.

Referenced by finish_cache_operation(), refresh_block(), and shutdown_task().