GNUnet  0.11.x
gnunet-service-zonemaster-monitor.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 "gnunet_util_lib.h"
28 #include "gnunet_dht_service.h"
31 
32 
33 #define LOG_STRERROR_FILE(kind, syscall, \
34  filename) GNUNET_log_from_strerror_file (kind, "util", \
35  syscall, \
36  filename)
37 
38 
43 #define PUBLISH_OPS_PER_EXPIRATION 4
44 
48 #define DHT_QUEUE_LIMIT 2000
49 
54 #define NAMESTORE_QUEUE_LIMIT 5
55 
59 #define DHT_GNS_REPLICATION_LEVEL 5
60 
61 
66 {
71 
76 
81 
86 };
87 
88 
93 
98 
103 
108 
112 static struct DhtPutActivity *ma_head;
113 
117 static struct DhtPutActivity *ma_tail;
118 
122 static unsigned int ma_queue_length;
123 
128 static int cache_keys;
129 
130 
137 static void
138 shutdown_task (void *cls)
139 {
140  struct DhtPutActivity *ma;
141 
142  (void) cls;
144  "Shutting down!\n");
145  while (NULL != (ma = ma_head))
146  {
148  ma_queue_length--;
150  ma_tail,
151  ma);
152  GNUNET_free (ma);
153  }
154  if (NULL != statistics)
155  {
156  GNUNET_STATISTICS_destroy (statistics,
157  GNUNET_NO);
158  statistics = NULL;
159  }
160  if (NULL != zmon)
161  {
163  zmon = NULL;
164  }
165  if (NULL != namestore_handle)
166  {
167  GNUNET_NAMESTORE_disconnect (namestore_handle);
168  namestore_handle = NULL;
169  }
170  if (NULL != dht_handle)
171  {
172  GNUNET_DHT_disconnect (dht_handle);
173  dht_handle = NULL;
174  }
175 }
176 
177 
184 static void
186 {
187  struct DhtPutActivity *ma = cls;
188 
190  1);
191  ma_queue_length--;
193  ma_tail,
194  ma);
195  GNUNET_free (ma);
196 }
197 
198 
209 static unsigned int
211  unsigned int rd_count,
212  struct GNUNET_GNSRECORD_Data *rd_public)
213 {
214  struct GNUNET_TIME_Absolute now;
215  unsigned int rd_public_count;
216 
217  rd_public_count = 0;
218  now = GNUNET_TIME_absolute_get ();
219  for (unsigned int i = 0; i < rd_count; i++)
220  {
221  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE))
222  continue;
223  if ((0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) &&
224  (rd[i].expiration_time < now.abs_value_us))
225  continue; /* record already expired, skip it */
226  rd_public[rd_public_count++] = rd[i];
227  }
228  return rd_public_count;
229 }
230 
231 
242 static struct GNUNET_DHT_PutHandle *
244  const char *label,
245  const struct GNUNET_GNSRECORD_Data *rd_public,
246  unsigned int rd_public_count,
247  struct DhtPutActivity *ma)
248 {
249  struct GNUNET_GNSRECORD_Block *block;
250  struct GNUNET_HashCode query;
251  struct GNUNET_TIME_Absolute expire;
252  size_t block_size;
253  struct GNUNET_DHT_PutHandle *ret;
254 
255  expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_public_count,
256  rd_public);
257  if (cache_keys)
258  block = GNUNET_GNSRECORD_block_create2 (key,
259  expire,
260  label,
261  rd_public,
262  rd_public_count);
263  else
264  block = GNUNET_GNSRECORD_block_create (key,
265  expire,
266  label,
267  rd_public,
268  rd_public_count);
269  if (NULL == block)
270  {
271  GNUNET_break (0);
272  return NULL; /* whoops */
273  }
274  block_size = ntohl (block->purpose.size)
275  + sizeof(struct GNUNET_CRYPTO_EcdsaSignature)
276  + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey);
278  label,
279  &query);
280  GNUNET_STATISTICS_update (statistics,
281  "DHT put operations initiated",
282  1,
283  GNUNET_NO);
285  "Storing %u record(s) for label `%s' in DHT with expiration `%s' under key %s\n",
286  rd_public_count,
287  label,
289  GNUNET_h2s (&query));
290  ret = GNUNET_DHT_put (dht_handle,
291  &query,
295  block_size,
296  block,
297  expire,
299  ma);
300  GNUNET_free (block);
301  return ret;
302 }
303 
304 
315 static void
317  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
318  const char *label,
319  unsigned int rd_count,
320  const struct GNUNET_GNSRECORD_Data *rd)
321 {
322  struct GNUNET_GNSRECORD_Data rd_public[rd_count];
323  unsigned int rd_public_count;
324  struct DhtPutActivity *ma;
325 
326  (void) cls;
327  GNUNET_STATISTICS_update (statistics,
328  "Namestore monitor events received",
329  1,
330  GNUNET_NO);
332  "Received %u records for label `%s' via namestore monitor\n",
333  rd_count,
334  label);
335  /* filter out records that are not public, and convert to
336  absolute expiration time. */
337  rd_public_count = convert_records_for_export (rd,
338  rd_count,
339  rd_public);
340  if (0 == rd_public_count)
341  {
343  1);
344  return; /* nothing to do */
345  }
346  ma = GNUNET_new (struct DhtPutActivity);
348  ma->ph = perform_dht_put (zone,
349  label,
350  rd,
351  rd_count,
352  ma);
353  if (NULL == ma->ph)
354  {
355  /* PUT failed, do not remember operation */
356  GNUNET_free (ma);
358  1);
359  return;
360  }
362  ma_tail,
363  ma);
364  ma_queue_length++;
366  {
367  ma = ma_head;
369  ma_tail,
370  ma);
372  ma_queue_length--;
374  "DHT PUT unconfirmed after %s, aborting PUT\n",
377  GNUNET_YES));
378  GNUNET_free (ma);
379  }
380 }
381 
382 
389 static void
391 {
392  (void) cls;
393  GNUNET_STATISTICS_update (statistics,
394  "Namestore monitor errors encountered",
395  1,
396  GNUNET_NO);
397 }
398 
399 
407 static void
408 run (void *cls,
409  const struct GNUNET_CONFIGURATION_Handle *c,
411 {
412  unsigned long long max_parallel_bg_queries = 128;
413 
414  (void) cls;
415  (void) service;
416  namestore_handle = GNUNET_NAMESTORE_connect (c);
417  if (NULL == namestore_handle)
418  {
420  _ ("Failed to connect to the namestore!\n"));
422  return;
423  }
425  "namestore",
426  "CACHE_KEYS");
427  if (GNUNET_OK ==
429  "zonemaster",
430  "MAX_PARALLEL_BACKGROUND_QUERIES",
431  &max_parallel_bg_queries))
432  {
434  "Number of allowed parallel background queries: %llu\n",
435  max_parallel_bg_queries);
436  }
437  if (0 == max_parallel_bg_queries)
438  max_parallel_bg_queries = 1;
439  dht_handle = GNUNET_DHT_connect (c,
440  (unsigned int) max_parallel_bg_queries);
441  if (NULL == dht_handle)
442  {
444  _ ("Could not connect to DHT!\n"));
446  NULL);
447  return;
448  }
449 
450  /* Schedule periodic put for our records. */
451  statistics = GNUNET_STATISTICS_create ("zonemaster-mon",
452  c);
454  NULL,
455  GNUNET_NO,
457  NULL,
459  NULL,
460  NULL /* sync_cb */,
461  NULL);
464  GNUNET_break (NULL != zmon);
466  NULL);
467 }
468 
469 
474  ("zonemaster-monitor",
476  &run,
477  NULL,
478  NULL,
479  NULL,
481 
482 
483 /* end of gnunet-service-zonemaster-monitor.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
struct GNUNET_DHT_PutHandle * ph
Handle for the DHT PUT operation.
struct DhtPutActivity * prev
Kept in a DLL.
int 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.
static int cache_keys
Optimize block insertion by caching map of private keys to public keys in memory? ...
void GNUNET_DHT_put_cancel(struct GNUNET_DHT_PutHandle *ph)
Cancels a DHT PUT operation.
Definition: dht_api.c:1035
static void shutdown_task(void *cls)
Task run during shutdown.
static struct GNUNET_STATISTICS_Handle * statistics
Handle to the statistics service.
static struct GNUNET_NAMESTORE_ZoneMonitor * zmon
Handle to monitor namestore changes to instant propagation.
struct GNUNET_NAMESTORE_ZoneMonitor * GNUNET_NAMESTORE_zone_monitor_start(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, int iterate_first, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor monitor, void *monitor_cls, GNUNET_SCHEDULER_TaskCallback sync_cb, void *sync_cb_cls)
Begin monitoring a zone for changes.
struct GNUNET_GNSRECORD_Block * GNUNET_GNSRECORD_block_create(const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count)
Sign name and records.
Handle to a service.
Definition: service.c:116
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, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1300
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
struct GNUNET_GNSRECORD_Block * GNUNET_GNSRECORD_block_create2(const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count)
Sign name and records, cache derived public key (also keeps the private key in static memory...
struct GNUNET_TIME_Absolute start_date
When was this PUT initiated?
#define DHT_GNS_REPLICATION_LEVEL
What replication level do we use for DHT PUT operations?
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
void GNUNET_NAMESTORE_zone_monitor_stop(struct GNUNET_NAMESTORE_ZoneMonitor *zm)
Stop monitoring a zone for changes.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
Information we have in an encrypted block with record data (i.e.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
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_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
Handle for the service.
uint64_t abs_value_us
The actual value.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Handle for DHT PUT activity triggered from the namestore monitor.
Connection to the DHT service.
Definition: dht_api.c:201
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
#define DHT_QUEUE_LIMIT
How many pending DHT operations do we allow at most?
static char * zone
Name of the zone we manage.
void GNUNET_GNSRECORD_query_from_private_key(const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, struct GNUNET_HashCode *query)
Calculate the DHT query for a given label in a given zone.
static struct GNUNET_NAMESTORE_Handle * namestore_handle
Our handle to the namestore service.
void GNUNET_NAMESTORE_disconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from the namestore service (and free associated resources).
Handle for a monitoring activity.
static void handle_monitor_error(void *cls)
The zone monitor encountered an IPC error trying to to get in sync.
GNUNET_SERVICE_MAIN("zonemaster-monitor", GNUNET_SERVICE_OPTION_NONE, &run, NULL, NULL, NULL, GNUNET_MQ_handler_end())
Define "main" method using service macro.
Connection to the NAMESTORE service.
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:1280
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:687
an ECC signature using ECDSA
This is a private record of this peer and it should thus not be handed out to other peers...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
Block for storing record data.
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_TIME_Absolute GNUNET_GNSRECORD_record_get_expiration_time(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Returns the expiration time of the given block of records.
struct GNUNET_HashCode key
The key used in the DHT.
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:966
#define NAMESTORE_QUEUE_LIMIT
How many events may the namestore give us before it has to wait for us to keep up?
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:890
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namestore service.
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:918
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
static struct DhtPutActivity * ma_head
Head of monitor activities; kept in a DLL.
Handle to a PUT request.
Definition: dht_api.c:43
static struct DhtPutActivity * ma_tail
Tail of monitor activities; kept in a DLL.
configuration data
Definition: configuration.c:85
static void handle_monitor_event(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process a record that was stored in the namestore (invoked by the monitor).
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:375
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
Performe zonemaster duties: watch namestore, publish records.
#define GNUNET_log(kind,...)
static struct GNUNET_DHT_Handle * dht_handle
Our handle to the DHT.
static unsigned int ma_queue_length
Number of entries in the DHT queue ma_head.
static struct GNUNET_DHT_PutHandle * perform_dht_put(const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, const char *label, const struct GNUNET_GNSRECORD_Data *rd_public, unsigned int rd_public_count, struct DhtPutActivity *ma)
Store GNS records in the DHT.
static unsigned int convert_records_for_export(const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *rd_public)
Convert namestore records from the internal format to that suitable for publication (removes private ...
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
static void dht_put_monitor_continuation(void *cls)
Continuation called from DHT once the PUT operation triggered by a monitor is done.
This flag is currently unused; former RF_PENDING flag.
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:742
int 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".
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Number of bytes signed; also specifies the number of bytes of encrypted data that follow...
struct DhtPutActivity * next
Kept in a DLL.
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)...
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
Each peer along the way should look at &#39;enc&#39; (otherwise only the k-peers closest to the key should lo...
#define GNUNET_free(ptr)
Wrapper around free.