GNUnet  0.10.x
gnunet-daemon-regexprofiler.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2012, 2013 Christian Grothoff
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 
30 #include "platform.h"
31 #include "gnunet_util_lib.h"
32 #include "regex_internal_lib.h"
33 #include "regex_test_lib.h"
34 #include "gnunet_dht_service.h"
36 
40 static int global_ret;
41 
45 static const struct GNUNET_CONFIGURATION_Handle *cfg;
46 
51 
56 
61 
66 
71 
75 static unsigned long long max_path_compression;
76 
81 static char * policy_filename;
82 
86 static char * regex_prefix;
87 
91 static char *rx_with_pfx;
92 
96 static unsigned int rounds = 3;
97 
102 
103 
104 
110 static void
111 shutdown_task(void *cls)
112 {
113  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "shutting down\n");
114 
115  if (NULL != announce_handle)
116  {
117  REGEX_INTERNAL_announce_cancel(announce_handle);
118  announce_handle = NULL;
119  }
120  if (NULL != reannounce_task)
121  {
122  GNUNET_free(GNUNET_SCHEDULER_cancel(reannounce_task));
123  reannounce_task = NULL;
124  }
125  if (NULL != dht_handle)
126  {
127  GNUNET_DHT_disconnect(dht_handle);
128  dht_handle = NULL;
129  }
130  GNUNET_free(my_private_key);
131  my_private_key = NULL;
132 
134  "Daemon for %s shutting down\n",
136 }
137 
138 
144 static void
146 {
147  char *regex = cls;
148  struct GNUNET_TIME_Relative random_delay;
149 
150  reannounce_task = NULL;
151  if (0 == rounds--)
152  {
153  global_ret = 0;
155  GNUNET_free(regex);
156  return;
157  }
158  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Announcing regex: %s\n", regex);
159  GNUNET_STATISTICS_update(stats_handle, "# regexes announced", 1, GNUNET_NO);
160  if (NULL == announce_handle && NULL != regex)
161  {
163  "First time, creating regex: %s\n",
164  regex);
165  announce_handle = REGEX_INTERNAL_announce(dht_handle,
166  my_private_key,
167  regex,
168  (unsigned int)max_path_compression,
169  stats_handle);
170  }
171  else
172  {
173  GNUNET_assert(NULL != announce_handle);
174  REGEX_INTERNAL_reannounce(announce_handle);
175  }
176 
177  random_delay =
182  reannounce_task = GNUNET_SCHEDULER_add_delayed(random_delay,
183  &reannounce_regex, cls);
184 }
185 
186 
193 static void
194 announce_regex(const char *regex)
195 {
196  char *copy;
197 
198  if (NULL == regex || 0 == strlen(regex))
199  {
200  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot announce empty regex\n");
201  return;
202  }
203 
205  "Daemon for %s starting\n",
207  GNUNET_assert(NULL == reannounce_task);
208  copy = GNUNET_strdup(regex);
209  reannounce_task = GNUNET_SCHEDULER_add_now(&reannounce_regex,
210  (void *)copy);
211 }
212 
213 
222 static int
223 scan(void *cls, const char *filename)
224 {
225  long n = (long)cls;
226  static long c = 0;
227 
228  if (c == n)
229  {
230  policy_filename = GNUNET_strdup(filename);
231  return GNUNET_NO;
232  }
233  c++;
234  return GNUNET_OK;
235 }
236 
237 
246 static void
247 run(void *cls, char *const *args GNUNET_UNUSED,
248  const char *cfgfile GNUNET_UNUSED,
249  const struct GNUNET_CONFIGURATION_Handle *cfg_)
250 {
251  char *regex = NULL;
252  char **components;
253  char *policy_dir;
254  long long unsigned int peer_id;
255 
256  cfg = cfg_;
257 
259  GNUNET_assert(NULL != my_private_key);
260  if (GNUNET_OK !=
261  GNUNET_CONFIGURATION_get_value_number(cfg, "REGEXPROFILER",
262  "MAX_PATH_COMPRESSION",
264  {
266  _
267  ("%s service is lacking key configuration settings (%s). Exiting.\n"),
268  "regexprofiler", "max_path_compression");
271  return;
272  }
273  if (GNUNET_OK !=
274  GNUNET_CONFIGURATION_get_value_string(cfg, "REGEXPROFILER",
275  "POLICY_DIR", &policy_dir))
276  {
277  GNUNET_log_config_missing(GNUNET_ERROR_TYPE_ERROR, "REGEXPROFILER", "POLICY_DIR");
280  return;
281  }
282  if (GNUNET_OK !=
284  "PEERID", &peer_id))
285  {
288  GNUNET_free(policy_dir);
290  return;
291  }
292 
293  if (GNUNET_OK !=
294  GNUNET_CONFIGURATION_get_value_string(cfg, "REGEXPROFILER",
295  "REGEX_PREFIX", &regex_prefix))
296  {
297  GNUNET_log_config_missing(GNUNET_ERROR_TYPE_ERROR, "REGEXPROFILER", "REGEX_PREFIX");
299  GNUNET_free(policy_dir);
301  return;
302  }
303 
304  if (GNUNET_OK !=
305  GNUNET_CONFIGURATION_get_value_time(cfg, "REGEXPROFILER",
306  "REANNOUNCE_PERIOD_MAX",
308  {
310  "reannounce_period_max not given. Using 10 minutes.\n");
313  }
314 
315  stats_handle = GNUNET_STATISTICS_create("regexprofiler", cfg);
316 
317  dht_handle = GNUNET_DHT_connect(cfg, 1);
318 
319  if (NULL == dht_handle)
320  {
322  "Could not acquire dht handle. Exiting.\n");
324  GNUNET_free(policy_dir);
326  return;
327  }
328 
329  /* Read regexes from policy files */
330  GNUNET_assert(-1 != GNUNET_DISK_directory_scan(policy_dir, &scan,
331  (void *)(long)peer_id));
332  if (NULL == (components = REGEX_TEST_read_from_file(policy_filename)))
333  {
335  "Policy file %s contains no policies. Exiting.\n",
338  GNUNET_free(policy_dir);
340  return;
341  }
342  GNUNET_free(policy_dir);
343  regex = REGEX_TEST_combine(components, 16);
344  REGEX_TEST_free_from_file(components);
345 
346  /* Announcing regexes from policy_filename */
348  "%s(%s)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)*",
349  regex_prefix,
350  regex);
352  GNUNET_free(regex);
354 
355  /* Scheduled the task to clean up when shutdown is called */
357  NULL);
358 }
359 
360 
368 int
369 main(int argc, char *const *argv)
370 {
371  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
373  };
374 
375  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args(argc, argv, &argc, &argv))
376  return 2;
377  return (GNUNET_OK ==
378  GNUNET_PROGRAM_run(argc, argv, "regexprofiler",
380  ("Daemon to announce regular expressions for the peer using cadet."),
381  options, &run, NULL)) ? global_ret : 1;
382 }
383 
384 
385 #if defined(LINUX) && defined(__GLIBC__)
386 #include <malloc.h>
387 
391 void __attribute__ ((constructor)) GNUNET_ARM_memory_init()
392 {
393  mallopt(M_TRIM_THRESHOLD, 4 * 1024);
394  mallopt(M_TOP_PAD, 1 * 1024);
395  malloc_trim(0);
396 }
397 #endif
398 
399 
400 /* end of gnunet-daemon-regexprofiler.c */
int 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.
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.
uint64_t rel_value_us
The actual value.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg_)
Main function that will be run by the scheduler.
#define GNUNET_UNUSED
gcc-ism to document unused arguments
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:1284
#define GNUNET_TIME_UNIT_MINUTES
One minute.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1439
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static char * regex_prefix
Prefix to add before every regex we&#39;re announcing.
static char * rx_with_pfx
Regex with prefix.
static char * peer_id
Option –peer.
Definition: gnunet-cadet.c:42
#define GNUNET_NO
Definition: gnunet_common.h:78
void REGEX_INTERNAL_announce_cancel(struct REGEX_INTERNAL_Announcement *h)
Clear all cached data used by a regex announce.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static char * policy_filename
Name of the file containing policies that this peer should announce.
Definition of a command line option.
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:909
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static struct GNUNET_TIME_Relative reannounce_period_max
What&#39;s the maximum reannounce period.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:517
Handle for the service.
static struct GNUNET_DHT_Handle * dht_handle
Peer&#39;s dht handle.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static void reannounce_regex(void *cls)
Announce a previously announced regex re-using cached data.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
Connection to the DHT service.
Definition: dht_api.c:198
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Private key for this peer.
static int scan(void *cls, const char *filename)
Scan through the policy_dir looking for the n-th filename.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * REGEX_TEST_combine(char *const regexes[], unsigned int alphabet_size)
Combine an array of regexes into a single prefix-shared regex.
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:1237
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
library to parse regular expressions into dfa
static void announce_regex(const char *regex)
Announce the given regular expression using regex and the path compression length read from config...
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:1264
static char * filename
static int global_ret
Return value from &#39;main&#39;.
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:440
Handle to store cached data about a regex announce.
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
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:885
struct REGEX_INTERNAL_Announcement * REGEX_INTERNAL_announce(struct GNUNET_DHT_Handle *dht, const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const char *regex, uint16_t compression, struct GNUNET_STATISTICS_Handle *stats)
Announce a regular expression: put all states of the automaton in the DHT.
static struct GNUNET_STATISTICS_Handle * stats_handle
Handle to the statistics service.
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:913
static char * policy_dir
Folder where policy files are stored.
static struct GNUNET_SCHEDULER_Task * reannounce_task
Periodically reannounce regex.
void REGEX_INTERNAL_reannounce(struct REGEX_INTERNAL_Announcement *h)
Announce again a regular expression previously announced.
static void shutdown_task(void *cls)
Task run during shutdown.
static struct REGEX_INTERNAL_Announcement * announce_handle
Peer&#39;s regex announce handle.
Private ECC key encoded for transmission.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we use.
enum RadiotapType __attribute__
static unsigned int rounds
How many put rounds should we do.
library to read regexes representing IP networks from a file.
void REGEX_TEST_free_from_file(char **regexes)
Free all memory reserved for a set of regexes created by read_from_file.
configuration data
Definition: configuration.c:83
char ** REGEX_TEST_read_from_file(const char *filename)
Read a set of regexes from a file, one per line and return them in an array suitable for REGEX_TEST_c...
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:131
int GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:367
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_configuration(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new private key by reading our peer&#39;s key from the file specified in the configuration...
int main(int argc, char *const *argv)
The main function of the regexprofiler service.
static unsigned long long max_path_compression
Maximal path compression length for regex announcing.
#define GNUNET_TIME_UNIT_MICROSECONDS
One microsecond, our basic time unit.
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
#define gettext_noop(String)
Definition: gettext.h:69
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956