X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftestbed%2Fgnunet-service-testbed_links.c;h=a2692e8a6f6625c61c40fc5e0579bac3c72f5c2e;hb=29e6158507a0758192075ac6ece7ba8e75ddc49a;hp=d34d0c040d8b8d4148dfd6317dcd493b5efa278d;hpb=6db7b23f0be85c8fc263cb8380cb9a3d495be75a;p=oweals%2Fgnunet.git diff --git a/src/testbed/gnunet-service-testbed_links.c b/src/testbed/gnunet-service-testbed_links.c index d34d0c040..a2692e8a6 100644 --- a/src/testbed/gnunet-service-testbed_links.c +++ b/src/testbed/gnunet-service-testbed_links.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2008--2013 Christian Grothoff (and other contributing authors) + Copyright (C) 2008--2013 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -14,8 +14,8 @@ You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /** @@ -92,13 +92,13 @@ struct LCFContext /** * The timeout task */ - GNUNET_SCHEDULER_TaskIdentifier timeout_task; + struct GNUNET_SCHEDULER_Task * timeout_task; /** * The id of the operation which created this context */ uint64_t operation_id; - + /** * should the slave controller start the delegated controller? */ @@ -186,7 +186,7 @@ struct Neighbour * The controller handle */ struct GNUNET_TESTBED_Controller *controller; - + /** * Operation handle for opening a lateral connection to another controller. * Will be NULL if the slave controller is started by this controller @@ -206,7 +206,7 @@ struct Neighbour /** * Task id for the task to call notifications from the notification list */ - GNUNET_SCHEDULER_TaskIdentifier notify_task; + struct GNUNET_SCHEDULER_Task * notify_task; /** * How many references are present currently to this neighbour's connection @@ -217,11 +217,11 @@ struct Neighbour * Is the conn_op inactivated? */ unsigned int inactive; - + /** * The id of the host this controller is running on */ - uint32_t host_id; + uint32_t host_id; }; @@ -256,7 +256,7 @@ struct NeighbourConnectCtxt * The neighbour to whom connection should be made */ struct Neighbour *n; - + /** * The client requesting the connection */ @@ -265,7 +265,7 @@ struct NeighbourConnectCtxt /** * Task to be run upon timeout */ - GNUNET_SCHEDULER_TaskIdentifier timeout_task; + struct GNUNET_SCHEDULER_Task * timeout_task; /** * The notification handle associated with the neighbour's connection request @@ -317,7 +317,7 @@ static struct LCFContextQueue *lcfq_tail; /** * The lcf_task handle */ -static GNUNET_SCHEDULER_TaskIdentifier lcf_proc_task_id; +static struct GNUNET_SCHEDULER_Task * lcf_proc_task_id; /** * The size of the route list @@ -379,7 +379,7 @@ void GST_route_list_clear () { unsigned int id; - + for (id = 0; id < route_list_size; id++) if (NULL != route_list[id]) GNUNET_free (route_list[id]); @@ -419,52 +419,79 @@ reghost_free_iterator (void *cls, const struct GNUNET_HashCode *key, } +/** + * Kill a #Slave object + * + * @param slave the #Slave object + */ +static void +kill_slave (struct Slave *slave) +{ + struct HostRegistration *hr_entry; + + while (NULL != (hr_entry = slave->hr_dll_head)) + { + GNUNET_CONTAINER_DLL_remove (slave->hr_dll_head, slave->hr_dll_tail, + hr_entry); + GNUNET_free (hr_entry); + } + if (NULL != slave->rhandle) + GNUNET_TESTBED_cancel_registration (slave->rhandle); + GNUNET_assert (GNUNET_SYSERR != + GNUNET_CONTAINER_multihashmap_iterate (slave->reghost_map, + reghost_free_iterator, + slave)); + GNUNET_CONTAINER_multihashmap_destroy (slave->reghost_map); + if (NULL != slave->controller) + GNUNET_TESTBED_controller_disconnect (slave->controller); + if (NULL != slave->controller_proc) + { + LOG_DEBUG ("Stopping a slave\n"); + GNUNET_TESTBED_controller_kill_ (slave->controller_proc); + } +} + + +/** + * Destroy a #Slave object + * + * @param slave the #Slave object + */ +static void +destroy_slave (struct Slave *slave) +{ + if (NULL != slave->controller_proc) + { + GNUNET_TESTBED_controller_destroy_ (slave->controller_proc); + LOG_DEBUG ("Slave stopped\n"); + } + GST_slave_list[slave->host_id] = NULL; + GNUNET_free (slave); +} + + /** * Cleans up the slave list */ void GST_slave_list_clear () { - struct HostRegistration *hr_entry; - struct GNUNET_TESTBED_ControllerProc *cproc; + struct Slave *slave; unsigned int id; for (id = 0; id < GST_slave_list_size; id++) { - if (NULL == GST_slave_list[id]) + slave = GST_slave_list[id]; + if (NULL == slave) continue; - while (NULL != (hr_entry = GST_slave_list[id]->hr_dll_head)) - { - GNUNET_CONTAINER_DLL_remove (GST_slave_list[id]->hr_dll_head, - GST_slave_list[id]->hr_dll_tail, hr_entry); - GNUNET_free (hr_entry); - } - if (NULL != GST_slave_list[id]->rhandle) - GNUNET_TESTBED_cancel_registration (GST_slave_list[id]->rhandle); - (void) - GNUNET_CONTAINER_multihashmap_iterate (GST_slave_list - [id]->reghost_map, - reghost_free_iterator, - GST_slave_list[id]); - GNUNET_CONTAINER_multihashmap_destroy (GST_slave_list[id]->reghost_map); - if (NULL != GST_slave_list[id]->controller) - GNUNET_TESTBED_controller_disconnect (GST_slave_list[id]->controller); - if (NULL != (cproc = GST_slave_list[id]->controller_proc)) - { - LOG_DEBUG ("Stopping a slave\n"); - GNUNET_TESTBED_controller_kill_ (cproc); - } + kill_slave (slave); } for (id = 0; id < GST_slave_list_size; id++) { - if (NULL == GST_slave_list[id]) + slave = GST_slave_list[id]; + if (NULL == slave) continue; - if (NULL != (cproc = GST_slave_list[id]->controller_proc)) - { - GNUNET_TESTBED_controller_destroy_ (cproc); - LOG_DEBUG ("Slave stopped\n"); - } - GNUNET_free (GST_slave_list[id]); + destroy_slave (slave); } GNUNET_free_non_null (GST_slave_list); GST_slave_list = NULL; @@ -518,7 +545,7 @@ send_controller_link_response (struct GNUNET_SERVER_Client *client, struct GNUNET_TESTBED_ControllerLinkResponse *msg; char *xconfig; size_t config_size; - size_t xconfig_size; + size_t xconfig_size; uint16_t msize; GNUNET_assert ((NULL == cfg) || (NULL == emsg)); @@ -558,10 +585,9 @@ send_controller_link_response (struct GNUNET_SERVER_Client *client, * 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); +lcf_proc_task (void *cls); /** @@ -575,7 +601,7 @@ lcf_proc_cc (void *cls, const char *emsg) { struct LCFContext *lcf = cls; - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == lcf_proc_task_id); + GNUNET_assert (NULL == lcf_proc_task_id); switch (lcf->state) { case INIT: @@ -607,32 +633,29 @@ registration_error: * 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); +lcf_proc_task (void *cls); /** * Task to free resources when forwarded link controllers has been timedout * * @param cls the LCFContext - * @param tc the task context from scheduler */ static void -lcf_forwarded_operation_timeout (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +lcf_forwarded_operation_timeout (void *cls) { struct LCFContext *lcf = cls; - lcf->timeout_task = GNUNET_SCHEDULER_NO_TASK; + lcf->timeout_task = NULL; // GST_forwarded_operation_timeout (lcf->fopc, tc); LOG (GNUNET_ERROR_TYPE_WARNING, "A forwarded controller link operation has timed out\n"); send_controller_link_response (lcf->client, lcf->operation_id, NULL, "A forwarded controller link operation has " "timed out\n"); - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == lcf_proc_task_id); + GNUNET_assert (NULL == lcf_proc_task_id); lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcf); } @@ -641,15 +664,14 @@ lcf_forwarded_operation_timeout (void *cls, * 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) +lcf_proc_task (void *cls) { struct LCFContext *lcf = cls; struct LCFContextQueue *lcfq; - lcf_proc_task_id = GNUNET_SCHEDULER_NO_TASK; + lcf_proc_task_id = NULL; switch (lcf->state) { case INIT: @@ -696,7 +718,8 @@ lcf_proc_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) lcfq = lcfq_head; GNUNET_assert (lcfq->lcf == lcf); GNUNET_SERVER_client_drop (lcf->client); - GNUNET_TESTBED_operation_done (lcf->op); + if (NULL != lcf->op) + GNUNET_TESTBED_operation_done (lcf->op); GNUNET_free (lcf); GNUNET_CONTAINER_DLL_remove (lcfq_head, lcfq_tail, lcfq); GNUNET_free (lcfq); @@ -718,24 +741,25 @@ slave_event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event) { struct LCFContext *lcf; - /* We currently only get here when working on RegisteredHostContexts and - LCFContexts */ + /* We currently only get here when working on LCFContexts */ GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type); lcf = event->op_cls; GNUNET_assert (lcf->op == event->op); + GNUNET_TESTBED_operation_done (lcf->op); + lcf->op = NULL; GNUNET_assert (FINISHED == lcf->state); - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != lcf->timeout_task); + GNUNET_assert (NULL != lcf->timeout_task); GNUNET_SCHEDULER_cancel (lcf->timeout_task); if (NULL == event->details.operation_finished.emsg) send_controller_link_response (lcf->client, lcf->operation_id, - GNUNET_TESTBED_host_get_cfg_ + GNUNET_TESTBED_host_get_cfg_ (GST_host_list[lcf->delegated_host_id]), NULL); else send_controller_link_response (lcf->client, lcf->operation_id, NULL, event->details.operation_finished.emsg); - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == lcf_proc_task_id); + GNUNET_assert (NULL == lcf_proc_task_id); lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcf); return; } @@ -761,8 +785,13 @@ slave_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, if (GNUNET_SYSERR == status) { slave->controller_proc = NULL; - GST_slave_list[slave->host_id] = NULL; - GNUNET_free (slave); + /* Stop all link controller forwarding tasks since we shutdown here anyway + and as these tasks they depend on the operation queues which are created + through GNUNET_TESTBED_controller_connect() and in kill_slave() we call + the destructor function GNUNET_TESTBED_controller_disconnect() */ + GST_free_lcfq (); + kill_slave (slave); + destroy_slave (slave); slave = NULL; LOG (GNUNET_ERROR_TYPE_WARNING, "Unexpected slave shutdown\n"); GNUNET_SCHEDULER_shutdown (); /* We too shutdown */ @@ -780,13 +809,12 @@ slave_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, { send_controller_link_response (lcc->client, lcc->operation_id, NULL, "Could not connect to delegated controller"); - GNUNET_TESTBED_controller_stop (slave->controller_proc); - GST_slave_list[slave->host_id] = NULL; - GNUNET_free (slave); + kill_slave (slave); + destroy_slave (slave); slave = NULL; } -clean_lcc: + clean_lcc: if (NULL != lcc) { if (NULL != lcc->client) @@ -819,20 +847,18 @@ trigger_notifications (struct Neighbour *n); * neighbour * * @param cls the neighbour - * @param tc scheduler task context */ static void -neighbour_connect_notify_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +neighbour_connect_notify_task (void *cls) { struct Neighbour *n = cls; struct NeighbourConnectNotification *h; GNUNET_assert (NULL != (h = n->nl_head)); - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != n->notify_task); - n->notify_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_assert (NULL != n->notify_task); + n->notify_task = NULL; GNUNET_assert (NULL != n->controller); - GNUNET_CONTAINER_DLL_remove (n->nl_head, n->nl_tail, h); + GNUNET_CONTAINER_DLL_remove (n->nl_head, n->nl_tail, h); trigger_notifications (n); h->cb (h->cb_cls, n->controller); GNUNET_free (h); @@ -855,8 +881,8 @@ trigger_notifications (struct Neighbour *n) return; if (NULL == n->controller) return; - if (GNUNET_SCHEDULER_NO_TASK != n->notify_task) - return; + if (NULL != n->notify_task) + return; if (1 == n->inactive) { GNUNET_assert (0 == n->reference_cnt); @@ -864,7 +890,7 @@ trigger_notifications (struct Neighbour *n) n->inactive = 0; } n->reference_cnt++; - n->notify_task = + n->notify_task = GNUNET_SCHEDULER_add_now (&neighbour_connect_notify_task, n); } @@ -880,7 +906,7 @@ static void opstart_neighbour_conn (void *cls) { struct Neighbour *n = cls; - + GNUNET_assert (NULL != n->conn_op); GNUNET_assert (NULL == n->controller); LOG_DEBUG ("Opening connection to controller on host %u\n", n->host_id); @@ -903,7 +929,7 @@ oprelease_neighbour_conn (void *cls) struct Neighbour *n = cls; GNUNET_assert (0 == n->reference_cnt); - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == n->notify_task); + GNUNET_assert (NULL == n->notify_task); GNUNET_assert (NULL == n->nl_head); if (NULL != n->controller) { @@ -937,7 +963,7 @@ GST_neighbour_get_connection (struct Neighbour *n, GNUNET_assert (NULL != cb); LOG_DEBUG ("Attempting to get connection to controller on host %u\n", n->host_id); - h = GNUNET_malloc (sizeof (struct NeighbourConnectNotification)); + h = GNUNET_new (struct NeighbourConnectNotification); h->n = n; h->cb = cb; h->cb_cls = cb_cls; @@ -966,19 +992,19 @@ GST_neighbour_get_connection_cancel (struct NeighbourConnectNotification *h) { struct Neighbour *n; int cleanup_task; - + n = h->n; cleanup_task = (h == n->nl_head) ? GNUNET_YES : GNUNET_NO; GNUNET_CONTAINER_DLL_remove (n->nl_head, n->nl_tail, h); GNUNET_free (h); if (GNUNET_NO == cleanup_task) return; - if (GNUNET_SCHEDULER_NO_TASK == n->notify_task) + if (NULL == n->notify_task) return; GNUNET_assert (0 < n->reference_cnt); n->reference_cnt--; GNUNET_SCHEDULER_cancel (n->notify_task); - n->notify_task = GNUNET_SCHEDULER_NO_TASK; + n->notify_task = NULL; if (NULL == n->nl_head) { if ( (0 == n->reference_cnt) && (0 == n->inactive) ) @@ -1023,7 +1049,7 @@ cleanup_ncc (struct NeighbourConnectCtxt *ncc) { if (NULL != ncc->nh) GST_neighbour_get_connection_cancel (ncc->nh); - if (GNUNET_SCHEDULER_NO_TASK != ncc->timeout_task) + if (NULL != ncc->timeout_task) GNUNET_SCHEDULER_cancel (ncc->timeout_task); GNUNET_SERVER_client_drop (ncc->client); GNUNET_CONTAINER_DLL_remove (ncc_head, ncc_tail, ncc); @@ -1085,15 +1111,13 @@ GST_free_nccq () * Task to be run upon timeout while attempting to connect to the neighbour * * @param cls the NeighbourConnectCtxt created in GST_handle_link_controllers() - * @param tc the scheduler task context */ static void -timeout_neighbour_connect (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +timeout_neighbour_connect (void *cls) { struct NeighbourConnectCtxt *ncc = cls; - ncc->timeout_task = GNUNET_SCHEDULER_NO_TASK; + ncc->timeout_task = NULL; send_controller_link_response (ncc->client, ncc->op_id, NULL, "Could not connect to delegated controller"); cleanup_ncc (ncc); @@ -1112,7 +1136,7 @@ neighbour_connect_cb (void *cls, struct GNUNET_TESTBED_Controller *c) struct NeighbourConnectCtxt *ncc = cls; GNUNET_SCHEDULER_cancel (ncc->timeout_task); - ncc->timeout_task = GNUNET_SCHEDULER_NO_TASK; + ncc->timeout_task = NULL; ncc->nh = NULL; GST_neighbour_release_connection (ncc->n); send_controller_link_response (ncc->client, ncc->op_id, NULL, NULL); @@ -1130,7 +1154,7 @@ GST_create_neighbour (struct GNUNET_TESTBED_Host *host) { struct Neighbour *n; - n = GNUNET_malloc (sizeof (struct Neighbour)); + n = GNUNET_new (struct Neighbour); n->host_id = GNUNET_TESTBED_host_get_id_ (host); neighbour_list_add (n); /* just add; connect on-demand */ return n; @@ -1200,7 +1224,7 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client, struct Slave *slave; struct LinkControllersContext *lcc; - + if (1 != msg->is_subordinate) { struct Neighbour *n; @@ -1216,16 +1240,16 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client, LOG_DEBUG ("Received request to establish a link to host %u\n", delegated_host_id); n = GST_create_neighbour (GST_host_list[delegated_host_id]); - ncc = GNUNET_malloc (sizeof (struct NeighbourConnectCtxt)); + ncc = GNUNET_new (struct NeighbourConnectCtxt); ncc->n = n; ncc->op_id = op_id; ncc->client = client; - GNUNET_SERVER_client_keep (client); + GNUNET_SERVER_client_keep (client); ncc->nh = GST_neighbour_get_connection (n, neighbour_connect_cb, ncc); ncc->timeout_task = GNUNET_SCHEDULER_add_delayed (GST_timeout, &timeout_neighbour_connect, ncc); - GNUNET_CONTAINER_DLL_insert_tail (ncc_head, ncc_tail, ncc); + GNUNET_CONTAINER_DLL_insert_tail (ncc_head, ncc_tail, ncc); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } @@ -1238,11 +1262,11 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client, } LOG_DEBUG ("Received request to start and establish a link to host %u\n", delegated_host_id); - slave = GNUNET_malloc (sizeof (struct Slave)); + slave = GNUNET_new (struct Slave); slave->host_id = delegated_host_id; slave->reghost_map = GNUNET_CONTAINER_multihashmap_create (100, GNUNET_NO); slave_list_add (slave); - lcc = GNUNET_malloc (sizeof (struct LinkControllersContext)); + lcc = GNUNET_new (struct LinkControllersContext); lcc->operation_id = op_id; GNUNET_SERVER_client_keep (client); lcc->client = client; @@ -1251,7 +1275,7 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_TESTBED_controller_start (GST_context->master_ip, GST_host_list[slave->host_id], &slave_status_cb, slave); - new_route = GNUNET_malloc (sizeof (struct Route)); + new_route = GNUNET_new (struct Route); new_route->dest = delegated_host_id; new_route->thru = GST_context->host_id; route_list_add (new_route); @@ -1265,8 +1289,8 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } - lcfq = GNUNET_malloc (sizeof (struct LCFContextQueue)); - lcfq->lcf = GNUNET_malloc (sizeof (struct LCFContext)); + lcfq = GNUNET_new (struct LCFContextQueue); + lcfq->lcf = GNUNET_new (struct LCFContext); lcfq->lcf->delegated_host_id = delegated_host_id; lcfq->lcf->slave_host_id = slave_host_id; route = GST_find_dest_route (slave_host_id); @@ -1281,7 +1305,7 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client, lcfq->lcf->client = client; if (NULL == lcfq_head) { - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == lcf_proc_task_id); + GNUNET_assert (NULL == 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->lcf); } @@ -1302,7 +1326,7 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } - new_route = GNUNET_malloc (sizeof (struct Route)); + new_route = GNUNET_new (struct Route); new_route->dest = delegated_host_id; new_route->thru = route->dest; route_list_add (new_route); @@ -1317,20 +1341,26 @@ void GST_free_lcfq () { struct LCFContextQueue *lcfq; - + struct LCFContext *lcf; + if (NULL != lcfq_head) { - if (GNUNET_SCHEDULER_NO_TASK != lcf_proc_task_id) + if (NULL != lcf_proc_task_id) { GNUNET_SCHEDULER_cancel (lcf_proc_task_id); - lcf_proc_task_id = GNUNET_SCHEDULER_NO_TASK; + lcf_proc_task_id = NULL; } } - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == lcf_proc_task_id); + GNUNET_assert (NULL == lcf_proc_task_id); for (lcfq = lcfq_head; NULL != lcfq; lcfq = lcfq_head) { - GNUNET_SERVER_client_drop (lcfq->lcf->client); - GNUNET_free (lcfq->lcf); + lcf = lcfq->lcf; + GNUNET_SERVER_client_drop (lcf->client); + if (NULL != lcf->op) + GNUNET_TESTBED_operation_done (lcf->op); + if (NULL != lcf->timeout_task) + GNUNET_SCHEDULER_cancel (lcf->timeout_task); + GNUNET_free (lcf); GNUNET_CONTAINER_DLL_remove (lcfq_head, lcfq_tail, lcfq); GNUNET_free (lcfq); }