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"
34 * Representation of an overlay link
39 * position of peer A's handle in peers array
44 * position of peer B's handle in peers array
52 * Context information for topology operations
54 struct TopologyContext
59 struct GNUNET_TESTBED_Peer **peers;
62 * An array of links; this array is of size link_array_size
64 struct OverlayLink *link_array;
67 * An array of operations resulting from the links we try to establish; the
68 * number of operations in this array is equal to link_array_size (1 link = 1
71 struct GNUNET_TESTBED_Operation **link_ops;
74 * The operation closure
79 * The size of the link array
81 unsigned int link_array_size;
87 * Callback to be called when an overlay_link operation complete
89 * @param cls element of the link_op array which points to the corresponding operation
90 * @param op the operation that has been finished
91 * @param emsg error message in case the operation has failed; will be NULL if
92 * operation has executed successfully.
95 overlay_link_completed (void *cls,
96 struct GNUNET_TESTBED_Operation *op,
99 struct GNUNET_TESTBED_Operation **link_op = cls;
101 GNUNET_assert (*link_op == op);
102 GNUNET_TESTBED_operation_done (op);
106 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
107 "Error while establishing a link: %s\n", emsg);
115 * Function called when a overlay connect operation is ready
117 * @param cls the Topology context
120 opstart_overlay_configure_topology (void *cls)
122 struct TopologyContext *tc = cls;
125 tc->link_ops = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Operations *)
126 * tc->link_array_size);
127 for (p = 0; p < tc->link_array_size; p++)
130 GNUNET_TESTBED_overlay_connect (tc->op_cls, &overlay_link_completed,
132 tc->peers[tc->link_array[p].A],
133 tc->peers[tc->link_array[p].B]);
139 * Callback which will be called when overlay connect operation is released
141 * @param cls the Topology context
144 oprelease_overlay_configure_topology (void *cls)
146 struct TopologyContext *tc = cls;
149 if (NULL != tc->link_ops)
151 for (p = 0; p < tc->link_array_size; p++)
152 if (NULL != tc->link_ops[p])
153 GNUNET_TESTBED_operation_cancel (tc->link_ops[p]);
154 GNUNET_free (tc->link_ops);
156 GNUNET_free_non_null (tc->link_array);
162 * Configure overall network topology to have a particular shape.
164 * @param op_cls closure argument to give with the operation event
165 * @param num_peers number of peers in 'peers'
166 * @param peers array of 'num_peers' with the peers to configure
167 * @param topo desired underlay topology to use
168 * @param ap topology-specific options
169 * @return handle to the operation, NULL if configuring the topology
170 * is not allowed at this time
172 struct GNUNET_TESTBED_Operation *
173 GNUNET_TESTBED_underlay_configure_topology_va (void *op_cls,
174 unsigned int num_peers,
175 struct GNUNET_TESTBED_Peer
178 GNUNET_TESTBED_TopologyOption
187 * Configure overall network topology to have a particular shape.
189 * @param op_cls closure argument to give with the operation event
190 * @param num_peers number of peers in 'peers'
191 * @param peers array of 'num_peers' with the peers to configure
192 * @param topo desired underlay topology to use
193 * @param ... topology-specific options
194 * @return handle to the operation, NULL if configuring the topology
195 * is not allowed at this time
197 struct GNUNET_TESTBED_Operation *
198 GNUNET_TESTBED_underlay_configure_topology (void *op_cls,
199 unsigned int num_peers,
200 struct GNUNET_TESTBED_Peer **peers,
201 enum GNUNET_TESTBED_TopologyOption
210 * All peers must have been started before calling this function.
211 * This function then connects the given peers in the P2P overlay
212 * using the given topology.
214 * @param op_cls closure argument to give with the operation event
215 * @param num_peers number of peers in 'peers'
216 * @param peers array of 'num_peers' with the peers to configure
217 * @param topo desired underlay topology to use
218 * @param va topology-specific options
219 * @return handle to the operation, NULL if connecting these
220 * peers is fundamentally not possible at this time (peers
221 * not running or underlay disallows) or if num_peers is less than 2
223 struct GNUNET_TESTBED_Operation *
224 GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls,
225 unsigned int num_peers,
226 struct GNUNET_TESTBED_Peer **peers,
227 enum GNUNET_TESTBED_TopologyOption
230 struct TopologyContext *tc;
231 struct GNUNET_TESTBED_Operation *op;
232 struct GNUNET_TESTBED_Controller *c;
237 c = peers[0]->controller;
238 tc = GNUNET_malloc (sizeof (struct TopologyContext));
240 tc->op_cls = tc->op_cls;
243 case GNUNET_TESTBED_TOPOLOGY_LINE:
244 tc->link_array_size = num_peers - 1;
245 tc->link_array = GNUNET_malloc (sizeof (struct OverlayLink) *
246 tc->link_array_size);
247 for (cnt=1; cnt < num_peers; cnt++)
249 tc->link_array[cnt-1].A = cnt-1;
250 tc->link_array[cnt-1].B = cnt;
253 case GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI:
254 tc->link_array_size = va_arg (va, unsigned int);
255 tc->link_array = GNUNET_malloc (sizeof (struct OverlayLink) *
256 tc->link_array_size);
257 for (cnt = 0; cnt < tc->link_array_size; cnt++)
263 A_rand = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
265 B_rand = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
267 } while (A_rand == B_rand);
268 tc->link_array[cnt].A = A_rand;
269 tc->link_array[cnt].B = B_rand;
276 op = GNUNET_TESTBED_operation_create_ (tc,
277 &opstart_overlay_configure_topology,
278 &oprelease_overlay_configure_topology);
279 GNUNET_TESTBED_operation_queue_insert_
280 (c->opq_parallel_topology_config_operations, op);
286 * All peers must have been started before calling this function.
287 * This function then connects the given peers in the P2P overlay
288 * using the given topology.
290 * @param op_cls closure argument to give with the operation event
291 * @param num_peers number of peers in 'peers'
292 * @param peers array of 'num_peers' with the peers to configure
293 * @param topo desired underlay topology to use
294 * @param ... topology-specific options
295 * @return handle to the operation, NULL if connecting these
296 * peers is fundamentally not possible at this time (peers
297 * not running or underlay disallows) or if num_peers is less than 2
299 struct GNUNET_TESTBED_Operation *
300 GNUNET_TESTBED_overlay_configure_topology (void *op_cls, unsigned int num_peers,
301 struct GNUNET_TESTBED_Peer **peers,
302 enum GNUNET_TESTBED_TopologyOption
305 struct GNUNET_TESTBED_Operation *op;
308 va_start (vargs, topo);
309 op = GNUNET_TESTBED_overlay_configure_topology_va (op_cls, num_peers, peers,
315 /* end of testbed_api_topology.c */