From 28f8e239844323e564d63fc8a792cbcbed41ec68 Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Tue, 5 Feb 2013 14:24:51 +0000 Subject: add completion callback for overlay topology configure functions --- src/gns/test_gns_dht_three_peers.c | 3 +- src/include/gnunet_testbed_service.h | 41 ++++++- src/regex/gnunet-regex-profiler.c | 5 +- src/testbed/test_testbed_api_topology.c | 2 + src/testbed/test_testbed_api_topology_clique.c | 2 + src/testbed/testbed_api_testbed.c | 6 + src/testbed/testbed_api_topology.c | 160 +++++++++++++++++++++---- 7 files changed, 191 insertions(+), 28 deletions(-) diff --git a/src/gns/test_gns_dht_three_peers.c b/src/gns/test_gns_dht_three_peers.c index 5c4e54e13..49c94571f 100644 --- a/src/gns/test_gns_dht_three_peers.c +++ b/src/gns/test_gns_dht_three_peers.c @@ -296,7 +296,8 @@ static void connect_peers () GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers started\n"); topology_op = - GNUNET_TESTBED_overlay_configure_topology (NULL, 3, cpeers, + GNUNET_TESTBED_overlay_configure_topology (NULL, 3, cpeers, NULL, + NULL, NULL, GNUNET_TESTBED_TOPOLOGY_RING, GNUNET_TESTBED_TOPOLOGY_OPTION_END); diff --git a/src/include/gnunet_testbed_service.h b/src/include/gnunet_testbed_service.h index 01d7f7f93..3c2d93272 100644 --- a/src/include/gnunet_testbed_service.h +++ b/src/include/gnunet_testbed_service.h @@ -1025,10 +1025,13 @@ enum GNUNET_TESTBED_TopologyOption GNUNET_TESTBED_TOPOLOGY_OPTION_END */ /** - * Disable automatic retrying for failed overlay connections. The default is - * to always retry failed overlay connections. This parameter takes no options. + * How many times should the failed overlay connect operations be retried + * before giving up. The default if this option is not specified is to retry + * 3 times. This option takes and unsigned integer as a parameter. Use this + * option with parameter 0 to disable retrying of failed overlay connect + * operations. */ - GNUNET_TESTBED_TOPOLOGY_DISABLE_AUTO_RETRY + GNUNET_TESTBED_TOPOLOGY_RETRY_CNT }; @@ -1092,16 +1095,34 @@ GNUNET_TESTBED_overlay_connect (void *op_cls, struct GNUNET_TESTBED_Peer *p2); +/** + * Callbacks of this type are called when topology configuration is completed + * + * @param cls the operation closure given to + * GNUNET_TESTBED_overlay_configure_topology_va() and + * GNUNET_TESTBED_overlay_configure() calls + * @param nsuccess the number of successful overlay connects + * @param nfailures the number of overlay connects which failed + */ +typedef void (*GNUNET_TESTBED_TopologyCompletionCallback) (void *cls, + unsigned int nsuccess, + unsigned int nfailures); + + /** * All peers must have been started before calling this function. * This function then connects the given peers in the P2P overlay * using the given topology. * - * @param op_cls closure argument to give with the operation event + * @param op_cls closure argument to give with the peer connect operation events + * generated through this function * @param num_peers number of peers in 'peers' * @param peers array of 'num_peers' with the peers to configure * @param max_connections the maximums number of overlay connections that will * be made to achieve the given topology + * @param comp_cb the completion callback to call when the topology generation + * is completed + * @param comp_cb_cls closure for the above completion callback * @param topo desired underlay topology to use * @param va topology-specific options * @return handle to the operation, NULL if connecting these @@ -1113,6 +1134,9 @@ GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls, unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers, unsigned int *max_connections, + GNUNET_TESTBED_TopologyCompletionCallback + comp_cb, + void *comp_cb_cls, enum GNUNET_TESTBED_TopologyOption topo, va_list va); @@ -1122,11 +1146,15 @@ GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls, * This function then connects the given peers in the P2P overlay * using the given topology. * - * @param op_cls closure argument to give with the operation event + * @param op_cls closure argument to give with the peer connect operation events + * generated through this function * @param num_peers number of peers in 'peers' * @param peers array of 'num_peers' with the peers to configure * @param max_connections the maximums number of overlay connections that will * be made to achieve the given topology + * @param comp_cb the completion callback to call when the topology generation + * is completed + * @param comp_cb_cls closure for the above completion callback * @param topo desired underlay topology to use * @param ... topology-specific options * @return handle to the operation, NULL if connecting these @@ -1138,6 +1166,9 @@ GNUNET_TESTBED_overlay_configure_topology (void *op_cls, unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers, unsigned int *max_connections, + GNUNET_TESTBED_TopologyCompletionCallback + comp_cb, + void *comp_cb_cls, enum GNUNET_TESTBED_TopologyOption topo, ...); diff --git a/src/regex/gnunet-regex-profiler.c b/src/regex/gnunet-regex-profiler.c index 26c052387..f0a05c457 100644 --- a/src/regex/gnunet-regex-profiler.c +++ b/src/regex/gnunet-regex-profiler.c @@ -1106,10 +1106,13 @@ do_configure_topology (void *cls, prof_start_time = GNUNET_TIME_absolute_get (); topology_op = GNUNET_TESTBED_overlay_configure_topology (NULL, num_peers, peer_handles, + NULL, + NULL, NULL, GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI, num_links, - GNUNET_TESTBED_TOPOLOGY_DISABLE_AUTO_RETRY, + GNUNET_TESTBED_TOPOLOGY_RETRY_CNT, + (unsigned int) 0, GNUNET_TESTBED_TOPOLOGY_OPTION_END); if (NULL == topology_op) { diff --git a/src/testbed/test_testbed_api_topology.c b/src/testbed/test_testbed_api_topology.c index a63ae1b1a..0098dbea4 100644 --- a/src/testbed/test_testbed_api_topology.c +++ b/src/testbed/test_testbed_api_topology.c @@ -135,6 +135,8 @@ test_master (void *cls, unsigned int num_peers, peers = peers_; overlay_connects = 0; op = GNUNET_TESTBED_overlay_configure_topology (NULL, NUM_PEERS, peers, NULL, + NULL, + NULL, GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI, NUM_PEERS, GNUNET_TESTBED_TOPOLOGY_OPTION_END); diff --git a/src/testbed/test_testbed_api_topology_clique.c b/src/testbed/test_testbed_api_topology_clique.c index eb6254b10..3f1ed7ade 100644 --- a/src/testbed/test_testbed_api_topology_clique.c +++ b/src/testbed/test_testbed_api_topology_clique.c @@ -130,6 +130,8 @@ test_master (void *cls, unsigned int num_peers, peers = peers_; overlay_connects = 0; op = GNUNET_TESTBED_overlay_configure_topology (NULL, NUM_PEERS, peers, NULL, + NULL, + NULL, GNUNET_TESTBED_TOPOLOGY_CLIQUE, /* GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI, */ /* NUM_PEERS, */ diff --git a/src/testbed/testbed_api_testbed.c b/src/testbed/testbed_api_testbed.c index 47e0edc89..1c9363c63 100644 --- a/src/testbed/testbed_api_testbed.c +++ b/src/testbed/testbed_api_testbed.c @@ -735,6 +735,8 @@ call_cc: rc->topology_operation = GNUNET_TESTBED_overlay_configure_topology (NULL, rc->num_peers, rc->peers, &rc->num_oc, + NULL, + NULL, rc->topology, rc->random_links, GNUNET_TESTBED_TOPOLOGY_OPTION_END); @@ -745,6 +747,8 @@ call_cc: rc->topology_operation = GNUNET_TESTBED_overlay_configure_topology (NULL, rc->num_peers, rc->peers, &rc->num_oc, + NULL, + NULL, rc->topology, rc->topo_file, GNUNET_TESTBED_TOPOLOGY_OPTION_END); @@ -753,6 +757,8 @@ call_cc: rc->topology_operation = GNUNET_TESTBED_overlay_configure_topology (NULL, rc->num_peers, rc->peers, &rc->num_oc, + NULL, + NULL, rc->topology, GNUNET_TESTBED_TOPOLOGY_OPTION_END); if (NULL == rc->topology_operation) diff --git a/src/testbed/testbed_api_topology.c b/src/testbed/testbed_api_topology.c index d9666e4df..9618f98dd 100644 --- a/src/testbed/testbed_api_topology.c +++ b/src/testbed/testbed_api_topology.c @@ -37,6 +37,12 @@ GNUNET_log_from (kind, "testbed-api-topology", __VA_ARGS__) +/** + * Default number of retires + */ +#define DEFAULT_RETRY_CNT 3 + + /** * Context information for topology operations */ @@ -72,6 +78,25 @@ struct OverlayLink }; +struct RetryListEntry +{ + /** + * the next pointer for the DLL + */ + struct RetryListEntry *next; + + /** + * the prev pointer for the DLL + */ + struct RetryListEntry *prev; + + /** + * The link to be retired + */ + struct OverlayLink *link; +}; + + /** * Context information for topology operations */ @@ -92,6 +117,26 @@ struct TopologyContext */ void *op_cls; + /** + * topology generation completion callback + */ + GNUNET_TESTBED_TopologyCompletionCallback comp_cb; + + /** + * The closure for the above callback + */ + void *comp_cb_cls; + + /** + * DLL head for retry list + */ + struct RetryListEntry *rl_head; + + /** + * DLL tail for retry list + */ + struct RetryListEntry *rl_tail; + /** * The number of peers */ @@ -103,10 +148,29 @@ struct TopologyContext unsigned int link_array_size; /** - * should the automatic retry be disabled + * How many retries to do before we give up */ - int disable_retry; + unsigned int retry_cnt; + /** + * Number of links to try + */ + unsigned int nlinks; + + /** + * How many links have been completed + */ + unsigned int ncompleted; + + /** + * Total successfully established overlay connections + */ + unsigned int nsuccess; + + /** + * Total failed overlay connections + */ + unsigned int nfailures; }; @@ -198,21 +262,51 @@ overlay_link_completed (void *cls, struct GNUNET_TESTBED_Operation *op, { struct OverlayLink *link = cls; struct TopologyContext *tc; + struct RetryListEntry *retry_entry; GNUNET_assert (op == link->op); GNUNET_TESTBED_operation_done (op); link->op = NULL; tc = link->tc; - if ((NULL != emsg) && (GNUNET_NO == tc->disable_retry)) + if (NULL != emsg) { - LOG (GNUNET_ERROR_TYPE_WARNING, - "Error while establishing a link: %s -- Retrying\n", emsg); - link->op = - GNUNET_TESTBED_overlay_connect (tc->op_cls, &overlay_link_completed, - link, tc->peers[link->A], - tc->peers[link->B]); + tc->nfailures++; + if (0 != tc->retry_cnt) + { + LOG (GNUNET_ERROR_TYPE_WARNING, + "Error while establishing a link: %s -- Retrying\n", emsg); + retry_entry = GNUNET_malloc (sizeof (struct RetryListEntry)); + retry_entry->link = link; + GNUNET_CONTAINER_DLL_insert_tail (tc->rl_head, tc->rl_tail, retry_entry); + } + } + else + tc->nsuccess++; + tc->ncompleted++; + if (tc->ncompleted < tc->nlinks) + return; + if ((0 != tc->retry_cnt) && (NULL != tc->rl_head)) + { + tc->retry_cnt--; + tc->ncompleted = 0; + tc->nlinks = 0; + while (NULL != (retry_entry = tc->rl_head)) + { + link = retry_entry->link; + link->op = + GNUNET_TESTBED_overlay_connect (tc->op_cls, &overlay_link_completed, + link, tc->peers[link->A], + tc->peers[link->B]); + tc->nlinks++; + GNUNET_CONTAINER_DLL_remove (tc->rl_head, tc->rl_tail, retry_entry); + GNUNET_free (retry_entry); + } return; } + if (NULL != tc->comp_cb) + { + tc->comp_cb (tc->comp_cb_cls, tc->nsuccess, tc->nfailures); + } } @@ -228,6 +322,7 @@ opstart_overlay_configure_topology (void *cls) struct TopologyContext *tc = cls; unsigned int p; + tc->nlinks = tc->link_array_size; for (p = 0; p < tc->link_array_size; p++) { tc->link_array[p].op = @@ -248,8 +343,14 @@ static void oprelease_overlay_configure_topology (void *cls) { struct TopologyContext *tc = cls; + struct RetryListEntry *retry_entry; unsigned int p; + while (NULL != (retry_entry = tc->rl_head)) + { + GNUNET_CONTAINER_DLL_remove (tc->rl_head, tc->rl_tail, retry_entry); + GNUNET_free (retry_entry); + } if (NULL != tc->link_array) { for (p = 0; p < tc->link_array_size; p++) @@ -741,11 +842,15 @@ GNUNET_TESTBED_underlay_configure_topology (void *op_cls, * This function then connects the given peers in the P2P overlay * using the given topology. * - * @param op_cls closure argument to give with the operation event + * @param op_cls closure argument to give with the peer connect operation events + * generated through this function * @param num_peers number of peers in 'peers' * @param peers array of 'num_peers' with the peers to configure * @param max_connections the maximums number of overlay connections that will * be made to achieve the given topology + * @param comp_cb the completion callback to call when the topology generation + * is completed + * @param comp_cb_cls closure for the above completion callback * @param topo desired underlay topology to use * @param va topology-specific options * @return handle to the operation, NULL if connecting these @@ -755,11 +860,13 @@ GNUNET_TESTBED_underlay_configure_topology (void *op_cls, struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls, unsigned int num_peers, - struct GNUNET_TESTBED_Peer - **peers, + struct GNUNET_TESTBED_Peer **peers, unsigned int *max_connections, - enum GNUNET_TESTBED_TopologyOption - topo, va_list va) + GNUNET_TESTBED_TopologyCompletionCallback + comp_cb, + void *comp_cb_cls, + enum GNUNET_TESTBED_TopologyOption topo, + va_list va) { struct TopologyContext *tc; struct GNUNET_TESTBED_Operation *op; @@ -774,6 +881,7 @@ GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls, tc->peers = peers; tc->num_peers = num_peers; tc->op_cls = op_cls; + tc->retry_cnt = DEFAULT_RETRY_CNT; switch (topo) { case GNUNET_TESTBED_TOPOLOGY_LINE: @@ -847,8 +955,8 @@ GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls, switch (secondary_option) { - case GNUNET_TESTBED_TOPOLOGY_DISABLE_AUTO_RETRY: - tc->disable_retry = GNUNET_YES; + case GNUNET_TESTBED_TOPOLOGY_RETRY_CNT: + tc->retry_cnt = va_arg (va, unsigned int); break; case GNUNET_TESTBED_TOPOLOGY_OPTION_END: break; @@ -880,11 +988,15 @@ GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls, * This function then connects the given peers in the P2P overlay * using the given topology. * - * @param op_cls closure argument to give with the operation event + * @param op_cls closure argument to give with the peer connect operation events + * generated through this function * @param num_peers number of peers in 'peers' * @param peers array of 'num_peers' with the peers to configure * @param max_connections the maximums number of overlay connections that will * be made to achieve the given topology + * @param comp_cb the completion callback to call when the topology generation + * is completed + * @param comp_cb_cls closure for the above completion callback * @param topo desired underlay topology to use * @param ... topology-specific options * @return handle to the operation, NULL if connecting these @@ -892,11 +1004,15 @@ GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls, * not running or underlay disallows) or if num_peers is less than 2 */ struct GNUNET_TESTBED_Operation * -GNUNET_TESTBED_overlay_configure_topology (void *op_cls, unsigned int num_peers, +GNUNET_TESTBED_overlay_configure_topology (void *op_cls, + unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers, unsigned int *max_connections, - enum GNUNET_TESTBED_TopologyOption - topo, ...) + GNUNET_TESTBED_TopologyCompletionCallback + comp_cb, + void *comp_cb_cls, + enum GNUNET_TESTBED_TopologyOption topo, + ...) { struct GNUNET_TESTBED_Operation *op; va_list vargs; @@ -904,7 +1020,9 @@ GNUNET_TESTBED_overlay_configure_topology (void *op_cls, unsigned int num_peers, GNUNET_assert (topo < GNUNET_TESTBED_TOPOLOGY_OPTION_END); va_start (vargs, topo); op = GNUNET_TESTBED_overlay_configure_topology_va (op_cls, num_peers, peers, - max_connections, topo, + max_connections, + comp_cb, comp_cb_cls, + topo, vargs); va_end (vargs); return op; -- cgit v1.2.3