From 53e453c99bb66db660a37ee9ce375fd213cf10f1 Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Tue, 19 Jun 2012 22:24:51 +0000 Subject: [PATCH] -testbed service reply queue and host success reply --- src/testbed/gnunet-service-testbed.c | 207 +++++++++++++++++++++++++-- src/testbed/testbed_api.c | 2 +- 2 files changed, 199 insertions(+), 10 deletions(-) diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c index 327daf584..1c1dc3583 100644 --- a/src/testbed/gnunet-service-testbed.c +++ b/src/testbed/gnunet-service-testbed.c @@ -30,10 +30,19 @@ #include "testbed.h" #include "gnunet_testbed_service.h" +#include "testbed_api_hosts.h" +/** + * Generic logging + */ #define LOG(kind,...) \ GNUNET_log (kind, __VA_ARGS__) +/** + * Debug logging + */ +#define LOG_DEBUG(...) \ + LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) struct Context { @@ -54,6 +63,34 @@ struct Context }; +/** + * The message queue for sending messages to clients + */ +struct MessageQueue +{ + /** + * The message to be sent + */ + struct GNUNET_MessageHeader *msg; + + /** + * The client to send the message to + */ + struct GNUNET_SERVER_Client *client; + + /** + * next pointer for DLL + */ + struct MessageQueue *next; + + /** + * prev pointer for DLL + */ + struct MessageQueue *prev; +}; + + + /** * Wrapped stdin. */ @@ -69,6 +106,130 @@ static struct Context *master_context; */ static GNUNET_SCHEDULER_TaskIdentifier shutdown_task_id; +/** + * Array of host list + */ +static struct GNUNET_TESTBED_Host **host_list; + +/** + * The size of the host list + */ +static uint32_t host_list_size; + +/** + * The message queue head + */ +static struct MessageQueue *mq_head; + +/** + * The message queue tail + */ +static struct MessageQueue *mq_tail; + +/** + * Current Transmit Handle; NULL if no notify transmit exists currently + */ +struct GNUNET_SERVER_TransmitHandle *transmit_handle; + + +/** + * Function called to notify a client about the connection begin ready to queue + * more data. "buf" will be NULL and "size" zero if the connection was closed + * for writing in the meantime. + * + * @param cls NULL + * @param size number of bytes available in buf + * @param buf where the callee should write the message + * @return number of bytes written to buf + */ +static size_t +transmit_ready_notify (void *cls, size_t size, void *buf) +{ + struct MessageQueue *mq_entry; + + transmit_handle = NULL; + mq_entry = mq_head; + GNUNET_assert (NULL != mq_entry); + if (0 == size) + return 0; + GNUNET_assert (ntohs (mq_entry->msg->size) <= size); + size = ntohs (mq_entry->msg->size); + memcpy (buf, mq_entry->msg, size); + GNUNET_free (mq_entry->msg); + GNUNET_CONTAINER_DLL_remove (mq_head, mq_tail, mq_entry); + GNUNET_free (mq_entry); + mq_entry = mq_head; + if (NULL != mq_entry) + transmit_handle = + GNUNET_SERVER_notify_transmit_ready (mq_entry->client, + ntohs (mq_entry->msg->size), + GNUNET_TIME_UNIT_FOREVER_REL, + &transmit_ready_notify, NULL); + return size; +} + + +/** + * Queues a message in send queue for sending to the service + * + * @param controller the handle to the controller + * @param msg the message to queue + */ +static void +queue_message (struct GNUNET_SERVER_Client *client, + struct GNUNET_MessageHeader *msg) +{ + struct MessageQueue *mq_entry; + uint16_t type; + uint16_t size; + + type = ntohs (msg->type); + size = ntohs (msg->size); + GNUNET_assert ((GNUNET_MESSAGE_TYPE_TESTBED_INIT <= type) && + (GNUNET_MESSAGE_TYPE_TESTBED_MAX > type)); + mq_entry = GNUNET_malloc (sizeof (struct MessageQueue)); + mq_entry->msg = msg; + mq_entry->client = client; + LOG_DEBUG ( "Queueing message of type %u, size %u for sending\n", type, + ntohs (msg->size)); + GNUNET_CONTAINER_DLL_insert_tail (mq_head, mq_tail, mq_entry); + if (NULL == transmit_handle) + transmit_handle = + GNUNET_SERVER_notify_transmit_ready (client, size, + GNUNET_TIME_UNIT_FOREVER_REL, + &transmit_ready_notify, NULL); +} + + +/** + * Function to add a host to the current list of known hosts + * + * @param host the host to add + * @return GNUNET_OK on success; GNUNET_SYSERR on failure due to host-id + * already in use + */ +static int +host_list_add (struct GNUNET_TESTBED_Host *host) +{ + uint32_t host_id; + + host_id = GNUNET_TESTBED_host_get_id_ (host); + if (host_list_size <= host_id) + { + host_list = GNUNET_realloc (host_list, + sizeof (struct GNUNET_TESTBED_Host *) + * (host_id + 10)); + host_list_size += (host_id + 10); + } + if (NULL != host_list[host_id]) + { + LOG_DEBUG ("A host with id: %u already exists\n", host_id); + return GNUNET_SYSERR; + } + host_list[host_id] = host; + return GNUNET_OK; +} + /** * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_INIT messages @@ -83,6 +244,7 @@ handle_init (void *cls, const struct GNUNET_MessageHeader *message) { const struct GNUNET_TESTBED_InitMessage *msg; + struct GNUNET_TESTBED_Host *host; if (NULL != master_context) { @@ -94,10 +256,13 @@ handle_init (void *cls, master_context = GNUNET_malloc (sizeof (struct Context)); master_context->client = client; master_context->host_id = ntohl (msg->host_id); + host = GNUNET_TESTBED_host_create_with_id (master_context->host_id, + NULL, NULL, 0); + host_list_add (host); 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); + LOG_DEBUG ("Created master context with host ID: %u\n", + master_context->host_id); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -116,10 +281,14 @@ handle_addhost (void *cls, { struct GNUNET_TESTBED_Host *host; const struct GNUNET_TESTBED_AddHostMessage *msg; + struct GNUNET_TESTBED_HostConfirmedMessage *reply; char *username; char *hostname; + char *emsg; + uint32_t host_id; uint16_t username_length; uint16_t hostname_length; + uint16_t reply_size; msg = (const struct GNUNET_TESTBED_AddHostMessage *) message; username_length = ntohs (msg->user_name_length); @@ -141,13 +310,28 @@ handle_addhost (void *cls, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } - host = GNUNET_TESTBED_host_create (hostname, username, ntohs - (msg->ssh_port)); - /* Store host in a hashmap? But the host_id will be different */ - /* hashmap? maybe array? 4-8 bytes/host and O(1) lookup vs. - > 80 bytes for hash map with slightly worse lookup; only - if we really get a tiny fraction of the hosts, the hash - map would result in any savings... (GNUNET_array_grow) */ + host_id = ntohl (msg->host_id); + LOG_DEBUG ("Received ADDHOST message\n"); + LOG_DEBUG ("-------host id: %u\n", host_id); + if (NULL != hostname) LOG_DEBUG ("-------hostname: %s\n", hostname); + if (NULL != username) LOG_DEBUG ("-------username: %s\n", username); + LOG_DEBUG ("-------ssh port: %u\n", ntohs (msg->ssh_port)); + host = GNUNET_TESTBED_host_create_with_id (host_id, hostname, username, + ntohs (msg->ssh_port)); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + if (GNUNET_OK == host_list_add (host)) + return; + /* We are unable to add a host */ + emsg = "A host exists with given host-id"; + GNUNET_TESTBED_host_destroy (host); + reply_size = sizeof (struct GNUNET_TESTBED_HostConfirmedMessage) + + strlen (emsg) + 1; + reply = GNUNET_malloc (reply_size); + reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_ADDHOSTSUCCESS); + reply->header.size = htons (reply_size); + reply->host_id = htonl (host_id); + memcpy (&reply[1], emsg, strlen (emsg) + 1); + queue_message (client, (struct GNUNET_MessageHeader *) reply); } @@ -161,6 +345,8 @@ static void shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { + uint32_t host_id; + shutdown_task_id = GNUNET_SCHEDULER_NO_TASK; GNUNET_SCHEDULER_shutdown (); LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down testbed service\n"); @@ -169,6 +355,9 @@ shutdown_task (void *cls, GNUNET_DISK_file_close (fh); fh = NULL; } + for (host_id = 0; host_id < host_list_size; host_id++) + if (NULL != host_list[host_id]) + GNUNET_TESTBED_host_destroy (host_list[host_id]); GNUNET_free_non_null (master_context); master_context = NULL; } diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c index 3f49890c4..fc4b86603 100644 --- a/src/testbed/testbed_api.c +++ b/src/testbed/testbed_api.c @@ -229,7 +229,7 @@ queue_message (struct GNUNET_TESTBED_Controller *controller, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &transmit_ready_notify, controller); - } +} /** -- 2.25.1