2 This file is part of GNUnet
3 (C) 2008--2012 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file testbed/testbed_api_topology.c
23 * @brief topology-generation functions
24 * @author Christian Grothoff
27 #include "gnunet_testbed_service.h"
28 #include "testbed_api.h"
29 #include "testbed_api_peers.h"
30 #include "testbed_api_operations.h"
33 * Generic loggins shorthand
35 #define LOG(kind,...) \
36 GNUNET_log_from (kind, "testbed-api-topology", __VA_ARGS__)
40 * Context information for topology operations
42 struct TopologyContext;
46 * Representation of an overlay link
52 * An operation corresponding to this link
54 struct GNUNET_TESTBED_Operation *op;
57 * The topology context this link is a part of
59 struct TopologyContext *tc;
62 * position of peer A's handle in peers array
67 * position of peer B's handle in peers array
75 * Context information for topology operations
77 struct TopologyContext
82 struct GNUNET_TESTBED_Peer **peers;
85 * An array of links; this array is of size link_array_size
87 struct OverlayLink *link_array;
90 * The operation closure
95 * The size of the link array
97 unsigned int link_array_size;
100 * should the automatic retry be disabled
108 * Callback to be called when an overlay_link operation complete
110 * @param cls element of the link_op array which points to the corresponding operation
111 * @param op the operation that has been finished
112 * @param emsg error message in case the operation has failed; will be NULL if
113 * operation has executed successfully.
116 overlay_link_completed (void *cls,
117 struct GNUNET_TESTBED_Operation *op,
120 struct OverlayLink *link = cls;
121 struct TopologyContext *tc;
123 GNUNET_assert (op == link->op);
124 GNUNET_TESTBED_operation_done (op);
127 if ((NULL != emsg) && (GNUNET_NO == tc->disable_retry))
129 LOG (GNUNET_ERROR_TYPE_WARNING,
130 "Error while establishing a link: %s -- Retrying\n", emsg);
132 GNUNET_TESTBED_overlay_connect (tc->op_cls,
133 &overlay_link_completed,
144 * Function called when a overlay connect operation is ready
146 * @param cls the Topology context
149 opstart_overlay_configure_topology (void *cls)
151 struct TopologyContext *tc = cls;
154 for (p = 0; p < tc->link_array_size; p++)
156 tc->link_array[p].op =
157 GNUNET_TESTBED_overlay_connect (tc->op_cls, &overlay_link_completed,
159 tc->peers[tc->link_array[p].A],
160 tc->peers[tc->link_array[p].B]);
166 * Callback which will be called when overlay connect operation is released
168 * @param cls the Topology context
171 oprelease_overlay_configure_topology (void *cls)
173 struct TopologyContext *tc = cls;
176 if (NULL != tc->link_array)
178 for (p = 0; p < tc->link_array_size; p++)
179 if (NULL != tc->link_array[p].op)
180 GNUNET_TESTBED_operation_done (tc->link_array[p].op);
181 GNUNET_free (tc->link_array);
188 * Configure overall network topology to have a particular shape.
190 * @param op_cls closure argument to give with the operation event
191 * @param num_peers number of peers in 'peers'
192 * @param peers array of 'num_peers' with the peers to configure
193 * @param topo desired underlay topology to use
194 * @param ap topology-specific options
195 * @return handle to the operation, NULL if configuring the topology
196 * is not allowed at this time
198 struct GNUNET_TESTBED_Operation *
199 GNUNET_TESTBED_underlay_configure_topology_va (void *op_cls,
200 unsigned int num_peers,
201 struct GNUNET_TESTBED_Peer
204 GNUNET_TESTBED_TopologyOption
213 * Configure overall network topology to have a particular shape.
215 * @param op_cls closure argument to give with the operation event
216 * @param num_peers number of peers in 'peers'
217 * @param peers array of 'num_peers' with the peers to configure
218 * @param topo desired underlay topology to use
219 * @param ... topology-specific options
220 * @return handle to the operation, NULL if configuring the topology
221 * is not allowed at this time
223 struct GNUNET_TESTBED_Operation *
224 GNUNET_TESTBED_underlay_configure_topology (void *op_cls,
225 unsigned int num_peers,
226 struct GNUNET_TESTBED_Peer **peers,
227 enum GNUNET_TESTBED_TopologyOption
236 * All peers must have been started before calling this function.
237 * This function then connects the given peers in the P2P overlay
238 * using the given topology.
240 * @param op_cls closure argument to give with the operation event
241 * @param num_peers number of peers in 'peers'
242 * @param peers array of 'num_peers' with the peers to configure
243 * @param topo desired underlay topology to use
244 * @param va topology-specific options
245 * @return handle to the operation, NULL if connecting these
246 * peers is fundamentally not possible at this time (peers
247 * not running or underlay disallows) or if num_peers is less than 2
249 struct GNUNET_TESTBED_Operation *
250 GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls,
251 unsigned int num_peers,
252 struct GNUNET_TESTBED_Peer **peers,
253 enum GNUNET_TESTBED_TopologyOption
256 struct TopologyContext *tc;
257 struct GNUNET_TESTBED_Operation *op;
258 struct GNUNET_TESTBED_Controller *c;
259 enum GNUNET_TESTBED_TopologyOption secondary_option;
264 c = peers[0]->controller;
265 tc = GNUNET_malloc (sizeof (struct TopologyContext));
270 case GNUNET_TESTBED_TOPOLOGY_LINE:
271 tc->link_array_size = num_peers - 1;
272 tc->link_array = GNUNET_malloc (sizeof (struct OverlayLink) *
273 tc->link_array_size);
274 for (cnt=1; cnt < num_peers; cnt++)
276 tc->link_array[cnt-1].A = cnt-1;
277 tc->link_array[cnt-1].B = cnt;
278 tc->link_array[cnt-1].tc = tc;
281 case GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI:
282 tc->link_array_size = va_arg (va, unsigned int);
283 tc->link_array = GNUNET_malloc (sizeof (struct OverlayLink) *
284 tc->link_array_size);
285 for (cnt = 0; cnt < tc->link_array_size; cnt++)
291 A_rand = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
293 B_rand = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
295 } while (A_rand == B_rand);
296 tc->link_array[cnt].A = A_rand;
297 tc->link_array[cnt].B = B_rand;
298 tc->link_array[cnt].tc = tc;
301 case GNUNET_TESTBED_TOPOLOGY_CLIQUE:
302 tc->link_array_size = num_peers * (num_peers - 1);
303 tc->link_array = GNUNET_malloc (sizeof (struct OverlayLink) *
304 tc->link_array_size);
309 for (cnt=0; cnt < num_peers; cnt++)
311 unsigned int neighbour;
313 for (neighbour=0; neighbour < num_peers; neighbour++)
315 if (neighbour == cnt)
317 tc->link_array[offset].A = cnt;
318 tc->link_array[offset].B = neighbour;
319 tc->link_array[offset].tc = tc;
331 secondary_option = va_arg (va, enum GNUNET_TESTBED_TopologyOption);
332 switch (secondary_option)
334 case GNUNET_TESTBED_TOPOLOGY_DISABLE_AUTO_RETRY:
335 tc->disable_retry = GNUNET_YES;
337 case GNUNET_TESTBED_TOPOLOGY_OPTION_END:
340 GNUNET_break (0); /* Should not use any other option apart from
341 the ones handled here */
342 GNUNET_free_non_null (tc->link_array);
346 } while (GNUNET_TESTBED_TOPOLOGY_OPTION_END != secondary_option);
347 op = GNUNET_TESTBED_operation_create_ (tc,
348 &opstart_overlay_configure_topology,
349 &oprelease_overlay_configure_topology);
350 GNUNET_TESTBED_operation_queue_insert_
351 (c->opq_parallel_topology_config_operations, op);
352 GNUNET_TESTBED_operation_begin_wait_ (op);
358 * All peers must have been started before calling this function.
359 * This function then connects the given peers in the P2P overlay
360 * using the given topology.
362 * @param op_cls closure argument to give with the operation event
363 * @param num_peers number of peers in 'peers'
364 * @param peers array of 'num_peers' with the peers to configure
365 * @param topo desired underlay topology to use
366 * @param ... topology-specific options
367 * @return handle to the operation, NULL if connecting these
368 * peers is fundamentally not possible at this time (peers
369 * not running or underlay disallows) or if num_peers is less than 2
371 struct GNUNET_TESTBED_Operation *
372 GNUNET_TESTBED_overlay_configure_topology (void *op_cls, unsigned int num_peers,
373 struct GNUNET_TESTBED_Peer **peers,
374 enum GNUNET_TESTBED_TopologyOption
377 struct GNUNET_TESTBED_Operation *op;
380 GNUNET_assert (topo < GNUNET_TESTBED_TOPOLOGY_OPTION_END);
381 va_start (vargs, topo);
382 op = GNUNET_TESTBED_overlay_configure_topology_va (op_cls, num_peers, peers,
388 /* end of testbed_api_topology.c */