- msg = (const struct GNUNET_TESTBED_PeerStartMessage *) message;
- peer_id = ntohl (msg->peer_id);
- if ((peer_id >= GST_peer_list_size) || (NULL == GST_peer_list[peer_id]))
- {
- GNUNET_break (0);
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "Asked to start a non existent peer with id: %u\n", peer_id);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
- peer = GST_peer_list[peer_id];
- if (GNUNET_YES == peer->is_remote)
- {
- fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
- GNUNET_SERVER_client_keep (client);
- fopc->client = client;
- fopc->operation_id = GNUNET_ntohll (msg->operation_id);
- fopc->type = OP_PEER_START;
- fopc->opc =
- GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
- slave->controller,
- fopc->operation_id, &msg->header,
- &GST_forwarded_operation_reply_relay,
- fopc);
- fopc->timeout_task =
- GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout,
- fopc);
- GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
- if (GNUNET_OK != GNUNET_TESTING_peer_start (peer->details.local.peer))
- {
- GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
- "Failed to start");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
- peer->details.local.is_running = GNUNET_YES;
- reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
- reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT);
- reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
- reply->event_type = htonl (GNUNET_TESTBED_ET_PEER_START);
- reply->host_id = htonl (GST_context->host_id);
- reply->peer_id = msg->peer_id;
- reply->operation_id = msg->operation_id;
- GST_queue_message (client, &reply->header);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
-}
-
-
-/**
- * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages
- *
- * @param cls NULL
- * @param client identification of the client
- * @param message the actual message
- */
-static void
-handle_peer_stop (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- const struct GNUNET_TESTBED_PeerStopMessage *msg;
- struct GNUNET_TESTBED_PeerEventMessage *reply;
- struct ForwardedOperationContext *fopc;
- struct Peer *peer;
- uint32_t peer_id;
-
- msg = (const struct GNUNET_TESTBED_PeerStopMessage *) message;
- peer_id = ntohl (msg->peer_id);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PEER_STOP for peer %u\n", peer_id);
- if ((peer_id >= GST_peer_list_size) || (NULL == GST_peer_list[peer_id]))
- {
- GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
- "Peer not found");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
- peer = GST_peer_list[peer_id];
- if (GNUNET_YES == peer->is_remote)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Forwarding PEER_STOP for peer %u\n",
- peer_id);
- fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
- GNUNET_SERVER_client_keep (client);
- fopc->client = client;
- fopc->operation_id = GNUNET_ntohll (msg->operation_id);
- fopc->type = OP_PEER_STOP;
- fopc->opc =
- GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
- slave->controller,
- fopc->operation_id, &msg->header,
- &GST_forwarded_operation_reply_relay,
- fopc);
- fopc->timeout_task =
- GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout,
- fopc);
- GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
- if (GNUNET_OK != GNUNET_TESTING_peer_kill (peer->details.local.peer))
- {
- LOG (GNUNET_ERROR_TYPE_WARNING, "Stopping peer %u failed\n", peer_id);
- GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
- "Peer not running");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Peer %u successfully stopped\n", peer_id);
- peer->details.local.is_running = GNUNET_NO;
- reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
- reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT);
- reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
- reply->event_type = htonl (GNUNET_TESTBED_ET_PEER_STOP);
- reply->host_id = htonl (GST_context->host_id);
- reply->peer_id = msg->peer_id;
- reply->operation_id = msg->operation_id;
- GST_queue_message (client, &reply->header);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- GNUNET_TESTING_peer_wait (peer->details.local.peer);
-}
-
-
-/**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_GETPEERCONFIG messages
- *
- * @param cls NULL
- * @param client identification of the client
- * @param message the actual message
- */
-static void
-handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- const struct GNUNET_TESTBED_PeerGetConfigurationMessage *msg;
- struct GNUNET_TESTBED_PeerConfigurationInformationMessage *reply;
- struct Peer *peer;
- char *config;
- char *xconfig;
- size_t c_size;
- size_t xc_size;
- uint32_t peer_id;
- uint16_t msize;
-
- msg = (const struct GNUNET_TESTBED_PeerGetConfigurationMessage *) message;
- peer_id = ntohl (msg->peer_id);
- if ((peer_id >= GST_peer_list_size) || (NULL == GST_peer_list[peer_id]))
- {
- GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
- "Peer not found");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
- peer = GST_peer_list[peer_id];
- if (GNUNET_YES == peer->is_remote)
- {
- struct ForwardedOperationContext *fopc;
-
- LOG_DEBUG ("Forwarding PEER_GET_CONFIG for peer: %u\n", peer_id);
- fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
- GNUNET_SERVER_client_keep (client);
- fopc->client = client;
- fopc->operation_id = GNUNET_ntohll (msg->operation_id);
- fopc->type = OP_PEER_INFO;
- fopc->opc =
- GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
- slave->controller,
- fopc->operation_id, &msg->header,
- &GST_forwarded_operation_reply_relay,
- fopc);
- fopc->timeout_task =
- GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout,
- fopc);
- GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
- LOG_DEBUG ("Received PEER_GET_CONFIG for peer: %u\n", peer_id);
- config =
- GNUNET_CONFIGURATION_serialize (GST_peer_list[peer_id]->details.local.cfg,
- &c_size);
- xc_size = GNUNET_TESTBED_compress_config_ (config, c_size, &xconfig);
- GNUNET_free (config);
- msize =
- xc_size +
- sizeof (struct GNUNET_TESTBED_PeerConfigurationInformationMessage);
- reply = GNUNET_realloc (xconfig, msize);
- (void) memmove (&reply[1], reply, xc_size);
- reply->header.size = htons (msize);
- reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_CONFIGURATION);
- reply->peer_id = msg->peer_id;
- reply->operation_id = msg->operation_id;
- GNUNET_TESTING_peer_get_identity (GST_peer_list[peer_id]->details.local.peer,
- &reply->peer_identity);
- reply->config_size = htons ((uint16_t) c_size);
- GST_queue_message (client, &reply->header);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
-}
-
-
-/**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_GETSLAVECONFIG messages
- *
- * @param cls NULL
- * @param client identification of the client
- * @param message the actual message
- */
-static void
-handle_slave_get_config (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_TESTBED_SlaveGetConfigurationMessage *msg;
- struct Slave *slave;
- struct GNUNET_TESTBED_SlaveConfiguration *reply;
- char *config;
- char *xconfig;
- size_t config_size;
- size_t xconfig_size;
- size_t reply_size;
- uint64_t op_id;
- uint32_t slave_id;
-
- msg = (struct GNUNET_TESTBED_SlaveGetConfigurationMessage *) message;
- slave_id = ntohl (msg->slave_id);
- op_id = GNUNET_ntohll (msg->operation_id);
- if ((GST_slave_list_size <= slave_id) || (NULL == GST_slave_list[slave_id]))
- {
- /* FIXME: Add forwardings for this type of message here.. */
- GST_send_operation_fail_msg (client, op_id, "Slave not found");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
- slave = GST_slave_list[slave_id];
- if (NULL == slave->cfg)
- {
- GST_send_operation_fail_msg (client, op_id,
- "Configuration not found (slave not started by me)");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
- config = GNUNET_CONFIGURATION_serialize (slave->cfg, &config_size);
- xconfig_size =
- GNUNET_TESTBED_compress_config_ (config, config_size, &xconfig);
- GNUNET_free (config);
- reply_size = xconfig_size + sizeof (struct GNUNET_TESTBED_SlaveConfiguration);
- GNUNET_break (reply_size <= UINT16_MAX);
- GNUNET_break (config_size <= UINT16_MAX);
- reply = GNUNET_realloc (xconfig, reply_size);
- (void) memmove (&reply[1], reply, xconfig_size);
- reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_SLAVE_CONFIGURATION);
- reply->header.size = htons ((uint16_t) reply_size);
- reply->slave_id = msg->slave_id;
- reply->operation_id = msg->operation_id;
- reply->config_size = htons ((uint16_t) config_size);
- GST_queue_message (client, &reply->header);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
-}
-
-
-/**
- * Iterator over hash map entries.
- *
- * @param cls closure
- * @param key current key code
- * @param value value in the hash map
- * @return GNUNET_YES if we should continue to
- * iterate,
- * GNUNET_NO if not.
- */
-static int
-ss_map_free_iterator (void *cls, const struct GNUNET_HashCode *key, void *value)
-{
- struct SharedService *ss = value;
-
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_remove (ss_map, key, value));
- GNUNET_free (ss->name);
- GNUNET_free (ss);
- return GNUNET_YES;
-}
-
-
-/**
- * Iterator for freeing hash map entries in a slave's reghost_map
- *
- * @param cls handle to the slave
- * @param key current key code
- * @param value value in the hash map
- * @return GNUNET_YES if we should continue to
- * iterate,
- * GNUNET_NO if not.
- */
-static int
-reghost_free_iterator (void *cls, const struct GNUNET_HashCode *key,
- void *value)
-{
- struct Slave *slave = cls;
- struct RegisteredHostContext *rhc = value;
- struct ForwardedOverlayConnectContext *focc;
-
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_remove (slave->reghost_map, key,
- value));
- while (NULL != (focc = rhc->focc_dll_head))
- {
- GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc);
- GST_cleanup_focc (focc);
- }
- if (NULL != rhc->sub_op)
- GNUNET_TESTBED_operation_done (rhc->sub_op);
- if (NULL != rhc->client)
- GNUNET_SERVER_client_drop (rhc->client);
- GNUNET_free (value);
- return GNUNET_YES;
-}
-
-
-/**
- * Task to clean up and shutdown nicely
- *
- * @param cls NULL
- * @param tc the TaskContext from scheduler
- */
-static void
-shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct LCFContextQueue *lcfq;
- struct ForwardedOperationContext *fopc;
- struct MessageQueue *mq_entry;
- uint32_t id;
-
- shutdown_task_id = GNUNET_SCHEDULER_NO_TASK;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down testbed service\n");
- (void) GNUNET_CONTAINER_multihashmap_iterate (ss_map, &ss_map_free_iterator,
- NULL);
- GNUNET_CONTAINER_multihashmap_destroy (ss_map);
- /* cleanup any remaining forwarded operations */