#include "testbed_api_peers.h"
#include "testbed_api_operations.h"
+/**
+ * Generic loggins shorthand
+ */
+#define LOG(kind,...) \
+ GNUNET_log_from (kind, "testbed-api-topology", __VA_ARGS__)
+
+
+/**
+ * Context information for topology operations
+ */
+struct TopologyContext;
+
/**
* Representation of an overlay link
*/
struct OverlayLink
{
+
+ /**
+ * An operation corresponding to this link
+ */
+ struct GNUNET_TESTBED_Operation *op;
+
+ /**
+ * The topology context this link is a part of
+ */
+ struct TopologyContext *tc;
+
/**
* position of peer A's handle in peers array
*/
struct OverlayLink *link_array;
/**
- * An array of operations resulting from the links we try to establish; the
- * number of operations in this array is equal to link_array_size (1 link = 1
- * operation)
+ * The operation closure
*/
- struct GNUNET_TESTBED_Operation **link_ops;
+ void *op_cls;
/**
* The size of the link array
*/
- unsigned int link_array_size;
+ unsigned int link_array_size;
};
struct GNUNET_TESTBED_Operation *op,
const char *emsg)
{
- struct GNUNET_TESTBED_Operation **link_op = cls;
+ struct OverlayLink *link = cls;
+ struct TopologyContext *tc;
- GNUNET_assert (*link_op == op);
+ GNUNET_assert (op == link->op);
GNUNET_TESTBED_operation_done (op);
- *link_op = NULL;
+ link->op = NULL;
if (NULL != emsg)
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Error while establishing a link: %s\n", emsg);
+ tc = link->tc;
+ 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]);
return;
}
}
struct TopologyContext *tc = cls;
unsigned int p;
- tc->link_ops = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Operations *)
- * tc->link_array_size);
for (p = 0; p < tc->link_array_size; p++)
{
- tc->link_ops[p] =
- GNUNET_TESTBED_overlay_connect (NULL, &overlay_link_completed,
- &tc->link_ops[p],
+ tc->link_array[p].op =
+ GNUNET_TESTBED_overlay_connect (tc->op_cls, &overlay_link_completed,
+ &tc->link_array[p],
tc->peers[tc->link_array[p].A],
tc->peers[tc->link_array[p].B]);
}
struct TopologyContext *tc = cls;
unsigned int p;
- if (NULL != tc->link_ops)
+ if (NULL != tc->link_array)
{
for (p = 0; p < tc->link_array_size; p++)
- if (NULL != tc->link_ops[p])
- GNUNET_TESTBED_operation_cancel (tc->link_ops[p]);
- GNUNET_free (tc->link_ops);
+ if (NULL != tc->link_array[p].op)
+ GNUNET_TESTBED_operation_cancel (tc->link_array[p].op);
+ GNUNET_free (tc->link_array);
}
- GNUNET_free_non_null (tc->link_array);
GNUNET_free (tc);
}
struct TopologyContext *tc;
struct GNUNET_TESTBED_Operation *op;
struct GNUNET_TESTBED_Controller *c;
- unsigned int p;
+ unsigned int cnt;
if (num_peers < 2)
return NULL;
c = peers[0]->controller;
tc = GNUNET_malloc (sizeof (struct TopologyContext));
tc->peers = peers;
+ tc->op_cls = op_cls;
switch (topo)
{
case GNUNET_TESTBED_TOPOLOGY_LINE:
tc->link_array_size = num_peers - 1;
tc->link_array = GNUNET_malloc (sizeof (struct OverlayLink) *
tc->link_array_size);
- for (p=1; p < num_peers; p++)
+ for (cnt=1; cnt < num_peers; cnt++)
+ {
+ tc->link_array[cnt-1].A = cnt-1;
+ tc->link_array[cnt-1].B = cnt;
+ tc->link_array[cnt-1].tc = tc;
+ }
+ break;
+ case GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI:
+ tc->link_array_size = va_arg (va, unsigned int);
+ tc->link_array = GNUNET_malloc (sizeof (struct OverlayLink) *
+ tc->link_array_size);
+ for (cnt = 0; cnt < tc->link_array_size; cnt++)
{
- tc->link_array[p-1].A = p-1;
- tc->link_array[p-1].B = p;
+ uint32_t A_rand;
+ uint32_t B_rand;
+
+ do {
+ A_rand = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
+ num_peers);
+ B_rand = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
+ num_peers);
+ } while (A_rand == B_rand);
+ tc->link_array[cnt].A = A_rand;
+ tc->link_array[cnt].B = B_rand;
+ tc->link_array[cnt].tc = tc;
}
break;
default: