50eeeb60c240a05dd53b9da62832fa7e1342dcda
[oweals/gnunet.git] / src / dv / test_transport_api_dv.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009 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 2, 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_api_dv.c
22  * @brief base test case for dv transport (separated from other transport
23  * testcases for two reasons. 1) dv-service relies on core and other
24  * transport plugins, dv plugin relies on dv-service, so dv-plugin needs
25  * to live here, and 2) a dv plugin testcase is different from other
26  * tranport plugin testcases because we need at least three peer to test
27  * it.
28  *
29  * This test case tests DV functionality.  Specifically it starts three
30  * peers connected in a line (1 <-> 2 <-> 3).  Then a message is transmitted
31  * from peer 1 to peer 3.  Assuming that DV is working, peer 2 should have
32  * gossiped about peer 3 to 1, and should then forward a message from one
33  * to 3.
34  */
35 #include "platform.h"
36 #include "gnunet_common.h"
37 #include "gnunet_hello_lib.h"
38 #include "gnunet_getopt_lib.h"
39 #include "gnunet_os_lib.h"
40 #include "gnunet_program_lib.h"
41 #include "gnunet_scheduler_lib.h"
42 #include "gnunet_transport_service.h"
43 #include "../transport/transport.h"
44
45 #define VERBOSE GNUNET_YES
46
47 #define VERBOSE_ARM GNUNET_NO
48
49 #define START_ARM GNUNET_YES
50
51 /**
52  * How long until we give up on transmitting the message?
53  */
54 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 50)
55
56 #define MTYPE 12345
57
58 static int num_wanted = 2;
59
60 static int num_received = 0;
61
62 struct PeerContext
63 {
64   struct GNUNET_CONFIGURATION_Handle *cfg;
65   struct GNUNET_TRANSPORT_Handle *th;
66   struct GNUNET_PeerIdentity id;
67   const char *cfg_file;
68   struct GNUNET_HELLO_Message *hello;
69 #if START_ARM
70   pid_t arm_pid;
71 #endif
72 };
73
74 static struct PeerContext p1;
75
76 static struct PeerContext p2;
77
78 static struct PeerContext p3;
79
80 static struct PeerContext p4;
81
82 static struct GNUNET_SCHEDULER_Handle *sched;
83
84 static int ok;
85
86 GNUNET_SCHEDULER_TaskIdentifier die_task;
87
88 #if VERBOSE
89 #define OKPP do { ok++; fprintf (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0)
90 #else
91 #define OKPP do { ok++; } while (0)
92 #endif
93
94
95 static void
96 end ()
97 {
98   /* do work here */
99   GNUNET_SCHEDULER_cancel (sched, die_task);
100
101   if (p1.th != NULL)
102     {
103       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transport 1!\n");
104       GNUNET_TRANSPORT_disconnect (p1.th);
105       p1.th = NULL;
106     }
107
108   if (p2.th != NULL)
109     {
110       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transport 2!\n");
111       GNUNET_TRANSPORT_disconnect (p2.th);
112       p2.th = NULL;
113     }
114
115   if (p3.th != NULL)
116     {
117       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transport 3!\n");
118       GNUNET_TRANSPORT_disconnect (p3.th);
119       p3.th = NULL;
120     }
121
122   if (p4.th != NULL)
123     {
124       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transport 4!\n");
125       GNUNET_TRANSPORT_disconnect (p4.th);
126       p4.th = NULL;
127     }
128
129   die_task = GNUNET_SCHEDULER_NO_TASK;
130   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transports disconnected, returning success!\n");
131   sleep(2);
132   ok = 0;
133 }
134
135 static void
136 stop_arm (struct PeerContext *p)
137 {
138 #if START_ARM
139   p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-arm",
140                                         "gnunet-arm",
141 #if VERBOSE
142                                         "-L", "DEBUG",
143 #endif
144                                         "-c", p->cfg_file, "-e", "-q", NULL);
145
146   GNUNET_OS_process_wait (p->arm_pid);
147 #endif
148   GNUNET_CONFIGURATION_destroy (p->cfg);
149 }
150
151
152 static void
153 restart_transport (struct PeerContext *p)
154 {
155 #if START_ARM
156   p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-arm",
157                                         "gnunet-arm",
158 #if VERBOSE
159                                         "-L", "DEBUG",
160 #endif
161                                         "-c", p->cfg_file, "-k", "transport", "-q", NULL);
162
163   GNUNET_OS_process_wait (p->arm_pid);
164 #endif
165
166 #if START_ARM
167   p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-arm",
168                                         "gnunet-arm",
169 #if VERBOSE
170                                         "-L", "DEBUG",
171 #endif
172                                         "-c", p->cfg_file, "-i", "transport", "-q", NULL);
173
174   GNUNET_OS_process_wait (p->arm_pid);
175 #endif
176 }
177
178
179 static void
180 end_badly ()
181 {
182   /* do work here */
183 #if VERBOSE
184   fprintf(stderr, "Ending on an unhappy note.\n");
185 #endif
186
187   if (p1.th != NULL)
188     {
189       GNUNET_TRANSPORT_disconnect (p1.th);
190       p1.th = NULL;
191     }
192
193   if (p2.th != NULL)
194     {
195       GNUNET_TRANSPORT_disconnect (p2.th);
196       p2.th = NULL;
197     }
198
199   if (p3.th != NULL)
200     {
201       GNUNET_TRANSPORT_disconnect (p3.th);
202       p3.th = NULL;
203     }
204
205   if (p4.th != NULL)
206     {
207       GNUNET_TRANSPORT_disconnect (p4.th);
208       p4.th = NULL;
209     }
210   sleep(2);
211   ok = 1;
212   return;
213 }
214
215 static void
216 notify_receive (void *cls,
217                 const struct GNUNET_PeerIdentity *peer,
218                 const struct GNUNET_MessageHeader *message,
219                 struct GNUNET_TIME_Relative latency,
220                 uint32_t distance)
221 {
222   if (ntohs(message->type) != MTYPE)
223     return;
224
225   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message of type %d from peer (%p) distance %d latency %u!\n",
226                 ntohs(message->type), cls, distance, latency.value);
227
228   GNUNET_assert (MTYPE == ntohs (message->type));
229   GNUNET_assert (sizeof (struct GNUNET_MessageHeader) ==
230                  ntohs (message->size));
231   num_received++;
232   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %d of %d messages.\n", num_received, num_wanted);
233
234   if (num_wanted == num_received)
235     {
236       end ();
237     }
238 }
239
240
241 static size_t
242 notify_ready (void *cls, size_t size, void *buf)
243 {
244   struct GNUNET_MessageHeader *hdr;
245
246   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
247               "Transmitting message to peer (%p) - %u!\n", cls, size);
248   GNUNET_assert (size >= 256);
249
250   if (buf != NULL)
251   {
252     hdr = buf;
253     hdr->size = htons (sizeof (struct GNUNET_MessageHeader));
254     hdr->type = htons (MTYPE);
255   }
256
257   return sizeof (struct GNUNET_MessageHeader);
258 }
259
260
261 static void
262 notify_connect (void *cls,
263                 const struct GNUNET_PeerIdentity *peer,
264                 struct GNUNET_TIME_Relative latency,
265                 uint32_t distance)
266 {
267   int peer_num = 0;
268   int connect_num = 0;
269   struct PeerContext *from_peer = cls;
270   char *from_peer_str;
271
272   if (cls == &p1)
273     peer_num = 1;
274   else if (cls == &p2)
275     peer_num = 2;
276   else if (cls == &p3)
277     peer_num = 3;
278   else if (cls == &p4)
279     peer_num = 4;
280
281   if (memcmp(peer, &p1.id, sizeof(struct GNUNET_PeerIdentity)) == 0)
282     connect_num = 1;
283   else if (memcmp(peer, &p2.id, sizeof(struct GNUNET_PeerIdentity)) == 0)
284     connect_num = 2;
285   else if (memcmp(peer, &p3.id, sizeof(struct GNUNET_PeerIdentity)) == 0)
286     connect_num = 3;
287   else if (memcmp(peer, &p4.id, sizeof(struct GNUNET_PeerIdentity)) == 0)
288     connect_num = 4;
289   else
290     connect_num = -1;
291
292   if ((cls == &p1) && (memcmp(peer, &p3.id, sizeof(struct GNUNET_PeerIdentity)) == 0))
293     {
294       GNUNET_TRANSPORT_notify_transmit_ready (p1.th,
295                                               &p3.id,
296                                               256, 0, TIMEOUT, &notify_ready,
297                                               &p1);
298     }
299
300   if ((cls == &p4) && (memcmp(peer, &p1.id, sizeof(struct GNUNET_PeerIdentity)) == 0))
301     {
302
303       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
304                  "Peer 4 notified about connection to peer 1, distance %u!\n", distance);
305
306       GNUNET_TRANSPORT_notify_transmit_ready (p4.th,
307                                               &p1.id,
308                                               256, 0, TIMEOUT, &notify_ready,
309                                               &p4);
310     }
311
312   GNUNET_asprintf(&from_peer_str, "%s", GNUNET_i2s(&from_peer->id));
313   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
314               "Peer `%d' %4s connected to peer `%d' %4s distance %d!\n", peer_num, from_peer_str, connect_num, GNUNET_i2s(peer), distance);
315 }
316
317
318 static void
319 notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
320 {
321   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
322               "Peer `%4s' disconnected (%p)!\n",
323               GNUNET_i2s (peer), cls);
324 }
325
326
327 static void
328 setup_peer (struct PeerContext *p, const char *cfgname)
329 {
330   p->cfg = GNUNET_CONFIGURATION_create ();
331   p->cfg_file = strdup(cfgname);
332 #if START_ARM
333   p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-arm",
334                                         "gnunet-arm",
335 #if VERBOSE_ARM
336                                         "-L", "DEBUG",
337 #endif
338                                         "-c", cfgname, "-s", "-q", NULL);
339 #endif
340   GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
341 }
342
343
344 static void blacklist_peer(struct GNUNET_DISK_FileHandle *file, struct PeerContext *peer)
345 {
346   struct GNUNET_CRYPTO_HashAsciiEncoded peer_enc;
347   char *buf;
348   size_t size;
349
350   GNUNET_CRYPTO_hash_to_enc(&peer->id.hashPubKey, &peer_enc);
351   size = GNUNET_asprintf(&buf, "%s:%s\n", "tcp", (char *)&peer_enc);
352   GNUNET_DISK_file_write(file, buf, size);
353   GNUNET_free_non_null(buf);
354 }
355
356 static void
357 setup_blacklists (void *cls,
358                   const struct GNUNET_SCHEDULER_TaskContext *tc)
359 {
360   char *blacklist_filename;
361   struct GNUNET_DISK_FileHandle *file;
362   int i;
363
364   for (i = 1; i <= 4; i++)
365     {
366       GNUNET_asprintf(&blacklist_filename, "/tmp/test-gnunetd-transport-peer-%d/blacklist", i);
367       if (blacklist_filename != NULL)
368         {
369           file = GNUNET_DISK_file_open(blacklist_filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_TRUNCATE | GNUNET_DISK_OPEN_CREATE,
370                                        GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
371           GNUNET_free(blacklist_filename);
372
373           if (file == NULL)
374             {
375               GNUNET_SCHEDULER_cancel(sched, die_task);
376               GNUNET_SCHEDULER_add_now(sched, &end_badly, NULL);
377               return;
378             }
379           switch (i)
380           {
381             case 1:
382               blacklist_peer(file, &p3);
383               blacklist_peer(file, &p4);
384               break;
385             case 2:
386               blacklist_peer(file, &p4);
387               break;
388             case 3:
389               blacklist_peer(file, &p1);
390               break;
391             case 4:
392               blacklist_peer(file, &p1);
393               blacklist_peer(file, &p2);
394               break;
395           }
396         }
397     }
398
399   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
400               "Disconnecting transports...\n");
401
402   if (p1.th != NULL)
403     {
404       GNUNET_TRANSPORT_disconnect (p1.th);
405       p1.th = NULL;
406     }
407
408   if (p2.th != NULL)
409     {
410       GNUNET_TRANSPORT_disconnect (p2.th);
411       p2.th = NULL;
412     }
413
414   if (p3.th != NULL)
415     {
416       GNUNET_TRANSPORT_disconnect (p3.th);
417       p3.th = NULL;
418     }
419
420   if (p4.th != NULL)
421     {
422       GNUNET_TRANSPORT_disconnect (p4.th);
423       p4.th = NULL;
424     }
425
426   sleep(1);
427
428   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
429                 "Restarting transport service (%p) with gnunet-arm -c %s -L DEBUG -k transport!\n", p1.arm_pid, p1.cfg_file);
430   restart_transport(&p1);
431
432   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
433                 "Restarting transport service (%p) with gnunet-arm -c %s -L DEBUG -k transport!\n", p2.arm_pid, p2.cfg_file);
434   restart_transport(&p2);
435
436   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
437                 "Restarting transport service (%p) with gnunet-arm -c %s -L DEBUG -k transport!\n", p3.arm_pid, p3.cfg_file);
438   restart_transport(&p3);
439
440   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
441                 "Restarting transport service (%p) with gnunet-arm -c %s -L DEBUG -k transport!\n", p4.arm_pid, p4.cfg_file);
442   restart_transport(&p4);
443
444   p1.th = GNUNET_TRANSPORT_connect (sched, p1.cfg,
445                                     &p1,
446                                     &notify_receive,
447                                     &notify_connect, &notify_disconnect);
448
449   p2.th = GNUNET_TRANSPORT_connect (sched, p2.cfg,
450                                     &p2,
451                                     &notify_receive,
452                                     &notify_connect, &notify_disconnect);
453
454   p3.th = GNUNET_TRANSPORT_connect (sched, p3.cfg,
455                                     &p3,
456                                     &notify_receive,
457                                     &notify_connect, &notify_disconnect);
458
459   p4.th = GNUNET_TRANSPORT_connect (sched, p4.cfg,
460                                     &p4,
461                                     &notify_receive,
462                                     &notify_connect, &notify_disconnect);
463   GNUNET_assert(p1.th != NULL);
464   GNUNET_assert(p2.th != NULL);
465   GNUNET_assert(p3.th != NULL);
466   GNUNET_assert(p4.th != NULL);
467
468   GNUNET_TRANSPORT_offer_hello (p1.th, GNUNET_HELLO_get_header(p2.hello));
469   GNUNET_TRANSPORT_offer_hello (p2.th, GNUNET_HELLO_get_header(p3.hello));
470   GNUNET_TRANSPORT_offer_hello (p3.th, GNUNET_HELLO_get_header(p4.hello));
471
472 }
473
474
475 static void
476 get_hello_fourth (void *cls,
477                 const struct GNUNET_MessageHeader *message)
478 {
479   struct PeerContext *me = cls;
480
481   GNUNET_TRANSPORT_get_hello_cancel (me->th, &get_hello_fourth, me);
482
483   GNUNET_assert (message != NULL);
484   GNUNET_assert (GNUNET_OK ==
485                  GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
486                                       message, &me->id));
487
488   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
489               "Received HELLO size %d\n", GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message));
490
491   me->hello = GNUNET_malloc(GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message));
492   memcpy(me->hello, message, GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message));
493
494   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
495               "All HELLO's received, setting up blacklists!\n");
496
497   GNUNET_SCHEDULER_add_now(sched, &setup_blacklists, NULL);
498 }
499
500
501 static void
502 get_hello_third (void *cls,
503                 const struct GNUNET_MessageHeader *message)
504 {
505   struct PeerContext *me = cls;
506
507   GNUNET_TRANSPORT_get_hello_cancel (me->th, &get_hello_third, me);
508
509   GNUNET_assert (message != NULL);
510   GNUNET_assert (GNUNET_OK ==
511                  GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
512                                       message, &me->id));
513
514   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
515               "Received HELLO size %d\n", GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message));
516
517   me->hello = GNUNET_malloc(GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message));
518   memcpy(me->hello, message, GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message));
519
520   GNUNET_TRANSPORT_get_hello (p4.th, &get_hello_fourth, &p4);
521 }
522
523
524 static void
525 get_hello_second (void *cls,
526                 const struct GNUNET_MessageHeader *message)
527 {
528   struct PeerContext *me = cls;
529
530   GNUNET_TRANSPORT_get_hello_cancel (me->th, &get_hello_second, me);
531
532   GNUNET_assert (message != NULL);
533   GNUNET_assert (GNUNET_OK ==
534                  GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
535                                       message, &me->id));
536
537   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
538               "Received HELLO size %d\n", GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message));
539
540   me->hello = GNUNET_malloc(GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message));
541   memcpy(me->hello, message, GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message));
542
543   GNUNET_TRANSPORT_get_hello (p3.th, &get_hello_third, &p3);
544 }
545
546
547 static void
548 get_hello_first (void *cls,
549                 const struct GNUNET_MessageHeader *message)
550 {
551   struct PeerContext *me = cls;
552
553   GNUNET_TRANSPORT_get_hello_cancel (me->th, &get_hello_first, me);
554
555   GNUNET_assert (message != NULL);
556   GNUNET_assert (GNUNET_OK ==
557                  GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
558                                       message, &me->id));
559
560   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
561               "Received HELLO size %d\n", GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message));
562
563   me->hello = GNUNET_malloc(GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message));
564   memcpy(me->hello, message, GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message));
565
566   GNUNET_TRANSPORT_get_hello (p2.th, &get_hello_second, &p2);
567 }
568
569 static void
570 run (void *cls,
571      struct GNUNET_SCHEDULER_Handle *s,
572      char *const *args,
573      const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
574 {
575   GNUNET_assert (ok == 1);
576   OKPP;
577   sched = s;
578
579   die_task = GNUNET_SCHEDULER_add_delayed (sched,
580       GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5), &end_badly, NULL);
581
582   setup_peer (&p1, "test_transport_api_dv_peer1.conf");
583   setup_peer (&p2, "test_transport_api_dv_peer2.conf");
584   setup_peer (&p3, "test_transport_api_dv_peer3.conf");
585   setup_peer (&p4, "test_transport_api_dv_peer4.conf");
586
587   p1.th = GNUNET_TRANSPORT_connect (sched, p1.cfg,
588                                     &p1,
589                                     &notify_receive,
590                                     &notify_connect, &notify_disconnect);
591
592   p2.th = GNUNET_TRANSPORT_connect (sched, p2.cfg,
593                                     &p2,
594                                     &notify_receive,
595                                     &notify_connect, &notify_disconnect);
596
597   p3.th = GNUNET_TRANSPORT_connect (sched, p3.cfg,
598                                     &p3,
599                                     &notify_receive,
600                                     &notify_connect, &notify_disconnect);
601
602   p4.th = GNUNET_TRANSPORT_connect (sched, p4.cfg,
603                                     &p4,
604                                     &notify_receive,
605                                     &notify_connect, &notify_disconnect);
606   GNUNET_assert(p1.th != NULL);
607   GNUNET_assert(p2.th != NULL);
608   GNUNET_assert(p3.th != NULL);
609   GNUNET_assert(p4.th != NULL);
610
611   GNUNET_TRANSPORT_get_hello (p1.th, &get_hello_first, &p1);
612 }
613
614 static int
615 check ()
616 {
617
618   char *const argv[] = { "test-transport-api",
619     "-c",
620     "test_transport_api_data.conf",
621 #if VERBOSE
622     "-L", "DEBUG",
623 #endif
624     NULL
625   };
626
627   struct GNUNET_GETOPT_CommandLineOption options[] = {
628     GNUNET_GETOPT_OPTION_END
629   };
630
631   ok = 1;
632   GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
633                       argv, "test-transport-api", "nohelp",
634                       options, &run, &ok);
635   stop_arm (&p1);
636   stop_arm (&p2);
637   stop_arm (&p3);
638   stop_arm (&p4);
639   return ok;
640 }
641
642
643 int
644 main (int argc, char *argv[])
645 {
646   int ret;
647 #ifdef MINGW
648   return GNUNET_SYSERR;
649 #endif
650
651   GNUNET_log_setup ("test-transport-api-dv",
652 #if VERBOSE
653                     "DEBUG",
654 #else
655                     "WARNING",
656 #endif
657                     NULL);
658   ret = check ();
659   GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-1");
660   GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-2");
661   GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-3");
662   GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-4");
663   return ret;
664 }
665
666 /* end of test_transport_api_dv.c */
667