GNUnet  0.11.x
gnunet-daemon-testbed-underlay.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2008--2013 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 
21 
29 #include "platform.h"
30 #include "gnunet_util_lib.h"
33 #include "gnunet_ats_service.h"
34 #include "gnunet_testing_lib.h"
35 #include <sqlite3.h>
36 
40 #define LOG(type, ...) \
41  GNUNET_log (type, __VA_ARGS__)
42 
46 #define DEBUG(...) \
47  LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
48 
54 #define LOG_SQLITE(db, msg, level, cmd) \
55  do { \
56  GNUNET_log_from (level, "sqlite", _ ( \
57  "`%s' failed at %s:%d with error: %s\n"), \
58  cmd, __FILE__, __LINE__, sqlite3_errmsg (db)); \
59  if (msg != NULL) \
60  GNUNET_asprintf (msg, _ ("`%s' failed at %s:%u with error: %s"), cmd, \
61  __FILE__, __LINE__, sqlite3_errmsg (db)); \
62  } while (0)
63 
64 
69 
73 static struct sqlite3 *db;
74 
80 
85 
90 
94 static void *hostkeys_data;
95 
100 
104 static unsigned int num_hostkeys;
105 
106 
118 static int
119 iterator (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
120 {
122  value));
123  return GNUNET_YES;
124 }
125 
126 
130 static void
132 {
133  if (NULL != map)
134  {
136  &
137  iterator,
138  NULL));
140  map = NULL;
141  }
142 }
143 
144 
152 static int
153 check_access (void *cls, const struct GNUNET_PeerIdentity *pid)
154 {
155  int contains;
156 
157  GNUNET_assert (NULL != map);
159  if (GNUNET_YES == contains)
160  {
161  DEBUG ("Permitting `%s'\n", GNUNET_i2s (pid));
162  return GNUNET_OK;
163  }
164  DEBUG ("Not permitting `%s'\n", GNUNET_i2s (pid));
165  return GNUNET_SYSERR;
166 }
167 
168 
169 static int
170 get_identity (unsigned int offset,
171  struct GNUNET_PeerIdentity *id)
172 {
173  struct GNUNET_CRYPTO_EddsaPrivateKey private_key;
174 
175  if (offset >= num_hostkeys)
176  return GNUNET_SYSERR;
177  GNUNET_memcpy (&private_key,
181  &id->public_key);
182  return GNUNET_OK;
183 }
184 
185 
190 {
195 
199  unsigned int id;
200 
204  int latency;
205 };
206 
207 
211 static int
213 {
214  char *data_dir;
215  char *idfile;
216  uint64_t fsize;
217 
218  data_dir = NULL;
219  idfile = NULL;
220  fsize = 0;
222  GNUNET_asprintf (&idfile, "%s/testing_hostkeys.ecc", data_dir);
223  GNUNET_free (data_dir);
224  data_dir = NULL;
225  if (GNUNET_OK !=
226  GNUNET_DISK_file_size (idfile, &fsize, GNUNET_YES, GNUNET_YES))
227  {
228  GNUNET_free (idfile);
229  return GNUNET_SYSERR;
230  }
231  if (0 != (fsize % GNUNET_TESTING_HOSTKEYFILESIZE))
232  {
234  _ ("Incorrect hostkey file format: %s\n"), idfile);
235  GNUNET_free (idfile);
236  return GNUNET_SYSERR;
237  }
240  if (NULL == hostkeys_fd)
241  {
243  GNUNET_free (idfile);
244  return GNUNET_SYSERR;
245  }
246  GNUNET_free (idfile);
247  idfile = NULL;
249  &hostkeys_map,
251  fsize);
252  if (NULL == hostkeys_data)
253  {
255  return GNUNET_SYSERR;
256  }
258  return GNUNET_OK;
259 }
260 
261 
265 static void
267 {
268  if (NULL != hostkeys_map)
269  {
270  GNUNET_assert (NULL != hostkeys_data);
272  hostkeys_map = NULL;
273  hostkeys_data = NULL;
274  }
275  if (NULL != hostkeys_fd)
276  {
278  hostkeys_fd = NULL;
279  }
280 }
281 
282 
288 static void
289 do_shutdown (void *cls)
290 {
291  if (NULL != transport)
292  {
294  transport = NULL;
295  }
296  cleanup_map ();
297  unload_keys ();
298  if (NULL != bh)
300 }
301 
302 
311 static int
312 db_read_whitelist (struct sqlite3 *db, int pid, struct WhiteListRow **wl_rows)
313 {
314  static const char *query_wl =
315  "SELECT oid, latency FROM whitelist WHERE (id == ?);";
316  struct sqlite3_stmt *stmt_wl;
317  struct WhiteListRow *lr;
318  int nrows;
319  int ret;
320 
321  if (SQLITE_OK != (ret = sqlite3_prepare_v2 (db, query_wl, -1, &stmt_wl,
322  NULL)))
323  {
324  LOG_SQLITE (db, NULL, GNUNET_ERROR_TYPE_ERROR, "sqlite3_prepare_v2");
325  return GNUNET_SYSERR;
326  }
327  if (SQLITE_OK != (ret = sqlite3_bind_int (stmt_wl, 1, pid)))
328  {
329  LOG_SQLITE (db, NULL, GNUNET_ERROR_TYPE_ERROR, "sqlite3_bind_int");
330  sqlite3_finalize (stmt_wl);
331  return GNUNET_SYSERR;
332  }
333  nrows = 0;
334  do
335  {
336  ret = sqlite3_step (stmt_wl);
337  if (SQLITE_ROW != ret)
338  break;
339  nrows++;
340  lr = GNUNET_new (struct WhiteListRow);
341  lr->id = sqlite3_column_int (stmt_wl, 0);
342  lr->latency = sqlite3_column_int (stmt_wl, 1);
343  lr->next = *wl_rows;
344  *wl_rows = lr;
345  }
346  while (1);
347  sqlite3_finalize (stmt_wl);
348  return nrows;
349 }
350 
351 
360 static void
361 run (void *cls, char *const *args, const char *cfgfile,
362  const struct GNUNET_CONFIGURATION_Handle *c)
363 {
364  char *dbfile;
365  struct WhiteListRow *wl_head;
366  struct WhiteListRow *wl_entry;
368  struct GNUNET_ATS_Properties prop;
370  unsigned long long pid;
371  unsigned int nrows;
372  int ret;
373 
374  if (GNUNET_OK !=
376  "PEERID", &pid))
377  {
378  GNUNET_break (0);
379  return;
380  }
382  "TESTBED-UNDERLAY",
383  "DBFILE",
384  &dbfile))
385  {
386  GNUNET_break (0);
387  return;
388  }
389  if (SQLITE_OK != (ret = sqlite3_open_v2 (dbfile, &db, SQLITE_OPEN_READONLY,
390  NULL)))
391  {
392  if (NULL != db)
393  {
394  LOG_SQLITE (db, NULL, GNUNET_ERROR_TYPE_ERROR, "sqlite_open_v2");
395  GNUNET_break (SQLITE_OK == sqlite3_close (db));
396  }
397  else
398  LOG (GNUNET_ERROR_TYPE_ERROR, "Cannot open sqlite file %s\n", dbfile);
399  GNUNET_free (dbfile);
400  return;
401  }
402  DEBUG ("Opened database %s\n", dbfile);
403  GNUNET_free (dbfile);
404  dbfile = NULL;
405  wl_head = NULL;
406  if (GNUNET_OK != load_keys (c))
407  goto close_db;
408 
410  if (NULL == transport)
411  {
412  GNUNET_break (0);
413  return;
414  }
415  /* read and process whitelist */
416  nrows = 0;
417  wl_head = NULL;
418  nrows = db_read_whitelist (db, pid, &wl_head);
419  if ((GNUNET_SYSERR == nrows) || (0 == nrows))
420  {
422  goto close_db;
423  }
425  while (NULL != (wl_entry = wl_head))
426  {
427  wl_head = wl_entry->next;
428  delay.rel_value_us = wl_entry->latency;
429  memset (&prop, 0, sizeof(prop));
430  GNUNET_assert (GNUNET_OK == get_identity (wl_entry->id, &identity));
434  DEBUG ("Setting %u ms latency to peer `%s'\n",
435  wl_entry->latency,
436  GNUNET_i2s (&identity));
438  &identity,
439  &prop,
440  delay,
441  delay);
442  GNUNET_free (wl_entry);
443  }
446 
447 close_db:
448  GNUNET_break (SQLITE_OK == sqlite3_close (db));
449 }
450 
451 
459 int
460 main (int argc, char *const *argv)
461 {
462  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
464  };
465  int ret;
466 
467  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
468  return 2;
469 #ifdef SQLITE_CONFIG_MMAP_SIZE
470  (void) sqlite3_config (SQLITE_CONFIG_MMAP_SIZE, 512000, 256000000);
471 #endif
472  ret =
473  (GNUNET_OK ==
474  GNUNET_PROGRAM_run (argc, argv, "testbed-underlay",
475  _
476  (
477  "Daemon to restrict underlay network in testbed deployments"),
478  options, &run, NULL)) ? 0 : 1;
479  GNUNET_free_nz ((void *) argv);
480  return ret;
481 }
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_IDENTITY_Handle * id
Handle to identity service.
static unsigned int num_hostkeys
The number of hostkeys in the hostkeys array.
static void unload_keys()
Function to unload keys.
static int db_read_whitelist(struct sqlite3 *db, int pid, struct WhiteListRow **wl_rows)
Function to read whitelist rows from the database.
static struct GNUNET_TRANSPORT_Blacklist * bh
The blacklist handle we obtain from transport when we register ourselves for access control.
static int check_access(void *cls, const struct GNUNET_PeerIdentity *pid)
Function that decides if a connection is acceptable or not.
static void * hostkeys_data
The hostkeys data.
#define LOG(type,...)
Logging shorthand.
static int get_identity(unsigned int offset, struct GNUNET_PeerIdentity *id)
static void do_shutdown(void *cls)
Shutdown task to cleanup our resources and exit.
static void cleanup_map()
Cleaup and destroy the map.
static int load_keys(const struct GNUNET_CONFIGURATION_Handle *c)
Function to load keys.
static struct GNUNET_CONTAINER_MultiPeerMap * map
The map to store the peer identities to allow/deny.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Main function that will be run.
struct GNUNET_DISK_FileHandle * hostkeys_fd
The hostkeys file.
#define DEBUG(...)
Debug logging shorthand.
#define LOG_SQLITE(db, msg, level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' on file 'file...
static struct GNUNET_TRANSPORT_ManipulationHandle * transport
Handle to the transport service.
static struct GNUNET_DISK_MapHandle * hostkeys_map
The hostkeys map.
int main(int argc, char *const *argv)
The main function.
static struct sqlite3 * db
The database connection.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_GNS_LookupWithTldRequest * lr
Handle to lookup request.
Definition: gnunet-gns.c:99
static char * value
Value of the record to add/remove.
static struct GNUNET_IDENTITY_Handle * identity
Which namespace do we publish to? NULL if we do not publish to a namespace.
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
Automatic transport selection and outbound bandwidth determination.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
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.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:197
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition: disk.c:1235
enum GNUNET_GenericReturnValue GNUNET_DISK_file_size(const char *filename, uint64_t *size, int include_symbolic_links, int single_file_mode)
Get the size of the file (or directory) of the given file (in bytes).
Definition: disk.c:222
void * GNUNET_DISK_file_map(const struct GNUNET_DISK_FileHandle *h, struct GNUNET_DISK_MapHandle **m, enum GNUNET_DISK_MapType access, size_t len)
Map a file into memory.
Definition: disk.c:1378
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1306
enum GNUNET_GenericReturnValue GNUNET_DISK_file_unmap(struct GNUNET_DISK_MapHandle *h)
Unmap a file.
Definition: disk.c:1409
@ GNUNET_DISK_OPEN_READ
Open the file for reading.
@ GNUNET_DISK_PERM_NONE
Nobody is allowed to do anything to the file.
@ GNUNET_DISK_MAP_TYPE_READ
Read-only memory map.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
int GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
int GNUNET_CONTAINER_multipeermap_contains(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Check if the map contains any value under the given key (including values that are NULL).
static int iterator(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Iterator over hash map entries.
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
, ' bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE...
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#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.
#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...
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_ERROR
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_free_nz(ptr)
Wrapper around free.
char * GNUNET_OS_installation_get_path(enum GNUNET_OS_InstallationPathKind dirkind)
Get the path to a specific GNUnet installation directory or, with GNUNET_OS_IPK_SELF_PREFIX,...
@ GNUNET_OS_IPK_DATADIR
Return the directory where data is installed (share/gnunet/)
enum GNUNET_GenericReturnValue 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,...
Definition: program.c:364
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:1331
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1209
#define GNUNET_TESTING_HOSTKEYFILESIZE
Size of each hostkey in the hostkey file (in BYTES).
void GNUNET_TRANSPORT_manipulation_set(struct GNUNET_TRANSPORT_ManipulationHandle *handle, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_ATS_Properties *prop, struct GNUNET_TIME_Relative delay_in, struct GNUNET_TIME_Relative delay_out)
Set transport metrics for a peer and a direction.
struct GNUNET_TRANSPORT_ManipulationHandle * GNUNET_TRANSPORT_manipulation_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the transport service.
void GNUNET_TRANSPORT_manipulation_disconnect(struct GNUNET_TRANSPORT_ManipulationHandle *handle)
Disconnect from the transport service.
struct GNUNET_TRANSPORT_Blacklist * GNUNET_TRANSPORT_blacklist(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_TRANSPORT_BlacklistCallback cb, void *cb_cls)
Install a blacklist callback.
void GNUNET_TRANSPORT_blacklist_cancel(struct GNUNET_TRANSPORT_Blacklist *br)
Abort the blacklist.
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
ATS performance characteristics for an address.
Internal representation of the hash map.
Private ECC key encoded for transmission.
Handle used to access files (and pipes).
Handle for a memory-mapping operation.
Definition: disk.c:1359
Definition of a command line option.
The identity of the host (wraps the signing key of the peer).
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Handle for blacklisting requests.
Handle for the transport service (includes all of the state for the transport service).
int latency
Latency to be assigned to the link.
struct WhiteListRow * next
Next ptr.
unsigned int id
The offset where to find the hostkey for the peer.