aboutsummaryrefslogtreecommitdiff
path: root/src/transport/transport-testing.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/transport-testing.c')
-rw-r--r--src/transport/transport-testing.c649
1 files changed, 227 insertions, 422 deletions
diff --git a/src/transport/transport-testing.c b/src/transport/transport-testing.c
index 4a3bf3c3e..a2f91d761 100644
--- a/src/transport/transport-testing.c
+++ b/src/transport/transport-testing.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2006, 2009, 2015 GNUnet e.V. 3 Copyright (C) 2006, 2009, 2015, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -17,12 +17,11 @@
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA. 18 Boston, MA 02110-1301, USA.
19*/ 19*/
20
21/** 20/**
22 * @file transport-testing.c 21 * @file transport-testing.c
23 * @brief testing lib for transport service 22 * @brief testing lib for transport service
24 *
25 * @author Matthias Wachs 23 * @author Matthias Wachs
24 * @author Christian Grothoff
26 */ 25 */
27#include "transport-testing.h" 26#include "transport-testing.h"
28 27
@@ -30,41 +29,38 @@
30#define LOG(kind,...) GNUNET_log_from(kind, "transport-testing", __VA_ARGS__) 29#define LOG(kind,...) GNUNET_log_from(kind, "transport-testing", __VA_ARGS__)
31 30
32 31
33static struct PeerContext * 32static struct GNUNET_TRANSPORT_TESTING_PeerContext *
34find_peer_context (struct GNUNET_TRANSPORT_TESTING_handle *tth, 33find_peer_context (struct GNUNET_TRANSPORT_TESTING_Handle *tth,
35 const struct GNUNET_PeerIdentity *peer) 34 const struct GNUNET_PeerIdentity *peer)
36{ 35{
37 struct PeerContext *t = tth->p_head; 36 struct GNUNET_TRANSPORT_TESTING_PeerContext *t;
38 37
39 while (t != NULL) 38 for (t = tth->p_head; NULL != t; t = t->next)
40 { 39 if (0 == memcmp (&t->id,
41 if (0 == memcmp (&t->id, peer, sizeof (struct GNUNET_PeerIdentity))) 40 peer,
42 break; 41 sizeof (struct GNUNET_PeerIdentity)))
43 t = t->next; 42 return t;
44 } 43 return NULL;
45
46 return t;
47} 44}
48 45
49 46
50static struct GNUNET_TRANSPORT_TESTING_ConnectRequest * 47static struct GNUNET_TRANSPORT_TESTING_ConnectRequest *
51find_connecting_context (struct GNUNET_TRANSPORT_TESTING_handle *tth, 48find_connecting_context (struct GNUNET_TRANSPORT_TESTING_Handle *tth,
52 struct PeerContext *p1, 49 struct GNUNET_TRANSPORT_TESTING_PeerContext *p1,
53 struct PeerContext *p2) 50 struct GNUNET_TRANSPORT_TESTING_PeerContext *p2)
54{ 51{
55 GNUNET_assert (tth != NULL); 52 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
56 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc = tth->cc_head;
57 53
58 while (cc != NULL) 54 for (cc = tth->cc_head; NULL != cc; cc = cc->next)
59 { 55 {
60 if ((cc->p1 == p1) && (cc->p2 == p2)) 56 if ( (cc->p1 == p1) &&
61 break; 57 (cc->p2 == p2) )
62 if ((cc->p1 == p2) && (cc->p2 == p1)) 58 return cc;
63 break; 59 if ( (cc->p1 == p2) &&
64 cc = cc->next; 60 (cc->p2 == p1) )
61 return cc;
65 } 62 }
66 63 return NULL;
67 return cc;
68} 64}
69 65
70 66
@@ -72,20 +68,26 @@ static void
72notify_connect (void *cls, 68notify_connect (void *cls,
73 const struct GNUNET_PeerIdentity *peer) 69 const struct GNUNET_PeerIdentity *peer)
74{ 70{
75 struct PeerContext *p = cls; 71 struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
76 char *p2_s; 72 char *p2_s;
77 struct PeerContext *p2; 73 struct GNUNET_TRANSPORT_TESTING_PeerContext *p2;
74 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
78 75
79 GNUNET_assert (NULL != p); 76 p2 = find_peer_context (p->tth,
80 GNUNET_assert (NULL != p->tth); 77 peer);
81 p2 = find_peer_context (p->tth, peer); 78 if (NULL != p->nc)
82 if (p->nc != NULL) 79 p->nc (p->cb_cls,
83 p->nc (p->cb_cls, peer); 80 peer);
84 81
85 if (p2 != NULL) 82 if (p2 != NULL)
86 GNUNET_asprintf (&p2_s, "%u (`%s')", p2->no, GNUNET_i2s (&p2->id)); 83 GNUNET_asprintf (&p2_s,
84 "%u (`%s')",
85 p2->no,
86 GNUNET_i2s (&p2->id));
87 else 87 else
88 GNUNET_asprintf (&p2_s, "`%s'", GNUNET_i2s (peer)); 88 GNUNET_asprintf (&p2_s,
89 "`%s'",
90 GNUNET_i2s (peer));
89 LOG (GNUNET_ERROR_TYPE_DEBUG, 91 LOG (GNUNET_ERROR_TYPE_DEBUG,
90 "Peers %s connected to peer %u (`%s')\n", 92 "Peers %s connected to peer %u (`%s')\n",
91 p2_s, 93 p2_s,
@@ -94,21 +96,21 @@ notify_connect (void *cls,
94 GNUNET_free (p2_s); 96 GNUNET_free (p2_s);
95 97
96 /* Find ConnectingContext */ 98 /* Find ConnectingContext */
97 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc = find_connecting_context (p->tth, p, p2); 99 cc = find_connecting_context (p->tth,
98 100 p,
99 if (cc == NULL) 101 p2);
102 if (NULL == cc)
100 return; 103 return;
101
102 if (p == cc->p1) 104 if (p == cc->p1)
103 cc->p1_c = GNUNET_YES; 105 cc->p1_c = GNUNET_YES;
104
105 if (p == cc->p2) 106 if (p == cc->p2)
106 cc->p2_c = GNUNET_YES; 107 cc->p2_c = GNUNET_YES;
107 108
108 if ((cc->p1_c == GNUNET_YES) && (cc->p2_c == GNUNET_YES)) 109 if ( (cc->p1_c == GNUNET_YES) &&
110 (cc->p2_c == GNUNET_YES) )
109 { 111 {
110 cc->cb (cc->p1, cc->p2, cc->cb_cls); 112 cc->cb (cc->cb_cls);
111 GNUNET_TRANSPORT_TESTING_connect_peers_cancel (p->tth, cc); 113 GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc);
112 } 114 }
113} 115}
114 116
@@ -117,25 +119,28 @@ static void
117notify_disconnect (void *cls, 119notify_disconnect (void *cls,
118 const struct GNUNET_PeerIdentity *peer) 120 const struct GNUNET_PeerIdentity *peer)
119{ 121{
120 struct PeerContext *p = cls; 122 struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
121 123 char *p2_s;
122 /* Find PeerContext */ 124 /* Find PeerContext */
123 int no = 0; 125 int no = 0;
124 struct PeerContext *p2 = NULL; 126 struct GNUNET_TRANSPORT_TESTING_PeerContext *p2 = NULL;
125 127
126 if (p != NULL) 128 if (NULL != p)
127 { 129 {
128 GNUNET_assert (p->tth != NULL); 130 p2 = find_peer_context (p->tth,
129 p2 = find_peer_context (p->tth, peer); 131 peer);
130 no = p->no; 132 no = p->no;
131 } 133 }
132 134
133 char *p2_s;
134
135 if (p2 != NULL) 135 if (p2 != NULL)
136 GNUNET_asprintf (&p2_s, "%u (`%s')", p2->no, GNUNET_i2s (&p2->id)); 136 GNUNET_asprintf (&p2_s,
137 "%u (`%s')",
138 p2->no,
139 GNUNET_i2s (&p2->id));
137 else 140 else
138 GNUNET_asprintf (&p2_s, "`%s'", GNUNET_i2s (peer)); 141 GNUNET_asprintf (&p2_s,
142 "`%s'",
143 GNUNET_i2s (peer));
139 LOG (GNUNET_ERROR_TYPE_DEBUG, 144 LOG (GNUNET_ERROR_TYPE_DEBUG,
140 "Peers %s disconnected from peer %u (`%s')\n", 145 "Peers %s disconnected from peer %u (`%s')\n",
141 p2_s, 146 p2_s,
@@ -143,10 +148,11 @@ notify_disconnect (void *cls,
143 GNUNET_i2s (&p->id)); 148 GNUNET_i2s (&p->id));
144 GNUNET_free (p2_s); 149 GNUNET_free (p2_s);
145 150
146 if (p == NULL) 151 if (NULL == p)
147 return; 152 return;
148 if (p->nd != NULL) 153 if (NULL != p->nd)
149 p->nd (p->cb_cls, peer); 154 p->nd (p->cb_cls,
155 peer);
150} 156}
151 157
152 158
@@ -155,12 +161,14 @@ notify_receive (void *cls,
155 const struct GNUNET_PeerIdentity *peer, 161 const struct GNUNET_PeerIdentity *peer,
156 const struct GNUNET_MessageHeader *message) 162 const struct GNUNET_MessageHeader *message)
157{ 163{
158 struct PeerContext *p = cls; 164 struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
159 165
160 if (p == NULL) 166 if (NULL == p)
161 return; 167 return;
162 if (p->rec != NULL) 168 if (NULL != p->rec)
163 p->rec (p->cb_cls, peer, message); 169 p->rec (p->cb_cls,
170 peer,
171 message);
164} 172}
165 173
166 174
@@ -168,14 +176,15 @@ static void
168get_hello (void *cb_cls, 176get_hello (void *cb_cls,
169 const struct GNUNET_MessageHeader *message) 177 const struct GNUNET_MessageHeader *message)
170{ 178{
171 struct PeerContext *p = cb_cls; 179 struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cb_cls;
172 struct GNUNET_PeerIdentity hello_id; 180 struct GNUNET_PeerIdentity hello_id;
173 181
174 GNUNET_assert (message != NULL);
175 GNUNET_assert (GNUNET_OK == 182 GNUNET_assert (GNUNET_OK ==
176 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) 183 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) message,
177 message, &hello_id)); 184 &hello_id));
178 GNUNET_assert (0 == memcmp (&hello_id, &p->id, sizeof (hello_id))); 185 GNUNET_assert (0 == memcmp (&hello_id,
186 &p->id,
187 sizeof (hello_id)));
179 GNUNET_free_non_null (p->hello); 188 GNUNET_free_non_null (p->hello);
180 p->hello = (struct GNUNET_HELLO_Message *) GNUNET_copy_message (message); 189 p->hello = (struct GNUNET_HELLO_Message *) GNUNET_copy_message (message);
181 190
@@ -185,75 +194,14 @@ get_hello (void *cb_cls,
185 "Peer %u (`%s') successfully started\n", 194 "Peer %u (`%s') successfully started\n",
186 p->no, 195 p->no,
187 GNUNET_i2s (&p->id)); 196 GNUNET_i2s (&p->id));
188 p->start_cb (p, p->cb_cls); 197 p->start_cb (p,
198 p->cb_cls);
189 p->start_cb = NULL; 199 p->start_cb = NULL;
190 } 200 }
191} 201}
192 202
193 203
194/** 204/**
195 * Offer the current HELLO of P2 to P1.
196 *
197 * @param cls our `struct GNUNET_TRANSPORT_TESTING_ConnectRequest `
198 */
199static void
200offer_hello (void *cls);
201
202
203/**
204 * Function called after the HELLO was passed to the
205 * transport service.
206 */
207static void
208hello_offered (void *cls)
209{
210 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc = cls;
211
212 cc->oh = NULL;
213 cc->tct =
214 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
215 &offer_hello,
216 cc);
217}
218
219
220/**
221 * Offer the current HELLO of P2 to P1.
222 *
223 * @param cls our `struct GNUNET_TRANSPORT_TESTING_ConnectRequest`
224 */
225static void
226offer_hello (void *cls)
227{
228 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc = cls;
229 struct PeerContext *p1 = cc->p1;
230 struct PeerContext *p2 = cc->p2;
231
232 cc->tct = NULL;
233 {
234 char *p2_s = GNUNET_strdup (GNUNET_i2s (&p2->id));
235
236 LOG (GNUNET_ERROR_TYPE_DEBUG,
237 "Asking peer %u (`%s') to connect peer %u (`%s'), providing HELLO with %u bytes\n",
238 p1->no,
239 GNUNET_i2s (&p1->id),
240 p2->no,
241 p2_s,
242 GNUNET_HELLO_size (cc->p2->hello));
243 GNUNET_free (p2_s);
244 }
245
246 if (NULL != cc->oh)
247 GNUNET_TRANSPORT_offer_hello_cancel (cc->oh);
248 cc->oh =
249 GNUNET_TRANSPORT_offer_hello (cc->p1->cfg,
250 (const struct GNUNET_MessageHeader *) cc->p2->hello,
251 &hello_offered,
252 cc);
253}
254
255
256/**
257 * Start a peer with the given configuration 205 * Start a peer with the given configuration
258 * @param tth the testing handle 206 * @param tth the testing handle
259 * @param cfgname configuration file 207 * @param cfgname configuration file
@@ -265,23 +213,21 @@ offer_hello (void *cls)
265 * @param cb_cls closure for callback 213 * @param cb_cls closure for callback
266 * @return the peer context 214 * @return the peer context
267 */ 215 */
268struct PeerContext * 216struct GNUNET_TRANSPORT_TESTING_PeerContext *
269GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth, 217GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_Handle *tth,
270 const char *cfgname, 218 const char *cfgname,
271 int peer_id, 219 int peer_id,
272 GNUNET_TRANSPORT_ReceiveCallback rec, 220 GNUNET_TRANSPORT_ReceiveCallback rec,
273 GNUNET_TRANSPORT_NotifyConnect nc, 221 GNUNET_TRANSPORT_NotifyConnect nc,
274 GNUNET_TRANSPORT_NotifyDisconnect nd, 222 GNUNET_TRANSPORT_NotifyDisconnect nd,
275 GNUNET_TRANSPORT_TESTING_start_cb start_cb, 223 GNUNET_TRANSPORT_TESTING_StartCallback start_cb,
276 void *cb_cls) 224 void *cb_cls)
277{ 225{
278 char *emsg = NULL; 226 char *emsg = NULL;
227 struct GNUNET_TRANSPORT_TESTING_PeerContext *p;
279 struct GNUNET_PeerIdentity *dummy; 228 struct GNUNET_PeerIdentity *dummy;
280 229
281 GNUNET_assert (NULL != tth); 230 if (GNUNET_NO == GNUNET_DISK_file_test (cfgname))
282 GNUNET_assert (NULL != tth->tl_system);
283
284 if (GNUNET_DISK_file_test (cfgname) == GNUNET_NO)
285 { 231 {
286 LOG (GNUNET_ERROR_TYPE_ERROR, 232 LOG (GNUNET_ERROR_TYPE_ERROR,
287 "File not found: `%s'\n", 233 "File not found: `%s'\n",
@@ -289,18 +235,32 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth
289 return NULL; 235 return NULL;
290 } 236 }
291 237
292 struct PeerContext *p = GNUNET_new (struct PeerContext); 238 p = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_PeerContext);
293 GNUNET_CONTAINER_DLL_insert (tth->p_head, tth->p_tail, p); 239 p->tth = tth;
240 p->nc = nc;
241 p->nd = nd;
242 p->rec = rec;
243 p->start_cb = start_cb;
244 if (cb_cls != NULL)
245 p->cb_cls = cb_cls;
246 else
247 p->cb_cls = p;
248 GNUNET_CONTAINER_DLL_insert (tth->p_head,
249 tth->p_tail,
250 p);
294 251
295 /* Create configuration and call testing lib to modify it */ 252 /* Create configuration and call testing lib to modify it */
296 p->cfg = GNUNET_CONFIGURATION_create (); 253 p->cfg = GNUNET_CONFIGURATION_create ();
297 GNUNET_assert (GNUNET_OK == 254 GNUNET_assert (GNUNET_OK ==
298 GNUNET_CONFIGURATION_load (p->cfg, cfgname)); 255 GNUNET_CONFIGURATION_load (p->cfg, cfgname));
299 if (GNUNET_SYSERR == GNUNET_TESTING_configuration_create (tth->tl_system, p->cfg)) 256 if (GNUNET_SYSERR ==
257 GNUNET_TESTING_configuration_create (tth->tl_system,
258 p->cfg))
300 { 259 {
301 LOG (GNUNET_ERROR_TYPE_ERROR, 260 LOG (GNUNET_ERROR_TYPE_ERROR,
302 "Testing library failed to create unique configuration based on `%s'\n", 261 "Testing library failed to create unique configuration based on `%s'\n",
303 cfgname); 262 cfgname);
263 GNUNET_CONFIGURATION_destroy (p->cfg);
304 GNUNET_free (p); 264 GNUNET_free (p);
305 return NULL; 265 return NULL;
306 } 266 }
@@ -308,14 +268,17 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth
308 p->no = peer_id; 268 p->no = peer_id;
309 /* Configure peer with configuration */ 269 /* Configure peer with configuration */
310 p->peer = GNUNET_TESTING_peer_configure (tth->tl_system, 270 p->peer = GNUNET_TESTING_peer_configure (tth->tl_system,
311 p->cfg, p->no, NULL, &emsg); 271 p->cfg,
272 p->no,
273 NULL,
274 &emsg);
312 if (NULL == p->peer) 275 if (NULL == p->peer)
313 { 276 {
314 LOG (GNUNET_ERROR_TYPE_ERROR, 277 LOG (GNUNET_ERROR_TYPE_ERROR,
315 "Testing library failed to create unique configuration based on `%s': `%s'\n", 278 "Testing library failed to create unique configuration based on `%s': `%s'\n",
316 cfgname, 279 cfgname,
317 emsg); 280 emsg);
318 GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); 281 GNUNET_TRANSPORT_TESTING_stop_peer (p);
319 GNUNET_free_non_null (emsg); 282 GNUNET_free_non_null (emsg);
320 return NULL; 283 return NULL;
321 } 284 }
@@ -325,39 +288,33 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth
325 LOG (GNUNET_ERROR_TYPE_ERROR, 288 LOG (GNUNET_ERROR_TYPE_ERROR,
326 "Testing library failed to create unique configuration based on `%s'\n", 289 "Testing library failed to create unique configuration based on `%s'\n",
327 cfgname); 290 cfgname);
328 GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); 291 GNUNET_TRANSPORT_TESTING_stop_peer (p);
329 return NULL; 292 return NULL;
330 } 293 }
331 294
332 memset(&dummy, '\0', sizeof (dummy)); 295 memset (&dummy,
333 GNUNET_TESTING_peer_get_identity (p->peer, &p->id); 296 '\0',
334 if (0 == memcmp (&dummy, &p->id, sizeof (struct GNUNET_PeerIdentity))) 297 sizeof (dummy));
298 GNUNET_TESTING_peer_get_identity (p->peer,
299 &p->id);
300 if (0 == memcmp (&dummy,
301 &p->id,
302 sizeof (struct GNUNET_PeerIdentity)))
335 { 303 {
336 LOG (GNUNET_ERROR_TYPE_ERROR, 304 LOG (GNUNET_ERROR_TYPE_ERROR,
337 "Testing library failed to obtain peer identity for peer %u\n", 305 "Testing library failed to obtain peer identity for peer %u\n",
338 p->no); 306 p->no);
339 GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); 307 GNUNET_TRANSPORT_TESTING_stop_peer (p);
340 return NULL; 308 return NULL;
341 } 309 }
342 else 310 LOG (GNUNET_ERROR_TYPE_DEBUG,
343 { 311 "Peer %u configured with identity `%s'\n",
344 LOG (GNUNET_ERROR_TYPE_DEBUG, 312 p->no,
345 "Peer %u configured with identity `%s'\n", 313 GNUNET_i2s_full (&p->id));
346 p->no,
347 GNUNET_i2s_full (&p->id));
348 }
349
350 p->tth = tth;
351 p->nc = nc;
352 p->nd = nd;
353 p->rec = rec;
354 p->start_cb = start_cb;
355 if (cb_cls != NULL)
356 p->cb_cls = cb_cls;
357 else
358 p->cb_cls = p;
359 314
360 p->th = GNUNET_TRANSPORT_connect (p->cfg, NULL, p, 315 p->th = GNUNET_TRANSPORT_connect (p->cfg,
316 NULL,
317 p,
361 &notify_receive, 318 &notify_receive,
362 &notify_connect, 319 &notify_connect,
363 &notify_disconnect); 320 &notify_disconnect);
@@ -367,7 +324,7 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth
367 "Failed to connect to transport service for peer `%s': `%s'\n", 324 "Failed to connect to transport service for peer `%s': `%s'\n",
368 cfgname, 325 cfgname,
369 emsg); 326 emsg);
370 GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); 327 GNUNET_TRANSPORT_TESTING_stop_peer (p);
371 return NULL; 328 return NULL;
372 } 329 }
373 p->ats = GNUNET_ATS_connectivity_init (p->cfg); 330 p->ats = GNUNET_ATS_connectivity_init (p->cfg);
@@ -377,40 +334,30 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth
377 "Failed to connect to ATS service for peer `%s': `%s'\n", 334 "Failed to connect to ATS service for peer `%s': `%s'\n",
378 cfgname, 335 cfgname,
379 emsg); 336 emsg);
380 GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); 337 GNUNET_TRANSPORT_TESTING_stop_peer (p);
381 return NULL; 338 return NULL;
382 } 339 }
383 p->ghh = GNUNET_TRANSPORT_get_hello (p->cfg, 340 p->ghh = GNUNET_TRANSPORT_get_hello (p->cfg,
384 &get_hello, 341 &get_hello,
385 p); 342 p);
386 GNUNET_assert (p->ghh != NULL); 343 GNUNET_assert (p->ghh != NULL);
387
388 return p; 344 return p;
389} 345}
390 346
391 347
392/** 348/**
393 * Restart the given peer 349 * Stops and restarts the given peer, sleeping (!) for 5s in between.
394 * 350 *
395 * @param p the peer 351 * @param p the peer
396 * @param cfgname the cfg file used to restart
397 * @param restart_cb callback to call when restarted 352 * @param restart_cb callback to call when restarted
398 * @param cb_cls callback closure 353 * @param cb_cls callback closure
399 * @return #GNUNET_OK in success otherwise #GNUNET_SYSERR 354 * @return #GNUNET_OK in success otherwise #GNUNET_SYSERR
400 */ 355 */
401int 356int
402GNUNET_TRANSPORT_TESTING_restart_peer (struct PeerContext *p, 357GNUNET_TRANSPORT_TESTING_restart_peer (struct GNUNET_TRANSPORT_TESTING_PeerContext *p,
403 const char *cfgname, 358 GNUNET_TRANSPORT_TESTING_StartCallback restart_cb,
404 GNUNET_TRANSPORT_TESTING_start_cb restart_cb,
405 void *cb_cls) 359 void *cb_cls)
406{ 360{
407 GNUNET_assert (NULL != p->peer);
408
409 LOG (GNUNET_ERROR_TYPE_DEBUG,
410 "Restarting peer %u (`%s')\n",
411 p->no,
412 GNUNET_i2s (&p->id));
413
414 /* shutdown */ 361 /* shutdown */
415 LOG (GNUNET_ERROR_TYPE_DEBUG, 362 LOG (GNUNET_ERROR_TYPE_DEBUG,
416 "Stopping peer %u (`%s')\n", 363 "Stopping peer %u (`%s')\n",
@@ -431,8 +378,8 @@ GNUNET_TRANSPORT_TESTING_restart_peer (struct PeerContext *p,
431 GNUNET_ATS_connectivity_done (p->ats); 378 GNUNET_ATS_connectivity_done (p->ats);
432 p->ats = NULL; 379 p->ats = NULL;
433 } 380 }
434 381 if (GNUNET_SYSERR ==
435 if (GNUNET_SYSERR == GNUNET_TESTING_peer_stop (p->peer)) 382 GNUNET_TESTING_peer_stop (p->peer))
436 { 383 {
437 LOG (GNUNET_ERROR_TYPE_ERROR, 384 LOG (GNUNET_ERROR_TYPE_ERROR,
438 "Failed to stop peer %u (`%s')\n", 385 "Failed to stop peer %u (`%s')\n",
@@ -443,6 +390,10 @@ GNUNET_TRANSPORT_TESTING_restart_peer (struct PeerContext *p,
443 390
444 sleep (5); // YUCK! 391 sleep (5); // YUCK!
445 392
393 LOG (GNUNET_ERROR_TYPE_DEBUG,
394 "Restarting peer %u (`%s')\n",
395 p->no,
396 GNUNET_i2s (&p->id));
446 /* restart */ 397 /* restart */
447 if (GNUNET_SYSERR == GNUNET_TESTING_peer_start (p->peer)) 398 if (GNUNET_SYSERR == GNUNET_TESTING_peer_start (p->peer))
448 { 399 {
@@ -476,13 +427,13 @@ GNUNET_TRANSPORT_TESTING_restart_peer (struct PeerContext *p,
476/** 427/**
477 * Shutdown the given peer 428 * Shutdown the given peer
478 * 429 *
479 * @param tth testing handle
480 * @param p the peer 430 * @param p the peer
481 */ 431 */
482void 432void
483GNUNET_TRANSPORT_TESTING_stop_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth, 433GNUNET_TRANSPORT_TESTING_stop_peer (struct GNUNET_TRANSPORT_TESTING_PeerContext *p)
484 struct PeerContext *p)
485{ 434{
435 struct GNUNET_TRANSPORT_TESTING_Handle *tth = p->tth;
436
486 if (NULL != p->ghh) 437 if (NULL != p->ghh)
487 { 438 {
488 GNUNET_TRANSPORT_get_hello_cancel (p->ghh); 439 GNUNET_TRANSPORT_get_hello_cancel (p->ghh);
@@ -495,10 +446,12 @@ GNUNET_TRANSPORT_TESTING_stop_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth,
495 } 446 }
496 if (NULL != p->peer) 447 if (NULL != p->peer)
497 { 448 {
498 if (GNUNET_OK != GNUNET_TESTING_peer_stop (p->peer)) 449 if (GNUNET_OK !=
450 GNUNET_TESTING_peer_stop (p->peer))
499 { 451 {
500 LOG (GNUNET_ERROR_TYPE_DEBUG, 452 LOG (GNUNET_ERROR_TYPE_DEBUG,
501 "Testing lib failed to stop peer %u (`%s') \n", p->no, 453 "Testing lib failed to stop peer %u (`%s')\n",
454 p->no,
502 GNUNET_i2s (&p->id)); 455 GNUNET_i2s (&p->id));
503 } 456 }
504 GNUNET_TESTING_peer_destroy (p->peer); 457 GNUNET_TESTING_peer_destroy (p->peer);
@@ -523,7 +476,7 @@ GNUNET_TRANSPORT_TESTING_stop_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth,
523 tth->p_tail, 476 tth->p_tail,
524 p); 477 p);
525 LOG (GNUNET_ERROR_TYPE_DEBUG, 478 LOG (GNUNET_ERROR_TYPE_DEBUG,
526 "Peer %u (`%s') stopped \n", 479 "Peer %u (`%s') stopped\n",
527 p->no, 480 p->no,
528 GNUNET_i2s (&p->id)); 481 GNUNET_i2s (&p->id));
529 GNUNET_free (p); 482 GNUNET_free (p);
@@ -531,6 +484,67 @@ GNUNET_TRANSPORT_TESTING_stop_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth,
531 484
532 485
533/** 486/**
487 * Offer the current HELLO of P2 to P1.
488 *
489 * @param cls our `struct GNUNET_TRANSPORT_TESTING_ConnectRequest`
490 */
491static void
492offer_hello (void *cls);
493
494
495/**
496 * Function called after the HELLO was passed to the
497 * transport service.
498 */
499static void
500hello_offered (void *cls)
501{
502 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc = cls;
503
504 cc->oh = NULL;
505 cc->tct = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
506 &offer_hello,
507 cc);
508}
509
510
511/**
512 * Offer the current HELLO of P2 to P1.
513 *
514 * @param cls our `struct GNUNET_TRANSPORT_TESTING_ConnectRequest`
515 */
516static void
517offer_hello (void *cls)
518{
519 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc = cls;
520 struct GNUNET_TRANSPORT_TESTING_PeerContext *p1 = cc->p1;
521 struct GNUNET_TRANSPORT_TESTING_PeerContext *p2 = cc->p2;
522
523 cc->tct = NULL;
524 {
525 char *p2_s = GNUNET_strdup (GNUNET_i2s (&p2->id));
526
527 LOG (GNUNET_ERROR_TYPE_DEBUG,
528 "Asking peer %u (`%s') to connect peer %u (`%s'), providing HELLO with %u bytes\n",
529 p1->no,
530 GNUNET_i2s (&p1->id),
531 p2->no,
532 p2_s,
533 GNUNET_HELLO_size (cc->p2->hello));
534 GNUNET_free (p2_s);
535 }
536
537 if (NULL != cc->oh)
538 GNUNET_TRANSPORT_offer_hello_cancel (cc->oh);
539 cc->oh =
540 GNUNET_TRANSPORT_offer_hello (cc->p1->cfg,
541 (const struct GNUNET_MessageHeader *) cc->p2->hello,
542 &hello_offered,
543 cc);
544}
545
546
547/**
534 * Initiate a connection from p1 to p2 by offering p1 p2's HELLO message 548 * Initiate a connection from p1 to p2 by offering p1 p2's HELLO message
535 * 549 *
536 * Remarks: start_peer's notify_connect callback can be called before. 550 * Remarks: start_peer's notify_connect callback can be called before.
@@ -543,12 +557,12 @@ GNUNET_TRANSPORT_TESTING_stop_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth,
543 * @return a connect request handle 557 * @return a connect request handle
544 */ 558 */
545struct GNUNET_TRANSPORT_TESTING_ConnectRequest * 559struct GNUNET_TRANSPORT_TESTING_ConnectRequest *
546GNUNET_TRANSPORT_TESTING_connect_peers (struct GNUNET_TRANSPORT_TESTING_handle *tth, 560GNUNET_TRANSPORT_TESTING_connect_peers (struct GNUNET_TRANSPORT_TESTING_PeerContext *p1,
547 struct PeerContext *p1, 561 struct GNUNET_TRANSPORT_TESTING_PeerContext *p2,
548 struct PeerContext *p2, 562 GNUNET_SCHEDULER_TaskCallback cb,
549 GNUNET_TRANSPORT_TESTING_connect_cb cb,
550 void *cls) 563 void *cls)
551{ 564{
565 struct GNUNET_TRANSPORT_TESTING_Handle *tth = p1->tth;
552 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc; 566 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
553 567
554 cc = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_ConnectRequest); 568 cc = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_ConnectRequest);
@@ -567,11 +581,9 @@ GNUNET_TRANSPORT_TESTING_connect_peers (struct GNUNET_TRANSPORT_TESTING_handle *
567 cc->ats_sh = GNUNET_ATS_connectivity_suggest (cc->p1->ats, 581 cc->ats_sh = GNUNET_ATS_connectivity_suggest (cc->p1->ats,
568 &p2->id, 582 &p2->id,
569 1); 583 1);
570
571 LOG (GNUNET_ERROR_TYPE_DEBUG, 584 LOG (GNUNET_ERROR_TYPE_DEBUG,
572 "New connect request %p\n", 585 "New connect request %p\n",
573 cc); 586 cc);
574
575 return cc; 587 return cc;
576} 588}
577 589
@@ -584,12 +596,12 @@ GNUNET_TRANSPORT_TESTING_connect_peers (struct GNUNET_TRANSPORT_TESTING_handle *
584 * @param cc a connect request handle 596 * @param cc a connect request handle
585 */ 597 */
586void 598void
587GNUNET_TRANSPORT_TESTING_connect_peers_cancel (struct GNUNET_TRANSPORT_TESTING_handle *tth, 599GNUNET_TRANSPORT_TESTING_connect_peers_cancel (struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc)
588 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc)
589{ 600{
601 struct GNUNET_TRANSPORT_TESTING_Handle *tth = cc->p1->tth;
602
590 LOG (GNUNET_ERROR_TYPE_DEBUG, 603 LOG (GNUNET_ERROR_TYPE_DEBUG,
591 "Canceling connect request %p!\n", 604 "Canceling connect request!\n");
592 cc);
593 if (NULL != cc->tct) 605 if (NULL != cc->tct)
594 { 606 {
595 GNUNET_SCHEDULER_cancel (cc->tct); 607 GNUNET_SCHEDULER_cancel (cc->tct);
@@ -605,7 +617,6 @@ GNUNET_TRANSPORT_TESTING_connect_peers_cancel (struct GNUNET_TRANSPORT_TESTING_h
605 GNUNET_ATS_connectivity_suggest_cancel (cc->ats_sh); 617 GNUNET_ATS_connectivity_suggest_cancel (cc->ats_sh);
606 cc->ats_sh = NULL; 618 cc->ats_sh = NULL;
607 } 619 }
608
609 GNUNET_CONTAINER_DLL_remove (tth->cc_head, 620 GNUNET_CONTAINER_DLL_remove (tth->cc_head,
610 tth->cc_tail, 621 tth->cc_tail,
611 cc); 622 cc);
@@ -615,57 +626,53 @@ GNUNET_TRANSPORT_TESTING_connect_peers_cancel (struct GNUNET_TRANSPORT_TESTING_h
615 626
616/** 627/**
617 * Clean up the transport testing 628 * Clean up the transport testing
629 *
618 * @param tth transport testing handle 630 * @param tth transport testing handle
619 */ 631 */
620void 632void
621GNUNET_TRANSPORT_TESTING_done (struct GNUNET_TRANSPORT_TESTING_handle *tth) 633GNUNET_TRANSPORT_TESTING_done (struct GNUNET_TRANSPORT_TESTING_Handle *tth)
622{ 634{
623 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc = tth->cc_head; 635 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
624 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ct = NULL; 636 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ct;
625 struct PeerContext *p = tth->p_head; 637 struct GNUNET_TRANSPORT_TESTING_PeerContext *p;
626 struct PeerContext *t = NULL; 638 struct GNUNET_TRANSPORT_TESTING_PeerContext *t;
627 639
628 while (cc != tth->cc_tail) 640 cc = tth->cc_head;
641 while (NULL != cc)
629 { 642 {
630 ct = cc->next; 643 ct = cc->next;
631 LOG (GNUNET_ERROR_TYPE_ERROR, 644 LOG (GNUNET_ERROR_TYPE_ERROR,
632 "Developer forgot to cancel connect request %p!\n", 645 "Developer forgot to cancel connect request!\n");
633 cc); 646 GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc);
634 GNUNET_TRANSPORT_TESTING_connect_peers_cancel (tth,
635 cc);
636 cc = ct; 647 cc = ct;
637 } 648 }
638 649 p = tth->p_head;
639 while (NULL != p) 650 while (NULL != p)
640 { 651 {
641 t = p->next; 652 t = p->next;
642 LOG (GNUNET_ERROR_TYPE_ERROR, 653 LOG (GNUNET_ERROR_TYPE_ERROR,
643 "Developer forgot to stop peer!\n"); 654 "Developer forgot to stop peer!\n");
644 GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); 655 GNUNET_TRANSPORT_TESTING_stop_peer (p);
645 p = t; 656 p = t;
646 } 657 }
647
648 GNUNET_TESTING_system_destroy (tth->tl_system, 658 GNUNET_TESTING_system_destroy (tth->tl_system,
649 GNUNET_YES); 659 GNUNET_YES);
650 660
651 GNUNET_free (tth); 661 GNUNET_free (tth);
652 tth = NULL;
653} 662}
654 663
655 664
656/** 665/**
657 * Initialize the transport testing 666 * Initialize the transport testing
667 *
658 * @return transport testing handle 668 * @return transport testing handle
659 */ 669 */
660struct GNUNET_TRANSPORT_TESTING_handle * 670struct GNUNET_TRANSPORT_TESTING_Handle *
661GNUNET_TRANSPORT_TESTING_init () 671GNUNET_TRANSPORT_TESTING_init ()
662{ 672{
663 struct GNUNET_TRANSPORT_TESTING_handle *tth; 673 struct GNUNET_TRANSPORT_TESTING_Handle *tth;
664
665 /* prepare hostkeys */
666 tth = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_handle);
667 674
668 /* Init testing the testing lib */ 675 tth = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_Handle);
669 tth->tl_system = GNUNET_TESTING_system_create ("transport-testing", 676 tth->tl_system = GNUNET_TESTING_system_create ("transport-testing",
670 NULL, 677 NULL,
671 NULL, 678 NULL,
@@ -673,213 +680,11 @@ GNUNET_TRANSPORT_TESTING_init ()
673 if (NULL == tth->tl_system) 680 if (NULL == tth->tl_system)
674 { 681 {
675 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 682 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
676 _("Failed to initialize testing library!\n")); 683 "Failed to initialize testing library!\n");
677 GNUNET_free (tth); 684 GNUNET_free (tth);
678 return NULL; 685 return NULL;
679 } 686 }
680
681 return tth; 687 return tth;
682} 688}
683 689
684
685/*
686 * Some utility functions
687 */
688
689/**
690 * Removes all directory separators from absolute filename
691 *
692 * @param file the absolute file name, e.g. as found in argv[0]
693 * @return extracted file name, has to be freed by caller
694 */
695static char *
696extract_filename (const char *file)
697{
698 char *pch = GNUNET_strdup (file);
699 char *backup = pch;
700 char *filename = NULL;
701 char *res;
702#if WINDOWS
703 if ((strlen (pch) >= 3) && pch[1] == ':')
704 {
705 if (NULL != strstr (pch, "\\"))
706 {
707 pch = strtok (pch, "\\");
708 while (pch != NULL)
709 {
710 pch = strtok (NULL, "\\");
711 if (pch != NULL)
712 filename = pch;
713 }
714 }
715 }
716 if (filename != NULL)
717 pch = filename; /* If we miss the next condition, filename = pch will
718 * not harm us.
719 */
720#endif
721 if (NULL != strstr (pch, "/"))
722 {
723 pch = strtok (pch, "/");
724 while (pch != NULL)
725 {
726 pch = strtok (NULL, "/");
727 if (pch != NULL)
728 {
729 filename = pch;
730 }
731 }
732 }
733 else
734 filename = pch;
735
736 res = GNUNET_strdup (filename);
737 GNUNET_free (backup);
738 return res;
739}
740
741
742/**
743 * Extracts the test filename from an absolute file name and removes
744 * the extension
745 *
746 * @param file absolute file name
747 * @param dest where to store result
748 */
749void
750GNUNET_TRANSPORT_TESTING_get_test_name (const char *file,
751 char **dest)
752{
753 char *filename = extract_filename (file);
754 char *backup = filename;
755 char *dotexe;
756
757 if (filename == NULL)
758 goto fail;
759
760 /* remove "lt-" */
761 filename = strstr (filename, "tes");
762 if (filename == NULL)
763 goto fail;
764
765 /* remove ".exe" */
766 if (NULL != (dotexe = strstr (filename, ".exe")))
767 dotexe[0] = '\0';
768
769 goto suc;
770
771fail:
772 (*dest) = NULL;
773 return;
774
775suc:
776 /* create filename */
777 GNUNET_asprintf (dest, "%s", filename);
778 GNUNET_free (backup);
779}
780
781
782/**
783 * Extracts the filename from an absolute file name and removes the extension
784 *
785 * @param file absolute file name
786 * @param dest where to store result
787 */
788void
789GNUNET_TRANSPORT_TESTING_get_test_source_name (const char *file,
790 char **dest)
791{
792 char *src = extract_filename (file);
793 char *split;
794
795 split = strstr (src, ".");
796 if (split != NULL)
797 {
798 split[0] = '\0';
799 }
800 GNUNET_asprintf (dest, "%s", src);
801 GNUNET_free (src);
802}
803
804
805/**
806 * Extracts the plugin name from an absolute file name and the test name
807 *
808 * @param file absolute file name
809 * @param test test name
810 * @param dest where to store result
811 */
812void
813GNUNET_TRANSPORT_TESTING_get_test_plugin_name (const char *file,
814 const char *test,
815 char **dest)
816{
817 char *filename;
818 char *dotexe;
819 char *e = extract_filename (file);
820 char *t = extract_filename (test);
821
822 if (NULL == e)
823 goto fail;
824 /* remove "lt-" */
825 filename = strstr (e, "tes");
826 if (NULL == filename)
827 goto fail;
828 /* remove ".exe" */
829 if (NULL != (dotexe = strstr (filename, ".exe")))
830 dotexe[0] = '\0';
831
832 /* find last _ */
833 filename = strstr (filename, t);
834 if (NULL == filename)
835 goto fail;
836 /* copy plugin */
837 filename += strlen (t);
838 if ('\0' != *filename)
839 filename++;
840 GNUNET_asprintf (dest, "%s", filename);
841 goto suc;
842fail:
843 (*dest) = NULL;
844suc:
845 GNUNET_free (t);
846 GNUNET_free (e);
847}
848
849
850/**
851 * This function takes the filename (e.g. argv[0), removes a "lt-"-prefix and
852 * if existing ".exe"-prefix and adds the peer-number
853 *
854 * @param file filename of the test, e.g. argv[0]
855 * @param dest where to write the filename
856 * @param count peer number
857 */
858void
859GNUNET_TRANSPORT_TESTING_get_config_name (const char *file,
860 char **dest,
861 int count)
862{
863 char *filename = extract_filename (file);
864 char *backup = filename;
865 char *dotexe;
866
867 if (NULL == filename)
868 goto fail;
869 /* remove "lt-" */
870 filename = strstr (filename, "tes");
871 if (NULL == filename)
872 goto fail;
873 /* remove ".exe" */
874 if (NULL != (dotexe = strstr (filename, ".exe")))
875 dotexe[0] = '\0';
876 GNUNET_asprintf (dest, "%s_peer%u.conf", filename, count);
877 GNUNET_free (backup);
878 return;
879fail:
880 (*dest) = NULL;
881 GNUNET_free (backup);
882}
883
884
885/* end of transport-testing.c */ 690/* end of transport-testing.c */