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;
103 * Callback to be called when an overlay_link operation complete
105 * @param cls element of the link_op array which points to the corresponding operation
106 * @param op the operation that has been finished
107 * @param emsg error message in case the operation has failed; will be NULL if
108 * operation has executed successfully.
111 overlay_link_completed (void *cls,
112 struct GNUNET_TESTBED_Operation *op,
115 struct OverlayLink *link = cls;
116 struct TopologyContext *tc;
118 GNUNET_assert (op == link->op);
119 GNUNET_TESTBED_operation_done (op);
124 LOG (GNUNET_ERROR_TYPE_WARNING,
125 "Error while establishing a link: %s -- Retrying\n", emsg);
127 GNUNET_TESTBED_overlay_connect (tc->op_cls,
128 &overlay_link_completed,
139 * Function called when a overlay connect operation is ready
141 * @param cls the Topology context
144 opstart_overlay_configure_topology (void *cls)
146 struct TopologyContext *tc = cls;
149 for (p = 0; p < tc->link_array_size; p++)
151 tc->link_array[p].op =
152 GNUNET_TESTBED_overlay_connect (tc->op_cls, &overlay_link_completed,
154 tc->peers[tc->link_array[p].A],
155 tc->peers[tc->link_array[p].B]);
161 * Callback which will be called when overlay connect operation is released
163 * @param cls the Topology context
166 oprelease_overlay_configure_topology (void *cls)
168 struct TopologyContext *tc = cls;
171 if (NULL != tc->link_array)
173 for (p = 0; p < tc->link_array_size; p++)
174 if (NULL != tc->link_array[p].op)
175 GNUNET_TESTBED_operation_cancel (tc->link_array[p].op);
176 GNUNET_free (tc->link_array);
183 * Configure overall network topology to have a particular shape.
185 * @param op_cls closure argument to give with the operation event
186 * @param num_peers number of peers in 'peers'
187 * @param peers array of 'num_peers' with the peers to configure
188 * @param topo desired underlay topology to use
189 * @param ap topology-specific options
190 * @return handle to the operation, NULL if configuring the topology
191 * is not allowed at this time
193 struct GNUNET_TESTBED_Operation *
194 GNUNET_TESTBED_underlay_configure_topology_va (void *op_cls,
195 unsigned int num_peers,
196 struct GNUNET_TESTBED_Peer
199 GNUNET_TESTBED_TopologyOption
208 * Configure overall network topology to have a particular shape.
210 * @param op_cls closure argument to give with the operation event
211 * @param num_peers number of peers in 'peers'
212 * @param peers array of 'num_peers' with the peers to configure
213 * @param topo desired underlay topology to use
214 * @param ... topology-specific options
215 * @return handle to the operation, NULL if configuring the topology
216 * is not allowed at this time
218 struct GNUNET_TESTBED_Operation *
219 GNUNET_TESTBED_underlay_configure_topology (void *op_cls,
220 unsigned int num_peers,
221 struct GNUNET_TESTBED_Peer **peers,
222 enum GNUNET_TESTBED_TopologyOption
231 * All peers must have been started before calling this function.
232 * This function then connects the given peers in the P2P overlay
233 * using the given topology.
235 * @param op_cls closure argument to give with the operation event
236 * @param num_peers number of peers in 'peers'
237 * @param peers array of 'num_peers' with the peers to configure
238 * @param topo desired underlay topology to use
239 * @param va topology-specific options
240 * @return handle to the operation, NULL if connecting these
241 * peers is fundamentally not possible at this time (peers
242 * not running or underlay disallows) or if num_peers is less than 2
244 struct GNUNET_TESTBED_Operation *
245 GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls,
246 unsigned int num_peers,
247 struct GNUNET_TESTBED_Peer **peers,
248 enum GNUNET_TESTBED_TopologyOption
251 struct TopologyContext *tc;
252 struct GNUNET_TESTBED_Operation *op;
253 struct GNUNET_TESTBED_Controller *c;
258 c = peers[0]->controller;
259 tc = GNUNET_malloc (sizeof (struct TopologyContext));
264 case GNUNET_TESTBED_TOPOLOGY_LINE:
265 tc->link_array_size = num_peers - 1;
266 tc->link_array = GNUNET_malloc (sizeof (struct OverlayLink) *
267 tc->link_array_size);
268 for (cnt=1; cnt < num_peers; cnt++)
270 tc->link_array[cnt-1].A = cnt-1;
271 tc->link_array[cnt-1].B = cnt;
272 tc->link_array[cnt-1].tc = tc;
275 case GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI:
276 tc->link_array_size = va_arg (va, unsigned int);
277 tc->link_array = GNUNET_malloc (sizeof (struct OverlayLink) *
278 tc->link_array_size);
279 for (cnt = 0; cnt < tc->link_array_size; cnt++)
285 A_rand = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
287 B_rand = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
289 } while (A_rand == B_rand);
290 tc->link_array[cnt].A = A_rand;
291 tc->link_array[cnt].B = B_rand;
292 tc->link_array[cnt].tc = tc;
299 op = GNUNET_TESTBED_operation_create_ (tc,
300 &opstart_overlay_configure_topology,
301 &oprelease_overlay_configure_topology);
302 GNUNET_TESTBED_operation_queue_insert_
303 (c->opq_parallel_topology_config_operations, op);
309 * All peers must have been started before calling this function.
310 * This function then connects the given peers in the P2P overlay
311 * using the given topology.
313 * @param op_cls closure argument to give with the operation event
314 * @param num_peers number of peers in 'peers'
315 * @param peers array of 'num_peers' with the peers to configure
316 * @param topo desired underlay topology to use
317 * @param ... topology-specific options
318 * @return handle to the operation, NULL if connecting these
319 * peers is fundamentally not possible at this time (peers
320 * not running or underlay disallows) or if num_peers is less than 2
322 struct GNUNET_TESTBED_Operation *
323 GNUNET_TESTBED_overlay_configure_topology (void *op_cls, unsigned int num_peers,
324 struct GNUNET_TESTBED_Peer **peers,
325 enum GNUNET_TESTBED_TopologyOption
328 struct GNUNET_TESTBED_Operation *op;
331 va_start (vargs, topo);
332 op = GNUNET_TESTBED_overlay_configure_topology_va (op_cls, num_peers, peers,
338 /* end of testbed_api_topology.c */