1f0fcfd3cda60da9f63c38715a258b93a7a02400
[oweals/gnunet.git] / src / transport / test_transport_api_reliability.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009, 2010 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_api_reliability.c
22  * @brief base test case for transport implementations
23  *
24  * This test case serves as a base for tcp and http
25  * transport test cases to check that the transports
26  * achieve reliable message delivery.
27  */
28 #include "platform.h"
29 #include "gnunet_common.h"
30 #include "gnunet_hello_lib.h"
31 #include "gnunet_getopt_lib.h"
32 #include "gnunet_os_lib.h"
33 #include "gnunet_program_lib.h"
34 #include "gnunet_scheduler_lib.h"
35 #include "gnunet_server_lib.h"
36 #include "gnunet_transport_service.h"
37 #include "transport.h"
38
39 #define VERBOSE GNUNET_NO
40
41 #define VERBOSE_ARM GNUNET_NO
42
43 #define START_ARM GNUNET_YES
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 (10000 * 2)
51
52 /**
53  * How long until we give up on transmitting the message?
54  */
55 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1500)
56
57 #define MTYPE 12345
58
59 struct PeerContext
60 {
61   struct GNUNET_CONFIGURATION_Handle *cfg;
62   struct GNUNET_TRANSPORT_Handle *th;
63   struct GNUNET_PeerIdentity id;
64 #if START_ARM
65   pid_t arm_pid;
66 #endif
67 };
68
69 static struct PeerContext p1;
70
71 static struct PeerContext p2;
72
73 static struct GNUNET_SCHEDULER_Handle *sched;
74
75 static int ok;
76
77 static int is_tcp;
78
79 static int is_tcp_nat;
80
81 static int is_http;
82
83 static int is_https;
84
85 static int is_udp;
86
87 static int connected;
88
89 static unsigned long long total_bytes;
90
91 static struct GNUNET_TIME_Absolute start_time;
92
93 static GNUNET_SCHEDULER_TaskIdentifier die_task;
94
95 static char * key_file_p1;
96 static char * cert_file_p1;
97
98 static char * key_file_p2;
99 static char * cert_file_p2;
100
101 static int msg_scheduled;
102 static int msg_sent;
103 static int msg_recv_expected;
104 static int msg_recv;
105
106
107 #if VERBOSE
108 #define OKPP do { ok++; fprintf (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0)
109 #else
110 #define OKPP do { ok++; } while (0)
111 #endif
112
113
114 static void
115 end ()
116 {
117   unsigned long long delta;
118
119   GNUNET_SCHEDULER_cancel (sched, die_task);
120   die_task = GNUNET_SCHEDULER_NO_TASK;
121 #if VERBOSE
122   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transports!\n");
123 #endif
124   GNUNET_TRANSPORT_disconnect (p1.th);
125   GNUNET_TRANSPORT_disconnect (p2.th);
126 #if VERBOSE
127   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
128               "Transports disconnected, returning success!\n");
129 #endif
130   delta = GNUNET_TIME_absolute_get_duration (start_time).value;
131   fprintf (stderr,
132            "\nThroughput was %llu kb/s\n",
133            total_bytes * 1000 / 1024 / delta);
134   ok = 0;
135
136 }
137
138
139
140 static void
141 stop_arm (struct PeerContext *p)
142 {
143 #if START_ARM
144   if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
145     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
146   GNUNET_OS_process_wait (p->arm_pid);
147 #endif
148   GNUNET_CONFIGURATION_destroy (p->cfg);
149 }
150
151
152 static void
153 end_badly (void *cls,
154            const struct GNUNET_SCHEDULER_TaskContext *tc)
155 {
156   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
157                   "Reliability failed: \nLast message sent %u \nNext message scheduled %u\nLast message received %u\nMessage expected %u \n ", msg_sent, msg_scheduled, msg_recv, msg_recv_expected);
158   GNUNET_break (0);
159   GNUNET_TRANSPORT_disconnect (p1.th);
160   GNUNET_TRANSPORT_disconnect (p2.th);
161   ok = 1;
162 }
163
164
165 struct TestMessage
166 {
167   struct GNUNET_MessageHeader header;
168   uint32_t num;
169 };
170
171
172 static unsigned int
173 get_size (unsigned int iter)
174 {
175   unsigned int ret;
176
177   if (iter < 60000)
178     return iter + sizeof (struct TestMessage);
179   ret = (iter * iter * iter);
180   return sizeof (struct TestMessage) + (ret % 60000);
181 }
182
183
184 static void
185 notify_receive (void *cls,
186                 const struct GNUNET_PeerIdentity *peer,
187                 const struct GNUNET_MessageHeader *message,
188                 struct GNUNET_TIME_Relative latency,
189                 uint32_t distance)
190 {
191   static int n;
192   unsigned int s;
193   char cbuf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
194   const struct TestMessage *hdr;
195
196   hdr = (const struct TestMessage*) message;
197   s = get_size (n);
198   if (MTYPE != ntohs (message->type))
199     return;
200   msg_recv_expected = n;
201   msg_recv = ntohl(hdr->num);
202   if (ntohs (message->size) != s)
203     {
204       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
205                   "Expected message %u of size %u, got %u bytes of message %u\n",
206                   n, s,
207                   ntohs (message->size),
208                   ntohl (hdr->num));
209       GNUNET_SCHEDULER_cancel (sched, die_task);
210       die_task = GNUNET_SCHEDULER_add_now (sched, &end_badly, NULL);
211       return;
212     }
213   if (ntohl (hdr->num) != n)
214     {
215       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
216                   "Expected message %u of size %u, got %u bytes of message %u\n",
217                   n, s,
218                   ntohs (message->size),
219                   ntohl (hdr->num));
220       GNUNET_SCHEDULER_cancel (sched, die_task);
221       die_task = GNUNET_SCHEDULER_add_now (sched, &end_badly, NULL);
222       return;
223     }
224   memset (cbuf, n, s - sizeof (struct TestMessage));
225   if (0 != memcmp (cbuf,
226                    &hdr[1],
227                    s - sizeof (struct TestMessage)))
228     {
229       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
230                   "Expected message %u with bits %u, but body did not match\n",
231                   n, (unsigned char) n);
232       GNUNET_SCHEDULER_cancel (sched, die_task);
233       die_task = GNUNET_SCHEDULER_add_now (sched, &end_badly, NULL);
234       return;
235     }
236 #if VERBOSE
237   if (ntohl(hdr->num) % 5000 == 0)
238     {
239       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
240                   "Got message %u of size %u\n",
241                   ntohl (hdr->num),
242                   ntohs (message->size));
243     }
244 #endif
245   n++;
246   if (0 == (n % (TOTAL_MSGS/100)))
247     {
248       fprintf (stderr, ".");
249       GNUNET_SCHEDULER_cancel (sched, die_task);
250       die_task = GNUNET_SCHEDULER_add_delayed (sched,
251                                                TIMEOUT,
252                                                &end_badly,
253                                                NULL);
254     }
255   if (n == TOTAL_MSGS)
256     end ();
257 }
258
259
260 static size_t
261 notify_ready (void *cls, size_t size, void *buf)
262 {
263   static int n;
264   char *cbuf = buf;
265   struct TestMessage hdr;
266   unsigned int s;
267   unsigned int ret;
268
269   if (buf == NULL)
270     {
271       GNUNET_break (0);
272       ok = 42;
273       return 0;
274     }
275   ret = 0;
276   s = get_size (n);
277   GNUNET_assert (size >= s);
278   GNUNET_assert (buf != NULL);
279   cbuf = buf;
280   do
281     {
282       hdr.header.size = htons (s);
283       hdr.header.type = htons (MTYPE);
284       hdr.num = htonl (n);
285       msg_sent = n;
286       memcpy (&cbuf[ret], &hdr, sizeof (struct TestMessage));
287       ret += sizeof (struct TestMessage);
288       memset (&cbuf[ret], n, s - sizeof (struct TestMessage));
289       ret += s - sizeof (struct TestMessage);
290 #if VERBOSE
291       if (n % 5000 == 0)
292         {
293           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
294                       "Sending message %u of size %u\n",
295                       n,
296                       s);
297         }
298 #endif
299       n++;
300       s = get_size (n);
301       if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16))
302         break; /* sometimes pack buffer full, sometimes not */
303     }
304   while (size - ret >= s);
305   if (n < TOTAL_MSGS)
306   {
307     GNUNET_TRANSPORT_notify_transmit_ready (p2.th,
308                                             &p1.id,
309                                             s, 0, TIMEOUT,
310                                             &notify_ready,
311                                             NULL);
312     msg_scheduled = n;
313   }
314   if (n % 5000 == 0)
315     {
316       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
317                   "Returning total message block of size %u\n",
318                   ret);
319     }
320   total_bytes += ret;
321   return ret;
322 }
323
324
325 static void
326 notify_connect (void *cls,
327                 const struct GNUNET_PeerIdentity *peer,
328                 struct GNUNET_TIME_Relative latency,
329                 uint32_t distance)
330 {
331   if (cls == &p1)
332     {
333       GNUNET_TRANSPORT_set_quota (p1.th,
334                                   &p2.id,
335                                   GNUNET_BANDWIDTH_value_init (1024 * 1024 * 1024),
336                                   GNUNET_BANDWIDTH_value_init (1024 * 1024 * 1024),
337                                   GNUNET_TIME_UNIT_FOREVER_REL,
338                                   NULL, NULL);
339       start_time = GNUNET_TIME_absolute_get ();
340       connected++;
341     }
342   else
343     {
344       GNUNET_TRANSPORT_set_quota (p2.th,
345                                   &p1.id,
346                                   GNUNET_BANDWIDTH_value_init (1024 * 1024 * 1024),
347                                   GNUNET_BANDWIDTH_value_init (1024 * 1024 * 1024),
348                                   GNUNET_TIME_UNIT_FOREVER_REL,
349                                   NULL, NULL);
350       connected++;
351     }
352
353   if (connected == 2)
354     {
355       GNUNET_TRANSPORT_notify_transmit_ready (p2.th,
356                                               &p1.id,
357                                               get_size (0), 0, TIMEOUT,
358                                               &notify_ready,
359                                               NULL);
360     }
361 #if VERBOSE
362   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
363               "Peer `%4s' connected to us (%p)!\n", GNUNET_i2s (peer), cls);
364 #endif
365 }
366
367
368 static void
369 notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
370 {
371 #if VERBOSE
372   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
373               "Peer `%4s' disconnected (%p)!\n",
374               GNUNET_i2s (peer), cls);
375 #endif
376 }
377
378
379 static void
380 setup_peer (struct PeerContext *p, const char *cfgname)
381 {
382   p->cfg = GNUNET_CONFIGURATION_create ();
383 #if START_ARM
384   p->arm_pid = GNUNET_OS_start_process (NULL, NULL,
385                                         "gnunet-service-arm",
386                                         "gnunet-service-arm",
387 #if VERBOSE_ARM
388                                         "-L", "DEBUG",
389 #endif
390                                         "-c", cfgname, NULL);
391 #endif
392   GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
393
394   if (is_https)
395   {
396           struct stat sbuf;
397           if (p==&p1)
398           {
399                   if (GNUNET_CONFIGURATION_have_value (p->cfg,
400                                                                                            "transport-https", "KEY_FILE"))
401                                 GNUNET_CONFIGURATION_get_value_string (p->cfg, "transport-https", "KEY_FILE", &key_file_p1);
402                   if (key_file_p1 == NULL)
403                           GNUNET_asprintf(&key_file_p1,"https_p1.key");
404                   if (0 == stat (key_file_p1, &sbuf ))
405                   {
406                           if (0 == remove(key_file_p1))
407                               GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Successfully removed existing private key file `%s'\n",key_file_p1);
408                           else
409                                   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to remove private key file `%s'\n",key_file_p1);
410                   }
411                   if (GNUNET_CONFIGURATION_have_value (p->cfg,"transport-https", "CERT_FILE"))
412                           GNUNET_CONFIGURATION_get_value_string (p->cfg, "transport-https", "CERT_FILE", &cert_file_p1);
413                   if (cert_file_p1 == NULL)
414                           GNUNET_asprintf(&cert_file_p1,"https_p1.cert");
415                   if (0 == stat (cert_file_p1, &sbuf ))
416                   {
417                           if (0 == remove(cert_file_p1))
418                               GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Successfully removed existing certificate file `%s'\n",cert_file_p1);
419                           else
420                                   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to remove existing certificate file `%s'\n",cert_file_p1);
421                   }
422           }
423           else if (p==&p2)
424           {
425                   if (GNUNET_CONFIGURATION_have_value (p->cfg,
426                                                                                            "transport-https", "KEY_FILE"))
427                                 GNUNET_CONFIGURATION_get_value_string (p->cfg, "transport-https", "KEY_FILE", &key_file_p2);
428                   if (key_file_p2 == NULL)
429                           GNUNET_asprintf(&key_file_p2,"https_p2.key");
430                   if (0 == stat (key_file_p2, &sbuf ))
431                   {
432                           if (0 == remove(key_file_p2))
433                               GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Successfully removed existing private key file `%s'\n",key_file_p2);
434                           else
435                                   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to remove private key file `%s'\n",key_file_p2);
436                   }
437                   if (GNUNET_CONFIGURATION_have_value (p->cfg,"transport-https", "CERT_FILE"))
438                           GNUNET_CONFIGURATION_get_value_string (p->cfg, "transport-https", "CERT_FILE", &cert_file_p2);
439                   if (cert_file_p2 == NULL)
440                           GNUNET_asprintf(&cert_file_p2,"https_p2.cert");
441                   if (0 == stat (cert_file_p2, &sbuf ))
442                   {
443                           if (0 == remove(cert_file_p2))
444                               GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Successfully removed existing certificate file `%s'\n",cert_file_p2);
445                           else
446                                   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to remove existing certificate file `%s'\n",cert_file_p2);
447                   }
448           }
449   }
450
451   p->th = GNUNET_TRANSPORT_connect (sched, p->cfg, NULL,
452                                     p,
453                                     &notify_receive,
454                                     &notify_connect,
455                                     &notify_disconnect);
456   GNUNET_assert (p->th != NULL);
457 }
458
459
460 static void
461 exchange_hello_last (void *cls,
462                      const struct GNUNET_MessageHeader *message)
463 {
464   struct PeerContext *me = cls;
465
466   GNUNET_TRANSPORT_get_hello_cancel (p2.th, &exchange_hello_last, me);
467 #if VERBOSE
468   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
469               "Exchanging HELLO with peer (%p)!\n", cls);
470 #endif
471   GNUNET_assert (ok >= 3);
472   OKPP;
473   GNUNET_assert (message != NULL);
474   GNUNET_assert (GNUNET_OK ==
475                  GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
476                                       message, &me->id));
477   /* both HELLOs exchanged, get ready to test transmission! */
478   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
479               "Finished exchanging HELLOs, now waiting for transmission!\n");
480 }
481
482
483 static void
484 exchange_hello (void *cls,
485                 const struct GNUNET_MessageHeader *message)
486 {
487   struct PeerContext *me = cls;
488
489   GNUNET_TRANSPORT_get_hello_cancel (p1.th, &exchange_hello, me);
490 #if VERBOSE
491   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
492               "Exchanging HELLO with peer (%p)!\n", cls);
493 #endif
494   GNUNET_assert (ok >= 2);
495   OKPP;
496   GNUNET_assert (message != NULL);
497   GNUNET_assert (GNUNET_OK ==
498                  GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
499                                       message, &me->id));
500
501 #if VERBOSE
502   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
503               "Received HELLO size %d\n",
504               GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message));
505 #endif
506   GNUNET_TRANSPORT_offer_hello (p2.th, message);
507   GNUNET_TRANSPORT_get_hello (p2.th, &exchange_hello_last, &p2);
508 }
509
510 /**
511  * Return the actual path to a file found in the current
512  * PATH environment variable.
513  *
514  * @param binary the name of the file to find
515  */
516 static char *
517 get_path_from_PATH (char *binary)
518 {
519   char *path;
520   char *pos;
521   char *end;
522   char *buf;
523   const char *p;
524
525   p = getenv ("PATH");
526   if (p == NULL)
527     {
528       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
529                   _("PATH environment variable is unset.\n"));
530       return NULL;
531     }
532   path = GNUNET_strdup (p);     /* because we write on it */
533   buf = GNUNET_malloc (strlen (path) + 20);
534   pos = path;
535
536   while (NULL != (end = strchr (pos, PATH_SEPARATOR)))
537     {
538       *end = '\0';
539       sprintf (buf, "%s/%s", pos, binary);
540       if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
541         {
542           GNUNET_free (path);
543           return buf;
544         }
545       pos = end + 1;
546     }
547   sprintf (buf, "%s/%s", pos, binary);
548   if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
549     {
550       GNUNET_free (path);
551       return buf;
552     }
553   GNUNET_free (buf);
554   GNUNET_free (path);
555   return NULL;
556 }
557
558 /**
559  * Check whether the suid bit is set on a file.
560  * Attempts to find the file using the current
561  * PATH environment variable as a search path.
562  *
563  * @param binary the name of the file to check
564  *
565  * @return GNUNET_YES if the binary is found and
566  *         can be run properly, GNUNET_NO otherwise
567  */
568 static int
569 check_gnunet_nat_binary(char *binary)
570 {
571   struct stat statbuf;
572   char *p;
573 #ifdef MINGW
574   SOCKET rawsock;
575 #endif
576
577 #ifdef MINGW
578   char *binaryexe;
579   GNUNET_asprintf (&binaryexe, "%s.exe", binary);
580   p = get_path_from_PATH (binaryexe);
581   free (binaryexe);
582 #else
583   p = get_path_from_PATH (binary);
584 #endif
585   if (p == NULL)
586     {
587       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
588                   _("Could not find binary `%s' in PATH!\n"),
589                   binary);
590       return GNUNET_NO;
591     }
592   if (0 != STAT (p, &statbuf))
593     {
594       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
595                   _("stat (%s) failed: %s\n"),
596                   p,
597                   STRERROR (errno));
598       GNUNET_free (p);
599       return GNUNET_SYSERR;
600     }
601   GNUNET_free (p);
602 #ifndef MINGW
603   if ( (0 != (statbuf.st_mode & S_ISUID)) &&
604        (statbuf.st_uid == 0) )
605     return GNUNET_YES;
606   return GNUNET_NO;
607 #else
608   rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
609   if (INVALID_SOCKET == rawsock)
610     {
611       DWORD err = GetLastError ();
612       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
613                   "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) have failed! GLE = %d\n", err);
614       return GNUNET_NO; /* not running as administrator */
615     }
616   closesocket (rawsock);
617   return GNUNET_YES;
618 #endif
619 }
620
621 static void
622 run (void *cls,
623      struct GNUNET_SCHEDULER_Handle *s,
624      char *const *args,
625      const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
626 {
627   GNUNET_assert (ok == 1);
628   OKPP;
629   sched = s;
630   die_task = GNUNET_SCHEDULER_add_delayed (sched,
631                                            TIMEOUT,
632                                            &end_badly,
633                                            NULL);
634   if (is_tcp)
635     {
636       setup_peer (&p1, "test_transport_api_tcp_peer1.conf");
637       setup_peer (&p2, "test_transport_api_tcp_peer2.conf");
638     }
639   else if (is_http)
640     {
641       setup_peer (&p1, "test_transport_api_rel_http_peer1.conf");
642       setup_peer (&p2, "test_transport_api_rel_http_peer2.conf");
643     }
644   else if (is_https)
645     {
646       setup_peer (&p1, "test_transport_api_rel_https_peer1.conf");
647       setup_peer (&p2, "test_transport_api_rel_https_peer2.conf");
648     }
649   else if (is_udp)
650     {
651       setup_peer (&p1, "test_transport_api_udp_peer1.conf");
652       setup_peer (&p2, "test_transport_api_udp_peer2.conf");
653     }
654   else if (is_tcp_nat)
655     {
656       setup_peer (&p1, "test_transport_api_tcp_nat_peer1.conf");
657       setup_peer (&p2, "test_transport_api_tcp_nat_peer2.conf");
658     }
659   else
660     GNUNET_assert (0);
661   GNUNET_assert(p1.th != NULL);
662   GNUNET_assert(p2.th != NULL);
663   GNUNET_TRANSPORT_get_hello (p1.th, &exchange_hello, &p1);
664 }
665
666
667 static int
668 check ()
669 {
670   char *const argv[] = { "test-transport-api-reliability",
671     "-c",
672     "test_transport_api_data.conf",
673 #if VERBOSE
674     "-L", "DEBUG",
675 #endif
676     NULL
677   };
678   struct GNUNET_GETOPT_CommandLineOption options[] = {
679     GNUNET_GETOPT_OPTION_END
680   };
681
682 #if WRITECONFIG
683   setTransportOptions("test_transport_api_data.conf");
684 #endif
685   ok = 1;
686
687   if ((GNUNET_YES == is_tcp_nat) && (check_gnunet_nat_binary("gnunet-nat-server") != GNUNET_YES))
688     {
689       GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Not running NAT test case, binaries not properly installed.\n");
690       return 0;
691     }
692
693   GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
694                       argv, "test-transport-api-reliability", "nohelp",
695                       options, &run, &ok);
696   stop_arm (&p1);
697   stop_arm (&p2);
698
699   if (is_https)
700   {
701     struct stat sbuf;
702     if (0 == stat (cert_file_p1, &sbuf ))
703     {
704       if (0 == remove(cert_file_p1))
705         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully removed existing certificate file `%s'\n",cert_file_p1);
706       else
707         GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to remove certfile `%s'\n",cert_file_p1);
708     }
709
710     if (0 == stat (key_file_p1, &sbuf ))
711     {
712       if (0 == remove(key_file_p1))
713         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully removed private key file `%s'\n",key_file_p1);
714       else
715         GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to private key file `%s'\n",key_file_p1);
716     }
717
718     if (0 == stat (cert_file_p2, &sbuf ))
719     {
720       if (0 == remove(cert_file_p2))
721         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully removed existing certificate file `%s'\n",cert_file_p2);
722       else
723         GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to remove certfile `%s'\n",cert_file_p2);
724     }
725
726     if (0 == stat (key_file_p2, &sbuf ))
727     {
728       if (0 == remove(key_file_p2))
729         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully removed private key file `%s'\n",key_file_p2);
730       else
731         GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to private key file `%s'\n",key_file_p2);
732     }
733     GNUNET_free(key_file_p1);
734     GNUNET_free(key_file_p2);
735     GNUNET_free(cert_file_p1);
736     GNUNET_free(cert_file_p2);
737   }
738
739   return ok;
740 }
741
742
743 int
744 main (int argc, char *argv[])
745 {
746   int ret;
747 #ifdef MINGW
748   return GNUNET_SYSERR;
749 #endif
750   if (strstr(argv[0], "tcp_nat") != NULL)
751     {
752       is_tcp_nat = GNUNET_YES;
753     }
754   else if (strstr(argv[0], "tcp") != NULL)
755     {
756       is_tcp = GNUNET_YES;
757     }
758   else if (strstr(argv[0], "https") != NULL)
759     {
760       is_https = GNUNET_YES;
761     }
762   else if (strstr(argv[0], "http") != NULL)
763     {
764       is_http = GNUNET_YES;
765     }
766   else if (strstr(argv[0], "udp") != NULL)
767     {
768       is_udp = GNUNET_YES;
769     }
770   GNUNET_log_setup ("test-transport-api-reliability",
771 #if VERBOSE
772                     "DEBUG",
773 #else
774                     "WARNING",
775 #endif
776                     NULL);
777   ret = check ();
778   GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-1");
779   GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-2");
780   return ret;
781 }
782
783 /* end of test_transport_api_reliability.c */