stuff
[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_assert (message != NULL);
147   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
148               "Exchanging HELLO of size %d with peer (%s)!\n", 
149               (int) GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message),
150               GNUNET_i2s (&me->id));
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   if (NULL != p->servicehome)
301     GNUNET_DISK_directory_remove (p->servicehome);    
302
303 #if START_ARM
304   p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
305                                         "gnunet-service-arm",
306 #if VERBOSE_ARM
307                                         "-L", "DEBUG",
308 #endif
309                                         "-c", cfgname, NULL);
310 #endif
311
312
313
314   if (is_https)
315     {
316       struct stat sbuf;
317       if (p==&p1)
318         {
319           if (GNUNET_CONFIGURATION_have_value (p->cfg,
320                                                "transport-https", "KEY_FILE"))
321             GNUNET_CONFIGURATION_get_value_string (p->cfg, "transport-https", "KEY_FILE", &key_file_p1);
322           if (key_file_p1==NULL)
323             GNUNET_asprintf(&key_file_p1,"https.key");
324           if (0 == stat (key_file_p1, &sbuf ))
325             {
326               if (0 == remove(key_file_p1))
327                 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
328                             "Successfully removed existing private key file `%s'\n",key_file_p1);
329               else
330                 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
331                             "Failed to remove private key file `%s'\n",key_file_p1);
332             }
333           if (GNUNET_CONFIGURATION_have_value (p->cfg,"transport-https", "CERT_FILE"))
334             GNUNET_CONFIGURATION_get_value_string (p->cfg, "transport-https", "CERT_FILE", &cert_file_p1);
335           if (cert_file_p1==NULL)
336             GNUNET_asprintf(&cert_file_p1,"https.cert");
337           if (0 == stat (cert_file_p1, &sbuf ))
338             {
339               if (0 == remove(cert_file_p1))
340                 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
341                             "Successfully removed existing certificate file `%s'\n",
342                             cert_file_p1);
343               else
344                 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
345                             "Failed to remove existing certificate file `%s'\n",
346                             cert_file_p1);
347             }
348         }
349       else if (p==&p2)
350         {
351           if (GNUNET_CONFIGURATION_have_value (p->cfg,
352                                                "transport-https", "KEY_FILE"))
353             GNUNET_CONFIGURATION_get_value_string (p->cfg, "transport-https", "KEY_FILE", &key_file_p2);
354           if (key_file_p2==NULL)
355             GNUNET_asprintf(&key_file_p2,"https.key");
356           if (0 == stat (key_file_p2, &sbuf ))
357             {
358               if (0 == remove(key_file_p2))
359                 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
360                             "Successfully removed existing private key file `%s'\n",
361                             key_file_p2);
362               else
363                 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
364                             "Failed to remove private key file `%s'\n",
365                             key_file_p2);
366             }
367           if (GNUNET_CONFIGURATION_have_value (p->cfg,"transport-https", "CERT_FILE"))
368             GNUNET_CONFIGURATION_get_value_string (p->cfg, "transport-https", "CERT_FILE", &cert_file_p2);
369           if (cert_file_p2==NULL)
370             GNUNET_asprintf(&cert_file_p2,"https.cert");
371           if (0 == stat (cert_file_p2, &sbuf ))
372             {
373               if (0 == remove(cert_file_p2))
374                 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
375                             "Successfully removed existing certificate file `%s'\n",cert_file_p2);
376               else
377                 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
378                             "Failed to remove existing certificate file `%s'\n",cert_file_p2);
379             }
380         }
381     }
382   
383   p->th = GNUNET_TRANSPORT_connect (p->cfg,
384                                     NULL, p,
385                                     &notify_receive,
386                                     &notify_connect, &notify_disconnect);
387   GNUNET_assert (p->th != NULL);
388 }
389
390
391 static void
392 try_connect (void *cls,
393              const struct GNUNET_SCHEDULER_TaskContext *tc)
394 {
395   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
396               "Asking peers to connect...\n");
397   /* FIXME: 'pX.id' may still be all-zeros here... */
398   GNUNET_TRANSPORT_try_connect (p2.th,
399                                 &p1.id);
400   GNUNET_TRANSPORT_try_connect (p1.th,
401                                 &p2.id);
402   tct = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
403                                       &try_connect,
404                                       NULL);
405 }
406
407
408 static void
409 run (void *cls,
410      char *const *args,
411      const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
412 {
413   GNUNET_assert (ok == 1);
414   OKPP;
415   die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
416                                            &end_badly, NULL);
417
418   if (is_udp)
419     {
420       setup_peer (&p1, "test_transport_api_udp_peer1.conf");
421       setup_peer (&p2, "test_transport_api_udp_peer2.conf");
422     }
423   if (is_unix)
424     {
425       setup_peer (&p1, "test_transport_api_unix_peer1.conf");
426       setup_peer (&p2, "test_transport_api_unix_peer2.conf");
427     }
428   if (is_multi_protocol)
429     {
430       setup_peer (&p1, "test_transport_api_multi_peer1.conf");
431       setup_peer (&p2, "test_transport_api_multi_peer2.conf");
432     }
433   else if (is_tcp)
434     {
435       setup_peer (&p1, "test_transport_api_tcp_peer1.conf");
436       setup_peer (&p2, "test_transport_api_tcp_peer2.conf");
437     }
438   else if (is_tcp_nat)
439     {
440       setup_peer (&p1, "test_transport_api_tcp_nat_peer1.conf");
441       setup_peer (&p2, "test_transport_api_tcp_nat_peer2.conf");
442     }
443   else if (is_udp_nat)
444     {
445       setup_peer (&p1, "test_transport_api_udp_nat_peer1.conf");
446       setup_peer (&p2, "test_transport_api_udp_nat_peer2.conf");
447     }
448   else if (is_http)
449     {
450       setup_peer (&p1, "test_transport_api_http_peer1.conf");
451       setup_peer (&p2, "test_transport_api_http_peer2.conf");
452     }
453   else if (is_https)
454     {
455       setup_peer (&p1, "test_transport_api_https_peer1.conf");
456       setup_peer (&p2, "test_transport_api_https_peer2.conf");
457     }
458   else if (is_wlan)
459     {
460       setup_peer (&p1, "test_transport_api_wlan_peer1.conf");
461       setup_peer (&p2, "test_transport_api_wlan_peer2.conf");
462     }
463   GNUNET_assert(p1.th != NULL);
464   GNUNET_assert(p2.th != NULL);
465
466   GNUNET_TRANSPORT_get_hello (p1.th, &exchange_hello, &p1);
467   GNUNET_TRANSPORT_get_hello (p2.th, &exchange_hello_last, &p2);
468   tct = GNUNET_SCHEDULER_add_now (&try_connect, NULL);
469 }
470
471 static int
472 check ()
473 {
474   static char *const argv[] = { "test-transport-api",
475     "-c",
476     "test_transport_api_data.conf",
477 #if VERBOSE
478     "-L", "DEBUG",
479 #endif
480     NULL
481   };
482   static struct GNUNET_GETOPT_CommandLineOption options[] = {
483     GNUNET_GETOPT_OPTION_END
484   };
485
486 #if WRITECONFIG
487   setTransportOptions("test_transport_api_data.conf");
488 #endif
489   ok = 1;
490   GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
491                       argv, "test-transport-api", "nohelp",
492                       options, &run, &ok);
493   stop_arm (&p1);
494   stop_arm (&p2);
495
496   if (is_https)
497     {
498       struct stat sbuf;
499       if (0 == stat (cert_file_p1, &sbuf ))
500         {
501           if (0 == remove(cert_file_p1))
502             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
503                         "Successfully removed existing certificate file `%s'\n",cert_file_p1);
504           else
505             GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
506                         "Failed to remove certfile `%s'\n",cert_file_p1);
507         }
508       
509       if (0 == stat (key_file_p1, &sbuf ))
510         {
511           if (0 == remove(key_file_p1))
512             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
513                         "Successfully removed private key file `%s'\n",key_file_p1);
514           else
515             GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
516                         "Failed to private key file `%s'\n",key_file_p1);
517         }
518       
519       if (0 == stat (cert_file_p2, &sbuf ))
520         {
521           if (0 == remove(cert_file_p2))
522             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
523                         "Successfully removed existing certificate file `%s'\n",cert_file_p2);
524           else
525             GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
526                         "Failed to remove certfile `%s'\n",cert_file_p2);
527         }
528       
529       if (0 == stat (key_file_p2, &sbuf ))
530         {
531           if (0 == remove(key_file_p2))
532             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
533                         "Successfully removed private key file `%s'\n",key_file_p2);
534           else
535             GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
536                         "Failed to private key file `%s'\n",key_file_p2);
537         }
538       GNUNET_free(key_file_p1);
539       GNUNET_free(key_file_p2);
540       GNUNET_free(cert_file_p1);
541       GNUNET_free(cert_file_p2);
542     }
543
544   if (p1.servicehome != NULL)
545     {
546     GNUNET_DISK_directory_remove (p1.servicehome);
547     GNUNET_free(p1.servicehome);
548     }
549   if (p2.servicehome != NULL)
550     {
551       GNUNET_DISK_directory_remove (p2.servicehome);
552       GNUNET_free(p2.servicehome);
553     }
554   return ok;
555 }
556
557 /**
558  * Return the actual path to a file found in the current
559  * PATH environment variable.
560  *
561  * @param binary the name of the file to find
562  */
563 static char *
564 get_path_from_PATH (char *binary)
565 {
566   char *path;
567   char *pos;
568   char *end;
569   char *buf;
570   const char *p;
571
572   p = getenv ("PATH");
573   if (p == NULL)
574     {
575       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
576                   _("PATH environment variable is unset.\n"));
577       return NULL;
578     }
579   path = GNUNET_strdup (p);     /* because we write on it */
580   buf = GNUNET_malloc (strlen (path) + 20);
581   pos = path;
582
583   while (NULL != (end = strchr (pos, PATH_SEPARATOR)))
584     {
585       *end = '\0';
586       sprintf (buf, "%s/%s", pos, binary);
587       if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
588         {
589           GNUNET_free (path);
590           return buf;
591         }
592       pos = end + 1;
593     }
594   sprintf (buf, "%s/%s", pos, binary);
595   if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
596     {
597       GNUNET_free (path);
598       return buf;
599     }
600   GNUNET_free (buf);
601   GNUNET_free (path);
602   return NULL;
603 }
604
605 /**
606  * Check whether the suid bit is set on a file.
607  * Attempts to find the file using the current
608  * PATH environment variable as a search path.
609  *
610  * @param binary the name of the file to check
611  *
612  * @return GNUNET_YES if the binary is found and
613  *         can be run properly, GNUNET_NO otherwise
614  */
615 static int
616 check_gnunet_nat_binary(char *binary)
617 {
618   struct stat statbuf;
619   char *p;
620 #ifdef MINGW
621   SOCKET rawsock;
622 #endif
623
624 #ifdef MINGW
625   char *binaryexe;
626   GNUNET_asprintf (&binaryexe, "%s.exe", binary);
627   p = get_path_from_PATH (binaryexe);
628   free (binaryexe);
629 #else
630   p = get_path_from_PATH (binary);
631 #endif
632   if (p == NULL)
633     {
634       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
635                   _("Could not find binary `%s' in PATH!\n"),
636                   binary);
637       return GNUNET_NO;
638     }
639   if (0 != STAT (p, &statbuf))
640     {
641       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
642                   _("stat (%s) failed: %s\n"),
643                   p,
644                   STRERROR (errno));
645       GNUNET_free (p);
646       return GNUNET_SYSERR;
647     }
648   GNUNET_free (p);
649 #ifndef MINGW
650   if ( (0 != (statbuf.st_mode & S_ISUID)) &&
651        (statbuf.st_uid == 0) )
652     return GNUNET_YES;
653   return GNUNET_NO;
654 #else
655   rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
656   if (INVALID_SOCKET == rawsock)
657     {
658       DWORD err = GetLastError ();
659       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
660                   "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) have failed! GLE = %d\n", err);
661       return GNUNET_NO; /* not running as administrator */
662     }
663   closesocket (rawsock);
664   return GNUNET_YES;
665 #endif
666 }
667
668 int
669 main (int argc, char *argv[])
670 {
671   int ret;
672
673   GNUNET_log_setup ("test-transport-api",
674 #if VERBOSE
675                     "DEBUG",
676 #else
677                     "WARNING",
678 #endif
679                     NULL);
680
681   if (strstr(argv[0], "tcp_nat") != NULL)
682     {
683       is_tcp_nat = GNUNET_YES;
684       if (GNUNET_YES != check_gnunet_nat_binary("gnunet-nat-server"))
685         {
686           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
687                       "`%s' not properly installed, cannot run NAT test!\n",
688                       "gnunet-nat-server");
689           return 0;
690         }
691     }
692   else if (strstr(argv[0], "tcp") != NULL)
693     {
694       is_tcp = GNUNET_YES;
695     }
696   else if (strstr(argv[0], "udp_nat") != NULL)
697     {
698       is_udp_nat = GNUNET_YES;
699       if (GNUNET_YES != check_gnunet_nat_binary("gnunet-nat-server"))
700         {
701           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
702                       "`%s' not properly installed, cannot run NAT test!\n",
703                       "gnunet-nat-server");
704           return 0;
705         }
706     }
707   else if (strstr(argv[0], "udp") != NULL)
708     {
709       is_udp = GNUNET_YES;
710     }
711   else if (strstr(argv[0], "unix") != NULL)
712     {
713       is_unix = GNUNET_YES;
714     }
715   else if (strstr(argv[0], "https") != NULL)
716     {
717       is_https = GNUNET_YES;
718     }
719   else if (strstr(argv[0], "http") != NULL)
720     {
721       is_http = GNUNET_YES;
722     }
723   else if (strstr(argv[0], "wlan") != NULL)
724     {
725        is_wlan = GNUNET_YES;
726     }
727   else if (strstr(argv[0], "multi") != NULL)
728     {
729        is_multi_protocol = GNUNET_YES;
730     }
731
732   ret = check ();
733
734   return ret;
735 }
736
737 /* end of test_transport_api.c */