From 640ff05da5015bdf48bed436eb617d42528a664c Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Tue, 3 Jul 2012 13:14:15 +0000 Subject: [PATCH] -LCFContext --- src/testbed/gnunet-service-testbed.c | 275 +++++++++++++++++++++++++-- src/testbed/testbed_api.c | 2 +- src/testbed/testbed_api_hosts.c | 70 ++++++- src/testbed/testbed_api_hosts.h | 2 +- 4 files changed, 324 insertions(+), 25 deletions(-) diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c index 63d28d97b..5c95a9a4f 100644 --- a/src/testbed/gnunet-service-testbed.c +++ b/src/testbed/gnunet-service-testbed.c @@ -119,20 +119,108 @@ struct SharedService struct Route { /** - * The destination host + * The forwarding (next hop) host id */ - const struct GNUNET_TESTBED_Host *dest; + uint32_t next_hop; /** - * The forwarding (next hop) host + * The controller handle if we have started the controller at the next hop + * host */ - const struct GNUNET_TESTBED_Host *fhost; + struct GNUNET_TESTBED_Controller *fcontroller; +}; + +/** + * States of LCFContext + */ +enum LCFContextState + { + /** + * The Context has been initialized; Nothing has been done on it + */ + INIT, + + /** + * Delegated host has been registered at the forwarding controller + */ + DELEGATED_HOST_REGISTERED, + + /** + * The slave host has been registred at the forwarding controller + */ + SLAVE_HOST_REGISTERED, + + /** + * The context has been finished (may have error) + */ + FINISHED + + }; + + +/** + * Link controllers request forwarding context + */ +struct LCFContext +{ /** - * The controller handle if we have started the controller at the next hop - * host + * The configuration + */ + struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * The handle of the controller this request has to be forwarded to */ struct GNUNET_TESTBED_Controller *fcontroller; + + /** + * The host registration handle while registered hosts in this context + */ + struct GNUNET_TESTBED_HostRegistrationHandle *rhandle; + + /** + * Should the delegated host be started by the slave host? + */ + int is_subordinate; + + /** + * The state of this context + */ + enum LCFContextState state; + + /** + * The delegated host + */ + uint32_t delegated_host_id; + + /** + * The slave host + */ + uint32_t slave_host_id; + +}; + + +/** + * Structure of a queue entry in LCFContext request queue + */ +struct LCFContextQueue +{ + /** + * The LCFContext + */ + struct LCFContext *lcf; + + /** + * Head prt for DLL + */ + struct LCFContextQueue *next; + + /** + * Tail ptr for DLL + */ + struct LCFContextQueue *prev; }; @@ -181,6 +269,16 @@ static struct MessageQueue *mq_head; */ static struct MessageQueue *mq_tail; +/** + * The head for the LCF queue + */ +static struct LCFContextQueue *lcfq_head; + +/** + * The tail for the LCF queue + */ +static struct LCFContextQueue *lcfq_tail; + /** * Current Transmit Handle; NULL if no notify transmit exists currently */ @@ -304,6 +402,120 @@ route_message (uint32_t host_id, const struct GNUNET_MessageHeader *msg) } +/** + * The Link Controller forwarding task + * + * @param cls the LCFContext + * @param tc the Task context from scheduler + */ +static void +lcf_proc_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); + + +/** + * Completion callback for host registrations while forwarding Link Controller messages + * + * @param cls the LCFContext + * @param emsg the error message; NULL if host registration is successful + */ +static void +lcf_proc_cc (void *cls, const char *emsg) +{ + struct LCFContext *lcf = cls; + + lcf->rhandle = NULL; + switch (lcf->state) + { + case INIT: + if (NULL != emsg) + goto registration_error; + lcf->state = DELEGATED_HOST_REGISTERED; + (void) GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcf); + break; + case DELEGATED_HOST_REGISTERED: + if (NULL != emsg) + goto registration_error; + lcf->state = SLAVE_HOST_REGISTERED; + (void) GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcf); + break; + default: + GNUNET_assert (0); /* Shouldn't reach here */ + } + return; + + registration_error: + LOG (GNUNET_ERROR_TYPE_WARNING, + "Host registration failed with message: %s\n", emsg); + lcf->state = FINISHED; + (void) GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcf); +} + + +/** + * The Link Controller forwarding task + * + * @param cls the LCFContext + * @param tc the Task context from scheduler + */ +static void +lcf_proc_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct LCFContext *lcf = cls; + struct LCFContextQueue *lcfq; + + switch (lcf->state) + { + case INIT: + if (GNUNET_NO == + GNUNET_TESTBED_is_host_registered_ (host_list[lcf->delegated_host_id], + lcf->fcontroller)) + { + lcf->rhandle = + GNUNET_TESTBED_register_host (lcf->fcontroller, + host_list[lcf->delegated_host_id], + lcf_proc_cc, lcf); + } + else + { + lcf->state = DELEGATED_HOST_REGISTERED; + (void) GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcf); + } + break; + case DELEGATED_HOST_REGISTERED: + if (GNUNET_NO == + GNUNET_TESTBED_is_host_registered_ (host_list[lcf->slave_host_id], + lcf->fcontroller)) + { + lcf->rhandle = + GNUNET_TESTBED_register_host (lcf->fcontroller, + host_list[lcf->slave_host_id], + lcf_proc_cc, lcf); + } + else + { + lcf->state = SLAVE_HOST_REGISTERED; + (void) GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcf); + } + break; + case SLAVE_HOST_REGISTERED: + GNUNET_TESTBED_controller_link (lcf->fcontroller, + host_list[lcf->delegated_host_id], + host_list[lcf->slave_host_id], + lcf->cfg, lcf->is_subordinate); + lcf->state = FINISHED; + break; + case FINISHED: + lcfq = lcfq_head; + GNUNET_CONFIGURATION_destroy (lcfq->lcf->cfg); + GNUNET_free (lcfq->lcf); + GNUNET_CONTAINER_DLL_remove (lcfq_head, lcfq_tail, lcfq); + GNUNET_free (lcfq); + if (NULL != lcfq_head) + (void) GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcfq_head->lcf); + } +} + + /** * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_INIT messages * @@ -514,6 +726,8 @@ handle_link_controllers (void *cls, { const struct GNUNET_TESTBED_ControllerLinkMessage *msg; struct GNUNET_CONFIGURATION_Handle *cfg; + struct LCFContextQueue *lcfq; + struct Route *route; char *config; uLongf dest_size; size_t config_size; @@ -537,14 +751,6 @@ handle_link_controllers (void *cls, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } - if ((delegated_host_id < route_list_size) && - (NULL != route_list[delegated_host_id])) - { - LOG (GNUNET_ERROR_TYPE_WARNING, - "Delegated host has already been linked\n"); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } if ((delegated_host_id >= host_list_size) || (NULL == host_list[delegated_host_id])) { @@ -559,6 +765,7 @@ handle_link_controllers (void *cls, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } + config_size = ntohs (msg->config_size); config = GNUNET_malloc (config_size); dest_size = (uLongf) config_size; @@ -582,7 +789,45 @@ handle_link_controllers (void *cls, return; } GNUNET_free (config); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + + /* If delegated host and slave host are not same we have to forward + towards delegated host */ + if (slave_host_id != delegated_host_id) + { + if ((slave_host_id >= route_list_size) || + (NULL == (route = route_list[slave_host_id])) || + (NULL == route->fcontroller)) + { + LOG (GNUNET_ERROR_TYPE_WARNING, "Not route towards slave host"); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + if (slave_host_id == route->next_hop) /* Slave directly connected */ + { + /* Then make slave host and delegated host same so that slave + will startup directly link to the delegated host */ + slave_host_id = delegated_host_id; + } + lcfq = GNUNET_malloc (sizeof (struct LCFContextQueue)); + lcfq->lcf = GNUNET_malloc (sizeof (struct LCFContext)); + lcfq->lcf->delegated_host_id = delegated_host_id; + lcfq->lcf->slave_host_id = slave_host_id; + lcfq->lcf->is_subordinate = + (1 == msg->is_subordinate) ? GNUNET_YES : GNUNET_NO; + lcfq->lcf->state = INIT; + lcfq->lcf->fcontroller = route->fcontroller; + lcfq->lcf->cfg = cfg; + if (NULL == lcfq_head) + { + GNUNET_CONTAINER_DLL_insert_tail (lcfq_head, lcfq_tail, lcfq); + (void) GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcfq); + } + else + GNUNET_CONTAINER_DLL_insert_tail (lcfq_head, lcfq_tail, lcfq); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + GNUNET_SERVER_receive_done (client, GNUNET_OK); /* If we are not the slave controller then we have to route the request towards the slave controller */ if (1 == msg->is_subordinate) diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c index 6e9fc491f..c61f10563 100644 --- a/src/testbed/testbed_api.c +++ b/src/testbed/testbed_api.c @@ -255,7 +255,7 @@ handle_addhostconfirm (struct GNUNET_TESTBED_Controller *c, if (sizeof (struct GNUNET_TESTBED_HostConfirmedMessage) == msg_size) { LOG_DEBUG ("Host %u successfully registered\n", ntohl (msg->host_id)); - GNUNET_TESTBED_mark_host_as_registered_ (rh->host, c); + GNUNET_TESTBED_mark_host_registered_at_ (rh->host, c); rh->cc (rh->cc_cls, NULL); GNUNET_free (rh); return GNUNET_OK; diff --git a/src/testbed/testbed_api_hosts.c b/src/testbed/testbed_api_hosts.c index 3df6e14fe..6c0877cea 100644 --- a/src/testbed/testbed_api_hosts.c +++ b/src/testbed/testbed_api_hosts.c @@ -33,7 +33,26 @@ #include "gnunet_hello_lib.h" #include "gnunet_container_lib.h" +/** + * A list entry for registered controllers list + */ +struct RegisteredController +{ + /** + * The controller at which this host is registered + */ + const struct GNUNET_TESTBED_Controller *controller; + + /** + * The next ptr for DLL + */ + struct RegisteredController *next; + /** + * The prev ptr for DLL + */ + struct RegisteredController *prev; +}; /** * Opaque handle to a host running experiments managed by the testing framework. @@ -64,9 +83,14 @@ struct GNUNET_TESTBED_Host const char *username; /** - * The controller at which this host is registered + * The head for the list of controllers where this host is registered */ - const struct GNUNET_TESTBED_Controller *controller; + struct RegisteredController *rc_head; + + /** + * The tail for the list of controllers where this host is registered + */ + struct RegisteredController *rc_tail; /** * Global ID we use to refer to a host on the network @@ -261,7 +285,15 @@ GNUNET_TESTBED_hosts_load_from_file (const char *filename, void GNUNET_TESTBED_host_destroy (struct GNUNET_TESTBED_Host *host) { - GNUNET_CONTAINER_DLL_remove (host_list_head, host_list_tail, host); + struct RegisteredController *rc; + + GNUNET_CONTAINER_DLL_remove (host_list_head, host_list_tail, host); + /* clear registered controllers list */ + for (rc=host->rc_head; NULL != rc; rc=host->rc_head) + { + GNUNET_CONTAINER_DLL_remove (host->rc_head, host->rc_tail, rc); + GNUNET_free (rc); + } GNUNET_free (host); } @@ -389,11 +421,24 @@ GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle) * @param controller the controller at which this host is registered */ void -GNUNET_TESTBED_mark_host_as_registered_ (struct GNUNET_TESTBED_Host *host, +GNUNET_TESTBED_mark_host_registered_at_ (struct GNUNET_TESTBED_Host *host, const struct GNUNET_TESTBED_Controller - *controller) + * const controller) { - host->controller = controller; + struct RegisteredController *rc; + + for (rc=host->rc_head; NULL != rc; rc=rc->next) + { + if (controller == rc->controller) /* already registered at controller */ + { + GNUNET_break (0); + return; + } + } + rc = GNUNET_malloc (sizeof (struct RegisteredController)); + rc->controller = controller; + //host->controller = controller; + GNUNET_CONTAINER_DLL_insert_tail (host->rc_head, host->rc_tail, rc); } @@ -407,9 +452,18 @@ GNUNET_TESTBED_mark_host_as_registered_ (struct GNUNET_TESTBED_Host *host, int GNUNET_TESTBED_is_host_registered_ (const struct GNUNET_TESTBED_Host *host, const struct GNUNET_TESTBED_Controller - *controller) + *const controller) { - return (controller == host->controller) ? GNUNET_YES : GNUNET_NO; + struct RegisteredController *rc; + + for (rc=host->rc_head; NULL != rc; rc=rc->next) + { + if (controller == rc->controller) /* already registered at controller */ + { + return GNUNET_YES; + } + } + return GNUNET_NO; } diff --git a/src/testbed/testbed_api_hosts.h b/src/testbed/testbed_api_hosts.h index c941608f4..1eab19363 100644 --- a/src/testbed/testbed_api_hosts.h +++ b/src/testbed/testbed_api_hosts.h @@ -132,7 +132,7 @@ GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle); * @param controller the controller at which this host is registered */ void -GNUNET_TESTBED_mark_host_as_registered_ (struct GNUNET_TESTBED_Host *host, +GNUNET_TESTBED_mark_host_registered_at_ (struct GNUNET_TESTBED_Host *host, const struct GNUNET_TESTBED_Controller *controller); -- 2.25.1