*/
struct GNUNET_TESTBED_Operation *sub_op;
+ /**
+ * The client which initiated the link controller operation
+ */
+ struct GNUNET_SERVER_Client *client;
+
+ /**
+ * A copy of the original overlay connect message
+ */
+ struct GNUNET_MessageHeader *orig_msg;
+
+ /**
+ * The host registration handle while registered hosts in this context
+ */
+ struct GNUNET_TESTBED_HostRegistrationHandle *rhandle;
+
+ /**
+ * The id of the operation which created this context information
+ */
+ uint64_t operation_id;
+
/**
* Enumeration of states for this context
*/
*/
FOCC_INIT = 0,
+ /**
+ * State where we attempt to register peer2's controller with peer1's controller
+ */
+ FOCC_REGISTER,
+
/**
* State where we attempt to get peer2's controller configuration
*/
*/
static char *hostname;
+
/***********/
/* Handles */
/***********/
+/**
+ * Our configuration
+ */
+static struct GNUNET_CONFIGURATION_Handle *our_config;
+
/**
* Current Transmit Handle; NULL if no notify transmit exists currently
*/
static struct MessageQueue *mq_tail;
/**
- * Array of host list
+ * Array of hosts
*/
static struct GNUNET_TESTBED_Host **host_list;
}
+/**
+ * Callback to be called when forwarded overlay connection operation has a reply
+ * from the sub-controller successfull. We have to relay the reply msg back to
+ * the client
+ *
+ * @param cls ForwardedOperationContext
+ * @param msg the peer create success message
+ */
+static void
+forwarded_overlay_connect_listener (void *cls,
+ const struct GNUNET_MessageHeader *msg);
+
+
+/**
+ * Cleans up ForwardedOverlayConnectContext
+ *
+ * @param focc the ForwardedOverlayConnectContext to cleanup
+ */
+static void
+cleanup_focc (struct ForwardedOverlayConnectContext *focc)
+{
+ if (NULL != focc->sub_op)
+ GNUNET_TESTBED_operation_done (focc->sub_op);
+ if (NULL != focc->client)
+ GNUNET_SERVER_client_drop (focc->client);
+ GNUNET_free_non_null (focc->orig_msg);
+ GNUNET_free (focc);
+}
+
/**
* Callback for event from slave controllers
*
const struct GNUNET_TESTBED_EventInformation *event)
{
struct ForwardedOverlayConnectContext *focc;
+ struct ForwardedOperationContext *fopc;
struct GNUNET_CONFIGURATION_Handle *slave_cfg;
+ struct GNUNET_TESTBED_Operation *old_op;
+ char *emsg;
/* We currently only get here when doing overlay connect operations and that
too while trying out sub operations */
- if (GNUNET_TESTBED_ET_OPERATION_FINISHED != event->type)
- return;
+ GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
focc = event->details.operation_finished.op_cls;
+ LOG_DEBUG ("Operation successful\n");
+ if (NULL != event->details.operation_finished.emsg)
+ {
+ GNUNET_asprintf (&emsg, "Failure executing suboperation: %s",
+ event->details.operation_finished.emsg);
+ send_operation_fail_msg (focc->client, focc->operation_id,
+ emsg);
+ GNUNET_free (emsg);
+ cleanup_focc (focc);
+ return;
+ }
switch (focc->state)
{
case FOCC_GET_CFG:
slave_cfg = event->details.operation_finished.generic;
- GNUNET_break (0); /* FIXME */
- GNUNET_CONFIGURATION_destroy (slave_cfg);
- default:
+ old_op = focc->sub_op;
+ focc->state = FOCC_LINK;
+ focc->sub_op = GNUNET_TESTBED_controller_link_ (focc,
+ focc->gateway,
+ focc->peer2_host_id,
+ peer_list[focc->peer1]->details.remote.remote_host_id,
+ slave_cfg,
+ GNUNET_NO);
+ GNUNET_TESTBED_operation_done (old_op);
+ break;
+ case FOCC_LINK:
+ LOG_DEBUG ("OL: Linking controllers successfull\n");
+ GNUNET_TESTBED_operation_done (focc->sub_op);
+ focc->sub_op = NULL;
+ focc->state = FOCC_OL_CONNECT;
+ fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
+ fopc->client = focc->client;
+ focc->client = NULL;
+ fopc->operation_id = focc->operation_id;
+ fopc->cls = NULL;
+ fopc->opc =
+ GNUNET_TESTBED_forward_operation_msg_ (focc->gateway,
+ focc->operation_id, focc->orig_msg,
+ &forwarded_operation_reply_relay,
+ fopc);
+ GNUNET_free (focc->orig_msg);
+ focc->orig_msg = NULL;
+ fopc->timeout_task =
+ GNUNET_SCHEDULER_add_delayed (TIMEOUT, &forwarded_operation_timeout,
+ fopc);
+ cleanup_focc (focc);
+ break;
+ default:
GNUNET_assert (0);
}
+ return;
}
master_context->system =
GNUNET_TESTING_system_create ("testbed", master_context->master_ip, hostname);
host =
- GNUNET_TESTBED_host_create_with_id (master_context->host_id, NULL, NULL,
+ GNUNET_TESTBED_host_create_with_id (master_context->host_id,
+ master_context->master_ip,
+ NULL,
0);
host_list_add (host);
GNUNET_SERVER_client_keep (client);
msg = (const struct GNUNET_TESTBED_AddHostMessage *) message;
msize = ntohs (msg->header.size);
- username = (char *) &(msg[1]);
+ username = (char *) &msg[1];
username_length = ntohs (msg->user_name_length);
- GNUNET_assert (msize > (sizeof (struct GNUNET_TESTBED_AddHostMessage) + username_length + 1)); /* msg must contain hostname */
if (0 != username_length)
- GNUNET_assert ('\0' == username[username_length]);
- username_length = (0 == username_length) ? 0 : username_length + 1;
+ username_length++;
+ /* msg must contain hostname */
+ GNUNET_assert (msize > (sizeof (struct GNUNET_TESTBED_AddHostMessage) +
+ username_length + 1));
+ if (0 != username_length)
+ GNUNET_assert ('\0' == username[username_length - 1]);
hostname = username + username_length;
hostname_length =
msize - (sizeof (struct GNUNET_TESTBED_AddHostMessage) + username_length);
slave_host_id = ntohl (msg->slave_host_id);
if ((slave_host_id >= host_list_size) || (NULL == host_list[slave_host_id]))
{
- LOG (GNUNET_ERROR_TYPE_WARNING, "Slave host not registered with us\n");
+ LOG (GNUNET_ERROR_TYPE_WARNING, "Slave host %u not registered with us\n",
+ slave_host_id);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
{
LOG (GNUNET_ERROR_TYPE_WARNING, "Host %u already connected\n",
delegated_host_id);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
}
config = GNUNET_malloc (config_size);
}
+/**
+ * This callback is a part of overlay connect operation. This will be run when
+ * the registration operation of peer2's controller is completed at peer1's
+ * controller
+ *
+ * @param cls the ForwardedOverlayConnectContext
+ * @param emsg the error message in case of any failure; NULL if host
+ * registration is successfull.
+ */
+static void
+focc_reg_completion_cc (void *cls, const char *emsg)
+{
+ struct ForwardedOverlayConnectContext *focc = cls;
+ struct GNUNET_CONFIGURATION_Handle *cfg;
+
+ GNUNET_assert (FOCC_REGISTER == focc->state);
+ focc->rhandle = NULL;
+ GNUNET_assert (NULL == focc->sub_op);
+ LOG_DEBUG ("Registering peer2's host successful\n");
+ if ((NULL == focc->gateway2)
+ || ((focc->peer2_host_id < slave_list_size) /* Check if we have the needed config */
+ && (NULL != slave_list[focc->peer2_host_id])))
+ {
+ focc->state = FOCC_LINK;
+ cfg = (NULL == focc->gateway2) ?
+ our_config : slave_list[focc->peer2_host_id]->cfg;
+ focc->sub_op =
+ GNUNET_TESTBED_controller_link_ (focc,
+ focc->gateway,
+ focc->peer2_host_id,
+ peer_list[focc->peer1]->details.remote.remote_host_id,
+ cfg,
+ GNUNET_NO);
+ return;
+ }
+ focc->state = FOCC_GET_CFG;
+ focc->sub_op = GNUNET_TESTBED_get_slave_config_ (focc, focc->gateway2,
+ focc->peer2_host_id);
+}
+
+
/**
* Callback to be called when forwarded overlay connection operation has a reply
* from the sub-controller successfull. We have to relay the reply msg back to
case FOCC_INIT:
if (GNUNET_MESSAGE_TYPE_TESTBED_NEEDCONTROLLERCONFIG != ntohs (msg->type))
{
- GNUNET_break (0); /* Something failed; you may check output of sub-controllers */
+ GNUNET_break (0); /* Something failed; you may check output of
+ sub-controllers */
+ cleanup_focc (focc);
forwarded_operation_reply_relay (cls, msg);
return;
}
- GNUNET_assert (NULL == focc->sub_op);
- focc->state = FOCC_GET_CFG;
- focc->sub_op = GNUNET_TESTBED_get_slave_config_ (focc, focc->gateway2,
- focc->peer2_host_id);
- /* FIXME */
- GNUNET_break (0);
+ LOG_DEBUG ("Registering peer2's host\n");
+ focc->state = FOCC_REGISTER;
+ focc->rhandle =
+ GNUNET_TESTBED_register_host (focc->gateway,
+ host_list[focc->peer2_host_id],
+ focc_reg_completion_cc, focc);
break;
- /* focc->op = GNUNET_TESTBED_controller_link (focc, */
- /* focc->gateway, */
- /* slave_list[peer2_host_id], */
- /* slave_list[peer_list[focc->peer1]->remote_host_id], */
- /* slave_list */
-
default:
GNUNET_assert (0);
}
+ GNUNET_SERVER_client_drop (fopc->client);
+ GNUNET_SCHEDULER_cancel (fopc->timeout_task);
+ fopc->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+ GNUNET_free (fopc);
}
uint32_t p2;
uint32_t peer2_host_id;
-
msg = (const struct GNUNET_TESTBED_OverlayConnectMessage *) message;
p1 = ntohl (msg->peer1);
p2 = ntohl (msg->peer2);
route_to_peer2_host = NULL;
route_to_peer1_host = NULL;
route_to_peer2_host = find_dest_route (peer2_host_id);
- if (NULL != route_to_peer2_host)
+ if ((NULL != route_to_peer2_host)
+ || (peer2_host_id == master_context->host_id))
{
route_to_peer1_host =
find_dest_route (peer_list[p1]->details.remote.remote_host_id);
GNUNET_assert (NULL != route_to_peer1_host);
- if (route_to_peer2_host->dest != route_to_peer1_host->dest)
+ if ((peer2_host_id == master_context->host_id)
+ || (route_to_peer2_host->dest != route_to_peer1_host->dest))
{
struct ForwardedOverlayConnectContext *focc;
-
+ uint16_t msize;
+
+ msize = sizeof (struct GNUNET_TESTBED_OverlayConnectMessage);
focc = GNUNET_malloc (sizeof (struct ForwardedOverlayConnectContext));
focc->gateway = peer->details.remote.controller;
- focc->gateway2 = slave_list[route_to_peer2_host->dest]->controller;
+ focc->gateway2 = (NULL == route_to_peer2_host) ? NULL :
+ slave_list[route_to_peer2_host->dest]->controller;
focc->peer1 = p1;
focc->peer2 = p2;
focc->peer2_host_id = peer2_host_id;
focc->state = FOCC_INIT;
+ focc->orig_msg = GNUNET_malloc (msize);
+ (void) memcpy (focc->orig_msg, message, msize);
+ GNUNET_SERVER_client_keep (client);
+ focc->client = client;
+ focc->operation_id = operation_id;
fopc->cls = focc;
}
}
master_context = NULL;
}
GNUNET_free_non_null (hostname);
+ GNUNET_CONFIGURATION_destroy (our_config);
}
GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string
(cfg, "testbed", "HOSTNAME", &hostname));
+ our_config = GNUNET_CONFIGURATION_dup (cfg);
GNUNET_SERVER_add_handlers (server, message_handlers);
GNUNET_SERVER_disconnect_notify (server, &client_disconnect_cb, NULL);
ss_map = GNUNET_CONTAINER_multihashmap_create (5, GNUNET_NO);
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
&shutdown_task, NULL);
LOG_DEBUG ("Testbed startup complete\n");
- event_mask = GNUNET_TESTBED_ET_OPERATION_FINISHED;
+ event_mask = 1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED;
}