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