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