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