GNUnet  0.19.2
testbed_api_hosts.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2008--2013 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
28 #include "platform.h"
29 #include "gnunet_util_lib.h"
30 #include "gnunet_testbed_service.h"
31 #include "gnunet_core_service.h"
33 
34 #include "testbed_api.h"
35 #include "testbed_api_hosts.h"
36 #include "testbed_helper.h"
37 #include "testbed_api_operations.h"
38 
39 #include <zlib.h>
40 #include <regex.h>
41 
45 #define LOG(kind, ...) GNUNET_log_from (kind, "testbed-api-hosts", __VA_ARGS__);
46 
50 #define LOG_DEBUG(...) LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__);
51 
55 #define API_VIOLATION(cond, errstr) \
56  do \
57  { \
58  if (cond) \
59  break; \
60  LOG (GNUNET_ERROR_TYPE_ERROR, "API violation detected: %s\n", errstr); \
61  GNUNET_assert (0); \
62  } while (0)
63 
68 #define LOG_GAI(level, cmd, rc) \
69  do \
70  { \
71  LOG (level, \
72  _ ("`%s' failed at %s:%d with error: %s\n"), \
73  cmd, \
74  __FILE__, \
75  __LINE__, \
76  gai_strerror (rc)); \
77  } while (0)
78 
82 #define HOST_LIST_GROW_STEP 10
83 
84 
89 {
94 
99 
104 };
105 
106 
113 {
117  const char *hostname;
118 
122  const char *username;
123 
131 
136 
141 
147 
152 
156  int locked;
157 
161  uint32_t id;
162 
166  uint16_t port;
167 };
168 
169 
174 
178 static unsigned int host_list_size;
179 
180 
188 struct GNUNET_TESTBED_Host *
190 {
191  if (host_list_size <= id)
192  return NULL;
193  return host_list[id];
194 }
195 
196 
209 struct GNUNET_TESTBED_Host *
211  uint32_t id,
212  const struct GNUNET_CONFIGURATION_Handle *cfg)
213 {
214  return GNUNET_TESTBED_host_create_with_id (id, NULL, NULL, cfg, 0);
215 }
216 
217 
218 uint32_t
220 {
221  return host->id;
222 }
223 
224 
231 const char *
233 {
234  return host->hostname;
235 }
236 
237 
244 const char *
246 {
247  return host->username;
248 }
249 
250 
257 uint16_t
259 {
260  return host->port;
261 }
262 
263 
270 int
272 {
273  return host->controller_started;
274 }
275 
276 
283 const struct GNUNET_CONFIGURATION_Handle *
285 {
286  return host->cfg;
287 }
288 
289 
296 void
298  struct GNUNET_TESTBED_Host *host,
299  const struct GNUNET_CONFIGURATION_Handle *new_cfg)
300 {
302  host->cfg = GNUNET_CONFIGURATION_dup (new_cfg);
303 }
304 
305 
319 struct GNUNET_TESTBED_Host *
321  uint32_t id,
322  const char *hostname,
323  const char *username,
324  const struct GNUNET_CONFIGURATION_Handle *cfg,
325  uint16_t port)
326 {
327  struct GNUNET_TESTBED_Host *host;
328  unsigned int new_size;
329 
330  if ((id < host_list_size) && (NULL != host_list[id]))
331  {
332  LOG (GNUNET_ERROR_TYPE_WARNING, "Host with id: %u already created\n", id);
333  return NULL;
334  }
335  host = GNUNET_new (struct GNUNET_TESTBED_Host);
336  host->hostname = (NULL != hostname) ? GNUNET_strdup (hostname) : NULL;
337  host->username = (NULL != username) ? GNUNET_strdup (username) : NULL;
338  host->id = id;
339  host->port = (0 == port) ? 22 : port;
340  host->cfg = GNUNET_CONFIGURATION_dup (cfg);
343  UINT_MAX);
344  new_size = host_list_size;
345  while (id >= new_size)
346  new_size += HOST_LIST_GROW_STEP;
347  if (new_size != host_list_size)
350  LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding host with id: %u\n", host->id);
351  host_list[id] = host;
352  return host;
353 }
354 
355 
367 struct GNUNET_TESTBED_Host *
369  const char *username,
370  const struct GNUNET_CONFIGURATION_Handle *cfg,
371  uint16_t port)
372 {
373  static uint32_t uid_generator;
374 
375  if (NULL == hostname)
377  hostname,
378  username,
379  cfg,
380  port);
381  return GNUNET_TESTBED_host_create_with_id (++uid_generator,
382  hostname,
383  username,
384  cfg,
385  port);
386 }
387 
388 
389 unsigned int
391  const char *filename,
392  const struct GNUNET_CONFIGURATION_Handle *cfg,
393  struct GNUNET_TESTBED_Host ***hosts)
394 {
395  struct GNUNET_TESTBED_Host *starting_host;
396  char *data;
397  char *buf;
398  char *username;
399  char *hostname;
400  regex_t rex;
401  regmatch_t pmatch[6];
402  uint64_t fs;
403  short int port;
404  unsigned int offset;
405  unsigned int count;
406 
407 
408  GNUNET_assert (NULL != filename);
410  {
411  LOG (GNUNET_ERROR_TYPE_WARNING, _ ("Hosts file %s not found\n"), filename);
412  return 0;
413  }
414  if (GNUNET_OK !=
416  fs = 0;
417  if (0 == fs)
418  {
420  _ ("Hosts file %s has no data\n"),
421  filename);
422  return 0;
423  }
424  data = GNUNET_malloc (fs);
426  {
427  GNUNET_free (data);
429  _ ("Hosts file %s cannot be read\n"),
430  filename);
431  return 0;
432  }
433  buf = data;
434  offset = 0;
435  starting_host = NULL;
436  count = 0;
437  /* refer RFC 952 and RFC 1123 for valid hostnames */
438  GNUNET_assert (0 == regcomp (&rex,
439  "^(([[:alnum:]]+)@)?" /* username */
440  "([[:alnum:]]+[-[:alnum:]_\\.]+)" /* hostname */
441  "(:([[:digit:]]{1,5}))?", /* port */
442  REG_EXTENDED | REG_ICASE));
443  while (offset < (fs - 1))
444  {
445  offset++;
446  if (((data[offset] == '\n')) && (buf != &data[offset]))
447  {
448  unsigned int size;
449 
450  data[offset] = '\0';
451  username = NULL;
452  hostname = NULL;
453  port = 0;
454  if ((REG_NOMATCH == regexec (&rex, buf, 6, pmatch, 0)) ||
455  (-1 == pmatch[3].rm_so))
456  {
458  "Error reading line `%s' in hostfile\n",
459  buf);
460  buf = &data[offset + 1];
461  continue;
462  }
463  if (-1 != pmatch[2].rm_so)
464  {
465  size = pmatch[2].rm_eo - pmatch[2].rm_so;
466  username = GNUNET_malloc (size + 1);
467  GNUNET_assert (
468  0 != GNUNET_strlcpy (username, buf + pmatch[2].rm_so, size + 1));
469  }
470  if (-1 != pmatch[5].rm_so)
471  {
472  (void) sscanf (buf + pmatch[5].rm_so, "%5hd", &port);
473  }
474  size = pmatch[3].rm_eo - pmatch[3].rm_so;
475  hostname = GNUNET_malloc (size + 1);
476  GNUNET_assert (
477  0 != GNUNET_strlcpy (hostname, buf + pmatch[3].rm_so, size + 1));
479  "Successfully read host %s, port %d and user %s from file\n",
480  (NULL == hostname) ? "NULL" : hostname,
481  port,
482  (NULL == username) ? "NULL" : username);
483  /* We store hosts in a static list; hence we only require the starting
484  * host pointer in that list to access the newly created list of hosts */
485  if (NULL == starting_host)
486  starting_host =
488  else
490  count++;
493  buf = &data[offset + 1];
494  }
495  else if ((data[offset] == '\n') || (data[offset] == '\0'))
496  buf = &data[offset + 1];
497  }
498  regfree (&rex);
499  GNUNET_free (data);
500  if (NULL == starting_host)
501  return 0;
502  *hosts = GNUNET_malloc (sizeof(struct GNUNET_TESTBED_Host *) * count);
503  GNUNET_memcpy (*hosts,
504  &host_list[GNUNET_TESTBED_host_get_id_ (starting_host)],
505  sizeof(struct GNUNET_TESTBED_Host *) * count);
506  return count;
507 }
508 
509 
516 const char *
517 simple_resolve (const char *host)
518 {
519  struct addrinfo *res;
520  const struct sockaddr_in *in_addr;
521  char *hostip;
522  struct addrinfo hint;
523  unsigned int rc;
524 
525  hint.ai_family = AF_INET; /* IPv4 */
526  hint.ai_socktype = 0;
527  hint.ai_protocol = 0;
528  hint.ai_addrlen = 0;
529  hint.ai_addr = NULL;
530  hint.ai_canonname = NULL;
531  hint.ai_next = NULL;
532  hint.ai_flags = AI_NUMERICSERV;
533  res = NULL;
534  LOG_DEBUG ("Resolving [%s]\n", host);
535  if (0 != (rc = getaddrinfo (host, "22", &hint, &res)))
536  {
537  LOG_GAI (GNUNET_ERROR_TYPE_ERROR, "getaddrinfo", rc);
538  return NULL;
539  }
540  GNUNET_assert (NULL != res);
541  GNUNET_assert (NULL != res->ai_addr);
542  GNUNET_assert (sizeof(struct sockaddr_in) == res->ai_addrlen);
543  in_addr = (const struct sockaddr_in *) res->ai_addr;
544  hostip = inet_ntoa (in_addr->sin_addr);
545  GNUNET_assert (NULL != hostip);
546  freeaddrinfo (res);
547  LOG_DEBUG ("Resolved [%s] to [%s]\n", host, hostip);
548  return hostip;
549 }
550 
551 
558 void
560 {
561  GNUNET_assert (host->id < host_list_size);
562  GNUNET_assert (host_list[host->id] == host);
563  host_list[host->id] = NULL;
564  /* clear registered controllers list */
565  for (struct RegisteredController *rc = host->rc_head;
566  NULL != rc;
567  rc = host->rc_head)
568  {
569  GNUNET_CONTAINER_DLL_remove (host->rc_head, host->rc_tail, rc);
570  GNUNET_free (rc);
571  }
572  GNUNET_free_nz ((char *) host->username);
573  GNUNET_free_nz ((char *) host->hostname);
577  GNUNET_free (host);
579  {
580  uint32_t id;
581 
582  for (id = host_list_size - 1; id > host_list_size - HOST_LIST_GROW_STEP;
583  id--)
584  if (NULL != host_list[id])
585  break;
587  break;
588  if (NULL != host_list[id])
589  break;
591  }
592  host_list =
594  sizeof(struct GNUNET_TESTBED_Host *) * host_list_size);
595 }
596 
597 
604 void
606  struct GNUNET_TESTBED_Host *host,
607  const struct GNUNET_TESTBED_Controller *const controller)
608 {
609  struct RegisteredController *rc;
610 
611  for (rc = host->rc_head; NULL != rc; rc = rc->next)
612  {
613  if (controller == rc->controller) /* already registered at controller */
614  {
615  GNUNET_break (0);
616  return;
617  }
618  }
619  rc = GNUNET_new (struct RegisteredController);
620  rc->controller = controller;
622 }
623 
624 
631 void
633  struct GNUNET_TESTBED_Host *host,
634  const struct GNUNET_TESTBED_Controller *const controller)
635 {
636  struct RegisteredController *rc;
637 
638  for (rc = host->rc_head; NULL != rc; rc = rc->next)
639  if (controller == rc->controller)
640  break;
641  if (NULL == rc)
642  {
643  GNUNET_break (0);
644  return;
645  }
646  GNUNET_CONTAINER_DLL_remove (host->rc_head, host->rc_tail, rc);
647  GNUNET_free (rc);
648 }
649 
650 
658 int
660  const struct GNUNET_TESTBED_Host *host,
661  const struct GNUNET_TESTBED_Controller *const controller)
662 {
663  struct RegisteredController *rc;
664 
665  for (rc = host->rc_head; NULL != rc; rc = rc->next)
666  {
667  if (controller == rc->controller) /* already registered at controller */
668  {
669  return GNUNET_YES;
670  }
671  }
672  return GNUNET_NO;
673 }
674 
675 
680 {
685 
689  char **helper_argv;
690 
695 
700 
704  void *cls;
705 
710 
715 };
716 
717 
724 static char **
725 copy_argv (const char *const *argv)
726 {
727  char **argv_dup;
728  unsigned int argp;
729 
730  GNUNET_assert (NULL != argv);
731  for (argp = 0; NULL != argv[argp]; argp++)
732  ;
733  argv_dup = GNUNET_malloc (sizeof(char *) * (argp + 1));
734  for (argp = 0; NULL != argv[argp]; argp++)
735  argv_dup[argp] = GNUNET_strdup (argv[argp]);
736  return argv_dup;
737 }
738 
739 
747 static char **
748 join_argv (const char *const *argv1, const char *const *argv2)
749 {
750  char **argvj;
751  char *argv;
752  unsigned int carg;
753  unsigned int cnt;
754 
755  carg = 0;
756  argvj = NULL;
757  for (cnt = 0; NULL != argv1[cnt]; cnt++)
758  {
759  argv = GNUNET_strdup (argv1[cnt]);
760  GNUNET_array_append (argvj, carg, argv);
761  }
762  for (cnt = 0; NULL != argv2[cnt]; cnt++)
763  {
764  argv = GNUNET_strdup (argv2[cnt]);
765  GNUNET_array_append (argvj, carg, argv);
766  }
767  GNUNET_array_append (argvj, carg, NULL);
768  return argvj;
769 }
770 
771 
777 static void
778 free_argv (char **argv)
779 {
780  unsigned int argp;
781 
782  for (argp = 0; NULL != argv[argp]; argp++)
783  GNUNET_free (argv[argp]);
784  GNUNET_free (argv);
785 }
786 
787 
802 static char **
803 gen_rsh_args (const char *port, const char *hostname, const char *username)
804 {
805  static const char *default_ssh_args[] =
806  { "ssh",
807  "-o",
808  "BatchMode=yes",
809  "-o",
810  "NoHostAuthenticationForLocalhost=yes",
811  "-o",
812  "StrictHostKeyChecking=no",
813  "-o",
814  "PasswordAuthentication=no",
815  "%h",
816  NULL };
817  char **ssh_args;
818  char *ssh_cmd;
819  char *ssh_cmd_cp;
820  char *arg;
821  const char *new_arg;
822  unsigned int size;
823  unsigned int cnt;
824 
825  ssh_args = NULL;
826  if (NULL != (ssh_cmd = getenv ("GNUNET_TESTBED_RSH_CMD")))
827  {
828  ssh_cmd = GNUNET_strdup (ssh_cmd);
829  ssh_cmd_cp = ssh_cmd;
830  for (size = 0; NULL != (arg = strtok (ssh_cmd, " ")); ssh_cmd = NULL)
831  GNUNET_array_append (ssh_args, size, GNUNET_strdup (arg));
832  GNUNET_free (ssh_cmd_cp);
833  }
834  else
835  {
836  ssh_args = copy_argv (default_ssh_args);
837  size = (sizeof(default_ssh_args)) / (sizeof(const char *));
838  GNUNET_array_grow (ssh_args, size, size - 1);
839  }
840  for (cnt = 0; cnt < size; cnt++)
841  {
842  arg = ssh_args[cnt];
843  if ('%' != arg[0])
844  continue;
845  switch (arg[1])
846  {
847  case 'p':
848  new_arg = port;
849  break;
850 
851  case 'u':
852  new_arg = username;
853  break;
854 
855  case 'h':
856  new_arg = hostname;
857  break;
858 
859  default:
860  continue;
861  }
862  if (NULL == new_arg)
863  continue;
864  GNUNET_free (arg);
865  ssh_args[cnt] = GNUNET_strdup (new_arg);
866  }
867  GNUNET_array_append (ssh_args, size, NULL);
868  return ssh_args;
869 }
870 
871 
882 static char **
883 gen_rsh_suffix_args (const char *const *append_args)
884 {
885  char **rshell_args;
886  char *rshell_cmd;
887  char *rshell_cmd_cp;
888  char *arg;
889  unsigned int cnt;
890  unsigned int append_cnt;
891 
892  rshell_args = NULL;
893  cnt = 0;
894  if (NULL != (rshell_cmd = getenv ("GNUNET_TESTBED_RSH_CMD_SUFFIX")))
895  {
896  rshell_cmd = GNUNET_strdup (rshell_cmd);
897  rshell_cmd_cp = rshell_cmd;
898  for (; NULL != (arg = strtok (rshell_cmd, " ")); rshell_cmd = NULL)
899  GNUNET_array_append (rshell_args, cnt, GNUNET_strdup (arg));
900  GNUNET_free (rshell_cmd_cp);
901  }
902  if (NULL != append_args)
903  {
904  for (append_cnt = 0; NULL != append_args[append_cnt]; append_cnt++)
905  GNUNET_array_append (rshell_args,
906  cnt,
907  GNUNET_strdup (append_args[append_cnt]));
908  }
909  GNUNET_array_append (rshell_args, cnt, NULL);
910  return rshell_args;
911 }
912 
913 
925 static int
926 helper_mst (void *cls, const struct GNUNET_MessageHeader *message)
927 {
928  struct GNUNET_TESTBED_ControllerProc *cp = cls;
929  const struct GNUNET_TESTBED_HelperReply *msg;
930  const char *hostname;
931  char *config;
932  uLongf config_size;
933  uLongf xconfig_size;
934 
935  msg = (const struct GNUNET_TESTBED_HelperReply *) message;
936  GNUNET_assert (sizeof(struct GNUNET_TESTBED_HelperReply) <
937  ntohs (msg->header.size));
939  ntohs (msg->header.type));
940  config_size = (uLongf) ntohs (msg->config_size);
941  xconfig_size = (uLongf) (ntohs (msg->header.size)
942  - sizeof(struct GNUNET_TESTBED_HelperReply));
944  GNUNET_assert (Z_OK == uncompress ((Bytef *) config,
945  &config_size,
946  (const Bytef *) &msg[1],
947  xconfig_size));
948  /* Replace the configuration template present in the host with the
949  controller's running configuration */
953  config,
954  config_size,
955  NULL));
957  if (NULL == (hostname = GNUNET_TESTBED_host_get_hostname (cp->host)))
958  hostname = "localhost";
959  /* Change the hostname so that we can connect to it */
961  "testbed",
962  "hostname",
963  hostname);
964  cp->host->locked = GNUNET_NO;
966  cp->cb (cp->cls, cp->host->cfg, GNUNET_OK);
967  return GNUNET_OK;
968 }
969 
970 
979 static void
980 clear_msg (void *cls, int result)
981 {
982  struct GNUNET_TESTBED_ControllerProc *cp = cls;
983 
984  GNUNET_assert (NULL != cp->shandle);
985  cp->shandle = NULL;
986  GNUNET_free (cp->msg);
987  cp->msg = NULL;
988 }
989 
990 
997 static void
999 {
1000  struct GNUNET_TESTBED_ControllerProc *cp = cls;
1002  void *cb_cls;
1003 
1004  cb = cp->cb;
1005  cb_cls = cp->cls;
1006  cp->helper = NULL;
1008  if (NULL != cb)
1009  cb (cb_cls, NULL, GNUNET_SYSERR);
1010 }
1011 
1012 
1037 GNUNET_TESTBED_controller_start (const char *trusted_ip,
1038  struct GNUNET_TESTBED_Host *host,
1040  void *cls)
1041 {
1042  struct GNUNET_TESTBED_ControllerProc *cp;
1044  const struct GNUNET_CONFIGURATION_Handle *cfg;
1045  const char *hostname;
1046  static char *const binary_argv[] = { HELPER_TESTBED_BINARY, NULL };
1047 
1048  GNUNET_assert (NULL != host);
1049  GNUNET_assert (NULL != (cfg = GNUNET_TESTBED_host_get_cfg_ (host)));
1050  hostname = NULL;
1051  API_VIOLATION (
1052  GNUNET_NO == host->locked,
1053  "Host is already locked by a previous call to GNUNET_TESTBED_controller_start()");
1054  host->locked = GNUNET_YES;
1055  API_VIOLATION (
1056  GNUNET_NO == host->controller_started,
1057  "Attempting to start a controller on a host which is already started a controller");
1059  if (0 == GNUNET_TESTBED_host_get_id_ (host))
1060  {
1063  binary_argv,
1064  &helper_mst,
1065  &helper_exp_cb,
1066  cp);
1067  }
1068  else
1069  {
1070  char *helper_binary_path_args[2];
1071  char **rsh_args;
1072  char **rsh_suffix_args;
1073  const char *username;
1074  char *port;
1075  char *argstr;
1076  char *aux;
1077  unsigned int cnt;
1078 
1079  username = host->username;
1080  hostname = host->hostname;
1081  GNUNET_asprintf (&port, "%u", host->port);
1082  LOG_DEBUG ("Starting remote connection to destination %s\n", hostname);
1083  if (GNUNET_OK !=
1085  "testbed",
1086  "HELPER_BINARY_PATH",
1087  &helper_binary_path_args[0]))
1088  helper_binary_path_args[0] =
1090  helper_binary_path_args[1] = NULL;
1091  rsh_args = gen_rsh_args (port, hostname, username);
1092  rsh_suffix_args =
1093  gen_rsh_suffix_args ((const char **) helper_binary_path_args);
1094  cp->helper_argv =
1095  join_argv ((const char **) rsh_args, (const char **) rsh_suffix_args);
1096  free_argv (rsh_args);
1097  free_argv (rsh_suffix_args);
1098  GNUNET_free (port);
1099  argstr = GNUNET_strdup ("");
1100  for (cnt = 0; NULL != cp->helper_argv[cnt]; cnt++)
1101  {
1102  aux = argstr;
1103  GNUNET_assert (
1104  0 < GNUNET_asprintf (&argstr, "%s %s", aux, cp->helper_argv[cnt]));
1105  GNUNET_free (aux);
1106  }
1107  LOG_DEBUG ("Helper cmd str: %s\n", argstr);
1108  GNUNET_free (argstr);
1110  cp->helper_argv[0],
1111  cp->helper_argv,
1112  &helper_mst,
1113  &helper_exp_cb,
1114  cp);
1115  GNUNET_free (helper_binary_path_args[0]);
1116  }
1117  if (NULL == cp->helper)
1118  {
1119  if (NULL != cp->helper_argv)
1120  free_argv (cp->helper_argv);
1121  GNUNET_free (cp);
1122  return NULL;
1123  }
1124  cp->host = host;
1125  cp->cb = cb;
1126  cp->cls = cls;
1128  cp->msg = &msg->header;
1129  cp->shandle =
1130  GNUNET_HELPER_send (cp->helper, &msg->header, GNUNET_NO, &clear_msg, cp);
1131  if (NULL == cp->shandle)
1132  {
1133  GNUNET_free (msg);
1135  return NULL;
1136  }
1137  return cp;
1138 }
1139 
1140 
1146 void
1148 {
1149  if (NULL != cproc->shandle)
1151  if (NULL != cproc->helper)
1153 }
1154 
1155 
1161 void
1163 {
1164  if (NULL != cproc->helper)
1165  {
1167  GNUNET_HELPER_destroy (cproc->helper);
1168  }
1169  if (NULL != cproc->helper_argv)
1170  free_argv (cproc->helper_argv);
1171  cproc->host->controller_started = GNUNET_NO;
1172  cproc->host->locked = GNUNET_NO;
1173  GNUNET_free (cproc->msg);
1174  GNUNET_free (cproc);
1175 }
1176 
1177 
1186 void
1188 {
1191 }
1192 
1193 
1198 {
1202  const struct GNUNET_TESTBED_Host *host;
1203 
1208 
1212  void *cb_cls;
1213 
1218 
1222  char **helper_argv;
1223 
1228 
1234 };
1235 
1236 
1242 static void
1244 {
1246  void *cb_cls;
1248  const struct GNUNET_TESTBED_Host *host;
1249  unsigned long code;
1251  int ret;
1252 
1253  h->habitability_check_task = NULL;
1254  ret = GNUNET_OS_process_status (h->auxp, &type, &code);
1255  if (GNUNET_SYSERR == ret)
1256  {
1257  GNUNET_break (0);
1258  ret = GNUNET_NO;
1259  goto call_cb;
1260  }
1261  if (GNUNET_NO == ret)
1262  {
1263  h->wait_time = GNUNET_TIME_STD_BACKOFF (h->wait_time);
1264  h->habitability_check_task =
1266  return;
1267  }
1268  GNUNET_OS_process_destroy (h->auxp);
1269  h->auxp = NULL;
1270  ret = (0 != code) ? GNUNET_NO : GNUNET_YES;
1271 
1272  call_cb:
1273  if (NULL != h->auxp)
1274  GNUNET_OS_process_destroy (h->auxp);
1275  cb = h->cb;
1276  cb_cls = h->cb_cls;
1277  host = h->host;
1278  free_argv (h->helper_argv);
1279  GNUNET_free (h);
1280  if (NULL != cb)
1281  cb (cb_cls, host, ret);
1282 }
1283 
1284 
1298  const struct GNUNET_TESTBED_Host *host,
1299  const struct GNUNET_CONFIGURATION_Handle *config,
1301  void *cb_cls)
1302 {
1304  char **rsh_args;
1305  char **rsh_suffix_args;
1306  char *stat_args[3];
1307  const char *hostname;
1308  char *port;
1309 
1311  h->cb = cb;
1312  h->cb_cls = cb_cls;
1313  h->host = host;
1314  hostname = (NULL == host->hostname) ? "127.0.0.1" : host->hostname;
1315  if (GNUNET_OK !=
1317  "testbed",
1318  "HELPER_BINARY_PATH",
1319  &stat_args[1]))
1321  GNUNET_asprintf (&port, "%u", host->port);
1322  rsh_args = gen_rsh_args (port, hostname, host->username);
1323  GNUNET_free (port);
1324  port = NULL;
1325  stat_args[0] = "stat";
1326  stat_args[2] = NULL;
1327  rsh_suffix_args = gen_rsh_suffix_args ((const char **) stat_args);
1328  GNUNET_free (stat_args[1]);
1329  h->helper_argv =
1330  join_argv ((const char **) rsh_args, (const char **) rsh_suffix_args);
1331  free_argv (rsh_suffix_args);
1332  free_argv (rsh_args);
1334  NULL,
1335  NULL,
1336  NULL,
1337  h->helper_argv[0],
1338  h->helper_argv);
1339  if (NULL == h->auxp)
1340  {
1341  GNUNET_break (0); /* Cannot exec SSH? */
1342  GNUNET_free (h);
1343  return NULL;
1344  }
1345  h->wait_time = GNUNET_TIME_STD_BACKOFF (h->wait_time);
1346  h->habitability_check_task =
1348  return h;
1349 }
1350 
1351 
1357 void
1360 {
1361  GNUNET_SCHEDULER_cancel (handle->habitability_check_task);
1363  (void) GNUNET_OS_process_wait (handle->auxp);
1365  free_argv (handle->helper_argv);
1366  GNUNET_free (handle);
1367 }
1368 
1369 
1384  struct GNUNET_TESTBED_Host *host,
1386  void *cc_cls)
1387 {
1390  const char *username;
1391  const char *hostname;
1392  char *config;
1393  char *cconfig;
1394  void *ptr;
1395  size_t cc_size;
1396  size_t config_size;
1397  uint16_t msg_size;
1398  uint16_t username_length;
1399  uint16_t hostname_length;
1400 
1401  if (NULL != controller->rh)
1402  return NULL;
1404  if (GNUNET_YES == GNUNET_TESTBED_is_host_registered_ (host, controller))
1405  {
1407  "Host hostname: %s already registered\n",
1408  (NULL == hostname) ? "localhost" : hostname);
1409  return NULL;
1410  }
1412  rh->host = host;
1413  rh->c = controller;
1414  GNUNET_assert (NULL != cc);
1415  rh->cc = cc;
1416  rh->cc_cls = cc_cls;
1417  controller->rh = rh;
1418  username = GNUNET_TESTBED_host_get_username_ (host);
1419  username_length = 0;
1420  if (NULL != username)
1421  username_length = strlen (username);
1422  GNUNET_assert (NULL != hostname); /* Hostname must be present */
1423  hostname_length = strlen (hostname);
1424  GNUNET_assert (NULL != host->cfg);
1426  cc_size = GNUNET_TESTBED_compress_config_ (config, config_size, &cconfig);
1427  GNUNET_free (config);
1428  msg_size = (sizeof(struct GNUNET_TESTBED_AddHostMessage));
1429  msg_size += username_length;
1430  msg_size += hostname_length;
1431  msg_size += cc_size;
1432  msg = GNUNET_malloc (msg_size);
1433  msg->header.size = htons (msg_size);
1434  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST);
1435  msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (host));
1436  msg->ssh_port = htons (GNUNET_TESTBED_host_get_ssh_port_ (host));
1437  ptr = &msg[1];
1438  if (NULL != username)
1439  {
1440  msg->username_length = htons (username_length);
1441  GNUNET_memcpy (ptr, username, username_length);
1442  ptr += username_length;
1443  }
1444  msg->hostname_length = htons (hostname_length);
1446  ptr += hostname_length;
1447  msg->config_size = htons (config_size);
1448  GNUNET_memcpy (ptr, cconfig, cc_size);
1449  ptr += cc_size;
1450  GNUNET_assert ((ptr - (void *) msg) == msg_size);
1451  GNUNET_free (cconfig);
1452  GNUNET_TESTBED_queue_message_ (controller,
1453  (struct GNUNET_MessageHeader *) msg);
1454  return rh;
1455 }
1456 
1457 
1465 void
1468 {
1469  if (handle != handle->c->rh)
1470  {
1471  GNUNET_break (0);
1472  return;
1473  }
1474  handle->c->rh = NULL;
1475  GNUNET_free (handle);
1476 }
1477 
1478 
1487 void
1489  struct GNUNET_TESTBED_Operation *op)
1490 {
1492  h->opq_parallel_overlay_connect_operations,
1493  op);
1494 }
1495 
1496 
1502 void
1504 {
1505  char *hostname;
1506 
1507  hostname = (char *) host->hostname;
1508  host->hostname = simple_resolve (hostname);
1509  if (NULL == host->hostname)
1510  {
1511  GNUNET_break (0);
1512  host->hostname = hostname;
1513  return;
1514  }
1516  host->hostname = GNUNET_strdup (host->hostname);
1517 }
1518 
1519 
1520 /* end of testbed_api_hosts.c */
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
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_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
static int res
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static struct GNUNET_IDENTITY_Handle * id
Handle to identity service.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static char * filename
static struct GNUNET_FS_Handle * fs
Handle to FS service.
Definition: gnunet-fs.c:37
uint32_t data
The data value.
static int result
Global testing status.
static char * hostname
Our hostname; we give this to all the peers we start.
static char buf[2048]
static const struct GNUNET_CONFIGURATION_Handle * config
Core service; the main API for encrypted P2P communications.
API for writing tests and creating large-scale emulation testbeds for GNUnet.
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.
char * GNUNET_CONFIGURATION_serialize(const struct GNUNET_CONFIGURATION_Handle *cfg, size_t *size)
Serializes the given configuration.
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.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(void)
Create a new configuration object.
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_deserialize(struct GNUNET_CONFIGURATION_Handle *cfg, const char *mem, size_t size, const char *source_filename)
De-serializes configuration.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_dup(const struct GNUNET_CONFIGURATION_Handle *cfg)
Duplicate an existing configuration object.
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:481
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
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:663
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
void GNUNET_HELPER_send_cancel(struct GNUNET_HELPER_SendHandle *sh)
Cancel a GNUNET_HELPER_send operation.
Definition: helper.c:654
int GNUNET_HELPER_kill(struct GNUNET_HELPER_Handle *h, int soft_kill)
Sends termination signal to the helper process.
Definition: helper.c:167
struct GNUNET_HELPER_SendHandle * GNUNET_HELPER_send(struct GNUNET_HELPER_Handle *h, const struct GNUNET_MessageHeader *msg, int can_drop, GNUNET_HELPER_Continuation cont, void *cont_cls)
Send an message to the helper.
Definition: helper.c:614
int GNUNET_HELPER_wait(struct GNUNET_HELPER_Handle *h)
Reap the helper process.
Definition: helper.c:207
struct GNUNET_HELPER_Handle * GNUNET_HELPER_start(int with_control_pipe, const char *binary_name, char *const binary_argv[], GNUNET_MessageTokenizerCallback cb, GNUNET_HELPER_ExceptionCallback exp_cb, void *cb_cls)
Starts a helper and begins reading from it.
Definition: helper.c:461
void GNUNET_HELPER_destroy(struct GNUNET_HELPER_Handle *h)
Free's the resources occupied by the helper handle.
Definition: helper.c:500
#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
#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.
@ 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_.
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
#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.
int GNUNET_OS_process_status(struct GNUNET_OS_Process *proc, enum GNUNET_OS_ProcessStatusType *type, unsigned long *code)
Retrieve the status of a process.
Definition: os_priority.c:905
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_vap(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, char *const argv[])
Start a process.
Definition: os_priority.c:580
int GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc)
Wait for a process to terminate.
Definition: os_priority.c:942
GNUNET_OS_ProcessStatusType
Process status types.
void GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition: os_priority.c:273
int GNUNET_OS_process_kill(struct GNUNET_OS_Process *proc, int sig)
Sends a signal to the process.
Definition: os_priority.c:210
@ GNUNET_OS_INHERIT_STD_ERR
When this flag is set, the child process will inherit stderr of the parent.
Definition: gnunet_os_lib.h:95
#define GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST
Message to add host.
#define GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY
The reply message from gnunet-testbed-helper.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:944
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1241
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:138
struct GNUNET_TESTBED_Host * GNUNET_TESTBED_host_create_with_id(uint32_t id, const char *hostname, const char *username, const struct GNUNET_CONFIGURATION_Handle *cfg, uint16_t port)
Create a host to run peers and controllers on.
void GNUNET_TESTBED_cancel_registration(struct GNUNET_TESTBED_HostRegistrationHandle *handle)
Cancel the pending registration.
struct GNUNET_TESTBED_HostHabitableCheckHandle * GNUNET_TESTBED_is_host_habitable(const struct GNUNET_TESTBED_Host *host, const struct GNUNET_CONFIGURATION_Handle *config, GNUNET_TESTBED_HostHabitableCallback cb, void *cb_cls)
Checks whether a host can be used to start testbed service.
struct GNUNET_TESTBED_Host * GNUNET_TESTBED_host_create(const char *hostname, const char *username, const struct GNUNET_CONFIGURATION_Handle *cfg, uint16_t port)
Create a host to run peers and controllers on.
void GNUNET_TESTBED_is_host_habitable_cancel(struct GNUNET_TESTBED_HostHabitableCheckHandle *handle)
Function to cancel a request started using GNUNET_TESTBED_is_host_habitable()
void(* GNUNET_TESTBED_ControllerStatusCallback)(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, int status)
Callback to signal successful startup of the controller process.
unsigned int GNUNET_TESTBED_hosts_load_from_file(const char *filename, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TESTBED_Host ***hosts)
Load a set of hosts from a configuration file.
void(* GNUNET_TESTBED_HostHabitableCallback)(void *cls, const struct GNUNET_TESTBED_Host *host, int status)
Callbacks of this type are called by GNUNET_TESTBED_is_host_habitable to inform whether the given hos...
void(* GNUNET_TESTBED_HostRegistrationCompletion)(void *cls, const char *emsg)
Callback which will be called to after a host registration succeeded or failed.
void GNUNET_TESTBED_controller_stop(struct GNUNET_TESTBED_ControllerProc *cproc)
Stop the controller process (also will terminate all peers and controllers dependent on this controll...
void GNUNET_TESTBED_host_destroy(struct GNUNET_TESTBED_Host *host)
Destroy a host handle.
const char * GNUNET_TESTBED_host_get_hostname(const struct GNUNET_TESTBED_Host *host)
Obtain the host's hostname.
struct GNUNET_TESTBED_ControllerProc * GNUNET_TESTBED_controller_start(const char *trusted_ip, struct GNUNET_TESTBED_Host *host, GNUNET_TESTBED_ControllerStatusCallback cb, void *cls)
Starts a controller process at the given host.
struct GNUNET_TESTBED_HostRegistrationHandle * GNUNET_TESTBED_register_host(struct GNUNET_TESTBED_Controller *controller, struct GNUNET_TESTBED_Host *host, GNUNET_TESTBED_HostRegistrationCompletion cc, void *cc_cls)
Register a host with the controller.
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
static unsigned int size
Size of the "table".
Definition: peer.c:68
#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
GNUNET_DNS_RequestHandler rh
Function to call to get replies.
Definition: dns_api.c:71
The handle to a helper process.
Definition: helper.c:78
Entry in the queue of messages we need to transmit to the helper.
Definition: helper.c:36
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Entry in list of pending tasks.
Definition: scheduler.c:136
Notify the service about a host that we intend to use.
Definition: testbed.h:65
uint16_t username_length
Number of bytes in the user name that follows; 0 to use no user name; otherwise 'strlen (username)',...
Definition: testbed.h:86
uint16_t hostname_length
Number of bytes in the host name (excluding 0-termination) that follows the user name; cannot be 0.
Definition: testbed.h:92
uint16_t config_size
The length of the uncompressed configuration.
Definition: testbed.h:97
Handle for controller process.
struct GNUNET_HELPER_SendHandle * shandle
The send handle for the helper.
char ** helper_argv
The arguments used to start the helper.
GNUNET_TESTBED_ControllerStatusCallback cb
The controller error callback.
struct GNUNET_HELPER_Handle * helper
The process handle.
struct GNUNET_MessageHeader * msg
The message corresponding to send handle.
struct GNUNET_TESTBED_Host * host
The host where the helper is run.
void * cls
The closure for the above callback.
Handle to interact with a GNUnet testbed controller.
Definition: testbed_api.h:194
struct GNUNET_TESTBED_HostRegistrationHandle * rh
The host registration handle; NULL if no current registration requests are present.
Definition: testbed_api.h:224
Initialization message for gnunet-helper-testbed to start testbed service.
Reply message from helper process.
uint16_t config_size
Size of the uncompressed configuration.
The handle for whether a host is habitable or not.
const struct GNUNET_TESTBED_Host * host
The host to check.
char ** helper_argv
The arguments used to start the helper.
struct GNUNET_OS_Process * auxp
The process handle for the SSH process.
struct GNUNET_TIME_Relative wait_time
How long we wait before checking the process status.
GNUNET_TESTBED_HostHabitableCallback cb
The callback to call once we have the status.
struct GNUNET_SCHEDULER_Task * habitability_check_task
Task id for the habitability check task.
handle for host registration
struct GNUNET_TESTBED_Host * host
The host being registered.
struct GNUNET_TESTBED_Controller * c
The controller at which this host is being registered.
GNUNET_TESTBED_HostRegistrationCompletion cc
The Registration completion callback.
void * cc_cls
The closure for above callback.
Opaque handle to a host running experiments managed by the testing framework.
struct GNUNET_CONFIGURATION_Handle * cfg
the configuration to use as a template while starting a controller on this host.
struct RegisteredController * rc_head
The head for the list of controllers where this host is registered.
const char * hostname
The hostname of the host; NULL for localhost.
uint32_t id
Global ID we use to refer to a host on the network.
struct OperationQueue * opq_parallel_overlay_connect_operations
Operation queue for simultaneous overlay connect operations target at this host.
uint16_t port
The port which is to be used for SSH.
int locked
Is this host locked by GNUNET_TESTBED_controller_start()?
const char * username
The username to be used for SSH login.
int controller_started
Is a controller started on this host? FIXME: Is this needed?
struct RegisteredController * rc_tail
The tail for the list of controllers where this host is registered.
Opaque handle to an abstract operation to be executed by the testing framework.
Time for relative time used by GNUnet, in microseconds.
Queue of operations where we can only support a certain number of concurrent operations of a particul...
A list entry for registered controllers list.
const struct GNUNET_TESTBED_Controller * controller
The controller at which this host is registered.
struct RegisteredController * prev
The prev ptr for DLL.
struct RegisteredController * next
The next ptr for DLL.
void GNUNET_TESTBED_queue_message_(struct GNUNET_TESTBED_Controller *controller, struct GNUNET_MessageHeader *msg)
Queues a message in send queue for sending to the service.
Definition: testbed_api.c:1336
struct GNUNET_TESTBED_HelperInit * GNUNET_TESTBED_create_helper_init_msg_(const char *trusted_ip, const char *hostname, const struct GNUNET_CONFIGURATION_Handle *cfg)
Creates a helper initialization message.
Definition: testbed_api.c:1957
size_t GNUNET_TESTBED_compress_config_(const char *config, size_t size, char **xconfig)
Compresses given configuration using zlib compress.
Definition: testbed_api.c:1758
Interface for functions internally exported from testbed_api.c.
#define HELPER_TESTBED_BINARY
Testbed Helper binary name.
Definition: testbed_api.h:38
static char ** gen_rsh_args(const char *port, const char *hostname, const char *username)
Generates arguments for opening a remote shell.
struct GNUNET_TESTBED_Host * GNUNET_TESTBED_host_create_by_id_(uint32_t id, const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a host by ID; given this host handle, we could not run peers at the host, but we can talk abou...
void GNUNET_TESTBED_host_queue_oc_(struct GNUNET_TESTBED_Host *h, struct GNUNET_TESTBED_Operation *op)
Queues the given operation in the queue for parallel overlay connects of the given host.
const char * GNUNET_TESTBED_host_get_username_(const struct GNUNET_TESTBED_Host *host)
Obtain the host's username.
void GNUNET_TESTBED_mark_host_registered_at_(struct GNUNET_TESTBED_Host *host, const struct GNUNET_TESTBED_Controller *const controller)
Marks a host as registered with a controller.
static unsigned int host_list_size
The size of the available hosts list.
int GNUNET_TESTBED_host_controller_started(const struct GNUNET_TESTBED_Host *host)
Check whether a controller is already started on the given host.
static void clear_msg(void *cls, int result)
Continuation function from GNUNET_HELPER_send()
void GNUNET_TESTBED_deregister_host_at_(struct GNUNET_TESTBED_Host *host, const struct GNUNET_TESTBED_Controller *const controller)
Unmarks a host registered at a controller.
int GNUNET_TESTBED_is_host_registered_(const struct GNUNET_TESTBED_Host *host, const struct GNUNET_TESTBED_Controller *const controller)
Checks whether a host has been registered.
void GNUNET_TESTBED_controller_kill_(struct GNUNET_TESTBED_ControllerProc *cproc)
Sends termination signal to the controller's helper process.
static struct GNUNET_TESTBED_Host ** host_list
Array of available hosts.
void GNUNET_TESTBED_host_resolve_(struct GNUNET_TESTBED_Host *host)
Resolves the hostname of the host to an ip address.
#define API_VIOLATION(cond, errstr)
Prints API violation message.
void GNUNET_TESTBED_controller_destroy_(struct GNUNET_TESTBED_ControllerProc *cproc)
Cleans-up the controller's helper process handle.
static void helper_exp_cb(void *cls)
Callback that will be called when the helper process dies.
static char ** gen_rsh_suffix_args(const char *const *append_args)
Generates the arguments needed for executing the given binary in a remote shell.
#define LOG_DEBUG(...)
Debug logging shorthand.
static void habitability_check(void *cls)
Task for checking whether a host is habitable or not.
static char ** copy_argv(const char *const *argv)
Function to copy NULL terminated list of arguments.
static void free_argv(char **argv)
Frees the given NULL terminated arguments.
void GNUNET_TESTBED_host_replace_cfg_(struct GNUNET_TESTBED_Host *host, const struct GNUNET_CONFIGURATION_Handle *new_cfg)
Function to replace host's configuration.
static char ** join_argv(const char *const *argv1, const char *const *argv2)
Function to join NULL terminated list of arguments.
static int helper_mst(void *cls, const struct GNUNET_MessageHeader *message)
Functions with this signature are called whenever a complete message is received by the tokenizer.
const char * simple_resolve(const char *host)
Resolves a hostname using getaddrinfo.
uint16_t GNUNET_TESTBED_host_get_ssh_port_(const struct GNUNET_TESTBED_Host *host)
Obtain the host's ssh port.
const struct GNUNET_CONFIGURATION_Handle * GNUNET_TESTBED_host_get_cfg_(const struct GNUNET_TESTBED_Host *host)
Obtain the host's configuration template.
#define LOG_GAI(level, cmd, rc)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
struct GNUNET_TESTBED_Host * GNUNET_TESTBED_host_lookup_by_id_(uint32_t id)
Lookup a host by ID.
#define LOG(kind,...)
Generic logging shorthand.
uint32_t GNUNET_TESTBED_host_get_id_(const struct GNUNET_TESTBED_Host *host)
Obtain a host's unique global ID.
#define HOST_LIST_GROW_STEP
Number of extra elements we create space for when we grow host list.
internal API to access the 'hosts' subsystem
struct OperationQueue * GNUNET_TESTBED_operation_queue_create_(enum OperationQueueType type, unsigned int max_active)
Create an operation queue.
void GNUNET_TESTBED_operation_queue_insert_(struct OperationQueue *queue, struct GNUNET_TESTBED_Operation *op)
Add an operation to a queue.
void GNUNET_TESTBED_operation_queue_destroy_(struct OperationQueue *queue)
Destroys an operation queue.
internal API to access the 'operations' subsystem
@ OPERATION_QUEUE_TYPE_ADAPTIVE
Operation queue which adapts the number of operations to be active based on the operation completion ...
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
Message formats for communication between testbed api and gnunet-helper-testbed process.