slave get config client part
[oweals/gnunet.git] / src / testbed / testbed_api_topology.c
1 /*
2       This file is part of GNUnet
3       (C) 2008--2012 Christian Grothoff (and other contributing authors)
4
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.
9
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.
14
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.
19  */
20
21 /**
22  * @file testbed/testbed_api_topology.c
23  * @brief topology-generation functions
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_testbed_service.h"
28 #include "testbed_api.h"
29 #include "testbed_api_peers.h"
30 #include "testbed_api_operations.h"
31
32
33 /**
34  * Representation of an overlay link
35  */
36 struct OverlayLink
37 {
38   /**
39    * position of peer A's handle in peers array
40    */
41   uint32_t A;
42
43   /**
44    * position of peer B's handle in peers array
45    */
46   uint32_t B;
47
48 };
49
50
51 /**
52  * Context information for topology operations
53  */
54 struct TopologyContext
55 {
56   /**
57    * The array of peers
58    */
59   struct GNUNET_TESTBED_Peer **peers;
60
61   /**
62    * An array of links; this array is of size link_array_size
63    */
64   struct OverlayLink *link_array;
65
66   /**
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
69    * operation)
70    */
71   struct GNUNET_TESTBED_Operation **link_ops;
72
73   /**
74    * The size of the link array
75    */
76   unsigned int link_array_size;  
77   
78 };
79
80
81 /**
82  * Callback to be called when an overlay_link operation complete
83  *
84  * @param cls element of the link_op array which points to the corresponding operation
85  * @param op the operation that has been finished
86  * @param emsg error message in case the operation has failed; will be NULL if
87  *          operation has executed successfully.
88  */
89 static void 
90 overlay_link_completed (void *cls,
91                         struct GNUNET_TESTBED_Operation *op, 
92                         const char *emsg)
93 {
94   struct GNUNET_TESTBED_Operation **link_op = cls;
95
96   GNUNET_assert (*link_op == op);
97   GNUNET_TESTBED_operation_done (op);
98   *link_op = NULL;
99   if (NULL != emsg)
100   {
101     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
102                 "Error while establishing a link: %s\n", emsg);
103     return;
104   }
105 }
106
107
108
109 /**
110  * Function called when a overlay connect operation is ready
111  *
112  * @param cls the Topology context
113  */
114 static void
115 opstart_overlay_configure_topology (void *cls)
116 {
117   struct TopologyContext *tc = cls;
118   unsigned int p;
119   
120   tc->link_ops = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Operations *)
121                                 * tc->link_array_size);
122   for (p = 0; p < tc->link_array_size; p++)
123   {
124     tc->link_ops[p] =
125         GNUNET_TESTBED_overlay_connect (NULL, &overlay_link_completed,
126                                         &tc->link_ops[p],
127                                         tc->peers[tc->link_array[p].A],
128                                         tc->peers[tc->link_array[p].B]);                                                  
129   }
130 }
131
132
133 /**
134  * Callback which will be called when overlay connect operation is released
135  *
136  * @param cls the Topology context
137  */
138 static void
139 oprelease_overlay_configure_topology (void *cls)
140 {
141   struct TopologyContext *tc = cls;
142   unsigned int p;
143   
144   if (NULL != tc->link_ops)
145   {
146     for (p = 0; p < tc->link_array_size; p++)
147       if (NULL != tc->link_ops[p])
148         GNUNET_TESTBED_operation_cancel (tc->link_ops[p]);      
149     GNUNET_free (tc->link_ops);    
150   }
151   GNUNET_free_non_null (tc->link_array);
152   GNUNET_free (tc);
153 }
154
155
156 /**
157  * Configure overall network topology to have a particular shape.
158  *
159  * @param op_cls closure argument to give with the operation event
160  * @param num_peers number of peers in 'peers'
161  * @param peers array of 'num_peers' with the peers to configure
162  * @param topo desired underlay topology to use
163  * @param ap topology-specific options
164  * @return handle to the operation, NULL if configuring the topology
165  *         is not allowed at this time
166  */
167 struct GNUNET_TESTBED_Operation *
168 GNUNET_TESTBED_underlay_configure_topology_va (void *op_cls,
169                                                unsigned int num_peers,
170                                                struct GNUNET_TESTBED_Peer
171                                                **peers,
172                                                enum
173                                                GNUNET_TESTBED_TopologyOption
174                                                topo, va_list ap)
175 {
176   GNUNET_break (0);
177   return NULL;
178 }
179
180
181 /**
182  * Configure overall network topology to have a particular shape.
183  *
184  * @param op_cls closure argument to give with the operation event
185  * @param num_peers number of peers in 'peers'
186  * @param peers array of 'num_peers' with the peers to configure
187  * @param topo desired underlay topology to use
188  * @param ... topology-specific options
189  * @return handle to the operation, NULL if configuring the topology
190  *         is not allowed at this time
191  */
192 struct GNUNET_TESTBED_Operation *
193 GNUNET_TESTBED_underlay_configure_topology (void *op_cls,
194                                             unsigned int num_peers,
195                                             struct GNUNET_TESTBED_Peer **peers,
196                                             enum GNUNET_TESTBED_TopologyOption
197                                             topo, ...)
198 {
199   GNUNET_break (0);
200   return NULL;
201 }
202
203
204 /**
205  * All peers must have been started before calling this function.
206  * This function then connects the given peers in the P2P overlay
207  * using the given topology.
208  *
209  * @param op_cls closure argument to give with the operation event
210  * @param num_peers number of peers in 'peers'
211  * @param peers array of 'num_peers' with the peers to configure
212  * @param topo desired underlay topology to use
213  * @param va topology-specific options
214  * @return handle to the operation, NULL if connecting these
215  *         peers is fundamentally not possible at this time (peers
216  *         not running or underlay disallows) or if num_peers is less than 2
217  */
218 struct GNUNET_TESTBED_Operation *
219 GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls,
220                                               unsigned int num_peers,
221                                               struct GNUNET_TESTBED_Peer **peers,
222                                               enum GNUNET_TESTBED_TopologyOption
223                                               topo, va_list va)
224 {
225   struct TopologyContext *tc;
226   struct GNUNET_TESTBED_Operation *op;
227   struct GNUNET_TESTBED_Controller *c;
228   unsigned int p;
229
230   if (num_peers < 2)
231     return NULL;
232   c = peers[0]->controller;
233   tc = GNUNET_malloc (sizeof (struct TopologyContext));
234   tc->peers = peers;
235   switch (topo)
236   {
237   case GNUNET_TESTBED_TOPOLOGY_LINE:
238     tc->link_array_size = num_peers - 1;
239     tc->link_array = GNUNET_malloc (sizeof (struct OverlayLink) *
240                                     tc->link_array_size);
241     for (p=1; p < num_peers; p++)
242     {
243       tc->link_array[p-1].A = p-1;
244       tc->link_array[p-1].B = p;
245     }
246     break;
247   default:
248     GNUNET_break (0);
249     return NULL;
250   }
251   op = GNUNET_TESTBED_operation_create_ (tc,
252                                          &opstart_overlay_configure_topology,
253                                          &oprelease_overlay_configure_topology);
254   GNUNET_TESTBED_operation_queue_insert_
255       (c->opq_parallel_topology_config_operations, op);
256   return op;
257 }
258
259
260 /**
261  * All peers must have been started before calling this function.
262  * This function then connects the given peers in the P2P overlay
263  * using the given topology.
264  *
265  * @param op_cls closure argument to give with the operation event
266  * @param num_peers number of peers in 'peers'
267  * @param peers array of 'num_peers' with the peers to configure
268  * @param topo desired underlay topology to use
269  * @param ... topology-specific options
270  * @return handle to the operation, NULL if connecting these
271  *         peers is fundamentally not possible at this time (peers
272  *         not running or underlay disallows) or if num_peers is less than 2
273  */
274 struct GNUNET_TESTBED_Operation *
275 GNUNET_TESTBED_overlay_configure_topology (void *op_cls, unsigned int num_peers,
276                                            struct GNUNET_TESTBED_Peer **peers,
277                                            enum GNUNET_TESTBED_TopologyOption
278                                            topo, ...)
279 {
280   struct GNUNET_TESTBED_Operation *op;
281   va_list vargs;
282
283   va_start (vargs, topo);
284   op = GNUNET_TESTBED_overlay_configure_topology_va (op_cls, num_peers, peers,
285                                                      topo, vargs);
286   va_end (vargs);
287   return op;
288 }
289
290 /* end of testbed_api_topology.c */