From 37f81821bc98f2342185a4bec3de044000be3596 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Tue, 18 Oct 2022 15:30:28 +0900 Subject: ZONEMASTER: Merge monitor into zonemaster process --- src/zonemaster/Makefile.am | 16 +- src/zonemaster/gnunet-service-zonemaster-monitor.c | 612 --------------------- src/zonemaster/gnunet-service-zonemaster.c | 283 +++++++++- src/zonemaster/zonemaster.conf.in | 18 - 4 files changed, 277 insertions(+), 652 deletions(-) delete mode 100644 src/zonemaster/gnunet-service-zonemaster-monitor.c (limited to 'src/zonemaster') diff --git a/src/zonemaster/Makefile.am b/src/zonemaster/Makefile.am index 90b70f58a..ef82fc19b 100644 --- a/src/zonemaster/Makefile.am +++ b/src/zonemaster/Makefile.am @@ -16,8 +16,7 @@ if USE_COVERAGE endif libexec_PROGRAMS = \ - gnunet-service-zonemaster \ - gnunet-service-zonemaster-monitor + gnunet-service-zonemaster gnunet_service_zonemaster_SOURCES = \ gnunet-service-zonemaster.c @@ -30,16 +29,3 @@ gnunet_service_zonemaster_LDADD = \ $(top_builddir)/src/namestore/libgnunetnamestore.la \ $(top_builddir)/src/namecache/libgnunetnamecache.la \ $(GN_LIBINTL) - - -gnunet_service_zonemaster_monitor_SOURCES = \ - gnunet-service-zonemaster-monitor.c -gnunet_service_zonemaster_monitor_LDADD = \ - $(top_builddir)/src/dht/libgnunetdht.la \ - $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ - $(top_builddir)/src/identity/libgnunetidentity.la \ - $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/namestore/libgnunetnamestore.la \ - $(top_builddir)/src/namecache/libgnunetnamecache.la \ - $(GN_LIBINTL) diff --git a/src/zonemaster/gnunet-service-zonemaster-monitor.c b/src/zonemaster/gnunet-service-zonemaster-monitor.c deleted file mode 100644 index fae97cb96..000000000 --- a/src/zonemaster/gnunet-service-zonemaster-monitor.c +++ /dev/null @@ -1,612 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2012, 2013, 2014, 2017, 2018 GNUnet e.V. - - GNUnet is free software: you can redistribute it and/or modify it - under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - SPDX-License-Identifier: AGPL3.0-or-later - */ - -/** - * @file zonemaster/gnunet-service-zonemaster-monitor.c - * @brief monitor namestore changes and publish them immediately to GNUnet name system - * @author Christian Grothoff - */ -#include "platform.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" - -#define LOG_STRERROR_FILE(kind, syscall, \ - filename) GNUNET_log_from_strerror_file (kind, "util", \ - syscall, \ - filename) - - -/** - * How often should we (re)publish each record before - * it expires? - */ -#define PUBLISH_OPS_PER_EXPIRATION 4 - -/** - * How many pending DHT operations do we allow at most? - */ -#define DHT_QUEUE_LIMIT 2000 - -/** - * How many events may the namestore give us before it has to wait - * for us to keep up? - */ -#define NAMESTORE_QUEUE_LIMIT 5 - -/** - * What replication level do we use for DHT PUT operations? - */ -#define DHT_GNS_REPLICATION_LEVEL 5 - -/** - * Handle for DHT PUT activity triggered from the namestore monitor. - */ -struct DhtPutActivity -{ - /** - * Kept in a DLL. - */ - struct DhtPutActivity *next; - - /** - * Kept in a DLL. - */ - struct DhtPutActivity *prev; - - /** - * Handle for the DHT PUT operation. - */ - struct GNUNET_DHT_PutHandle *ph; - - /** - * When was this PUT initiated? - */ - struct GNUNET_TIME_Absolute start_date; -}; - -/** - * Pending operation on the namecache. - */ -struct CacheOperation -{ - /** - * Kept in a DLL. - */ - struct CacheOperation *prev; - - /** - * Kept in a DLL. - */ - struct CacheOperation *next; - - /** - * Handle to namecache queue. - */ - struct GNUNET_NAMECACHE_QueueEntry *qe; - -}; - - -/** - * Handle to the statistics service - */ -static struct GNUNET_STATISTICS_Handle *statistics; - -/** - * Our handle to the DHT - */ -static struct GNUNET_DHT_Handle *dht_handle; - -/** - * Our handle to the namestore service - */ -static struct GNUNET_NAMESTORE_Handle *namestore_handle; - -/** - * Handle to monitor namestore changes to instant propagation. - */ -static struct GNUNET_NAMESTORE_ZoneMonitor *zmon; - -/** - * Head of monitor activities; kept in a DLL. - */ -static struct DhtPutActivity *ma_head; - -/** - * Tail of monitor activities; kept in a DLL. - */ -static struct DhtPutActivity *ma_tail; - -/** - * Our handle to the namecache service - */ -static struct GNUNET_NAMECACHE_Handle *namecache; - -/** - * Use the namecache? Doing so creates additional cryptographic - * operations whenever we touch a record. - */ -static int disable_namecache; - - -/** - * Number of entries in the DHT queue #ma_head. - */ -static unsigned int ma_queue_length; - -/** - * Optimize block insertion by caching map of private keys to - * public keys in memory? - */ -static int cache_keys; - -/** - * Head of cop DLL. - */ -static struct CacheOperation *cop_head; - -/** - * Tail of cop DLL. - */ -static struct CacheOperation *cop_tail; - - -/** - * Task run during shutdown. - * - * @param cls unused - * @param tc unused - */ -static void -shutdown_task (void *cls) -{ - struct DhtPutActivity *ma; - struct CacheOperation *cop; - - - (void) cls; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Shutting down!\n"); - while (NULL != (cop = cop_head)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Aborting incomplete namecache operation\n"); - GNUNET_NAMECACHE_cancel (cop->qe); - GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); - GNUNET_free (cop); - } - while (NULL != (ma = ma_head)) - { - GNUNET_DHT_put_cancel (ma->ph); - ma_queue_length--; - GNUNET_CONTAINER_DLL_remove (ma_head, - ma_tail, - ma); - GNUNET_free (ma); - } - if (NULL != statistics) - { - GNUNET_STATISTICS_destroy (statistics, - GNUNET_NO); - statistics = NULL; - } - if (NULL != zmon) - { - GNUNET_NAMESTORE_zone_monitor_stop (zmon); - zmon = NULL; - } - if (NULL != namestore_handle) - { - GNUNET_NAMESTORE_disconnect (namestore_handle); - namestore_handle = NULL; - } - if (NULL != namecache) - { - GNUNET_NAMECACHE_disconnect (namecache); - namecache = NULL; - } - if (NULL != dht_handle) - { - GNUNET_DHT_disconnect (dht_handle); - dht_handle = NULL; - } -} - -/** - * Cache operation complete, clean up. - * - * @param cls the `struct CacheOperation` - * @param success success - * @param emsg error messages - */ -static void -finish_cache_operation (void *cls, int32_t success, const char *emsg) -{ - struct CacheOperation *cop = cls; - - if (NULL != emsg) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ ("Failed to replicate block in namecache: %s\n"), - emsg); - else - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n"); - GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); - GNUNET_free (cop); -} - - -/** - * Refresh the (encrypted) block in the namecache. - * - * @param zone_key private key of the zone - * @param name label for the records - * @param rd_count number of records - * @param rd records stored under the given @a name - */ -static void -refresh_block (const struct GNUNET_GNSRECORD_Block *block) -{ - struct CacheOperation *cop; - - if (GNUNET_YES == disable_namecache) - { - GNUNET_STATISTICS_update (statistics, - "Namecache updates skipped (NC disabled)", - 1, - GNUNET_NO); - return; - } - GNUNET_assert (NULL != block); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Caching block in namecache\n"); - GNUNET_STATISTICS_update (statistics, - "Namecache updates pushed", - 1, - GNUNET_NO); - cop = GNUNET_new (struct CacheOperation); - GNUNET_CONTAINER_DLL_insert (cop_head, cop_tail, cop); - cop->qe = GNUNET_NAMECACHE_block_cache (namecache, - block, - &finish_cache_operation, - cop); -} - - - -/** - * Continuation called from DHT once the PUT operation triggered - * by a monitor is done. - * - * @param cls a `struct DhtPutActivity` - */ -static void -dht_put_monitor_continuation (void *cls) -{ - struct DhtPutActivity *ma = cls; - - GNUNET_NAMESTORE_zone_monitor_next (zmon, - 1); - ma_queue_length--; - GNUNET_CONTAINER_DLL_remove (ma_head, - ma_tail, - ma); - GNUNET_free (ma); -} - - -/** - * Store GNS records in the DHT. - * - * @param key key of the zone - * @param label label to store under - * @param rd_public public record data - * @param rd_public_count number of records in @a rd_public - * @param ma handle for the PUT operation - * @return DHT PUT handle, NULL on error - */ -static struct GNUNET_DHT_PutHandle * -perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, - const char *label, - const struct GNUNET_GNSRECORD_Data *rd, - unsigned int rd_count, - struct GNUNET_TIME_Absolute expire, - struct DhtPutActivity *ma) -{ - struct GNUNET_GNSRECORD_Data rd_public[rd_count]; - struct GNUNET_GNSRECORD_Block *block; - struct GNUNET_GNSRECORD_Block *block_priv; - struct GNUNET_HashCode query; - struct GNUNET_TIME_Absolute expire_priv; - size_t block_size; - unsigned int rd_public_count = 0; - struct GNUNET_DHT_PutHandle *ret; - char *emsg; - - if (GNUNET_OK != - GNUNET_GNSRECORD_normalize_record_set (label, - rd, - rd_count, - rd_public, - &rd_public_count, - &expire_priv, - GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE, - &emsg)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%s\n", emsg); - GNUNET_free (emsg); - } - - if (cache_keys) - GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (key, - expire, - label, - rd_public, - rd_public_count, - &block)); - else - GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (key, - expire, - label, - rd_public, - rd_public_count, - &block)); - if (NULL == block) - { - GNUNET_break (0); - return NULL; /* whoops */ - } - if (rd_count != rd_public_count) - GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (key, - expire_priv, - label, - rd, - rd_count, - &block_priv)); - else - block_priv = block; - block_size = GNUNET_GNSRECORD_block_get_size (block); - GNUNET_GNSRECORD_query_from_private_key (key, - label, - &query); - GNUNET_STATISTICS_update (statistics, - "DHT put operations initiated", - 1, - GNUNET_NO); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Storing %u record(s) for label `%s' in DHT with expiration `%s' under key %s\n", - rd_public_count, - label, - GNUNET_STRINGS_absolute_time_to_string (expire), - GNUNET_h2s (&query)); - ret = GNUNET_DHT_put (dht_handle, - &query, - DHT_GNS_REPLICATION_LEVEL, - GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, - GNUNET_BLOCK_TYPE_GNS_NAMERECORD, - block_size, - block, - expire, - &dht_put_monitor_continuation, - ma); - refresh_block (block_priv); - if (block != block_priv) - GNUNET_free (block_priv); - GNUNET_free (block); - return ret; -} - -/** - * Process a record that was stored in the namestore - * (invoked by the monitor). - * - * @param cls closure, NULL - * @param zone private key of the zone; NULL on disconnect - * @param label label of the records; NULL on disconnect - * @param rd_count number of entries in @a rd array, 0 if label was deleted - * @param rd array of records with data to store - * @param expire expiration of this record set - */ -static void -handle_monitor_event (void *cls, - const struct GNUNET_IDENTITY_PrivateKey *zone, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd, - struct GNUNET_TIME_Absolute expire) -{ - struct DhtPutActivity *ma; - - (void) cls; - GNUNET_STATISTICS_update (statistics, - "Namestore monitor events received", - 1, - GNUNET_NO); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received %u records for label `%s' via namestore monitor\n", - rd_count, - label); - if (0 == rd_count) - { - GNUNET_NAMESTORE_zone_monitor_next (zmon, - 1); - return; /* nothing to do */ - } - ma = GNUNET_new (struct DhtPutActivity); - ma->start_date = GNUNET_TIME_absolute_get (); - ma->ph = perform_dht_put (zone, - label, - rd, - rd_count, - expire, - ma); - if (NULL == ma->ph) - { - /* PUT failed, do not remember operation */ - GNUNET_free (ma); - GNUNET_NAMESTORE_zone_monitor_next (zmon, - 1); - return; - } - GNUNET_CONTAINER_DLL_insert_tail (ma_head, - ma_tail, - ma); - ma_queue_length++; - if (ma_queue_length > DHT_QUEUE_LIMIT) - { - ma = ma_head; - GNUNET_CONTAINER_DLL_remove (ma_head, - ma_tail, - ma); - GNUNET_DHT_put_cancel (ma->ph); - ma_queue_length--; - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "DHT PUT unconfirmed after %s, aborting PUT\n", - GNUNET_STRINGS_relative_time_to_string ( - GNUNET_TIME_absolute_get_duration (ma->start_date), - GNUNET_YES)); - GNUNET_free (ma); - } -} - - -/** - * The zone monitor encountered an IPC error trying to to get in - * sync. Restart from the beginning. - * - * @param cls NULL - */ -static void -handle_monitor_error (void *cls) -{ - (void) cls; - GNUNET_STATISTICS_update (statistics, - "Namestore monitor errors encountered", - 1, - GNUNET_NO); -} - - -/** - * Perform zonemaster duties: watch namestore, publish records. - * - * @param cls closure - * @param server the initialized server - * @param c configuration to use - */ -static void -run (void *cls, - const struct GNUNET_CONFIGURATION_Handle *c, - struct GNUNET_SERVICE_Handle *service) -{ - unsigned long long max_parallel_bg_queries = 128; - - (void) cls; - (void) service; - namestore_handle = GNUNET_NAMESTORE_connect (c); - if (NULL == namestore_handle) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _ ("Failed to connect to the namestore!\n")); - GNUNET_SCHEDULER_shutdown (); - return; - } - disable_namecache = GNUNET_CONFIGURATION_get_value_yesno (c, - "namecache", - "DISABLE"); - if (GNUNET_NO == disable_namecache) - { - namecache = GNUNET_NAMECACHE_connect (c); - if (NULL == namecache) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _ ("Failed to connect to the namecache!\n")); - GNUNET_SCHEDULER_shutdown (); - return; - } - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ ("Namecache is disabled!\n")); - } - cache_keys = GNUNET_CONFIGURATION_get_value_yesno (c, - "namestore", - "CACHE_KEYS"); - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_number (c, - "zonemaster", - "MAX_PARALLEL_BACKGROUND_QUERIES", - &max_parallel_bg_queries)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Number of allowed parallel background queries: %llu\n", - max_parallel_bg_queries); - } - if (0 == max_parallel_bg_queries) - max_parallel_bg_queries = 1; - dht_handle = GNUNET_DHT_connect (c, - (unsigned int) max_parallel_bg_queries); - if (NULL == dht_handle) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _ ("Could not connect to DHT!\n")); - GNUNET_SCHEDULER_add_now (&shutdown_task, - NULL); - return; - } - - /* Schedule periodic put for our records. */ - statistics = GNUNET_STATISTICS_create ("zonemaster-mon", - c); - zmon = GNUNET_NAMESTORE_zone_monitor_start2 (c, - NULL, - GNUNET_NO, - &handle_monitor_error, - NULL, - &handle_monitor_event, - NULL, - NULL /* sync_cb */, - NULL, - GNUNET_GNSRECORD_FILTER_NONE); - GNUNET_NAMESTORE_zone_monitor_next (zmon, - NAMESTORE_QUEUE_LIMIT - 1); - GNUNET_break (NULL != zmon); - GNUNET_SCHEDULER_add_shutdown (&shutdown_task, - NULL); -} - - -/** - * Define "main" method using service macro. - */ -GNUNET_SERVICE_MAIN - ("zonemaster-monitor", - GNUNET_SERVICE_OPTION_NONE, - &run, - NULL, - NULL, - NULL, - GNUNET_MQ_handler_end ()); - - -/* end of gnunet-service-zonemaster-monitor.c */ diff --git a/src/zonemaster/gnunet-service-zonemaster.c b/src/zonemaster/gnunet-service-zonemaster.c index 9f5d9b47a..f5c1d781b 100644 --- a/src/zonemaster/gnunet-service-zonemaster.c +++ b/src/zonemaster/gnunet-service-zonemaster.c @@ -66,6 +66,12 @@ */ #define NAMESTORE_QUEUE_LIMIT 50 +/** + * How many events may the namestore give us before it has to wait + * for us to keep up? + */ +#define NAMESTORE_MONITOR_QUEUE_LIMIT 5 + /** * The initial interval in milliseconds btween puts in * a zone iteration @@ -154,6 +160,21 @@ static struct GNUNET_DHT_Handle *dht_handle; */ static struct GNUNET_NAMESTORE_Handle *namestore_handle; +/** + * Handle to monitor namestore changes to instant propagation. + */ +static struct GNUNET_NAMESTORE_ZoneMonitor *zmon; + +/** + * Head of monitor activities; kept in a DLL. + */ +static struct DhtPutActivity *ma_head; + +/** + * Tail of monitor activities; kept in a DLL. + */ +static struct DhtPutActivity *ma_tail; + /** * Our handle to the namecache service */ @@ -165,6 +186,11 @@ static struct GNUNET_NAMECACHE_Handle *namecache; */ static int disable_namecache; +/** + * Number of entries in the DHT queue #ma_head. + */ +static unsigned int ma_queue_length; + /** * Handle to iterate over our authoritative zone in namestore */ @@ -314,6 +340,15 @@ shutdown_task (void *cls) dht_queue_length--; GNUNET_free (ma); } + while (NULL != (ma = ma_head)) + { + GNUNET_DHT_put_cancel (ma->ph); + ma_queue_length--; + GNUNET_CONTAINER_DLL_remove (ma_head, + ma_tail, + ma); + GNUNET_free (ma); + } if (NULL != statistics) { GNUNET_STATISTICS_destroy (statistics, @@ -330,6 +365,11 @@ shutdown_task (void *cls) GNUNET_NAMESTORE_zone_iteration_stop (namestore_iter); namestore_iter = NULL; } + if (NULL != zmon) + { + GNUNET_NAMESTORE_zone_monitor_stop (zmon); + zmon = NULL; + } if (NULL != namestore_handle) { GNUNET_NAMESTORE_disconnect (namestore_handle); @@ -340,7 +380,7 @@ shutdown_task (void *cls) GNUNET_NAMECACHE_disconnect (namecache); namecache = NULL; } -if (NULL != dht_handle) + if (NULL != dht_handle) { GNUNET_DHT_disconnect (dht_handle); dht_handle = NULL; @@ -666,7 +706,7 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, struct GNUNET_GNSRECORD_Block *block; struct GNUNET_GNSRECORD_Block *block_priv; struct GNUNET_HashCode query; - struct GNUNET_TIME_Absolute expire_priv; + struct GNUNET_TIME_Absolute expire_pub; size_t block_size; unsigned int rd_public_count = 0; struct GNUNET_DHT_PutHandle *ret; @@ -678,7 +718,7 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, rd_count, rd_public, &rd_public_count, - &expire_priv, + &expire_pub, GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE, &emsg)) { @@ -690,7 +730,7 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, if (cache_keys) { GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (key, - expire, + expire_pub, label, rd_public, rd_public_count, @@ -699,7 +739,7 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, else { GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (key, - expire, + expire_pub, label, rd_public, rd_public_count, @@ -712,7 +752,7 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, } if (rd_count != rd_public_count) GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (key, - expire_priv, + expire, label, rd, rd_count, @@ -741,7 +781,7 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, GNUNET_BLOCK_TYPE_GNS_NAMERECORD, block_size, block, - expire, + expire_pub, &dht_put_continuation, ma); refresh_block (block_priv); @@ -942,6 +982,221 @@ publish_zone_dht_start (void *cls) } +/** + * Continuation called from DHT once the PUT operation triggered + * by a monitor is done. + * + * @param cls a `struct DhtPutActivity` + */ +static void +dht_put_monitor_continuation (void *cls) +{ + struct DhtPutActivity *ma = cls; + + GNUNET_NAMESTORE_zone_monitor_next (zmon, + 1); + ma_queue_length--; + GNUNET_CONTAINER_DLL_remove (ma_head, + ma_tail, + ma); + GNUNET_free (ma); +} + + +/** + * Store GNS records in the DHT. + * + * @param key key of the zone + * @param label label to store under + * @param rd_public public record data + * @param rd_public_count number of records in @a rd_public + * @param ma handle for the PUT operation + * @return DHT PUT handle, NULL on error + */ +static struct GNUNET_DHT_PutHandle * +perform_dht_put_monitor (const struct GNUNET_IDENTITY_PrivateKey *key, + const char *label, + const struct GNUNET_GNSRECORD_Data *rd, + unsigned int rd_count, + struct GNUNET_TIME_Absolute expire, + struct DhtPutActivity *ma) +{ + struct GNUNET_GNSRECORD_Data rd_public[rd_count]; + struct GNUNET_GNSRECORD_Block *block; + struct GNUNET_GNSRECORD_Block *block_priv; + struct GNUNET_HashCode query; + struct GNUNET_TIME_Absolute expire_pub; + size_t block_size; + unsigned int rd_public_count = 0; + struct GNUNET_DHT_PutHandle *ret; + char *emsg; + + if (GNUNET_OK != + GNUNET_GNSRECORD_normalize_record_set (label, + rd, + rd_count, + rd_public, + &rd_public_count, + &expire_pub, + GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE, + &emsg)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "%s\n", emsg); + GNUNET_free (emsg); + } + + if (cache_keys) + GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (key, + expire_pub, + label, + rd_public, + rd_public_count, + &block)); + else + GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (key, + expire_pub, + label, + rd_public, + rd_public_count, + &block)); + if (NULL == block) + { + GNUNET_break (0); + return NULL; /* whoops */ + } + if (rd_count != rd_public_count) + GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (key, + expire, + label, + rd, + rd_count, + &block_priv)); + else + block_priv = block; + block_size = GNUNET_GNSRECORD_block_get_size (block); + GNUNET_GNSRECORD_query_from_private_key (key, + label, + &query); + GNUNET_STATISTICS_update (statistics, + "DHT put operations initiated", + 1, + GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Storing %u public of %u record(s) for label `%s' in DHT with expiration `%s' under key %s\n", + rd_public_count, + rd_count, + label, + GNUNET_STRINGS_absolute_time_to_string (expire), + GNUNET_h2s (&query)); + ret = GNUNET_DHT_put (dht_handle, + &query, + DHT_GNS_REPLICATION_LEVEL, + GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, + GNUNET_BLOCK_TYPE_GNS_NAMERECORD, + block_size, + block, + expire_pub, + &dht_put_monitor_continuation, + ma); + refresh_block (block_priv); + if (block != block_priv) + GNUNET_free (block_priv); + GNUNET_free (block); + return ret; +} + +/** + * Process a record that was stored in the namestore + * (invoked by the monitor). + * + * @param cls closure, NULL + * @param zone private key of the zone; NULL on disconnect + * @param label label of the records; NULL on disconnect + * @param rd_count number of entries in @a rd array, 0 if label was deleted + * @param rd array of records with data to store + * @param expire expiration of this record set + */ +static void +handle_monitor_event (void *cls, + const struct GNUNET_IDENTITY_PrivateKey *zone, + const char *label, + unsigned int rd_count, + const struct GNUNET_GNSRECORD_Data *rd, + struct GNUNET_TIME_Absolute expire) +{ + struct DhtPutActivity *ma; + + (void) cls; + GNUNET_STATISTICS_update (statistics, + "Namestore monitor events received", + 1, + GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received %u records for label `%s' via namestore monitor\n", + rd_count, + label); + if (0 == rd_count) + { + GNUNET_NAMESTORE_zone_monitor_next (zmon, + 1); + return; /* nothing to do */ + } + ma = GNUNET_new (struct DhtPutActivity); + ma->start_date = GNUNET_TIME_absolute_get (); + ma->ph = perform_dht_put_monitor (zone, + label, + rd, + rd_count, + expire, + ma); + if (NULL == ma->ph) + { + /* PUT failed, do not remember operation */ + GNUNET_free (ma); + GNUNET_NAMESTORE_zone_monitor_next (zmon, + 1); + return; + } + GNUNET_CONTAINER_DLL_insert_tail (ma_head, + ma_tail, + ma); + ma_queue_length++; + if (ma_queue_length > DHT_QUEUE_LIMIT) + { + ma = ma_head; + GNUNET_CONTAINER_DLL_remove (ma_head, + ma_tail, + ma); + GNUNET_DHT_put_cancel (ma->ph); + ma_queue_length--; + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "DHT PUT unconfirmed after %s, aborting PUT\n", + GNUNET_STRINGS_relative_time_to_string ( + GNUNET_TIME_absolute_get_duration (ma->start_date), + GNUNET_YES)); + GNUNET_free (ma); + } +} + + +/** + * The zone monitor encountered an IPC error trying to to get in + * sync. Restart from the beginning. + * + * @param cls NULL + */ +static void +handle_monitor_error (void *cls) +{ + (void) cls; + GNUNET_STATISTICS_update (statistics, + "Namestore monitor errors encountered", + 1, + GNUNET_NO); +} + + /** * Perform zonemaster duties: watch namestore, publish records. * @@ -1034,6 +1289,20 @@ run (void *cls, GNUNET_NO); zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start, NULL); + zmon = GNUNET_NAMESTORE_zone_monitor_start2 (c, + NULL, + GNUNET_NO, + &handle_monitor_error, + NULL, + &handle_monitor_event, + NULL, + NULL /* sync_cb */, + NULL, + GNUNET_GNSRECORD_FILTER_NONE); + GNUNET_NAMESTORE_zone_monitor_next (zmon, + NAMESTORE_MONITOR_QUEUE_LIMIT - 1); + GNUNET_break (NULL != zmon); + GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); } diff --git a/src/zonemaster/zonemaster.conf.in b/src/zonemaster/zonemaster.conf.in index 315388417..560239944 100644 --- a/src/zonemaster/zonemaster.conf.in +++ b/src/zonemaster/zonemaster.conf.in @@ -24,21 +24,3 @@ ZONE_PUBLISH_TIME_WINDOW = 4 h # USE_CACHE = YES # PREFIX = valgrind --leak-check=full --track-origins=yes - - - -[zonemaster-monitor] -START_ON_DEMAND = @START_ON_DEMAND@ -RUN_PER_USER = YES -IMMEDIATE_START = YES -HOSTNAME = localhost -BINARY = gnunet-service-zonemaster-monitor -UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-zonemaster-monitor.sock -@JAVAPORT@PORT = 2124 - -# Do we require users that want to access GNS to run this process -# (usually not a good idea) -UNIX_MATCH_UID = NO - -# Do we require users that want to access GNS to be in the 'gnunet' group? -UNIX_MATCH_GID = NO -- cgit v1.2.3