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