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