GNUnet 0.28.0-dev.3-7-g31e20e2e6
 
Loading...
Searching...
No Matches
gnunet-service-zonemaster.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012, 2013, 2014, 2017, 2018 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
26#include "platform.h"
27#include <pthread.h>
28#include "gnunet_util_lib.h"
29#include "gnunet_dht_service.h"
33
34#define LOG_STRERROR_FILE(kind, syscall, \
35 filename) GNUNET_log_from_strerror_file (kind, "util", \
36 syscall, \
37 filename)
38
39
44#define PUBLISH_OPS_PER_EXPIRATION 4
45
51#define DELTA_INTERVAL 100
52
56#define NS_BLOCK_SIZE 1000
57
61#define JOB_QUEUE_LIMIT 5000
62
67#define NAMESTORE_MONITOR_QUEUE_LIMIT 5
68
73#define INITIAL_ZONE_ITERATION_INTERVAL GNUNET_TIME_UNIT_MILLISECONDS
74
79#define MAXIMUM_ZONE_ITERATION_INTERVAL GNUNET_TIME_relative_multiply ( \
80 GNUNET_TIME_UNIT_MINUTES, 15)
81
86#define LATE_ITERATION_SPEEDUP_FACTOR 2
87
91#define DHT_GNS_REPLICATION_LEVEL 5
92
96static pthread_t * worker;
97
101static pthread_mutex_t sign_jobs_lock;
102
106static pthread_mutex_t sign_results_lock;
107
111static pthread_cond_t sign_jobs_cond;
112
117
122
127
132
217
218
224
229
234
239
240
245
250
251
256{
261
266
271
272};
273
274
279
284
289
294
299
305
310
314static unsigned int job_queue_length;
315
319static unsigned long long num_public_records;
320
324static unsigned long long last_num_public_records;
325
330static unsigned long long put_cnt;
331
340
346
352
357
363
369
377
382
387static unsigned int ns_iteration_left;
388
393
398static int cache_keys;
399
404
409
410
411static void
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}
429
430
437static void
438shutdown_task (void *cls)
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}
524
525
533static void
534finish_cache_operation (void *cls, int32_t success, const char *emsg)
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}
547
548
557static void
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}
583
584
590static void
601
602
608static void
609publish_zone_dht_start (void *cls);
610
611
615static void
658
659
667static void
668update_velocity (unsigned int cnt)
669{
671 unsigned long long pct = 0;
672
673 if (0 == cnt)
674 return;
675 /* How fast were we really? */
677 delta.rel_value_us /= cnt;
679
680 /* calculate expected frequency */
683 {
685 "Last record count was lower than current record count. Reducing interval.\n");
689 }
691 "Desired global zone iteration interval is %s/record!\n",
694 GNUNET_YES));
695
696 /* Tell statistics actual vs. desired speed */
698 "Current zone iteration velocity (μs/record)",
700 GNUNET_NO);
701 /* update "sub_delta" based on difference, taking
702 previous sub_delta into account! */
704 {
705 /* We were too fast, reduce sub_delta! */
706 struct GNUNET_TIME_Relative corr;
707
709 delta);
711 {
712 /* Reduce sub_delta by corr */
714 corr);
715 }
716 else
717 {
718 /* We're doing fine with waiting the full time, this
719 should theoretically only happen if we run at
720 infinite speed. */
722 }
723 }
726 {
727 /* We were too slow, increase sub_delta! */
728 struct GNUNET_TIME_Relative corr;
729
733 corr);
736 {
737 /* CPU overload detected, we cannot go at desired speed,
738 as this would mean using a negative delay. */
739 /* compute how much faster we would want to be for
740 the desired velocity */
742 pct = UINT64_MAX; /* desired speed is infinity ... */
743 else
748 }
749 }
751 "# dispatched jobs",
753 GNUNET_NO);
755 "% speed increase needed for target velocity",
756 pct,
757 GNUNET_NO);
759 "# records processed in current iteration",
761 GNUNET_NO);
762}
763
764
769static void
771{
772 struct GNUNET_TIME_Relative delay;
773
774 if (0 != ns_iteration_left)
775 return; /* current NAMESTORE iteration not yet done */
777 {
779 "Job queue length exceeded (%u/%u). Pausing namestore iteration.\n",
782 return;
783 }
785 put_cnt = 0;
787 sub_delta);
788 /* We delay *once* per #NS_BLOCK_SIZE, so we need to multiply the
789 per-record delay calculated so far with the #NS_BLOCK_SIZE */
791 "Current artificial NAMESTORE delay (μs/record)",
792 delay.rel_value_us,
793 GNUNET_NO);
794 delay = GNUNET_TIME_relative_multiply (delay,
796 /* make sure we do not overshoot because of the #NS_BLOCK_SIZE factor */
798 delay);
799 /* no delays on first iteration */
801 delay = GNUNET_TIME_UNIT_ZERO;
805 ,
806 NULL);
807}
808
809
810static void
812{
813
814 if (NULL == zone_publish_task)
817 {
819 {
821 "Job queue emptied (%u/%u). Resuming monitor.\n",
826 }
827 }
829 free_job (job);
830}
831
832
837static void
839{
840 struct RecordPublicationJob *job = cls;
841
843 "PUT complete; Pending jobs: %u\n", job_queue_length - 1);
844 /* When we just fall under the limit, trigger monitor/iterator again
845 * if halted. We can only safely trigger one, prefer iterator. */
848 job);
850}
851
852
863static void
865 const char *label,
866 const struct GNUNET_GNSRECORD_Data *rd,
867 unsigned int rd_count,
868 const struct GNUNET_TIME_Absolute expire)
869{
870 struct GNUNET_GNSRECORD_Data rd_public[rd_count];
871 struct GNUNET_TIME_Absolute expire_pub;
873 unsigned char *rdata_public;
874 unsigned char *rdata_priv;
875 size_t rdata_public_len;
876 size_t rdata_private_len;
877 unsigned int rd_public_count = 0;
878 char *emsg;
879
880 if (GNUNET_OK !=
882 rd,
883 rd_count,
884 rd_public,
885 &rd_public_count,
886 &expire_pub,
888 &emsg))
889 {
891 "%s\n", emsg);
892 GNUNET_free (emsg);
893 }
894
895 rdata_public_len = GNUNET_GNSRECORD_records_get_size (rd_public_count,
896 rd_public);
897
898 rdata_private_len = GNUNET_GNSRECORD_records_get_size (rd_count,
899 rd);
900
901 rdata_public = GNUNET_malloc (rdata_public_len);
903 rd_public_count,
904 rd_public,
905 rdata_public,
906 rdata_public_len));
907 if (rd_count != rd_public_count)
908 {
909 rdata_priv = GNUNET_malloc (rdata_private_len);
911 rd_count,
912 rd,
914 rdata_private_len));
915 }
916 else
917 {
918 rdata_priv = rdata_public;
919 }
920 GNUNET_assert (0 == pthread_mutex_lock (&sign_jobs_lock));
922 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Public record count: %d\n",
923 rd_public_count);
924 job->have_public_records = (rd_public_count > 0);
925 job->rdata_pub = rdata_public;
926 job->rdata_pub_len = rdata_public_len;
927 job->rdata_priv = rdata_priv;
928 job->rdata_priv_len = rdata_private_len;
929 job->zone = *key;
930 job->label = GNUNET_strdup (label);
931 job->expire_pub = expire_pub;
932 job->expire_priv = expire;
935 GNUNET_assert (0 == pthread_cond_signal (&sign_jobs_cond));
936 GNUNET_assert (0 == pthread_mutex_unlock (&sign_jobs_lock));
938 "Creating job with %u record(s) for label `%s', expiration `%s'\n",
939 rd_public_count,
940 label,
943 return;
944}
945
946
947static void
948notification_pipe_cb (void *cls);
949
950static void
952{
953 struct GNUNET_HashCode query;
955 const struct GNUNET_DISK_FileHandle *np_fh;
956 char buf[100];
957 ssize_t nf_count;
958
959 pipe_read_task = NULL;
965 np_fh,
967 NULL);
968 /* empty queue */
969 nf_count = GNUNET_DISK_file_read (np_fh, buf, sizeof (buf));
970 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Read %lld notifications from pipe\n",
971 (long long) nf_count);
972 while (true)
973 {
974 GNUNET_assert (0 == pthread_mutex_lock (&sign_results_lock));
975 if (NULL == sign_results_head)
976 {
978 "No more results. Back to sleep.\n");
979 GNUNET_assert (0 == pthread_mutex_unlock (&sign_results_lock));
980 return;
981 }
984 GNUNET_assert (0 == pthread_mutex_unlock (&sign_results_lock));
986 job->label,
987 &query);
988 // It is possible that the public block size is 0 (no public blocks)
989 // Do not bother with the DHT in that case
990 if (job->have_public_records)
991 {
992 size_t block_size = GNUNET_GNSRECORD_block_get_size (job->block_pub);
994 &query,
998 block_size,
999 job->block_pub,
1000 job->expire_pub,
1002 job);
1003 if (NULL == job->ph)
1004 {
1006 "Could not perform DHT PUT, is the DHT running?\n");
1007 free_job (job);
1008 return;
1009 }
1011 "DHT put operations initiated",
1012 1,
1013 GNUNET_NO);
1015 "Storing record(s) for label `%s' in DHT under key %s\n",
1016 job->label,
1017 GNUNET_h2s (&query));
1018 refresh_block (job->block_priv);
1020 }
1021 else
1022 {
1023 // Private blocks may still be available and must be updated
1024 // in the cache
1025 refresh_block (job->block_priv);
1026 cleanup_job (job);
1027 }
1028 }
1029}
1030
1031
1037static void
1039{
1040 (void) cls;
1042 "Got disconnected from namestore database, retrying.\n");
1043 namestore_iter = NULL;
1044 /* We end up here on error/disconnect/shutdown, so potentially
1045 while a zone publish task or a DHT put is still running; hence
1046 we need to cancel those. */
1047 if (NULL != zone_publish_task)
1048 {
1050 zone_publish_task = NULL;
1051 }
1053 NULL);
1054}
1055
1056
1062static void
1064{
1065 (void) cls;
1066 /* we're done with one iteration, calculate when to do the next one */
1067 namestore_iter = NULL;
1072 /* reset for next iteration */
1076 "Zone iteration finished. Adjusted zone iteration interval to %s\n",
1079 GNUNET_YES));
1081 "Target zone iteration velocity (μs)",
1083 GNUNET_NO);
1085 "Number of public records in DHT",
1087 GNUNET_NO);
1089 if (0 == last_num_public_records)
1090 {
1094 NULL);
1095 }
1096 else
1097 {
1099 NULL);
1100 }
1101}
1102
1103
1113static void
1114handle_record (void *cls,
1116 const char *label,
1117 unsigned int rd_count,
1118 const struct GNUNET_GNSRECORD_Data *rd,
1120{
1121 (void) cls;
1123 if (0 == rd_count)
1124 {
1126 "Record set empty, moving to next record set\n");
1128 return;
1129 }
1130 for (unsigned int i = 0; i < rd_count; i++)
1131 {
1132 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
1133 {
1134 /* GNUNET_GNSRECORD_block_create will convert to absolute time;
1135 we just need to adjust our iteration frequency */
1137 GNUNET_MIN (rd[i].expiration_time,
1139 }
1140 }
1141
1142
1143 /* We got a set of records to publish */
1145 "Starting DHT PUT\n");
1146 put_cnt++;
1147 if (0 == put_cnt % DELTA_INTERVAL)
1150 label,
1151 rd,
1152 rd_count,
1153 expire);
1156}
1157
1158
1164static void
1166{
1167 (void) cls;
1168 zone_publish_task = NULL;
1170 "Full zone iterations launched",
1171 1,
1172 GNUNET_NO);
1174 "Starting DHT zone update!\n");
1175 /* start counting again */
1177 GNUNET_assert (NULL == namestore_iter);
1181 NULL, /* All zones */
1183 NULL,
1185 NULL,
1187 NULL,
1189 GNUNET_assert (NULL != namestore_iter);
1190}
1191
1192
1201static void
1203 const char *label,
1204 const struct GNUNET_GNSRECORD_Data *rd,
1205 unsigned int rd_count,
1207{
1208 dispatch_job (key, label, rd, rd_count, expire);
1209}
1210
1211
1223static void
1225 const struct GNUNET_CRYPTO_BlindablePrivateKey *zone,
1226 const char *label,
1227 unsigned int rd_count,
1228 const struct GNUNET_GNSRECORD_Data *rd,
1230{
1231 (void) cls;
1233 "Namestore monitor events received",
1234 1,
1235 GNUNET_NO);
1237 "Received %u records for label `%s' via namestore monitor\n",
1238 rd_count,
1239 label);
1240 if (0 == rd_count)
1241 {
1243 1);
1244 return; /* nothing to do */
1245 }
1247 label,
1248 rd,
1249 rd_count,
1250 expire);
1253 {
1255 "Job queue length exceeded (%u/%u). Halting monitor.\n",
1259 return;
1260 }
1262 1);
1263}
1264
1265
1272static void
1274{
1275 (void) cls;
1277 "Namestore monitor errors encountered",
1278 1,
1279 GNUNET_NO);
1280}
1281
1282
1283static void*
1284sign_worker (void *cls)
1285{
1286 struct RecordPublicationJob *job;
1287 const struct GNUNET_DISK_FileHandle *fh;
1288
1290 while (GNUNET_YES != in_shutdown)
1291 {
1292 GNUNET_assert (0 == pthread_mutex_lock (&sign_jobs_lock));
1293 while (NULL == sign_jobs_head)
1294 GNUNET_assert (0 == pthread_cond_wait (&sign_jobs_cond, &sign_jobs_lock));
1295 if (GNUNET_YES == in_shutdown)
1296 {
1297 GNUNET_assert (0 == pthread_mutex_unlock (&sign_jobs_lock));
1298 return NULL;
1299 }
1301 "Taking on Job for %s\n", sign_jobs_head->label);
1304 GNUNET_assert (0 == pthread_mutex_unlock (&sign_jobs_lock));
1305 job->ec->seal (job->ec->cls,
1306 job->label,
1307 job->expire_pub,
1308 job->rdata_pub,
1309 job->rdata_pub_len,
1310 &job->block_pub);
1311 if (job->rdata_pub != job->rdata_priv)
1312 job->ec->seal (job->ec->cls,
1313 job->label,
1314 job->expire_priv,
1315 job->rdata_priv,
1316 job->rdata_priv_len,
1317 &job->block_priv);
1318 else
1319 job->block_priv = job->block_pub;
1320 GNUNET_assert (0 == pthread_mutex_lock (&sign_results_lock));
1322 GNUNET_assert (0 == pthread_mutex_unlock (&sign_results_lock));
1324 "Done, notifying main thread through pipe!\n");
1325 GNUNET_DISK_file_write (fh, "!", 1);
1326 }
1327 return NULL;
1328}
1329
1330
1331static void
1333{
1335 "Received wake up notification through pipe, checking results\n");
1337}
1338
1339
1347static void
1348run (void *cls,
1349 const struct GNUNET_CONFIGURATION_Handle *c,
1351{
1352 unsigned long long max_parallel_bg_queries = 128;
1353 const struct GNUNET_DISK_FileHandle *np_fh;
1354
1355 (void) cls;
1356 (void) service;
1357 pthread_mutex_init (&sign_jobs_lock, NULL);
1358 pthread_mutex_init (&sign_results_lock, NULL);
1359 pthread_cond_init (&sign_jobs_cond, NULL);
1360 last_put_100 = GNUNET_TIME_absolute_get (); /* first time! */
1365 if (NULL == namestore_handle)
1366 {
1368 _ ("Failed to connect to the namestore!\n"));
1370 return;
1371 }
1373 "namecache",
1374 "DISABLE");
1376 {
1378 if (NULL == namecache)
1379 {
1381 _ ("Failed to connect to the namecache!\n"));
1383 return;
1384 }
1385 }
1387 "namestore",
1388 "CACHE_KEYS");
1390 if (GNUNET_OK ==
1392 "zonemaster",
1393 "ZONE_PUBLISH_TIME_WINDOW",
1395 {
1397 "Time window for zone iteration: %s\n",
1400 GNUNET_YES));
1401 }
1403 if (GNUNET_OK ==
1405 "zonemaster",
1406 "MAX_PARALLEL_BACKGROUND_QUERIES",
1407 &max_parallel_bg_queries))
1408 {
1410 "Number of allowed parallel background queries: %llu\n",
1411 max_parallel_bg_queries);
1412 }
1413 if (0 == max_parallel_bg_queries)
1414 max_parallel_bg_queries = 1;
1416 (unsigned int) max_parallel_bg_queries);
1417 if (NULL == dht_handle)
1418 {
1420 _ ("Could not connect to DHT!\n"));
1422 NULL);
1423 return;
1424 }
1425
1426 /* Schedule periodic put for our records. */
1428 statistics = GNUNET_STATISTICS_create ("zonemaster",
1429 c);
1431 "Target zone iteration velocity (μs)",
1433 GNUNET_NO);
1435 NULL);
1437 NULL,
1438 GNUNET_NO,
1440 NULL,
1442 NULL,
1443 NULL /* sync_cb */,
1444 NULL,
1448 GNUNET_break (NULL != zmon);
1449
1451 NULL);
1452
1454 np_fh = GNUNET_DISK_pipe_handle (
1458 np_fh,
1459 notification_pipe_cb, NULL);
1460
1461 {
1462 long long unsigned int worker_count = 1;
1463 if (GNUNET_OK !=
1465 "zonemaster",
1466 "WORKER_COUNT",
1467 &worker_count))
1468 {
1470 "Number of workers not defined falling back to 1\n");
1471 }
1472 worker = GNUNET_malloc (sizeof (pthread_t) * worker_count);
1474 for (int i = 0; i < worker_count; i++)
1475 {
1476 if (0 !=
1477 pthread_create (&worker[i],
1478 NULL,
1479 &sign_worker,
1480 NULL))
1481 {
1483 "pthread_create");
1485 }
1487 "Workers running",
1488 1,
1489 GNUNET_NO);
1490 }
1491 }
1492}
1493
1494
1500 "zonemaster",
1502 &run,
1503 NULL,
1504 NULL,
1505 NULL,
1507
1508
1509/* 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 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.
API to the DHT service.
API that can be used to store naming information on a GNUnet node.
API that can be used to store naming information on a GNUnet node;.
API to create, modify and access statistics.
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_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
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).
Handle used to manage a pipe.
Definition disk.c:69
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.
struct GNUNET_DHT_PutHandle * ph
Handle for the DHT PUT operation.
struct GNUNET_GNSRECORD_Block * block_pub
The block to put into the DHT.
size_t rdata_priv_len
The size of the private RDATA.
struct GNUNET_TIME_Absolute expire_priv
The expiration time of the private RDATA for the DHT put.
unsigned char * rdata_priv
The private RDATA to sign, may point to block in case the public and private blocks are the same.
size_t rdata_pub_len
The size of the public RDATA.
struct GNUNET_TIME_Absolute start_date
When was this PUT initiated?
int have_public_records
Do we have any public records at all?
struct RecordPublicationJob * prev
DLL.
char * label
The label of the block needed for signing.
unsigned char * rdata_pub
The public RDATA to sign.
struct GNUNET_TIME_Absolute expire_pub
The expiration time of the public RDATA for the DHT put.
struct GNUNET_GNSRECORD_Block * block_priv
The block to refresh in the private namecache.
struct GNUNET_GNSRECORD_EncryptionContext * ec
Sign context.
struct GNUNET_CRYPTO_BlindablePrivateKey zone
The zone key to sign the block with.