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