58817005a4545fd5226ed3d9691daf23b0cd0621
[oweals/gnunet.git] / src / transport / test_plugin_transport_https.c
1 /*
2      This file is part of GNUnet.
3      (C) 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_plugin_transport_https.c
22  * @brief testcase for plugin_transport_https.c
23  * @author Matthias Wachs
24  */
25
26 #include "platform.h"
27 #include "gnunet_constants.h"
28 #include "gnunet_common.h"
29 #include "gnunet_getopt_lib.h"
30 #include "gnunet_hello_lib.h"
31 #include "gnunet_os_lib.h"
32 #include "gnunet_peerinfo_service.h"
33 #include "gnunet_plugin_lib.h"
34 #include "gnunet_protocols.h"
35 #include "gnunet_program_lib.h"
36 #include "gnunet_signatures.h"
37 #include "gnunet_service_lib.h"
38 #include "gnunet_crypto_lib.h"
39
40 #include "plugin_transport.h"
41 #include "gnunet_statistics_service.h"
42 #include "transport.h"
43 #include <curl/curl.h>
44 #include <netinet/in.h>
45 #include <arpa/inet.h>
46
47 #define VERBOSE GNUNET_NO
48 #define DEBUG_CURL GNUNET_NO
49 #define HTTP_BUFFER_SIZE 2048
50
51 #define PLUGIN libgnunet_plugin_transport_template
52
53 #define PROTOCOL_PREFIX "https"
54
55 /**
56  * How long until we give up on transmitting the message?
57  */
58 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
59
60 /**
61  * Testcase timeout
62  */
63 #define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 20)
64
65 /**
66  * How long between recieve and send?
67  */
68 #define WAIT_INTERVALL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
69
70
71
72 /**
73  *  Struct for plugin addresses
74  */
75 struct Plugin_Address
76 {
77   /**
78    * Next field for linked list
79    */
80   struct Plugin_Address * next;
81
82   /**
83    * buffer containing data to send
84    */
85   void * addr;
86
87   /**
88    * amount of data to sent
89    */
90   size_t addrlen;
91 };
92
93 /**
94  *  Message to send using http
95  */
96 struct HTTP_Message
97 {
98   /**
99    * buffer
100    */
101   unsigned char buf[HTTP_BUFFER_SIZE];
102
103   /**
104    * current position in buffer
105    */
106   size_t pos;
107
108   /**
109    * buffer size
110    */
111   size_t size;
112
113   /**
114    * data size
115    */
116   size_t len;
117 };
118
119
120 /**
121  *  Struct for plugin addresses
122  */
123 struct HTTP_Transfer
124 {
125   /**
126    * amount of bytes we recieved
127    */
128   size_t data_size;
129
130   /**
131    * buffer for http transfers
132    */
133   unsigned char buf[HTTP_BUFFER_SIZE];
134
135   /**
136    * buffer size this transfer
137    */
138   size_t size;
139
140   /**
141    * amount of bytes we recieved
142    */
143   size_t pos;
144
145   /**
146    * HTTP Header result for transfer
147    */
148   unsigned int http_result_code;
149
150   /**
151    * did the test fail?
152    */
153   unsigned int test_failed;
154
155   /**
156    * was this test already executed?
157    */
158   unsigned int test_executed;
159 };
160
161
162 /**
163  * Network format for IPv4 addresses.
164  */
165 struct IPv4HttpAddress
166 {
167   /**
168    * IPv4 address, in network byte order.
169    */
170   uint32_t ipv4_addr GNUNET_PACKED;
171
172   /**
173    * Port number, in network byte order.
174    */
175   uint16_t u_port GNUNET_PACKED;
176
177 };
178
179
180 /**
181  * Network format for IPv6 addresses.
182  */
183 struct IPv6HttpAddress
184 {
185   /**
186    * IPv6 address.
187    */
188   struct in6_addr ipv6_addr GNUNET_PACKED;
189
190   /**
191    * Port number, in network byte order.
192    */
193   uint16_t u6_port GNUNET_PACKED;
194
195 };
196
197 /**
198  * Our public key.
199  */
200 /* static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; */
201
202 /**
203  * Our public key.
204  */
205 static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key;
206
207 /**
208  * Our identity.
209  */
210 static struct GNUNET_PeerIdentity my_identity;
211
212 /**
213  * Our private key.
214  */
215 static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key;
216
217 /**
218  * Peer's port
219  */
220 static long long unsigned int port;
221
222 /**
223  * Peer's addr
224  */
225 static char * test_addr;
226
227 /**
228  * Our scheduler.
229  */
230 struct GNUNET_SCHEDULER_Handle *sched;
231
232 /**
233  * Our statistics handle.
234  */
235 struct GNUNET_STATISTICS_Handle *stats;
236
237
238 /**
239  * Our configuration.
240  */
241 const struct GNUNET_CONFIGURATION_Handle *cfg;
242
243 /**
244  * Number of neighbours we'd like to have.
245  */
246 static uint32_t max_connect_per_transport;
247
248 /**
249  * Environment for this plugin.
250  */
251 static struct GNUNET_TRANSPORT_PluginEnvironment env;
252
253 /**
254  *handle for the api provided by this plugin
255  */
256 static struct GNUNET_TRANSPORT_PluginFunctions *api;
257
258 /**
259  * ID of the task controlling the testcase timeout
260  */
261 static GNUNET_SCHEDULER_TaskIdentifier ti_timeout;
262
263 static GNUNET_SCHEDULER_TaskIdentifier ti_send;
264
265 //const struct GNUNET_PeerIdentity * p;
266
267 /**
268  * buffer for data to send
269  */
270 static struct HTTP_Message buffer_out;
271
272 /**
273  * buffer for data to recieve
274  */
275 static struct HTTP_Message buffer_in;
276
277
278 struct Plugin_Address * addr_head;
279
280 /**
281  * Did the test pass or fail?
282  */
283 static int fail_notify_address;
284 /**
285  * Did the test pass or fail?
286  */
287 static int fail_notify_address_count;
288
289 /**
290  * Did the test pass or fail?
291  */
292 static int fail_pretty_printer;
293
294 /**
295  * Did the test pass or fail?
296  */
297 static int fail_pretty_printer_count;
298
299 /**
300  * Did the test pass or fail?
301  */
302 static int fail_addr_to_str;
303
304 /**
305  * No. of msgs transmitted successfully to local addresses
306  */
307 static int fail_msgs_transmited_to_local_addrs;
308
309 /**
310  * Test: transmit msg of max. size
311  */
312 static int fail_msg_transmited_bigger_max_size;
313
314 /**
315  * Test: transmit msg of max. size
316  */
317 static int fail_msg_transmited_max_size;
318
319 /**
320  * Test: transmit 2 msgs. in in send operation
321  */
322 static int fail_multiple_msgs_in_transmission;
323
324 /**
325  * Test: connect to peer without peer identification
326  */
327 static struct HTTP_Transfer test_no_ident;
328
329 /**
330  * Test: connect to peer without peer identification
331  */
332 static struct HTTP_Transfer test_too_short_ident;
333
334 /**
335  * Test: connect to peer without peer identification
336  */
337 static struct HTTP_Transfer test_too_long_ident;
338
339 /**
340  * Test: connect to peer with valid peer identification
341  */
342 static struct HTTP_Transfer test_valid_ident;
343
344 /**
345  * Test: session selection, use any existing
346  */
347 static int fail_session_selection_any;
348
349 /**
350  * Test: session selection, use existing inbound session
351  */
352 static int fail_session_selection_session;
353
354 /**
355  * Test: session selection, use existing inbound session
356  * max message, not fitting in send & recv buffers at one time
357  */
358 static int fail_session_selection_session_big;
359
360 /**
361 * Test: session selection, use reliable existing
362  */
363 static int fail_session_selection_reliable;
364
365 /**
366  * Did the test pass or fail?
367  */
368 static int fail;
369
370 /**
371  * Number of local addresses
372  */
373 static unsigned int count_str_addr;
374
375 CURL *curl_handle;
376
377 /**
378  * cURL Multihandle
379  */
380 static CURLM *multi_handle;
381
382 /**
383  * The task sending data
384  */
385 static GNUNET_SCHEDULER_TaskIdentifier http_task_send;
386
387 /**
388  * Shutdown testcase
389  */
390 static void
391 shutdown_clean ()
392 {
393   struct Plugin_Address * cur;
394   struct Plugin_Address * tmp;
395
396   /* Evaluate results  */
397   fail = 0;
398   if ((fail_notify_address == GNUNET_YES) || (fail_pretty_printer == GNUNET_YES) || (fail_addr_to_str == GNUNET_YES))
399   {
400     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Phase 0: Test plugin functions failed\n"));
401     fail = 1;
402   }
403   if ((test_no_ident.test_failed == GNUNET_YES) || (test_too_short_ident.test_failed == GNUNET_YES) || (test_too_long_ident.test_failed == GNUNET_YES) || (test_valid_ident.test_failed == GNUNET_YES))
404   {
405     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Phase 1: Test connect with wrong data failed\n"));
406     fail = 1;
407   }
408   if ((fail_session_selection_any != GNUNET_NO) || (fail_session_selection_reliable != GNUNET_NO) || (fail_session_selection_session != GNUNET_NO) || (fail_session_selection_session_big != GNUNET_NO))
409   {
410     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Phase 2: Test session selection failed\n"));
411     fail = 1;
412   }
413   if ((fail_msgs_transmited_to_local_addrs != count_str_addr) || (fail_multiple_msgs_in_transmission != 2) || (fail_msg_transmited_max_size == GNUNET_YES))
414   {
415     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Phase 3: Test sending with plugin failed\n"));
416     fail = 1;
417   }
418   if (fail != 1)
419   {
420     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All tests successful\n");
421   }
422
423   api->disconnect(api->cls,&my_identity);
424
425   curl_multi_cleanup(multi_handle);
426
427   if (NULL != curl_handle)
428     curl_easy_cleanup (curl_handle);
429
430   /* cleaning addresses */
431   while (addr_head != NULL)
432   {
433     cur = addr_head;
434     tmp = addr_head->next;
435     GNUNET_free (addr_head->addr);
436     GNUNET_free (addr_head);
437     addr_head=tmp;
438   }
439
440   if (ti_send != GNUNET_SCHEDULER_NO_TASK)
441   {
442     GNUNET_SCHEDULER_cancel(sched,ti_send);
443     ti_send = GNUNET_SCHEDULER_NO_TASK;
444   }
445
446   if (http_task_send != GNUNET_SCHEDULER_NO_TASK)
447   {
448     GNUNET_SCHEDULER_cancel(sched,http_task_send);
449     http_task_send = GNUNET_SCHEDULER_NO_TASK;
450   }
451
452   if (ti_timeout != GNUNET_SCHEDULER_NO_TASK)
453   {
454     GNUNET_SCHEDULER_cancel(sched,ti_timeout);
455     ti_timeout = GNUNET_SCHEDULER_NO_TASK;
456   }
457
458   GNUNET_free(test_addr);
459   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Unloading http plugin\n");
460   GNUNET_assert (NULL == GNUNET_PLUGIN_unload ("libgnunet_plugin_transport_http", api));
461
462   GNUNET_SCHEDULER_shutdown(sched);
463   GNUNET_DISK_directory_remove ("/tmp/test_plugin_transport_http");
464
465   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Exiting testcase\n");
466   exit(fail);
467   return;
468 }
469
470
471 /**
472  * Continuation called after plugin send message
473  * @cls closure
474  * @target target
475  * @result GNUNET_OK or GNUNET_SYSERR
476  */
477
478 static void task_send_cont (void *cls,
479                             const struct GNUNET_PeerIdentity * target,
480                             int result)
481 {
482   struct Plugin_Address * tmp_addr;
483   tmp_addr = addr_head;
484
485   if ((cls == &fail_msg_transmited_bigger_max_size) && (result == GNUNET_SYSERR))
486   {
487     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Message bigger max msg size was not sent!\n");
488     fail_msg_transmited_bigger_max_size = GNUNET_NO;
489     return;
490   }
491
492   if ((cls == &fail_msg_transmited_max_size) && (result == GNUNET_OK))
493   {
494     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Message with max msg size succesfully sent!\n",fail_msgs_transmited_to_local_addrs);
495     fail_msg_transmited_max_size = GNUNET_NO;
496   }
497 }
498
499
500 static void run_connection_tests( int phase , void * cls);
501
502 /**
503  * Recieves messages from plugin, in real world transport
504  */
505 static struct GNUNET_TIME_Relative
506 receive (void *cls,
507          const struct GNUNET_PeerIdentity * peer,
508          const struct GNUNET_MessageHeader * message,
509          uint32_t distance,
510          struct Session *session,
511          const char *sender_address,
512          uint16_t sender_address_len)
513 {
514   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testcase recieved new message from peer `%s' with type %u and length %u, session %X\n",  GNUNET_i2s(peer), ntohs(message->type), ntohs(message->size),session);
515
516   if ((ntohs(message->type)>=10) && (ntohs(message->type)<20))
517   {
518     fail_msgs_transmited_to_local_addrs++;
519     if (fail_msgs_transmited_to_local_addrs == count_str_addr)
520       run_connection_tests(2, session);
521   }
522
523
524   if ((ntohs(message->type)==20))
525   {
526     fail_session_selection_reliable = GNUNET_NO;
527   }
528
529   if ((ntohs(message->type)==21))
530   {
531     fail_session_selection_any = GNUNET_NO;
532   }
533   if ((ntohs(message->type)==22))
534   {
535     fail_session_selection_session = GNUNET_NO;
536   }
537
538   if ((ntohs(message->type)==23))
539   {
540     fail_session_selection_session_big = GNUNET_NO;
541     run_connection_tests(3, NULL);
542   }
543
544   if ((ntohs(message->type)==30) || (ntohs(message->type)==31))
545   {
546     fail_multiple_msgs_in_transmission ++;
547   }
548
549   if ((ntohs(message->type)==32) && (ntohs(message->size) == GNUNET_SERVER_MAX_MESSAGE_SIZE-1))
550   {
551     fail_msg_transmited_max_size = GNUNET_NO;
552     shutdown_clean();
553   }
554
555   return GNUNET_TIME_UNIT_ZERO;
556 }
557
558 static size_t send_function (void *stream, size_t size, size_t nmemb, void *ptr)
559 {
560   unsigned int len;
561
562   len = buffer_out.len;
563
564   if (( buffer_out.pos == len) || (len > (size * nmemb)))
565     return 0;
566   memcpy(stream, buffer_out.buf, len);
567   buffer_out.pos = len;
568   return len;
569 }
570
571 static size_t recv_function (void *ptr, size_t size, size_t nmemb, void *ctx)
572 {
573
574   if (buffer_in.pos + size * nmemb > buffer_in.size)
575     return 0;                   /* overflow */
576
577   buffer_in.len = size * nmemb;
578   memcpy (&buffer_in.buf[buffer_in.pos], ptr, size * nmemb);
579   buffer_in.pos += size * nmemb;
580   buffer_in.len = buffer_in.pos;
581   buffer_in.buf[buffer_in.pos] = '\0';
582   return buffer_in.pos;
583 }
584
585 static size_t header_function( void *ptr, size_t size, size_t nmemb, void *stream)
586 {
587   struct HTTP_Transfer * res = (struct HTTP_Transfer *) stream;
588   char * tmp;
589   unsigned int len = size * nmemb;
590
591   tmp = GNUNET_malloc (  len+1 );
592   memcpy(tmp,ptr,len);
593   if (tmp[len-2] == 13)
594     tmp[len-2]= '\0';
595 #if DEBUG_CURL
596   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Header: `%s'\n",tmp);
597 #endif
598   if (0==strcmp (tmp,"HTTP/1.1 100 Continue"))
599   {
600     res->http_result_code=100;
601   }
602   if (0==strcmp (tmp,"HTTP/1.1 200 OK"))
603   {
604     res->http_result_code=200;
605   }
606   if (0==strcmp (tmp,"HTTP/1.1 400 Bad Request"))
607   {
608     res->http_result_code=400;
609   }
610   if (0==strcmp (tmp,"HTTP/1.1 404 Not Found"))
611   {
612     res->http_result_code=404;
613   }
614   if (0==strcmp (tmp,"HTTP/1.1 413 Request entity too large"))
615   {
616     res->http_result_code=413;
617   }
618
619   GNUNET_free (tmp);
620   return size * nmemb;
621 }
622
623 static size_t send_prepare( struct HTTP_Transfer * result);
624
625
626
627 static void send_execute (void *cls,
628              const struct GNUNET_SCHEDULER_TaskContext *tc)
629 {
630   struct HTTP_Transfer *res;
631
632   int running;
633   struct CURLMsg *msg;
634   CURLMcode mret;
635
636   res = (struct HTTP_Transfer *) cls;
637   http_task_send = GNUNET_SCHEDULER_NO_TASK;
638   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
639     return;
640
641   do
642     {
643       running = 0;
644       mret = curl_multi_perform (multi_handle, &running);
645       if (running == 0)
646         {
647           do
648             {
649
650               msg = curl_multi_info_read (multi_handle, &running);
651               if (msg == NULL)
652                 break;
653               /* get session for affected curl handle */
654               //cs = find_session_by_curlhandle (msg->easy_handle);
655               //GNUNET_assert ( cs != NULL );
656               switch (msg->msg)
657                 {
658
659                 case CURLMSG_DONE:
660                   if ( (msg->data.result != CURLE_OK) &&
661                        (msg->data.result != CURLE_GOT_NOTHING) )
662                     {
663
664                     GNUNET_log(GNUNET_ERROR_TYPE_INFO,
665                                _("curl failed for `%s' at %s:%d: `%s'\n"),
666                                "curl_multi_perform",
667                                __FILE__,
668                                __LINE__,
669                                curl_easy_strerror (msg->data.result));
670                     /* sending msg failed*/
671                     curl_easy_cleanup(curl_handle);
672                     curl_handle=NULL;
673
674                     run_connection_tests(0, NULL);
675                     }
676                   if (res == &test_no_ident)
677                   {
678                     if  ((res->http_result_code==404) && (buffer_in.len==208))
679                     {
680                       GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connecting to peer without any peer identification: test passed\n");
681                       res->test_failed = GNUNET_NO;
682                     }
683                     else
684                       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Connecting to peer without any peer identification: test failed\n"));
685                   }
686                   if (res == &test_too_short_ident)
687                   {
688                     if  ((res->http_result_code==404) && (buffer_in.len==208))
689                     {
690                       GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connecting to peer with too short peer identification: test passed\n");
691                       res->test_failed = GNUNET_NO;
692                     }
693                     else
694                       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Connecting to peer with too short peer identification: test failed\n"));
695                   }
696                   if (res == &test_too_long_ident)
697                   {
698                     if  ((res->http_result_code==404) && (buffer_in.len==208))
699                       {
700                       GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connecting to peer with too long peer identification: test passed\n");
701                       res->test_failed = GNUNET_NO;
702                       }
703                     else
704                       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Connecting to peer with too long peer identification: test failed\n"));
705                   }
706                   if (res == &test_valid_ident)
707                   {
708                     if  ((res->http_result_code==200))
709                     {
710                       GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connecting to peer with valid peer identification: test passed\n");
711                       res->test_failed = GNUNET_NO;
712                     }
713                     else
714                       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Connecting to peer with valid peer identification: test failed\n"));
715                   }
716                   curl_easy_cleanup(curl_handle);
717                   curl_handle=NULL;
718                   if ((res == &test_valid_ident) && (res->test_failed == GNUNET_NO))
719                     run_connection_tests(1, NULL);
720                   run_connection_tests(0, NULL);
721                   return;
722                 default:
723                   break;
724                 }
725
726             }
727           while ( (running > 0) );
728         }
729     }
730   while (mret == CURLM_CALL_MULTI_PERFORM);
731   send_prepare(cls);
732 }
733
734 /**
735  * Function setting up file descriptors and scheduling task to run
736  * @param ses session to send data to
737  * @return bytes sent to peer
738  */
739 static size_t send_prepare( struct HTTP_Transfer * result)
740 {
741   fd_set rs;
742   fd_set ws;
743   fd_set es;
744   int max;
745   struct GNUNET_NETWORK_FDSet *grs;
746   struct GNUNET_NETWORK_FDSet *gws;
747   long to;
748   CURLMcode mret;
749
750   max = -1;
751   FD_ZERO (&rs);
752   FD_ZERO (&ws);
753   FD_ZERO (&es);
754   mret = curl_multi_fdset (multi_handle, &rs, &ws, &es, &max);
755   if (mret != CURLM_OK)
756     {
757       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
758                   _("%s failed at %s:%d: `%s'\n"),
759                   "curl_multi_fdset", __FILE__, __LINE__,
760                   curl_multi_strerror (mret));
761       return -1;
762     }
763   mret = curl_multi_timeout (multi_handle, &to);
764   if (mret != CURLM_OK)
765     {
766       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
767                   _("%s failed at %s:%d: `%s'\n"),
768                   "curl_multi_timeout", __FILE__, __LINE__,
769                   curl_multi_strerror (mret));
770       return -1;
771     }
772
773   grs = GNUNET_NETWORK_fdset_create ();
774   gws = GNUNET_NETWORK_fdset_create ();
775   GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1);
776   GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1);
777   http_task_send = GNUNET_SCHEDULER_add_select (sched,
778                                    GNUNET_SCHEDULER_PRIORITY_DEFAULT,
779                                    GNUNET_SCHEDULER_NO_TASK,
780                                    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 0),
781                                    grs,
782                                    gws,
783                                    &send_execute,
784                                    result);
785   GNUNET_NETWORK_fdset_destroy (gws);
786   GNUNET_NETWORK_fdset_destroy (grs);
787
788   /* FIXME: return bytes REALLY sent */
789   return 0;
790 }
791
792 /**
793  * function to send data to server
794  */
795 static int send_data( struct HTTP_Transfer * result, char * url)
796 {
797
798   curl_handle = curl_easy_init();
799   if( NULL == curl_handle)
800   {
801     printf("easy_init failed \n");
802     return GNUNET_SYSERR;
803   }
804 #if DEBUG_CURL
805   curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
806 #endif
807   curl_easy_setopt(curl_handle, CURLOPT_URL, url);
808   curl_easy_setopt(curl_handle, CURLOPT_PUT, 1L);
809   //curl_easy_setopt(curl_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
810   curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
811   curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
812   curl_easy_setopt (curl_handle, CURLOPT_HEADERFUNCTION, &header_function);
813   curl_easy_setopt (curl_handle, CURLOPT_WRITEHEADER, result);
814   curl_easy_setopt (curl_handle, CURLOPT_WRITEFUNCTION, &recv_function);
815   curl_easy_setopt (curl_handle, CURLOPT_WRITEDATA, result);
816   curl_easy_setopt (curl_handle, CURLOPT_READFUNCTION, &send_function);
817   curl_easy_setopt (curl_handle, CURLOPT_READDATA, result);
818   curl_easy_setopt(curl_handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t) buffer_out.len);
819   curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 30);
820   curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT, 20);
821
822   curl_multi_add_handle(multi_handle, curl_handle);
823
824   send_prepare(result);
825
826   return GNUNET_OK;
827 }
828
829 /**
830  * Plugin notifies transport (aka testcase) about its addresses
831  */
832 void
833 notify_address (void *cls,
834                 const char *name,
835                 const void *addr,
836                 uint16_t addrlen,
837                 struct GNUNET_TIME_Relative expires)
838 {
839   char address[INET6_ADDRSTRLEN];
840   unsigned int port;
841   struct Plugin_Address * pl_addr;
842   struct Plugin_Address * cur;
843
844   if (addrlen == (sizeof (struct IPv4HttpAddress)))
845     {
846       inet_ntop(AF_INET, (struct in_addr *) addr,address,INET_ADDRSTRLEN);
847       port = ntohs(((struct IPv4HttpAddress *) addr)->u_port);
848     }
849   else if (addrlen == (sizeof (struct IPv6HttpAddress)))
850     {
851       inet_ntop(AF_INET6, (struct in6_addr *) addr,address,INET6_ADDRSTRLEN);
852       port = ntohs(((struct IPv6HttpAddress *) addr)->u6_port);
853     }
854   else
855     {
856     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
857                 _("Unknown address size: ipv6 has %u ipv4 has %u but this has %u\n"),
858                 sizeof (struct IPv6HttpAddress),
859                 sizeof (struct IPv4HttpAddress),
860                 addrlen);
861       return;
862     }
863   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
864               _("Transport plugin notification for address: `%s':%u\n"),
865               address,
866               port);
867   pl_addr = GNUNET_malloc (sizeof (struct Plugin_Address) );
868   pl_addr->addrlen = addrlen;
869   pl_addr->addr = GNUNET_malloc(addrlen);
870   memcpy(pl_addr->addr,addr,addrlen);
871   pl_addr->next = NULL;
872
873   if ( NULL == addr_head)
874     {
875       addr_head = pl_addr;
876     }
877   else
878     {
879       cur = addr_head;
880       while (NULL != cur->next)
881         {
882           cur = cur->next;
883         }
884       cur->next = pl_addr;
885     }
886   fail_notify_address_count++;
887   fail_notify_address = GNUNET_NO;
888 }
889
890 static void
891 plugin_env_session_end  (void *cls,
892                          const struct GNUNET_PeerIdentity *peer,
893                          struct Session *session)
894 {
895           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Pluging tells me: session %X to peer `%s' ended\n", session, GNUNET_i2s(peer));
896 }
897
898
899 /**
900  * Setup plugin environment
901  */
902 static void
903 setup_plugin_environment ()
904 {
905   env.cfg = cfg;
906   env.sched = sched;
907   env.stats = stats;
908   env.my_identity = &my_identity;
909   env.cls = &env;
910   env.receive = &receive;
911   env.notify_address = &notify_address;
912   env.max_connections = max_connect_per_transport;
913   env.session_end = &plugin_env_session_end;
914 }
915
916
917 /**
918  * Task shutting down testcase if it a timeout occurs
919  */
920 static void
921 task_timeout (void *cls,
922             const struct GNUNET_SCHEDULER_TaskContext *tc)
923 {
924   ti_timeout = GNUNET_SCHEDULER_NO_TASK;
925   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
926     return;
927
928   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testcase timeout\n");
929   fail = GNUNET_YES;
930   shutdown_clean();
931   return;
932 }
933
934 static void pretty_printer_cb (void *cls,
935                                const char *address)
936 {
937   if (NULL==address)
938     return;
939   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Plugin returned pretty address: `%s'\n",address);
940   fail_pretty_printer_count++;
941 }
942
943 /**
944  * Runs every single test to test the plugin
945  */
946 static void run_connection_tests( int phase , void * cls)
947 {
948   struct GNUNET_MessageHeader * msg;
949   unsigned int size;
950
951   if (phase==0)
952   {
953     char * host_str = NULL;
954     /* resetting buffers */
955     buffer_in.size = HTTP_BUFFER_SIZE;
956     buffer_in.pos = 0;
957     buffer_in.len = 0;
958
959     buffer_out.size = HTTP_BUFFER_SIZE;
960     buffer_out.pos = 0;
961     buffer_out.len = 0;
962
963     if (test_no_ident.test_executed == GNUNET_NO)
964     {
965       /* Connecting to peer without identification */
966       char * ident = "";
967       GNUNET_asprintf (&host_str, "%s://%s/%s",PROTOCOL_PREFIX, test_addr,ident);
968       GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Connecting to peer without any peer identification.\n"));
969       test_no_ident.test_executed = GNUNET_YES;
970       send_data ( &test_no_ident, host_str);
971       GNUNET_free (host_str);
972       return;
973     }
974     if (test_too_short_ident.test_executed == GNUNET_NO)
975     {
976       char * ident = "AAAAAAAAAA";
977       /* Connecting to peer with too short identification */
978       GNUNET_asprintf (&host_str, "%s://%s/%s",PROTOCOL_PREFIX, test_addr,ident);
979       GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Connecting to peer with too short peer identification.\n"));
980       test_too_short_ident.test_executed = GNUNET_YES;
981       send_data ( &test_too_short_ident, host_str);
982       GNUNET_free (host_str);
983       return;
984     }
985
986     if (test_too_long_ident.test_executed == GNUNET_NO)
987     {
988       char * ident = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
989
990       /* Connecting to peer with too long identification */
991       GNUNET_asprintf (&host_str, "%s://%s/%s",PROTOCOL_PREFIX, test_addr,ident);
992       GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Connecting to peer with too long peer identification.\n"));
993       test_too_long_ident.test_executed = GNUNET_YES;
994       send_data ( &test_too_long_ident, host_str);
995       GNUNET_free (host_str);
996       return;
997     }
998     if (test_valid_ident.test_executed == GNUNET_NO)
999     {
1000       struct GNUNET_CRYPTO_HashAsciiEncoded ident;
1001       GNUNET_CRYPTO_hash_to_enc(&my_identity.hashPubKey,&ident);
1002       GNUNET_asprintf (&host_str, "%s://%s/%s%s",PROTOCOL_PREFIX, test_addr,(char *) &ident,";0");
1003       GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Connecting to peer with valid peer identification.\n"));
1004       test_valid_ident.test_executed = GNUNET_YES;
1005       send_data ( &test_valid_ident, host_str);
1006       GNUNET_free (host_str);
1007       return;
1008     }
1009   }
1010   if (phase==1)
1011   {
1012     GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("\nPhase 1: transmit data to all suggested addresses\n\n"));
1013     /* Using one of the addresses the plugin proposed */
1014     GNUNET_assert (addr_head->addr != NULL);
1015
1016     struct Plugin_Address * tmp_addr;
1017     struct GNUNET_MessageHeader msg;
1018     char * tmp = GNUNET_malloc(sizeof(struct GNUNET_MessageHeader));
1019     char address[INET6_ADDRSTRLEN];
1020     unsigned int port;
1021     unsigned int type = 10;
1022
1023     msg.size=htons(sizeof(struct GNUNET_MessageHeader));
1024     tmp_addr = addr_head;
1025     /* send a message to all addresses advertised by plugin */
1026
1027     int count = 0;
1028     while (tmp_addr != NULL)
1029     {
1030       if (tmp_addr->addrlen == (sizeof (struct IPv4HttpAddress)))
1031         {
1032           inet_ntop(AF_INET, (struct in_addr *) tmp_addr->addr,address,INET_ADDRSTRLEN);
1033           port = ntohs(((struct IPv4HttpAddress *) tmp_addr->addr)->u_port);
1034           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Sending message to addres no. %u: `%s':%u\n", count,address, port);
1035         }
1036       if (tmp_addr->addrlen == (sizeof (struct IPv6HttpAddress)))
1037         {
1038           inet_ntop(AF_INET6, (struct in6_addr *) tmp_addr->addr,address,INET6_ADDRSTRLEN);
1039           port = ntohs(((struct IPv6HttpAddress *) tmp_addr->addr)->u6_port);
1040           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Sending message to addres no. %u: `%s':%u\n", count,address,port);
1041         }
1042       msg.type=htons(type);
1043       memcpy(tmp,&msg,sizeof(struct GNUNET_MessageHeader));
1044       api->send(api->cls, &my_identity, tmp, sizeof(struct GNUNET_MessageHeader), 0, TIMEOUT, NULL,tmp_addr->addr, tmp_addr->addrlen, GNUNET_YES, &task_send_cont, &fail_msgs_transmited_to_local_addrs);
1045       tmp_addr = tmp_addr->next;
1046
1047       count ++;
1048       type ++;
1049     }
1050     GNUNET_free(tmp);
1051     return;
1052   }
1053
1054   if (phase==2)
1055   {
1056     struct Session * session = cls;
1057     msg = GNUNET_malloc (sizeof(struct GNUNET_MessageHeader));
1058
1059     GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("\nPhase 2: session selection\n\n"));
1060     size = sizeof(struct GNUNET_MessageHeader);
1061     msg->size=htons(size);
1062     msg->type = htons(20);
1063     api->send(api->cls, &my_identity, (const char *) msg, size, 0, TIMEOUT, NULL, NULL, 0, GNUNET_NO, &task_send_cont, NULL);
1064
1065     msg->type = htons(21);
1066     api->send(api->cls, &my_identity, (const char *) msg, size, 0, TIMEOUT, NULL, NULL, 0, GNUNET_SYSERR, &task_send_cont, NULL);
1067
1068     /* answer on session*/
1069     size = sizeof( struct GNUNET_MessageHeader);
1070     msg->size = htons(size);
1071     msg->type = htons(22);
1072     api->send(api->cls, &my_identity, (const char *) msg, size, 0, TIMEOUT, session, NULL, 0, GNUNET_SYSERR, &task_send_cont, NULL);
1073
1074     GNUNET_free(msg);
1075
1076     /* answer on session with big message not fitting in mhd send buffer*/
1077     size = GNUNET_SERVER_MAX_MESSAGE_SIZE-1;
1078     msg = GNUNET_malloc (size);
1079     msg->size=htons(size);
1080     msg->type = htons(23);
1081     api->send(api->cls, &my_identity, (const char *) msg, size, 0, TIMEOUT, session, NULL, 0, GNUNET_NO, &task_send_cont, NULL);
1082     GNUNET_free(msg);
1083     return;
1084   }
1085
1086   if (phase==3)
1087   {
1088
1089     GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("\nPhase 3: send multiple or big messages after disconnect\n\n"));
1090     /* disconnect from peer, so new connections are created */
1091     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Disconnect from peer: `%s'\n", GNUNET_i2s(&my_identity));
1092     api->disconnect(api->cls, &my_identity);
1093
1094     GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Phase 3: sending messages\n"));
1095     /* send a multiple GNUNET_messages at a time*/
1096     size = 2 * sizeof(struct GNUNET_MessageHeader);
1097     msg = GNUNET_malloc( 2* size);
1098     msg->size = htons(size);
1099     msg->type = htons(30);
1100     struct GNUNET_MessageHeader * msg2 = &msg[2];
1101     msg2->size = htons(2 * sizeof(struct GNUNET_MessageHeader));
1102     msg2->type = htons(31);
1103     api->send(api->cls, &my_identity, (const char *) msg, 4 * sizeof(struct GNUNET_MessageHeader), 0, TIMEOUT, NULL,addr_head->addr, addr_head->addrlen, GNUNET_NO, &task_send_cont, &fail_multiple_msgs_in_transmission);
1104     GNUNET_free(msg);
1105     /* send a message with size GNUNET_SERVER_MAX_MESSAGE_SIZE-1  */
1106
1107     size = GNUNET_SERVER_MAX_MESSAGE_SIZE-1;
1108     msg = GNUNET_malloc(size);
1109     msg->size = htons(size);
1110     msg->type = htons(32);
1111     api->send(api->cls, &my_identity, (const char *) msg, size, 0, TIMEOUT, NULL,addr_head->addr, addr_head->addrlen, GNUNET_NO, &task_send_cont, &fail_msg_transmited_max_size);
1112     GNUNET_free(msg);
1113     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No more tests to run\n");
1114   }
1115 }
1116
1117
1118 /**
1119  * Runs the test.
1120  *
1121  * @param cls closure
1122  * @param s scheduler to use
1123  * @param c configuration to use
1124  */
1125 static void
1126 run (void *cls,
1127      struct GNUNET_SCHEDULER_Handle *s,
1128      char *const *args,
1129      const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
1130 {
1131   char * libname;
1132   sched = s;
1133   cfg = c;
1134   char *keyfile;
1135   unsigned long long tneigh;
1136   struct Plugin_Address * cur;
1137   const char * addr_str;
1138
1139
1140   unsigned int suggest_res;
1141
1142   fail_pretty_printer = GNUNET_YES;
1143   fail_notify_address = GNUNET_YES;
1144   fail_addr_to_str = GNUNET_YES;
1145   fail_msgs_transmited_to_local_addrs = 0;
1146   fail_msg_transmited_max_size = GNUNET_YES;
1147   fail_multiple_msgs_in_transmission = 0;
1148   fail_session_selection_reliable = GNUNET_YES;
1149   fail_session_selection_reliable = GNUNET_YES;
1150   fail_session_selection_session = GNUNET_YES;
1151   fail_session_selection_session_big = GNUNET_YES;
1152
1153   addr_head = NULL;
1154   count_str_addr = 0;
1155   /* parse configuration */
1156   if ((GNUNET_OK !=
1157        GNUNET_CONFIGURATION_get_value_number (c,
1158                                               "TRANSPORT",
1159                                               "NEIGHBOUR_LIMIT",
1160                                               &tneigh)) ||
1161       (GNUNET_OK !=
1162        GNUNET_CONFIGURATION_get_value_filename (c,
1163                                                 "GNUNETD",
1164                                                 "HOSTKEY", &keyfile)))
1165     {
1166       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1167                   _
1168                   ("Transport service is lacking key configuration settings.  Exiting.\n"));
1169       GNUNET_SCHEDULER_shutdown (s);
1170       fail = 1;
1171       return;
1172     }
1173
1174   if ((GNUNET_OK !=
1175       GNUNET_CONFIGURATION_get_value_number (cfg,
1176                                              "transport-https",
1177                                              "PORT",
1178                                              &port)) ||
1179      (port > 65535) || (port == 0))
1180   {
1181     GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
1182                      "https",
1183                      _
1184                      ("Require valid port number for transport plugin `%s' in configuration!\n"),
1185                      "transport-http");
1186   }
1187
1188   max_connect_per_transport = (uint32_t) tneigh;
1189   my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
1190   GNUNET_free (keyfile);
1191   if (my_private_key == NULL)
1192     {
1193       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1194                   _("Transport service could not access hostkey.  Exiting.\n"));
1195       GNUNET_SCHEDULER_shutdown (s);
1196       fail = 1;
1197       return;
1198     }
1199
1200   GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
1201   GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key), &my_identity.hashPubKey);
1202
1203   /* assertions before start */
1204   GNUNET_assert ((port > 0) && (port <= 65535));
1205   GNUNET_assert(&my_public_key != NULL);
1206   GNUNET_assert(&my_identity.hashPubKey != NULL);
1207
1208   /* load plugins... */
1209   setup_plugin_environment ();
1210   GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading HTTPS transport plugin `%s'\n"),"libgnunet_plugin_transport_http");
1211   GNUNET_asprintf (&libname, "libgnunet_plugin_transport_https");
1212   api = GNUNET_PLUGIN_load (libname, &env);
1213   GNUNET_free (libname);
1214   if (api == NULL)
1215   {
1216     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1217                 _("Failed to load transport plugin for https\n"));
1218     fail = 1;
1219     return;
1220   }
1221
1222   ti_timeout = GNUNET_SCHEDULER_add_delayed (sched, TEST_TIMEOUT, &task_timeout, NULL);
1223
1224   /* testing plugin functionality */
1225   GNUNET_assert (0!=fail_notify_address_count);
1226   GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Transport plugin returned %u addresses to connect to\n"),  fail_notify_address_count);
1227
1228   /* testing pretty printer with all addresses obtained from the plugin*/
1229   cur = addr_head;
1230   while (cur != NULL)
1231   {
1232
1233     api->address_pretty_printer (api->cls, "http",cur->addr,cur->addrlen, GNUNET_NO,TEST_TIMEOUT, &pretty_printer_cb,NULL);
1234     addr_str = api->address_to_string (api->cls, cur->addr, cur->addrlen);
1235     suggest_res = api->check_address (api->cls, cur->addr, cur->addrlen);
1236
1237     GNUNET_assert (GNUNET_OK == suggest_res);
1238     GNUNET_assert (NULL != addr_str);
1239     count_str_addr++;
1240     GNUNET_free ( (char *) addr_str);
1241     cur = cur->next;
1242   }
1243   GNUNET_assert (fail_pretty_printer_count > 0);
1244   GNUNET_assert (fail_pretty_printer_count==fail_notify_address_count);
1245   GNUNET_assert (fail_pretty_printer_count==count_str_addr);
1246   fail_pretty_printer=GNUNET_NO;
1247   fail_addr_to_str=GNUNET_NO;
1248
1249   /* Suggesting addresses with wrong port*/
1250   struct IPv4HttpAddress failing_addr;
1251   failing_addr.ipv4_addr = htonl(INADDR_LOOPBACK);
1252   failing_addr.u_port = htons(0);
1253   suggest_res = api->check_address (api->cls,&failing_addr,sizeof (struct IPv4HttpAddress));
1254   GNUNET_assert (GNUNET_SYSERR == suggest_res);
1255
1256   /* Suggesting addresses with wrong size*/
1257   failing_addr.ipv4_addr = htonl(INADDR_LOOPBACK);
1258   failing_addr.u_port = htons(0);
1259   suggest_res = api->check_address (api->cls,&failing_addr,sizeof (struct IPv6HttpAddress));
1260   GNUNET_assert (GNUNET_SYSERR == suggest_res);
1261
1262   /* Suggesting addresses with wrong address*/
1263   failing_addr.ipv4_addr = htonl(0xffc00000);
1264   failing_addr.u_port = htons(12389);
1265   suggest_res = api->check_address (api->cls,&failing_addr,100);
1266   GNUNET_assert (GNUNET_SYSERR == suggest_res);
1267
1268   /* test sending to client */
1269   multi_handle = curl_multi_init();
1270
1271   /* Setting up buffers */
1272   buffer_in.size = HTTP_BUFFER_SIZE;
1273   buffer_in.pos = 0;
1274   buffer_in.len = 0;
1275
1276   buffer_out.size = HTTP_BUFFER_SIZE;
1277   buffer_out.pos = 0;
1278   buffer_out.len = 0;
1279
1280   /* Setting up connection tests */
1281
1282   /* Test: connecting without a peer identification */
1283   test_no_ident.test_executed = GNUNET_NO;
1284   test_no_ident.test_failed = GNUNET_YES;
1285
1286   /* Test: connecting with too short peer identification */
1287   test_too_short_ident.test_executed = GNUNET_NO;
1288   test_too_short_ident.test_failed = GNUNET_YES;
1289
1290   /* Test: connecting with too long peer identification */
1291   test_too_long_ident.test_executed = GNUNET_NO;
1292   test_too_long_ident.test_failed = GNUNET_YES;
1293
1294   /* Test: connecting with valid identification */
1295   test_valid_ident.test_executed = GNUNET_NO;
1296   test_valid_ident.test_failed = GNUNET_YES;
1297
1298   test_addr = (char *) api->address_to_string (api->cls,addr_head->addr,addr_head->addrlen);
1299
1300   GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("\nPhase 0\n\n"));
1301   run_connection_tests(0, NULL);
1302
1303   /* testing finished */
1304
1305   return;
1306 }
1307
1308
1309 /**
1310  * The main function for the transport service.
1311  *
1312  * @param argc number of arguments from the command line
1313  * @param argv command line arguments
1314  * @return 0 ok, 1 on error
1315  */
1316 int
1317 main (int argc, char *const *argv)
1318 {
1319
1320   static struct GNUNET_GETOPT_CommandLineOption options[] = {
1321     GNUNET_GETOPT_OPTION_END
1322   };
1323   int ret;
1324   char *const argv_prog[] = {
1325     "test_plugin_transport_https",
1326     "-c",
1327     "test_plugin_transport_data_http.conf",
1328     "-L",
1329 #if VERBOSE
1330     "DEBUG",
1331 #else
1332     "WARNING",
1333 #endif
1334     NULL
1335   };
1336   GNUNET_log_setup ("test_plugin_transport_https",
1337 #if VERBOSE
1338                     "DEBUG",
1339 #else
1340                     "WARNING",
1341 #endif
1342                     NULL);
1343
1344   ret = (GNUNET_OK ==
1345          GNUNET_PROGRAM_run (5,
1346                              argv_prog,
1347                              "test_plugin_transport_https",
1348                              "testcase", options, &run, NULL)) ? GNUNET_NO : GNUNET_YES;
1349
1350     GNUNET_DISK_directory_remove ("/tmp/test_plugin_transport_https");
1351
1352   return fail;
1353 }
1354
1355 /* end of test_plugin_transport_http.c */