From: Sree Harsha Totakura Date: Thu, 5 Jul 2012 21:14:10 +0000 (+0000) Subject: routing controller link messages X-Git-Tag: initial-import-from-subversion-38251~12626 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=8c37520f379651afd01fbb65f66fca17d0cf4ce3;p=oweals%2Fgnunet.git routing controller link messages --- diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c index 4b6fa5f69..7cc822aca 100644 --- a/src/testbed/gnunet-service-testbed.c +++ b/src/testbed/gnunet-service-testbed.c @@ -122,20 +122,36 @@ struct SharedService struct Route { /** - * The forwarding (next hop) host id + * destination host */ - uint32_t next_hop; + uint32_t dest; /** - * The controller handle if we have started the controller at the next hop - * host + * The host destination is reachable thru */ - struct GNUNET_TESTBED_Controller *fcontroller; + uint32_t thru; +}; + + +/** + * Structure representing a connected(directly-linked) controller + */ +struct Slave +{ + /** + * The controller process handle if we had started the controller + */ + struct GNUNET_TESTBED_ControllerProc *controller_proc; /** - * The controller process handle if we started the controller + * The controller handle */ - struct GNUNET_TESTBED_ControllerProc *fcontroller_proc; + struct GNUNET_TESTBED_Controller *controller; + + /** + * The id of the host this controller is running on + */ + uint32_t host_id; }; @@ -154,11 +170,6 @@ enum LCFContextState */ DELEGATED_HOST_REGISTERED, - /** - * The slave host has been registred at the forwarding controller - */ - SLAVE_HOST_REGISTERED, - /** * The context has been finished (may have error) */ @@ -173,20 +184,30 @@ enum LCFContextState struct LCFContext { /** - * The configuration + * The serialized and compressed configuration */ - struct GNUNET_CONFIGURATION_Handle *cfg; + char *sxcfg; /** - * The handle of the controller this request has to be forwarded to + * The gateway which will pass the link message to delegated host */ - struct GNUNET_TESTBED_Controller *fcontroller; + struct Slave *gateway; /** * The host registration handle while registered hosts in this context */ struct GNUNET_TESTBED_HostRegistrationHandle *rhandle; + /** + * The size of the compressed serialized configuration + */ + size_t sxcfg_size; + + /** + * The size of the uncompressed configuration + */ + size_t scfg_size; + /** * Should the delegated host be started by the slave host? */ @@ -201,11 +222,7 @@ struct LCFContext * The delegated host */ uint32_t delegated_host_id; - - /** - * The slave host - */ - uint32_t slave_host_id; + }; @@ -232,29 +249,6 @@ struct LCFContextQueue }; - -/** - * Structure representing a connected(directly-linked) controller - */ -struct Slave -{ - /** - * The controller process handle if we had started the controller - */ - struct GNUNET_TESTBED_ControllerProc *controller_proc; - - /** - * The controller handle - */ - struct GNUNET_TESTBED_Controller *controller; - - /** - * The id of the host this controller is running on - */ - uint32_t host; -}; - - /** * The master context; generated with the first INIT message */ @@ -447,6 +441,25 @@ host_list_add (struct GNUNET_TESTBED_Host *host) } +/** + * Adds a route to the route list + * + * @param route the route to add + */ +static void +route_list_add (struct Route *route) +{ + if (route->dest > route_list_size) + { + route_list_size += LIST_GROW_STEP; + route_list = GNUNET_realloc (route_list, sizeof (struct Route *) + * route_list_size); + } + GNUNET_assert (NULL == route_list[route->dest]); + route_list[route->dest] = route; +} + + /** * Routes message to a host given its host_id * @@ -487,26 +500,19 @@ lcf_proc_cc (void *cls, const char *emsg) { case INIT: if (NULL != emsg) - goto registration_error; + { + LOG (GNUNET_ERROR_TYPE_WARNING, + "Host registration failed with message: %s\n", emsg); + lcf->state = FINISHED; + lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcf); + return; + } lcf->state = DELEGATED_HOST_REGISTERED; lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcf); break; - case DELEGATED_HOST_REGISTERED: - if (NULL != emsg) - goto registration_error; - lcf->state = SLAVE_HOST_REGISTERED; - lcf_proc_task_id = 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; - lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcf); } @@ -528,10 +534,10 @@ lcf_proc_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) case INIT: if (GNUNET_NO == GNUNET_TESTBED_is_host_registered_ (host_list[lcf->delegated_host_id], - lcf->fcontroller)) + lcf->gateway->controller)) { lcf->rhandle = - GNUNET_TESTBED_register_host (lcf->fcontroller, + GNUNET_TESTBED_register_host (lcf->gateway->controller, host_list[lcf->delegated_host_id], lcf_proc_cc, lcf); } @@ -542,35 +548,23 @@ lcf_proc_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } 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; - lcf_proc_task_id = 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); + GNUNET_TESTBED_controller_link_2 (lcf->gateway->controller, + host_list[lcf->delegated_host_id], + host_list[lcf->gateway->host_id], + lcf->sxcfg, lcf->sxcfg_size, + lcf->scfg_size, + lcf->is_subordinate); lcf->state = FINISHED; - case FINISHED: + case FINISHED: lcfq = lcfq_head; - GNUNET_CONFIGURATION_destroy (lcfq->lcf->cfg); - GNUNET_free (lcfq->lcf); + GNUNET_assert (lcfq->lcf == lcf); + GNUNET_free (lcf->sxcfg); + GNUNET_free (lcf); GNUNET_CONTAINER_DLL_remove (lcfq_head, lcfq_tail, lcfq); GNUNET_free (lcfq); if (NULL != lcfq_head) - lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcfq_head->lcf); + lcf_proc_task_id = + GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcfq_head->lcf); } } @@ -802,6 +796,7 @@ handle_link_controllers (void *cls, struct GNUNET_CONFIGURATION_Handle *cfg; struct LCFContextQueue *lcfq; struct Route *route; + struct Route *new_route; char *config; uLongf dest_size; size_t config_size; @@ -845,8 +840,19 @@ handle_link_controllers (void *cls, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } + if (slave_host_id == delegated_host_id) + { + LOG (GNUNET_ERROR_TYPE_WARNING, "Slave and delegated host are same\n"); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + msize -= sizeof (struct GNUNET_TESTBED_ControllerLinkMessage); + config_size = ntohs (msg->config_size); + if (slave_host_id == master_context->host_id) /* Link from us */ { + struct Slave *slave; + if ((delegated_host_id < slave_list_size) && (NULL != slave_list[delegated_host_id])) /* We have already added */ { @@ -854,11 +860,9 @@ handle_link_controllers (void *cls, delegated_host_id); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; - } - config_size = ntohs (msg->config_size); + } config = GNUNET_malloc (config_size); - dest_size = (uLongf) config_size; - msize -= sizeof (struct GNUNET_TESTBED_ControllerLinkMessage); + dest_size = (uLongf) config_size; if (Z_OK != uncompress ((Bytef *) config, &dest_size, (const Bytef *) &msg[1], (uLong) msize)) { @@ -867,13 +871,18 @@ handle_link_controllers (void *cls, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } - GNUNET_assert (config_size == dest_size); + if (config_size == dest_size) + { + LOG (GNUNET_ERROR_TYPE_WARNING, "Uncompressed config size mismatch\n"); + GNUNET_free (config); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + } cfg = GNUNET_CONFIGURATION_create (); /* Free here or in lcfcontext */ if (GNUNET_OK != GNUNET_CONFIGURATION_deserialize (cfg, config, config_size, GNUNET_NO)) { GNUNET_break (0); /* Configuration parsing error */ - GNUNET_break (config); + GNUNET_free (config); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } @@ -884,9 +893,8 @@ handle_link_controllers (void *cls, slave_list = GNUNET_realloc (slave_list, sizeof (struct Slave *) * slave_list_size); } - struct Slave *slave; slave = GNUNET_malloc (sizeof (struct Slave)); - slave->host = delegated_host_id; + slave->host_id = delegated_host_id; slave_list[delegated_host_id] = slave; if (1 == msg->is_subordinate) { @@ -897,62 +905,55 @@ handle_link_controllers (void *cls, GNUNET_TESTBED_controller_connect (cfg, host_list[delegated_host_id], master_context->event_mask, &slave_event_callback, slave); - GNUNET_CONFIGURATION_destroy (cfg); + GNUNET_CONFIGURATION_destroy (cfg); + new_route = GNUNET_malloc (sizeof (struct Route)); + new_route->dest = delegated_host_id; + new_route->thru = master_context->host_id; + route_list_add (new_route); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; } - /* Route the request */ - - - /* If delegated host and slave host are not same we have to forward - towards delegated host */ - if (slave_host_id != delegated_host_id) + /* Route the request */ + if (slave_host_id >= route_list_size) { - 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_assert (GNUNET_SCHEDULER_NO_TASK == lcf_proc_task_id); - GNUNET_CONTAINER_DLL_insert_tail (lcfq_head, lcfq_tail, lcfq); - lcf_proc_task_id = 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); + LOG (GNUNET_ERROR_TYPE_WARNING, "No route towards slave host"); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } - else + while (NULL != (route = route_list[slave_host_id])) { - + if (route->thru == master_context->host_id) + break; + slave_host_id = route->thru; } - 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) + GNUNET_assert (NULL != route); /* because we add routes carefully */ + GNUNET_assert (route->dest < slave_list_size); + GNUNET_assert (NULL != slave_list[route->dest]); + lcfq = GNUNET_malloc (sizeof (struct LCFContextQueue)); + lcfq->lcf = GNUNET_malloc (sizeof (struct LCFContext)); + lcfq->lcf->delegated_host_id = delegated_host_id; + lcfq->lcf->is_subordinate = + (1 == msg->is_subordinate) ? GNUNET_YES : GNUNET_NO; + lcfq->lcf->state = INIT; + lcfq->lcf->gateway = slave_list[route->dest]; + lcfq->lcf->sxcfg_size = msize; + lcfq->lcf->sxcfg = GNUNET_malloc (msize); + lcfq->lcf->scfg_size = config_size; + (void) memcpy (lcfq->lcf->sxcfg, &msg[1], msize); + if (NULL == lcfq_head) { - GNUNET_break (0); /* FIXME: Implement the slave controller - startup */ - } + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == lcf_proc_task_id); + GNUNET_CONTAINER_DLL_insert_tail (lcfq_head, lcfq_tail, lcfq); + lcf_proc_task_id = 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); + new_route = GNUNET_malloc (sizeof (struct Route)); + new_route->dest = delegated_host_id; + new_route->thru = route->dest; + route_list_add (new_route); } @@ -991,8 +992,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct LCFContextQueue *lcfq; - uint32_t host_id; - uint32_t route_id; + uint32_t id; shutdown_task_id = GNUNET_SCHEDULER_NO_TASK; GNUNET_SCHEDULER_shutdown (); @@ -1018,27 +1018,30 @@ shutdown_task (void *cls, GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == lcf_proc_task_id); for (lcfq = lcfq_head; NULL != lcfq; lcfq = lcfq_head) { - GNUNET_CONFIGURATION_destroy (lcfq->lcf->cfg); + GNUNET_free (lcfq->lcf->sxcfg); GNUNET_free (lcfq->lcf); GNUNET_CONTAINER_DLL_remove (lcfq_head, lcfq_tail, lcfq); GNUNET_free (lcfq); } /* Clear host list */ - 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]); + for (id = 0; id < host_list_size; id++) + if (NULL != host_list[id]) + GNUNET_TESTBED_host_destroy (host_list[id]); GNUNET_free_non_null (host_list); /* Clear route list */ - for (route_id = 0; route_id < route_list_size; route_id++) - if (NULL != route_list[route_id]) + for (id = 0; id < route_list_size; id++) + if (NULL != route_list[id]) + GNUNET_free (route_list[id]); + GNUNET_free_non_null (route_list); + /* Clear slave_list */ + for (id = 0; id < slave_list_size; id++) + if (NULL != slave_list[id]) { - if (NULL != route_list[route_id]->fcontroller) - GNUNET_TESTBED_controller_disconnect (route_list[route_id]->fcontroller); - if (NULL != route_list[route_id]->fcontroller_proc) - GNUNET_TESTBED_controller_stop (route_list[route_id]->fcontroller_proc); - GNUNET_free (route_list[route_id]); + GNUNET_assert (NULL != slave_list[id]->controller); + GNUNET_TESTBED_controller_disconnect (slave_list[id]->controller); + if (NULL != slave_list[id]->controller_proc) + GNUNET_TESTBED_controller_stop (slave_list[id]->controller_proc); } - GNUNET_free_non_null (route_list); GNUNET_free_non_null (master_context); }