/** * Functions with this signature are called whenever a * complete message is received by the tokenizer. * * Do not call GNUNET_SERVER_mst_destroy in callback * * @param cls closure * @param client identification of the client * @param message the actual message * * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing */ static int helper_mst (void *cls, void *client, const struct GNUNET_MessageHeader *message) { struct GNUNET_TESTBED_ControllerProc *cp = cls; const struct GNUNET_TESTBED_HelperReply *msg; const char *hostname; char *config; uLongf config_size; uLongf xconfig_size; msg = (const struct GNUNET_TESTBED_HelperReply *) message; GNUNET_assert (sizeof (struct GNUNET_TESTBED_HelperReply) < ntohs (msg->header.size)); GNUNET_assert (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY == ntohs (msg->header.type)); config_size = (uLongf) ntohs (msg->config_size); xconfig_size = (uLongf) (ntohs (msg->header.size) - sizeof (struct GNUNET_TESTBED_HelperReply)); config = GNUNET_malloc (config_size); GNUNET_assert (Z_OK == uncompress ((Bytef *) config, &config_size, (const Bytef *) &msg[1], xconfig_size)); /* Replace the configuration template present in the host with the controller's running configuration */ GNUNET_CONFIGURATION_destroy (cp->host->cfg); cp->host->cfg = GNUNET_CONFIGURATION_create (); GNUNET_assert (GNUNET_CONFIGURATION_deserialize (cp->host->cfg, config, config_size, GNUNET_NO)); GNUNET_free (config); if (NULL == (hostname = GNUNET_TESTBED_host_get_hostname (cp->host))) hostname = "localhost"; /* Change the hostname so that we can connect to it */ GNUNET_CONFIGURATION_set_value_string (cp->host->cfg, "testbed", "hostname", hostname); cp->host->locked = GNUNET_NO; cp->host->controller_started = GNUNET_YES; cp->cb (cp->cls, cp->host->cfg, GNUNET_OK); return GNUNET_OK; }
/** * The main scheduler run task * * @param cls NULL * @param tc scheduler task context */ static void run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_TESTBED_Host **hosts; const struct GNUNET_CONFIGURATION_Handle *null_cfg; char *tmpdir; char *hostname; size_t hostname_len; unsigned int nhosts; null_cfg = GNUNET_CONFIGURATION_create (); nhosts = GNUNET_TESTBED_hosts_load_from_loadleveler (null_cfg, &hosts); if (0 == nhosts) { GNUNET_break (0); ret = GNUNET_SYSERR; return; } hostname_len = GNUNET_OS_get_hostname_max_length (); hostname = GNUNET_malloc (hostname_len); if (0 != gethostname (hostname, hostname_len)) { LOG (GNUNET_ERROR_TYPE_ERROR, "Cannot get hostname. Exiting\n"); GNUNET_free (hostname); destroy_hosts (hosts, nhosts); ret = GNUNET_SYSERR; return; } if (NULL == strstr (GNUNET_TESTBED_host_get_hostname (hosts[0]), hostname)) { LOG_DEBUG ("Exiting as `%s' is not the lowest host\n", hostname); GNUNET_free (hostname); ret = GNUNET_OK; return; } LOG_DEBUG ("Will be executing `%s' on host `%s'\n", argv2[0], hostname); GNUNET_free (hostname); destroy_hosts (hosts, nhosts); tmpdir = getenv ("TMPDIR"); if (NULL == tmpdir) tmpdir = getenv ("TMP"); if (NULL == tmpdir) tmpdir = getenv ("TEMP"); if (NULL == tmpdir) tmpdir = "/tmp"; (void) GNUNET_asprintf (&fn, "%s/gnunet-testbed-spawn.lock", tmpdir); /* Open the unique file; we can create it then we can spawn the child process else we exit */ fh = open (fn, O_CREAT | O_EXCL | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (-1 == fh) { if (EEXIST == errno) { LOG_DEBUG ("Lock file already created by other process. Exiting\n"); ret = GNUNET_OK; return; } GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "open"); ret = GNUNET_SYSERR; return; } /* Spawn the new process here */ LOG (GNUNET_ERROR_TYPE_INFO, _("Spawning process `%s'\n"), argv2[0]); child = GNUNET_OS_start_process_vap (GNUNET_NO, GNUNET_OS_INHERIT_STD_ALL, NULL, NULL, NULL, argv2[0], argv2); if (NULL == child) { GNUNET_break (0); ret = GNUNET_SYSERR; shutdown_task_id = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); return; } ret = GNUNET_OK; terminate_task_id = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &terminate_task, NULL); child_death_task_id = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ), &child_death_task, NULL); }
/** * Main run function. * * @param cls NULL * @param args arguments passed to GNUNET_PROGRAM_run * @param cfgfile the path to configuration file * @param cfg the configuration file handle */ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *config) { unsigned int cnt; cfg = GNUNET_CONFIGURATION_dup (config); host = GNUNET_TESTBED_host_create ("localhost", NULL, cfg, 0); GNUNET_assert (NULL != host); GNUNET_assert (0 != GNUNET_TESTBED_host_get_id_ (host)); GNUNET_TESTBED_host_destroy (host); host = GNUNET_TESTBED_host_create (NULL, NULL, cfg, 0); GNUNET_assert (NULL != host); GNUNET_assert (0 == GNUNET_TESTBED_host_get_id_ (host)); GNUNET_assert (host == GNUNET_TESTBED_host_lookup_by_id_ (0)); hosts = NULL; num_hosts = GNUNET_TESTBED_hosts_load_from_file ("sample_hosts.txt", cfg, &hosts); GNUNET_assert (7 == num_hosts); GNUNET_assert (NULL != hosts); for (cnt = 0; cnt < num_hosts; cnt++) { if (cnt < 3) { GNUNET_assert (0 == strcmp ("totakura", GNUNET_TESTBED_host_get_username_ (hosts[cnt]))); GNUNET_assert (NULL != GNUNET_TESTBED_host_get_hostname (hosts[cnt])); GNUNET_assert (22 == GNUNET_TESTBED_host_get_ssh_port_ (hosts[cnt])); } if (3 == cnt) { GNUNET_assert (0 == strcmp ("totakura", GNUNET_TESTBED_host_get_username_ (hosts[cnt]))); GNUNET_assert (NULL != GNUNET_TESTBED_host_get_hostname (hosts[cnt])); GNUNET_assert (2022 == GNUNET_TESTBED_host_get_ssh_port_ (hosts[cnt])); } if (4 == cnt) { GNUNET_assert (0 == strcmp ("totakura", GNUNET_TESTBED_host_get_username_ (hosts[cnt]))); GNUNET_assert (0 == strcmp ("asgard.realm", GNUNET_TESTBED_host_get_hostname (hosts[cnt]))); GNUNET_assert (22 == GNUNET_TESTBED_host_get_ssh_port_ (hosts[cnt])); } if (5 == cnt) { GNUNET_assert (NULL == GNUNET_TESTBED_host_get_username_ (hosts[cnt])); GNUNET_assert (0 == strcmp ("rivendal", GNUNET_TESTBED_host_get_hostname (hosts[cnt]))); GNUNET_assert (22 == GNUNET_TESTBED_host_get_ssh_port_ (hosts[cnt])); } if (6 == cnt) { GNUNET_assert (NULL == GNUNET_TESTBED_host_get_username_ (hosts[cnt])); GNUNET_assert (0 == strcmp ("rohan", GNUNET_TESTBED_host_get_hostname (hosts[cnt]))); GNUNET_assert (561 == GNUNET_TESTBED_host_get_ssh_port_ (hosts[cnt])); } } status = GNUNET_YES; shutdown_id = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (0), &do_shutdown, NULL); }
/** * Register a host with the controller * * @param controller the controller handle * @param host the host to register * @param cc the completion callback to call to inform the status of * registration. After calling this callback the registration handle * will be invalid. Cannot be NULL. * @param cc_cls the closure for the cc * @return handle to the host registration which can be used to cancel the * registration */ 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) { struct GNUNET_TESTBED_HostRegistrationHandle *rh; struct GNUNET_TESTBED_AddHostMessage *msg; const char *username; const char *hostname; char *config; char *cconfig; void *ptr; size_t cc_size; size_t config_size; uint16_t msg_size; uint16_t username_length; uint16_t hostname_length; if (NULL != controller->rh) return NULL; hostname = GNUNET_TESTBED_host_get_hostname (host); if (GNUNET_YES == GNUNET_TESTBED_is_host_registered_ (host, controller)) { LOG (GNUNET_ERROR_TYPE_WARNING, "Host hostname: %s already registered\n", (NULL == hostname) ? "localhost" : hostname); return NULL; } rh = GNUNET_new (struct GNUNET_TESTBED_HostRegistrationHandle); rh->host = host; rh->c = controller; GNUNET_assert (NULL != cc); rh->cc = cc; rh->cc_cls = cc_cls; controller->rh = rh; username = GNUNET_TESTBED_host_get_username_ (host); username_length = 0; if (NULL != username) username_length = strlen (username); GNUNET_assert (NULL != hostname); /* Hostname must be present */ hostname_length = strlen (hostname); GNUNET_assert (NULL != host->cfg); config = GNUNET_CONFIGURATION_serialize (host->cfg, &config_size); cc_size = GNUNET_TESTBED_compress_config_ (config, config_size, &cconfig); GNUNET_free (config); msg_size = (sizeof (struct GNUNET_TESTBED_AddHostMessage)); msg_size += username_length; msg_size += hostname_length; msg_size += cc_size; msg = GNUNET_malloc (msg_size); msg->header.size = htons (msg_size); msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST); msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (host)); msg->ssh_port = htons (GNUNET_TESTBED_host_get_ssh_port_ (host)); ptr = &msg[1]; if (NULL != username) { msg->username_length = htons (username_length); GNUNET_memcpy (ptr, username, username_length); ptr += username_length; } msg->hostname_length = htons (hostname_length); GNUNET_memcpy (ptr, hostname, hostname_length); ptr += hostname_length; msg->config_size = htons (config_size); GNUNET_memcpy (ptr, cconfig, cc_size); ptr += cc_size; GNUNET_assert ((ptr - (void *) msg) == msg_size); GNUNET_free (cconfig); GNUNET_TESTBED_queue_message_ (controller, (struct GNUNET_MessageHeader *) msg); return rh; }