aboutsummaryrefslogtreecommitdiff
path: root/src/transport/test_transport_address_switch.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/test_transport_address_switch.c')
-rw-r--r--src/transport/test_transport_address_switch.c652
1 files changed, 652 insertions, 0 deletions
diff --git a/src/transport/test_transport_address_switch.c b/src/transport/test_transport_address_switch.c
new file mode 100644
index 000000000..cf0d6f9db
--- /dev/null
+++ b/src/transport/test_transport_address_switch.c
@@ -0,0 +1,652 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009, 2010, 2011 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 * @file transport/test_transport_address_switch.c
22 * @brief base test case for transport implementations
23 *
24 * This test case tests if peers can successfully switch address when connected
25 * connected
26 */
27#include "platform.h"
28#include "gnunet_transport_service.h"
29#include "gnunet_ats_service.h"
30#include "gauger.h"
31#include "transport-testing.h"
32
33/*
34 * Testcase specific declarations
35 */
36
37GNUNET_NETWORK_STRUCT_BEGIN
38struct TestMessage
39{
40 struct GNUNET_MessageHeader header;
41 uint32_t num;
42};
43GNUNET_NETWORK_STRUCT_END
44
45/**
46 * Note that this value must not significantly exceed
47 * 'MAX_PENDING' in 'gnunet-service-transport.c', otherwise
48 * messages may be dropped even for a reliable transport.
49 */
50#define TOTAL_MSGS (4096 * 2)
51
52/**
53 * Message type for test messages
54 */
55#define MTYPE 12345
56
57/**
58 * Testcase timeout
59 */
60#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120)
61
62/**
63 * How long until we give up on transmitting the message?
64 */
65#define TIMEOUT_TRANSMIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
66
67#define DURATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
68#define DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
69
70static GNUNET_SCHEDULER_TaskIdentifier die_task;
71
72static GNUNET_SCHEDULER_TaskIdentifier delayed_end_task;
73
74static GNUNET_SCHEDULER_TaskIdentifier measure_task;
75
76struct PeerContext *p1;
77char *cfg_file_p1;
78struct GNUNET_STATISTICS_Handle *p1_stat;
79
80struct PeerContext *p2;
81char *cfg_file_p2;
82struct GNUNET_STATISTICS_Handle *p2_stat;
83
84struct PeerContext *sender;
85
86struct PeerContext *receiver;
87
88struct GNUNET_TRANSPORT_TransmitHandle *th;
89
90static int test_connected;
91static int res;
92
93struct GNUNET_TRANSPORT_TESTING_handle *tth;
94
95static GNUNET_TRANSPORT_TESTING_ConnectRequest cc;
96
97static unsigned int p1_switch_attempts;
98static unsigned int p1_switch_success;
99static unsigned int p1_switch_fail;
100
101static unsigned int p2_switch_attempts;
102static unsigned int p2_switch_success;
103static unsigned int p2_switch_fail;
104
105static unsigned long long bytes_sent_total;
106static unsigned long long bytes_recv_total;
107
108static unsigned long long bytes_sent_after_switch;
109static unsigned long long bytes_recv_after_switch;
110
111static struct GNUNET_TIME_Absolute start_time;
112static struct GNUNET_TIME_Absolute start_time;
113
114/*
115 * END Testcase specific declarations
116 */
117
118#if VERBOSE
119#define OKPP do { ok++; FPRINTF (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0)
120#else
121#define OKPP do { ok++; } while (0)
122#endif
123
124static void end ();
125
126static int
127stat_start_attempt_cb (void *cls, const char *subsystem, const char *name,
128 uint64_t value, int is_persistent)
129{
130 if (cls == p1)
131 {
132 p1_switch_attempts++;
133 FPRINTF (stderr, "Peer 1 tries to switch.");
134 }
135 else if (cls == p2)
136 {
137 p2_switch_attempts++;
138 FPRINTF (stderr, "Peer 2 tries to switch.");
139 }
140 else
141 return GNUNET_OK;
142
143 if (GNUNET_SCHEDULER_NO_TASK == delayed_end_task)
144 delayed_end_task = GNUNET_SCHEDULER_add_delayed (DELAY, &end, NULL );
145 return GNUNET_OK;
146}
147
148
149static int
150stat_success_attempt_cb (void *cls, const char *subsystem, const char *name,
151 uint64_t value, int is_persistent)
152{
153 if (cls == p1)
154 {
155 p1_switch_success++;
156 FPRINTF (stderr, "Peer 1 switched successfully.");
157 }
158 if (cls == p2)
159 {
160 p2_switch_success++;
161 FPRINTF (stderr, "Peer 2 switched successfully.");
162 }
163
164 return GNUNET_OK;
165}
166
167
168static int
169stat_fail_attempt_cb (void *cls, const char *subsystem, const char *name,
170 uint64_t value, int is_persistent)
171{
172 if (cls == p1)
173 {
174 p1_switch_fail++;
175 FPRINTF (stderr, "Peer 1 failed to switch.");
176 }
177 if (cls == p2)
178 {
179 p2_switch_fail++;
180 FPRINTF (stderr, "Peer 2 failed to switch.");
181 }
182
183 return GNUNET_OK;
184}
185
186
187static void
188clean_up ()
189{
190 if (measure_task != GNUNET_SCHEDULER_NO_TASK )
191 {
192 GNUNET_SCHEDULER_cancel (measure_task);
193 measure_task = GNUNET_SCHEDULER_NO_TASK;
194 }
195
196 if (delayed_end_task != GNUNET_SCHEDULER_NO_TASK )
197 {
198 GNUNET_SCHEDULER_cancel (delayed_end_task);
199 delayed_end_task = GNUNET_SCHEDULER_NO_TASK;
200 }
201
202 if (die_task != GNUNET_SCHEDULER_NO_TASK )
203 {
204 GNUNET_SCHEDULER_cancel (die_task);
205 die_task = GNUNET_SCHEDULER_NO_TASK;
206 }
207
208 if (NULL != p1_stat)
209 {
210 GNUNET_STATISTICS_watch_cancel (p1_stat, "transport",
211 "# Attempts to switch addresses", stat_start_attempt_cb, p1);
212 GNUNET_STATISTICS_watch_cancel (p1_stat, "transport",
213 "# Successful attempts to switch addresses", stat_success_attempt_cb, p1);
214 GNUNET_STATISTICS_watch_cancel (p1_stat, "transport",
215 "# Failed attempts to switch addresses (failed to send CONNECT CONT)",
216 stat_fail_attempt_cb, p1);
217 GNUNET_STATISTICS_watch_cancel (p1_stat, "transport",
218 "# Failed attempts to switch addresses (failed to send CONNECT)",
219 stat_fail_attempt_cb, p1);
220 GNUNET_STATISTICS_watch_cancel (p1_stat, "transport",
221 "# Failed attempts to switch addresses (no response)",
222 stat_fail_attempt_cb, p1);
223 GNUNET_STATISTICS_destroy (p1_stat, GNUNET_NO);
224 p1_stat = NULL;
225 }
226 if (NULL != p2_stat)
227 {
228 GNUNET_STATISTICS_watch_cancel (p2_stat, "transport",
229 "# Attempts to switch addresses", stat_start_attempt_cb, p2);
230 GNUNET_STATISTICS_watch_cancel (p2_stat, "transport",
231 "# Successful attempts to switch addresses", stat_success_attempt_cb, p2);
232 GNUNET_STATISTICS_watch_cancel (p2_stat, "transport",
233 "# Failed attempts to switch addresses (failed to send CONNECT CONT)",
234 stat_fail_attempt_cb, p2);
235 GNUNET_STATISTICS_watch_cancel (p2_stat, "transport",
236 "# Failed attempts to switch addresses (failed to send CONNECT)",
237 stat_fail_attempt_cb, p2);
238 GNUNET_STATISTICS_watch_cancel (p2_stat, "transport",
239 "# Failed attempts to switch addresses (no response)",
240 stat_fail_attempt_cb, p2);
241 GNUNET_STATISTICS_destroy (p2_stat, GNUNET_NO);
242 p2_stat = NULL;
243 }
244
245 if (die_task != GNUNET_SCHEDULER_NO_TASK )
246 {
247 GNUNET_SCHEDULER_cancel (die_task);
248 die_task = GNUNET_SCHEDULER_NO_TASK;
249 }
250
251 if (th != NULL )
252 {
253 GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
254 th = NULL;
255 }
256
257 if (cc != NULL )
258 {
259 GNUNET_TRANSPORT_TESTING_connect_peers_cancel (tth, cc);
260 cc = NULL;
261 }
262
263 if (p1 != NULL )
264 {
265 GNUNET_TRANSPORT_TESTING_stop_peer (tth, p1);
266 p1 = NULL;
267 }
268 if (p2 != NULL )
269 {
270 GNUNET_TRANSPORT_TESTING_stop_peer (tth, p2);
271 p2 = NULL;
272 }
273
274}
275
276
277static void
278end ()
279{
280 int result = 0;
281 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Stopping peers\n");
282
283 delayed_end_task = GNUNET_SCHEDULER_NO_TASK;
284
285 if (p1_switch_attempts > 0)
286 {
287 FPRINTF (stderr, "Peer 1 tried %u times to switch and succeeded %u times, failed %u times\n",
288 p1_switch_attempts, p1_switch_success, p1_switch_fail);
289 if (p1_switch_success != p1_switch_attempts)
290 result ++;
291 }
292 if (p2_switch_attempts > 0)
293 {
294 FPRINTF (stderr, "Peer 2 tried %u times to switch and succeeded %u times, failed %u times\n",
295 p2_switch_attempts, p2_switch_success, p2_switch_fail);
296 if (p2_switch_success != p2_switch_attempts)
297 result ++;
298 }
299
300 if ( ((p1_switch_attempts > 0) || (p2_switch_attempts > 0)) &&
301 (bytes_sent_after_switch == 0) )
302 {
303 FPRINTF (stderr, "No data sent after switching!\n");
304 res ++;
305 }
306 if ( ((p1_switch_attempts > 0) || (p2_switch_attempts > 0)) &&
307 (bytes_recv_after_switch == 0) )
308 {
309 FPRINTF (stderr, "No data received after switching!\n");
310 res ++;
311 }
312
313 clean_up();
314
315 res = result;
316}
317
318
319static void
320end_badly ()
321{
322 die_task = GNUNET_SCHEDULER_NO_TASK;
323 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Fail! Stopping peers\n");
324
325 if (test_connected == GNUNET_YES)
326 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Peers got connected\n");
327 else
328 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Peers got NOT connected\n");
329
330 clean_up();
331
332 res = GNUNET_YES;
333}
334
335
336static unsigned int
337get_size (unsigned int iter)
338{
339 unsigned int ret;
340 ret = (iter * iter * iter);
341 return sizeof(struct TestMessage) + (ret % 60000);
342}
343
344
345static void
346notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
347 const struct GNUNET_MessageHeader *message)
348{
349 const struct TestMessage *hdr;
350
351 hdr = (const struct TestMessage *) message;
352 if (MTYPE != ntohs (message->type))
353 return;
354
355 struct PeerContext *p = cls;
356 char *ps = GNUNET_strdup (GNUNET_i2s (&p->id));
357
358 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
359 "Peer %u (`%s') got message %u of size %u from peer (`%s')\n", p->no, ps,
360 ntohl (hdr->num), ntohs (message->size), GNUNET_i2s (peer));
361
362 bytes_recv_total += ntohs(hdr->header.size);
363 if ((p1_switch_attempts > 0) || (p2_switch_attempts > 0))
364 bytes_recv_after_switch += ntohs(hdr->header.size);
365
366 GNUNET_free(ps);
367}
368
369
370static size_t
371notify_ready (void *cls, size_t size, void *buf)
372{
373 static int n;
374 char *cbuf = buf;
375 struct TestMessage hdr;
376 unsigned int s;
377 unsigned int ret;
378
379 th = NULL;
380 if (buf == NULL )
381 {
382 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
383 "Timeout occurred while waiting for transmit_ready for message\n");
384 if (GNUNET_SCHEDULER_NO_TASK != die_task)
385 GNUNET_SCHEDULER_cancel (die_task);
386 die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL );
387 res = 1;
388 return 0;
389 }
390
391 ret = 0;
392 s = get_size (n);
393 GNUNET_assert(size >= s);
394 GNUNET_assert(buf != NULL);
395 cbuf = buf;
396 do
397 {
398 hdr.header.size = htons (s);
399 hdr.header.type = htons (MTYPE);
400 hdr.num = htonl (n);
401 memcpy (&cbuf[ret], &hdr, sizeof(struct TestMessage));
402 ret += sizeof(struct TestMessage);
403 memset (&cbuf[ret], n, s - sizeof(struct TestMessage));
404 ret += s - sizeof(struct TestMessage);
405#if VERBOSE
406 if (n % 5000 == 0)
407 {
408#endif
409 char *receiver_s = GNUNET_strdup (GNUNET_i2s (&receiver->id));
410
411 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
412 "Sending message %u of size %u from peer %u (`%4s') -> peer %u (`%s') !\n",
413 n, s, sender->no, GNUNET_i2s (&sender->id), receiver->no, receiver_s);
414 GNUNET_free(receiver_s);
415#if 0
416 }
417#endif
418 n++;
419 s = get_size (n);
420 if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16))
421 break; /* sometimes pack buffer full, sometimes not */
422 }
423 while (size - ret >= s);
424 if (n < TOTAL_MSGS)
425 {
426 if (th == NULL )
427 th = GNUNET_TRANSPORT_notify_transmit_ready (p2->th, &p1->id, s,
428 TIMEOUT_TRANSMIT, &notify_ready, NULL );
429 }
430 if (n % 5000 == 0)
431 {
432
433 }
434 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
435 "Returning total message block of size %u\n", ret);
436
437 bytes_sent_total += ret;
438 if ((p1_switch_attempts > 0) || (p2_switch_attempts > 0))
439 bytes_sent_after_switch += ret;
440
441 if (n == TOTAL_MSGS)
442 {
443 FPRINTF (stderr, "%s", "\n");
444 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "All messages sent\n");
445 }
446 return ret;
447}
448
449
450static void
451notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
452{
453 struct PeerContext *p = cls;
454 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Peer %u (`%4s') connected to us!\n",
455 p->no, GNUNET_i2s (peer));
456}
457
458
459static void
460notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
461{
462 struct PeerContext *p = cls;
463 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Peer %u (`%4s') disconnected!\n", p->no,
464 GNUNET_i2s (peer));
465 if (th != NULL )
466 GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
467 th = NULL;
468
469}
470
471
472static void
473sendtask ()
474{
475 start_time = GNUNET_TIME_absolute_get ();
476 th = GNUNET_TRANSPORT_notify_transmit_ready (p2->th, &p1->id, get_size (0),
477 TIMEOUT_TRANSMIT, &notify_ready, NULL );
478}
479
480
481static void
482measure (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
483{
484 static int counter;
485
486 measure_task = GNUNET_SCHEDULER_NO_TASK;
487
488 counter++;
489 if ((DURATION.rel_value_us / 1000 / 1000LL) < counter)
490 {
491 FPRINTF (stderr, "%s", ".\n");
492 }
493 else
494 {
495 FPRINTF (stderr, "%s", ".");
496 measure_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
497 &measure, NULL );
498 }
499}
500
501
502static void
503testing_connect_cb (struct PeerContext *p1, struct PeerContext *p2, void *cls)
504{
505 char *p1_c = GNUNET_strdup (GNUNET_i2s (&p1->id));
506
507 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Peers connected: %u (%s) <-> %u (%s)\n",
508 p1->no, p1_c, p2->no, GNUNET_i2s (&p2->id));
509 GNUNET_free(p1_c);
510
511 cc = NULL;
512 test_connected = GNUNET_YES;
513
514 measure_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
515 &measure, NULL );
516 GNUNET_SCHEDULER_add_now (&sendtask, NULL );
517}
518
519
520static void
521start_cb (struct PeerContext *p, void *cls)
522{
523 static int started;
524 started++;
525
526 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Peer %u (`%s') started\n", p->no,
527 GNUNET_i2s (&p->id));
528 if (started != 2)
529 return;
530
531 test_connected = GNUNET_NO;
532 sender = p2;
533 receiver = p1;
534
535 char *sender_c = GNUNET_strdup (GNUNET_i2s (&sender->id));
536 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
537 "Test tries to send from %u (%s) -> peer %u (%s)\n", sender->no, sender_c,
538 receiver->no, GNUNET_i2s (&receiver->id));
539 GNUNET_free(sender_c);
540 cc = GNUNET_TRANSPORT_TESTING_connect_peers (tth, p1, p2, &testing_connect_cb,
541 NULL );
542}
543
544
545static void
546run (void *cls, char * const *args, const char *cfgfile,
547 const struct GNUNET_CONFIGURATION_Handle *cfg)
548{
549 die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL );
550
551 p1 = GNUNET_TRANSPORT_TESTING_start_peer (tth, cfg_file_p1, 1,
552 &notify_receive, &notify_connect, &notify_disconnect, &start_cb, NULL );
553 p1_stat = GNUNET_STATISTICS_create ("transport", p1->cfg);
554 GNUNET_STATISTICS_watch (p1_stat, "transport",
555 "# Attempts to switch addresses",
556 stat_start_attempt_cb, p1);
557 GNUNET_STATISTICS_watch (p1_stat, "transport",
558 "# Successful attempts to switch addresses",
559 stat_success_attempt_cb, p1);
560 GNUNET_STATISTICS_watch (p1_stat, "transport",
561 "# Failed attempts to switch addresses (failed to send CONNECT CONT)",
562 stat_fail_attempt_cb, p1);
563 GNUNET_STATISTICS_watch (p1_stat, "transport",
564 "# Failed attempts to switch addresses (failed to send CONNECT)",
565 stat_fail_attempt_cb, p1);
566 GNUNET_STATISTICS_watch (p1_stat, "transport",
567 "# Failed attempts to switch addresses (no response)",
568 stat_fail_attempt_cb, p1);
569
570 p2 = GNUNET_TRANSPORT_TESTING_start_peer (tth, cfg_file_p2, 2,
571 &notify_receive, &notify_connect, &notify_disconnect, &start_cb, NULL );
572
573 p2_stat = GNUNET_STATISTICS_create ("transport", p2->cfg);
574 GNUNET_STATISTICS_watch (p2_stat, "transport",
575 "# Attempts to switch addresses",
576 stat_start_attempt_cb, p2);
577 GNUNET_STATISTICS_watch (p2_stat, "transport",
578 "# Successful attempts to switch addresses",
579 stat_success_attempt_cb, p2);
580 GNUNET_STATISTICS_watch (p2_stat, "transport",
581 "# Failed attempts to switch addresses (failed to send CONNECT CONT)",
582 stat_fail_attempt_cb, p2);
583 GNUNET_STATISTICS_watch (p2_stat, "transport",
584 "# Failed attempts to switch addresses (failed to send CONNECT)",
585 stat_fail_attempt_cb, p2);
586 GNUNET_STATISTICS_watch (p2_stat, "transport",
587 "# Failed attempts to switch addresses (no response)",
588 stat_fail_attempt_cb, p2);
589
590 if ((p1 == NULL )|| (p2 == NULL))
591 {
592 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Fail! Could not start peers!\n");
593 if (die_task != GNUNET_SCHEDULER_NO_TASK)
594 GNUNET_SCHEDULER_cancel (die_task);
595 die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
596 return;
597 }
598
599 if ((p1_stat == NULL )|| (p2_stat == NULL))
600 {
601 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Fail! Could not create statistics for peers!\n");
602 if (die_task != GNUNET_SCHEDULER_NO_TASK)
603 GNUNET_SCHEDULER_cancel (die_task);
604 die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
605 return;
606 }
607}
608
609int
610main (int argc, char *argv[])
611{
612 char *test_plugin;
613 char *test_source;
614 char *test_name;
615
616 static char *argv_new[] = { "test-transport-address-switch", "-c",
617 "test_transport_startonly.conf", NULL };
618
619 static struct GNUNET_GETOPT_CommandLineOption options[] = {
620 GNUNET_GETOPT_OPTION_END };
621
622 GNUNET_TRANSPORT_TESTING_get_test_name (argv[0], &test_name);
623
624 GNUNET_log_setup (test_name, "WARNING", NULL );
625
626 GNUNET_TRANSPORT_TESTING_get_test_source_name (__FILE__, &test_source);
627 GNUNET_TRANSPORT_TESTING_get_test_plugin_name (argv[0], test_source,
628 &test_plugin);
629
630 tth = GNUNET_TRANSPORT_TESTING_init ();
631
632 GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], &cfg_file_p1, 1);
633 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Using cfg [%u] : %s \n", 1, cfg_file_p1);
634 GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], &cfg_file_p2, 2);
635 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Using cfg [%u] : %s \n", 2, cfg_file_p2);
636
637 GNUNET_PROGRAM_run ((sizeof(argv_new) / sizeof(char *)) - 1, argv_new,
638 test_name, "nohelp", options, &run, NULL );
639
640 GNUNET_free(cfg_file_p1);
641 GNUNET_free(cfg_file_p2);
642
643 GNUNET_free(test_source);
644 GNUNET_free(test_plugin);
645 GNUNET_free(test_name);
646
647 GNUNET_TRANSPORT_TESTING_done (tth);
648
649 return res;
650}
651
652/* end of test_transport_address_switch.c */