#define DEBUG_TESTING GNUNET_NO
#define DEBUG_TESTING_RECONNECT GNUNET_YES
+#define WAIT_FOR_HELLO GNUNET_NO
/**
* How long do we wait after starting gnunet-service-arm
if (daemon == NULL)
return;
- GNUNET_assert (daemon->phase == SP_GET_HELLO);
+ GNUNET_assert (daemon->phase == SP_GET_HELLO || daemon->phase == SP_START_DONE);
cb = daemon->cb;
daemon->cb = NULL;
}
daemon->phase = SP_START_DONE;
+#if WAIT_FOR_HELLO
if (NULL != cb) /* FIXME: what happens when this callback calls GNUNET_TESTING_daemon_stop? */
cb (daemon->cb_cls, &daemon->id, daemon->cfg, daemon, NULL);
+#endif
}
static void
start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+#if WAIT_FOR_HELLO
/**
* Function called after GNUNET_CORE_connect has succeeded
* (or failed for good). Note that the private key of the
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Successfully started peer `%4s'.\n", GNUNET_i2s (my_identity));
#endif
- d->id = *my_identity;
+ d->id = *my_identity; /* FIXME: shouldn't we already have this from reading the hostkey file? */
if (d->shortname == NULL)
d->shortname = strdup (GNUNET_i2s (my_identity));
d->server = server;
= GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT,
&start_fsm, d);
}
+#endif
+#if !WAIT_FOR_HELLO
+/**
+ * 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.
+ *
+ * @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);
+}
+#endif
/**
* Finite-state machine for starting GNUnet.
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_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT,
&start_fsm, d);
break;
- case SP_TOPOLOGY_SETUP:
+ case SP_TOPOLOGY_SETUP: /* Indicates topology setup has completed! */
/* start GNUnet on remote host */
if (NULL == d->hostname)
{
if (d->server != NULL)
GNUNET_CORE_disconnect(d->server);
+#if WAIT_FOR_HELLO
if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value ==
0)
{
d->task
= GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_CONSTANTS_SERVICE_RETRY, 2),
&start_fsm, d);
+#else
+ 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;
+ }
+#if DEBUG_TESTING
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Connected to transport service `%s', getting HELLO\n",
+ GNUNET_i2s (&d->id));
+#endif
+
+ GNUNET_TRANSPORT_get_hello (d->th, &process_hello, d);
+ 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;
+#endif
break;
case SP_GET_HELLO:
if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value ==
*
* @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
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,
}
ret->username = username;
- /* copy directory to remote host */
- if (NULL != hostname)
+ if (GNUNET_NO == pretend) /* Copy files, enter finite state machine */
{
+ /* copy directory to remote host */
+ if (NULL != hostname)
+ {
#if DEBUG_TESTING
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Copying configuration directory to host `%s'.\n", hostname);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Copying configuration directory to host `%s'.\n", hostname);
#endif
- 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);
+ 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);
- if (ret->ssh_port_str == NULL)
- {
- ret->proc = GNUNET_OS_start_process (NULL, NULL, "scp", "scp", "-r",
+ if (ret->ssh_port_str == NULL)
+ {
+ ret->proc = GNUNET_OS_start_process (NULL, NULL, "scp", "scp", "-r",
#if !DEBUG_TESTING
- "-q",
+ "-q",
#endif
- servicehome, arg, NULL);
+ servicehome, arg, NULL);
#if DEBUG_TESTING
- GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "copying directory with command scp -r %s %s\n", servicehome, arg);
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "copying directory with command scp -r %s %s\n", servicehome, arg);
#endif
- }
- else
- {
- ret->proc = GNUNET_OS_start_process (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);
+ }
+ else
+ {
+ ret->proc = GNUNET_OS_start_process (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_assert (GNUNET_OK == GNUNET_DISK_directory_remove (servicehome));
+ GNUNET_free(baseservicehome);
GNUNET_free(servicehome);
- return NULL;
+ return ret;
}
-
- ret->task
- = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT,
- &start_fsm, ret);
- GNUNET_free_non_null(hostkeyfile);
- GNUNET_free(baseservicehome);
- GNUNET_free(servicehome);
- return ret;
- }
#if DEBUG_TESTING
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"No need to copy configuration file since we are running locally.\n");
#endif
- ret->phase = SP_COPIED;
- GNUNET_SCHEDULER_add_continuation (&start_fsm,
- ret,
- GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+ ret->phase = SP_COPIED;
+ GNUNET_SCHEDULER_add_continuation (&start_fsm,
+ ret,
+ GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+ }
GNUNET_free_non_null(hostkeyfile);
GNUNET_free(servicehome);
return ret;
if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
return;
if ((ctx->d1core_ready == GNUNET_YES) && (ctx->d2->hello != NULL)
- && (NULL != GNUNET_HELLO_get_header (ctx->d2->hello)))
+ && (NULL != GNUNET_HELLO_get_header (ctx->d2->hello))
+ && (ctx->d1->phase == SP_START_DONE)
+ && (ctx->d2->phase == SP_START_DONE))
{
hello = GNUNET_HELLO_get_header (ctx->d2->hello);
GNUNET_assert (hello != NULL);
+#if DEBUG_TESTING
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Offering hello of %s to %s\n", ctx->d2->shortname, ctx->d1->shortname);
+#endif
GNUNET_TRANSPORT_offer_hello (ctx->d1th, hello, NULL, NULL);
GNUNET_assert (ctx->d1core != NULL);
ctx->connect_request_handle =
return;
}
+ /* Don't know reason for initial connect failure, update the HELLO for the second peer */
+ if (NULL != ctx->d2->hello)
+ {
+ GNUNET_free(ctx->d2->hello);
+ ctx->d2->hello = NULL;
+ if (NULL != ctx->d2->th)
+ {
+ GNUNET_TRANSPORT_get_hello_cancel(ctx->d2->th, &process_hello, ctx->d2);
+ GNUNET_TRANSPORT_disconnect(ctx->d2->th);
+ }
+ ctx->d2->th = GNUNET_TRANSPORT_connect (ctx->d2->cfg, &ctx->d2->id, NULL, NULL, NULL, NULL);
+ GNUNET_assert(ctx->d2->th != NULL);
+ GNUNET_TRANSPORT_get_hello (ctx->d2->th, &process_hello, ctx->d2);
+ }
+
+ if ((NULL == ctx->d2->hello) && (ctx->d2->th == NULL))
+ {
+ ctx->d2->th = GNUNET_TRANSPORT_connect (ctx->d2->cfg, &ctx->d2->id, NULL, NULL, NULL, NULL);
+ if (ctx->d2->th == NULL)
+ {
+ GNUNET_CORE_disconnect (ctx->d1core);
+ GNUNET_free (ctx);
+ if (NULL != ctx->cb)
+ ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, 0, ctx->d1->cfg, ctx->d2->cfg, ctx->d1, ctx->d2,
+ _("Failed to connect to transport service!\n"));
+ return;
+ }
+ GNUNET_TRANSPORT_get_hello (ctx->d2->th, &process_hello, ctx->d2);
+ }
+
if (ctx->send_hello == GNUNET_YES)
{
ctx->d1th = GNUNET_TRANSPORT_connect (ctx->d1->cfg,
return;
}
+ if ((NULL == ctx->d2->hello) && (ctx->d2->th == NULL)) /* Do not yet have the second peer's hello, set up a task to get it */
+ {
+ ctx->d2->th = GNUNET_TRANSPORT_connect (ctx->d2->cfg, &ctx->d2->id, NULL, NULL, NULL, NULL);
+ if (ctx->d2->th == NULL)
+ {
+ GNUNET_CORE_disconnect (ctx->d1core);
+ GNUNET_free (ctx);
+ if (NULL != ctx->cb)
+ ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, 0, ctx->d1->cfg, ctx->d2->cfg, ctx->d1, ctx->d2,
+ _("Failed to connect to transport service!\n"));
+ return;
+ }
+ GNUNET_TRANSPORT_get_hello (ctx->d2->th, &process_hello, ctx->d2);
+ }
+
if (ctx->send_hello == GNUNET_YES)
{
ctx->d1th = GNUNET_TRANSPORT_connect (ctx->d1->cfg,
if (NULL != cb)
cb (cb_cls, &d1->id, &d2->id, 0, d1->cfg, d2->cfg, d1, d2,
_("Peers are not fully running yet, can not connect!\n"));
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Peers are not up!\n");
return;
}