GNUnet 0.28.1-dev.5-1-gae1c02d74
 
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
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}
661
662
670static void
672 unsigned int rd_count)
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}
685
686
694static void
695update_velocity (unsigned int cnt)
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}
790
791
796static void
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}
846
847
848static void
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}
869
870
875static void
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}
889
890
901static void
903 const char *label,
904 const struct GNUNET_GNSRECORD_Data *rd,
905 unsigned int rd_count,
906 const struct GNUNET_TIME_Absolute expire)
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}
983
984
985static void
986notification_pipe_cb (void *cls);
987
988static void
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}
1072
1073
1079static void
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}
1097
1098
1104static void
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}
1144
1145
1155static void
1156handle_record (void *cls,
1158 const char *label,
1159 unsigned int rd_count,
1160 const struct GNUNET_GNSRECORD_Data *rd,
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}
1189
1190
1196static void
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}
1223
1224
1233static void
1235 const char *label,
1236 const struct GNUNET_GNSRECORD_Data *rd,
1237 unsigned int rd_count,
1239{
1240 dispatch_job (key, label, rd, rd_count, expire);
1241}
1242
1243
1255static void
1257 const struct GNUNET_CRYPTO_BlindablePrivateKey *zone,
1258 const char *label,
1259 unsigned int rd_count,
1260 const struct GNUNET_GNSRECORD_Data *rd,
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}
1318
1319
1326static void
1328{
1329 (void) cls;
1331 "Namestore monitor errors encountered",
1332 1,
1333 GNUNET_NO);
1334}
1335
1336
1337static void*
1338sign_worker (void *cls)
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}
1383
1384
1385static void
1387{
1389 "Received wake up notification through pipe, checking results\n");
1391}
1392
1393
1401static void
1402run (void *cls,
1403 const struct GNUNET_CONFIGURATION_Handle *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}
1547
1548
1554 "zonemaster",
1556 &run,
1557 NULL,
1558 NULL,
1559 NULL,
1561
1562
1563/* 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.
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_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).
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.