aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2012-10-18 14:26:30 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2012-10-18 14:26:30 +0000
commit7360be56a1334394337d279676d1785ec69aa26f (patch)
tree4cf0328edf327ea8302f051d066721fa1a370694 /src
parentaadda4ec9d989fd49eea186420d4ea86b769dddd (diff)
downloadgnunet-7360be56a1334394337d279676d1785ec69aa26f.tar.gz
gnunet-7360be56a1334394337d279676d1785ec69aa26f.zip
-topology test case relaxed to accommodated overlay timeouts
-bounded overlay connects -topology API to retry on timeouts -test case configuration to include bounds on topology -cleanup of occs during shutdown
Diffstat (limited to 'src')
-rw-r--r--src/testbed/gnunet-service-testbed.c107
-rw-r--r--src/testbed/test_testbed_api.conf2
-rw-r--r--src/testbed/test_testbed_api_topology.c15
-rw-r--r--src/testbed/testbed_api_peers.c6
-rw-r--r--src/testbed/testbed_api_topology.c59
5 files changed, 137 insertions, 52 deletions
diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c
index 9c4b90653..2371d2825 100644
--- a/src/testbed/gnunet-service-testbed.c
+++ b/src/testbed/gnunet-service-testbed.c
@@ -58,7 +58,7 @@
58/** 58/**
59 * Default timeout for operations which may take some time 59 * Default timeout for operations which may take some time
60 */ 60 */
61#define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 60) 61#define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30)
62 62
63/** 63/**
64 * The main context information associated with the client which started us 64 * The main context information associated with the client which started us
@@ -497,6 +497,16 @@ struct Peer
497struct OverlayConnectContext 497struct OverlayConnectContext
498{ 498{
499 /** 499 /**
500 * The next pointer for maintaining a DLL
501 */
502 struct OverlayConnectContext *next;
503
504 /**
505 * The prev pointer for maintaining a DLL
506 */
507 struct OverlayConnectContext *prev;
508
509 /**
500 * The client which has requested for overlay connection 510 * The client which has requested for overlay connection
501 */ 511 */
502 struct GNUNET_SERVER_Client *client; 512 struct GNUNET_SERVER_Client *client;
@@ -573,6 +583,11 @@ struct OverlayConnectContext
573 GNUNET_SCHEDULER_TaskIdentifier timeout_task; 583 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
574 584
575 /** 585 /**
586 * The id of the cleanup task
587 */
588 GNUNET_SCHEDULER_TaskIdentifier cleanup_task;
589
590 /**
576 * The id of peer A 591 * The id of peer A
577 */ 592 */
578 uint32_t peer_id; 593 uint32_t peer_id;
@@ -777,6 +792,16 @@ static struct MessageQueue *mq_head;
777static struct MessageQueue *mq_tail; 792static struct MessageQueue *mq_tail;
778 793
779/** 794/**
795 * DLL head for OverlayConnectContext DLL - to be used to clean up during shutdown
796 */
797static struct OverlayConnectContext *occq_head;
798
799/**
800 * DLL tail for OverlayConnectContext DLL
801 */
802static struct OverlayConnectContext *occq_tail;
803
804/**
780 * Array of hosts 805 * Array of hosts
781 */ 806 */
782static struct GNUNET_TESTBED_Host **host_list; 807static struct GNUNET_TESTBED_Host **host_list;
@@ -865,6 +890,7 @@ transmit_ready_notify (void *cls, size_t size, void *buf)
865 size = ntohs (mq_entry->msg->size); 890 size = ntohs (mq_entry->msg->size);
866 memcpy (buf, mq_entry->msg, size); 891 memcpy (buf, mq_entry->msg, size);
867 GNUNET_free (mq_entry->msg); 892 GNUNET_free (mq_entry->msg);
893 GNUNET_SERVER_client_drop (mq_entry->client);
868 GNUNET_CONTAINER_DLL_remove (mq_head, mq_tail, mq_entry); 894 GNUNET_CONTAINER_DLL_remove (mq_head, mq_tail, mq_entry);
869 GNUNET_free (mq_entry); 895 GNUNET_free (mq_entry);
870 mq_entry = mq_head; 896 mq_entry = mq_head;
@@ -899,6 +925,7 @@ queue_message (struct GNUNET_SERVER_Client *client,
899 mq_entry = GNUNET_malloc (sizeof (struct MessageQueue)); 925 mq_entry = GNUNET_malloc (sizeof (struct MessageQueue));
900 mq_entry->msg = msg; 926 mq_entry->msg = msg;
901 mq_entry->client = client; 927 mq_entry->client = client;
928 GNUNET_SERVER_client_keep (client);
902 LOG_DEBUG ("Queueing message of type %u, size %u for sending\n", type, 929 LOG_DEBUG ("Queueing message of type %u, size %u for sending\n", type,
903 ntohs (msg->size)); 930 ntohs (msg->size));
904 GNUNET_CONTAINER_DLL_insert_tail (mq_head, mq_tail, mq_entry); 931 GNUNET_CONTAINER_DLL_insert_tail (mq_head, mq_tail, mq_entry);
@@ -2537,16 +2564,13 @@ handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
2537 2564
2538 2565
2539/** 2566/**
2540 * Task for cleaing up overlay connect context structure 2567 * Cleanup overlay connect context structure
2541 * 2568 *
2542 * @param cls the overlay connect context 2569 * @param occ the overlay connect context
2543 * @param tc the task context
2544 */ 2570 */
2545static void 2571static void
2546occ_cleanup (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 2572cleanup_occ (struct OverlayConnectContext *occ)
2547{ 2573{
2548 struct OverlayConnectContext *occ = cls;
2549
2550 LOG_DEBUG ("Cleaning up occ\n"); 2574 LOG_DEBUG ("Cleaning up occ\n");
2551 GNUNET_free_non_null (occ->emsg); 2575 GNUNET_free_non_null (occ->emsg);
2552 GNUNET_free_non_null (occ->hello); 2576 GNUNET_free_non_null (occ->hello);
@@ -2555,6 +2579,10 @@ occ_cleanup (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2555 GNUNET_TESTBED_forward_operation_msg_cancel_ (occ->opc); 2579 GNUNET_TESTBED_forward_operation_msg_cancel_ (occ->opc);
2556 if (GNUNET_SCHEDULER_NO_TASK != occ->send_hello_task) 2580 if (GNUNET_SCHEDULER_NO_TASK != occ->send_hello_task)
2557 GNUNET_SCHEDULER_cancel (occ->send_hello_task); 2581 GNUNET_SCHEDULER_cancel (occ->send_hello_task);
2582 if (GNUNET_SCHEDULER_NO_TASK != occ->cleanup_task)
2583 GNUNET_SCHEDULER_cancel (occ->cleanup_task);
2584 if (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task)
2585 GNUNET_SCHEDULER_cancel (occ->timeout_task);
2558 if (NULL != occ->ch) 2586 if (NULL != occ->ch)
2559 GNUNET_CORE_disconnect (occ->ch); 2587 GNUNET_CORE_disconnect (occ->ch);
2560 if (NULL != occ->ghh) 2588 if (NULL != occ->ghh)
@@ -2563,11 +2591,28 @@ occ_cleanup (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2563 GNUNET_TRANSPORT_disconnect (occ->p1th); 2591 GNUNET_TRANSPORT_disconnect (occ->p1th);
2564 if (NULL != occ->p2th) 2592 if (NULL != occ->p2th)
2565 GNUNET_TRANSPORT_disconnect (occ->p2th); 2593 GNUNET_TRANSPORT_disconnect (occ->p2th);
2594 GNUNET_CONTAINER_DLL_remove (occq_head, occq_tail, occ);
2566 GNUNET_free (occ); 2595 GNUNET_free (occ);
2567} 2596}
2568 2597
2569 2598
2570/** 2599/**
2600 * Task for cleaing up overlay connect context structure
2601 *
2602 * @param cls the overlay connect context
2603 * @param tc the task context
2604 */
2605static void
2606do_cleanup_occ (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2607{
2608 struct OverlayConnectContext *occ = cls;
2609
2610 occ->cleanup_task = GNUNET_SCHEDULER_NO_TASK;
2611 cleanup_occ (occ);
2612}
2613
2614
2615/**
2571 * Task which will be run when overlay connect request has been timed out 2616 * Task which will be run when overlay connect request has been timed out
2572 * 2617 *
2573 * @param cls the OverlayConnectContext 2618 * @param cls the OverlayConnectContext
@@ -2584,7 +2629,7 @@ timeout_overlay_connect (void *cls,
2584 "Timeout while connecting peers %u and %u\n", 2629 "Timeout while connecting peers %u and %u\n",
2585 occ->peer_id, occ->other_peer_id); 2630 occ->peer_id, occ->other_peer_id);
2586 send_operation_fail_msg (occ->client, occ->op_id, occ->emsg); 2631 send_operation_fail_msg (occ->client, occ->op_id, occ->emsg);
2587 occ_cleanup (occ, tc); 2632 cleanup_occ (occ);
2588} 2633}
2589 2634
2590 2635
@@ -2652,7 +2697,8 @@ overlay_connect_notify (void *cls, const struct GNUNET_PeerIdentity *new_peer,
2652 msg->peer2 = htonl (occ->other_peer_id); 2697 msg->peer2 = htonl (occ->other_peer_id);
2653 msg->operation_id = GNUNET_htonll (occ->op_id); 2698 msg->operation_id = GNUNET_htonll (occ->op_id);
2654 queue_message (occ->client, &msg->header); 2699 queue_message (occ->client, &msg->header);
2655 GNUNET_SCHEDULER_add_now (&occ_cleanup, occ); 2700 occ->cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup_occ, occ);
2701 //cleanup_occ (occ);
2656} 2702}
2657 2703
2658 2704
@@ -2949,11 +2995,12 @@ handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client,
2949 const struct GNUNET_MessageHeader *message) 2995 const struct GNUNET_MessageHeader *message)
2950{ 2996{
2951 const struct GNUNET_TESTBED_OverlayConnectMessage *msg; 2997 const struct GNUNET_TESTBED_OverlayConnectMessage *msg;
2952 struct OverlayConnectContext *occ;
2953 const struct GNUNET_CORE_MessageHandler no_handlers[] = { 2998 const struct GNUNET_CORE_MessageHandler no_handlers[] = {
2954 {NULL, 0, 0} 2999 {NULL, 0, 0}
2955 }; 3000 };
2956 struct Peer *peer; 3001 struct Peer *peer;
3002 struct OverlayConnectContext *occ;
3003 struct GNUNET_TESTBED_Controller *peer2_controller;
2957 uint64_t operation_id; 3004 uint64_t operation_id;
2958 uint32_t p1; 3005 uint32_t p1;
2959 uint32_t p2; 3006 uint32_t p2;
@@ -3069,13 +3116,8 @@ handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client,
3069 GNUNET_SERVER_receive_done (client, GNUNET_OK); 3116 GNUNET_SERVER_receive_done (client, GNUNET_OK);
3070 return; 3117 return;
3071 } 3118 }
3072 occ = GNUNET_malloc (sizeof (struct OverlayConnectContext)); 3119
3073 GNUNET_SERVER_client_keep (client); 3120 peer2_controller = NULL;
3074 occ->client = client;
3075 occ->peer_id = p1;
3076 occ->other_peer_id = p2;
3077 occ->peer = peer_list[p1];
3078 occ->op_id = GNUNET_ntohll (msg->operation_id);
3079 if ((p2 >= peer_list_size) || (NULL == peer_list[p2])) 3121 if ((p2 >= peer_list_size) || (NULL == peer_list[p2]))
3080 { 3122 {
3081 if ((peer2_host_id >= slave_list_size) 3123 if ((peer2_host_id >= slave_list_size)
@@ -3084,8 +3126,7 @@ handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client,
3084 struct GNUNET_TESTBED_NeedControllerConfig *reply; 3126 struct GNUNET_TESTBED_NeedControllerConfig *reply;
3085 3127
3086 LOG_DEBUG ("Need controller configuration for connecting peers %u and %u\n", 3128 LOG_DEBUG ("Need controller configuration for connecting peers %u and %u\n",
3087 occ->peer_id, occ->other_peer_id); 3129 p1, p2);
3088 GNUNET_free (occ);
3089 reply = GNUNET_malloc (sizeof (struct 3130 reply = GNUNET_malloc (sizeof (struct
3090 GNUNET_TESTBED_NeedControllerConfig)); 3131 GNUNET_TESTBED_NeedControllerConfig));
3091 reply->header.size = htons (sizeof (struct 3132 reply->header.size = htons (sizeof (struct
@@ -3099,12 +3140,11 @@ handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client,
3099 } 3140 }
3100 else 3141 else
3101 { 3142 {
3102 occ->peer2_controller = slave_list[peer2_host_id]->controller; 3143 //occ->peer2_controller = slave_list[peer2_host_id]->controller;
3103 if (NULL == occ->peer2_controller) 3144 peer2_controller = slave_list[peer2_host_id]->controller;
3145 if (NULL == peer2_controller)
3104 { 3146 {
3105 GNUNET_break (0); /* What's going on? */ 3147 GNUNET_break (0); /* What's going on? */
3106 GNUNET_SERVER_client_drop (client);
3107 GNUNET_free (occ);
3108 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 3148 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
3109 return; 3149 return;
3110 } 3150 }
@@ -3112,9 +3152,18 @@ handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client,
3112 } 3152 }
3113 else 3153 else
3114 { 3154 {
3115 if (GNUNET_YES == peer_list[occ->other_peer_id]->is_remote) 3155 if (GNUNET_YES == peer_list[p2]->is_remote)
3116 occ->peer2_controller = peer_list[occ->other_peer_id]->details.remote.slave->controller; 3156 peer2_controller = peer_list[p2]->details.remote.slave->controller;
3117 } 3157 }
3158 occ = GNUNET_malloc (sizeof (struct OverlayConnectContext));
3159 GNUNET_CONTAINER_DLL_insert_tail (occq_head, occq_tail, occ);
3160 GNUNET_SERVER_client_keep (client);
3161 occ->client = client;
3162 occ->peer_id = p1;
3163 occ->other_peer_id = p2;
3164 occ->peer = peer_list[p1];
3165 occ->op_id = GNUNET_ntohll (msg->operation_id);
3166 occ->peer2_controller = peer2_controller;
3118 /* Get the identity of the second peer */ 3167 /* Get the identity of the second peer */
3119 if (NULL != occ->peer2_controller) 3168 if (NULL != occ->peer2_controller)
3120 { 3169 {
@@ -3449,6 +3498,7 @@ static void
3449shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 3498shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3450{ 3499{
3451 struct LCFContextQueue *lcfq; 3500 struct LCFContextQueue *lcfq;
3501 struct OverlayConnectContext *occ;
3452 uint32_t id; 3502 uint32_t id;
3453 3503
3454 shutdown_task_id = GNUNET_SCHEDULER_NO_TASK; 3504 shutdown_task_id = GNUNET_SCHEDULER_NO_TASK;
@@ -3472,6 +3522,8 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3472 GNUNET_CONTAINER_DLL_remove (lcfq_head, lcfq_tail, lcfq); 3522 GNUNET_CONTAINER_DLL_remove (lcfq_head, lcfq_tail, lcfq);
3473 GNUNET_free (lcfq); 3523 GNUNET_free (lcfq);
3474 } 3524 }
3525 while (NULL != (occ = occq_head))
3526 cleanup_occ (occ);
3475 /* Clear peer list */ 3527 /* Clear peer list */
3476 for (id = 0; id < peer_list_size; id++) 3528 for (id = 0; id < peer_list_size; id++)
3477 if (NULL != peer_list[id]) 3529 if (NULL != peer_list[id])
@@ -3605,8 +3657,9 @@ testbed_run (void *cls, struct GNUNET_SERVER_Handle *server,
3605 GNUNET_SERVER_disconnect_notify (server, &client_disconnect_cb, NULL); 3657 GNUNET_SERVER_disconnect_notify (server, &client_disconnect_cb, NULL);
3606 ss_map = GNUNET_CONTAINER_multihashmap_create (5, GNUNET_NO); 3658 ss_map = GNUNET_CONTAINER_multihashmap_create (5, GNUNET_NO);
3607 shutdown_task_id = 3659 shutdown_task_id =
3608 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, 3660 GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_UNIT_FOREVER_REL,
3609 &shutdown_task, NULL); 3661 GNUNET_SCHEDULER_PRIORITY_IDLE,
3662 &shutdown_task, NULL);
3610 LOG_DEBUG ("Testbed startup complete\n"); 3663 LOG_DEBUG ("Testbed startup complete\n");
3611 event_mask = 1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED; 3664 event_mask = 1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED;
3612} 3665}
diff --git a/src/testbed/test_testbed_api.conf b/src/testbed/test_testbed_api.conf
index 2fdefcc1f..dfdfdb93b 100644
--- a/src/testbed/test_testbed_api.conf
+++ b/src/testbed/test_testbed_api.conf
@@ -3,6 +3,8 @@ AUTOSTART = NO
3PORT = 12113 3PORT = 12113
4ACCEPT_FROM = 127.0.0.1; 4ACCEPT_FROM = 127.0.0.1;
5HOSTNAME = localhost 5HOSTNAME = localhost
6NEIGHBOUR_LIMIT = 100
7MAX_PARALLEL_OVERLAY_CONNECT_OPERATIONS = 10
6#PREFIX = xterm -geometry 100x85 -T peer1 -e libtool --mode=execute gdb --args 8#PREFIX = xterm -geometry 100x85 -T peer1 -e libtool --mode=execute gdb --args
7 9
8[fs] 10[fs]
diff --git a/src/testbed/test_testbed_api_topology.c b/src/testbed/test_testbed_api_topology.c
index 91a9f4bde..8e673d293 100644
--- a/src/testbed/test_testbed_api_topology.c
+++ b/src/testbed/test_testbed_api_topology.c
@@ -44,6 +44,11 @@ static struct GNUNET_TESTBED_Peer **peers;
44static struct GNUNET_TESTBED_Operation *op; 44static struct GNUNET_TESTBED_Operation *op;
45 45
46/** 46/**
47 * Shutdown task
48 */
49static GNUNET_SCHEDULER_TaskIdentifier shutdown_task;
50
51/**
47 * Testing result 52 * Testing result
48 */ 53 */
49static int result; 54static int result;
@@ -63,6 +68,7 @@ static unsigned int overlay_connects;
63static void 68static void
64do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 69do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
65{ 70{
71 shutdown_task = GNUNET_SCHEDULER_NO_TASK;
66 if (NULL != op) 72 if (NULL != op)
67 { 73 {
68 GNUNET_TESTBED_operation_done (op); 74 GNUNET_TESTBED_operation_done (op);
@@ -91,6 +97,9 @@ controller_event_cb (void *cls,
91 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); 97 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
92 } 98 }
93 break; 99 break;
100 case GNUNET_TESTBED_ET_OPERATION_FINISHED:
101 GNUNET_assert (NULL != event->details.operation_finished.emsg);
102 break;
94 default: 103 default:
95 GNUNET_break (0); 104 GNUNET_break (0);
96 if ((GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type) && 105 if ((GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type) &&
@@ -99,7 +108,8 @@ controller_event_cb (void *cls,
99 "An operation failed with error: %s\n", 108 "An operation failed with error: %s\n",
100 event->details.operation_finished.emsg); 109 event->details.operation_finished.emsg);
101 result = GNUNET_SYSERR; 110 result = GNUNET_SYSERR;
102 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); 111 GNUNET_SCHEDULER_cancel (shutdown_task);
112 shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
103 } 113 }
104} 114}
105 115
@@ -128,6 +138,9 @@ test_master (void *cls, unsigned int num_peers,
128 GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI, 138 GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI,
129 NUM_PEERS); 139 NUM_PEERS);
130 GNUNET_assert (NULL != op); 140 GNUNET_assert (NULL != op);
141 shutdown_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
142 (GNUNET_TIME_UNIT_SECONDS, 120),
143 do_shutdown, NULL);
131} 144}
132 145
133 146
diff --git a/src/testbed/testbed_api_peers.c b/src/testbed/testbed_api_peers.c
index 3c3f478ea..07103ca89 100644
--- a/src/testbed/testbed_api_peers.c
+++ b/src/testbed/testbed_api_peers.c
@@ -357,7 +357,7 @@ oprelease_overlay_connect (void *cls)
357{ 357{
358 struct OperationContext *opc = cls; 358 struct OperationContext *opc = cls;
359 359
360 if (OPC_STATE_FINISHED != opc->state) 360 if (OPC_STATE_STARTED == opc->state)
361 { 361 {
362 GNUNET_free (opc->data); 362 GNUNET_free (opc->data);
363 GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc); 363 GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc);
@@ -720,8 +720,8 @@ GNUNET_TESTBED_overlay_connect (void *op_cls,
720 opc->op = 720 opc->op =
721 GNUNET_TESTBED_operation_create_ (opc, &opstart_overlay_connect, 721 GNUNET_TESTBED_operation_create_ (opc, &opstart_overlay_connect,
722 &oprelease_overlay_connect); 722 &oprelease_overlay_connect);
723 GNUNET_TESTBED_operation_queue_insert_ (opc->c->opq_parallel_operations, 723 /* GNUNET_TESTBED_operation_queue_insert_ (opc->c->opq_parallel_operations, */
724 opc->op); 724 /* opc->op); */
725 GNUNET_TESTBED_operation_queue_insert_ 725 GNUNET_TESTBED_operation_queue_insert_
726 (opc->c->opq_parallel_overlay_connect_operations, opc->op); 726 (opc->c->opq_parallel_overlay_connect_operations, opc->op);
727 return opc->op; 727 return opc->op;
diff --git a/src/testbed/testbed_api_topology.c b/src/testbed/testbed_api_topology.c
index 22e9207f3..0e237cde3 100644
--- a/src/testbed/testbed_api_topology.c
+++ b/src/testbed/testbed_api_topology.c
@@ -35,11 +35,29 @@
35#define LOG(kind,...) \ 35#define LOG(kind,...) \
36 GNUNET_log_from (kind, "testbed-api-topology", __VA_ARGS__) 36 GNUNET_log_from (kind, "testbed-api-topology", __VA_ARGS__)
37 37
38
39/**
40 * Context information for topology operations
41 */
42struct TopologyContext;
43
44
38/** 45/**
39 * Representation of an overlay link 46 * Representation of an overlay link
40 */ 47 */
41struct OverlayLink 48struct OverlayLink
42{ 49{
50
51 /**
52 * An operation corresponding to this link
53 */
54 struct GNUNET_TESTBED_Operation *op;
55
56 /**
57 * The topology context this link is a part of
58 */
59 struct TopologyContext *tc;
60
43 /** 61 /**
44 * position of peer A's handle in peers array 62 * position of peer A's handle in peers array
45 */ 63 */
@@ -69,13 +87,6 @@ struct TopologyContext
69 struct OverlayLink *link_array; 87 struct OverlayLink *link_array;
70 88
71 /** 89 /**
72 * An array of operations resulting from the links we try to establish; the
73 * number of operations in this array is equal to link_array_size (1 link = 1
74 * operation)
75 */
76 struct GNUNET_TESTBED_Operation **link_ops;
77
78 /**
79 * The operation closure 90 * The operation closure
80 */ 91 */
81 void *op_cls; 92 void *op_cls;
@@ -101,15 +112,23 @@ overlay_link_completed (void *cls,
101 struct GNUNET_TESTBED_Operation *op, 112 struct GNUNET_TESTBED_Operation *op,
102 const char *emsg) 113 const char *emsg)
103{ 114{
104 struct GNUNET_TESTBED_Operation **link_op = cls; 115 struct OverlayLink *link = cls;
116 struct TopologyContext *tc;
105 117
106 GNUNET_assert (*link_op == op); 118 GNUNET_assert (op == link->op);
107 GNUNET_TESTBED_operation_done (op); 119 GNUNET_TESTBED_operation_done (op);
108 *link_op = NULL; 120 link->op = NULL;
109 if (NULL != emsg) 121 if (NULL != emsg)
110 { 122 {
123 tc = link->tc;
111 LOG (GNUNET_ERROR_TYPE_WARNING, 124 LOG (GNUNET_ERROR_TYPE_WARNING,
112 "Error while establishing a link: %s\n", emsg); 125 "Error while establishing a link: %s -- Retrying\n", emsg);
126 link->op =
127 GNUNET_TESTBED_overlay_connect (tc->op_cls,
128 &overlay_link_completed,
129 link,
130 tc->peers[link->A],
131 tc->peers[link->B]);
113 return; 132 return;
114 } 133 }
115} 134}
@@ -127,13 +146,11 @@ opstart_overlay_configure_topology (void *cls)
127 struct TopologyContext *tc = cls; 146 struct TopologyContext *tc = cls;
128 unsigned int p; 147 unsigned int p;
129 148
130 tc->link_ops = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Operations *)
131 * tc->link_array_size);
132 for (p = 0; p < tc->link_array_size; p++) 149 for (p = 0; p < tc->link_array_size; p++)
133 { 150 {
134 tc->link_ops[p] = 151 tc->link_array[p].op =
135 GNUNET_TESTBED_overlay_connect (tc->op_cls, &overlay_link_completed, 152 GNUNET_TESTBED_overlay_connect (tc->op_cls, &overlay_link_completed,
136 &tc->link_ops[p], 153 &tc->link_array[p],
137 tc->peers[tc->link_array[p].A], 154 tc->peers[tc->link_array[p].A],
138 tc->peers[tc->link_array[p].B]); 155 tc->peers[tc->link_array[p].B]);
139 } 156 }
@@ -151,14 +168,13 @@ oprelease_overlay_configure_topology (void *cls)
151 struct TopologyContext *tc = cls; 168 struct TopologyContext *tc = cls;
152 unsigned int p; 169 unsigned int p;
153 170
154 if (NULL != tc->link_ops) 171 if (NULL != tc->link_array)
155 { 172 {
156 for (p = 0; p < tc->link_array_size; p++) 173 for (p = 0; p < tc->link_array_size; p++)
157 if (NULL != tc->link_ops[p]) 174 if (NULL != tc->link_array[p].op)
158 GNUNET_TESTBED_operation_cancel (tc->link_ops[p]); 175 GNUNET_TESTBED_operation_cancel (tc->link_array[p].op);
159 GNUNET_free (tc->link_ops); 176 GNUNET_free (tc->link_array);
160 } 177 }
161 GNUNET_free_non_null (tc->link_array);
162 GNUNET_free (tc); 178 GNUNET_free (tc);
163} 179}
164 180
@@ -242,7 +258,7 @@ GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls,
242 c = peers[0]->controller; 258 c = peers[0]->controller;
243 tc = GNUNET_malloc (sizeof (struct TopologyContext)); 259 tc = GNUNET_malloc (sizeof (struct TopologyContext));
244 tc->peers = peers; 260 tc->peers = peers;
245 tc->op_cls = tc->op_cls; 261 tc->op_cls = op_cls;
246 switch (topo) 262 switch (topo)
247 { 263 {
248 case GNUNET_TESTBED_TOPOLOGY_LINE: 264 case GNUNET_TESTBED_TOPOLOGY_LINE:
@@ -272,6 +288,7 @@ GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls,
272 } while (A_rand == B_rand); 288 } while (A_rand == B_rand);
273 tc->link_array[cnt].A = A_rand; 289 tc->link_array[cnt].A = A_rand;
274 tc->link_array[cnt].B = B_rand; 290 tc->link_array[cnt].B = B_rand;
291 tc->link_array[cnt].tc = tc;
275 } 292 }
276 break; 293 break;
277 default: 294 default: