GNUnet  0.20.0
testing.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2008, 2009, 2012 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 
32 #include "platform.h"
33 #include "gnunet_util_lib.h"
34 #include "gnunet_arm_service.h"
35 #include "gnunet_testing_lib.h"
36 #include "gnunet_testing_ng_lib.h"
37 #include "gnunet_testing_plugin.h"
38 #include "gnunet_testing_barrier.h"
40 #include "testing_cmds.h"
41 
42 #define LOG(kind, ...) GNUNET_log_from (kind, "testing-api", __VA_ARGS__)
43 
44 #define CONNECT_ADDRESS_TEMPLATE "%s-192.168.15.%u"
45 
46 #define ROUTER_CONNECT_ADDRESS_TEMPLATE "%s-92.68.150.%u"
47 
48 #define KNOWN_CONNECT_ADDRESS_TEMPLATE "%s-92.68.151.%u"
49 
50 /* Use the IP addresses below instead of the public ones,
51  * if the start script was not started from within a new namespace
52  * created by unshare. The UPNP test case needs public IP
53  * addresse for miniupnpd to function.
54  * FIXME We should introduce a switch indicating if public
55  * addresses should be used or not. This info has to be
56  * propagated from the start script to the c code.
57 #define ROUTER_CONNECT_ADDRESS_TEMPLATE "%s-172.16.150.%u"
58 
59 #define KNOWN_CONNECT_ADDRESS_TEMPLATE "%s-172.16.151.%u"
60 */
61 
62 #define PREFIX_TCP "tcp"
63 
64 #define PREFIX_UDP "udp"
65 
66 #define PREFIX_TCP_NATTED "tcp_natted"
67 
68 #define PREFIX_UDP_NATTED "udp_natted"
69 
76 #define LOW_PORT 12000
77 
83 #define HIGH_PORT 56000
84 
85 
87 {
88  struct SharedService *ss;
89 
90  char *cfg_fn;
91 
93 
94  char *unix_sock;
95 
96  char *port_str;
97 
98  unsigned int n_refs;
99 };
100 
101 struct SharedService
102 {
103  char *sname;
104 
106 
108 
109  unsigned int n_peers;
110 
111  unsigned int share;
112 
113  unsigned int n_instances;
114 };
115 
116 
122 {
127  char *tmppath;
128 
133  char *trusted_ip;
134 
138  char *hostname;
139 
144 
149 
151 
152  unsigned int n_shared_services;
153 
162  uint32_t reserved_ports[65536 / 32];
163 
172  uint32_t path_counter;
173 
177  uint32_t total_hostkeys;
178 
182  uint16_t lowport;
183 
187  uint16_t highport;
188 };
189 
190 
195 {
200 
204  char *cfgfile;
205 
212  char *main_binary;
213  char *args;
214 
220 
225 
230 
235 
239  void *cb_cls;
240 
246 
248 
254  uint16_t *ports;
255 
259  unsigned int nports;
260 
264  uint32_t key_number;
265 };
266 
267 
275 static enum GNUNET_GenericReturnValue
276 hostkeys_load (struct GNUNET_TESTING_System *system)
277 {
278  uint64_t fs;
279  char *data_dir;
280  char *filename;
281  struct GNUNET_DISK_FileHandle *fd;
282 
283  GNUNET_assert (NULL == system->hostkeys_data);
285  GNUNET_asprintf (&filename, "%s/testing_hostkeys.ecc", data_dir);
286  GNUNET_free (data_dir);
287 
289  {
291  _ ("Hostkeys file not found: %s\n"),
292  filename);
294  return GNUNET_SYSERR;
295  }
296  /* Check hostkey file size, read entire thing into memory */
297  if (GNUNET_OK !=
299  fs = 0;
300  if (0 == fs)
301  {
303  return GNUNET_SYSERR; /* File is empty */
304  }
305  if (0 != (fs % GNUNET_TESTING_HOSTKEYFILESIZE))
306  {
308  _ ("Incorrect hostkey file format: %s\n"),
309  filename);
311  return GNUNET_SYSERR;
312  }
316  if (NULL == fd)
317  {
320  return GNUNET_SYSERR;
321  }
323  system->hostkeys_data =
326  if (NULL == system->hostkeys_data)
327  return GNUNET_SYSERR;
329  return GNUNET_OK;
330 }
331 
332 
338 static void
340 {
341  GNUNET_break (NULL != system->hostkeys_data);
342  system->hostkeys_data = NULL;
343  GNUNET_DISK_file_unmap (system->map);
344  system->map = NULL;
345  system->hostkeys_data = NULL;
346  system->total_hostkeys = 0;
347 }
348 
349 
358 static void
359 cfg_copy_iterator (void *cls,
360  const char *section,
361  const char *option,
362  const char *value)
363 {
364  struct GNUNET_CONFIGURATION_Handle *cfg2 = cls;
365 
366  GNUNET_CONFIGURATION_set_value_string (cfg2, section, option, value);
367 }
368 
369 
391 struct GNUNET_TESTING_System *
393  const char *testdir,
394  const char *trusted_ip,
395  const char *hostname,
397  uint16_t lowport,
398  uint16_t highport)
399 {
400  struct GNUNET_TESTING_System *system;
401  struct GNUNET_TESTING_SharedService tss;
402  struct SharedService ss;
403  unsigned int cnt;
404 
405  GNUNET_assert (NULL != testdir);
406  system = GNUNET_new (struct GNUNET_TESTING_System);
407  if (NULL == (system->tmppath = getenv (GNUNET_TESTING_PREFIX)))
408  system->tmppath = GNUNET_DISK_mkdtemp (testdir);
409  else
410  system->tmppath = GNUNET_strdup (system->tmppath);
411  system->lowport = lowport;
412  system->highport = highport;
413  if (NULL == system->tmppath)
414  {
415  GNUNET_free (system);
416  return NULL;
417  }
418  if (NULL != trusted_ip)
419  system->trusted_ip = GNUNET_strdup (trusted_ip);
420  if (NULL != hostname)
421  system->hostname = GNUNET_strdup (hostname);
422  if (GNUNET_OK != hostkeys_load (system))
423  {
425  return NULL;
426  }
427  if (NULL == shared_services)
428  return system;
429  for (cnt = 0; NULL != shared_services[cnt].service; cnt++)
430  {
431  tss = shared_services[cnt];
432  memset (&ss, 0, sizeof (ss));
433  ss.sname = GNUNET_strdup (tss.service);
436  ss.sname,
438  ss.cfg);
440  "TESTING",
442  ss.cfg);
444  "PATHS",
446  ss.cfg);
447  ss.share = tss.share;
449  system->n_shared_services,
450  ss);
451  }
452  return system;
453 }
454 
455 
476 struct GNUNET_TESTING_System *
478  const char *testdir,
479  const char *trusted_ip,
480  const char *hostname,
482 {
484  trusted_ip,
485  hostname,
487  LOW_PORT,
488  HIGH_PORT);
489 }
490 
491 
492 static void
494 {
495  if (NULL != i->cfg_fn)
496  {
497  (void) unlink (i->cfg_fn);
498  GNUNET_free (i->cfg_fn);
499  }
500  GNUNET_free (i->unix_sock);
501  GNUNET_free (i->port_str);
502  GNUNET_break (NULL == i->proc);
503  GNUNET_break (0 == i->n_refs);
504  GNUNET_free (i);
505 }
506 
507 
508 static enum GNUNET_GenericReturnValue
510 {
511  char *binary;
512  char *libexec_binary;
513 
514  GNUNET_assert (NULL == i->proc);
515  GNUNET_assert (NULL != i->cfg_fn);
516  (void) GNUNET_asprintf (&binary, "gnunet-service-%s", i->ss->sname);
517  libexec_binary = GNUNET_OS_get_libexec_binary_path (binary);
518  GNUNET_free (binary);
520  NULL,
521  NULL,
522  NULL,
523  libexec_binary,
524  libexec_binary,
525  "-c",
526  i->cfg_fn,
527  NULL);
528  GNUNET_free (libexec_binary);
529  if (NULL == i->proc)
530  return GNUNET_SYSERR;
531  return GNUNET_OK;
532 }
533 
534 
535 static void
537 {
538  GNUNET_break (0 == i->n_refs);
541  "Killing shared service instance (%s) failed\n",
542  i->ss->sname);
543  (void) GNUNET_OS_process_wait (i->proc);
545  i->proc = NULL;
546 }
547 
548 
556 void
558  int remove_paths)
559 {
560  struct SharedService *ss;
561  struct SharedServiceInstance *i;
562  unsigned int ss_cnt;
563  unsigned int i_cnt;
564 
565  if (NULL != system->hostkeys_data)
566  hostkeys_unload (system);
567  for (ss_cnt = 0; ss_cnt < system->n_shared_services; ss_cnt++)
568  {
569  ss = &system->shared_services[ss_cnt];
570  for (i_cnt = 0; i_cnt < ss->n_instances; i_cnt++)
571  {
572  i = ss->instances[i_cnt];
573  if (NULL != i->proc)
576  }
579  GNUNET_free (ss->sname);
580  }
581  GNUNET_free (system->shared_services);
582  if (GNUNET_YES == remove_paths)
584  GNUNET_free (system->tmppath);
585  GNUNET_free (system->trusted_ip);
586  GNUNET_free (system->hostname);
587  GNUNET_free (system);
588 }
589 
590 
597 uint16_t
599 {
600  struct GNUNET_NETWORK_Handle *socket;
601  struct addrinfo hint;
602  struct addrinfo *ret;
603  struct addrinfo *ai;
604  uint32_t *port_buckets;
605  char *open_port_str;
606  int bind_status;
607  uint32_t xor_image;
608  uint16_t index;
609  uint16_t open_port;
610  uint16_t pos;
611 
612  /*
613  FIXME: Instead of using getaddrinfo we should try to determine the port
614  status by the following heurestics.
615 
616  On systems which support both IPv4 and IPv6, only ports open on both
617  address families are considered open.
618  On system with either IPv4 or IPv6. A port is considered open if it's
619  open in the respective address family
620  */hint.ai_family = AF_UNSPEC; /* IPv4 and IPv6 */
621  hint.ai_socktype = 0;
622  hint.ai_protocol = 0;
623  hint.ai_addrlen = 0;
624  hint.ai_addr = NULL;
625  hint.ai_canonname = NULL;
626  hint.ai_next = NULL;
627  hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV; /* Wild card address */
628  port_buckets = system->reserved_ports;
629  for (index = (system->lowport / 32) + 1; index < (system->highport / 32);
630  index++)
631  {
632  xor_image = (UINT32_MAX ^ port_buckets[index]);
633  if (0 == xor_image) /* Ports in the bucket are full */
634  continue;
635  pos = system->lowport % 32;
636  while (pos < 32)
637  {
638  if (0 == ((xor_image >> pos) & 1U))
639  {
640  pos++;
641  continue;
642  }
643  open_port = (index * 32) + pos;
644  if (open_port >= system->highport)
645  return 0;
646  GNUNET_asprintf (&open_port_str, "%u", (unsigned int) open_port);
647  ret = NULL;
648  GNUNET_assert (0 == getaddrinfo (NULL, open_port_str, &hint, &ret));
649  GNUNET_free (open_port_str);
650  bind_status = GNUNET_NO;
651  for (ai = ret; NULL != ai; ai = ai->ai_next)
652  {
653  socket = GNUNET_NETWORK_socket_create (ai->ai_family, SOCK_STREAM, 0);
654  if (NULL == socket)
655  continue;
656  bind_status =
657  GNUNET_NETWORK_socket_bind (socket, ai->ai_addr, ai->ai_addrlen);
659  if (GNUNET_OK != bind_status)
660  break;
661  socket = GNUNET_NETWORK_socket_create (ai->ai_family, SOCK_DGRAM, 0);
662  if (NULL == socket)
663  continue;
664  bind_status =
665  GNUNET_NETWORK_socket_bind (socket, ai->ai_addr, ai->ai_addrlen);
667  if (GNUNET_OK != bind_status)
668  break;
669  }
670  port_buckets[index] |= (1U << pos); /* Set the port bit */
671  freeaddrinfo (ret);
672  if (GNUNET_OK == bind_status)
673  {
675  "Found a free port %u\n",
676  (unsigned int) open_port);
677  return open_port;
678  }
679  pos++;
680  }
681  }
682  return 0;
683 }
684 
685 
693 void
695  uint16_t port)
696 {
697  uint32_t *port_buckets;
698  uint16_t bucket;
699  uint16_t pos;
700 
701  port_buckets = system->reserved_ports;
702  bucket = port / 32;
703  pos = port % 32;
704  LOG (GNUNET_ERROR_TYPE_DEBUG, "Releasing port %u\n", port);
705  if (0 == (port_buckets[bucket] & (1U << pos)))
706  {
707  GNUNET_break (0); /* Port was not reserved by us using reserve_port() */
708  return;
709  }
710  port_buckets[bucket] &= ~(1U << pos);
711 }
712 
713 
733  uint32_t key_number,
734  struct GNUNET_PeerIdentity *id)
735 {
736  struct GNUNET_CRYPTO_EddsaPrivateKey *private_key;
737 
738  if ((NULL == id) || (NULL == system->hostkeys_data))
739  return NULL;
740  if (key_number >= system->total_hostkeys)
741  {
743  _ ("Key number %u does not exist\n"),
744  key_number);
745  return NULL;
746  }
747  private_key = GNUNET_new (struct GNUNET_CRYPTO_EddsaPrivateKey);
748  GNUNET_memcpy (private_key,
749  system->hostkeys_data
750  + (key_number * GNUNET_TESTING_HOSTKEYFILESIZE),
752  GNUNET_CRYPTO_eddsa_key_get_public (private_key, &id->public_key);
753  return private_key;
754 }
755 
756 
761 struct UpdateContext
762 {
767 
772 
776  char *gnunet_home;
777 
783  uint16_t *ports;
784 
788  unsigned int nports;
789 
793  int status;
794 };
795 
796 
807 static void
808 update_config (void *cls,
809  const char *section,
810  const char *option,
811  const char *value)
812 {
813  struct UpdateContext *uc = cls;
814  unsigned int ival;
815  char cval[12];
816  char uval[PATH_MAX];
817  char *single_variable;
818  char *per_host_variable;
819  unsigned long long num_per_host;
820  uint16_t new_port;
821 
822  if (GNUNET_OK != uc->status)
823  return;
824  if (! ((0 == strcmp (option, "PORT")) || (0 == strcmp (option, "UNIXPATH")) ||
825  (0 == strcmp (option, "HOSTNAME"))))
826  return;
827  GNUNET_asprintf (&single_variable, "single_%s_per_host", section);
828  GNUNET_asprintf (&per_host_variable, "num_%s_per_host", section);
829  if ((0 == strcmp (option, "PORT")) && (1 == sscanf (value, "%u", &ival)))
830  {
831  if ((ival != 0) &&
833  "testing",
834  single_variable)))
835  {
836  new_port = GNUNET_TESTING_reserve_port (uc->system);
837  if (0 == new_port)
838  {
839  uc->status = GNUNET_SYSERR;
840  GNUNET_free (single_variable);
841  GNUNET_free (per_host_variable);
842  return;
843  }
844  GNUNET_snprintf (cval, sizeof(cval), "%u", new_port);
845  value = cval;
846  GNUNET_array_append (uc->ports, uc->nports, new_port);
847  }
848  else if ((ival != 0) &&
849  (GNUNET_YES ==
851  "testing",
852  single_variable)) &&
854  "testing",
855  per_host_variable,
856  &num_per_host))
857  {
858  /* GNUNET_snprintf (cval, sizeof (cval), "%u", */
859  /* ival + ctx->fdnum % num_per_host); */
860  /* value = cval; */
861  GNUNET_break (0); /* FIXME */
862  }
863  }
864  if (0 == strcmp (option, "UNIXPATH"))
865  {
867  "testing",
868  single_variable))
869  {
870  GNUNET_snprintf (uval,
871  sizeof(uval),
872  "%s/%s.sock",
873  uc->gnunet_home,
874  section);
875  value = uval;
876  }
877  else if ((GNUNET_YES ==
879  "testing",
880  per_host_variable,
881  &num_per_host)) &&
882  (num_per_host > 0))
883  {
884  GNUNET_break (0); /* FIXME */
885  }
886  }
887  if (0 == strcmp (option, "HOSTNAME"))
888  {
889  value = (NULL == uc->system->hostname) ? "localhost" : uc->system->hostname;
890  }
891  GNUNET_free (single_variable);
892  GNUNET_free (per_host_variable);
893  GNUNET_CONFIGURATION_set_value_string (uc->cfg, section, option, value);
894 }
895 
896 
904 static void
905 update_config_sections (void *cls, const char *section)
906 {
907  struct UpdateContext *uc = cls;
908  char **ikeys;
909  char *val;
910  char *ptr;
911  char *orig_allowed_hosts;
912  char *allowed_hosts;
913  char *ACCEPT_FROM_key;
914  uint16_t ikeys_cnt;
915  uint16_t key;
916 
917  ikeys_cnt = 0;
918  val = NULL;
919  /* Ignore certain options from sections. See
920  https://gnunet.org/bugs/view.php?id=2476 */
921  if (GNUNET_YES ==
922  GNUNET_CONFIGURATION_have_value (uc->cfg, section, "TESTING_IGNORE_KEYS"))
923  {
926  section,
927  "TESTING_IGNORE_KEYS",
928  &val));
929  ptr = val;
930  for (ikeys_cnt = 0; NULL != (ptr = strstr (ptr, ";")); ikeys_cnt++)
931  ptr++;
932  if (0 == ikeys_cnt)
933  GNUNET_break (0);
934  else
935  {
936  ikeys = GNUNET_malloc ((sizeof(char *)) * ikeys_cnt);
937  ptr = val;
938  for (key = 0; key < ikeys_cnt; key++)
939  {
940  ikeys[key] = ptr;
941  ptr = strstr (ptr, ";");
942  GNUNET_assert (NULL != ptr); /* worked just before... */
943  *ptr = '\0';
944  ptr++;
945  }
946  }
947  }
948  if (0 != ikeys_cnt)
949  {
950  for (key = 0; key < ikeys_cnt; key++)
951  {
952  if (NULL != strstr (ikeys[key], "ADVERTISED_PORT"))
953  break;
954  }
955  if ((key == ikeys_cnt) &&
956  (GNUNET_YES ==
957  GNUNET_CONFIGURATION_have_value (uc->cfg, section, "ADVERTISED_PORT")))
958  {
960  section,
961  "PORT",
962  &ptr))
963  {
965  section,
966  "ADVERTISED_PORT",
967  ptr);
968  GNUNET_free (ptr);
969  }
970  }
971  for (key = 0; key < ikeys_cnt; key++)
972  {
973  if (NULL != strstr (ikeys[key], "ACCEPT_FROM"))
974  {
975  GNUNET_free (ikeys);
976  GNUNET_free (val);
977  return;
978  }
979  }
980  GNUNET_free (ikeys);
981  }
982  GNUNET_free (val);
983  ACCEPT_FROM_key = "ACCEPT_FROM";
984  if ((NULL != uc->system->trusted_ip) &&
985  (NULL != strstr (uc->system->trusted_ip, ":"))) /* IPv6 in use */
986  ACCEPT_FROM_key = "ACCEPT_FROM6";
988  section,
989  ACCEPT_FROM_key,
990  &orig_allowed_hosts))
991  {
992  orig_allowed_hosts = GNUNET_strdup ("127.0.0.1;");
993  }
994  if (NULL == uc->system->trusted_ip)
995  allowed_hosts = GNUNET_strdup (orig_allowed_hosts);
996  else
997  GNUNET_asprintf (&allowed_hosts,
998  "%s%s;",
999  orig_allowed_hosts,
1000  uc->system->trusted_ip);
1001  GNUNET_free (orig_allowed_hosts);
1003  section,
1004  ACCEPT_FROM_key,
1005  allowed_hosts);
1006  GNUNET_free (allowed_hosts);
1007 }
1008 
1009 
1010 static struct SharedServiceInstance *
1012  struct SharedService *ss,
1014 {
1015  struct SharedServiceInstance *i;
1016  struct GNUNET_CONFIGURATION_Handle *temp;
1017  char *gnunet_home;
1018  uint32_t port;
1019 
1020  ss->n_peers++;
1021  if (((0 == ss->share) && (NULL == ss->instances)) ||
1022  ((0 != ss->share) &&
1023  (ss->n_instances < ((ss->n_peers + ss->share - 1) / ss->share))))
1024  {
1025  i = GNUNET_new (struct SharedServiceInstance);
1026  i->ss = ss;
1027  (void) GNUNET_asprintf (&gnunet_home,
1028  "%s/shared/%s/%u",
1029  system->tmppath,
1030  ss->sname,
1031  ss->n_instances);
1032  (void) GNUNET_asprintf (&i->unix_sock, "%s/sock", gnunet_home);
1033  port = GNUNET_TESTING_reserve_port (system);
1034  if (0 == port)
1035  {
1036  GNUNET_free (gnunet_home);
1038  return NULL;
1039  }
1041  temp = GNUNET_CONFIGURATION_dup (ss->cfg);
1042  (void) GNUNET_asprintf (&i->port_str, "%u", port);
1043  (void) GNUNET_asprintf (&i->cfg_fn, "%s/config", gnunet_home);
1045  "PATHS",
1046  "GNUNET_HOME",
1047  gnunet_home);
1048  GNUNET_free (gnunet_home);
1050  ss->sname,
1051  "UNIXPATH",
1052  i->unix_sock);
1054  ss->sname,
1055  "PORT",
1056  i->port_str);
1058  {
1061  return NULL;
1062  }
1064  }
1065  else
1066  {
1067  GNUNET_assert (NULL != ss->instances);
1068  GNUNET_assert (0 < ss->n_instances);
1069  i = ss->instances[ss->n_instances - 1];
1070  }
1072  ss->sname,
1074  cfg);
1076  ss->sname,
1077  "UNIXPATH",
1078  i->unix_sock);
1080  return i;
1081 }
1082 
1083 
1103 static int
1106  uint16_t **ports,
1107  unsigned int *nports)
1108 {
1109  struct UpdateContext uc;
1110  char *default_config;
1111 
1112  uc.system = system;
1113  uc.cfg = cfg;
1114  uc.status = GNUNET_OK;
1115  uc.ports = NULL;
1116  uc.nports = 0;
1117  GNUNET_asprintf (&uc.gnunet_home,
1118  "%s/%u",
1119  system->tmppath,
1120  system->path_counter++);
1121  GNUNET_asprintf (&default_config, "%s/config", uc.gnunet_home);
1123  "PATHS",
1124  "DEFAULTCONFIG",
1125  default_config);
1126  GNUNET_CONFIGURATION_set_value_string (cfg, "arm", "CONFIG", default_config);
1127  GNUNET_free (default_config);
1129  "PATHS",
1130  "GNUNET_HOME",
1131  uc.gnunet_home);
1132  /* make PORTs and UNIXPATHs unique */
1134  /* allow connections to services from system trusted_ip host */
1136  /* enable loopback-based connections between peers */
1137  GNUNET_CONFIGURATION_set_value_string (cfg, "nat", "USE_LOCALADDR", "YES");
1138  GNUNET_free (uc.gnunet_home);
1139  if ((NULL != ports) && (NULL != nports))
1140  {
1141  *ports = uc.ports;
1142  *nports = uc.nports;
1143  }
1144  else
1145  GNUNET_free (uc.ports);
1146  return uc.status;
1147 }
1148 
1149 
1166 int
1169 {
1170  return GNUNET_TESTING_configuration_create_ (system, cfg, NULL, NULL);
1171 }
1172 
1173 
1187 struct GNUNET_TESTING_Peer *
1190  uint32_t key_number,
1191  struct GNUNET_PeerIdentity *id,
1192  char **emsg)
1193 {
1194  struct GNUNET_TESTING_Peer *peer;
1195  struct GNUNET_DISK_FileHandle *fd;
1196  char *hostkey_filename;
1197  char *config_filename;
1198  char *libexec_binary;
1199  char *emsg_;
1201  uint16_t *ports;
1202  struct SharedService *ss;
1203  struct SharedServiceInstance **ss_instances;
1204  unsigned int cnt;
1205  unsigned int nports;
1206 
1207  ports = NULL;
1208  nports = 0;
1209  ss_instances = NULL;
1210  if (NULL != emsg)
1211  *emsg = NULL;
1212  if (key_number >= system->total_hostkeys)
1213  {
1214  GNUNET_asprintf (
1215  &emsg_,
1216  _ (
1217  "You attempted to create a testbed with more than %u hosts. Please precompute more hostkeys first.\n"),
1218  (unsigned int) system->total_hostkeys);
1219  goto err_ret;
1220  }
1221  pk = NULL;
1222  if ((NULL != id) &&
1223  (NULL == (pk = GNUNET_TESTING_hostkey_get (system, key_number, id))))
1224  {
1225  GNUNET_asprintf (&emsg_,
1226  _ ("Failed to initialize hostkey for peer %u\n"),
1227  (unsigned int) key_number);
1228  goto err_ret;
1229  }
1230  if (NULL != pk)
1231  GNUNET_free (pk);
1232  if (GNUNET_NO == GNUNET_CONFIGURATION_have_value (cfg, "PEER", "PRIVATE_KEY"))
1233  {
1234  GNUNET_asprintf (
1235  &emsg_,
1236  _ ("PRIVATE_KEY option in PEER section missing in configuration\n"));
1237  goto err_ret;
1238  }
1239  /* Remove sections for shared services */
1240  for (cnt = 0; cnt < system->n_shared_services; cnt++)
1241  {
1242  ss = &system->shared_services[cnt];
1244  }
1245  if (GNUNET_OK !=
1246  GNUNET_TESTING_configuration_create_ (system, cfg, &ports, &nports))
1247  {
1248  GNUNET_asprintf (&emsg_,
1249  _ ("Failed to create configuration for peer "
1250  "(not enough free ports?)\n"));
1251  goto err_ret;
1252  }
1255  "PEER",
1256  "PRIVATE_KEY",
1257  &hostkey_filename));
1258  fd = GNUNET_DISK_file_open (hostkey_filename,
1262  if (NULL == fd)
1263  {
1264  GNUNET_asprintf (&emsg_,
1265  _ ("Cannot open hostkey file `%s': %s\n"),
1266  hostkey_filename,
1267  strerror (errno));
1268  GNUNET_free (hostkey_filename);
1269  goto err_ret;
1270  }
1271  GNUNET_free (hostkey_filename);
1274  system->hostkeys_data
1275  + (key_number * GNUNET_TESTING_HOSTKEYFILESIZE),
1277  {
1278  GNUNET_asprintf (&emsg_,
1279  _ ("Failed to write hostkey file for peer %u: %s\n"),
1280  (unsigned int) key_number,
1281  strerror (errno));
1283  goto err_ret;
1284  }
1286  ss_instances = GNUNET_new_array (system->n_shared_services,
1287  struct SharedServiceInstance*);
1288  for (cnt = 0; cnt < system->n_shared_services; cnt++)
1289  {
1290  ss = &system->shared_services[cnt];
1291  ss_instances[cnt] = associate_shared_service (system, ss, cfg);
1292  if (NULL == ss_instances[cnt])
1293  {
1294  emsg_ = GNUNET_strdup ("FIXME");
1295  goto err_ret;
1296  }
1297  }
1300  "PATHS",
1301  "DEFAULTCONFIG",
1302  &config_filename));
1303  if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, config_filename))
1304  {
1305  GNUNET_asprintf (&emsg_,
1306  _ (
1307  "Failed to write configuration file `%s' for peer %u: %s\n"),
1308  config_filename,
1309  (unsigned int) key_number,
1310  strerror (errno));
1311  GNUNET_free (config_filename);
1312  goto err_ret;
1313  }
1314  peer = GNUNET_new (struct GNUNET_TESTING_Peer);
1315  peer->ss_instances = ss_instances;
1316  peer->cfgfile = config_filename; /* Free in peer_destroy */
1318  libexec_binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-arm");
1319  if (GNUNET_SYSERR ==
1321  "arm",
1322  "PREFIX",
1323  &peer->main_binary))
1324  {
1325  /* No prefix */
1326  GNUNET_asprintf (&peer->main_binary, "%s", libexec_binary);
1327  peer->args = GNUNET_strdup ("");
1328  }
1329  else
1330  {
1331  peer->args = GNUNET_strdup (libexec_binary);
1332  }
1333  peer->system = system;
1334  peer->key_number = key_number;
1335  GNUNET_free (libexec_binary);
1336  peer->ports = ports; /* Free in peer_destroy */
1337  peer->nports = nports;
1338  return peer;
1339 
1340 err_ret:
1341  GNUNET_free (ss_instances);
1342  GNUNET_free (ports);
1343  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", emsg_);
1344  if (NULL != emsg)
1345  *emsg = emsg_;
1346  else
1347  GNUNET_free (emsg_);
1348  return NULL;
1349 }
1350 
1351 
1358 void
1360  struct GNUNET_PeerIdentity *id)
1361 {
1362  if (NULL != peer->id)
1363  {
1364  GNUNET_memcpy (id, peer->id, sizeof(struct GNUNET_PeerIdentity));
1365  return;
1366  }
1367  peer->id = GNUNET_new (struct GNUNET_PeerIdentity);
1368  GNUNET_free_nz (
1369  GNUNET_TESTING_hostkey_get (peer->system, peer->key_number, peer->id));
1370  GNUNET_memcpy (id, peer->id, sizeof(struct GNUNET_PeerIdentity));
1371 }
1372 
1373 
1380 int
1382 {
1383  struct SharedServiceInstance *i;
1384  unsigned int cnt;
1385 
1386  if (NULL != peer->main_process)
1387  {
1388  GNUNET_break (0);
1389  return GNUNET_SYSERR;
1390  }
1391  GNUNET_assert (NULL != peer->cfgfile);
1392  for (cnt = 0; cnt < peer->system->n_shared_services; cnt++)
1393  {
1394  i = peer->ss_instances[cnt];
1395  if ((0 == i->n_refs) &&
1397  return GNUNET_SYSERR;
1398  i->n_refs++;
1399  }
1400  peer->main_binary =
1401  GNUNET_CONFIGURATION_expand_dollar (peer->cfg, peer->main_binary);
1402  peer->main_process =
1404  NULL,
1405  peer->main_binary,
1406  peer->args,
1407  "-c",
1408  peer->cfgfile,
1409  NULL);
1410  if (NULL == peer->main_process)
1411  {
1413  _ ("Failed to start `%s': %s\n"),
1414  peer->main_binary,
1415  strerror (errno));
1416  return GNUNET_SYSERR;
1417  }
1418  return GNUNET_OK;
1419 }
1420 
1421 
1429 int
1431 {
1432  struct SharedServiceInstance *i;
1433  unsigned int cnt;
1434 
1435  if (NULL == peer->main_process)
1436  {
1437  GNUNET_break (0);
1438  return GNUNET_SYSERR;
1439  }
1440  if (0 != GNUNET_OS_process_kill (peer->main_process, GNUNET_TERM_SIG))
1441  return GNUNET_SYSERR;
1442  for (cnt = 0; cnt < peer->system->n_shared_services; cnt++)
1443  {
1444  i = peer->ss_instances[cnt];
1445  GNUNET_assert (0 != i->n_refs);
1446  i->n_refs--;
1447  if (0 == i->n_refs)
1449  }
1450  return GNUNET_OK;
1451 }
1452 
1453 
1461 int
1463 {
1464  int ret;
1465 
1466  if (NULL == peer->main_process)
1467  {
1468  GNUNET_break (0);
1469  return GNUNET_SYSERR;
1470  }
1471  ret = GNUNET_OS_process_wait (peer->main_process);
1472  GNUNET_OS_process_destroy (peer->main_process);
1473  peer->main_process = NULL;
1474  return ret;
1475 }
1476 
1477 
1484 int
1486 {
1488  return GNUNET_SYSERR;
1490  return GNUNET_SYSERR;
1491  return GNUNET_OK;
1492 }
1493 
1494 
1502 static void
1503 disconn_status (void *cls, int connected)
1504 {
1505  struct GNUNET_TESTING_Peer *peer = cls;
1506 
1507  if (GNUNET_SYSERR == connected)
1508  {
1509  peer->cb (peer->cb_cls, peer, connected);
1510  return;
1511  }
1512  if (GNUNET_YES == connected)
1513  {
1515  return;
1516  }
1519  peer->ah = NULL;
1520  peer->cb (peer->cb_cls, peer, GNUNET_YES);
1521 }
1522 
1523 
1524 int
1527  void *cb_cls)
1528 {
1529  if (NULL == peer->main_process)
1530  return GNUNET_SYSERR;
1532  if (NULL == peer->ah)
1533  return GNUNET_SYSERR;
1534  peer->cb = cb;
1535  peer->cb_cls = cb_cls;
1536  return GNUNET_OK;
1537 }
1538 
1539 
1549 void
1551 {
1552  GNUNET_assert (NULL != peer->ah);
1554  peer->ah = NULL;
1555 }
1556 
1557 
1565 void
1567 {
1568  unsigned int cnt;
1569 
1570  if (NULL != peer->main_process)
1572  if (NULL != peer->ah)
1574  GNUNET_free (peer->cfgfile);
1575  if (NULL != peer->cfg)
1577  GNUNET_free (peer->main_binary);
1578  GNUNET_free (peer->args);
1579  GNUNET_free (peer->id);
1580  GNUNET_free (peer->ss_instances);
1581  if (NULL != peer->ports)
1582  {
1583  for (cnt = 0; cnt < peer->nports; cnt++)
1584  GNUNET_TESTING_release_port (peer->system, peer->ports[cnt]);
1585  GNUNET_free (peer->ports);
1586  }
1587  GNUNET_free (peer);
1588 }
1589 
1590 
1591 int
1592 GNUNET_TESTING_peer_run (const char *testdir,
1593  const char *cfgfilename,
1595  void *tm_cls)
1596 {
1597  return GNUNET_TESTING_service_run (testdir, "arm", cfgfilename, tm, tm_cls);
1598 }
1599 
1600 
1605 {
1610 
1615 
1620 
1624  void *tm_cls;
1625 };
1626 
1627 
1633 static void
1634 service_run_main (void *cls)
1635 {
1636  struct ServiceContext *sc = cls;
1637 
1638  sc->tm (sc->tm_cls, sc->cfg, sc->peer);
1639 }
1640 
1641 
1642 int
1643 GNUNET_TESTING_service_run (const char *testdir,
1644  const char *service_name,
1645  const char *cfgfilename,
1647  void *tm_cls)
1648 {
1649  struct ServiceContext sc;
1650  struct GNUNET_TESTING_System *system;
1651  struct GNUNET_TESTING_Peer *peer;
1653  char *binary;
1654  char *libexec_binary;
1655 
1656  GNUNET_log_setup (testdir, "WARNING", NULL);
1657  system = GNUNET_TESTING_system_create (testdir, "127.0.0.1", NULL, NULL);
1658  if (NULL == system)
1659  return 1;
1661  if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, cfgfilename))
1662  {
1664  _ ("Failed to load configuration from %s\n"),
1665  cfgfilename);
1668  return 1;
1669  }
1670  peer = GNUNET_TESTING_peer_configure (system, cfg, 0, NULL, NULL);
1671  if (NULL == peer)
1672  {
1674  hostkeys_unload (system);
1676  return 1;
1677  }
1678  GNUNET_free (peer->main_binary);
1679  GNUNET_free (peer->args);
1680  GNUNET_asprintf (&binary, "gnunet-service-%s", service_name);
1681  libexec_binary = GNUNET_OS_get_libexec_binary_path (binary);
1682  if (GNUNET_SYSERR ==
1684  service_name,
1685  "PREFIX",
1686  &peer->main_binary))
1687  {
1688  /* No prefix */
1689  GNUNET_asprintf (&peer->main_binary, "%s", libexec_binary);
1690  peer->args = GNUNET_strdup ("");
1691  }
1692  else
1693  peer->args = GNUNET_strdup (libexec_binary);
1694 
1695  GNUNET_free (libexec_binary);
1696  GNUNET_free (binary);
1698  {
1702  return 1;
1703  }
1704  sc.cfg = cfg;
1705  sc.tm = tm;
1706  sc.tm_cls = tm_cls;
1707  sc.peer = peer;
1708  GNUNET_SCHEDULER_run (&service_run_main, &sc); /* Scheduler loop */
1709  if ((NULL != peer->main_process) &&
1711  {
1715  return 1;
1716  }
1720  return 0;
1721 }
1722 
1723 
1733 static unsigned int
1734 get_first_value (const char *line)
1735 {
1736  char *copy;
1737  size_t slen;
1738  char *token;
1739  unsigned int ret;
1740  char *rest = NULL;
1741 
1742  slen = strlen (line) + 1;
1743  copy = GNUNET_malloc (slen);
1744  memcpy (copy, line, slen);
1745  token = strtok_r (copy, ":", &rest);
1746  token = strtok_r (NULL, ":", &rest);
1747  GNUNET_assert (1 == sscanf (token, "%u", &ret));
1748  GNUNET_free (copy);
1749  return ret;
1750 }
1751 
1752 
1760 static char *
1761 get_key (const char *line)
1762 {
1763  char *copy;
1764  size_t slen;
1765  size_t tlen;
1766  char *token;
1767  char *ret;
1768  char *rest = NULL;
1769 
1770  slen = strlen (line) + 1;
1771  copy = GNUNET_malloc (slen);
1772  memcpy (copy, line, slen);
1773  token = strtok_r (copy, ":", &rest);
1774  tlen = strlen (token) + 1;
1775  ret = GNUNET_malloc (tlen);
1776  memcpy (ret, token, tlen);
1777  GNUNET_free (copy);
1778  return ret;
1779 }
1780 
1781 
1791 static char *
1793 {
1794  char *copy;
1795  size_t slen, slen_token;
1796  char *token;
1797  char *ret;
1798  char *rest = NULL;
1799 
1800  slen = strlen (line) + 1;
1801  copy = GNUNET_malloc (slen);
1802  memcpy (copy, line, slen);
1803  token = strtok_r (copy, ":", &rest);
1804  token = strtok_r (NULL, ":", &rest);
1806  "first token %s\n",
1807  token);
1808  slen_token = strlen (token);
1809  ret = GNUNET_malloc (slen_token + 1);
1810  memcpy (ret, token, slen_token + 1);
1811  GNUNET_free (copy);
1812  return ret;
1813 }
1814 
1815 
1825 static unsigned int
1826 get_second_value (const char *line)
1827 {
1828  char *copy;
1829  char *token;
1830  unsigned int ret;
1831  char *rest = NULL;
1832 
1833  copy = GNUNET_strdup (line);
1834  token = strtok_r (copy, ":", &rest);
1835  token = strtok_r (NULL, ":", &rest);
1836  token = strtok_r (NULL, ":", &rest);
1838  "Format error in configuration line: %s\n",
1839  line);
1840  GNUNET_assert (1 == sscanf (token, "%u", &ret));
1841  GNUNET_free (copy);
1842  return ret;
1843 }
1844 
1845 
1856 static char *
1857 get_value (const char *key, const char *line)
1858 {
1859  char copy[strlen (line) + 1];
1860  size_t slen;
1861  char *token;
1862  char *token2;
1863  char *temp;
1864  char *rest = NULL;
1865 
1866  slen = strlen (line) + 1;
1867  memcpy (copy, line, slen);
1868  temp = strstr (copy, key);
1869  if (NULL == temp)
1870  return NULL;
1871  token = strtok_r (temp, ":", &rest);
1872  if (NULL == token)
1873  return NULL;
1874  token = strtok_r (NULL, ":", &rest);
1875  if (NULL == token)
1876  return NULL;
1877  token2 = strtok_r (token, "}", &rest);
1878  if (NULL == token2)
1879  return NULL;
1880  return GNUNET_strdup (token2);
1881 }
1882 
1883 
1896 static struct GNUNET_TESTING_NodeConnection *
1899 {
1900  struct GNUNET_TESTING_NodeConnection *node_connection;
1901  char *copy;
1902  char *token;
1903  char *token2;
1904  unsigned int node_n;
1905  unsigned int namespace_n;
1906  char *rest = NULL;
1907  char *rest2 = NULL;
1909  unsigned int sscanf_ret;
1910 
1911  node_connection = GNUNET_new (struct GNUNET_TESTING_NodeConnection);
1912  node_connection->node = node;
1913 
1914  copy = GNUNET_strdup (line);
1915  token = strtok_r (copy, ":", &rest);
1916  if (0 == strcmp ("{K", token))
1917  {
1918  node_connection->node_type = GNUNET_TESTING_GLOBAL_NODE;
1919  token = strtok_r (NULL, ":", &rest);
1920  GNUNET_assert (1 == sscanf (token, "%u", &node_n));
1922  "node_n %u\n",
1923  node_n);
1924  node_connection->node_n = node_n;
1925  node_connection->namespace_n = 0;
1926  }
1927  else if (0 == strcmp ("{P", token))
1928  {
1929  node_connection->node_type = GNUNET_TESTING_SUBNET_NODE;
1930  token = strtok_r (NULL, ":", &rest);
1931  errno = 0;
1932  sscanf_ret = sscanf (token, "%u", &namespace_n);
1933  if (errno != 0)
1934  {
1936  }
1937  GNUNET_assert (0 < sscanf_ret);
1938  node_connection->namespace_n = namespace_n;
1939  token = strtok_r (NULL, ":", &rest);
1940  errno = 0;
1941  sscanf_ret = sscanf (token, "%u", &node_n);
1942  if (errno != 0)
1943  {
1945  }
1946  GNUNET_assert (0 < sscanf_ret);
1947  node_connection->node_n = node_n;
1949  "node_n %u namespace_n %u node->node_n %u node->namespace_n %u\n",
1950  node_n,
1951  namespace_n,
1952  node->node_n,
1953  node->namespace_n);
1954  }
1955  else
1956  {
1957  GNUNET_break (0);
1958  GNUNET_free (node_connection);
1959  GNUNET_free (copy);
1960  return NULL;
1961  }
1962 
1963  while (NULL != (token = strtok_r (NULL, ":", &rest)))
1964  {
1966  token2 = strtok_r (token, "}", &rest2);
1967  if (NULL != token2)
1968  prefix->address_prefix = GNUNET_strdup (token2);
1969  else
1970  prefix->address_prefix = GNUNET_strdup (token);
1971 
1973  "address_prefix %s\n",
1974  prefix->address_prefix);
1975 
1977  node_connection->address_prefixes_tail,
1978  prefix);
1980  "address_prefix %s\n",
1981  prefix->address_prefix);
1982  }
1983 
1984  GNUNET_free (copy);
1985  return node_connection;
1986 }
1987 
1988 
2005 static void
2007 {
2008  char *value, *value2;
2009  char *temp;
2010  char *copy;
2011  char *rest = NULL;
2012  char *rest2 = NULL;
2013  struct GNUNET_TESTING_NodeConnection *node_connection;
2014 
2015 
2016  temp = strstr (line, "connect");
2017  if (NULL != temp)
2018  {
2019  copy = GNUNET_strdup (temp);
2020  strtok_r (copy, ":", &rest);
2021  value = strtok_r (rest, "|", &rest2);
2022 
2023  while (NULL != value)
2024  {
2026  "node_connections value %s\n",
2027  value);
2028  node_connection = get_connect_value (value, node);
2029  if (NULL == node_connection)
2030  {
2032  "connect key was not expected in this configuration line: %s\n",
2033  line);
2034  break;
2035  }
2038  node_connection);
2039  value2 = strstr (value, "}}");
2040  if (NULL != value2)
2041  break;
2042  value = strtok_r (NULL, "|", &rest2);
2043 
2044  }
2045  GNUNET_free (copy);
2046  }
2047 }
2048 
2049 
2058 static int
2059 log_nodes (void *cls, const struct GNUNET_ShortHashCode *id, void *value)
2060 {
2061  struct GNUNET_TESTING_NetjailNode *node = value;
2062  struct GNUNET_TESTING_NodeConnection *pos_connection;
2063  struct GNUNET_TESTING_AddressPrefix *pos_prefix;
2064 
2066  "plugin: %s space: %u node: %u global: %u\n",
2067  node->plugin,
2068  node->namespace_n,
2069  node->node_n,
2070  node->is_global);
2071 
2072  for (pos_connection = node->node_connections_head; NULL != pos_connection;
2073  pos_connection = pos_connection->next)
2074  {
2075 
2077  "namespace_n: %u node_n: %u node_type: %u\n",
2078  pos_connection->namespace_n,
2079  pos_connection->node_n,
2080  pos_connection->node_type);
2081 
2082  for (pos_prefix = pos_connection->address_prefixes_head; NULL != pos_prefix;
2083  pos_prefix =
2084  pos_prefix->next)
2085  {
2087  "prefix: %s\n",
2088  pos_prefix->address_prefix);
2089  }
2090  }
2091  return GNUNET_YES;
2092 }
2093 
2094 
2103 static int
2104 log_namespaces (void *cls, const struct GNUNET_ShortHashCode *id, void *value)
2105 {
2106  struct GNUNET_TESTING_NetjailNamespace *namespace = value;
2107 
2108  GNUNET_CONTAINER_multishortmap_iterate (namespace->nodes, &log_nodes, NULL);
2109  return GNUNET_YES;
2110 }
2111 
2112 
2118 static int
2120 {
2122  "plugin: %s spaces: %u nodes: %u known: %u\n",
2123  topology->plugin,
2124  topology->namespaces_n,
2125  topology->nodes_m,
2126  topology->nodes_x);
2127 
2129  log_namespaces, NULL);
2131  NULL);
2132  return GNUNET_YES;
2133 }
2134 
2135 
2146 static void
2147 get_node_info (unsigned int num,
2149  struct GNUNET_TESTING_NetjailNode **node_ex,
2150  struct GNUNET_TESTING_NetjailNamespace **namespace_ex,
2151  struct GNUNET_TESTING_NodeConnection **node_connections_ex)
2152 {
2153  struct GNUNET_ShortHashCode hkey;
2154  struct GNUNET_HashCode hc;
2155  unsigned int namespace_n;
2156  unsigned int node_m;
2157  struct GNUNET_TESTING_NetjailNode *node;
2158  struct GNUNET_TESTING_NetjailNamespace *namespace;
2160 
2161  log_topo (topology);
2163  "num: %u \n",
2164  num);
2165  if (topology->nodes_x >= num)
2166  {
2167 
2168  GNUNET_CRYPTO_hash (&num, sizeof(num), &hc);
2169  memcpy (&hkey,
2170  &hc,
2171  sizeof (hkey));
2173  &hkey);
2174  if (NULL != node)
2175  {
2176  *node_ex = node;
2177  *node_connections_ex = node->node_connections_head;
2178  }
2179  }
2180  else
2181  {
2182  namespace_n = (unsigned int) ceil ((double) (num - topology->nodes_x)
2183  / topology->nodes_m);
2185  "ceil num: %u nodes_x: %u nodes_m: %u namespace_n: %u\n",
2186  num,
2187  topology->nodes_x,
2188  topology->nodes_m,
2189  namespace_n);
2190  GNUNET_CRYPTO_hash (&namespace_n, sizeof(namespace_n), &hc);
2191  memcpy (&hkey,
2192  &hc,
2193  sizeof (hkey));
2194  namespace = GNUNET_CONTAINER_multishortmap_get (topology->map_namespaces,
2195  &hkey);
2196  if (NULL != namespace)
2197  {
2198  node_m = num - topology->nodes_x - topology->nodes_m * (namespace_n - 1);
2199  GNUNET_CRYPTO_hash (&node_m, sizeof(node_m), &hc);
2200  memcpy (&hkey,
2201  &hc,
2202  sizeof (hkey));
2203  node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes,
2204  &hkey);
2205  if (NULL != node)
2206  {
2208  "node additional_connects: %u %p\n",
2209  node->additional_connects,
2210  node);
2212  }
2213  *node_ex = node;
2214  *namespace_ex = namespace;
2215  *node_connections_ex = node_connections;
2216  }
2217  }
2218 }
2219 
2220 
2229 GNUNET_TESTING_get_node (unsigned int num,
2231 {
2232  struct GNUNET_TESTING_NetjailNode *node;
2233  struct GNUNET_TESTING_NetjailNamespace *namespace;
2235 
2236  get_node_info (num, topology, &node, &namespace, &node_connections);
2237 
2238  return node;
2239 
2240 }
2241 
2242 
2252  const struct
2254 {
2255  struct GNUNET_TESTING_NetjailNode *node;
2256  struct GNUNET_TESTING_NetjailNamespace *namespace;
2258 
2260  "get_connections\n");
2261 
2262  get_node_info (num, topology, &node, &namespace, &node_connections);
2263 
2264  return node_connections;
2265 }
2266 
2267 
2275 struct GNUNET_PeerIdentity *
2276 GNUNET_TESTING_get_peer (unsigned int num,
2277  const struct GNUNET_TESTING_System *tl_system)
2278 {
2280  struct GNUNET_CRYPTO_EddsaPrivateKey *priv_key;
2281 
2282  priv_key = GNUNET_TESTING_hostkey_get (tl_system,
2283  num,
2284  peer);
2285 
2287  &peer->public_key);
2288  GNUNET_free (priv_key);
2289  return peer;
2290 }
2291 
2292 
2293 int
2294 free_nodes_cb (void *cls,
2295  const struct GNUNET_ShortHashCode *key,
2296  void *value)
2297 {
2298  (void) cls;
2299  struct GNUNET_TESTING_NetjailNode *node = value;
2300  struct GNUNET_TESTING_NodeConnection *pos_connection;
2301  struct GNUNET_TESTING_AddressPrefix *pos_prefix;
2302 
2303  while (NULL != (pos_connection = node->node_connections_head))
2304  {
2305  while (NULL != (pos_prefix = pos_connection->address_prefixes_head))
2306  {
2308  pos_connection->address_prefixes_tail,
2309  pos_prefix);
2310  GNUNET_free (pos_prefix->address_prefix);
2311  GNUNET_free (pos_prefix);
2312  }
2314  node->node_connections_tail,
2315  pos_connection);
2316  GNUNET_free (pos_connection);
2317  }
2318 
2319  GNUNET_free (node->plugin);
2320  GNUNET_free (node);
2321  return GNUNET_OK;
2322 }
2323 
2324 
2325 int
2327  const struct GNUNET_ShortHashCode *key,
2328  void *value)
2329 {
2330  (void) cls;
2331  struct GNUNET_TESTING_NetjailNamespace *namespace = value;
2332 
2333  GNUNET_free (namespace->router);
2335  namespace->nodes);
2336  return GNUNET_OK;
2337 
2338 }
2339 
2340 
2346 void
2348 {
2350  free_namespaces_cb, NULL);
2353  NULL);
2355  GNUNET_free (topology->plugin);
2357 }
2358 
2359 
2360 unsigned int
2362  struct GNUNET_TESTING_NodeConnection *node_connection,
2364 {
2365  unsigned int n, m, num;
2366 
2367  n = node_connection->namespace_n;
2368  m = node_connection->node_n;
2369 
2370  if (0 == n)
2371  num = m;
2372  else
2373  num = (n - 1) * topology->nodes_m + m + topology->nodes_x;
2374 
2375  return num;
2376 }
2377 
2378 
2386 char *
2388  const char *prefix)
2389 {
2390  struct GNUNET_TESTING_NetjailNode *node;
2391  char *addr;
2392  char *template;
2393  unsigned int node_n;
2394 
2396  "get address prefix: %s node_n: %u\n",
2397  prefix,
2398  connection->node_n);
2399 
2400  node = connection->node;
2401  if (connection->namespace_n == node->namespace_n)
2402  {
2403  template = CONNECT_ADDRESS_TEMPLATE;
2404  node_n = connection->node_n;
2405  }
2406  else if (0 == connection->namespace_n)
2407  {
2408  template = KNOWN_CONNECT_ADDRESS_TEMPLATE;
2409  node_n = connection->node_n;
2410  }
2411  else if (1 == connection->node_n)
2412  {
2414  node_n = connection->namespace_n;
2415  }
2416  else
2417  {
2418  return NULL;
2419  }
2420 
2421  if (0 == strcmp (PREFIX_TCP, prefix) ||
2422  0 == strcmp (PREFIX_UDP, prefix) ||
2423  0 == strcmp (PREFIX_UDP_NATTED, prefix) ||
2424  0 == strcmp (PREFIX_TCP_NATTED, prefix))
2425  {
2426  GNUNET_asprintf (&addr,
2427  template,
2428  prefix,
2429  node_n);
2430  }
2431  else
2432  {
2433  GNUNET_assert (0);
2434  }
2435 
2436  return addr;
2437 }
2438 
2439 
2446 unsigned int
2449  topology)
2450 {
2451  struct GNUNET_TESTING_NetjailNode *node;
2452  struct GNUNET_TESTING_NetjailNamespace *namespace;
2454 
2456  "get_additional_connects\n");
2457 
2458  get_node_info (num, topology, &node, &namespace, &node_connections);
2459 
2460  if (NULL == node)
2461  {
2463  "No info found for node %d\n", num);
2464  return 0;
2465  }
2467  "node additional_connects for node %p\n",
2468  node);
2470  "node additional_connects: %u\n",
2471  node->additional_connects);
2472 
2473  return node->additional_connects;
2474 }
2475 
2476 
2477 static void
2478 parse_ac (struct GNUNET_TESTING_NetjailNode *p_node, const char *token)
2479 {
2480  char *ac_value;
2481  int ret;
2482 
2483  ac_value = get_value ("AC", token);
2484  if (NULL != ac_value)
2485  {
2487  "ac value: %s\n",
2488  ac_value);
2489  errno = 0;
2490  ret = sscanf (ac_value, "%u", &p_node->additional_connects);
2491  if (errno != 0)
2492  {
2494  }
2495  GNUNET_assert (0 < ret);
2497  "AC %u\n",
2498  p_node->additional_connects);
2499  }
2500  else
2501  {
2502  p_node->additional_connects = 0;
2503  }
2504  GNUNET_free (ac_value);
2505 }
2506 
2507 
2516 {
2517  char *token;
2518  char *key = NULL;
2519  unsigned int out;
2520  char *rest = NULL;
2521  char *value = NULL;
2522  char *value2;
2523  char *data;
2524  int ret;
2525  struct GNUNET_TESTING_NetjailTopology *topo;
2526  struct GNUNET_TESTING_NetjailRouter *router;
2527  struct GNUNET_TESTING_NetjailNamespace *namespace;
2528  struct GNUNET_HashCode hc;
2529 
2530  data = GNUNET_strdup (input);
2531  token = strtok_r (data, "\n", &rest);
2533  topo->map_namespaces =
2535  topo->map_globals =
2537 
2538  while (NULL != token)
2539  {
2540  if (NULL != key)
2541  GNUNET_free (key);
2542  key = get_key (token);
2544  "In the loop with token: %s beginning with %s\n",
2545  token,
2546  key);
2547  if (0 == strcmp (key, "M"))
2548  {
2550  "Get first Value for M.\n");
2551  out = get_first_value (token);
2553  "M: %u\n",
2554  out);
2555  topo->nodes_m = out;
2556  }
2557  else if (0 == strcmp (key, "N"))
2558  {
2560  "Get first Value for N.\n");
2561  out = get_first_value (token);
2563  "N: %u\n",
2564  out);
2565  topo->namespaces_n = out;
2566  }
2567  else if (0 == strcmp (key, "X"))
2568  {
2570  "Get first Value for X.\n");
2571  out = get_first_value (token);
2573  "X: %u\n",
2574  out);
2575  topo->nodes_x = out;
2576  }
2577  else if (0 == strcmp (key, "AC"))
2578  {
2580  "Get first Value for AC.\n");
2581  out = get_first_value (token);
2583  "AC: %u\n",
2584  out);
2585  topo->additional_connects = out;
2586  }
2587  else if (0 == strcmp (key, "T"))
2588  {
2590  "Get first string value for T.\n");
2591  value = get_first_string_value (token);
2593  "value: %s\n",
2594  value);
2595  topo->plugin = value;
2596  }
2597  else if (0 == strcmp (key, "K"))
2598  {
2599  struct GNUNET_ShortHashCode hkey_k;
2600  struct GNUNET_TESTING_NetjailNode *k_node = GNUNET_new (struct
2602 
2604  "Get first Value for K.\n");
2605  out = get_first_value (token);
2607  "K: %u\n",
2608  out);
2609  k_node->node_n = out;
2610  GNUNET_CRYPTO_hash (&out, sizeof(out), &hc);
2611  memcpy (&hkey_k,
2612  &hc,
2613  sizeof (hkey_k));
2614  k_node->is_global = GNUNET_YES;
2615 
2617  topo->map_globals,
2618  &hkey_k))
2619  GNUNET_break (0);
2620  else
2622  &hkey_k,
2623  k_node,
2626  "Get value for key value on K.\n");
2627  value = get_value ("plugin", token);
2629  "value: %s\n",
2630  value);
2631  k_node->plugin = value;
2632  parse_ac (k_node, token);
2633  node_connections (token, k_node);
2634  GNUNET_free (value);
2635  }
2636  else if (0 == strcmp (key, "R"))
2637  {
2638  struct GNUNET_ShortHashCode hkey_r;
2639  router = GNUNET_new (struct GNUNET_TESTING_NetjailRouter);
2640 
2642  "Get first Value for R.\n");
2643  out = get_first_value (token);
2645  "R: %u\n",
2646  out);
2647  GNUNET_CRYPTO_hash (&out, sizeof(out), &hc);
2648  memcpy (&hkey_r,
2649  &hc,
2650  sizeof (hkey_r));
2652  "Get value for key tcp_port on R.\n");
2653  value = get_value ("tcp_port", token);
2655  "tcp_port: %s\n",
2656  value);
2657  ret = sscanf (value, "%u", &(router->tcp_port));
2658  GNUNET_free (value);
2659  GNUNET_break (0 != ret && 1 >= router->tcp_port);
2660 
2662  "Get value for key udp_port on R.\n");
2663  value2 = get_value ("udp_port", token);
2664  ret = sscanf (value2, "%u", &(router->udp_port));
2665  GNUNET_free (value2);
2666  GNUNET_break (0 != ret && 1 >= router->udp_port);
2668  "udp_port: %s\n",
2669  value2);
2670  GNUNET_free (value2);
2672  topo->map_namespaces,
2673  &hkey_r))
2674  {
2676  &hkey_r);
2677  }
2678  else
2679  {
2680  namespace = GNUNET_new (struct GNUNET_TESTING_NetjailNamespace);
2681  namespace->namespace_n = out;
2682  namespace->nodes = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
2684  &hkey_r,
2685  namespace,
2687  }
2688  namespace->router = router;
2689 
2690  }
2691  else if (0 == strcmp (key, "P"))
2692  {
2693  struct GNUNET_TESTING_NetjailNode *p_node = GNUNET_new (struct
2695  struct GNUNET_ShortHashCode hkey_p;
2696 
2698  "Get first Value for P.\n");
2699  out = get_first_value (token);
2701  "P: %u\n",
2702  out);
2703  GNUNET_CRYPTO_hash (&out, sizeof(out), &hc);
2704  memcpy (&hkey_p,
2705  &hc,
2706  sizeof (hkey_p));
2707 
2709  topo->map_namespaces,
2710  &hkey_p))
2711  {
2713  &hkey_p);
2714  }
2715  else
2716  {
2717  namespace = GNUNET_new (struct GNUNET_TESTING_NetjailNamespace);
2718  namespace->nodes = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
2719  namespace->namespace_n = out;
2721  &hkey_p,
2722  namespace,
2724  }
2726  "Get second Value for P.\n");
2727  out = get_second_value (token);
2729  "P: %u\n",
2730  out);
2731  GNUNET_CRYPTO_hash (&out, sizeof(out), &hc);
2732  memcpy (&hkey_p,
2733  &hc,
2734  sizeof (hkey_p));
2736  namespace->nodes,
2737  &hkey_p))
2738  {
2739  GNUNET_break (0);
2740  }
2741  else
2742  {
2743 
2744  GNUNET_CONTAINER_multishortmap_put (namespace->nodes,
2745  &hkey_p,
2746  p_node,
2749  "Get value for key plugin on P.\n");
2750  value = get_value ("plugin", token);
2751  if (NULL != value)
2752  {
2754  "plugin: %s\n",
2755  value);
2756  p_node->plugin = value;
2757  }
2758  p_node->node_n = out;
2759  p_node->namespace_n = namespace->namespace_n;
2760  }
2762  "Get AC Value for P.\n");
2763  parse_ac (p_node, token);
2764  node_connections (token, p_node);
2765  }
2766  token = strtok_r (NULL, "\n", &rest);
2767  if (NULL != token)
2769  "Next token %s\n",
2770  token);
2771  }
2772  if (NULL != key)
2773  GNUNET_free (key);
2774  GNUNET_free (data);
2775  return topo;
2776 }
2777 
2778 
2787 {
2788  uint64_t fs;
2789  char *data;
2790  struct GNUNET_TESTING_NetjailTopology *topo;
2791 
2793  {
2795  _ ("Topology file %s not found\n"),
2796  filename);
2797  return NULL;
2798  }
2799  if (GNUNET_OK !=
2801  {
2803  _ ("Topology file %s has no data\n"),
2804  filename);
2805  return NULL;
2806  }
2807  data = GNUNET_malloc (fs + 1);
2808  if (fs != GNUNET_DISK_fn_read (filename, data, fs))
2809  {
2811  _ ("Topology file %s cannot be read\n"),
2812  filename);
2813  GNUNET_free (data);
2814  return NULL;
2815  }
2816 
2818  "file length %" PRIu64 "\n",
2819  fs);
2820  data[fs] = '\0';
2821 
2823 
2824  GNUNET_free (data);
2825 
2826  return topo;
2827 }
2828 
2829 
2830 /* end of testing.c */
enum GNUNET_TESTBED_TopologyOption topology
The topology to generate.
char * getenv()
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
static int prefix
If printing the value of PREFIX has been requested.
Definition: gnunet-config.c:59
static char * line
Desired phone line (string to be converted to a hash).
static struct GNUNET_IDENTITY_Handle * id
Handle to identity service.
struct GNUNET_HashCode key
The key used in the DHT.
static char * filename
static struct GNUNET_FS_Handle * fs
Handle to FS service.
Definition: gnunet-fs.c:37
uint32_t data
The data value.
struct GNUNET_IDENTITY_PrivateKey pk
Private key from command line option, or NULL.
static char * value
Value of the record to add/remove.
static struct GNUNET_FS_SearchContext * sc
Definition: gnunet-search.c:87
static char * hostname
Our hostname; we give this to all the peers we start.
static struct GNUNET_FS_UnindexContext * uc
static char * service_name
Option -s: service name (hash to get service descriptor)
Definition: gnunet-vpn.c:50
API to manage barriers.
Convenience API for writing testcases for GNUnet.
@ GNUNET_TESTING_SUBNET_NODE
Node in a subnet.
@ GNUNET_TESTING_GLOBAL_NODE
Global known node.
struct GNUNET_ARM_Handle * GNUNET_ARM_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_ARM_ConnectionStatusCallback conn_status, void *conn_status_cls)
Set up a context for communicating with ARM, then start connecting to the ARM service using that cont...
Definition: arm_api.c:577
void GNUNET_ARM_disconnect(struct GNUNET_ARM_Handle *h)
Disconnect from the ARM service (if connected) and destroy the context.
Definition: arm_api.c:602
void GNUNET_CONFIGURATION_set_value_string(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
Set a configuration value that should be a string.
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.
void GNUNET_CONFIGURATION_remove_section(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section)
Remove the given section and all options in it.
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.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(void)
Create a new configuration object.
void GNUNET_CONFIGURATION_iterate_sections(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_SectionIterator iter, void *iter_cls)
Iterate over all sections in the configuration.
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
void GNUNET_CONFIGURATION_iterate(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_Iterator iter, void *iter_cls)
Iterate over all options in the configuration.
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".
char * GNUNET_CONFIGURATION_expand_dollar(const struct GNUNET_CONFIGURATION_Handle *cfg, char *orig)
Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR" where either in the "PATHS" section or...
enum GNUNET_GenericReturnValue 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.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_load(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Load configuration.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_write(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Write configuration file.
void GNUNET_CONFIGURATION_iterate_section_values(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, GNUNET_CONFIGURATION_Iterator iter, void *iter_cls)
Iterate over values of a section in the configuration.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_dup(const struct GNUNET_CONFIGURATION_Handle *cfg)
Duplicate an existing configuration object.
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:198
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:1237
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
Definition: disk.c:482
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:686
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:221
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:1380
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition: disk.c:1087
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1308
char * GNUNET_DISK_mkdtemp(const char *t)
Create an (empty) temporary directory on disk.
Definition: disk.c:339
enum GNUNET_GenericReturnValue GNUNET_DISK_file_unmap(struct GNUNET_DISK_MapHandle *h)
Unmap a file.
Definition: disk.c:1411
ssize_t GNUNET_DISK_fn_read(const char *fn, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:664
@ GNUNET_DISK_OPEN_READ
Open the file for reading.
@ GNUNET_DISK_OPEN_WRITE
Open the file for writing.
@ GNUNET_DISK_OPEN_CREATE
Create file if it doesn't exist.
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_NONE
Nobody is allowed to do anything to the file.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
@ GNUNET_DISK_MAP_TYPE_READ
Read-only memory map.
#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_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multishortmap_put(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
int GNUNET_CONTAINER_multishortmap_iterate(struct GNUNET_CONTAINER_MultiShortmap *map, GNUNET_CONTAINER_ShortmapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiShortmap * GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
void * GNUNET_CONTAINER_multishortmap_get(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
Given a key find a value in the map matching the key.
int GNUNET_CONTAINER_multishortmap_contains(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
Check if the map contains any value under the given key (including values that are NULL).
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
#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_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#define GNUNET_array_append(arr, len, element)
Append an element to an array (growing the array by one).
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_free_nz(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:509
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:833
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:440
char * GNUNET_OS_get_libexec_binary_path(const char *progname)
Given the name of a gnunet-helper, gnunet-service or gnunet-daemon binary, try to prefix it with the ...
struct GNUNET_OS_Process * GNUNET_OS_start_process(enum GNUNET_OS_InheritStdioFlags std_inheritance, struct GNUNET_DISK_PipeHandle *pipe_stdin, struct GNUNET_DISK_PipeHandle *pipe_stdout, struct GNUNET_DISK_PipeHandle *pipe_stderr, const char *filename,...)
Start a process.
Definition: os_priority.c:620
struct GNUNET_OS_Process * GNUNET_OS_start_process_s(enum GNUNET_OS_InheritStdioFlags std_inheritance, const int *lsocks, const char *filename,...)
Start a process.
Definition: os_priority.c:659
void GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition: os_priority.c:260
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,...
int GNUNET_OS_process_kill(struct GNUNET_OS_Process *proc, int sig)
Sends a signal to the process.
Definition: os_priority.c:210
enum GNUNET_GenericReturnValue GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc)
Wait for a process to terminate.
Definition: os_priority.c:871
@ GNUNET_OS_INHERIT_STD_OUT_AND_ERR
When these flags are set, the child process will inherit stdout and stderr of the parent.
@ GNUNET_OS_IPK_DATADIR
Return the directory where data is installed (share/gnunet/)
void GNUNET_SCHEDULER_run(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Initialize and run scheduler.
Definition: scheduler.c:720
int GNUNET_TESTING_peer_stop(struct GNUNET_TESTING_Peer *peer)
Stop the peer.
Definition: testing.c:1485
struct GNUNET_TESTING_System * GNUNET_TESTING_system_create(const char *testdir, const char *trusted_ip, const char *hostname, const struct GNUNET_TESTING_SharedService *shared_services)
Create a system handle.
Definition: testing.c:477
#define GNUNET_TESTING_PREFIX
The environmental variable, if set, that dictates where testing should place generated peer configura...
struct GNUNET_TESTING_System * GNUNET_TESTING_system_create_with_portrange(const char *testdir, const char *trusted_ip, const char *hostname, const struct GNUNET_TESTING_SharedService *shared_services, uint16_t lowport, uint16_t highport)
Create a system handle.
Definition: testing.c:392
struct GNUNET_TESTING_Peer * GNUNET_TESTING_peer_configure(struct GNUNET_TESTING_System *system, struct GNUNET_CONFIGURATION_Handle *cfg, uint32_t key_number, struct GNUNET_PeerIdentity *id, char **emsg)
Configure a GNUnet peer.
Definition: testing.c:1188
void(* GNUNET_TESTING_PeerStopCallback)(void *cls, struct GNUNET_TESTING_Peer *peer, int success)
Callback to inform whether the peer is running or stopped.
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_TESTING_hostkey_get(const struct GNUNET_TESTING_System *system, uint32_t key_number, struct GNUNET_PeerIdentity *id)
Testing includes a number of pre-created hostkeys for faster peer startup.
Definition: testing.c:732
int GNUNET_TESTING_peer_run(const char *testdir, const char *cfgfilename, GNUNET_TESTING_TestMain tm, void *tm_cls)
Start a single peer and run a test using the testing library.
Definition: testing.c:1592
void(* GNUNET_TESTING_TestMain)(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TESTING_Peer *peer)
Signature of the 'main' function for a (single-peer) testcase that is run using GNUNET_TESTING_peer_r...
void GNUNET_TESTING_system_destroy(struct GNUNET_TESTING_System *system, int remove_paths)
Free system resources.
Definition: testing.c:557
int GNUNET_TESTING_service_run(const char *testdir, const char *service_name, const char *cfgfilename, GNUNET_TESTING_TestMain tm, void *tm_cls)
Start a single service (no ARM, except of course if the given service name is 'arm') and run a test u...
Definition: testing.c:1643
int GNUNET_TESTING_peer_start(struct GNUNET_TESTING_Peer *peer)
Start the peer.
Definition: testing.c:1381
uint16_t GNUNET_TESTING_reserve_port(struct GNUNET_TESTING_System *system)
Reserve a TCP or UDP port for a peer.
Definition: testing.c:598
void GNUNET_TESTING_release_port(struct GNUNET_TESTING_System *system, uint16_t port)
Release reservation of a TCP or UDP port for a peer (used during GNUNET_TESTING_peer_destroy()).
Definition: testing.c:694
void GNUNET_TESTING_peer_stop_async_cancel(struct GNUNET_TESTING_Peer *peer)
Cancel a previous asynchronous peer stop request.
Definition: testing.c:1550
int GNUNET_TESTING_peer_stop_async(struct GNUNET_TESTING_Peer *peer, GNUNET_TESTING_PeerStopCallback cb, void *cb_cls)
Stop a peer asynchronously using ARM API.
Definition: testing.c:1525
int GNUNET_TESTING_configuration_create(struct GNUNET_TESTING_System *system, struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new configuration using the given configuration as a template; ports and paths will be modif...
Definition: testing.c:1167
int GNUNET_TESTING_peer_kill(struct GNUNET_TESTING_Peer *peer)
Sends SIGTERM to the peer's main process.
Definition: testing.c:1430
void GNUNET_TESTING_peer_destroy(struct GNUNET_TESTING_Peer *peer)
Destroy the peer.
Definition: testing.c:1566
int GNUNET_TESTING_peer_wait(struct GNUNET_TESTING_Peer *peer)
Waits for a peer to terminate.
Definition: testing.c:1462
void GNUNET_TESTING_peer_get_identity(struct GNUNET_TESTING_Peer *peer, struct GNUNET_PeerIdentity *id)
Obtain the peer identity from a peer handle.
Definition: testing.c:1359
#define GNUNET_TESTING_HOSTKEYFILESIZE
Size of each hostkey in the hostkey file (in BYTES).
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
#define AI_NUMERICSERV
AI_NUMERICSERV not defined in windows.
Definition: platform.h:219
#define GNUNET_TERM_SIG
The termination signal.
Definition: platform.h:234
#define PATH_MAX
Assumed maximum path length.
Definition: platform.h:241
Handle for interacting with ARM.
Definition: arm_api.c:103
Private ECC key encoded for transmission.
Handle used to access files (and pipes).
int fd
File handle on Unix-like systems.
Handle for a memory-mapping operation.
Definition: disk.c:1361
A 512-bit hashcode.
handle to a socket
Definition: network.c:54
The identity of the host (wraps the signing key of the peer).
A 256-bit hashcode.
Protocol address prefix für a connection between nodes.
struct GNUNET_TESTING_AddressPrefix * next
Pointer to the next prefix in the DLL.
char * address_prefix
The address prefix.
Node in the netjail topology.
unsigned int namespace_n
The number of the subnet this node is running in.
struct GNUNET_TESTING_NodeConnection * node_connections_head
Head of the DLL with the connections which shall be established to other nodes.
unsigned int additional_connects
The number of unintentional additional connections this node waits for.
unsigned int is_global
Flag indicating if this node is a global known node.
char * plugin
Plugin for the test case to be run on this node.
unsigned int node_n
The number of this node in the subnet.
struct GNUNET_TESTING_NodeConnection * node_connections_tail
Tail of the DLL with the connections which shall be established to other nodes.
unsigned int tcp_port
Will tcp be forwarded?
unsigned int udp_port
Will udp be forwarded?
struct GNUNET_CONTAINER_MultiShortmap * map_globals
Hash map containing the global known nodes which are not natted.
char * plugin
Default plugin for the test case to be run on nodes.
unsigned int nodes_m
Number of nodes per subnet.
unsigned int nodes_x
Number of global known nodes.
unsigned int namespaces_n
Number of subnets.
struct GNUNET_CONTAINER_MultiShortmap * map_namespaces
Hash map containing the subnets (for natted nodes) of the topology.
unsigned int additional_connects
Additional connects we do expect, beside the connects which are configured in the topology.
struct GNUNET_TESTING_AddressPrefix * address_prefixes_tail
Tail of the DLL with the address prefixes for the protocolls this node is reachable.
struct GNUNET_TESTING_NodeConnection * next
Pointer to the next connection in the DLL.
unsigned int node_n
The number of the node this connection points to.
struct GNUNET_TESTING_NetjailNode * node
The node which establish the connection.
unsigned int namespace_n
The number of the subnet of the node this connection points to.
struct GNUNET_TESTING_AddressPrefix * address_prefixes_head
Head of the DLL with the address prefixes for the protocolls this node is reachable.
enum GNUNET_TESTING_NodeType node_type
The type of the node this connection points to.
Handle for a GNUnet peer controlled by testing.
Definition: testing.c:195
struct GNUNET_TESTING_System * system
The TESTING system associated with this peer.
Definition: testing.c:199
struct GNUNET_OS_Process * main_process
Handle to the running binary of the service, NULL if the peer/service is currently not running.
Definition: testing.c:219
unsigned int nports
The number of ports in the above array.
Definition: testing.c:259
char * main_binary
Binary to be executed during 'GNUNET_TESTING_peer_start'.
Definition: testing.c:212
struct GNUNET_CONFIGURATION_Handle * cfg
The config of the peer.
Definition: testing.c:229
uint16_t * ports
Array of ports currently allocated to this peer.
Definition: testing.c:254
struct SharedServiceInstance ** ss_instances
Definition: testing.c:247
struct GNUNET_PeerIdentity * id
The cached identity of this peer.
Definition: testing.c:245
struct GNUNET_ARM_Handle * ah
The handle to the peer's ARM service.
Definition: testing.c:224
uint32_t key_number
The keynumber of this peer's hostkey.
Definition: testing.c:264
void * cb_cls
The closure for the above callback.
Definition: testing.c:239
char * cfgfile
Path to the configuration file for this peer.
Definition: testing.c:204
GNUNET_TESTING_PeerStopCallback cb
The callback to call asynchronously when a peer is stopped.
Definition: testing.c:234
Specification of a service that is to be shared among peers.
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration template for the service.
unsigned int share
The number of peers which share an instance of the service.
const char * service
The name of the service.
Handle for a system on which GNUnet peers are executed; a system is used for reserving unique paths a...
Definition: testing.c:122
uint16_t highport
Highest port we are allowed to use.
Definition: testing.c:187
char * trusted_ip
The trusted ip.
Definition: testing.c:133
char * tmppath
Prefix (e.g.
Definition: testing.c:127
uint32_t total_hostkeys
The number of hostkeys.
Definition: testing.c:177
unsigned int n_shared_services
Definition: testing.c:152
char * hostname
our hostname
Definition: testing.c:138
uint32_t reserved_ports[65536/32]
Bitmap where each port that has already been reserved for some GNUnet peer is recorded.
Definition: testing.c:162
char * hostkeys_data
Hostkeys data, contains "GNUNET_TESTING_HOSTKEYFILESIZE * total_hostkeys" bytes.
Definition: testing.c:143
struct SharedService * shared_services
Definition: testing.c:150
uint32_t path_counter
Counter we use to make service home paths unique on this system; the full path consists of the tmppat...
Definition: testing.c:172
struct GNUNET_DISK_MapHandle * map
memory map for hostkeys_data.
Definition: testing.c:148
uint16_t lowport
Lowest port we are allowed to use.
Definition: testing.c:182
Structure for holding service data.
Definition: testing.c:1605
struct GNUNET_TESTING_Peer * peer
The peer in which the service is run.
Definition: testing.c:1619
void * tm_cls
Closure for the above callback.
Definition: testing.c:1624
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration of the peer in which the service is run.
Definition: testing.c:1609
GNUNET_TESTING_TestMain tm
Callback to signal service startup.
Definition: testing.c:1614
unsigned int n_refs
Definition: testing.c:98
struct SharedService * ss
Definition: testing.c:88
struct GNUNET_OS_Process * proc
Definition: testing.c:92
The structure for identifying a shared service.
unsigned int share
Definition: testing.c:111
struct GNUNET_CONFIGURATION_Handle * cfg
Definition: testing.c:107
unsigned int n_instances
Definition: testing.c:113
struct SharedServiceInstance ** instances
Definition: testing.c:105
unsigned int n_peers
Definition: testing.c:109
char * sname
Definition: testing.c:103
Closure for update_rel_sum() and update_abs_sum().
uint16_t * ports
Array of ports currently allocated to this peer.
Definition: testing.c:783
struct GNUNET_TESTING_System * system
The system for which we are building configurations.
Definition: testing.c:766
char * gnunet_home
The customized service home path for this peer.
Definition: testing.c:776
struct GNUNET_CONFIGURATION_Handle * cfg
The configuration we are building.
Definition: testing.c:771
unsigned int nports
The number of ports in the above array.
Definition: testing.c:788
int status
build status - to signal error while building a configuration
Definition: testing.c:793
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
int free_nodes_cb(void *cls, const struct GNUNET_ShortHashCode *key, void *value)
Definition: testing.c:2294
static enum GNUNET_GenericReturnValue start_shared_service_instance(struct SharedServiceInstance *i)
Definition: testing.c:509
static unsigned int get_first_value(const char *line)
Every line in the topology configuration starts with a string indicating which kind of information wi...
Definition: testing.c:1734
struct GNUNET_PeerIdentity * GNUNET_TESTING_get_peer(unsigned int num, const struct GNUNET_TESTING_System *tl_system)
Retrieve the peer identity from the test system with the unique node id.
Definition: testing.c:2276
static void disconn_status(void *cls, int connected)
Function called whenever we connect to or disconnect from ARM.
Definition: testing.c:1503
#define PREFIX_UDP_NATTED
Definition: testing.c:68
static void service_run_main(void *cls)
Callback to be called when SCHEDULER has been started.
Definition: testing.c:1634
static void node_connections(const char *line, struct GNUNET_TESTING_NetjailNode *node)
Every line in the topology configuration starts with a string indicating which kind of information wi...
Definition: testing.c:2006
#define HIGH_PORT
Highest port used for GNUnet testing.
Definition: testing.c:83
static void hostkeys_unload(struct GNUNET_TESTING_System *system)
Function to remove the loaded hostkeys.
Definition: testing.c:339
unsigned int GNUNET_TESTING_get_additional_connects(unsigned int num, struct GNUNET_TESTING_NetjailTopology *topology)
Get the number of unintentional additional connections the node waits for.
Definition: testing.c:2447
#define PREFIX_TCP
Definition: testing.c:62
static struct GNUNET_TESTING_NodeConnection * get_connect_value(const char *line, struct GNUNET_TESTING_NetjailNode *node)
Every line in the topology configuration starts with a string indicating which kind of information wi...
Definition: testing.c:1897
static char * get_value(const char *key, const char *line)
Every line in the topology configuration starts with a string indicating which kind of information wi...
Definition: testing.c:1857
static char * get_first_string_value(const char *line)
Every line in the topology configuration starts with a string indicating which kind of information wi...
Definition: testing.c:1792
struct GNUNET_TESTING_NodeConnection * GNUNET_TESTING_get_connections(unsigned int num, const struct GNUNET_TESTING_NetjailTopology *topology)
Get the connections to other nodes for a specific node.
Definition: testing.c:2251
static enum GNUNET_GenericReturnValue hostkeys_load(struct GNUNET_TESTING_System *system)
Testing includes a number of pre-created hostkeys for faster peer startup.
Definition: testing.c:276
int free_namespaces_cb(void *cls, const struct GNUNET_ShortHashCode *key, void *value)
Definition: testing.c:2326
#define PREFIX_TCP_NATTED
Definition: testing.c:66
static unsigned int get_second_value(const char *line)
Every line in the topology configuration starts with a string indicating which kind of information wi...
Definition: testing.c:1826
static void cleanup_shared_service_instance(struct SharedServiceInstance *i)
Definition: testing.c:493
static void get_node_info(unsigned int num, const struct GNUNET_TESTING_NetjailTopology *topology, struct GNUNET_TESTING_NetjailNode **node_ex, struct GNUNET_TESTING_NetjailNamespace **namespace_ex, struct GNUNET_TESTING_NodeConnection **node_connections_ex)
This function extracts information about a specific node from the topology.
Definition: testing.c:2147
static void update_config(void *cls, const char *section, const char *option, const char *value)
Function to iterate over options.
Definition: testing.c:808
static struct SharedServiceInstance * associate_shared_service(struct GNUNET_TESTING_System *system, struct SharedService *ss, struct GNUNET_CONFIGURATION_Handle *cfg)
Definition: testing.c:1011
struct GNUNET_TESTING_NetjailTopology * GNUNET_TESTING_get_topo_from_string(const char *input)
Parse the topology data.
Definition: testing.c:2515
static void stop_shared_service_instance(struct SharedServiceInstance *i)
Definition: testing.c:536
static char * get_key(const char *line)
Every line in the topology configuration starts with a string indicating which kind of information wi...
Definition: testing.c:1761
struct GNUNET_TESTING_NetjailNode * GNUNET_TESTING_get_node(unsigned int num, struct GNUNET_TESTING_NetjailTopology *topology)
Get a node from the topology.
Definition: testing.c:2229
unsigned int GNUNET_TESTING_calculate_num(struct GNUNET_TESTING_NodeConnection *node_connection, struct GNUNET_TESTING_NetjailTopology *topology)
Calculate the unique id identifying a node from a given connection.
Definition: testing.c:2361
#define LOG(kind,...)
Definition: testing.c:42
char * GNUNET_TESTING_get_address(struct GNUNET_TESTING_NodeConnection *connection, const char *prefix)
Get the address for a specific communicator from a connection.
Definition: testing.c:2387
static void update_config_sections(void *cls, const char *section)
Section iterator to set ACCEPT_FROM/ACCEPT_FROM6 to include the address of 'trusted_hosts' in all sec...
Definition: testing.c:905
static int GNUNET_TESTING_configuration_create_(struct GNUNET_TESTING_System *system, struct GNUNET_CONFIGURATION_Handle *cfg, uint16_t **ports, unsigned int *nports)
Create a new configuration using the given configuration as a template; ports and paths will be modif...
Definition: testing.c:1104
#define CONNECT_ADDRESS_TEMPLATE
Definition: testing.c:44
#define PREFIX_UDP
Definition: testing.c:64
static int log_topo(const struct GNUNET_TESTING_NetjailTopology *topology)
Helper function to log the configuration in case of a problem with configuration.
Definition: testing.c:2119
struct GNUNET_TESTING_NetjailTopology * GNUNET_TESTING_get_topo_from_file(const char *filename)
Getting the topology from file.
Definition: testing.c:2786
#define LOW_PORT
Lowest port used for GNUnet testing.
Definition: testing.c:76
static void cfg_copy_iterator(void *cls, const char *section, const char *option, const char *value)
Function to iterate over options.
Definition: testing.c:359
static int log_nodes(void *cls, const struct GNUNET_ShortHashCode *id, void *value)
A helper function to log information about individual nodes.
Definition: testing.c:2059
#define KNOWN_CONNECT_ADDRESS_TEMPLATE
Definition: testing.c:48
void GNUNET_TESTING_free_topology(struct GNUNET_TESTING_NetjailTopology *topology)
Deallocate memory of the struct GNUNET_TESTING_NetjailTopology.
Definition: testing.c:2347
#define ROUTER_CONNECT_ADDRESS_TEMPLATE
Definition: testing.c:46
static int log_namespaces(void *cls, const struct GNUNET_ShortHashCode *id, void *value)
Helper function to log information about namespaces.
Definition: testing.c:2104
static void parse_ac(struct GNUNET_TESTING_NetjailNode *p_node, const char *token)
Definition: testing.c:2478
Message formats for communication between testing cmds helper and testcase plugins.