aboutsummaryrefslogtreecommitdiff
path: root/src/testbed
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2013-03-08 15:34:45 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2013-03-08 15:34:45 +0000
commit19b4dacf08575bd188f9010558e8299c6c8eb56e (patch)
tree1555b7c5ac0e6a4ac39028830a50086c70d19830 /src/testbed
parent6419502e4bb83f53caf9f3fd5170f8219516e38a (diff)
downloadgnunet-19b4dacf08575bd188f9010558e8299c6c8eb56e.tar.gz
gnunet-19b4dacf08575bd188f9010558e8299c6c8eb56e.zip
- fix (case where peers <= 2)
Diffstat (limited to 'src/testbed')
-rw-r--r--src/testbed/gnunet-service-testbed.c228
-rw-r--r--src/testbed/test_testbed_api_testbed_run.c2
-rw-r--r--src/testbed/testbed_api_testbed.c107
-rw-r--r--src/testbed/testbed_api_topology.c4
4 files changed, 228 insertions, 113 deletions
diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c
index 2435ba50e..a7af7b99c 100644
--- a/src/testbed/gnunet-service-testbed.c
+++ b/src/testbed/gnunet-service-testbed.c
@@ -1973,6 +1973,194 @@ handle_slave_get_config (void *cls, struct GNUNET_SERVER_Client *client,
1973 1973
1974 1974
1975/** 1975/**
1976 * Context data for GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS handler
1977 */
1978struct HandlerContext_ShutdownPeers
1979{
1980 /**
1981 * The number of slave we expect to hear from since we forwarded the
1982 * GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS message to them
1983 */
1984 unsigned int nslaves;
1985
1986 /**
1987 * Did we observe a timeout with respect to this operation at any of the
1988 * slaves
1989 */
1990 int timeout;
1991};
1992
1993
1994/**
1995 * Task run upon timeout of forwarded SHUTDOWN_PEERS operation
1996 *
1997 * @param cls the ForwardedOperationContext
1998 * @param tc the scheduler task context
1999 */
2000static void
2001shutdown_peers_timeout_cb (void *cls,
2002 const struct GNUNET_SCHEDULER_TaskContext *tc)
2003{
2004 struct ForwardedOperationContext *fo_ctxt = cls;
2005 struct HandlerContext_ShutdownPeers *hc;
2006
2007 hc = fo_ctxt->cls;
2008 hc->timeout = GNUNET_YES;
2009 GNUNET_assert (0 < hc->nslaves);
2010 hc->nslaves--;
2011 if (0 == hc->nslaves)
2012 GST_send_operation_fail_msg (fo_ctxt->client, fo_ctxt->operation_id,
2013 "Timeout at a slave controller");
2014 GNUNET_TESTBED_forward_operation_msg_cancel_ (fo_ctxt->opc);
2015 GNUNET_SERVER_client_drop (fo_ctxt->client);
2016 GNUNET_CONTAINER_DLL_remove (fopcq_head, fopcq_tail, fo_ctxt);
2017 GNUNET_free (fo_ctxt);
2018}
2019
2020
2021/**
2022 * The reply msg handler forwarded SHUTDOWN_PEERS operation. Checks if a
2023 * success reply is received from all clients and then sends the success message
2024 * to the client
2025 *
2026 * @param cls ForwardedOperationContext
2027 * @param msg the message to relay
2028 */
2029static void
2030shutdown_peers_reply_cb (void *cls,
2031 const struct GNUNET_MessageHeader *msg)
2032{
2033 struct ForwardedOperationContext *fo_ctxt = cls;
2034 struct HandlerContext_ShutdownPeers *hc;
2035
2036 hc = fo_ctxt->cls;
2037 GNUNET_assert (0 < hc->nslaves);
2038 hc->nslaves--;
2039 if (GNUNET_MESSAGE_TYPE_TESTBED_GENERIC_OPERATION_SUCCESS !=
2040 ntohs (msg->type))
2041 hc->timeout = GNUNET_YES;
2042 if (0 == hc->nslaves)
2043 {
2044 if (GNUNET_YES == hc->timeout)
2045 GST_send_operation_fail_msg (fo_ctxt->client, fo_ctxt->operation_id,
2046 "Timeout at a slave controller");
2047 else
2048 send_operation_success_msg (fo_ctxt->client, fo_ctxt->operation_id);
2049 }
2050 GNUNET_SERVER_client_drop (fo_ctxt->client);
2051 GNUNET_CONTAINER_DLL_remove (fopcq_head, fopcq_tail, fo_ctxt);
2052 GNUNET_free (fo_ctxt);
2053}
2054
2055
2056/**
2057 * Stops and destroys all peers
2058 */
2059static void
2060destroy_peers ()
2061{
2062 struct Peer *peer;
2063 unsigned int id;
2064
2065 if (NULL == GST_peer_list)
2066 return;
2067 for (id = 0; id < GST_peer_list_size; id++)
2068 {
2069 peer = GST_peer_list[id];
2070 if (NULL == peer)
2071 continue;
2072 /* If destroy flag is set it means that this peer should have been
2073 * destroyed by a context which we destroy before */
2074 GNUNET_break (GNUNET_NO == peer->destroy_flag);
2075 /* counter should be zero as we free all contexts before */
2076 GNUNET_break (0 == peer->reference_cnt);
2077 if ((GNUNET_NO == peer->is_remote) &&
2078 (GNUNET_YES == peer->details.local.is_running))
2079 GNUNET_TESTING_peer_kill (peer->details.local.peer);
2080 }
2081 for (id = 0; id < GST_peer_list_size; id++)
2082 {
2083 peer = GST_peer_list[id];
2084 if (NULL == peer)
2085 continue;
2086 if (GNUNET_NO == peer->is_remote)
2087 {
2088 if (GNUNET_YES == peer->details.local.is_running)
2089 GNUNET_TESTING_peer_wait (peer->details.local.peer);
2090 GNUNET_TESTING_peer_destroy (peer->details.local.peer);
2091 GNUNET_CONFIGURATION_destroy (peer->details.local.cfg);
2092 }
2093 GNUNET_free (peer);
2094 }
2095 GNUNET_free_non_null (GST_peer_list);
2096 GST_peer_list = NULL;
2097}
2098
2099
2100/**
2101 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS messages
2102 *
2103 * @param cls NULL
2104 * @param client identification of the client
2105 * @param message the actual message
2106 */
2107static void
2108handle_shutdown_peers (void *cls, struct GNUNET_SERVER_Client *client,
2109 const struct GNUNET_MessageHeader *message)
2110{
2111 const struct GNUNET_TESTBED_ShutdownPeersMessage *msg;
2112 struct HandlerContext_ShutdownPeers *hc;
2113 struct Slave *slave;
2114 struct ForwardedOperationContext *fo_ctxt;
2115 uint64_t op_id;
2116 unsigned int cnt;
2117
2118 msg = (const struct GNUNET_TESTBED_ShutdownPeersMessage *) message;
2119 LOG_DEBUG ("Received SHUTDOWN_PEERS\n");
2120 /* Forward to all slaves which we have started */
2121 op_id = GNUNET_ntohll (msg->operation_id);
2122 hc = GNUNET_malloc (sizeof (struct HandlerContext_ShutdownPeers));
2123 /* FIXME: have a better implementation where we track which slaves are
2124 started by this controller */
2125 for (cnt = 0; cnt < GST_slave_list_size; cnt++)
2126 {
2127 slave = GST_slave_list[cnt];
2128 if (NULL == slave)
2129 continue;
2130 if (NULL == slave->controller_proc) /* We didn't start the slave */
2131 continue;
2132 LOG_DEBUG ("Forwarding SHUTDOWN_PEERS\n");
2133 hc->nslaves++;
2134 fo_ctxt = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
2135 GNUNET_SERVER_client_keep (client);
2136 fo_ctxt->client = client;
2137 fo_ctxt->operation_id = op_id;
2138 fo_ctxt->cls = hc;
2139 fo_ctxt->type = OP_SHUTDOWN_PEERS;
2140 fo_ctxt->opc =
2141 GNUNET_TESTBED_forward_operation_msg_ (slave->controller,
2142 fo_ctxt->operation_id,
2143 &msg->header,
2144 shutdown_peers_reply_cb,
2145 fo_ctxt);
2146 fo_ctxt->timeout_task =
2147 GNUNET_SCHEDULER_add_delayed (GST_timeout, &shutdown_peers_timeout_cb,
2148 fo_ctxt);
2149 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fo_ctxt);
2150 }
2151 LOG_DEBUG ("Shutting down peers\n");
2152 /* Stop and destroy all peers */
2153 destroy_peers ();
2154 if (0 == hc->nslaves)
2155 {
2156 send_operation_success_msg (client, op_id);
2157 GNUNET_free (hc);
2158 }
2159 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2160}
2161
2162
2163/**
1976 * Iterator over hash map entries. 2164 * Iterator over hash map entries.
1977 * 2165 *
1978 * @param cls closure 2166 * @param cls closure
@@ -2062,6 +2250,16 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2062 case OP_PEER_CREATE: 2250 case OP_PEER_CREATE:
2063 GNUNET_free (fopc->cls); 2251 GNUNET_free (fopc->cls);
2064 break; 2252 break;
2253 case OP_SHUTDOWN_PEERS:
2254 {
2255 struct HandlerContext_ShutdownPeers *hc = fopc->cls;
2256
2257 GNUNET_assert (0 < hc->nslaves);
2258 hc->nslaves--;
2259 if (0 == hc->nslaves)
2260 GNUNET_free (hc);
2261 }
2262 break;
2065 case OP_PEER_START: 2263 case OP_PEER_START:
2066 case OP_PEER_STOP: 2264 case OP_PEER_STOP:
2067 case OP_PEER_DESTROY: 2265 case OP_PEER_DESTROY:
@@ -2096,31 +2294,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2096 GST_free_occq (); 2294 GST_free_occq ();
2097 GST_free_roccq (); 2295 GST_free_roccq ();
2098 /* Clear peer list */ 2296 /* Clear peer list */
2099 for (id = 0; id < GST_peer_list_size; id++) 2297 destroy_peers ();
2100 if (NULL != GST_peer_list[id])
2101 {
2102 /* If destroy flag is set it means that this peer should have been
2103 * destroyed by a context which we destroy before */
2104 GNUNET_break (GNUNET_NO == GST_peer_list[id]->destroy_flag);
2105 /* counter should be zero as we free all contexts before */
2106 GNUNET_break (0 == GST_peer_list[id]->reference_cnt);
2107 if ((GNUNET_NO == GST_peer_list[id]->is_remote) &&
2108 (GNUNET_YES == GST_peer_list[id]->details.local.is_running))
2109 GNUNET_TESTING_peer_kill (GST_peer_list[id]->details.local.peer);
2110 }
2111 for (id = 0; id < GST_peer_list_size; id++)
2112 if (NULL != GST_peer_list[id])
2113 {
2114 if (GNUNET_NO == GST_peer_list[id]->is_remote)
2115 {
2116 if (GNUNET_YES == GST_peer_list[id]->details.local.is_running)
2117 GNUNET_TESTING_peer_wait (GST_peer_list[id]->details.local.peer);
2118 GNUNET_TESTING_peer_destroy (GST_peer_list[id]->details.local.peer);
2119 GNUNET_CONFIGURATION_destroy (GST_peer_list[id]->details.local.cfg);
2120 }
2121 GNUNET_free (GST_peer_list[id]);
2122 }
2123 GNUNET_free_non_null (GST_peer_list);
2124 /* Clear host list */ 2298 /* Clear host list */
2125 for (id = 0; id < GST_host_list_size; id++) 2299 for (id = 0; id < GST_host_list_size; id++)
2126 if (NULL != GST_host_list[id]) 2300 if (NULL != GST_host_list[id])
@@ -2242,9 +2416,11 @@ testbed_run (void *cls, struct GNUNET_SERVER_Handle *server,
2242 sizeof (struct GNUNET_TESTBED_OverlayConnectMessage)}, 2416 sizeof (struct GNUNET_TESTBED_OverlayConnectMessage)},
2243 {&GST_handle_remote_overlay_connect, NULL, 2417 {&GST_handle_remote_overlay_connect, NULL,
2244 GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT, 0}, 2418 GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT, 0},
2245 {handle_slave_get_config, NULL, 2419 {&handle_slave_get_config, NULL,
2246 GNUNET_MESSAGE_TYPE_TESTBED_GET_SLAVE_CONFIGURATION, 2420 GNUNET_MESSAGE_TYPE_TESTBED_GET_SLAVE_CONFIGURATION,
2247 sizeof (struct GNUNET_TESTBED_SlaveGetConfigurationMessage)}, 2421 sizeof (struct GNUNET_TESTBED_SlaveGetConfigurationMessage)},
2422 {&handle_shutdown_peers, NULL, GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS,
2423 sizeof (struct GNUNET_TESTBED_ShutdownPeersMessage)},
2248 {NULL} 2424 {NULL}
2249 }; 2425 };
2250 char *logfile; 2426 char *logfile;
diff --git a/src/testbed/test_testbed_api_testbed_run.c b/src/testbed/test_testbed_api_testbed_run.c
index 9cad74a7b..10317b489 100644
--- a/src/testbed/test_testbed_api_testbed_run.c
+++ b/src/testbed/test_testbed_api_testbed_run.c
@@ -31,7 +31,7 @@
31/** 31/**
32 * Number of peers we want to start 32 * Number of peers we want to start
33 */ 33 */
34#define NUM_PEERS 5 34#define NUM_PEERS 2
35 35
36/** 36/**
37 * The array of peers; we fill this as the peers are given to us by the testbed 37 * The array of peers; we fill this as the peers are given to us by the testbed
diff --git a/src/testbed/testbed_api_testbed.c b/src/testbed/testbed_api_testbed.c
index 282e4af88..c54ef3e19 100644
--- a/src/testbed/testbed_api_testbed.c
+++ b/src/testbed/testbed_api_testbed.c
@@ -103,15 +103,20 @@ enum State
103 */ 103 */
104 RC_READY, 104 RC_READY,
105 105
106 /** 106 /* /\** */
107 * Peers are stopped 107 /* * Peers are stopped */
108 */ 108 /* *\/ */
109 RC_PEERS_STOPPED, 109 /* RC_PEERS_STOPPED, */
110
111 /* /\** */
112 /* * Peers are destroyed */
113 /* *\/ */
114 /* RC_PEERS_DESTROYED */
110 115
111 /** 116 /**
112 * Peers are destroyed 117 * All peers shutdown (stopped and destroyed)
113 */ 118 */
114 RC_PEERS_DESTROYED 119 RC_PEERS_SHUTDOWN
115}; 120};
116 121
117 122
@@ -377,7 +382,7 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
377 GNUNET_assert (NULL == rc->reg_handle); 382 GNUNET_assert (NULL == rc->reg_handle);
378 GNUNET_assert (NULL == rc->peers); 383 GNUNET_assert (NULL == rc->peers);
379 GNUNET_assert (NULL == rc->hc_handles); 384 GNUNET_assert (NULL == rc->hc_handles);
380 GNUNET_assert (RC_PEERS_DESTROYED == rc->state); 385 GNUNET_assert (RC_PEERS_SHUTDOWN == rc->state);
381 if (NULL != rc->dll_op_head) 386 if (NULL != rc->dll_op_head)
382 { /* cancel our pending operations */ 387 { /* cancel our pending operations */
383 while (NULL != (dll_op = rc->dll_op_head)) 388 while (NULL != (dll_op = rc->dll_op_head))
@@ -441,8 +446,6 @@ shutdown_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
441{ 446{
442 struct RunContext *rc = cls; 447 struct RunContext *rc = cls;
443 struct DLLOperation *dll_op; 448 struct DLLOperation *dll_op;
444 int all_peers_destroyed;
445 unsigned int peer;
446 unsigned int nhost; 449 unsigned int nhost;
447 450
448 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != rc->shutdown_run_task); 451 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != rc->shutdown_run_task);
@@ -479,61 +482,17 @@ shutdown_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
479 } 482 }
480 if (RC_INIT == rc->state) 483 if (RC_INIT == rc->state)
481 rc->state = RC_READY; /* Even though we haven't called the master callback */ 484 rc->state = RC_READY; /* Even though we haven't called the master callback */
482 rc->peer_count = 0; 485 dll_op = GNUNET_malloc (sizeof (struct DLLOperation));
483 /* Check if some peers are stopped */ 486 dll_op->op = GNUNET_TESTBED_shutdown_peers (rc->c, dll_op, NULL, NULL);
484 for (peer = 0; peer < rc->num_peers; peer++) 487 DEBUG ("Shutting down peers\n");
485 {
486 if (NULL == rc->peers[peer])
487 continue;
488 if (PS_STOPPED != rc->peers[peer]->state)
489 break;
490 }
491 if (peer == rc->num_peers)
492 {
493 /* All peers are stopped */
494 rc->state = RC_PEERS_STOPPED;
495 all_peers_destroyed = GNUNET_YES;
496 for (peer = 0; peer < rc->num_peers; peer++)
497 {
498 if (NULL == rc->peers[peer])
499 continue;
500 all_peers_destroyed = GNUNET_NO;
501 dll_op = GNUNET_malloc (sizeof (struct DLLOperation));
502 dll_op->op = GNUNET_TESTBED_peer_destroy (rc->peers[peer]);
503 GNUNET_CONTAINER_DLL_insert_tail (rc->dll_op_head, rc->dll_op_tail,
504 dll_op);
505 }
506 if (all_peers_destroyed == GNUNET_NO)
507 {
508 DEBUG ("Destroying peers\n");
509 rc->pstart_time = GNUNET_TIME_absolute_get ();
510 return;
511 }
512 }
513 /* Some peers are stopped */
514 DEBUG ("Stopping peers\n");
515 rc->pstart_time = GNUNET_TIME_absolute_get (); 488 rc->pstart_time = GNUNET_TIME_absolute_get ();
516 for (peer = 0; peer < rc->num_peers; peer++) 489 GNUNET_CONTAINER_DLL_insert_tail (rc->dll_op_head, rc->dll_op_tail,
517 { 490 dll_op);
518 if ((NULL == rc->peers[peer]) || (PS_STARTED != rc->peers[peer]->state)) 491 return;
519 {
520 rc->peer_count++;
521 continue;
522 }
523 dll_op = GNUNET_malloc (sizeof (struct DLLOperation));
524 dll_op->op = GNUNET_TESTBED_peer_stop (rc->peers[peer], NULL, NULL);
525 dll_op->cls = rc->peers[peer];
526 GNUNET_CONTAINER_DLL_insert_tail (rc->dll_op_head, rc->dll_op_tail,
527 dll_op);
528 }
529 if (rc->peer_count != rc->num_peers)
530 return;
531 GNUNET_free (rc->peers);
532 rc->peers = NULL;
533 } 492 }
534 } 493 }
535 rc->state = RC_PEERS_DESTROYED; /* No peers are present so we consider the 494 rc->state = RC_PEERS_SHUTDOWN; /* No peers are present so we consider the
536 * state where all peers are destroyed */ 495 * state where all peers are SHUTDOWN */
537 GNUNET_SCHEDULER_add_now (&cleanup_task, rc); 496 GNUNET_SCHEDULER_add_now (&cleanup_task, rc);
538} 497}
539 498
@@ -625,7 +584,6 @@ event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
625{ 584{
626 struct RunContext *rc = cls; 585 struct RunContext *rc = cls;
627 struct DLLOperation *dll_op; 586 struct DLLOperation *dll_op;
628 unsigned int peer_id;
629 587
630 if (RC_INIT == rc->state) 588 if (RC_INIT == rc->state)
631 { 589 {
@@ -661,40 +619,20 @@ event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
661 if ((GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type) && 619 if ((GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type) &&
662 (event->details.operation_finished.operation == dll_op->op)) 620 (event->details.operation_finished.operation == dll_op->op))
663 break; 621 break;
664 if ((GNUNET_TESTBED_ET_PEER_STOP == event->type) &&
665 (event->details.peer_stop.peer == dll_op->cls))
666 break;
667 } 622 }
668 if (NULL == dll_op) 623 if (NULL == dll_op)
669 goto call_cc; 624 goto call_cc;
670 GNUNET_CONTAINER_DLL_remove (rc->dll_op_head, rc->dll_op_tail, dll_op); 625 GNUNET_CONTAINER_DLL_remove (rc->dll_op_head, rc->dll_op_tail, dll_op);
671 GNUNET_TESTBED_operation_done (dll_op->op); 626 GNUNET_TESTBED_operation_done (dll_op->op);
672 GNUNET_free (dll_op); 627 GNUNET_free (dll_op);
673 rc->peer_count++;
674 if (rc->peer_count < rc->num_peers)
675 return;
676 switch (rc->state) 628 switch (rc->state)
677 { 629 {
678 case RC_PEERS_CREATED: 630 case RC_PEERS_CREATED:
679 case RC_READY: 631 case RC_READY:
680 rc->state = RC_PEERS_STOPPED; 632 rc->state = RC_PEERS_SHUTDOWN;
681 DEBUG ("Peers stopped in %s\n", prof_time (rc));
682 DEBUG ("Destroying peers\n");
683 rc->pstart_time = GNUNET_TIME_absolute_get ();
684 rc->peer_count = 0;
685 for (peer_id = 0; peer_id < rc->num_peers; peer_id++)
686 {
687 dll_op = GNUNET_malloc (sizeof (struct DLLOperation));
688 dll_op->op = GNUNET_TESTBED_peer_destroy (rc->peers[peer_id]);
689 GNUNET_CONTAINER_DLL_insert_tail (rc->dll_op_head, rc->dll_op_tail,
690 dll_op);
691 }
692 break;
693 case RC_PEERS_STOPPED:
694 rc->state = RC_PEERS_DESTROYED;
695 GNUNET_free (rc->peers); 633 GNUNET_free (rc->peers);
696 rc->peers = NULL; 634 rc->peers = NULL;
697 DEBUG ("Peers destroyed in %s\n", prof_time (rc)); 635 DEBUG ("Peers shut down in %s\n", prof_time (rc));
698 GNUNET_SCHEDULER_add_now (&cleanup_task, rc); 636 GNUNET_SCHEDULER_add_now (&cleanup_task, rc);
699 break; 637 break;
700 default: 638 default:
@@ -876,7 +814,6 @@ controller_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
876 GNUNET_CONFIGURATION_destroy (rc->cfg); 814 GNUNET_CONFIGURATION_destroy (rc->cfg);
877 rc->cfg = GNUNET_CONFIGURATION_dup (cfg); 815 rc->cfg = GNUNET_CONFIGURATION_dup (cfg);
878 event_mask = rc->event_mask; 816 event_mask = rc->event_mask;
879 event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_STOP);
880 event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED); 817 event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED);
881 event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_START); 818 event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_START);
882 if (rc->topology < GNUNET_TESTBED_TOPOLOGY_NONE) 819 if (rc->topology < GNUNET_TESTBED_TOPOLOGY_NONE)
diff --git a/src/testbed/testbed_api_topology.c b/src/testbed/testbed_api_topology.c
index 6bb1e5d73..c68d336e5 100644
--- a/src/testbed/testbed_api_topology.c
+++ b/src/testbed/testbed_api_topology.c
@@ -429,6 +429,8 @@ gen_topo_ring (struct TopologyContext *tc)
429 * @param rows number of rows in the 2d torus. Can be NULL 429 * @param rows number of rows in the 2d torus. Can be NULL
430 * @param rows_len the length of each row. This array will be allocated 430 * @param rows_len the length of each row. This array will be allocated
431 * fresh. The caller should free it. Can be NULL 431 * fresh. The caller should free it. Can be NULL
432 * @return the number of links that are required to generate a 2d torus for the
433 * given number of peers
432 */ 434 */
433unsigned int 435unsigned int
434GNUNET_TESTBED_2dtorus_calc_links (unsigned int num_peers, unsigned int *rows, 436GNUNET_TESTBED_2dtorus_calc_links (unsigned int num_peers, unsigned int *rows,
@@ -451,7 +453,7 @@ GNUNET_TESTBED_2dtorus_calc_links (unsigned int num_peers, unsigned int *rows,
451 for (y = 0; y < _rows - 1; y++) 453 for (y = 0; y < _rows - 1; y++)
452 _rows_len[y] = sq_floor; 454 _rows_len[y] = sq_floor;
453 _num_peers = sq_floor * sq_floor; 455 _num_peers = sq_floor * sq_floor;
454 cnt = 2 * _num_peers; 456 cnt = (_num_peers < 2) ? _num_peers : 2 * _num_peers;
455 x = 0; 457 x = 0;
456 y = 0; 458 y = 0;
457 while (_num_peers < num_peers) 459 while (_num_peers < num_peers)