X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftestbed%2Fgnunet-service-testbed_peers.c;h=d3d597d4f96f2107b5b7c9bd2129066b258b0daa;hb=d17a17ea785f91c18b5694eab3372c4e4564d95e;hp=ece0e83e95f41a8f90258cea7656fca301389a48;hpb=6db7b23f0be85c8fc263cb8380cb9a3d495be75a;p=oweals%2Fgnunet.git
diff --git a/src/testbed/gnunet-service-testbed_peers.c b/src/testbed/gnunet-service-testbed_peers.c
index ece0e83e9..d3d597d4f 100644
--- a/src/testbed/gnunet-service-testbed_peers.c
+++ b/src/testbed/gnunet-service-testbed_peers.c
@@ -1,28 +1,28 @@
/*
- This file is part of GNUnet.
- (C) 2008--2013 Christian Grothoff (and other contributing authors)
+ This file is part of GNUnet.
+ Copyright (C) 2008--2013, 2016 GNUnet e.V.
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
/**
* @file testbed/gnunet-service-testbed_peers.c
* @brief implementation of TESTBED service that deals with peer management
- * @author Sree Harsha Totakura
+ * @author Sree Harsha Totakura
*/
#include "gnunet-service-testbed.h"
@@ -35,6 +35,11 @@
*/
struct Peer **GST_peer_list;
+/**
+ * The current number of peers running locally under this controller
+ */
+unsigned int GST_num_local_peers;
+
/**
* Context information to manage peers' services
@@ -64,13 +69,18 @@ struct ManageServiceContext
/**
* The client which requested to manage the peer's service
*/
- struct GNUNET_SERVER_Client *client;
-
+ struct GNUNET_SERVICE_Client *client;
+
+ /**
+ * Name of the service.
+ */
+ char *service;
+
/**
* The operation id of the associated request
*/
uint64_t op_id;
-
+
/**
* 1 if the service at the peer has to be started; 0 if it has to be stopped
*/
@@ -80,7 +90,7 @@ struct ManageServiceContext
* Is this context expired? Do not work on this context if it is set to
* GNUNET_YES
*/
- uint8_t expired;
+ uint8_t expired;
};
@@ -102,7 +112,7 @@ struct PeerReconfigureContext
/**
* The client which gave this operation to us
*/
- struct GNUNET_SERVER_Client *client;
+ struct GNUNET_SERVICE_Client *client;
/**
* The configuration handle to use as the new template
@@ -138,7 +148,6 @@ static struct PeerReconfigureContext *prc_head;
static struct PeerReconfigureContext *prc_tail;
-
/**
* DLL head for queue of manage service requests
*/
@@ -162,6 +171,8 @@ peer_list_add (struct Peer *peer)
GST_array_grow_large_enough (GST_peer_list, GST_peer_list_size, peer->id);
GNUNET_assert (NULL == GST_peer_list[peer->id]);
GST_peer_list[peer->id] = peer;
+ if (GNUNET_NO == peer->is_remote)
+ GST_num_local_peers++;
}
@@ -176,6 +187,8 @@ peer_list_remove (struct Peer *peer)
unsigned int orig_size;
uint32_t id;
+ if (GNUNET_NO == peer->is_remote)
+ GST_num_local_peers--;
GST_peer_list[peer->id] = NULL;
orig_size = GST_peer_list_size;
while (GST_peer_list_size >= LIST_GROW_STEP)
@@ -192,8 +205,8 @@ peer_list_remove (struct Peer *peer)
if (orig_size == GST_peer_list_size)
return;
GST_peer_list =
- GNUNET_realloc (GST_peer_list,
- sizeof (struct Peer *) * GST_peer_list_size);
+ GNUNET_realloc (GST_peer_list,
+ sizeof(struct Peer *) * GST_peer_list_size);
}
@@ -202,16 +215,14 @@ peer_list_remove (struct Peer *peer)
* timed out
*
* @param cls the FowardedOperationContext
- * @param tc the TaskContext from the scheduler
*/
static void
-peer_create_forward_timeout (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+peer_create_forward_timeout (void *cls)
{
struct ForwardedOperationContext *fopc = cls;
GNUNET_free (fopc->cls);
- GST_forwarded_operation_timeout (fopc, tc);
+ GST_forwarded_operation_timeout (fopc);
}
@@ -234,7 +245,8 @@ peer_create_success_cb (void *cls, const struct GNUNET_MessageHeader *msg)
remote_peer = fopc->cls;
peer_list_add (remote_peer);
}
- GST_forwarded_operation_reply_relay (fopc, msg);
+ GST_forwarded_operation_reply_relay (fopc,
+ msg);
}
@@ -265,6 +277,115 @@ GST_destroy_peer (struct Peer *peer)
}
+/**
+ * Cleanup the context information created for managing a peer's service
+ *
+ * @param mctx the ManageServiceContext
+ */
+static void
+cleanup_mctx (struct ManageServiceContext *mctx)
+{
+ mctx->expired = GNUNET_YES;
+ GNUNET_CONTAINER_DLL_remove (mctx_head,
+ mctx_tail,
+ mctx);
+ GNUNET_ARM_disconnect (mctx->ah);
+ GNUNET_assert (0 < mctx->peer->reference_cnt);
+ mctx->peer->reference_cnt--;
+ if ((GNUNET_YES == mctx->peer->destroy_flag) &&
+ (0 == mctx->peer->reference_cnt))
+ GST_destroy_peer (mctx->peer);
+ GNUNET_free (mctx->service);
+ GNUNET_free (mctx);
+}
+
+
+/**
+ * Stops a peer
+ *
+ * @param peer the peer to stop
+ * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
+ */
+static int
+stop_peer (struct Peer *peer)
+{
+ GNUNET_assert (GNUNET_NO == peer->is_remote);
+ if (GNUNET_OK != GNUNET_TESTING_peer_kill (peer->details.local.peer))
+ return GNUNET_SYSERR;
+ peer->details.local.is_running = GNUNET_NO;
+ return GNUNET_OK;
+}
+
+
+/**
+ * Cleans up the given PeerReconfigureContext
+ *
+ * @param prc the PeerReconfigureContext
+ */
+static void
+cleanup_prc (struct PeerReconfigureContext *prc)
+{
+ struct Peer *peer;
+
+ if (VALID_PEER_ID (prc->peer_id))
+ {
+ peer = GST_peer_list [prc->peer_id];
+ if (1 != prc->stopped)
+ {
+ GNUNET_TESTING_peer_stop_async_cancel (peer->details.local.peer);
+ stop_peer (peer); /* Stop the peer synchronously */
+ }
+ }
+ if (NULL != prc->cfg)
+ GNUNET_CONFIGURATION_destroy (prc->cfg);
+ GNUNET_CONTAINER_DLL_remove (prc_head,
+ prc_tail,
+ prc);
+ GNUNET_free (prc);
+}
+
+
+/**
+ * Notify peers subsystem that @a client disconnected.
+ *
+ * @param client the client that disconnected
+ */
+void
+GST_notify_client_disconnect_peers (struct GNUNET_SERVICE_Client *client)
+{
+ struct ForwardedOperationContext *fopc;
+ struct ForwardedOperationContext *fopcn;
+ struct ManageServiceContext *mctx;
+ struct ManageServiceContext *mctxn;
+ struct PeerReconfigureContext *prc;
+ struct PeerReconfigureContext *prcn;
+
+ for (fopc = fopcq_head; NULL != fopc; fopc = fopcn)
+ {
+ fopcn = fopc->next;
+ if (client == fopc->client)
+ {
+ if (OP_PEER_CREATE == fopc->type)
+ GNUNET_free (fopc->cls);
+ GNUNET_SCHEDULER_cancel (fopc->timeout_task);
+ GST_forwarded_operation_timeout (fopc);
+ }
+ }
+ for (mctx = mctx_head; NULL != mctx; mctx = mctxn)
+ {
+ mctxn = mctx->next;
+ if (client == mctx->client)
+ cleanup_mctx (mctx);
+ }
+ for (prc = prc_head; NULL != prc; prc = prcn)
+ {
+ prcn = prc->next;
+ if (client == prc->client)
+ cleanup_prc (prc);
+ }
+}
+
+
/**
* Callback to be called when forwarded peer destroy operation is successfull. We
* have to relay the reply msg back to the client
@@ -287,22 +408,38 @@ peer_destroy_success_cb (void *cls, const struct GNUNET_MessageHeader *msg)
if (0 == remote_peer->reference_cnt)
GST_destroy_peer (remote_peer);
}
- GST_forwarded_operation_reply_relay (fopc, msg);
+ GST_forwarded_operation_reply_relay (fopc,
+ msg);
}
/**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages
*
- * @param cls NULL
- * @param client identification of the client
- * @param message the actual message
+ * @param cls identification of the client
+ * @param msg the actual message
+ * @return #GNUNET_OK if @a msg is well-formed
+ */
+int
+check_peer_create (void *cls,
+ const struct GNUNET_TESTBED_PeerCreateMessage *msg)
+{
+ return GNUNET_OK; /* checked later */
+}
+
+
+/**
+ * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages
+ *
+ * @param cls identification of the client
+ * @param msg the actual message
*/
void
-GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
+handle_peer_create (void *cls,
+ const struct GNUNET_TESTBED_PeerCreateMessage *msg)
{
- const struct GNUNET_TESTBED_PeerCreateMessage *msg;
+ struct GNUNET_SERVICE_Client *client = cls;
+ struct GNUNET_MQ_Envelope *env;
struct GNUNET_TESTBED_PeerCreateSuccessEventMessage *reply;
struct GNUNET_CONFIGURATION_Handle *cfg;
struct ForwardedOperationContext *fo_ctxt;
@@ -311,79 +448,79 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client,
char *emsg;
uint32_t host_id;
uint32_t peer_id;
- uint16_t msize;
-
- msize = ntohs (message->size);
- if (msize <= sizeof (struct GNUNET_TESTBED_PeerCreateMessage))
- {
- GNUNET_break (0); /* We need configuration */
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
- msg = (const struct GNUNET_TESTBED_PeerCreateMessage *) message;
host_id = ntohl (msg->host_id);
peer_id = ntohl (msg->peer_id);
if (VALID_PEER_ID (peer_id))
{
- (void) GNUNET_asprintf (&emsg, "Peer with ID %u already exists", peer_id);
- GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
+ (void) GNUNET_asprintf (&emsg,
+ "Peer with ID %u already exists",
+ peer_id);
+ GST_send_operation_fail_msg (client,
+ GNUNET_ntohll (msg->operation_id),
emsg);
GNUNET_free (emsg);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
return;
}
if (UINT32_MAX == peer_id)
- {
- GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
+ {
+ GST_send_operation_fail_msg (client,
+ GNUNET_ntohll (msg->operation_id),
"Cannot create peer with given ID");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
return;
}
if (host_id == GST_context->host_id)
{
/* We are responsible for this peer */
- cfg = GNUNET_TESTBED_extract_config_ (message);
+ cfg = GNUNET_TESTBED_extract_config_ (&msg->header);
if (NULL == cfg)
{
GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ GNUNET_SERVICE_client_drop (client);
return;
}
- GNUNET_CONFIGURATION_set_value_number (cfg, "TESTBED", "PEERID",
+ GNUNET_CONFIGURATION_set_value_number (cfg,
+ "TESTBED",
+ "PEERID",
+ (unsigned long long) peer_id);
+
+ GNUNET_CONFIGURATION_set_value_number (cfg,
+ "PATHS",
+ "PEERID",
(unsigned long long) peer_id);
- peer = GNUNET_malloc (sizeof (struct Peer));
+ peer = GNUNET_new (struct Peer);
peer->is_remote = GNUNET_NO;
peer->details.local.cfg = cfg;
peer->id = peer_id;
- LOG_DEBUG ("Creating peer with id: %u\n", (unsigned int) peer->id);
+ LOG_DEBUG ("Creating peer with id: %u\n",
+ (unsigned int) peer->id);
peer->details.local.peer =
- GNUNET_TESTING_peer_configure (GST_context->system,
- peer->details.local.cfg, peer->id,
- NULL /* Peer id */ ,
- &emsg);
+ GNUNET_TESTING_peer_configure (GST_context->system,
+ peer->details.local.cfg, peer->id,
+ NULL /* Peer id */,
+ &emsg);
if (NULL == peer->details.local.peer)
{
- LOG (GNUNET_ERROR_TYPE_WARNING, "Configuring peer failed: %s\n", emsg);
+ LOG (GNUNET_ERROR_TYPE_WARNING,
+ "Configuring peer failed: %s\n",
+ emsg);
GNUNET_free (emsg);
GNUNET_free (peer);
GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ GNUNET_SERVICE_client_drop (client);
return;
}
peer->details.local.is_running = GNUNET_NO;
peer_list_add (peer);
- reply =
- GNUNET_malloc (sizeof
- (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage));
- reply->header.size =
- htons (sizeof (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage));
- reply->header.type =
- htons (GNUNET_MESSAGE_TYPE_TESTBED_CREATE_PEER_SUCCESS);
+ env = GNUNET_MQ_msg (reply,
+ GNUNET_MESSAGE_TYPE_TESTBED_CREATE_PEER_SUCCESS);
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_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+ env);
+ GNUNET_SERVICE_client_continue (client);
return;
}
@@ -392,83 +529,90 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client,
if (NULL == route)
{
GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client); // ?
return;
}
- peer = GNUNET_malloc (sizeof (struct Peer));
+ peer = GNUNET_new (struct Peer);
peer->is_remote = GNUNET_YES;
peer->id = peer_id;
peer->details.remote.slave = GST_slave_list[route->dest];
peer->details.remote.remote_host_id = host_id;
- fo_ctxt = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
- GNUNET_SERVER_client_keep (client);
+ fo_ctxt = GNUNET_new (struct ForwardedOperationContext);
fo_ctxt->client = client;
fo_ctxt->operation_id = GNUNET_ntohll (msg->operation_id);
fo_ctxt->cls = peer;
fo_ctxt->type = OP_PEER_CREATE;
fo_ctxt->opc =
- GNUNET_TESTBED_forward_operation_msg_ (GST_slave_list
- [route->dest]->controller,
- fo_ctxt->operation_id,
- &msg->header,
- peer_create_success_cb, fo_ctxt);
+ GNUNET_TESTBED_forward_operation_msg_ (GST_slave_list
+ [route->dest]->controller,
+ fo_ctxt->operation_id,
+ &msg->header,
+ &peer_create_success_cb,
+ fo_ctxt);
fo_ctxt->timeout_task =
- GNUNET_SCHEDULER_add_delayed (GST_timeout, &peer_create_forward_timeout,
+ GNUNET_SCHEDULER_add_delayed (GST_timeout,
+ &peer_create_forward_timeout,
+ fo_ctxt);
+ GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+ fopcq_tail,
fo_ctxt);
- GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fo_ctxt);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
}
/**
- * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages
+ * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages
*
- * @param cls NULL
- * @param client identification of the client
- * @param message the actual message
+ * @param cls identification of the client
+ * @param msg the actual message
*/
void
-GST_handle_peer_destroy (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
+handle_peer_destroy (void *cls,
+ const struct GNUNET_TESTBED_PeerDestroyMessage *msg)
{
- const struct GNUNET_TESTBED_PeerDestroyMessage *msg;
+ struct GNUNET_SERVICE_Client *client = cls;
struct ForwardedOperationContext *fopc;
struct Peer *peer;
uint32_t peer_id;
- msg = (const struct GNUNET_TESTBED_PeerDestroyMessage *) message;
peer_id = ntohl (msg->peer_id);
- LOG_DEBUG ("Received peer destory on peer: %u and operation id: %ul\n",
- peer_id, GNUNET_ntohll (msg->operation_id));
- if (!VALID_PEER_ID (peer_id))
+ LOG_DEBUG ("Received peer destory on peer: %u and operation id: %llu\n",
+ (unsigned int) peer_id,
+ (unsigned long long) GNUNET_ntohll (msg->operation_id));
+ if (! VALID_PEER_ID (peer_id))
{
LOG (GNUNET_ERROR_TYPE_ERROR,
"Asked to destroy a non existent peer with id: %u\n", peer_id);
- GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
+ GST_send_operation_fail_msg (client,
+ GNUNET_ntohll (msg->operation_id),
"Peer doesn't exist");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
return;
}
peer = GST_peer_list[peer_id];
if (GNUNET_YES == peer->is_remote)
{
/* Forward the destory message to sub controller */
- fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
- GNUNET_SERVER_client_keep (client);
+ fopc = GNUNET_new (struct ForwardedOperationContext);
fopc->client = client;
fopc->cls = peer;
fopc->type = OP_PEER_DESTROY;
fopc->operation_id = GNUNET_ntohll (msg->operation_id);
fopc->opc =
- GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
- slave->controller,
- fopc->operation_id, &msg->header,
- &peer_destroy_success_cb, fopc);
+ GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
+ slave->controller,
+ fopc->operation_id,
+ &msg->header,
+ &peer_destroy_success_cb,
+ fopc);
fopc->timeout_task =
- GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout,
+ GNUNET_SCHEDULER_add_delayed (GST_timeout,
+ &GST_forwarded_operation_timeout,
+ fopc);
+ GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+ fopcq_tail,
fopc);
- GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
return;
}
peer->destroy_flag = GNUNET_YES;
@@ -477,8 +621,9 @@ GST_handle_peer_destroy (void *cls, struct GNUNET_SERVER_Client *client,
else
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Delaying peer destroy as peer is currently in use\n");
- GST_send_operation_success_msg (client, GNUNET_ntohll (msg->operation_id));
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GST_send_operation_success_msg (client,
+ GNUNET_ntohll (msg->operation_id));
+ GNUNET_SERVICE_client_continue (client);
}
@@ -486,7 +631,7 @@ GST_handle_peer_destroy (void *cls, struct GNUNET_SERVER_Client *client,
* Stats a peer
*
* @param peer the peer to start
- * @return GNUNET_OK upon success; GNUNET_SYSERR upon failure
+ * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
*/
static int
start_peer (struct Peer *peer)
@@ -500,173 +645,172 @@ start_peer (struct Peer *peer)
/**
- * Stops a peer
+ * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_START_PEER messages
*
- * @param peer the peer to stop
- * @return GNUNET_OK upon success; GNUNET_SYSERR upon failure
- */
-static int
-stop_peer (struct Peer *peer)
-{
- GNUNET_assert (GNUNET_NO == peer->is_remote);
- if (GNUNET_OK != GNUNET_TESTING_peer_kill (peer->details.local.peer))
- return GNUNET_SYSERR;
- peer->details.local.is_running = GNUNET_NO;
- return 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
+ * @param cls identification of the client
+ * @param msg the actual message
*/
void
-GST_handle_peer_start (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
+handle_peer_start (void *cls,
+ const struct GNUNET_TESTBED_PeerStartMessage *msg)
{
- const struct GNUNET_TESTBED_PeerStartMessage *msg;
+ struct GNUNET_SERVICE_Client *client = cls;
+ struct GNUNET_MQ_Envelope *env;
struct GNUNET_TESTBED_PeerEventMessage *reply;
struct ForwardedOperationContext *fopc;
struct Peer *peer;
uint32_t peer_id;
- msg = (const struct GNUNET_TESTBED_PeerStartMessage *) message;
peer_id = ntohl (msg->peer_id);
- if (!VALID_PEER_ID (peer_id))
+ if (! VALID_PEER_ID (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);
+ "Asked to start a non existent peer with id: %u\n",
+ peer_id);
+ GNUNET_SERVICE_client_continue (client);
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 = GNUNET_new (struct ForwardedOperationContext);
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);
+ 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,
+ GNUNET_SCHEDULER_add_delayed (GST_timeout,
+ &GST_forwarded_operation_timeout,
+ fopc);
+ GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+ fopcq_tail,
fopc);
- GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
return;
}
if (GNUNET_OK != start_peer (peer))
{
GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
"Failed to start");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
return;
}
- 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));
+ env = GNUNET_MQ_msg (reply,
+ GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT);
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);
+ GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+ env);
+ GNUNET_SERVICE_client_continue (client);
}
/**
- * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages
+ * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_STOP_PEER messages
*
- * @param cls NULL
- * @param client identification of the client
- * @param message the actual message
+ * @param cls identification of the client
+ * @param msg the actual message
*/
void
-GST_handle_peer_stop (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
+handle_peer_stop (void *cls,
+ const struct GNUNET_TESTBED_PeerStopMessage *msg)
{
- const struct GNUNET_TESTBED_PeerStopMessage *msg;
+ struct GNUNET_SERVICE_Client *client = cls;
+ struct GNUNET_MQ_Envelope *env;
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 (!VALID_PEER_ID (peer_id))
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Received PEER_STOP for peer %u\n",
+ (unsigned int) peer_id);
+ if (! VALID_PEER_ID (peer_id))
{
- GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
+ GST_send_operation_fail_msg (client,
+ GNUNET_ntohll (msg->operation_id),
"Peer not found");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
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);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Forwarding PEER_STOP for peer %u\n",
+ (unsigned int) peer_id);
+ fopc = GNUNET_new (struct ForwardedOperationContext);
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);
+ 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,
+ GNUNET_SCHEDULER_add_delayed (GST_timeout,
+ &GST_forwarded_operation_timeout,
+ fopc);
+ GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+ fopcq_tail,
fopc);
- GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
return;
}
if (GNUNET_OK != stop_peer (peer))
{
- LOG (GNUNET_ERROR_TYPE_WARNING, "Stopping peer %u failed\n", peer_id);
- GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
+ LOG (GNUNET_ERROR_TYPE_WARNING,
+ "Stopping peer %u failed\n",
+ (unsigned int) peer_id);
+ GST_send_operation_fail_msg (client,
+ GNUNET_ntohll (msg->operation_id),
"Peer not running");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
return;
}
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Peer %u successfully stopped\n", peer_id);
- 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));
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Peer %u successfully stopped\n",
+ (unsigned int) peer_id);
+ env = GNUNET_MQ_msg (reply,
+ GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT);
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_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+ env);
+ GNUNET_SERVICE_client_continue (client);
GNUNET_TESTING_peer_wait (peer->details.local.peer);
}
/**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_GETPEERCONFIG messages
+ * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_GET_PEER_INFORMATION messages
*
- * @param cls NULL
- * @param client identification of the client
- * @param message the actual message
+ * @param cls identification of the client
+ * @param msg the actual message
*/
void
-GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
+handle_peer_get_config (void *cls,
+ const struct
+ GNUNET_TESTBED_PeerGetConfigurationMessage *msg)
{
- const struct GNUNET_TESTBED_PeerGetConfigurationMessage *msg;
+ struct GNUNET_SERVICE_Client *client = cls;
+ struct GNUNET_MQ_Envelope *env;
struct GNUNET_TESTBED_PeerConfigurationInformationMessage *reply;
struct ForwardedOperationContext *fopc;
struct Peer *peer;
@@ -675,98 +819,107 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
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);
- LOG_DEBUG ("Received GET_CONFIG for peer %u\n", peer_id);
- if (!VALID_PEER_ID (peer_id))
+ LOG_DEBUG ("Received GET_CONFIG for peer %u\n",
+ (unsigned int) peer_id);
+ if (! VALID_PEER_ID (peer_id))
{
- GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
+ GST_send_operation_fail_msg (client,
+ GNUNET_ntohll (msg->operation_id),
"Peer not found");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
return;
}
peer = GST_peer_list[peer_id];
if (GNUNET_YES == peer->is_remote)
{
- LOG_DEBUG ("Forwarding PEER_GET_CONFIG for peer: %u\n", peer_id);
- fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
- GNUNET_SERVER_client_keep (client);
+ LOG_DEBUG ("Forwarding PEER_GET_CONFIG for peer: %u\n",
+ (unsigned int) peer_id);
+ fopc = GNUNET_new (struct ForwardedOperationContext);
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);
+ 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,
+ GNUNET_SCHEDULER_add_delayed (GST_timeout,
+ &GST_forwarded_operation_timeout,
+ fopc);
+ GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+ fopcq_tail,
fopc);
- GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
return;
}
- LOG_DEBUG ("Received PEER_GET_CONFIG for peer: %u\n", peer_id);
+ 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_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_INFORMATION);
+ env = GNUNET_MQ_msg_extra (reply,
+ xc_size,
+ GNUNET_MESSAGE_TYPE_TESTBED_PEER_INFORMATION);
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);
+ GNUNET_memcpy (&reply[1],
+ xconfig,
+ xc_size);
+ GNUNET_free (xconfig);
+ GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+ env);
+ GNUNET_SERVICE_client_continue (client);
}
/**
- * Cleans up the given PeerReconfigureContext
- *
- * @param prc the PeerReconfigureContext
+ * Cleans up the Peer reconfigure context list
*/
-static void
-cleanup_prc (struct PeerReconfigureContext *prc)
+void
+GST_free_prcq ()
{
- struct Peer *peer;
-
- if (VALID_PEER_ID (prc->peer_id))
- {
- peer = GST_peer_list [prc->peer_id];
- if (1 != prc->stopped)
- {
- GNUNET_TESTING_peer_stop_async_cancel (peer->details.local.peer);
- stop_peer (peer); /* Stop the peer synchronously */
- }
- }
- if (NULL != prc->cfg)
- GNUNET_CONFIGURATION_destroy (prc->cfg);
- GNUNET_SERVER_client_drop (prc->client);
- GNUNET_CONTAINER_DLL_remove (prc_head, prc_tail, prc);
- GNUNET_free (prc);
+ while (NULL != prc_head)
+ cleanup_prc (prc_head);
}
/**
- * Cleans up the Peer reconfigure context list
+ * Update peer configuration
+ *
+ * @param peer the peer to update
+ * @param cfg the new configuration
+ * @return error message (freshly allocated); NULL upon success
*/
-void
-GST_free_prcq ()
+static char *
+update_peer_config (struct Peer *peer,
+ struct GNUNET_CONFIGURATION_Handle *cfg)
{
- while (NULL != prc_head)
- cleanup_prc (prc_head);
+ char *emsg;
+
+ GNUNET_TESTING_peer_destroy (peer->details.local.peer);
+ GNUNET_CONFIGURATION_destroy (peer->details.local.cfg);
+ peer->details.local.cfg = cfg;
+ emsg = NULL;
+ peer->details.local.peer
+ = GNUNET_TESTING_peer_configure (GST_context->system,
+ peer->details.local.cfg,
+ peer->id,
+ NULL /* Peer id */,
+ &emsg);
+ return emsg;
}
@@ -775,164 +928,193 @@ GST_free_prcq ()
*
* @param cls the closure given to GNUNET_TESTING_peer_stop_async()
* @param p the respective peer whose status is being reported
- * @param success GNUNET_YES if the peer is stopped; GNUNET_SYSERR upon any
+ * @param success #GNUNET_YES if the peer is stopped; #GNUNET_SYSERR upon any
* error
*/
static void
-prc_stop_cb (void *cls, struct GNUNET_TESTING_Peer *p, int success)
+prc_stop_cb (void *cls,
+ struct GNUNET_TESTING_Peer *p,
+ int success)
{
struct PeerReconfigureContext *prc = cls;
struct Peer *peer;
char *emsg;
-
+
GNUNET_assert (VALID_PEER_ID (prc->peer_id));
peer = GST_peer_list [prc->peer_id];
GNUNET_assert (GNUNET_NO == peer->is_remote);
- GNUNET_TESTING_peer_destroy (peer->details.local.peer);
- GNUNET_CONFIGURATION_destroy (peer->details.local.cfg);
- peer->details.local.cfg = prc->cfg;
+ emsg = update_peer_config (peer, prc->cfg);
prc->cfg = NULL;
prc->stopped = 1;
- emsg = NULL;
- peer->details.local.peer
- = GNUNET_TESTING_peer_configure (GST_context->system,
- peer->details.local.cfg, peer->id,
- NULL /* Peer id */ ,
- &emsg);
- if (NULL == peer->details.local.peer)
+ if (NULL != emsg)
{
- GST_send_operation_fail_msg (prc->client, prc->op_id, emsg);
+ GST_send_operation_fail_msg (prc->client,
+ prc->op_id,
+ emsg);
goto cleanup;
}
if (GNUNET_OK != start_peer (peer))
{
-
- GST_send_operation_fail_msg (prc->client, prc->op_id,
+ GST_send_operation_fail_msg (prc->client,
+ prc->op_id,
"Failed to start reconfigured peer");
goto cleanup;
}
- GST_send_operation_success_msg (prc->client, prc->op_id);
-
- cleanup:
+ GST_send_operation_success_msg (prc->client,
+ prc->op_id);
+
+cleanup:
cleanup_prc (prc);
return;
}
/**
- * Handler for GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages.
+ * Check #GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages.
+ *
+ * @param cls identification of the client
+ * @param msg the actual message
+ * @return #GNUNET_OK if @a msg is well-formed
+ */
+int
+check_peer_reconfigure (void *cls,
+ const struct GNUNET_TESTBED_PeerReconfigureMessage *msg)
+{
+ return GNUNET_OK; /* checked later */
+}
+
+
+/**
+ * Handler for #GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages.
* Should stop the peer asyncronously, destroy it and create it again with the
* new configuration.
*
- * @param cls NULL
- * @param client identification of the client
- * @param message the actual message
+ * @param cls identification of the client
+ * @param msg the actual message
*/
void
-GST_handle_peer_reconfigure (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
+handle_peer_reconfigure (void *cls,
+ const struct
+ GNUNET_TESTBED_PeerReconfigureMessage *msg)
{
- const struct GNUNET_TESTBED_PeerReconfigureMessage *msg;
+ struct GNUNET_SERVICE_Client *client = cls;
struct Peer *peer;
struct GNUNET_CONFIGURATION_Handle *cfg;
struct ForwardedOperationContext *fopc;
struct PeerReconfigureContext *prc;
+ char *emsg;
uint64_t op_id;
uint32_t peer_id;
- uint16_t msize;
-
- msize = ntohs (message->size);
- if (msize <= sizeof (struct GNUNET_TESTBED_PeerReconfigureMessage))
- {
- GNUNET_break_op (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- msg = (const struct GNUNET_TESTBED_PeerReconfigureMessage *) message;
+
peer_id = ntohl (msg->peer_id);
op_id = GNUNET_ntohll (msg->operation_id);
- if (!VALID_PEER_ID (peer_id))
+ if (! VALID_PEER_ID (peer_id))
{
GNUNET_break (0);
- GST_send_operation_fail_msg (client, op_id, "Peer not found");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GST_send_operation_fail_msg (client,
+ op_id,
+ "Peer not found");
+ GNUNET_SERVICE_client_continue (client);
return;
}
peer = GST_peer_list[peer_id];
if (GNUNET_YES == peer->is_remote)
{
LOG_DEBUG ("Forwarding PEER_RECONFIGURE for peer: %u\n", peer_id);
- fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
- GNUNET_SERVER_client_keep (client);
+ fopc = GNUNET_new (struct ForwardedOperationContext);
fopc->client = client;
fopc->operation_id = op_id;
fopc->type = OP_PEER_RECONFIGURE;
fopc->opc =
- GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
- slave->controller,
- fopc->operation_id, &msg->header,
- &GST_forwarded_operation_reply_relay,
- fopc);
+ 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,
+ GNUNET_SCHEDULER_add_delayed (GST_timeout,
+ &GST_forwarded_operation_timeout,
+ fopc);
+ GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+ fopcq_tail,
fopc);
- GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
return;
}
- LOG_DEBUG ("Received PEER_RECONFIGURE for peer %u\n", peer_id);
+ LOG_DEBUG ("Received PEER_RECONFIGURE for peer %u\n",
+ (unsigned int) peer_id);
if (0 < peer->reference_cnt)
{
GNUNET_break (0);
- GST_send_operation_fail_msg (client, op_id, "Peer in use");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GST_send_operation_fail_msg (client,
+ op_id,
+ "Peer in use");
+ GNUNET_SERVICE_client_continue (client);
return;
}
if (GNUNET_YES == peer->destroy_flag)
{
GNUNET_break (0);
- GST_send_operation_fail_msg (client, op_id, "Peer is being destroyed");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GST_send_operation_fail_msg (client,
+ op_id,
+ "Peer is being destroyed");
+ GNUNET_SERVICE_client_continue (client);
return;
}
- cfg = GNUNET_TESTBED_extract_config_ (message);
+ cfg = GNUNET_TESTBED_extract_config_ (&msg->header);
if (NULL == cfg)
{
- GNUNET_break (0);
- GST_send_operation_fail_msg (client, op_id, "Compression error");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_break (0);
+ GST_send_operation_fail_msg (client,
+ op_id,
+ "Compression error");
+ GNUNET_SERVICE_client_continue (client);
+ return;
+ }
+ if (GNUNET_NO == peer->details.local.is_running)
+ {
+ emsg = update_peer_config (peer,
+ cfg);
+ if (NULL != emsg)
+ GST_send_operation_fail_msg (client,
+ op_id,
+ emsg);
+ GST_send_operation_success_msg (client,
+ op_id);
+ GNUNET_SERVICE_client_continue (client);
+ GNUNET_free_non_null (emsg);
+ return;
+ }
+ prc = GNUNET_new (struct PeerReconfigureContext);
+ if (GNUNET_OK !=
+ GNUNET_TESTING_peer_stop_async (peer->details.local.peer,
+ &prc_stop_cb,
+ prc))
+ {
+ GNUNET_assert (0 < GNUNET_asprintf (&emsg,
+ "Error trying to stop peer %u asynchronously\n",
+ peer_id));
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "%s\n",
+ emsg);
+ GST_send_operation_fail_msg (client,
+ op_id,
+ emsg);
+ GNUNET_SERVICE_client_continue (client);
+ GNUNET_free (prc);
+ GNUNET_free (emsg);
return;
}
- prc = GNUNET_malloc (sizeof (struct PeerReconfigureContext));
prc->cfg = cfg;
prc->peer_id = peer_id;
prc->op_id = op_id;
- prc->client = client;
- GNUNET_SERVER_client_keep (client);
- GNUNET_CONTAINER_DLL_insert_tail (prc_head, prc_tail, prc);
- GNUNET_TESTING_peer_stop_async (peer->details.local.peer, prc_stop_cb, prc);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
-}
-
-
-/**
- * Cleanup the context information created for managing a peer's service
- *
- * @param mctx the ManageServiceContext
- */
-static void
-cleanup_mctx (struct ManageServiceContext *mctx)
-{
- mctx->expired = GNUNET_YES;
- GNUNET_CONTAINER_DLL_remove (mctx_head, mctx_tail, mctx);
- GNUNET_SERVER_client_drop (mctx->client);
- GNUNET_ARM_disconnect_and_free (mctx->ah);
- GNUNET_assert (0 < mctx->peer->reference_cnt);
- mctx->peer->reference_cnt--;
- if ( (GNUNET_YES == mctx->peer->destroy_flag)
- && (0 == mctx->peer->reference_cnt) )
- GST_destroy_peer (mctx->peer);
- GNUNET_free (mctx);
+ prc->client = client;
+ GNUNET_CONTAINER_DLL_insert_tail (prc_head,
+ prc_tail,
+ prc);
+ GNUNET_SERVICE_client_continue (client);
}
@@ -948,7 +1130,7 @@ GST_free_mctxq ()
/**
- * Returns a string interpretation of 'rs'
+ * Returns a string interpretation of @a rs.
*
* @param rs the request status from ARM
* @return a string interpretation of the request status
@@ -959,24 +1141,17 @@ arm_req_string (enum GNUNET_ARM_RequestStatus rs)
switch (rs)
{
case GNUNET_ARM_REQUEST_SENT_OK:
- return _("Message was sent successfully");
- case GNUNET_ARM_REQUEST_CONFIGURATION_ERROR:
- return _("Misconfiguration (can't connect to the ARM service)");
+ return _ ("Message was sent successfully");
+
case GNUNET_ARM_REQUEST_DISCONNECTED:
- return _("We disconnected from ARM before we could send a request");
- case GNUNET_ARM_REQUEST_BUSY:
- return _("ARM API is busy");
- case GNUNET_ARM_REQUEST_TOO_LONG:
- return _("Request doesn't fit into a message");
- case GNUNET_ARM_REQUEST_TIMEOUT:
- return _("Request timed out");
+ return _ ("We disconnected from ARM before we could send a request");
}
- return _("Unknown request status");
+ return _ ("Unknown request status");
}
/**
- * Returns a string interpretation of the 'result'
+ * Returns a string interpretation of the @a result.
*
* @param result the arm result
* @return a string interpretation
@@ -987,27 +1162,36 @@ arm_ret_string (enum GNUNET_ARM_Result result)
switch (result)
{
case GNUNET_ARM_RESULT_STOPPED:
- return _("%s is stopped");
+ return _ ("%s is stopped");
+
case GNUNET_ARM_RESULT_STARTING:
- return _("%s is starting");
+ return _ ("%s is starting");
+
case GNUNET_ARM_RESULT_STOPPING:
- return _("%s is stopping");
+ return _ ("%s is stopping");
+
case GNUNET_ARM_RESULT_IS_STARTING_ALREADY:
- return _("%s is starting already");
+ return _ ("%s is starting already");
+
case GNUNET_ARM_RESULT_IS_STOPPING_ALREADY:
- return _("%s is stopping already");
+ return _ ("%s is stopping already");
+
case GNUNET_ARM_RESULT_IS_STARTED_ALREADY:
- return _("%s is started already");
+ return _ ("%s is started already");
+
case GNUNET_ARM_RESULT_IS_STOPPED_ALREADY:
- return _("%s is stopped already");
+ return _ ("%s is stopped already");
+
case GNUNET_ARM_RESULT_IS_NOT_KNOWN:
- return _("%s service is not known to ARM");
+ return _ ("%s service is not known to ARM");
+
case GNUNET_ARM_RESULT_START_FAILED:
- return _("%s service failed to start");
+ return _ ("%s service failed to start");
+
case GNUNET_ARM_RESULT_IN_SHUTDOWN:
- return _("%s service can't be started because ARM is shutting down");
+ return _ ("%s service can't be started because ARM is shutting down");
}
- return _("%.s Unknown result code.");
+ return _ ("%.s Unknown result code.");
}
@@ -1015,17 +1199,16 @@ arm_ret_string (enum GNUNET_ARM_Result result)
* Function called in response to a start/stop request.
* Will be called when request was not sent successfully,
* or when a reply comes. If the request was not sent successfully,
- * 'rs' will indicate that, and 'service' and 'result' will be undefined.
+ * @a rs will indicate that, and @a result will be undefined.
*
* @param cls ManageServiceContext
* @param rs status of the request
- * @param service service name
* @param result result of the operation
*/
static void
-service_manage_result_cb (void *cls,
- enum GNUNET_ARM_RequestStatus rs,
- const char *service, enum GNUNET_ARM_Result result)
+service_manage_result_cb (void *cls,
+ enum GNUNET_ARM_RequestStatus rs,
+ enum GNUNET_ARM_Result result)
{
struct ManageServiceContext *mctx = cls;
char *emsg;
@@ -1035,93 +1218,111 @@ service_manage_result_cb (void *cls,
return;
if (GNUNET_ARM_REQUEST_SENT_OK != rs)
{
- GNUNET_asprintf (&emsg, "Error communicating with Peer %u's ARM: %s",
- mctx->peer->id, arm_req_string (rs));
+ GNUNET_asprintf (&emsg,
+ "Error communicating with Peer %u's ARM: %s",
+ mctx->peer->id,
+ arm_req_string (rs));
goto ret;
}
if (1 == mctx->start)
goto service_start_check;
if (! ((GNUNET_ARM_RESULT_STOPPED == result)
- || (GNUNET_ARM_RESULT_STOPPING == result)
- || (GNUNET_ARM_RESULT_IS_STOPPING_ALREADY == result)
- || (GNUNET_ARM_RESULT_IS_STOPPED_ALREADY == result)) )
+ || (GNUNET_ARM_RESULT_STOPPING == result)
+ || (GNUNET_ARM_RESULT_IS_STOPPING_ALREADY == result)
+ || (GNUNET_ARM_RESULT_IS_STOPPED_ALREADY == result)))
{
/* stopping a service failed */
- GNUNET_asprintf (&emsg, arm_ret_string (result), service);
+ GNUNET_asprintf (&emsg,
+ arm_ret_string (result),
+ mctx->service);
goto ret;
}
/* service stopped successfully */
goto ret;
- service_start_check:
+service_start_check:
if (! ((GNUNET_ARM_RESULT_STARTING == result)
- || (GNUNET_ARM_RESULT_IS_STARTING_ALREADY == result)
- || (GNUNET_ARM_RESULT_IS_STARTED_ALREADY == result)) )
+ || (GNUNET_ARM_RESULT_IS_STARTING_ALREADY == result)
+ || (GNUNET_ARM_RESULT_IS_STARTED_ALREADY == result)))
{
/* starting a service failed */
- GNUNET_asprintf (&emsg, arm_ret_string (result), service);
+ GNUNET_asprintf (&emsg,
+ arm_ret_string (result),
+ mctx->service);
goto ret;
}
/* service started successfully */
-
- ret:
+
+ret:
if (NULL != emsg)
{
LOG_DEBUG ("%s\n", emsg);
- GST_send_operation_fail_msg (mctx->client, mctx->op_id, emsg);
+ GST_send_operation_fail_msg (mctx->client,
+ mctx->op_id,
+ emsg);
}
else
- GST_send_operation_success_msg (mctx->client, mctx->op_id);
+ GST_send_operation_success_msg (mctx->client,
+ mctx->op_id);
GNUNET_free_non_null (emsg);
cleanup_mctx (mctx);
}
/**
- * Handler for GNUNET_TESTBED_ManagePeerServiceMessage message
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE message
*
- * @param cls NULL
- * @param client identification of client
- * @param message the actual message
+ * @param cls identification of client
+ * @param msg the actual message
+ * @return #GNUNET_OK if @a msg is well-formed
*/
-void
-GST_handle_manage_peer_service (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
+int
+check_manage_peer_service (void *cls,
+ const struct
+ GNUNET_TESTBED_ManagePeerServiceMessage *msg)
{
- const struct GNUNET_TESTBED_ManagePeerServiceMessage *msg;
- const char* service;
- struct Peer *peer;
- char *emsg;
- struct GNUNET_ARM_Handle *ah;
- struct ManageServiceContext *mctx;
- struct ForwardedOperationContext *fopc;
- uint64_t op_id;
- uint32_t peer_id;
uint16_t msize;
-
+ const char*service;
- msize = ntohs (message->size);
- if (msize <= sizeof (struct GNUNET_TESTBED_ManagePeerServiceMessage))
- {
- GNUNET_break_op (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- msg = (const struct GNUNET_TESTBED_ManagePeerServiceMessage *) message;
- service = (const char *) &msg[1];
+ msize = ntohs (msg->header.size);
+ service = (const char *) &msg[1];
if ('\0' != service[msize - sizeof
(struct GNUNET_TESTBED_ManagePeerServiceMessage) - 1])
{
GNUNET_break_op (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
+ return GNUNET_SYSERR;
}
if (1 < msg->start)
{
GNUNET_break_op (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
+ return GNUNET_SYSERR;
}
+ return GNUNET_OK;
+}
+
+
+/**
+ * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE messages
+ *
+ * @param cls identification of client
+ * @param msg the actual message
+ */
+void
+handle_manage_peer_service (void *cls,
+ const struct
+ GNUNET_TESTBED_ManagePeerServiceMessage *msg)
+{
+ struct GNUNET_SERVICE_Client *client = cls;
+ const char*service;
+ struct Peer *peer;
+ char *emsg;
+ struct GNUNET_ARM_Handle *ah;
+ struct ManageServiceContext *mctx;
+ struct ForwardedOperationContext *fopc;
+ uint64_t op_id;
+ uint32_t peer_id;
+
+ service = (const char *) &msg[1];
peer_id = ntohl (msg->peer_id);
op_id = GNUNET_ntohll (msg->operation_id);
LOG_DEBUG ("Received request to manage service %s on peer %u\n",
@@ -1142,28 +1343,37 @@ GST_handle_manage_peer_service (void *cls, struct GNUNET_SERVER_Client *client,
if (GNUNET_YES == peer->is_remote)
{
/* Forward the destory message to sub controller */
- fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
- GNUNET_SERVER_client_keep (client);
+ fopc = GNUNET_new (struct ForwardedOperationContext);
fopc->client = client;
fopc->cls = peer;
fopc->type = OP_MANAGE_SERVICE;
fopc->operation_id = op_id;
fopc->opc =
- GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
- slave->controller,
- fopc->operation_id, &msg->header,
- &GST_forwarded_operation_reply_relay,
- fopc);
+ 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,
+ GNUNET_SCHEDULER_add_delayed (GST_timeout,
+ &GST_forwarded_operation_timeout,
+ fopc);
+ GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+ fopcq_tail,
fopc);
- GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
return;
}
+ if (GNUNET_NO == peer->details.local.is_running)
+ {
+ emsg = GNUNET_strdup ("Peer not running\n");
+ goto err_ret;
+ }
if ((0 != peer->reference_cnt)
- && ( (0 == strcasecmp ("core", service))
- || (0 == strcasecmp ("transport", service)) ) )
+ && ((0 == strcasecmp ("core", service))
+ || (0 == strcasecmp ("transport", service))))
{
GNUNET_asprintf (&emsg, "Cannot stop %s service of peer with id: %u "
"since it is required by existing operations",
@@ -1178,34 +1388,35 @@ GST_handle_manage_peer_service (void *cls, struct GNUNET_SERVER_Client *client,
peer_id);
goto err_ret;
}
- mctx = GNUNET_malloc (sizeof (struct ManageServiceContext));
+ mctx = GNUNET_new (struct ManageServiceContext);
mctx->peer = peer;
peer->reference_cnt++;
mctx->op_id = op_id;
mctx->ah = ah;
- GNUNET_SERVER_client_keep (client);
mctx->client = client;
mctx->start = msg->start;
- GNUNET_CONTAINER_DLL_insert_tail (mctx_head, mctx_tail, mctx);
+ mctx->service = GNUNET_strdup (service);
+ GNUNET_CONTAINER_DLL_insert_tail (mctx_head,
+ mctx_tail,
+ mctx);
if (1 == mctx->start)
- GNUNET_ARM_request_service_start (mctx->ah, service,
+ GNUNET_ARM_request_service_start (mctx->ah,
+ service,
GNUNET_OS_INHERIT_STD_ERR,
- GST_timeout,
- service_manage_result_cb,
+ &service_manage_result_cb,
mctx);
else
GNUNET_ARM_request_service_stop (mctx->ah, service,
- GST_timeout,
- service_manage_result_cb,
+ &service_manage_result_cb,
mctx);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
return;
- err_ret:
+err_ret:
LOG (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
GST_send_operation_fail_msg (client, op_id, emsg);
GNUNET_free (emsg);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
}
@@ -1238,7 +1449,7 @@ GST_destroy_peers ()
{
peer = GST_peer_list[id];
if (NULL == peer)
- continue;
+ continue;
if (GNUNET_NO == peer->is_remote)
{
if (GNUNET_YES == peer->details.local.is_running)
@@ -1254,38 +1465,6 @@ GST_destroy_peers ()
}
-/**
- * Task run upon timeout of forwarded SHUTDOWN_PEERS operation
- *
- * @param cls the ForwardedOperationContext
- * @param tc the scheduler task context
- */
-static void
-shutdown_peers_timeout_cb (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct ForwardedOperationContext *fo_ctxt = cls;
- struct HandlerContext_ShutdownPeers *hc;
-
- fo_ctxt->timeout_task = GNUNET_SCHEDULER_NO_TASK;
- hc = fo_ctxt->cls;
- hc->timeout = GNUNET_YES;
- GNUNET_assert (0 < hc->nslaves);
- hc->nslaves--;
- if (0 == hc->nslaves)
- {
- GST_send_operation_fail_msg (fo_ctxt->client, fo_ctxt->operation_id,
- "Timeout at a slave controller");
- GNUNET_free (hc);
- hc = NULL;
- }
- GNUNET_TESTBED_forward_operation_msg_cancel_ (fo_ctxt->opc);
- GNUNET_SERVER_client_drop (fo_ctxt->client);
- GNUNET_CONTAINER_DLL_remove (fopcq_head, fopcq_tail, fo_ctxt);
- GNUNET_free (fo_ctxt);
-}
-
-
/**
* The reply msg handler forwarded SHUTDOWN_PEERS operation. Checks if a
* success reply is received from all clients and then sends the success message
@@ -1300,60 +1479,58 @@ shutdown_peers_reply_cb (void *cls,
{
struct ForwardedOperationContext *fo_ctxt = cls;
struct HandlerContext_ShutdownPeers *hc;
-
+
hc = fo_ctxt->cls;
- GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != fo_ctxt->timeout_task);
- GNUNET_SCHEDULER_cancel (fo_ctxt->timeout_task);
- fo_ctxt->timeout_task = GNUNET_SCHEDULER_NO_TASK;
GNUNET_assert (0 < hc->nslaves);
hc->nslaves--;
- if (GNUNET_MESSAGE_TYPE_TESTBED_GENERIC_OPERATION_SUCCESS !=
+ if (GNUNET_MESSAGE_TYPE_TESTBED_GENERIC_OPERATION_SUCCESS !=
ntohs (msg->type))
hc->timeout = GNUNET_YES;
if (0 == hc->nslaves)
{
if (GNUNET_YES == hc->timeout)
- GST_send_operation_fail_msg (fo_ctxt->client, fo_ctxt->operation_id,
+ GST_send_operation_fail_msg (fo_ctxt->client,
+ fo_ctxt->operation_id,
"Timeout at a slave controller");
else
- GST_send_operation_success_msg (fo_ctxt->client, fo_ctxt->operation_id);
+ GST_send_operation_success_msg (fo_ctxt->client,
+ fo_ctxt->operation_id);
GNUNET_free (hc);
hc = NULL;
}
- GNUNET_SERVER_client_drop (fo_ctxt->client);
- GNUNET_CONTAINER_DLL_remove (fopcq_head, fopcq_tail, fo_ctxt);
+ GNUNET_CONTAINER_DLL_remove (fopcq_head,
+ fopcq_tail,
+ fo_ctxt);
GNUNET_free (fo_ctxt);
}
/**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS messages
+ * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS messages
*
- * @param cls NULL
- * @param client identification of the client
- * @param message the actual message
+ * @param cls identification of the client
+ * @param msg the actual message
*/
void
-GST_handle_shutdown_peers (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
+handle_shutdown_peers (void *cls,
+ const struct GNUNET_TESTBED_ShutdownPeersMessage *msg)
{
- const struct GNUNET_TESTBED_ShutdownPeersMessage *msg;
+ struct GNUNET_SERVICE_Client *client = cls;
struct HandlerContext_ShutdownPeers *hc;
struct Slave *slave;
struct ForwardedOperationContext *fo_ctxt;
uint64_t op_id;
unsigned int cnt;
- msg = (const struct GNUNET_TESTBED_ShutdownPeersMessage *) message;
LOG_DEBUG ("Received SHUTDOWN_PEERS\n");
- /* Stop and destroy all peers */
+ /* Stop and destroy all peers */
GST_free_mctxq ();
GST_free_occq ();
GST_free_roccq ();
GST_clear_fopcq ();
/* Forward to all slaves which we have started */
op_id = GNUNET_ntohll (msg->operation_id);
- hc = GNUNET_malloc (sizeof (struct HandlerContext_ShutdownPeers));
+ hc = GNUNET_new (struct HandlerContext_ShutdownPeers);
/* FIXME: have a better implementation where we track which slaves are
started by this controller */
for (cnt = 0; cnt < GST_slave_list_size; cnt++)
@@ -1361,33 +1538,32 @@ GST_handle_shutdown_peers (void *cls, struct GNUNET_SERVER_Client *client,
slave = GST_slave_list[cnt];
if (NULL == slave)
continue;
- if (NULL == slave->controller_proc) /* We didn't start the slave */
+ if (NULL == slave->controller_proc) /* We didn't start the slave */
continue;
LOG_DEBUG ("Forwarding SHUTDOWN_PEERS\n");
hc->nslaves++;
- fo_ctxt = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
- GNUNET_SERVER_client_keep (client);
+ fo_ctxt = GNUNET_new (struct ForwardedOperationContext);
fo_ctxt->client = client;
fo_ctxt->operation_id = op_id;
fo_ctxt->cls = hc;
fo_ctxt->type = OP_SHUTDOWN_PEERS;
fo_ctxt->opc =
- GNUNET_TESTBED_forward_operation_msg_ (slave->controller,
- fo_ctxt->operation_id,
- &msg->header,
- shutdown_peers_reply_cb,
- fo_ctxt);
- fo_ctxt->timeout_task =
- GNUNET_SCHEDULER_add_delayed (GST_timeout, &shutdown_peers_timeout_cb,
+ GNUNET_TESTBED_forward_operation_msg_ (slave->controller,
+ fo_ctxt->operation_id,
+ &msg->header,
+ shutdown_peers_reply_cb,
+ fo_ctxt);
+ GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+ fopcq_tail,
fo_ctxt);
- GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fo_ctxt);
}
LOG_DEBUG ("Shutting down peers\n");
GST_destroy_peers ();
if (0 == hc->nslaves)
{
- GST_send_operation_success_msg (client, op_id);
+ GST_send_operation_success_msg (client,
+ op_id);
GNUNET_free (hc);
}
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVICE_client_continue (client);
}