GNUnet  0.19.4
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 int
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 int
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 
1737 char *
1739 {
1740  size_t slen = strlen (argv0) + 1;
1741  char sbuf[slen];
1742  char *ret;
1743  char *dot;
1744 
1745  GNUNET_memcpy (sbuf, argv0, slen);
1746  ret = strrchr (sbuf, '_');
1747  if (NULL == ret)
1748  return NULL;
1749  ret++; /* skip underscore */
1750  dot = strchr (ret, '.');
1751  if (NULL != dot)
1752  *dot = '\0';
1753  return GNUNET_strdup (ret);
1754 }
1755 
1756 
1766 static unsigned int
1767 get_first_value (const char *line)
1768 {
1769  char *copy;
1770  size_t slen;
1771  char *token;
1772  unsigned int ret;
1773  char *rest = NULL;
1774 
1775  slen = strlen (line) + 1;
1776  copy = GNUNET_malloc (slen);
1777  memcpy (copy, line, slen);
1778  token = strtok_r (copy, ":", &rest);
1779  token = strtok_r (NULL, ":", &rest);
1780  GNUNET_assert (1 == sscanf (token, "%u", &ret));
1781  GNUNET_free (copy);
1782  return ret;
1783 }
1784 
1785 
1793 static char *
1794 get_key (const char *line)
1795 {
1796  char *copy;
1797  size_t slen;
1798  size_t tlen;
1799  char *token;
1800  char *ret;
1801  char *rest = NULL;
1802 
1803  slen = strlen (line) + 1;
1804  copy = GNUNET_malloc (slen);
1805  memcpy (copy, line, slen);
1806  token = strtok_r (copy, ":", &rest);
1807  tlen = strlen (token) + 1;
1808  ret = GNUNET_malloc (tlen);
1809  memcpy (ret, token, tlen);
1810  GNUNET_free (copy);
1811  return ret;
1812 }
1813 
1814 
1824 static char *
1826 {
1827  char *copy;
1828  size_t slen, slen_token;
1829  char *token;
1830  char *ret;
1831  char *rest = NULL;
1832 
1833  slen = strlen (line) + 1;
1834  copy = GNUNET_malloc (slen);
1835  memcpy (copy, line, slen);
1836  token = strtok_r (copy, ":", &rest);
1837  token = strtok_r (NULL, ":", &rest);
1839  "first token %s\n",
1840  token);
1841  slen_token = strlen (token);
1842  ret = GNUNET_malloc (slen_token + 1);
1843  memcpy (ret, token, slen_token + 1);
1844  GNUNET_free (copy);
1845  return ret;
1846 }
1847 
1848 
1858 static unsigned int
1859 get_second_value (const char *line)
1860 {
1861  char *copy;
1862  char *token;
1863  unsigned int ret;
1864  char *rest = NULL;
1865 
1866  copy = GNUNET_strdup (line);
1867  token = strtok_r (copy, ":", &rest);
1868  token = strtok_r (NULL, ":", &rest);
1869  token = strtok_r (NULL, ":", &rest);
1871  "Format error in configuration line: %s\n",
1872  line);
1873  GNUNET_assert (1 == sscanf (token, "%u", &ret));
1874  GNUNET_free (copy);
1875  return ret;
1876 }
1877 
1878 
1889 static char *
1890 get_value (const char *key, const char *line)
1891 {
1892  char copy[strlen (line) + 1];
1893  size_t slen;
1894  char *token;
1895  char *token2;
1896  char *temp;
1897  char *rest = NULL;
1898 
1899  slen = strlen (line) + 1;
1900  memcpy (copy, line, slen);
1901  temp = strstr (copy, key);
1902  if (NULL == temp)
1903  return NULL;
1904  token = strtok_r (temp, ":", &rest);
1905  if (NULL == token)
1906  return NULL;
1907  token = strtok_r (NULL, ":", &rest);
1908  if (NULL == token)
1909  return NULL;
1910  token2 = strtok_r (token, "}", &rest);
1911  if (NULL == token2)
1912  return NULL;
1913  return GNUNET_strdup (token2);
1914 }
1915 
1916 
1929 static struct GNUNET_TESTING_NodeConnection *
1932 {
1933  struct GNUNET_TESTING_NodeConnection *node_connection;
1934  char *copy;
1935  char *token;
1936  char *token2;
1937  unsigned int node_n;
1938  unsigned int namespace_n;
1939  char *rest = NULL;
1940  char *rest2 = NULL;
1942  unsigned int sscanf_ret;
1943 
1944  node_connection = GNUNET_new (struct GNUNET_TESTING_NodeConnection);
1945  node_connection->node = node;
1946 
1947  copy = GNUNET_strdup (line);
1948  token = strtok_r (copy, ":", &rest);
1949  if (0 == strcmp ("{K", token))
1950  {
1951  node_connection->node_type = GNUNET_TESTING_GLOBAL_NODE;
1952  token = strtok_r (NULL, ":", &rest);
1953  GNUNET_assert (1 == sscanf (token, "%u", &node_n));
1955  "node_n %u\n",
1956  node_n);
1957  node_connection->node_n = node_n;
1958  node_connection->namespace_n = 0;
1959  }
1960  else if (0 == strcmp ("{P", token))
1961  {
1962  node_connection->node_type = GNUNET_TESTING_SUBNET_NODE;
1963  token = strtok_r (NULL, ":", &rest);
1964  errno = 0;
1965  sscanf_ret = sscanf (token, "%u", &namespace_n);
1966  if (errno != 0)
1967  {
1969  }
1970  GNUNET_assert (0 < sscanf_ret);
1971  node_connection->namespace_n = namespace_n;
1972  token = strtok_r (NULL, ":", &rest);
1973  errno = 0;
1974  sscanf_ret = sscanf (token, "%u", &node_n);
1975  if (errno != 0)
1976  {
1978  }
1979  GNUNET_assert (0 < sscanf_ret);
1980  node_connection->node_n = node_n;
1982  "node_n %u namespace_n %u node->node_n %u node->namespace_n %u\n",
1983  node_n,
1984  namespace_n,
1985  node->node_n,
1986  node->namespace_n);
1987  }
1988  else
1989  {
1990  GNUNET_break (0);
1991  GNUNET_free (node_connection);
1992  GNUNET_free (copy);
1993  return NULL;
1994  }
1995 
1996  while (NULL != (token = strtok_r (NULL, ":", &rest)))
1997  {
1999  token2 = strtok_r (token, "}", &rest2);
2000  if (NULL != token2)
2001  prefix->address_prefix = GNUNET_strdup (token2);
2002  else
2003  prefix->address_prefix = GNUNET_strdup (token);
2004 
2006  "address_prefix %s\n",
2007  prefix->address_prefix);
2008 
2010  node_connection->address_prefixes_tail,
2011  prefix);
2013  "address_prefix %s\n",
2014  prefix->address_prefix);
2015  }
2016 
2017  GNUNET_free (copy);
2018  return node_connection;
2019 }
2020 
2021 
2038 static void
2040 {
2041  char *value, *value2;
2042  char *temp;
2043  char *copy;
2044  char *rest = NULL;
2045  char *rest2 = NULL;
2046  struct GNUNET_TESTING_NodeConnection *node_connection;
2047 
2048 
2049  temp = strstr (line, "connect");
2050  if (NULL != temp)
2051  {
2052  copy = GNUNET_strdup (temp);
2053  strtok_r (copy, ":", &rest);
2054  value = strtok_r (rest, "|", &rest2);
2055 
2056  while (NULL != value)
2057  {
2059  "node_connections value %s\n",
2060  value);
2061  node_connection = get_connect_value (value, node);
2062  if (NULL == node_connection)
2063  {
2065  "connect key was not expected in this configuration line: %s\n",
2066  line);
2067  break;
2068  }
2071  node_connection);
2072  value2 = strstr (value, "}}");
2073  if (NULL != value2)
2074  break;
2075  value = strtok_r (NULL, "|", &rest2);
2076 
2077  }
2078  GNUNET_free (copy);
2079  }
2080 }
2081 
2082 
2091 static int
2092 log_nodes (void *cls, const struct GNUNET_ShortHashCode *id, void *value)
2093 {
2094  struct GNUNET_TESTING_NetjailNode *node = value;
2095  struct GNUNET_TESTING_NodeConnection *pos_connection;
2096  struct GNUNET_TESTING_AddressPrefix *pos_prefix;
2097 
2099  "plugin: %s space: %u node: %u global: %u\n",
2100  node->plugin,
2101  node->namespace_n,
2102  node->node_n,
2103  node->is_global);
2104 
2105  for (pos_connection = node->node_connections_head; NULL != pos_connection;
2106  pos_connection = pos_connection->next)
2107  {
2108 
2110  "namespace_n: %u node_n: %u node_type: %u\n",
2111  pos_connection->namespace_n,
2112  pos_connection->node_n,
2113  pos_connection->node_type);
2114 
2115  for (pos_prefix = pos_connection->address_prefixes_head; NULL != pos_prefix;
2116  pos_prefix =
2117  pos_prefix->next)
2118  {
2120  "prefix: %s\n",
2121  pos_prefix->address_prefix);
2122  }
2123  }
2124  return GNUNET_YES;
2125 }
2126 
2127 
2136 static int
2137 log_namespaces (void *cls, const struct GNUNET_ShortHashCode *id, void *value)
2138 {
2139  struct GNUNET_TESTING_NetjailNamespace *namespace = value;
2140 
2141  GNUNET_CONTAINER_multishortmap_iterate (namespace->nodes, &log_nodes, NULL);
2142  return GNUNET_YES;
2143 }
2144 
2145 
2151 static int
2153 {
2155  "plugin: %s spaces: %u nodes: %u known: %u\n",
2156  topology->plugin,
2157  topology->namespaces_n,
2158  topology->nodes_m,
2159  topology->nodes_x);
2160 
2162  log_namespaces, NULL);
2164  NULL);
2165  return GNUNET_YES;
2166 }
2167 
2168 
2179 static void
2180 get_node_info (unsigned int num,
2182  struct GNUNET_TESTING_NetjailNode **node_ex,
2183  struct GNUNET_TESTING_NetjailNamespace **namespace_ex,
2184  struct GNUNET_TESTING_NodeConnection **node_connections_ex)
2185 {
2186  struct GNUNET_ShortHashCode hkey;
2187  struct GNUNET_HashCode hc;
2188  unsigned int namespace_n;
2189  unsigned int node_m;
2190  struct GNUNET_TESTING_NetjailNode *node;
2191  struct GNUNET_TESTING_NetjailNamespace *namespace;
2193 
2194  log_topo (topology);
2196  "num: %u \n",
2197  num);
2198  if (topology->nodes_x >= num)
2199  {
2200 
2201  GNUNET_CRYPTO_hash (&num, sizeof(num), &hc);
2202  memcpy (&hkey,
2203  &hc,
2204  sizeof (hkey));
2206  &hkey);
2207  if (NULL != node)
2208  {
2209  *node_ex = node;
2210  *node_connections_ex = node->node_connections_head;
2211  }
2212  }
2213  else
2214  {
2215  namespace_n = (unsigned int) ceil ((double) (num - topology->nodes_x)
2216  / topology->nodes_m);
2218  "ceil num: %u nodes_x: %u nodes_m: %u namespace_n: %u\n",
2219  num,
2220  topology->nodes_x,
2221  topology->nodes_m,
2222  namespace_n);
2223  GNUNET_CRYPTO_hash (&namespace_n, sizeof(namespace_n), &hc);
2224  memcpy (&hkey,
2225  &hc,
2226  sizeof (hkey));
2227  namespace = GNUNET_CONTAINER_multishortmap_get (topology->map_namespaces,
2228  &hkey);
2229  if (NULL != namespace)
2230  {
2231  node_m = num - topology->nodes_x - topology->nodes_m * (namespace_n - 1);
2232  GNUNET_CRYPTO_hash (&node_m, sizeof(node_m), &hc);
2233  memcpy (&hkey,
2234  &hc,
2235  sizeof (hkey));
2236  node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes,
2237  &hkey);
2238  if (NULL != node)
2239  {
2241  "node additional_connects: %u %p\n",
2242  node->additional_connects,
2243  node);
2245  }
2246  *node_ex = node;
2247  *namespace_ex = namespace;
2248  *node_connections_ex = node_connections;
2249  }
2250  }
2251 }
2252 
2253 
2262 GNUNET_TESTING_get_node (unsigned int num,
2264 {
2265  struct GNUNET_TESTING_NetjailNode *node;
2266  struct GNUNET_TESTING_NetjailNamespace *namespace;
2268 
2269  get_node_info (num, topology, &node, &namespace, &node_connections);
2270 
2271  return node;
2272 
2273 }
2274 
2275 
2285  const struct
2287 {
2288  struct GNUNET_TESTING_NetjailNode *node;
2289  struct GNUNET_TESTING_NetjailNamespace *namespace;
2291 
2293  "get_connections\n");
2294 
2295  get_node_info (num, topology, &node, &namespace, &node_connections);
2296 
2297  return node_connections;
2298 }
2299 
2300 
2308 struct GNUNET_PeerIdentity *
2309 GNUNET_TESTING_get_peer (unsigned int num,
2310  const struct GNUNET_TESTING_System *tl_system)
2311 {
2313  struct GNUNET_CRYPTO_EddsaPrivateKey *priv_key;
2314 
2315  priv_key = GNUNET_TESTING_hostkey_get (tl_system,
2316  num,
2317  peer);
2318 
2320  &peer->public_key);
2321  GNUNET_free (priv_key);
2322  return peer;
2323 }
2324 
2325 
2326 int
2327 free_nodes_cb (void *cls,
2328  const struct GNUNET_ShortHashCode *key,
2329  void *value)
2330 {
2331  (void) cls;
2332  struct GNUNET_TESTING_NetjailNode *node = value;
2333  struct GNUNET_TESTING_NodeConnection *pos_connection;
2334  struct GNUNET_TESTING_AddressPrefix *pos_prefix;
2335 
2336  while (NULL != (pos_connection = node->node_connections_head))
2337  {
2338  while (NULL != (pos_prefix = pos_connection->address_prefixes_head))
2339  {
2341  pos_connection->address_prefixes_tail,
2342  pos_prefix);
2343  GNUNET_free (pos_prefix->address_prefix);
2344  GNUNET_free (pos_prefix);
2345  }
2347  node->node_connections_tail,
2348  pos_connection);
2349  GNUNET_free (pos_connection);
2350  }
2351 
2352  GNUNET_free (node->plugin);
2353  GNUNET_free (node);
2354  return GNUNET_OK;
2355 }
2356 
2357 
2358 int
2360  const struct GNUNET_ShortHashCode *key,
2361  void *value)
2362 {
2363  (void) cls;
2364  struct GNUNET_TESTING_NetjailNamespace *namespace = value;
2365 
2366  GNUNET_free (namespace->router);
2368  namespace->nodes);
2369  return GNUNET_OK;
2370 
2371 }
2372 
2373 
2379 void
2381 {
2383  free_namespaces_cb, NULL);
2386  NULL);
2388  GNUNET_free (topology->plugin);
2390 }
2391 
2392 
2393 unsigned int
2395  struct GNUNET_TESTING_NodeConnection *node_connection,
2397 {
2398  unsigned int n, m, num;
2399 
2400  n = node_connection->namespace_n;
2401  m = node_connection->node_n;
2402 
2403  if (0 == n)
2404  num = m;
2405  else
2406  num = (n - 1) * topology->nodes_m + m + topology->nodes_x;
2407 
2408  return num;
2409 }
2410 
2411 
2419 char *
2421  const char *prefix)
2422 {
2423  struct GNUNET_TESTING_NetjailNode *node;
2424  char *addr;
2425  char *template;
2426  unsigned int node_n;
2427 
2429  "get address prefix: %s node_n: %u\n",
2430  prefix,
2431  connection->node_n);
2432 
2433  node = connection->node;
2434  if (connection->namespace_n == node->namespace_n)
2435  {
2436  template = CONNECT_ADDRESS_TEMPLATE;
2437  node_n = connection->node_n;
2438  }
2439  else if (0 == connection->namespace_n)
2440  {
2441  template = KNOWN_CONNECT_ADDRESS_TEMPLATE;
2442  node_n = connection->node_n;
2443  }
2444  else if (1 == connection->node_n)
2445  {
2447  node_n = connection->namespace_n;
2448  }
2449  else
2450  {
2451  return NULL;
2452  }
2453 
2454  if (0 == strcmp (PREFIX_TCP, prefix) ||
2455  0 == strcmp (PREFIX_UDP, prefix) ||
2456  0 == strcmp (PREFIX_UDP_NATTED, prefix) ||
2457  0 == strcmp (PREFIX_TCP_NATTED, prefix))
2458  {
2459  GNUNET_asprintf (&addr,
2460  template,
2461  prefix,
2462  node_n);
2463  }
2464  else
2465  {
2466  GNUNET_assert (0);
2467  }
2468 
2469  return addr;
2470 }
2471 
2472 
2479 unsigned int
2482  topology)
2483 {
2484  struct GNUNET_TESTING_NetjailNode *node;
2485  struct GNUNET_TESTING_NetjailNamespace *namespace;
2487 
2489  "get_additional_connects\n");
2490 
2491  get_node_info (num, topology, &node, &namespace, &node_connections);
2492 
2493  if (NULL == node)
2494  {
2496  "No info found for node %d\n", num);
2497  return 0;
2498  }
2500  "node additional_connects for node %p\n",
2501  node);
2503  "node additional_connects: %u\n",
2504  node->additional_connects);
2505 
2506  return node->additional_connects;
2507 }
2508 
2509 
2510 static void
2511 parse_ac (struct GNUNET_TESTING_NetjailNode *p_node, const char *token)
2512 {
2513  char *ac_value;
2514  int ret;
2515 
2516  ac_value = get_value ("AC", token);
2517  if (NULL != ac_value)
2518  {
2520  "ac value: %s\n",
2521  ac_value);
2522  errno = 0;
2523  ret = sscanf (ac_value, "%u", &p_node->additional_connects);
2524  if (errno != 0)
2525  {
2527  }
2528  GNUNET_assert (0 < ret);
2530  "AC %u\n",
2531  p_node->additional_connects);
2532  }
2533  else
2534  {
2535  p_node->additional_connects = 0;
2536  }
2537  GNUNET_free (ac_value);
2538 }
2539 
2540 
2549 {
2550  char *token;
2551  char *key = NULL;
2552  unsigned int out;
2553  char *rest = NULL;
2554  char *value = NULL;
2555  char *value2;
2556  char *data;
2557  int ret;
2558  struct GNUNET_TESTING_NetjailTopology *topo;
2559  struct GNUNET_TESTING_NetjailRouter *router;
2560  struct GNUNET_TESTING_NetjailNamespace *namespace;
2561  struct GNUNET_HashCode hc;
2562 
2563  data = GNUNET_strdup (input);
2564  token = strtok_r (data, "\n", &rest);
2566  topo->map_namespaces =
2568  topo->map_globals =
2570 
2571  while (NULL != token)
2572  {
2573  if (NULL != key)
2574  GNUNET_free (key);
2575  key = get_key (token);
2577  "In the loop with token: %s beginning with %s\n",
2578  token,
2579  key);
2580  if (0 == strcmp (key, "M"))
2581  {
2583  "Get first Value for M.\n");
2584  out = get_first_value (token);
2586  "M: %u\n",
2587  out);
2588  topo->nodes_m = out;
2589  }
2590  else if (0 == strcmp (key, "N"))
2591  {
2593  "Get first Value for N.\n");
2594  out = get_first_value (token);
2596  "N: %u\n",
2597  out);
2598  topo->namespaces_n = out;
2599  }
2600  else if (0 == strcmp (key, "X"))
2601  {
2603  "Get first Value for X.\n");
2604  out = get_first_value (token);
2606  "X: %u\n",
2607  out);
2608  topo->nodes_x = out;
2609  }
2610  else if (0 == strcmp (key, "AC"))
2611  {
2613  "Get first Value for AC.\n");
2614  out = get_first_value (token);
2616  "AC: %u\n",
2617  out);
2618  topo->additional_connects = out;
2619  }
2620  else if (0 == strcmp (key, "T"))
2621  {
2623  "Get first string value for T.\n");
2624  value = get_first_string_value (token);
2626  "value: %s\n",
2627  value);
2628  topo->plugin = value;
2629  }
2630  else if (0 == strcmp (key, "K"))
2631  {
2632  struct GNUNET_ShortHashCode hkey_k;
2633  struct GNUNET_TESTING_NetjailNode *k_node = GNUNET_new (struct
2635 
2637  "Get first Value for K.\n");
2638  out = get_first_value (token);
2640  "K: %u\n",
2641  out);
2642  k_node->node_n = out;
2643  GNUNET_CRYPTO_hash (&out, sizeof(out), &hc);
2644  memcpy (&hkey_k,
2645  &hc,
2646  sizeof (hkey_k));
2647  k_node->is_global = GNUNET_YES;
2648 
2650  topo->map_globals,
2651  &hkey_k))
2652  GNUNET_break (0);
2653  else
2655  &hkey_k,
2656  k_node,
2659  "Get value for key value on K.\n");
2660  value = get_value ("plugin", token);
2662  "value: %s\n",
2663  value);
2664  k_node->plugin = value;
2665  parse_ac (k_node, token);
2666  node_connections (token, k_node);
2667  GNUNET_free (value);
2668  }
2669  else if (0 == strcmp (key, "R"))
2670  {
2671  struct GNUNET_ShortHashCode hkey_r;
2672  router = GNUNET_new (struct GNUNET_TESTING_NetjailRouter);
2673 
2675  "Get first Value for R.\n");
2676  out = get_first_value (token);
2678  "R: %u\n",
2679  out);
2680  GNUNET_CRYPTO_hash (&out, sizeof(out), &hc);
2681  memcpy (&hkey_r,
2682  &hc,
2683  sizeof (hkey_r));
2685  "Get value for key tcp_port on R.\n");
2686  value = get_value ("tcp_port", token);
2688  "tcp_port: %s\n",
2689  value);
2690  ret = sscanf (value, "%u", &(router->tcp_port));
2691  GNUNET_free (value);
2692  GNUNET_break (0 != ret && 1 >= router->tcp_port);
2693 
2695  "Get value for key udp_port on R.\n");
2696  value2 = get_value ("udp_port", token);
2697  ret = sscanf (value2, "%u", &(router->udp_port));
2698  GNUNET_free (value2);
2699  GNUNET_break (0 != ret && 1 >= router->udp_port);
2701  "udp_port: %s\n",
2702  value2);
2703  GNUNET_free (value2);
2705  topo->map_namespaces,
2706  &hkey_r))
2707  {
2709  &hkey_r);
2710  }
2711  else
2712  {
2713  namespace = GNUNET_new (struct GNUNET_TESTING_NetjailNamespace);
2714  namespace->namespace_n = out;
2715  namespace->nodes = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
2717  &hkey_r,
2718  namespace,
2720  }
2721  namespace->router = router;
2722 
2723  }
2724  else if (0 == strcmp (key, "P"))
2725  {
2726  struct GNUNET_TESTING_NetjailNode *p_node = GNUNET_new (struct
2728  struct GNUNET_ShortHashCode hkey_p;
2729 
2731  "Get first Value for P.\n");
2732  out = get_first_value (token);
2734  "P: %u\n",
2735  out);
2736  GNUNET_CRYPTO_hash (&out, sizeof(out), &hc);
2737  memcpy (&hkey_p,
2738  &hc,
2739  sizeof (hkey_p));
2740 
2742  topo->map_namespaces,
2743  &hkey_p))
2744  {
2746  &hkey_p);
2747  }
2748  else
2749  {
2750  namespace = GNUNET_new (struct GNUNET_TESTING_NetjailNamespace);
2751  namespace->nodes = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
2752  namespace->namespace_n = out;
2754  &hkey_p,
2755  namespace,
2757  }
2759  "Get second Value for P.\n");
2760  out = get_second_value (token);
2762  "P: %u\n",
2763  out);
2764  GNUNET_CRYPTO_hash (&out, sizeof(out), &hc);
2765  memcpy (&hkey_p,
2766  &hc,
2767  sizeof (hkey_p));
2769  namespace->nodes,
2770  &hkey_p))
2771  {
2772  GNUNET_break (0);
2773  }
2774  else
2775  {
2776 
2777  GNUNET_CONTAINER_multishortmap_put (namespace->nodes,
2778  &hkey_p,
2779  p_node,
2782  "Get value for key plugin on P.\n");
2783  value = get_value ("plugin", token);
2784  if (NULL != value)
2785  {
2787  "plugin: %s\n",
2788  value);
2789  p_node->plugin = value;
2790  }
2791  p_node->node_n = out;
2792  p_node->namespace_n = namespace->namespace_n;
2793  }
2795  "Get AC Value for P.\n");
2796  parse_ac (p_node, token);
2797  node_connections (token, p_node);
2798  }
2799  token = strtok_r (NULL, "\n", &rest);
2800  if (NULL != token)
2802  "Next token %s\n",
2803  token);
2804  }
2805  if (NULL != key)
2806  GNUNET_free (key);
2807  GNUNET_free (data);
2808  return topo;
2809 }
2810 
2811 
2820 {
2821  uint64_t fs;
2822  char *data;
2823  struct GNUNET_TESTING_NetjailTopology *topo;
2824 
2826  {
2828  _ ("Topology file %s not found\n"),
2829  filename);
2830  return NULL;
2831  }
2832  if (GNUNET_OK !=
2834  {
2836  _ ("Topology file %s has no data\n"),
2837  filename);
2838  return NULL;
2839  }
2840  data = GNUNET_malloc (fs + 1);
2841  if (fs != GNUNET_DISK_fn_read (filename, data, fs))
2842  {
2844  _ ("Topology file %s cannot be read\n"),
2845  filename);
2846  GNUNET_free (data);
2847  return NULL;
2848  }
2849 
2851  "file length %lu\n",
2852  fs);
2853  data[fs] = '\0';
2854 
2856 
2857  GNUNET_free (data);
2858 
2859  return topo;
2860 }
2861 
2862 
2863 /* 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: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: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_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:508
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:832
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:439
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
char * GNUNET_TESTING_get_testname_from_underscore(const char *argv0)
Sometimes we use the binary name to determine which specific test to run.
Definition: testing.c:1738
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:177
#define AI_NUMERICSERV
AI_NUMERICSERV not defined in windows.
Definition: platform.h:218
#define GNUNET_TERM_SIG
The termination signal.
Definition: platform.h:233
#define PATH_MAX
Assumed maximum path length.
Definition: platform.h:240
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:53
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:2327
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:1767
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:2309
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 int start_shared_service_instance(struct SharedServiceInstance *i)
Definition: testing.c:509
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:2039
#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:2480
#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:1930
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:1890
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:1825
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:2284
int free_namespaces_cb(void *cls, const struct GNUNET_ShortHashCode *key, void *value)
Definition: testing.c:2359
#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:1859
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:2180
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:2548
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:1794
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:2262
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:2394
#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:2420
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:2152
struct GNUNET_TESTING_NetjailTopology * GNUNET_TESTING_get_topo_from_file(const char *filename)
Getting the topology from file.
Definition: testing.c:2819
#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:2092
#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:2380
#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:2137
static void parse_ac(struct GNUNET_TESTING_NetjailNode *p_node, const char *token)
Definition: testing.c:2511
static int hostkeys_load(struct GNUNET_TESTING_System *system)
Testing includes a number of pre-created hostkeys for faster peer startup.
Definition: testing.c:276
Message formats for communication between testing cmds helper and testcase plugins.