GNUnet  0.11.x
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 
225 uint32_t
227 {
228  return host->id;
229 }
230 
231 
238 const char *
240 {
241  return host->hostname;
242 }
243 
244 
251 const char *
253 {
254  return host->username;
255 }
256 
257 
264 uint16_t
266 {
267  return host->port;
268 }
269 
270 
277 int
279 {
280  return host->controller_started;
281 }
282 
283 
290 const struct GNUNET_CONFIGURATION_Handle *
292 {
293  return host->cfg;
294 }
295 
296 
303 void
305  struct GNUNET_TESTBED_Host *host,
306  const struct GNUNET_CONFIGURATION_Handle *new_cfg)
307 {
309  host->cfg = GNUNET_CONFIGURATION_dup (new_cfg);
310 }
311 
312 
326 struct GNUNET_TESTBED_Host *
328  uint32_t id,
329  const char *hostname,
330  const char *username,
331  const struct GNUNET_CONFIGURATION_Handle *cfg,
332  uint16_t port)
333 {
334  struct GNUNET_TESTBED_Host *host;
335  unsigned int new_size;
336 
337  if ((id < host_list_size) && (NULL != host_list[id]))
338  {
339  LOG (GNUNET_ERROR_TYPE_WARNING, "Host with id: %u already created\n", id);
340  return NULL;
341  }
342  host = GNUNET_new (struct GNUNET_TESTBED_Host);
343  host->hostname = (NULL != hostname) ? GNUNET_strdup (hostname) : NULL;
344  host->username = (NULL != username) ? GNUNET_strdup (username) : NULL;
345  host->id = id;
346  host->port = (0 == port) ? 22 : port;
347  host->cfg = GNUNET_CONFIGURATION_dup (cfg);
350  UINT_MAX);
351  new_size = host_list_size;
352  while (id >= new_size)
353  new_size += HOST_LIST_GROW_STEP;
354  if (new_size != host_list_size)
357  LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding host with id: %u\n", host->id);
358  host_list[id] = host;
359  return host;
360 }
361 
362 
374 struct GNUNET_TESTBED_Host *
376  const char *username,
377  const struct GNUNET_CONFIGURATION_Handle *cfg,
378  uint16_t port)
379 {
380  static uint32_t uid_generator;
381 
382  if (NULL == hostname)
384  hostname,
385  username,
386  cfg,
387  port);
388  return GNUNET_TESTBED_host_create_with_id (++uid_generator,
389  hostname,
390  username,
391  cfg,
392  port);
393 }
394 
395 
407 unsigned int
409  const char *filename,
410  const struct GNUNET_CONFIGURATION_Handle *cfg,
411  struct GNUNET_TESTBED_Host ***hosts)
412 {
413  struct GNUNET_TESTBED_Host *starting_host;
414  char *data;
415  char *buf;
416  char *username;
417  char *hostname;
418  regex_t rex;
419  regmatch_t pmatch[6];
420  uint64_t fs;
421  short int port;
422  unsigned int offset;
423  unsigned int count;
424 
425 
426  GNUNET_assert (NULL != filename);
428  {
429  LOG (GNUNET_ERROR_TYPE_WARNING, _ ("Hosts file %s not found\n"), filename);
430  return 0;
431  }
432  if (GNUNET_OK !=
434  fs = 0;
435  if (0 == fs)
436  {
438  _ ("Hosts file %s has no data\n"),
439  filename);
440  return 0;
441  }
442  data = GNUNET_malloc (fs);
444  {
445  GNUNET_free (data);
447  _ ("Hosts file %s cannot be read\n"),
448  filename);
449  return 0;
450  }
451  buf = data;
452  offset = 0;
453  starting_host = NULL;
454  count = 0;
455  /* refer RFC 952 and RFC 1123 for valid hostnames */
456  GNUNET_assert (0 == regcomp (&rex,
457  "^(([[:alnum:]]+)@)?" /* username */
458  "([[:alnum:]]+[-[:alnum:]_\\.]+)" /* hostname */
459  "(:([[:digit:]]{1,5}))?", /* port */
460  REG_EXTENDED | REG_ICASE));
461  while (offset < (fs - 1))
462  {
463  offset++;
464  if (((data[offset] == '\n')) && (buf != &data[offset]))
465  {
466  unsigned int size;
467 
468  data[offset] = '\0';
469  username = NULL;
470  hostname = NULL;
471  port = 0;
472  if ((REG_NOMATCH == regexec (&rex, buf, 6, pmatch, 0)) ||
473  (-1 == pmatch[3].rm_so))
474  {
476  "Error reading line `%s' in hostfile\n",
477  buf);
478  buf = &data[offset + 1];
479  continue;
480  }
481  if (-1 != pmatch[2].rm_so)
482  {
483  size = pmatch[2].rm_eo - pmatch[2].rm_so;
484  username = GNUNET_malloc (size + 1);
485  GNUNET_assert (
486  0 != GNUNET_strlcpy (username, buf + pmatch[2].rm_so, size + 1));
487  }
488  if (-1 != pmatch[5].rm_so)
489  {
490  (void) sscanf (buf + pmatch[5].rm_so, "%5hd", &port);
491  }
492  size = pmatch[3].rm_eo - pmatch[3].rm_so;
493  hostname = GNUNET_malloc (size + 1);
494  GNUNET_assert (
495  0 != GNUNET_strlcpy (hostname, buf + pmatch[3].rm_so, size + 1));
497  "Successfully read host %s, port %d and user %s from file\n",
498  (NULL == hostname) ? "NULL" : hostname,
499  port,
500  (NULL == username) ? "NULL" : username);
501  /* We store hosts in a static list; hence we only require the starting
502  * host pointer in that list to access the newly created list of hosts */
503  if (NULL == starting_host)
504  starting_host =
506  else
508  count++;
511  buf = &data[offset + 1];
512  }
513  else if ((data[offset] == '\n') || (data[offset] == '\0'))
514  buf = &data[offset + 1];
515  }
516  regfree (&rex);
517  GNUNET_free (data);
518  if (NULL == starting_host)
519  return 0;
520  *hosts = GNUNET_malloc (sizeof(struct GNUNET_TESTBED_Host *) * count);
521  GNUNET_memcpy (*hosts,
522  &host_list[GNUNET_TESTBED_host_get_id_ (starting_host)],
523  sizeof(struct GNUNET_TESTBED_Host *) * count);
524  return count;
525 }
526 
527 
534 const char *
535 simple_resolve (const char *host)
536 {
537  struct addrinfo *res;
538  const struct sockaddr_in *in_addr;
539  char *hostip;
540  struct addrinfo hint;
541  unsigned int rc;
542 
543  hint.ai_family = AF_INET; /* IPv4 */
544  hint.ai_socktype = 0;
545  hint.ai_protocol = 0;
546  hint.ai_addrlen = 0;
547  hint.ai_addr = NULL;
548  hint.ai_canonname = NULL;
549  hint.ai_next = NULL;
550  hint.ai_flags = AI_NUMERICSERV;
551  res = NULL;
552  LOG_DEBUG ("Resolving [%s]\n", host);
553  if (0 != (rc = getaddrinfo (host, "22", &hint, &res)))
554  {
555  LOG_GAI (GNUNET_ERROR_TYPE_ERROR, "getaddrinfo", rc);
556  return NULL;
557  }
558  GNUNET_assert (NULL != res);
559  GNUNET_assert (NULL != res->ai_addr);
560  GNUNET_assert (sizeof(struct sockaddr_in) == res->ai_addrlen);
561  in_addr = (const struct sockaddr_in *) res->ai_addr;
562  hostip = inet_ntoa (in_addr->sin_addr);
563  GNUNET_assert (NULL != hostip);
564  freeaddrinfo (res);
565  LOG_DEBUG ("Resolved [%s] to [%s]\n", host, hostip);
566  return hostip;
567 }
568 
569 
576 void
578 {
579  GNUNET_assert (host->id < host_list_size);
580  GNUNET_assert (host_list[host->id] == host);
581  host_list[host->id] = NULL;
582  /* clear registered controllers list */
583  for (struct RegisteredController *rc = host->rc_head;
584  NULL != rc;
585  rc = host->rc_head)
586  {
587  GNUNET_CONTAINER_DLL_remove (host->rc_head, host->rc_tail, rc);
588  GNUNET_free (rc);
589  }
590  GNUNET_free_nz ((char *) host->username);
591  GNUNET_free_nz ((char *) host->hostname);
595  GNUNET_free (host);
597  {
598  uint32_t id;
599 
600  for (id = host_list_size - 1; id > host_list_size - HOST_LIST_GROW_STEP;
601  id--)
602  if (NULL != host_list[id])
603  break;
605  break;
606  if (NULL != host_list[id])
607  break;
609  }
610  host_list =
612  sizeof(struct GNUNET_TESTBED_Host *) * host_list_size);
613 }
614 
615 
622 void
624  struct GNUNET_TESTBED_Host *host,
625  const struct GNUNET_TESTBED_Controller *const controller)
626 {
627  struct RegisteredController *rc;
628 
629  for (rc = host->rc_head; NULL != rc; rc = rc->next)
630  {
631  if (controller == rc->controller) /* already registered at controller */
632  {
633  GNUNET_break (0);
634  return;
635  }
636  }
637  rc = GNUNET_new (struct RegisteredController);
638  rc->controller = controller;
640 }
641 
642 
649 void
651  struct GNUNET_TESTBED_Host *host,
652  const struct GNUNET_TESTBED_Controller *const controller)
653 {
654  struct RegisteredController *rc;
655 
656  for (rc = host->rc_head; NULL != rc; rc = rc->next)
657  if (controller == rc->controller)
658  break;
659  if (NULL == rc)
660  {
661  GNUNET_break (0);
662  return;
663  }
664  GNUNET_CONTAINER_DLL_remove (host->rc_head, host->rc_tail, rc);
665  GNUNET_free (rc);
666 }
667 
668 
676 int
678  const struct GNUNET_TESTBED_Host *host,
679  const struct GNUNET_TESTBED_Controller *const controller)
680 {
681  struct RegisteredController *rc;
682 
683  for (rc = host->rc_head; NULL != rc; rc = rc->next)
684  {
685  if (controller == rc->controller) /* already registered at controller */
686  {
687  return GNUNET_YES;
688  }
689  }
690  return GNUNET_NO;
691 }
692 
693 
698 {
703 
707  char **helper_argv;
708 
713 
718 
722  void *cls;
723 
728 
733 };
734 
735 
742 static char **
743 copy_argv (const char *const *argv)
744 {
745  char **argv_dup;
746  unsigned int argp;
747 
748  GNUNET_assert (NULL != argv);
749  for (argp = 0; NULL != argv[argp]; argp++)
750  ;
751  argv_dup = GNUNET_malloc (sizeof(char *) * (argp + 1));
752  for (argp = 0; NULL != argv[argp]; argp++)
753  argv_dup[argp] = GNUNET_strdup (argv[argp]);
754  return argv_dup;
755 }
756 
757 
765 static char **
766 join_argv (const char *const *argv1, const char *const *argv2)
767 {
768  char **argvj;
769  char *argv;
770  unsigned int carg;
771  unsigned int cnt;
772 
773  carg = 0;
774  argvj = NULL;
775  for (cnt = 0; NULL != argv1[cnt]; cnt++)
776  {
777  argv = GNUNET_strdup (argv1[cnt]);
778  GNUNET_array_append (argvj, carg, argv);
779  }
780  for (cnt = 0; NULL != argv2[cnt]; cnt++)
781  {
782  argv = GNUNET_strdup (argv2[cnt]);
783  GNUNET_array_append (argvj, carg, argv);
784  }
785  GNUNET_array_append (argvj, carg, NULL);
786  return argvj;
787 }
788 
789 
795 static void
796 free_argv (char **argv)
797 {
798  unsigned int argp;
799 
800  for (argp = 0; NULL != argv[argp]; argp++)
801  GNUNET_free (argv[argp]);
802  GNUNET_free (argv);
803 }
804 
805 
820 static char **
821 gen_rsh_args (const char *port, const char *hostname, const char *username)
822 {
823  static const char *default_ssh_args[] =
824  { "ssh",
825  "-o",
826  "BatchMode=yes",
827  "-o",
828  "NoHostAuthenticationForLocalhost=yes",
829  "-o",
830  "StrictHostKeyChecking=no",
831  "-o",
832  "PasswordAuthentication=no",
833  "%h",
834  NULL };
835  char **ssh_args;
836  char *ssh_cmd;
837  char *ssh_cmd_cp;
838  char *arg;
839  const char *new_arg;
840  unsigned int size;
841  unsigned int cnt;
842 
843  ssh_args = NULL;
844  if (NULL != (ssh_cmd = getenv ("GNUNET_TESTBED_RSH_CMD")))
845  {
846  ssh_cmd = GNUNET_strdup (ssh_cmd);
847  ssh_cmd_cp = ssh_cmd;
848  for (size = 0; NULL != (arg = strtok (ssh_cmd, " ")); ssh_cmd = NULL)
849  GNUNET_array_append (ssh_args, size, GNUNET_strdup (arg));
850  GNUNET_free (ssh_cmd_cp);
851  }
852  else
853  {
854  ssh_args = copy_argv (default_ssh_args);
855  size = (sizeof(default_ssh_args)) / (sizeof(const char *));
856  GNUNET_array_grow (ssh_args, size, size - 1);
857  }
858  for (cnt = 0; cnt < size; cnt++)
859  {
860  arg = ssh_args[cnt];
861  if ('%' != arg[0])
862  continue;
863  switch (arg[1])
864  {
865  case 'p':
866  new_arg = port;
867  break;
868 
869  case 'u':
870  new_arg = username;
871  break;
872 
873  case 'h':
874  new_arg = hostname;
875  break;
876 
877  default:
878  continue;
879  }
880  if (NULL == new_arg)
881  continue;
882  GNUNET_free (arg);
883  ssh_args[cnt] = GNUNET_strdup (new_arg);
884  }
885  GNUNET_array_append (ssh_args, size, NULL);
886  return ssh_args;
887 }
888 
889 
900 static char **
901 gen_rsh_suffix_args (const char *const *append_args)
902 {
903  char **rshell_args;
904  char *rshell_cmd;
905  char *rshell_cmd_cp;
906  char *arg;
907  unsigned int cnt;
908  unsigned int append_cnt;
909 
910  rshell_args = NULL;
911  cnt = 0;
912  if (NULL != (rshell_cmd = getenv ("GNUNET_TESTBED_RSH_CMD_SUFFIX")))
913  {
914  rshell_cmd = GNUNET_strdup (rshell_cmd);
915  rshell_cmd_cp = rshell_cmd;
916  for (; NULL != (arg = strtok (rshell_cmd, " ")); rshell_cmd = NULL)
917  GNUNET_array_append (rshell_args, cnt, GNUNET_strdup (arg));
918  GNUNET_free (rshell_cmd_cp);
919  }
920  if (NULL != append_args)
921  {
922  for (append_cnt = 0; NULL != append_args[append_cnt]; append_cnt++)
923  GNUNET_array_append (rshell_args,
924  cnt,
925  GNUNET_strdup (append_args[append_cnt]));
926  }
927  GNUNET_array_append (rshell_args, cnt, NULL);
928  return rshell_args;
929 }
930 
931 
944 static int
945 helper_mst (void *cls, const struct GNUNET_MessageHeader *message)
946 {
947  struct GNUNET_TESTBED_ControllerProc *cp = cls;
948  const struct GNUNET_TESTBED_HelperReply *msg;
949  const char *hostname;
950  char *config;
951  uLongf config_size;
952  uLongf xconfig_size;
953 
954  msg = (const struct GNUNET_TESTBED_HelperReply *) message;
955  GNUNET_assert (sizeof(struct GNUNET_TESTBED_HelperReply) <
956  ntohs (msg->header.size));
958  ntohs (msg->header.type));
959  config_size = (uLongf) ntohs (msg->config_size);
960  xconfig_size = (uLongf) (ntohs (msg->header.size)
961  - sizeof(struct GNUNET_TESTBED_HelperReply));
963  GNUNET_assert (Z_OK == uncompress ((Bytef *) config,
964  &config_size,
965  (const Bytef *) &msg[1],
966  xconfig_size));
967  /* Replace the configuration template present in the host with the
968  controller's running configuration */
972  config,
973  config_size,
974  NULL));
976  if (NULL == (hostname = GNUNET_TESTBED_host_get_hostname (cp->host)))
977  hostname = "localhost";
978  /* Change the hostname so that we can connect to it */
980  "testbed",
981  "hostname",
982  hostname);
983  cp->host->locked = GNUNET_NO;
985  cp->cb (cp->cls, cp->host->cfg, GNUNET_OK);
986  return GNUNET_OK;
987 }
988 
989 
998 static void
999 clear_msg (void *cls, int result)
1000 {
1001  struct GNUNET_TESTBED_ControllerProc *cp = cls;
1002 
1003  GNUNET_assert (NULL != cp->shandle);
1004  cp->shandle = NULL;
1005  GNUNET_free (cp->msg);
1006  cp->msg = NULL;
1007 }
1008 
1009 
1016 static void
1018 {
1019  struct GNUNET_TESTBED_ControllerProc *cp = cls;
1021  void *cb_cls;
1022 
1023  cb = cp->cb;
1024  cb_cls = cp->cls;
1025  cp->helper = NULL;
1027  if (NULL != cb)
1028  cb (cb_cls, NULL, GNUNET_SYSERR);
1029 }
1030 
1031 
1056 GNUNET_TESTBED_controller_start (const char *trusted_ip,
1057  struct GNUNET_TESTBED_Host *host,
1059  void *cls)
1060 {
1061  struct GNUNET_TESTBED_ControllerProc *cp;
1063  const struct GNUNET_CONFIGURATION_Handle *cfg;
1064  const char *hostname;
1065  static char *const binary_argv[] = { HELPER_TESTBED_BINARY, NULL };
1066 
1067  GNUNET_assert (NULL != host);
1068  GNUNET_assert (NULL != (cfg = GNUNET_TESTBED_host_get_cfg_ (host)));
1069  hostname = NULL;
1070  API_VIOLATION (
1071  GNUNET_NO == host->locked,
1072  "Host is already locked by a previous call to GNUNET_TESTBED_controller_start()");
1073  host->locked = GNUNET_YES;
1074  API_VIOLATION (
1075  GNUNET_NO == host->controller_started,
1076  "Attempting to start a controller on a host which is already started a controller");
1078  if (0 == GNUNET_TESTBED_host_get_id_ (host))
1079  {
1082  binary_argv,
1083  &helper_mst,
1084  &helper_exp_cb,
1085  cp);
1086  }
1087  else
1088  {
1089  char *helper_binary_path_args[2];
1090  char **rsh_args;
1091  char **rsh_suffix_args;
1092  const char *username;
1093  char *port;
1094  char *argstr;
1095  char *aux;
1096  unsigned int cnt;
1097 
1098  username = host->username;
1099  hostname = host->hostname;
1100  GNUNET_asprintf (&port, "%u", host->port);
1101  LOG_DEBUG ("Starting remote connection to destination %s\n", hostname);
1102  if (GNUNET_OK !=
1104  "testbed",
1105  "HELPER_BINARY_PATH",
1106  &helper_binary_path_args[0]))
1107  helper_binary_path_args[0] =
1109  helper_binary_path_args[1] = NULL;
1110  rsh_args = gen_rsh_args (port, hostname, username);
1111  rsh_suffix_args =
1112  gen_rsh_suffix_args ((const char **) helper_binary_path_args);
1113  cp->helper_argv =
1114  join_argv ((const char **) rsh_args, (const char **) rsh_suffix_args);
1115  free_argv (rsh_args);
1116  free_argv (rsh_suffix_args);
1117  GNUNET_free (port);
1118  argstr = GNUNET_strdup ("");
1119  for (cnt = 0; NULL != cp->helper_argv[cnt]; cnt++)
1120  {
1121  aux = argstr;
1122  GNUNET_assert (
1123  0 < GNUNET_asprintf (&argstr, "%s %s", aux, cp->helper_argv[cnt]));
1124  GNUNET_free (aux);
1125  }
1126  LOG_DEBUG ("Helper cmd str: %s\n", argstr);
1127  GNUNET_free (argstr);
1129  cp->helper_argv[0],
1130  cp->helper_argv,
1131  &helper_mst,
1132  &helper_exp_cb,
1133  cp);
1134  GNUNET_free (helper_binary_path_args[0]);
1135  }
1136  if (NULL == cp->helper)
1137  {
1138  if (NULL != cp->helper_argv)
1139  free_argv (cp->helper_argv);
1140  GNUNET_free (cp);
1141  return NULL;
1142  }
1143  cp->host = host;
1144  cp->cb = cb;
1145  cp->cls = cls;
1147  cp->msg = &msg->header;
1148  cp->shandle =
1149  GNUNET_HELPER_send (cp->helper, &msg->header, GNUNET_NO, &clear_msg, cp);
1150  if (NULL == cp->shandle)
1151  {
1152  GNUNET_free (msg);
1154  return NULL;
1155  }
1156  return cp;
1157 }
1158 
1159 
1165 void
1167 {
1168  if (NULL != cproc->shandle)
1170  if (NULL != cproc->helper)
1172 }
1173 
1174 
1180 void
1182 {
1183  if (NULL != cproc->helper)
1184  {
1186  GNUNET_HELPER_destroy (cproc->helper);
1187  }
1188  if (NULL != cproc->helper_argv)
1189  free_argv (cproc->helper_argv);
1190  cproc->host->controller_started = GNUNET_NO;
1191  cproc->host->locked = GNUNET_NO;
1192  GNUNET_free (cproc->msg);
1193  GNUNET_free (cproc);
1194 }
1195 
1196 
1205 void
1207 {
1210 }
1211 
1212 
1217 {
1221  const struct GNUNET_TESTBED_Host *host;
1222 
1227 
1231  void *cb_cls;
1232 
1237 
1241  char **helper_argv;
1242 
1247 
1253 };
1254 
1255 
1261 static void
1263 {
1265  void *cb_cls;
1267  const struct GNUNET_TESTBED_Host *host;
1268  unsigned long code;
1270  int ret;
1271 
1272  h->habitability_check_task = NULL;
1273  ret = GNUNET_OS_process_status (h->auxp, &type, &code);
1274  if (GNUNET_SYSERR == ret)
1275  {
1276  GNUNET_break (0);
1277  ret = GNUNET_NO;
1278  goto call_cb;
1279  }
1280  if (GNUNET_NO == ret)
1281  {
1282  h->wait_time = GNUNET_TIME_STD_BACKOFF (h->wait_time);
1283  h->habitability_check_task =
1285  return;
1286  }
1287  GNUNET_OS_process_destroy (h->auxp);
1288  h->auxp = NULL;
1289  ret = (0 != code) ? GNUNET_NO : GNUNET_YES;
1290 
1291  call_cb:
1292  if (NULL != h->auxp)
1293  GNUNET_OS_process_destroy (h->auxp);
1294  cb = h->cb;
1295  cb_cls = h->cb_cls;
1296  host = h->host;
1297  free_argv (h->helper_argv);
1298  GNUNET_free (h);
1299  if (NULL != cb)
1300  cb (cb_cls, host, ret);
1301 }
1302 
1303 
1317  const struct GNUNET_TESTBED_Host *host,
1318  const struct GNUNET_CONFIGURATION_Handle *config,
1320  void *cb_cls)
1321 {
1323  char **rsh_args;
1324  char **rsh_suffix_args;
1325  char *stat_args[3];
1326  const char *hostname;
1327  char *port;
1328 
1330  h->cb = cb;
1331  h->cb_cls = cb_cls;
1332  h->host = host;
1333  hostname = (NULL == host->hostname) ? "127.0.0.1" : host->hostname;
1334  if (GNUNET_OK !=
1336  "testbed",
1337  "HELPER_BINARY_PATH",
1338  &stat_args[1]))
1340  GNUNET_asprintf (&port, "%u", host->port);
1341  rsh_args = gen_rsh_args (port, hostname, host->username);
1342  GNUNET_free (port);
1343  port = NULL;
1344  stat_args[0] = "stat";
1345  stat_args[2] = NULL;
1346  rsh_suffix_args = gen_rsh_suffix_args ((const char **) stat_args);
1347  GNUNET_free (stat_args[1]);
1348  h->helper_argv =
1349  join_argv ((const char **) rsh_args, (const char **) rsh_suffix_args);
1350  free_argv (rsh_suffix_args);
1351  free_argv (rsh_args);
1353  NULL,
1354  NULL,
1355  NULL,
1356  h->helper_argv[0],
1357  h->helper_argv);
1358  if (NULL == h->auxp)
1359  {
1360  GNUNET_break (0); /* Cannot exec SSH? */
1361  GNUNET_free (h);
1362  return NULL;
1363  }
1364  h->wait_time = GNUNET_TIME_STD_BACKOFF (h->wait_time);
1365  h->habitability_check_task =
1367  return h;
1368 }
1369 
1370 
1376 void
1379 {
1380  GNUNET_SCHEDULER_cancel (handle->habitability_check_task);
1382  (void) GNUNET_OS_process_wait (handle->auxp);
1384  free_argv (handle->helper_argv);
1385  GNUNET_free (handle);
1386 }
1387 
1388 
1403  struct GNUNET_TESTBED_Host *host,
1405  void *cc_cls)
1406 {
1409  const char *username;
1410  const char *hostname;
1411  char *config;
1412  char *cconfig;
1413  void *ptr;
1414  size_t cc_size;
1415  size_t config_size;
1416  uint16_t msg_size;
1417  uint16_t username_length;
1418  uint16_t hostname_length;
1419 
1420  if (NULL != controller->rh)
1421  return NULL;
1423  if (GNUNET_YES == GNUNET_TESTBED_is_host_registered_ (host, controller))
1424  {
1426  "Host hostname: %s already registered\n",
1427  (NULL == hostname) ? "localhost" : hostname);
1428  return NULL;
1429  }
1431  rh->host = host;
1432  rh->c = controller;
1433  GNUNET_assert (NULL != cc);
1434  rh->cc = cc;
1435  rh->cc_cls = cc_cls;
1436  controller->rh = rh;
1437  username = GNUNET_TESTBED_host_get_username_ (host);
1438  username_length = 0;
1439  if (NULL != username)
1440  username_length = strlen (username);
1441  GNUNET_assert (NULL != hostname); /* Hostname must be present */
1442  hostname_length = strlen (hostname);
1443  GNUNET_assert (NULL != host->cfg);
1445  cc_size = GNUNET_TESTBED_compress_config_ (config, config_size, &cconfig);
1446  GNUNET_free (config);
1447  msg_size = (sizeof(struct GNUNET_TESTBED_AddHostMessage));
1448  msg_size += username_length;
1449  msg_size += hostname_length;
1450  msg_size += cc_size;
1451  msg = GNUNET_malloc (msg_size);
1452  msg->header.size = htons (msg_size);
1453  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST);
1454  msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (host));
1455  msg->ssh_port = htons (GNUNET_TESTBED_host_get_ssh_port_ (host));
1456  ptr = &msg[1];
1457  if (NULL != username)
1458  {
1459  msg->username_length = htons (username_length);
1460  GNUNET_memcpy (ptr, username, username_length);
1461  ptr += username_length;
1462  }
1463  msg->hostname_length = htons (hostname_length);
1465  ptr += hostname_length;
1466  msg->config_size = htons (config_size);
1467  GNUNET_memcpy (ptr, cconfig, cc_size);
1468  ptr += cc_size;
1469  GNUNET_assert ((ptr - (void *) msg) == msg_size);
1470  GNUNET_free (cconfig);
1471  GNUNET_TESTBED_queue_message_ (controller,
1472  (struct GNUNET_MessageHeader *) msg);
1473  return rh;
1474 }
1475 
1476 
1484 void
1487 {
1488  if (handle != handle->c->rh)
1489  {
1490  GNUNET_break (0);
1491  return;
1492  }
1493  handle->c->rh = NULL;
1494  GNUNET_free (handle);
1495 }
1496 
1497 
1506 void
1508  struct GNUNET_TESTBED_Operation *op)
1509 {
1511  h->opq_parallel_overlay_connect_operations,
1512  op);
1513 }
1514 
1515 
1521 void
1523 {
1524  char *hostname;
1525 
1526  hostname = (char *) host->hostname;
1527  host->hostname = simple_resolve (hostname);
1528  if (NULL == host->hostname)
1529  {
1530  GNUNET_break (0);
1531  host->hostname = hostname;
1532  return;
1533  }
1535  host->hostname = GNUNET_strdup (host->hostname);
1536 }
1537 
1538 
1539 /* 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:83
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:36
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
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
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:482
enum GNUNET_GenericReturnValue GNUNET_DISK_file_size(const char *filename, uint64_t *size, int include_symbolic_links, int single_file_mode)
Get the size of the file (or directory) of the given file (in bytes).
Definition: disk.c:222
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
#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:697
int GNUNET_HELPER_kill(struct GNUNET_HELPER_Handle *h, int soft_kill)
Sends termination signal to the helper process.
Definition: helper.c:177
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:657
int GNUNET_HELPER_wait(struct GNUNET_HELPER_Handle *h)
Reap the helper process.
Definition: helper.c:225
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:491
void GNUNET_HELPER_destroy(struct GNUNET_HELPER_Handle *h)
Free's the resources occupied by the helper handle.
Definition: helper.c:530
#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:946
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:604
int GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc)
Wait for a process to terminate.
Definition: os_priority.c:983
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:286
int GNUNET_OS_process_kill(struct GNUNET_OS_Process *proc, int sig)
Sends a signal to the process.
Definition: os_priority.c:224
@ GNUNET_OS_INHERIT_STD_ERR
When this flag is set, the child process will inherit stderr of the parent.
Definition: gnunet_os_lib.h:91
#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:972
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:1269
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:162
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:67
#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:79
Entry in the queue of messages we need to transmit to the helper.
Definition: helper.c:37
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:135
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:1981
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 the 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.