From e05cff45c3a0cc64197962ade380ac57093b6623 Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Wed, 13 Jun 2012 15:23:49 +0000 Subject: [PATCH] -handler for INIT messages in testbed server --- src/testbed/gnunet-service-testbed.c | 89 +++++++++++++++++++++++----- src/testbed/testbed_api.c | 22 +++++-- 2 files changed, 92 insertions(+), 19 deletions(-) diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c index 58639384e..24f5b9b15 100644 --- a/src/testbed/gnunet-service-testbed.c +++ b/src/testbed/gnunet-service-testbed.c @@ -35,6 +35,36 @@ GNUNET_log (kind, __VA_ARGS__) +struct Context +{ + /** + * The client handle associated with this context + */ + struct GNUNET_SERVER_Client *client; + + /** + * Event mask of event to be responded in this context + */ + uint64_t event_mask; + + /** + * Our host id according to this context + */ + uint32_t host_id; +}; + + +/** + * The master context; generated with the first INIT message + */ +static struct Context *master_context; + +/** + * The shutdown task handle + */ +static GNUNET_SCHEDULER_TaskIdentifier shutdown_task_id; + + /** * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_INIT messages * @@ -47,34 +77,60 @@ handle_init (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { - GNUNET_break (0); + const struct GNUNET_TESTBED_Message *msg; + + if (NULL != master_context) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + msg = (const struct GNUNET_TESTBED_Message *) message; + master_context = GNUNET_malloc (sizeof (struct Context)); + master_context->client = client; + master_context->host_id = ntohl (msg->host_id); + master_context->event_mask = GNUNET_ntohll (msg->event_mask); + GNUNET_SERVER_client_keep (client); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Created master context with host ID: %u\n", master_context->host_id); + GNUNET_SERVER_receive_done (client, GNUNET_OK); } /** - * Callback for client disconnect + * Task to clean up and shutdown nicely * * @param cls NULL - * @param client the client which has disconnected + * @param tc the TaskContext from scheduler */ static void -client_disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client) +shutdown_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { - GNUNET_break (0); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down testbed service\n"); + GNUNET_free_non_null (master_context); } /** - * Task to clean up and shutdown nicely + * Callback for client disconnect * * @param cls NULL - * @param tc the TaskContext from scheduler + * @param client the client which has disconnected */ static void -shutdown_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +client_disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client) { - GNUNET_break (0); + if (NULL == master_context) + return; + if (client == master_context->client) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, "Master client disconnected\n"); + GNUNET_SERVER_client_drop (client); + GNUNET_SCHEDULER_cancel (shutdown_task_id); + shutdown_task_id = + GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + } } @@ -87,22 +143,25 @@ shutdown_task (void *cls, */ static void testbed_run (void *cls, - struct GNUNET_SERVER_Handle * server, + struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *cfg) { static const struct GNUNET_SERVER_MessageHandler message_handlers[] = { - {&handle_init, NULL, GNUNET_MESSAGE_TYPE_TESTBED_INIT, 0}, + {&handle_init, NULL, GNUNET_MESSAGE_TYPE_TESTBED_INIT, + sizeof (struct GNUNET_TESTBED_Message)}, {NULL} }; + GNUNET_SERVER_add_handlers (server, message_handlers); GNUNET_SERVER_disconnect_notify (server, &client_disconnect_cb, NULL); - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, - &shutdown_task, - NULL); + shutdown_task_id = + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, + &shutdown_task, + NULL); } diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c index f12ed64fc..7d86d5fd5 100644 --- a/src/testbed/testbed_api.c +++ b/src/testbed/testbed_api.c @@ -82,7 +82,7 @@ struct GNUNET_TESTBED_Controller /** * The helper handle */ - struct GNUNET_HELPER_Handle *h; + struct GNUNET_HELPER_Handle *helper; /** * The controller callback @@ -142,6 +142,7 @@ transmit_ready_notify (void *cls, size_t size, void *buf) struct GNUNET_TESTBED_Controller *c = cls; struct MessageQueue *mq_entry; + c->th = NULL; mq_entry = c->mq_head; GNUNET_assert (NULL != mq_entry); GNUNET_assert (ntohs (mq_entry->msg->size) <= size); @@ -277,9 +278,9 @@ GNUNET_TESTBED_controller_start (const struct GNUNET_CONFIGURATION_Handle *cfg, "gnunet-service-testbed", NULL}; controller = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Controller)); - controller->h = GNUNET_TESTBED_host_run_ (host, binary_argv, + controller->helper = GNUNET_TESTBED_host_run_ (host, binary_argv, &server_mst_cb, controller); - if (NULL == controller->h) + if (NULL == controller->helper) { GNUNET_free (controller); return NULL; @@ -325,7 +326,20 @@ GNUNET_TESTBED_controller_configure_sharing (struct GNUNET_TESTBED_Controller *c void GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_Controller *controller) { - GNUNET_break (0); + struct MessageQueue *mq_entry; + + if (NULL != controller->th) + GNUNET_CLIENT_notify_transmit_ready_cancel (controller->th); + for (mq_entry = controller->mq_head; /* Clear the message queue */ + NULL != mq_entry; mq_entry = controller->mq_head) + { + GNUNET_free (mq_entry->msg); + GNUNET_free (mq_entry); + } + GNUNET_CLIENT_disconnect (controller->client); + GNUNET_HELPER_stop (controller->helper); + GNUNET_CONFIGURATION_destroy (controller->cfg); + GNUNET_free (controller); } -- 2.25.1