From 9279bfb981fff618746e93a2c5d1c1672f5d464a Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Sat, 7 Jul 2012 16:12:09 +0000 Subject: [PATCH] -peer create message handler --- src/testbed/Makefile.am | 1 + src/testbed/gnunet-service-testbed.c | 216 ++++++++++++++++++++++++--- src/testbed/testbed.h | 5 + src/testbed/testbed_api_peers.c | 1 + 4 files changed, 199 insertions(+), 24 deletions(-) diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am index 8a3912f5b..012f35e20 100644 --- a/src/testbed/Makefile.am +++ b/src/testbed/Makefile.am @@ -21,6 +21,7 @@ gnunet_service_testbed_SOURCES = \ gnunet-service-testbed.c gnunet_service_testbed_LDADD = $(XLIB) \ $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/testbed/libgnunettestbed.la \ $(LTLIBINTL) -lz gnunet_service_testbed_DEPENDENCIES = \ diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c index a89ae405c..d9eb9d617 100644 --- a/src/testbed/gnunet-service-testbed.c +++ b/src/testbed/gnunet-service-testbed.c @@ -32,6 +32,7 @@ #include "testbed.h" #include "gnunet_testbed_service.h" #include "testbed_api_hosts.h" +#include "gnunet_testing_lib-new.h" /** * Generic logging @@ -249,6 +250,30 @@ struct LCFContextQueue }; +/** + * A locally started peer + */ +struct Peer +{ + /** + * The peer handle from testing API + */ + struct GNUNET_TESTING_Peer *peer; + + /** + * The modified (by GNUNET_TESTING_peer_configure) configuration this peer is + * configured with + */ + struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * Our local reference id for this peer + */ + uint32_t id; + +}; + + /** * The master context; generated with the first INIT message */ @@ -307,6 +332,11 @@ static struct Route **route_list; */ static struct Slave **slave_list; +/** + * A list of peers we own locally + */ +static struct Peer **peer_list; + /** * The hashmap of shared services */ @@ -327,6 +357,11 @@ static uint32_t route_list_size; */ static uint32_t slave_list_size; +/** + * The size of the peer list + */ +static uint32_t peer_list_size; + /*********/ /* Tasks */ /*********/ @@ -341,6 +376,15 @@ static GNUNET_SCHEDULER_TaskIdentifier lcf_proc_task_id; */ static GNUNET_SCHEDULER_TaskIdentifier shutdown_task_id; +/******************/ +/* Testing System */ +/******************/ + +/** + * Handle to the local testing system - for starting peers locally + */ +static struct GNUNET_TESTING_System *test_system; + /** * Function called to notify a client about the connection begin ready to queue @@ -411,6 +455,24 @@ queue_message (struct GNUNET_SERVER_Client *client, } +/** + * Similar to GNUNET_realloc; however clears tail part of newly allocated memory + * + * @param ptr the memory block to realloc + * @param size the size of ptr + * @param new_size the size to which ptr has to be realloc'ed + * @return the newly reallocated memory block + */ +static void * +TESTBED_realloc (void *ptr, size_t size, size_t new_size) +{ + ptr = GNUNET_realloc (ptr, new_size); + if (new_size > size) + ptr = memset (ptr + size, 0, new_size - size); + return ptr; +} + + /** * Function to add a host to the current list of known hosts * @@ -422,18 +484,16 @@ static int host_list_add (struct GNUNET_TESTBED_Host *host) { uint32_t host_id; - uint32_t new_size; host_id = GNUNET_TESTBED_host_get_id_ (host); if (host_list_size <= host_id) { - new_size = host_list_size + LIST_GROW_STEP; - host_list = GNUNET_realloc (host_list, - sizeof (struct GNUNET_TESTBED_Host *) - * new_size); - memset (&host_list[host_list_size], 0, - sizeof (struct Slave *) * LIST_GROW_STEP); - host_list_size = new_size; + host_list = + TESTBED_realloc (host_list, + sizeof (struct GNUNET_TESTBED_Host *) * host_list_size, + sizeof (struct GNUNET_TESTBED_Host *) * + (host_list_size + LIST_GROW_STEP)); + host_list_size += LIST_GROW_STEP; } if (NULL != host_list[host_id]) { @@ -453,16 +513,14 @@ host_list_add (struct GNUNET_TESTBED_Host *host) static void route_list_add (struct Route *route) { - uint32_t new_size; - if (route->dest >= route_list_size) { - new_size = route_list_size + LIST_GROW_STEP; - route_list = GNUNET_realloc (route_list, sizeof (struct Route *) - * new_size); - memset (&route_list[route_list_size], 0, - sizeof (struct Slave *) * LIST_GROW_STEP); - route_list_size = new_size; + route_list = + TESTBED_realloc (route_list, + sizeof (struct Route *) * route_list_size, + sizeof (struct Route *) * + (route_list_size + LIST_GROW_STEP)); + route_list_size += LIST_GROW_STEP; } GNUNET_assert (NULL == route_list[route->dest]); route_list[route->dest] = route; @@ -477,22 +535,40 @@ route_list_add (struct Route *route) static void slave_list_add (struct Slave *slave) { - uint32_t new_size; - if (slave->host_id >= slave_list_size) { - new_size = slave_list_size + LIST_GROW_STEP; - slave_list = GNUNET_realloc (slave_list, sizeof (struct Slave *) - * new_size); - memset (&slave_list[slave_list_size], 0, - sizeof (struct Slave *) * LIST_GROW_STEP); - slave_list_size = new_size; + slave_list = TESTBED_realloc (slave_list, + sizeof (struct Slave *) *slave_list_size, + sizeof (struct Slave *) * + (slave_list_size) + LIST_GROW_STEP); + slave_list_size += LIST_GROW_STEP; } GNUNET_assert (NULL == slave_list[slave->host_id]); slave_list[slave->host_id] = slave; } +/** + * Adds a peer to the peer array + * + * @param route the route to add + */ +static void +peer_list_add (struct Peer *peer) +{ + if (peer->id >= peer_list_size) + { + peer_list = TESTBED_realloc (peer_list, + sizeof (struct Peer *) *peer_list_size, + sizeof (struct Peer *) * + (peer_list_size) + LIST_GROW_STEP); + peer_list_size += LIST_GROW_STEP; + } + GNUNET_assert (NULL == peer_list[peer->id]); + peer_list[peer->id] = peer; +} + + /** * Routes message to a host given its host_id * @@ -749,6 +825,7 @@ int ss_exists_iterator (void *cls, return GNUNET_YES; } + /** * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_ADDHOST messages * @@ -992,6 +1069,93 @@ handle_link_controllers (void *cls, } +/** + * Handler for GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages + * + * @param cls NULL + * @param client identification of the client + * @param message the actual message + */ +static void +handle_peer_create (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + const struct GNUNET_TESTBED_PeerCreateMessage *msg; + struct GNUNET_CONFIGURATION_Handle *cfg; + char *config; + size_t dest_size; + uint16_t msize; + uint16_t config_size; + + + 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; + if (ntohs (msg->host_id) == master_context->host_id) + { + struct Peer *peer; + char *emsg; + + /* We are responsidble for this peer */ + msize -= sizeof (struct GNUNET_TESTBED_PeerCreateMessage); + config_size = ntohl (msg->config_size); + config = GNUNET_malloc (msg->config_size); + if (Z_OK != uncompress ((Bytef *) config, (uLongf *) &dest_size, + (const Bytef *) &msg[1], (uLong) msize)) + { + GNUNET_break (0); /* uncompression error */ + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + if (config_size == dest_size) + { + GNUNET_break (0);/* Uncompressed config size mismatch */ + GNUNET_free (config); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + cfg = GNUNET_CONFIGURATION_create (); + if (GNUNET_OK != GNUNET_CONFIGURATION_deserialize (cfg, config, config_size, + GNUNET_NO)) + { + GNUNET_break (0); /* Configuration parsing error */ + GNUNET_free (config); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + GNUNET_free (config); + peer = GNUNET_malloc (sizeof (struct Peer)); + peer->cfg = cfg; + peer->id = ntohl (msg->peer_id); + peer->peer = GNUNET_TESTING_peer_configure (test_system, peer->cfg, + peer->id, + NULL /* Peer id */, + &emsg); + if (NULL == peer->peer) + { + LOG (GNUNET_ERROR_TYPE_WARNING, "Configuring peer failed: %s\n", emsg); + GNUNET_free (emsg); + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + peer_list_add (peer); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + + /* Forward the peer to other host */ + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} + + /** * Iterator over hash map entries. * @@ -1035,6 +1199,7 @@ shutdown_task (void *cls, (void) GNUNET_CONTAINER_multihashmap_iterate (ss_map, &ss_map_free_iterator, NULL); GNUNET_CONTAINER_multihashmap_destroy (ss_map); + GNUNET_TESTING_system_destroy (test_system, GNUNET_YES); if (NULL != fh) { GNUNET_DISK_file_close (fh); @@ -1127,6 +1292,7 @@ testbed_run (void *cls, GNUNET_MESSAGE_TYPE_TESTBED_SERVICESHARE, 0}, {&handle_link_controllers, NULL, GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS, 0}, + {&handle_peer_create, NULL, GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER, 0}, {NULL} }; @@ -1136,6 +1302,8 @@ testbed_run (void *cls, &client_disconnect_cb, NULL); ss_map = GNUNET_CONTAINER_multihashmap_create (5); + test_system = GNUNET_TESTING_system_create ("testbed_peers", NULL); + fh = GNUNET_DISK_get_handle_from_native (stdin); if (NULL == fh) shutdown_task_id = diff --git a/src/testbed/testbed.h b/src/testbed/testbed.h index 70c921a9f..fff76f2ec 100644 --- a/src/testbed/testbed.h +++ b/src/testbed/testbed.h @@ -207,6 +207,11 @@ struct GNUNET_TESTBED_PeerCreateMessage */ uint32_t peer_id GNUNET_PACKED; + /** + * Size of the uncompressed configuration + */ + uint32_t config_size GNUNET_PACKED; + /* followed by serialized peer configuration; gzip'ed configuration file in INI format */ diff --git a/src/testbed/testbed_api_peers.c b/src/testbed/testbed_api_peers.c index 1ec827e37..844510cda 100644 --- a/src/testbed/testbed_api_peers.c +++ b/src/testbed/testbed_api_peers.c @@ -156,6 +156,7 @@ GNUNET_TESTBED_peer_create_with_id_ (uint32_t unique_id, msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER); msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (peer->host)); msg->peer_id = htonl (peer->unique_id); + msg->config_size = htonl (c_size); GNUNET_TESTBED_queue_message (controller, (struct GNUNET_MessageHeader *) msg); return peer; -- 2.25.1