- struct GNUNET_TESTING_Daemon *daemon = cls;
- int msize;
-
-#if EMPTY_HACK
- int empty;
-
- empty = GNUNET_YES;
- GNUNET_assert (message != NULL);
- GNUNET_HELLO_iterate_addresses ((const struct GNUNET_HELLO_Message *) message,
- GNUNET_NO, &test_address, &empty);
- if (GNUNET_YES == empty)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Skipping empty HELLO address of peer %s\n",
- GNUNET_i2s (&daemon->id));
- return;
- }
-#endif
- GNUNET_assert (daemon->phase == SP_GET_HELLO ||
- daemon->phase == SP_START_DONE);
- daemon->cb = NULL; // FIXME: why??? (see fsm:SP_START_CORE, notify_daemon_started)
- if (daemon->task != GNUNET_SCHEDULER_NO_TASK) /* Assertion here instead? */
- GNUNET_SCHEDULER_cancel (daemon->task);
-
- if (daemon->server != NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received `%s' from transport service of `%4s', disconnecting core!\n",
- "HELLO", GNUNET_i2s (&daemon->id));
- GNUNET_CORE_disconnect (daemon->server);
- daemon->server = NULL;
- }
-
- msize = ntohs (message->size);
- if (msize < 1)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "HELLO message of peer %s is of size 0\n",
- GNUNET_i2s (&daemon->id));
- return;
- }
- if (daemon->ghh != NULL)
- {
- GNUNET_TRANSPORT_get_hello_cancel (daemon->ghh);
- daemon->ghh = NULL;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received `%s' from transport service of `%4s'\n", "HELLO",
- GNUNET_i2s (&daemon->id));
- GNUNET_free_non_null (daemon->hello);
- daemon->hello = GNUNET_malloc (msize);
- memcpy (daemon->hello, message, msize);
-
- if (daemon->th != NULL)
- {
- GNUNET_TRANSPORT_disconnect (daemon->th);
- daemon->th = NULL;
- }
- daemon->phase = SP_START_DONE;
-}
-
-
-/**
- * Notify of a peer being up and running. Scheduled as a task
- * so that variables which may need to be set are set before
- * the connect callback can set up new operations.
- * FIXME: what variables?????? where from????
- *
- * @param cls the testing daemon
- * @param tc task scheduler context
- */
-static void
-notify_daemon_started (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct GNUNET_TESTING_Daemon *d = cls;
- GNUNET_TESTING_NotifyDaemonRunning cb;
-
- cb = d->cb;
- d->cb = NULL;
- if (NULL != cb)
- cb (d->cb_cls, &d->id, d->cfg, d, NULL);
-}
-
-
-/**
- * Finite-state machine for starting GNUnet.
- *
- * @param cls our "struct GNUNET_TESTING_Daemon"
- * @param tc unused
- */
-static void
-start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct GNUNET_TESTING_Daemon *d = cls;
- GNUNET_TESTING_NotifyDaemonRunning cb;
- enum GNUNET_OS_ProcessStatusType type;
- unsigned long code;
- char *dst;
- int bytes_read;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer %s FSM is in phase %u.\n",
- GNUNET_i2s (&d->id), d->phase);
- d->task = GNUNET_SCHEDULER_NO_TASK;
- switch (d->phase)
- {
- case SP_COPYING:
- /* confirm copying complete */
- if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code))
- {
- if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0)
- {
- cb = d->cb;
- d->cb = NULL;
- if (NULL != cb)
- cb (d->cb_cls, NULL, d->cfg, d,
- _
- ("`scp' does not seem to terminate (timeout copying config).\n"));
- return;
- }
- /* wait some more */
- d->task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm,
- d);
- return;
- }
- if ((type != GNUNET_OS_PROCESS_EXITED) || (code != 0))
- {
- cb = d->cb;
- d->cb = NULL;
- if (NULL != cb)
- cb (d->cb_cls, NULL, d->cfg, d, _("`scp' did not complete cleanly.\n"));
- return;
- }
- GNUNET_OS_process_close (d->proc);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Successfully copied configuration file.\n");
- d->phase = SP_COPIED;
- /* fall-through */
- case SP_COPIED:
- /* Start create hostkey process if we don't already know the peer identity! */
- if (GNUNET_NO == d->have_hostkey)
- {
- d->pipe_stdout = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_YES);
- if (d->pipe_stdout == NULL)
- {
- cb = d->cb;
- d->cb = NULL;
- if (NULL != cb)
- cb (d->cb_cls, NULL, d->cfg, d,
- (NULL ==
- d->hostname) ?
- _("Failed to create pipe for `gnunet-peerinfo' process.\n") :
- _("Failed to create pipe for `ssh' process.\n"));
- return;
- }
- if (NULL == d->hostname)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Starting `%s', with command `%s %s %s %s'.\n",
- "gnunet-peerinfo", "gnunet-peerinfo", "-c", d->cfgfile,
- "-sq");
- d->proc =
- GNUNET_OS_start_process (GNUNET_YES, NULL, d->pipe_stdout, "gnunet-peerinfo",
- "gnunet-peerinfo", "-c", d->cfgfile, "-sq",
- NULL);
- GNUNET_DISK_pipe_close_end (d->pipe_stdout, GNUNET_DISK_PIPE_END_WRITE);
- }
- else
- {
- if (d->username != NULL)
- GNUNET_asprintf (&dst, "%s@%s", d->username, d->hostname);
- else
- dst = GNUNET_strdup (d->hostname);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Starting `%s', with command `%s %s %s %s %s %s'.\n",
- "gnunet-peerinfo", "ssh", dst, "gnunet-peerinfo", "-c",
- d->cfgfile, "-sq");
- if (d->ssh_port_str == NULL)
- {
- d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, d->pipe_stdout, "ssh", "ssh",
-#if !DEBUG_TESTING
- "-q",
-#endif
- dst, "gnunet-peerinfo", "-c",
- d->cfgfile, "-sq", NULL);
- }
- else
- {
- d->proc =
- GNUNET_OS_start_process (GNUNET_NO, NULL, d->pipe_stdout, "ssh", "ssh", "-p",
- d->ssh_port_str,
-#if !DEBUG_TESTING
- "-q",
-#endif
- dst, "gnunet-peerinfo", "-c", d->cfgfile,
- "-sq", NULL);
- }
- GNUNET_DISK_pipe_close_end (d->pipe_stdout, GNUNET_DISK_PIPE_END_WRITE);
- GNUNET_free (dst);
- }
- if (NULL == d->proc)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("Could not start `%s' process to create hostkey.\n"),
- (NULL == d->hostname) ? "gnunet-peerinfo" : "ssh");
- cb = d->cb;
- d->cb = NULL;
- if (NULL != cb)
- cb (d->cb_cls, NULL, d->cfg, d,
- (NULL ==
- d->hostname) ? _("Failed to start `gnunet-peerinfo' process.\n")
- : _("Failed to start `ssh' process.\n"));
- GNUNET_DISK_pipe_close (d->pipe_stdout);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Started `%s', waiting for hostkey.\n", "gnunet-peerinfo");
- d->phase = SP_HOSTKEY_CREATE;
- d->task =
- GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining
- (d->max_timeout),
- GNUNET_DISK_pipe_handle
- (d->pipe_stdout,
- GNUNET_DISK_PIPE_END_READ),
- &start_fsm, d);
- }
- else /* Already have a hostkey! */
- {
- if (d->hostkey_callback != NULL)
- {
- d->hostkey_callback (d->hostkey_cls, &d->id, d, NULL);
- d->hostkey_callback = NULL;
- d->phase = SP_HOSTKEY_CREATED;
- }
- else
- d->phase = SP_TOPOLOGY_SETUP;
-
- /* wait some more */
- d->task = GNUNET_SCHEDULER_add_now (&start_fsm, d);
- }
- break;
- case SP_HOSTKEY_CREATE:
- bytes_read =
- GNUNET_DISK_file_read (GNUNET_DISK_pipe_handle
- (d->pipe_stdout, GNUNET_DISK_PIPE_END_READ),
- &d->hostkeybuf[d->hostkeybufpos],
- sizeof (d->hostkeybuf) - d->hostkeybufpos);
- if (bytes_read > 0)
- d->hostkeybufpos += bytes_read;
-
- if ((d->hostkeybufpos < 104) && (bytes_read > 0))
- {
- /* keep reading */
- d->task =
- GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining
- (d->max_timeout),
- GNUNET_DISK_pipe_handle
- (d->pipe_stdout,
- GNUNET_DISK_PIPE_END_READ),
- &start_fsm, d);
- return;
- }
- d->hostkeybuf[103] = '\0';
-
- if ((bytes_read < 0) ||
- (GNUNET_OK !=
- GNUNET_CRYPTO_hash_from_string (d->hostkeybuf, &d->id.hashPubKey)))
- {
- /* error */
- if (bytes_read < 0)
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _("Error reading from gnunet-peerinfo: %s\n"),
- STRERROR (errno));
- else
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _("Malformed output from gnunet-peerinfo!\n"));
- cb = d->cb;
- d->cb = NULL;
- GNUNET_DISK_pipe_close (d->pipe_stdout);
- d->pipe_stdout = NULL;
- (void) GNUNET_OS_process_kill (d->proc, SIGKILL);
- GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (d->proc));
- GNUNET_OS_process_close (d->proc);
- d->proc = NULL;
- if (NULL != cb)
- cb (d->cb_cls, NULL, d->cfg, d, _("Failed to get hostkey!\n"));
- return;
- }
- d->shortname = GNUNET_strdup (GNUNET_i2s (&d->id));
- GNUNET_DISK_pipe_close (d->pipe_stdout);
- d->pipe_stdout = NULL;
- (void) GNUNET_OS_process_kill (d->proc, SIGKILL);
- GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (d->proc));
- GNUNET_OS_process_close (d->proc);
- d->proc = NULL;
- d->have_hostkey = GNUNET_YES;
- if (d->hostkey_callback != NULL)
- {
- d->hostkey_callback (d->hostkey_cls, &d->id, d, NULL);
- d->hostkey_callback = NULL;
- d->phase = SP_HOSTKEY_CREATED;
- }
- else
- {
- d->phase = SP_TOPOLOGY_SETUP;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully got hostkey!\n");
- /* Fall through */
- case SP_HOSTKEY_CREATED:
- /* wait for topology finished */
- if ((GNUNET_YES == d->dead) ||
- (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0))
- {
- cb = d->cb;
- d->cb = NULL;
- if (NULL != cb)
- cb (d->cb_cls, NULL, d->cfg, d,
- _("`Failed while waiting for topology setup!\n"));
- return;
- }
-
- d->task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm,
- d);
- break;
- case SP_TOPOLOGY_SETUP: /* Indicates topology setup has completed! */
- /* start GNUnet on remote host */
- if (NULL == d->hostname)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Starting `%s', with command `%s %s %s %s %s %s'.\n",
- "gnunet-arm", "gnunet-arm", "-c", d->cfgfile, "-L", "DEBUG",
- "-s");
- d->proc =
- GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm", "-c",
- d->cfgfile,
- "-L", "DEBUG",
- "-s", "-q", "-T",
- GNUNET_TIME_relative_to_string
- (GNUNET_TIME_absolute_get_remaining
- (d->max_timeout)), NULL);
- }
- else
- {
- if (d->username != NULL)
- GNUNET_asprintf (&dst, "%s@%s", d->username, d->hostname);
- else
- dst = GNUNET_strdup (d->hostname);
-
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Starting `%s', with command `%s %s %s %s %s %s %s %s'.\n",
- "gnunet-arm", "ssh", dst, "gnunet-arm", "-c", d->cfgfile,
- "-L", "DEBUG", "-s", "-q");
- if (d->ssh_port_str == NULL)
- {
- d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh",
-#if !DEBUG_TESTING
- "-q",
-#endif
- dst, "gnunet-arm",
-#if DEBUG_TESTING
- "-L", "DEBUG",
-#endif
- "-c", d->cfgfile, "-s", "-q", "-T",
- GNUNET_TIME_relative_to_string
- (GNUNET_TIME_absolute_get_remaining
- (d->max_timeout)), NULL);
- }
- else
- {
-
- d->proc =
- GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", "-p",
- d->ssh_port_str,
-#if !DEBUG_TESTING
- "-q",
-#endif
- dst, "gnunet-arm",
-#if DEBUG_TESTING
- "-L", "DEBUG",
-#endif
- "-c", d->cfgfile, "-s", "-q", "-T",
- GNUNET_TIME_relative_to_string
- (GNUNET_TIME_absolute_get_remaining
- (d->max_timeout)), NULL);
- }
- GNUNET_free (dst);
- }
- if (NULL == d->proc)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("Could not start `%s' process to start GNUnet.\n"),
- (NULL == d->hostname) ? "gnunet-arm" : "ssh");
- cb = d->cb;
- d->cb = NULL;
- if (NULL != cb)
- cb (d->cb_cls, NULL, d->cfg, d,
- (NULL ==
- d->hostname) ? _("Failed to start `gnunet-arm' process.\n") :
- _("Failed to start `ssh' process.\n"));
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Started `%s', waiting for `%s' to be up.\n", "gnunet-arm",
- "gnunet-service-core");
- d->phase = SP_START_ARMING;
- d->task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm,
- d);
- break;
- case SP_START_ARMING:
- if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code))
- {
- if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0)
- {
- cb = d->cb;
- d->cb = NULL;
- if (NULL != cb)
- cb (d->cb_cls, NULL, d->cfg, d,
- (NULL ==
- d->hostname) ? _("`gnunet-arm' does not seem to terminate.\n") :
- _("`ssh' does not seem to terminate.\n"));
- if (d->cfg != NULL)
- {
- GNUNET_CONFIGURATION_destroy (d->cfg);
- d->cfg = NULL;
- }
- if (d->cfgfile != NULL)
- {
- GNUNET_free (d->cfgfile);
- d->cfgfile = NULL;
- }
- GNUNET_free_non_null (d->hostname);
- GNUNET_free_non_null (d->username);
- GNUNET_free (d->proc);
-// GNUNET_free (d); // FIXME (could this leak)
- d->hostname = NULL; // Quick hack to avoid crashing (testing need to be
- d->cfg = NULL; // overhauled anyway, and the error managing is
- // pretty broken anyway.
- return;
- }
- /* wait some more */
- d->task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm,
- d);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully started `%s'.\n",
- "gnunet-arm");
- GNUNET_free (d->proc);
- d->phase = SP_START_CORE;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Calling CORE_connect\n");
- /* Fall through */
- case SP_START_CORE:
- if (d->server != NULL)
- GNUNET_CORE_disconnect (d->server);
-
- d->th = GNUNET_TRANSPORT_connect (d->cfg, &d->id, d, NULL, NULL, NULL);
- if (d->th == NULL)
- {
- if (GNUNET_YES == d->dead)
- GNUNET_TESTING_daemon_stop (d,
- GNUNET_TIME_absolute_get_remaining
- (d->max_timeout), d->dead_cb,
- d->dead_cb_cls, GNUNET_YES, GNUNET_NO);
- else if (NULL != d->cb)
- d->cb (d->cb_cls, &d->id, d->cfg, d,
- _("Failed to connect to transport service!\n"));
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Connected to transport service `%s', getting HELLO\n",
- GNUNET_i2s (&d->id));
- d->ghh = GNUNET_TRANSPORT_get_hello (d->th, &process_hello, d);
- /* FIXME: store task ID somewhere! */
- GNUNET_SCHEDULER_add_now (¬ify_daemon_started, d);
- /*cb = d->cb;
- * d->cb = NULL;
- * if (NULL != cb)
- * cb (d->cb_cls, &d->id, d->cfg, d, NULL); */
- d->running = GNUNET_YES;
- d->phase = SP_GET_HELLO;
- break;
- case SP_GET_HELLO:
- if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0)
- {
- if (d->server != NULL)
- GNUNET_CORE_disconnect (d->server);
- if (d->th != NULL)
- GNUNET_TRANSPORT_disconnect (d->th);
- cb = d->cb;
- d->cb = NULL;
- if (NULL != cb)
- cb (d->cb_cls, NULL, d->cfg, d, _("Unable to get HELLO for peer!\n"));
- GNUNET_CONFIGURATION_destroy (d->cfg);
- GNUNET_free (d->cfgfile);
- GNUNET_free_non_null (d->hostname);
- GNUNET_free_non_null (d->username);
- GNUNET_free (d);
- return;
- }
- if (d->hello != NULL)
- return;
- GNUNET_assert (d->task == GNUNET_SCHEDULER_NO_TASK);
- d->task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
- (GNUNET_CONSTANTS_SERVICE_RETRY, 2),
- &start_fsm, d);
- break;
- case SP_START_DONE:
- GNUNET_break (0);
- break;
- case SP_SERVICE_START:
- /* confirm gnunet-arm exited */
- if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code))
- {
- if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0)
- {
- cb = d->cb;
- d->cb = NULL;
- if (NULL != cb)
- cb (d->cb_cls, NULL, d->cfg, d,
- (NULL ==
- d->hostname) ? _("`gnunet-arm' does not seem to terminate.\n") :
- _("`ssh' does not seem to terminate.\n"));
- return;
- }
- /* wait some more */
- d->task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm,
- d);
- return;
- }
-#if EXTRA_CHECKS
- if ((type != GNUNET_OS_PROCESS_EXITED) || (code != 0))
- {
- cb = d->cb;
- d->cb = NULL;
- if (NULL != cb)
- cb (d->cb_cls, NULL, d->cfg, d,
- (NULL ==
- d->hostname) ?
- _
- ("`gnunet-arm' terminated with non-zero exit status (or timed out)!\n")
- : _("`ssh' does not seem to terminate.\n"));
- return;
- }
-#endif
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service startup complete!\n");
- cb = d->cb;
- d->cb = NULL;
- d->phase = SP_START_DONE;
- if (NULL != cb)
- cb (d->cb_cls, &d->id, d->cfg, d, NULL);
- break;
- case SP_SERVICE_SHUTDOWN_START:
- /* confirm copying complete */
- if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code))
- {
- if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0)
- {
- if (NULL != d->dead_cb)
- d->dead_cb (d->dead_cb_cls,
- _
- ("either `gnunet-arm' or `ssh' does not seem to terminate.\n"));
- return;
- }
- /* wait some more */
- d->task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm,
- d);
- return;
- }
-#if EXTRA_CHECKS
- if ((type != GNUNET_OS_PROCESS_EXITED) || (code != 0))
- {
- if (NULL != d->dead_cb)
- d->dead_cb (d->dead_cb_cls,
- _
- ("shutdown (either `gnunet-arm' or `ssh') did not complete cleanly.\n"));
- return;
- }
-#endif
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service shutdown complete.\n");
- if (NULL != d->dead_cb)
- d->dead_cb (d->dead_cb_cls, NULL);
- break;
- case SP_SHUTDOWN_START:
- /* confirm copying complete */
- if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code))
- {
- if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0)
- {
- if (NULL != d->dead_cb)
- d->dead_cb (d->dead_cb_cls,
- _
- ("either `gnunet-arm' or `ssh' does not seem to terminate.\n"));
- if (d->th != NULL)
- {
- GNUNET_TRANSPORT_get_hello_cancel (d->ghh);
- d->ghh = NULL;
- GNUNET_TRANSPORT_disconnect (d->th);
- d->th = NULL;
- }
- if (d->cfg != NULL)
- {
- GNUNET_CONFIGURATION_destroy (d->cfg);
- d->cfg = NULL;
- }
- if (d->cfgfile != NULL)
- {
- GNUNET_free (d->cfgfile);
- d->cfgfile = NULL;
- }
- GNUNET_free_non_null (d->hello);
- GNUNET_free_non_null (d->hostname);
- GNUNET_free_non_null (d->username);
- GNUNET_free_non_null (d->shortname);
- GNUNET_free_non_null (d->proc);
- d->proc = NULL;
- GNUNET_free (d);
- return;
- }
- /* wait some more */
- d->task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm,
- d);
- return;
- }
- if ((type != GNUNET_OS_PROCESS_EXITED) || (code != 0))
- {
- if (NULL != d->dead_cb)
- d->dead_cb (d->dead_cb_cls,
- _
- ("shutdown (either `gnunet-arm' or `ssh') did not complete cleanly.\n"));
- if (d->th != NULL)
- {
- GNUNET_TRANSPORT_get_hello_cancel (d->ghh);
- d->ghh = NULL;
- GNUNET_TRANSPORT_disconnect (d->th);
- d->th = NULL;
- }
- if (d->server != NULL)
- {
- GNUNET_CORE_disconnect (d->server);
- d->server = NULL;
- }
- GNUNET_CONFIGURATION_destroy (d->cfg);
- d->cfg = NULL;
- GNUNET_free (d->cfgfile);
- GNUNET_free_non_null (d->hello);
- GNUNET_free_non_null (d->hostname);
- GNUNET_free_non_null (d->username);
- GNUNET_free_non_null (d->shortname);
- GNUNET_free_non_null (d->proc);
- d->proc = NULL;
- GNUNET_free (d);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer shutdown complete.\n");
- if (d->server != NULL)
- {
- GNUNET_CORE_disconnect (d->server);
- d->server = NULL;
- }
-
- if (d->th != NULL)
- {
- GNUNET_TRANSPORT_get_hello_cancel (d->ghh);
- d->ghh = NULL;
- GNUNET_TRANSPORT_disconnect (d->th);
- d->th = NULL;
- }
-
- if (NULL != d->dead_cb)
- d->dead_cb (d->dead_cb_cls, NULL);
-
- /* state clean up and notifications */
- if (d->churn == GNUNET_NO)
- {
- GNUNET_CONFIGURATION_destroy (d->cfg);
- d->cfg = NULL;
- GNUNET_free (d->cfgfile);
- GNUNET_free_non_null (d->hostname);
- GNUNET_free_non_null (d->username);
- }
-
- GNUNET_free_non_null (d->hello);
- d->hello = NULL;
- GNUNET_free_non_null (d->shortname);
- GNUNET_free_non_null (d->proc);
- d->proc = NULL;
- d->shortname = NULL;
- if (d->churn == GNUNET_NO)
- GNUNET_free (d);
-
- break;
- case SP_CONFIG_UPDATE:
- /* confirm copying complete */
- if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code))
- {
- if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0) /* FIXME: config update should take timeout parameter! */
- {
- cb = d->cb;
- d->cb = NULL;
- if (NULL != cb)
- cb (d->cb_cls, NULL, d->cfg, d,
- _("`scp' does not seem to terminate.\n"));
- return;
- }
- /* wait some more */
- d->task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm,
- d);
- return;
- }
- if ((type != GNUNET_OS_PROCESS_EXITED) || (code != 0))
- {
- if (NULL != d->update_cb)
- d->update_cb (d->update_cb_cls, _("`scp' did not complete cleanly.\n"));
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Successfully copied configuration file.\n");
- if (NULL != d->update_cb)
- d->update_cb (d->update_cb_cls, NULL);
- d->phase = SP_START_DONE;
- break;
- }
-}
-
-/**
- * Continues GNUnet daemon startup when user wanted to be notified
- * once a hostkey was generated (for creating friends files, blacklists,
- * etc.).
- *
- * @param daemon the daemon to finish starting
- */
-void
-GNUNET_TESTING_daemon_continue_startup (struct GNUNET_TESTING_Daemon *daemon)
-{
- GNUNET_assert (daemon->phase == SP_HOSTKEY_CREATED);
- daemon->phase = SP_TOPOLOGY_SETUP;
-}
-
-/**
- * Check whether the given daemon is running.
- *
- * @param daemon the daemon to check
- *
- * @return GNUNET_YES if the daemon is up, GNUNET_NO if the
- * daemon is down, GNUNET_SYSERR on error.
- */
-int
-GNUNET_TESTING_test_daemon_running (struct GNUNET_TESTING_Daemon *daemon)
-{
- if (daemon == NULL)
- return GNUNET_SYSERR;
-
- if (daemon->running == GNUNET_YES)
- return GNUNET_YES;
- return GNUNET_NO;
-}
-
-
-/**
- * Starts a GNUnet daemon service which has been previously stopped.
- *
- * @param d the daemon for which the service should be started
- * @param service the name of the service to start
- * @param timeout how long to wait for process for shutdown to complete
- * @param cb function called once the service starts
- * @param cb_cls closure for cb
- */
-void
-GNUNET_TESTING_daemon_start_stopped_service (struct GNUNET_TESTING_Daemon *d,
- char *service,
- struct GNUNET_TIME_Relative
- timeout,
- GNUNET_TESTING_NotifyDaemonRunning
- cb, void *cb_cls)
-{
- char *arg;
-
- d->cb = cb;
- d->cb_cls = cb_cls;
-
- GNUNET_assert (d->running == GNUNET_YES);
-
- if (d->phase == SP_CONFIG_UPDATE)
- {
- GNUNET_SCHEDULER_cancel (d->task);
- d->phase = SP_START_DONE;
- }
-
- if (d->churned_services == NULL)
- {
- d->cb (d->cb_cls, &d->id, d->cfg, d,
- "No service has been churned off yet!!");
- return;
- }
- d->phase = SP_SERVICE_START;
- GNUNET_free (d->churned_services);
- d->churned_services = NULL;
- d->max_timeout = GNUNET_TIME_relative_to_absolute (timeout);
- /* Check if this is a local or remote process */
- if (NULL != d->hostname)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Starting gnunet-arm with config `%s' on host `%s'.\n",
- d->cfgfile, d->hostname);
- if (d->username != NULL)
- GNUNET_asprintf (&arg, "%s@%s", d->username, d->hostname);
- else
- arg = GNUNET_strdup (d->hostname);
-
- d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh",
-#if !DEBUG_TESTING
- "-q",
-#endif
- arg, "gnunet-arm",
-#if DEBUG_TESTING
- "-L", "DEBUG",
-#endif
- "-c", d->cfgfile, "-i", service, "-q",
- "-T",
- GNUNET_TIME_relative_to_string (timeout),
- NULL);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Starting gnunet-arm with command ssh %s gnunet-arm -c %s -i %s -q\n",
- arg, "gnunet-arm", d->cfgfile, service);
- GNUNET_free (arg);
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Starting gnunet-arm with config `%s' locally.\n", d->cfgfile);
- d->proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm",
-#if DEBUG_TESTING
- "-L", "DEBUG",
-#endif
- "-c", d->cfgfile, "-i", service, "-q",
- "-T",
- GNUNET_TIME_relative_to_string (timeout),
- NULL);
- }
-
- d->max_timeout = GNUNET_TIME_relative_to_absolute (timeout);
- d->task = GNUNET_SCHEDULER_add_now (&start_fsm, d);
-}
-
-/**
- * Starts a GNUnet daemon's service.
- *
- * @param d the daemon for which the service should be started
- * @param service the name of the service to start
- * @param timeout how long to wait for process for startup
- * @param cb function called once gnunet-arm returns
- * @param cb_cls closure for cb
- */
-void
-GNUNET_TESTING_daemon_start_service (struct GNUNET_TESTING_Daemon *d,
- const char *service,
- struct GNUNET_TIME_Relative timeout,
- GNUNET_TESTING_NotifyDaemonRunning cb,
- void *cb_cls)
-{
- char *arg;
-
- d->cb = cb;
- d->cb_cls = cb_cls;
-
- GNUNET_assert (service != NULL);
- GNUNET_assert (d->running == GNUNET_YES);
- GNUNET_assert (d->phase == SP_START_DONE);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- _("Starting service %s for peer `%4s'\n"), service,
- GNUNET_i2s (&d->id));
- d->phase = SP_SERVICE_START;
- d->max_timeout = GNUNET_TIME_relative_to_absolute (timeout);
- /* Check if this is a local or remote process */
- if (NULL != d->hostname)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Starting gnunet-arm with config `%s' on host `%s'.\n",
- d->cfgfile, d->hostname);
- if (d->username != NULL)
- GNUNET_asprintf (&arg, "%s@%s", d->username, d->hostname);
- else
- arg = GNUNET_strdup (d->hostname);
-
- d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh",
-#if !DEBUG_TESTING
- "-q",
-#endif
- arg, "gnunet-arm",
-#if DEBUG_TESTING
- "-L", "DEBUG",
-#endif
- "-c", d->cfgfile, "-i", service, "-q",
- "-T",
- GNUNET_TIME_relative_to_string (timeout),
- NULL);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Starting gnunet-arm with command ssh %s gnunet-arm -c %s -i %s -q -T %s\n",
- arg, "gnunet-arm", d->cfgfile, service,
- GNUNET_TIME_relative_to_string (timeout));
- GNUNET_free (arg);
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Starting gnunet-arm with config `%s' locally.\n", d->cfgfile);
- d->proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm",
-#if DEBUG_TESTING
- "-L", "DEBUG",
-#endif
- "-c", d->cfgfile, "-i", service, "-q",
- "-T",
- GNUNET_TIME_relative_to_string (timeout),
- NULL);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Starting gnunet-arm with command %s -c %s -i %s -q -T %s\n",
- "gnunet-arm", d->cfgfile, service,
- GNUNET_TIME_relative_to_string (timeout));
- }
-
- d->max_timeout = GNUNET_TIME_relative_to_absolute (timeout);
- d->task = GNUNET_SCHEDULER_add_now (&start_fsm, d);
-}
-
-/**
- * Start a peer that has previously been stopped using the daemon_stop
- * call (and files weren't deleted and the allow restart flag)
- *
- * @param daemon the daemon to start (has been previously stopped)
- * @param timeout how long to wait for restart
- * @param cb the callback for notification when the peer is running
- * @param cb_cls closure for the callback
- */
-void
-GNUNET_TESTING_daemon_start_stopped (struct GNUNET_TESTING_Daemon *daemon,
- struct GNUNET_TIME_Relative timeout,
- GNUNET_TESTING_NotifyDaemonRunning cb,
- void *cb_cls)
-{
- if (daemon->running == GNUNET_YES)
- {
- cb (cb_cls, &daemon->id, daemon->cfg, daemon,
- "Daemon already running, can't restart!");
- return;
- }
-
- daemon->cb = cb;
- daemon->cb_cls = cb_cls;
- daemon->phase = SP_TOPOLOGY_SETUP;
- daemon->max_timeout = GNUNET_TIME_relative_to_absolute (timeout);
- /* FIXME: why add_continuation? */
- GNUNET_SCHEDULER_add_continuation (&start_fsm, daemon,
- GNUNET_SCHEDULER_REASON_PREREQ_DONE);
-}
-
-/**
- * Starts a GNUnet daemon. GNUnet must be installed on the target
- * system and available in the PATH. The machine must furthermore be
- * reachable via "ssh" (unless the hostname is "NULL") without the
- * need to enter a password.
- *
- * @param cfg configuration to use
- * @param timeout how long to wait starting up peers
- * @param pretend GNUNET_YES to set up files but not start peer GNUNET_NO
- * to really start the peer (default)
- * @param hostname name of the machine where to run GNUnet
- * (use NULL for localhost).
- * @param ssh_username ssh username to use when connecting to hostname
- * @param sshport port to pass to ssh process when connecting to hostname
- * @param hostkey pointer to a hostkey to be written to disk (instead of being generated)
- * @param hostkey_callback function to call once the hostkey has been
- * generated for this peer, but it hasn't yet been started
- * (NULL to start immediately, otherwise waits on GNUNET_TESTING_daemon_continue_start)
- * @param hostkey_cls closure for hostkey callback
- * @param cb function to call once peer is up, or failed to start
- * @param cb_cls closure for cb
- * @return handle to the daemon (actual start will be completed asynchronously)
- */
-struct GNUNET_TESTING_Daemon *
-GNUNET_TESTING_daemon_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
- struct GNUNET_TIME_Relative timeout, int pretend,
- const char *hostname, const char *ssh_username,
- uint16_t sshport, const char *hostkey,
- GNUNET_TESTING_NotifyHostkeyCreated
- hostkey_callback, void *hostkey_cls,
- GNUNET_TESTING_NotifyDaemonRunning cb,
- void *cb_cls)
-{
- struct GNUNET_TESTING_Daemon *ret;
- char *arg;
- char *username;
- char *servicehome;
- char *baseservicehome;
- char *slash;
- char *hostkeyfile;
- char *temp_file_name;
- struct GNUNET_DISK_FileHandle *fn;
- struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key;
- struct GNUNET_CRYPTO_RsaPrivateKey *private_key;
-
- ret = GNUNET_malloc (sizeof (struct GNUNET_TESTING_Daemon));
- ret->hostname = (hostname == NULL) ? NULL : GNUNET_strdup (hostname);
- if (sshport != 0)
- {
- GNUNET_asprintf (&ret->ssh_port_str, "%d", sshport);
- }
- else
- ret->ssh_port_str = NULL;
-
- /* Find service home and base service home directories, create it if it doesn't exist */
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS",
- "SERVICEHOME",
- &servicehome));
-
- GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_create (servicehome));
- GNUNET_asprintf (&temp_file_name, "%s/gnunet-testing-config", servicehome);
- ret->cfgfile = GNUNET_DISK_mktemp (temp_file_name);
- GNUNET_free (temp_file_name);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Setting up peer with configuration file `%s'.\n", ret->cfgfile);
- if (NULL == ret->cfgfile)
- {
- GNUNET_free_non_null (ret->ssh_port_str);
- GNUNET_free_non_null (ret->hostname);
- GNUNET_free (ret);
- return NULL;
- }
- ret->hostkey_callback = hostkey_callback;
- ret->hostkey_cls = hostkey_cls;
- ret->cb = cb;
- ret->cb_cls = cb_cls;
- ret->max_timeout = GNUNET_TIME_relative_to_absolute (timeout);
- ret->cfg = GNUNET_CONFIGURATION_dup (cfg);
- GNUNET_CONFIGURATION_set_value_string (ret->cfg, "PATHS", "DEFAULTCONFIG",
- ret->cfgfile);
-
- if (hostkey != NULL) /* Get the peer identity from the hostkey */
- {
- private_key = GNUNET_CRYPTO_rsa_decode_key (hostkey, HOSTKEYFILESIZE);
- GNUNET_assert (private_key != NULL);
- GNUNET_CRYPTO_rsa_key_get_public (private_key, &public_key);
- GNUNET_CRYPTO_hash (&public_key,
- sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
- &ret->id.hashPubKey);
- ret->shortname = GNUNET_strdup (GNUNET_i2s (&ret->id));
- ret->have_hostkey = GNUNET_YES;
- GNUNET_CRYPTO_rsa_key_free (private_key);
- }
-
- /* Write hostkey to file, if we were given one */
- hostkeyfile = NULL;
- if (hostkey != NULL)
- {
- GNUNET_asprintf (&hostkeyfile, "%s/.hostkey", servicehome);
- fn = GNUNET_DISK_file_open (hostkeyfile,
- GNUNET_DISK_OPEN_READWRITE |
- GNUNET_DISK_OPEN_CREATE,
- GNUNET_DISK_PERM_USER_READ |
- GNUNET_DISK_PERM_USER_WRITE);
- GNUNET_assert (fn != NULL);
- GNUNET_assert (HOSTKEYFILESIZE ==
- GNUNET_DISK_file_write (fn, hostkey, HOSTKEYFILESIZE));
- GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fn));
- }
-
- /* write configuration to temporary file */
- if (GNUNET_OK != GNUNET_CONFIGURATION_write (ret->cfg, ret->cfgfile))
- {
- if (0 != UNLINK (ret->cfgfile))
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink",
- ret->cfgfile);
- GNUNET_CONFIGURATION_destroy (ret->cfg);
- GNUNET_free_non_null (ret->hostname);
- GNUNET_free (ret->cfgfile);
- GNUNET_free (ret);
- return NULL;
- }
- if (ssh_username != NULL)
- username = GNUNET_strdup (ssh_username);
- if ((ssh_username == NULL) &&
- (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg, "TESTING", "USERNAME",
- &username)))
- {
- if (NULL != getenv ("USER"))
- username = GNUNET_strdup (getenv ("USER"));
- else
- username = NULL;
- }
- ret->username = username;
-
- if (GNUNET_NO == pretend) /* Copy files, enter finite state machine */
- {
- /* copy directory to remote host */
- if (NULL != hostname)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Copying configuration directory to host `%s'.\n", hostname);
- baseservicehome = GNUNET_strdup (servicehome);
- /* Remove trailing /'s */
- while (baseservicehome[strlen (baseservicehome) - 1] == '/')
- baseservicehome[strlen (baseservicehome) - 1] = '\0';
- /* Find next directory /, jump one ahead */
- slash = strrchr (baseservicehome, '/');
- if (slash != NULL)
- *(++slash) = '\0';
-
- ret->phase = SP_COPYING;
- if (NULL != username)
- GNUNET_asprintf (&arg, "%s@%s:%s", username, hostname, baseservicehome);
- else
- GNUNET_asprintf (&arg, "%s:%s", hostname, baseservicehome);
- GNUNET_free (baseservicehome);
- if (ret->ssh_port_str == NULL)
- {
- ret->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "scp", "scp", "-r",
-#if !DEBUG_TESTING
- "-q",
-#endif
- servicehome, arg, NULL);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "copying directory with command scp -r %s %s\n",
- servicehome, arg);
- }
- else
- {
- ret->proc =
- GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "scp", "scp", "-r", "-P",
- ret->ssh_port_str,
-#if !DEBUG_TESTING
- "-q",
-#endif
- servicehome, arg, NULL);
- }
- GNUNET_free (arg);
- if (NULL == ret->proc)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _
- ("Could not start `%s' process to copy configuration directory.\n"),
- "scp");
- if (0 != UNLINK (ret->cfgfile))
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink",
- ret->cfgfile);
- GNUNET_CONFIGURATION_destroy (ret->cfg);
- GNUNET_free_non_null (ret->hostname);
- GNUNET_free_non_null (ret->username);
- GNUNET_free (ret->cfgfile);
- GNUNET_free (ret);
- if ((hostkey != NULL) && (0 != UNLINK (hostkeyfile)))
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink",
- hostkeyfile);
- GNUNET_free_non_null (hostkeyfile);
- GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (servicehome));
- GNUNET_free (servicehome);
- return NULL;
- }
-
- ret->task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm,
- ret);
- GNUNET_free_non_null (hostkeyfile);
- GNUNET_free (servicehome);
- return ret;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "No need to copy configuration file since we are running locally.\n");
- ret->phase = SP_COPIED;
- /* FIXME: why add_cont? */
- GNUNET_SCHEDULER_add_continuation (&start_fsm, ret,
- GNUNET_SCHEDULER_REASON_PREREQ_DONE);
- }
- GNUNET_free_non_null (hostkeyfile);
- GNUNET_free (servicehome);
- return ret;
-}
-
-
-/**
- * Restart (stop and start) a GNUnet daemon.
- *
- * @param d the daemon that should be restarted
- * @param cb function called once the daemon is (re)started
- * @param cb_cls closure for cb
- */
-void
-GNUNET_TESTING_daemon_restart (struct GNUNET_TESTING_Daemon *d,
- GNUNET_TESTING_NotifyDaemonRunning cb,
- void *cb_cls)
-{
- char *arg;
- char *del_arg;
-
- del_arg = NULL;
- if (NULL != d->cb)
- {
- d->dead = GNUNET_YES;
- return;
- }
-
- d->cb = cb;
- d->cb_cls = cb_cls;
-
- if (d->phase == SP_CONFIG_UPDATE)
- {
- GNUNET_SCHEDULER_cancel (d->task);
- d->phase = SP_START_DONE;
- }
- if (d->server != NULL)
- {
- GNUNET_CORE_disconnect (d->server);
- d->server = NULL;
- }
-
- if (d->th != NULL)
- {
- GNUNET_TRANSPORT_get_hello_cancel (d->ghh);
- d->ghh = NULL;
- GNUNET_TRANSPORT_disconnect (d->th);
- d->th = NULL;
- }
- /* state clean up and notifications */
- GNUNET_free_non_null (d->hello);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Terminating peer `%4s'\n"),
- GNUNET_i2s (&d->id));
- d->phase = SP_START_ARMING;
-
- /* Check if this is a local or remote process */
- if (NULL != d->hostname)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Stopping gnunet-arm with config `%s' on host `%s'.\n",
- d->cfgfile, d->hostname);
- if (d->username != NULL)
- GNUNET_asprintf (&arg, "%s@%s", d->username, d->hostname);
- else
- arg = GNUNET_strdup (d->hostname);
-
- d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh",
-#if !DEBUG_TESTING
- "-q",
-#endif
- arg, "gnunet-arm",
-#if DEBUG_TESTING
- "-L", "DEBUG",
-#endif
- "-c", d->cfgfile, "-e", "-r", NULL);
- /* Use -r to restart arm and all services */
-
- GNUNET_free (arg);
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Stopping gnunet-arm with config `%s' locally.\n", d->cfgfile);
- d->proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm",
-#if DEBUG_TESTING
- "-L", "DEBUG",
-#endif
- "-c", d->cfgfile, "-e", "-r", NULL);
- }
-
- GNUNET_free_non_null (del_arg);
- d->task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm, d);
-
-}
-
-
-/**
- * Stops a GNUnet daemon.
- *
- * @param d the daemon that should be stopped
- * @param service the name of the service to stop
- * @param timeout how long to wait for process for shutdown to complete
- * @param cb function called once the daemon was stopped
- * @param cb_cls closure for cb
- */
-void
-GNUNET_TESTING_daemon_stop_service (struct GNUNET_TESTING_Daemon *d,
- const char *service,
- struct GNUNET_TIME_Relative timeout,
- GNUNET_TESTING_NotifyCompletion cb,
- void *cb_cls)
-{
- char *arg;
-
- d->dead_cb = cb;
- d->dead_cb_cls = cb_cls;
-
- GNUNET_assert (d->running == GNUNET_YES);
-
- if (d->phase == SP_CONFIG_UPDATE)
- {
- GNUNET_SCHEDULER_cancel (d->task);
- d->phase = SP_START_DONE;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Terminating peer `%4s'\n"),
- GNUNET_i2s (&d->id));
- if (d->churned_services != NULL)
- {
- d->dead_cb (d->dead_cb_cls, "A service has already been turned off!!");
- return;
- }
- d->phase = SP_SERVICE_SHUTDOWN_START;
- d->churned_services = GNUNET_strdup (service);
- d->max_timeout = GNUNET_TIME_relative_to_absolute (timeout);
- /* Check if this is a local or remote process */
- if (NULL != d->hostname)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Stopping gnunet-arm with config `%s' on host `%s'.\n",
- d->cfgfile, d->hostname);
- if (d->username != NULL)
- GNUNET_asprintf (&arg, "%s@%s", d->username, d->hostname);
- else
- arg = GNUNET_strdup (d->hostname);
-
- d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh",
-#if !DEBUG_TESTING
- "-q",
-#endif
- arg, "gnunet-arm",
-#if DEBUG_TESTING
- "-L", "DEBUG",
-#endif
- "-c", d->cfgfile, "-k", service, "-q",
- "-T",
- GNUNET_TIME_relative_to_string (timeout),
- NULL);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Stopping gnunet-arm with command ssh %s gnunet-arm -c %s -k %s -q\n",
- arg, "gnunet-arm", d->cfgfile, service);
- GNUNET_free (arg);
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Stopping gnunet-arm with config `%s' locally.\n", d->cfgfile);
- d->proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm",
-#if DEBUG_TESTING
- "-L", "DEBUG",
-#endif
- "-c", d->cfgfile, "-k", service, "-q",
- "-T",
- GNUNET_TIME_relative_to_string (timeout),
- NULL);
- }
-
- d->max_timeout = GNUNET_TIME_relative_to_absolute (timeout);
- d->task = GNUNET_SCHEDULER_add_now (&start_fsm, d);
-}
-
-
-/**
- * Stops a GNUnet daemon.
- *
- * @param d the daemon that should be stopped
- * @param timeout how long to wait for process for shutdown to complete
- * @param cb function called once the daemon was stopped
- * @param cb_cls closure for cb
- * @param delete_files GNUNET_YES to remove files, GNUNET_NO
- * to leave them
- * @param allow_restart GNUNET_YES to restart peer later (using this API)
- * GNUNET_NO to kill off and clean up for good
- */
-void
-GNUNET_TESTING_daemon_stop (struct GNUNET_TESTING_Daemon *d,
- struct GNUNET_TIME_Relative timeout,
- GNUNET_TESTING_NotifyCompletion cb, void *cb_cls,
- int delete_files, int allow_restart)
-{
- char *arg;
- char *del_arg;
-
- d->dead_cb = cb;
- d->dead_cb_cls = cb_cls;
-
- if (NULL != d->cb)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Setting d->dead on peer `%4s'\n"),
- GNUNET_i2s (&d->id));
- d->dead = GNUNET_YES;
- return;
- }
-
- if ((d->running == GNUNET_NO) && (d->churn == GNUNET_YES)) /* Peer has already been stopped in churn context! */
- {
- /* Free what was left from churning! */
- GNUNET_assert (d->cfg != NULL);
- GNUNET_CONFIGURATION_destroy (d->cfg);
- if (delete_files == GNUNET_YES)
- {
- if (0 != UNLINK (d->cfgfile))
- {
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "unlink");
- }
- }
- GNUNET_free (d->cfgfile);
- GNUNET_free_non_null (d->hostname);
- GNUNET_free_non_null (d->username);
- if (NULL != d->dead_cb)
- d->dead_cb (d->dead_cb_cls, NULL);
- GNUNET_free (d);
- return;
- }
-
- del_arg = NULL;
- if (delete_files == GNUNET_YES)
- {
- GNUNET_asprintf (&del_arg, "-d");
- }
-
- if (d->phase == SP_CONFIG_UPDATE)
- {
- GNUNET_SCHEDULER_cancel (d->task);
- d->phase = SP_START_DONE;
- }
- /** Move this call to scheduled shutdown as fix for CORE_connect calling daemon_stop?
- if (d->server != NULL)
- {
- GNUNET_CORE_disconnect (d->server);
- d->server = NULL;
- }
- */
- /* shutdown ARM process (will terminate others) */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Terminating peer `%4s'\n" ,
- GNUNET_i2s (&d->id));
- d->phase = SP_SHUTDOWN_START;
- d->running = GNUNET_NO;
- if (allow_restart == GNUNET_YES)
- d->churn = GNUNET_YES;
- if (d->th != NULL)
- {
- GNUNET_TRANSPORT_get_hello_cancel (d->ghh);
- d->ghh = NULL;
- GNUNET_TRANSPORT_disconnect (d->th);
- d->th = NULL;
- }
- /* Check if this is a local or remote process */
- if (NULL != d->hostname)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Stopping gnunet-arm with config `%s' on host `%s'.\n",
- d->cfgfile, d->hostname);
- if (d->username != NULL)
- GNUNET_asprintf (&arg, "%s@%s", d->username, d->hostname);
- else
- arg = GNUNET_strdup (d->hostname);
-
- d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh",
-#if !DEBUG_TESTING
- "-q",
-#endif
- arg, "gnunet-arm",
-#if DEBUG_TESTING
- "-L", "DEBUG",
-#endif
- "-c", d->cfgfile, "-e", "-q", "-T",
- GNUNET_TIME_relative_to_string (timeout),
- del_arg, NULL);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Stopping gnunet-arm with command ssh %s gnunet-arm -c %s -e -q %s\n",
- arg, "gnunet-arm", d->cfgfile, del_arg);
- /* Use -e to end arm, and -d to remove temp files */
- GNUNET_free (arg);
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Stopping gnunet-arm with config `%s' locally.\n", d->cfgfile);
- d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "gnunet-arm", "gnunet-arm",
-#if DEBUG_TESTING
- "-L", "DEBUG",
-#endif
- "-c", d->cfgfile, "-e", "-q", "-T",
- GNUNET_TIME_relative_to_string (timeout),
- del_arg, NULL);
- GNUNET_assert (NULL != d->proc);
- }
-
- GNUNET_free_non_null (del_arg);
- d->max_timeout = GNUNET_TIME_relative_to_absolute (timeout);
- if (GNUNET_SCHEDULER_NO_TASK != d->task)
- GNUNET_SCHEDULER_cancel(d->task);
- d->task = GNUNET_SCHEDULER_add_now (&start_fsm, d);
-}
-
-
-/**
- * Changes the configuration of a GNUnet daemon.
- *
- * @param d the daemon that should be modified
- * @param cfg the new configuration for the daemon
- * @param cb function called once the configuration was changed
- * @param cb_cls closure for cb
- */
-void
-GNUNET_TESTING_daemon_reconfigure (struct GNUNET_TESTING_Daemon *d,
- struct GNUNET_CONFIGURATION_Handle *cfg,
- GNUNET_TESTING_NotifyCompletion cb,
- void *cb_cls)
-{
- char *arg;
-
- if (d->phase != SP_START_DONE)
- {
- if (NULL != cb)
- cb (cb_cls,
- _
- ("Peer not yet running, can not change configuration at this point."));
- return;
- }
-
- /* 1) write configuration to temporary file */
- if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, d->cfgfile))
- {
- if (NULL != cb)
- cb (cb_cls, _("Failed to write new configuration to disk."));
- return;
- }
-
- /* 2) copy file to remote host (if necessary) */
- if (NULL == d->hostname)
- {
- /* signal success */
- if (NULL != cb)
- cb (cb_cls, NULL);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Copying updated configuration file to remote host `%s'.\n",
- d->hostname);
- d->phase = SP_CONFIG_UPDATE;
- if (NULL != d->username)
- GNUNET_asprintf (&arg, "%s@%s:%s", d->username, d->hostname, d->cfgfile);
- else
- GNUNET_asprintf (&arg, "%s:%s", d->hostname, d->cfgfile);
- d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "scp", "scp",
-#if !DEBUG_TESTING
- "-q",
-#endif
- d->cfgfile, arg, NULL);
- GNUNET_free (arg);
- if (NULL == d->proc)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("Could not start `%s' process to copy configuration file.\n"),
- "scp");
- if (NULL != cb)
- cb (cb_cls, _("Failed to copy new configuration to remote machine."));
- d->phase = SP_START_DONE;
- return;
- }
- d->update_cb = cb;
- d->update_cb_cls = cb_cls;
- d->task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm, d);
-}
-