diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-11-22 20:07:46 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-11-22 20:07:46 +0000 |
commit | 3a628a8b12195e3d15dce032d2e11110a6bb71a0 (patch) | |
tree | e04c545488b6e191f739b5bec4e1b6cc5db70e27 | |
parent | dc82ebded4c48483815fd73d4e33750b73fed496 (diff) | |
download | gnunet-3a628a8b12195e3d15dce032d2e11110a6bb71a0.tar.gz gnunet-3a628a8b12195e3d15dce032d2e11110a6bb71a0.zip |
adding TCP STEALTH support to HTTP client (without integrity protection)
-rw-r--r-- | src/transport/plugin_transport_http.h | 140 | ||||
-rw-r--r-- | src/transport/plugin_transport_http_client.c | 449 | ||||
-rw-r--r-- | src/transport/plugin_transport_http_common.h | 10 |
3 files changed, 408 insertions, 191 deletions
diff --git a/src/transport/plugin_transport_http.h b/src/transport/plugin_transport_http.h index ae0c784ee..d43eb9bab 100644 --- a/src/transport/plugin_transport_http.h +++ b/src/transport/plugin_transport_http.h | |||
@@ -69,21 +69,18 @@ | |||
69 | struct Plugin | 69 | struct Plugin |
70 | { | 70 | { |
71 | /** | 71 | /** |
72 | * General handles | ||
73 | * --------------- | ||
74 | */ | ||
75 | |||
76 | /** | ||
77 | * Our environment. | 72 | * Our environment. |
78 | */ | 73 | */ |
79 | struct GNUNET_TRANSPORT_PluginEnvironment *env; | 74 | struct GNUNET_TRANSPORT_PluginEnvironment *env; |
80 | 75 | ||
81 | /** | 76 | /** |
82 | * Linked list of open sessions. | 77 | * Head of linked list of open sessions. |
83 | */ | 78 | */ |
84 | |||
85 | struct Session *head; | 79 | struct Session *head; |
86 | 80 | ||
81 | /** | ||
82 | * Tail of linked list of open sessions. | ||
83 | */ | ||
87 | struct Session *tail; | 84 | struct Session *tail; |
88 | 85 | ||
89 | /** | 86 | /** |
@@ -92,25 +89,15 @@ struct Plugin | |||
92 | struct GNUNET_NAT_Handle *nat; | 89 | struct GNUNET_NAT_Handle *nat; |
93 | 90 | ||
94 | /** | 91 | /** |
95 | * List of own addresses | 92 | * Our own IPv4 addresses DLL head |
96 | */ | ||
97 | |||
98 | /** | ||
99 | * IPv4 addresses DLL head | ||
100 | */ | 93 | */ |
101 | struct HttpAddressWrapper *addr_head; | 94 | struct HttpAddressWrapper *addr_head; |
102 | 95 | ||
103 | /** | 96 | /** |
104 | * IPv4 addresses DLL tail | 97 | * Our own IPv4 addresses DLL tail |
105 | */ | 98 | */ |
106 | struct HttpAddressWrapper *addr_tail; | 99 | struct HttpAddressWrapper *addr_tail; |
107 | 100 | ||
108 | |||
109 | /** | ||
110 | * Plugin configuration | ||
111 | * -------------------- | ||
112 | */ | ||
113 | |||
114 | /** | 101 | /** |
115 | * External hostname the plugin can be connected to, can be different to | 102 | * External hostname the plugin can be connected to, can be different to |
116 | * the host's FQDN, used e.g. for reverse proxying | 103 | * the host's FQDN, used e.g. for reverse proxying |
@@ -133,9 +120,8 @@ struct Plugin | |||
133 | */ | 120 | */ |
134 | GNUNET_SCHEDULER_TaskIdentifier notify_ext_task; | 121 | GNUNET_SCHEDULER_TaskIdentifier notify_ext_task; |
135 | 122 | ||
136 | |||
137 | /** | 123 | /** |
138 | * Plugin name | 124 | * Plugin name. |
139 | * Equals configuration section: transport-http, transport-https | 125 | * Equals configuration section: transport-http, transport-https |
140 | */ | 126 | */ |
141 | char *name; | 127 | char *name; |
@@ -147,21 +133,18 @@ struct Plugin | |||
147 | char *protocol; | 133 | char *protocol; |
148 | 134 | ||
149 | /** | 135 | /** |
150 | * Use IPv4? | 136 | * Use IPv4? #GNUNET_YES or #GNUNET_NO |
151 | * GNUNET_YES or GNUNET_NO | ||
152 | */ | 137 | */ |
153 | int ipv4; | 138 | int ipv4; |
154 | 139 | ||
155 | /** | 140 | /** |
156 | * Use IPv6? | 141 | * Use IPv6? #GNUNET_YES or #GNUNET_NO |
157 | * GNUNET_YES or GNUNET_NO | ||
158 | */ | 142 | */ |
159 | int ipv6; | 143 | int ipv6; |
160 | 144 | ||
161 | /** | 145 | /** |
162 | * Does plugin just use outbound connections and not accept inbound? | 146 | * Does plugin just use outbound connections and not accept inbound? |
163 | */ | 147 | */ |
164 | |||
165 | int client_only; | 148 | int client_only; |
166 | 149 | ||
167 | /** | 150 | /** |
@@ -186,18 +169,12 @@ struct Plugin | |||
186 | unsigned int inbound_sessions; | 169 | unsigned int inbound_sessions; |
187 | 170 | ||
188 | /** | 171 | /** |
189 | * Plugin HTTPS SSL/TLS options | ||
190 | * ---------------------------- | ||
191 | */ | ||
192 | |||
193 | /** | ||
194 | * libCurl TLS crypto init string, can be set to enhance performance | 172 | * libCurl TLS crypto init string, can be set to enhance performance |
195 | * | 173 | * |
196 | * Example: | 174 | * Example: |
197 | * | 175 | * |
198 | * Use RC4-128 instead of AES: | 176 | * Use RC4-128 instead of AES: |
199 | * NONE:+VERS-TLS1.0:+ARCFOUR-128:+SHA1:+RSA:+COMP-NULL | 177 | * NONE:+VERS-TLS1.0:+ARCFOUR-128:+SHA1:+RSA:+COMP-NULL |
200 | * | ||
201 | */ | 178 | */ |
202 | char *crypto_init; | 179 | char *crypto_init; |
203 | 180 | ||
@@ -212,11 +189,6 @@ struct Plugin | |||
212 | char *cert; | 189 | char *cert; |
213 | 190 | ||
214 | /** | 191 | /** |
215 | * Plugin values | ||
216 | * ------------- | ||
217 | */ | ||
218 | |||
219 | /** | ||
220 | * Current number of establishes connections | 192 | * Current number of establishes connections |
221 | */ | 193 | */ |
222 | int cur_connections; | 194 | int cur_connections; |
@@ -227,11 +199,6 @@ struct Plugin | |||
227 | uint32_t last_tag; | 199 | uint32_t last_tag; |
228 | 200 | ||
229 | /** | 201 | /** |
230 | * Server handles | ||
231 | * -------------- | ||
232 | */ | ||
233 | |||
234 | /** | ||
235 | * MHD IPv4 daemon | 202 | * MHD IPv4 daemon |
236 | */ | 203 | */ |
237 | struct MHD_Daemon *server_v4; | 204 | struct MHD_Daemon *server_v4; |
@@ -259,7 +226,6 @@ struct Plugin | |||
259 | /** | 226 | /** |
260 | * The IPv6 server is scheduled to run asap | 227 | * The IPv6 server is scheduled to run asap |
261 | */ | 228 | */ |
262 | |||
263 | int server_v6_immediately; | 229 | int server_v6_immediately; |
264 | 230 | ||
265 | /** | 231 | /** |
@@ -273,17 +239,18 @@ struct Plugin | |||
273 | struct sockaddr_in6 *server_addr_v6; | 239 | struct sockaddr_in6 *server_addr_v6; |
274 | 240 | ||
275 | /** | 241 | /** |
276 | * Server semi connections | 242 | * Head of server semi connections |
277 | * A full session consists of 2 semi-connections: send and receive | 243 | * A full session consists of 2 semi-connections: send and receive |
278 | * If not both directions are established the server keeps this sessions here | 244 | * If not both directions are established the server keeps this sessions here |
279 | */ | 245 | */ |
280 | struct Session *server_semi_head; | 246 | struct Session *server_semi_head; |
281 | 247 | ||
282 | struct Session *server_semi_tail; | 248 | /** |
283 | 249 | * Tail of server semi connections | |
284 | /* | 250 | * A full session consists of 2 semi-connections: send and receive |
285 | * Client handles | 251 | * If not both directions are established the server keeps this sessions here |
286 | */ | 252 | */ |
253 | struct Session *server_semi_tail; | ||
287 | 254 | ||
288 | /** | 255 | /** |
289 | * cURL Multihandle | 256 | * cURL Multihandle |
@@ -351,21 +318,28 @@ GNUNET_NETWORK_STRUCT_END | |||
351 | 318 | ||
352 | struct ServerRequest | 319 | struct ServerRequest |
353 | { | 320 | { |
354 | /* _RECV or _SEND */ | 321 | /** |
322 | * _RECV or _SEND | ||
323 | */ | ||
355 | int direction; | 324 | int direction; |
356 | 325 | ||
357 | /* Should this connection get disconnected? GNUNET_YES/NO */ | 326 | /** |
327 | * Should this connection get disconnected? #GNUNET_YES / #GNUNET_NO | ||
328 | */ | ||
358 | int disconnect; | 329 | int disconnect; |
359 | 330 | ||
360 | /* The session this server connection belongs to */ | 331 | /** |
332 | * The session this server connection belongs to | ||
333 | */ | ||
361 | struct Session *session; | 334 | struct Session *session; |
362 | 335 | ||
363 | /* The MHD connection */ | 336 | /** |
337 | * The MHD connection | ||
338 | */ | ||
364 | struct MHD_Connection *mhd_conn; | 339 | struct MHD_Connection *mhd_conn; |
365 | }; | 340 | }; |
366 | 341 | ||
367 | 342 | ||
368 | |||
369 | /** | 343 | /** |
370 | * Session handle for connections. | 344 | * Session handle for connections. |
371 | */ | 345 | */ |
@@ -416,7 +390,6 @@ struct Session | |||
416 | */ | 390 | */ |
417 | struct HTTP_Message *msg_tail; | 391 | struct HTTP_Message *msg_tail; |
418 | 392 | ||
419 | |||
420 | /** | 393 | /** |
421 | * Message stream tokenizer for incoming data | 394 | * Message stream tokenizer for incoming data |
422 | */ | 395 | */ |
@@ -430,8 +403,8 @@ struct Session | |||
430 | 403 | ||
431 | /** | 404 | /** |
432 | * Inbound or outbound connection | 405 | * Inbound or outbound connection |
433 | * Outbound: GNUNET_NO (client is used to send and receive) | 406 | * Outbound: #GNUNET_NO (client is used to send and receive) |
434 | * Inbound : GNUNET_YES (server is used to send and receive) | 407 | * Inbound : #GNUNET_YES (server is used to send and receive) |
435 | */ | 408 | */ |
436 | int inbound; | 409 | int inbound; |
437 | 410 | ||
@@ -441,10 +414,6 @@ struct Session | |||
441 | uint32_t tag; | 414 | uint32_t tag; |
442 | 415 | ||
443 | /** | 416 | /** |
444 | * Client handles | ||
445 | */ | ||
446 | |||
447 | /** | ||
448 | * Client send handle | 417 | * Client send handle |
449 | */ | 418 | */ |
450 | void *client_put; | 419 | void *client_put; |
@@ -466,15 +435,11 @@ struct Session | |||
466 | 435 | ||
467 | /** | 436 | /** |
468 | * Is client send handle paused since there are no data to send? | 437 | * Is client send handle paused since there are no data to send? |
469 | * GNUNET_YES/NO | 438 | * #GNUNET_YES or #GNUNET_NO |
470 | */ | 439 | */ |
471 | int client_put_paused; | 440 | int client_put_paused; |
472 | 441 | ||
473 | /** | 442 | /** |
474 | * Server handles | ||
475 | */ | ||
476 | |||
477 | /** | ||
478 | * Client send handle | 443 | * Client send handle |
479 | */ | 444 | */ |
480 | struct ServerRequest *server_recv; | 445 | struct ServerRequest *server_recv; |
@@ -485,6 +450,7 @@ struct Session | |||
485 | struct ServerRequest *server_send; | 450 | struct ServerRequest *server_send; |
486 | }; | 451 | }; |
487 | 452 | ||
453 | |||
488 | /** | 454 | /** |
489 | * Message to send using http | 455 | * Message to send using http |
490 | */ | 456 | */ |
@@ -523,64 +489,90 @@ struct HTTP_Message | |||
523 | GNUNET_TRANSPORT_TransmitContinuation transmit_cont; | 489 | GNUNET_TRANSPORT_TransmitContinuation transmit_cont; |
524 | 490 | ||
525 | /** | 491 | /** |
526 | * Closure for transmit_cont. | 492 | * Closure for @e transmit_cont. |
527 | */ | 493 | */ |
528 | void *transmit_cont_cls; | 494 | void *transmit_cont_cls; |
529 | }; | 495 | }; |
530 | 496 | ||
497 | |||
531 | struct Session * | 498 | struct Session * |
532 | create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, | 499 | create_session (struct Plugin *plugin, |
533 | const void *addr, size_t addrlen); | 500 | const struct GNUNET_PeerIdentity *target, |
501 | const void *addr, | ||
502 | size_t addrlen); | ||
503 | |||
534 | 504 | ||
535 | int | 505 | int |
536 | exist_session (struct Plugin *plugin, struct Session *s); | 506 | exist_session (struct Plugin *plugin, |
507 | struct Session *s); | ||
508 | |||
537 | 509 | ||
538 | void | 510 | void |
539 | delete_session (struct Session *s); | 511 | delete_session (struct Session *s); |
540 | 512 | ||
513 | |||
541 | int | 514 | int |
542 | exist_session (struct Plugin *plugin, struct Session *s); | 515 | exist_session (struct Plugin *plugin, |
516 | struct Session *s); | ||
517 | |||
543 | 518 | ||
544 | struct GNUNET_TIME_Relative | 519 | struct GNUNET_TIME_Relative |
545 | http_plugin_receive (void *cls, const struct GNUNET_PeerIdentity *peer, | 520 | http_plugin_receive (void *cls, |
521 | const struct GNUNET_PeerIdentity *peer, | ||
546 | const struct GNUNET_MessageHeader *message, | 522 | const struct GNUNET_MessageHeader *message, |
547 | struct Session *session, const char *sender_address, | 523 | struct Session *session, |
524 | const char *sender_address, | ||
548 | uint16_t sender_address_len); | 525 | uint16_t sender_address_len); |
549 | 526 | ||
527 | |||
550 | const char * | 528 | const char * |
551 | http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen); | 529 | http_plugin_address_to_string (void *cls, |
530 | const void *addr, | ||
531 | size_t addrlen); | ||
532 | |||
552 | 533 | ||
553 | int | 534 | int |
554 | client_disconnect (struct Session *s); | 535 | client_disconnect (struct Session *s); |
555 | 536 | ||
537 | |||
556 | int | 538 | int |
557 | client_connect (struct Session *s); | 539 | client_connect (struct Session *s); |
558 | 540 | ||
541 | |||
559 | int | 542 | int |
560 | client_send (struct Session *s, struct HTTP_Message *msg); | 543 | client_send (struct Session *s, struct HTTP_Message *msg); |
561 | 544 | ||
545 | |||
562 | int | 546 | int |
563 | client_start (struct Plugin *plugin); | 547 | client_start (struct Plugin *plugin); |
564 | 548 | ||
549 | |||
565 | void | 550 | void |
566 | client_stop (struct Plugin *plugin); | 551 | client_stop (struct Plugin *plugin); |
567 | 552 | ||
553 | |||
568 | int | 554 | int |
569 | server_disconnect (struct Session *s); | 555 | server_disconnect (struct Session *s); |
570 | 556 | ||
557 | |||
571 | int | 558 | int |
572 | server_send (struct Session *s, struct HTTP_Message *msg); | 559 | server_send (struct Session *s, struct HTTP_Message *msg); |
573 | 560 | ||
561 | |||
574 | int | 562 | int |
575 | server_start (struct Plugin *plugin); | 563 | server_start (struct Plugin *plugin); |
576 | 564 | ||
565 | |||
577 | void | 566 | void |
578 | server_stop (struct Plugin *plugin); | 567 | server_stop (struct Plugin *plugin); |
579 | 568 | ||
569 | |||
580 | void | 570 | void |
581 | notify_session_end (void *cls, const struct GNUNET_PeerIdentity *peer, | 571 | notify_session_end (void *cls, |
572 | const struct GNUNET_PeerIdentity *peer, | ||
582 | struct Session *s); | 573 | struct Session *s); |
583 | 574 | ||
575 | |||
584 | /*#ifndef PLUGIN_TRANSPORT_HTTP_H*/ | 576 | /*#ifndef PLUGIN_TRANSPORT_HTTP_H*/ |
585 | #endif | 577 | #endif |
586 | /* end of plugin_transport_http.h */ | 578 | /* end of plugin_transport_http.h */ |
diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c index adb83c719..971e581fd 100644 --- a/src/transport/plugin_transport_http_client.c +++ b/src/transport/plugin_transport_http_client.c | |||
@@ -384,6 +384,7 @@ struct HTTP_Client_Plugin | |||
384 | int emulate_xhr; | 384 | int emulate_xhr; |
385 | }; | 385 | }; |
386 | 386 | ||
387 | |||
387 | /** | 388 | /** |
388 | * Disconnect a session | 389 | * Disconnect a session |
389 | * | 390 | * |
@@ -394,6 +395,7 @@ struct HTTP_Client_Plugin | |||
394 | static int | 395 | static int |
395 | http_client_plugin_session_disconnect (void *cls, struct Session *s); | 396 | http_client_plugin_session_disconnect (void *cls, struct Session *s); |
396 | 397 | ||
398 | |||
397 | /** | 399 | /** |
398 | * If a session monitor is attached, notify it about the new | 400 | * If a session monitor is attached, notify it about the new |
399 | * session state. | 401 | * session state. |
@@ -589,20 +591,23 @@ client_schedule (struct HTTP_Client_Plugin *plugin, | |||
589 | mret = curl_multi_fdset (plugin->curl_multi_handle, &rs, &ws, &es, &max); | 591 | mret = curl_multi_fdset (plugin->curl_multi_handle, &rs, &ws, &es, &max); |
590 | if (mret != CURLM_OK) | 592 | if (mret != CURLM_OK) |
591 | { | 593 | { |
592 | LOG (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), | 594 | LOG (GNUNET_ERROR_TYPE_ERROR, |
593 | "curl_multi_fdset", __FILE__, __LINE__, | 595 | _("%s failed at %s:%d: `%s'\n"), |
594 | curl_multi_strerror (mret)); | 596 | "curl_multi_fdset", |
597 | __FILE__, | ||
598 | __LINE__, | ||
599 | curl_multi_strerror (mret)); | ||
595 | return GNUNET_SYSERR; | 600 | return GNUNET_SYSERR; |
596 | } | 601 | } |
597 | mret = curl_multi_timeout (plugin->curl_multi_handle, &to); | 602 | mret = curl_multi_timeout (plugin->curl_multi_handle, &to); |
598 | if (to == -1) | 603 | if (-1 == to) |
599 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1); | 604 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1); |
600 | else | 605 | else |
601 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to); | 606 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to); |
602 | if (now == GNUNET_YES) | 607 | if (now == GNUNET_YES) |
603 | timeout = GNUNET_TIME_UNIT_MILLISECONDS; | 608 | timeout = GNUNET_TIME_UNIT_MILLISECONDS; |
604 | 609 | ||
605 | if (mret != CURLM_OK) | 610 | if (CURLM_OK != mret) |
606 | { | 611 | { |
607 | LOG (GNUNET_ERROR_TYPE_ERROR, | 612 | LOG (GNUNET_ERROR_TYPE_ERROR, |
608 | _("%s failed at %s:%d: `%s'\n"), | 613 | _("%s failed at %s:%d: `%s'\n"), |
@@ -626,6 +631,7 @@ client_schedule (struct HTTP_Client_Plugin *plugin, | |||
626 | return GNUNET_OK; | 631 | return GNUNET_OK; |
627 | } | 632 | } |
628 | 633 | ||
634 | |||
629 | #if VERBOSE_CURL | 635 | #if VERBOSE_CURL |
630 | /** | 636 | /** |
631 | * Loggging function | 637 | * Loggging function |
@@ -648,7 +654,9 @@ client_log (CURL *curl, | |||
648 | const char *ttype = "UNSPECIFIED"; | 654 | const char *ttype = "UNSPECIFIED"; |
649 | char text[size + 2]; | 655 | char text[size + 2]; |
650 | 656 | ||
651 | if (! ((type == CURLINFO_TEXT) || (type == CURLINFO_HEADER_IN) || (type == CURLINFO_HEADER_OUT))) | 657 | if (! ((CURLINFO_TEXT == type) || |
658 | (CURLINFO_HEADER_IN == type) || | ||
659 | (CURLINFO_HEADER_OUT == type))) | ||
652 | return 0; | 660 | return 0; |
653 | switch (type) | 661 | switch (type) |
654 | { | 662 | { |
@@ -731,7 +739,7 @@ client_connect_put (struct Session *s); | |||
731 | * been transmitted (or if the transport is ready | 739 | * been transmitted (or if the transport is ready |
732 | * for the next transmission call; or if the | 740 | * for the next transmission call; or if the |
733 | * peer disconnected...); can be NULL | 741 | * peer disconnected...); can be NULL |
734 | * @param cont_cls closure for cont | 742 | * @param cont_cls closure for @a cont |
735 | * @return number of bytes used (on the physical network, with overheads); | 743 | * @return number of bytes used (on the physical network, with overheads); |
736 | * -1 on hard errors (i.e. address invalid); 0 is a legal value | 744 | * -1 on hard errors (i.e. address invalid); 0 is a legal value |
737 | * and does NOT mean that the message was not transmitted (DV) | 745 | * and does NOT mean that the message was not transmitted (DV) |
@@ -752,18 +760,20 @@ http_client_plugin_send (void *cls, | |||
752 | 760 | ||
753 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 761 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
754 | "Session %p/request %p: Sending message with %u to peer `%s' \n", | 762 | "Session %p/request %p: Sending message with %u to peer `%s' \n", |
755 | s, s->put.easyhandle, | 763 | s, |
756 | msgbuf_size, GNUNET_i2s (&s->address->peer)); | 764 | s->put.easyhandle, |
765 | msgbuf_size, | ||
766 | GNUNET_i2s (&s->address->peer)); | ||
757 | 767 | ||
758 | /* create new message and schedule */ | 768 | /* create new message and schedule */ |
759 | msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); | 769 | msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); |
760 | msg->next = NULL; | ||
761 | msg->size = msgbuf_size; | 770 | msg->size = msgbuf_size; |
762 | msg->pos = 0; | ||
763 | msg->buf = (char *) &msg[1]; | 771 | msg->buf = (char *) &msg[1]; |
764 | msg->transmit_cont = cont; | 772 | msg->transmit_cont = cont; |
765 | msg->transmit_cont_cls = cont_cls; | 773 | msg->transmit_cont_cls = cont_cls; |
766 | memcpy (msg->buf, msgbuf, msgbuf_size); | 774 | memcpy (msg->buf, |
775 | msgbuf, | ||
776 | msgbuf_size); | ||
767 | GNUNET_CONTAINER_DLL_insert_tail (s->msg_head, | 777 | GNUNET_CONTAINER_DLL_insert_tail (s->msg_head, |
768 | s->msg_tail, | 778 | s->msg_tail, |
769 | msg); | 779 | msg); |
@@ -833,8 +843,11 @@ http_client_plugin_session_disconnect (void *cls, | |||
833 | struct HTTP_Client_Plugin *plugin = cls; | 843 | struct HTTP_Client_Plugin *plugin = cls; |
834 | 844 | ||
835 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 845 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
836 | "Session %p: notifying transport about ending session\n",s); | 846 | "Session %p: notifying transport about ending session\n", |
837 | plugin->env->session_end (plugin->env->cls, s->address, s); | 847 | s); |
848 | plugin->env->session_end (plugin->env->cls, | ||
849 | s->address, | ||
850 | s); | ||
838 | client_delete_session (s); | 851 | client_delete_session (s); |
839 | 852 | ||
840 | /* Re-schedule since handles have changed */ | 853 | /* Re-schedule since handles have changed */ |
@@ -902,8 +915,10 @@ http_client_plugin_peer_disconnect (void *cls, | |||
902 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 915 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
903 | "Transport tells me to disconnect `%s'\n", | 916 | "Transport tells me to disconnect `%s'\n", |
904 | GNUNET_i2s (target)); | 917 | GNUNET_i2s (target)); |
905 | GNUNET_CONTAINER_multipeermap_get_multiple (plugin->sessions, target, | 918 | GNUNET_CONTAINER_multipeermap_get_multiple (plugin->sessions, |
906 | &destroy_session_cb, plugin); | 919 | target, |
920 | &destroy_session_cb, | ||
921 | plugin); | ||
907 | } | 922 | } |
908 | 923 | ||
909 | 924 | ||
@@ -992,7 +1007,8 @@ client_put_disconnect (void *cls, | |||
992 | s, s->put.easyhandle); | 1007 | s, s->put.easyhandle); |
993 | s->put.state = H_TMP_DISCONNECTING; | 1008 | s->put.state = H_TMP_DISCONNECTING; |
994 | if (NULL != s->put.easyhandle) | 1009 | if (NULL != s->put.easyhandle) |
995 | curl_easy_pause (s->put.easyhandle, CURLPAUSE_CONT); | 1010 | curl_easy_pause (s->put.easyhandle, |
1011 | CURLPAUSE_CONT); | ||
996 | client_schedule (s->plugin, GNUNET_YES); | 1012 | client_schedule (s->plugin, GNUNET_YES); |
997 | } | 1013 | } |
998 | 1014 | ||
@@ -1033,7 +1049,8 @@ client_send_cb (void *stream, | |||
1033 | { | 1049 | { |
1034 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1050 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1035 | "Session %p/request %p: PUT request finished\n", | 1051 | "Session %p/request %p: PUT request finished\n", |
1036 | s, s->put.easyhandle); | 1052 | s, |
1053 | s->put.easyhandle); | ||
1037 | s->put.state = H_TMP_DISCONNECTING; | 1054 | s->put.state = H_TMP_DISCONNECTING; |
1038 | return 0; | 1055 | return 0; |
1039 | } | 1056 | } |
@@ -1041,7 +1058,8 @@ client_send_cb (void *stream, | |||
1041 | /* We have nothing to send, so pause PUT request */ | 1058 | /* We have nothing to send, so pause PUT request */ |
1042 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1059 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1043 | "Session %p/request %p: nothing to send, suspending\n", | 1060 | "Session %p/request %p: nothing to send, suspending\n", |
1044 | s, s->put.easyhandle); | 1061 | s, |
1062 | s->put.easyhandle); | ||
1045 | s->put_disconnect_task = GNUNET_SCHEDULER_add_delayed (PUT_DISCONNECT_TIMEOUT, | 1063 | s->put_disconnect_task = GNUNET_SCHEDULER_add_delayed (PUT_DISCONNECT_TIMEOUT, |
1046 | &client_put_disconnect, s); | 1064 | &client_put_disconnect, s); |
1047 | s->put.state = H_PAUSED; | 1065 | s->put.state = H_PAUSED; |
@@ -1058,7 +1076,10 @@ client_send_cb (void *stream, | |||
1058 | { | 1076 | { |
1059 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1077 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1060 | "Session %p/request %p: sent message with %u bytes sent, removing message from queue\n", | 1078 | "Session %p/request %p: sent message with %u bytes sent, removing message from queue\n", |
1061 | s, s->put.easyhandle, msg->size, msg->pos); | 1079 | s, |
1080 | s->put.easyhandle, | ||
1081 | msg->size, | ||
1082 | msg->pos); | ||
1062 | /* Calling transmit continuation */ | 1083 | /* Calling transmit continuation */ |
1063 | GNUNET_CONTAINER_DLL_remove (s->msg_head, | 1084 | GNUNET_CONTAINER_DLL_remove (s->msg_head, |
1064 | s->msg_tail, | 1085 | s->msg_tail, |
@@ -1161,7 +1182,8 @@ client_receive_mst_cb (void *cls, | |||
1161 | s, | 1182 | s, |
1162 | message); | 1183 | message); |
1163 | plugin->env->update_address_metrics (plugin->env->cls, | 1184 | plugin->env->update_address_metrics (plugin->env->cls, |
1164 | s->address, s, | 1185 | s->address, |
1186 | s, | ||
1165 | &atsi, 1); | 1187 | &atsi, 1); |
1166 | 1188 | ||
1167 | GNUNET_asprintf (&stat_txt, | 1189 | GNUNET_asprintf (&stat_txt, |
@@ -1232,8 +1254,10 @@ client_receive (void *stream, | |||
1232 | 1254 | ||
1233 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1255 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1234 | "Session %p / request %p: Received %u bytes from peer `%s'\n", | 1256 | "Session %p / request %p: Received %u bytes from peer `%s'\n", |
1235 | s, s->get.easyhandle, | 1257 | s, |
1236 | len, GNUNET_i2s (&s->address->peer)); | 1258 | s->get.easyhandle, |
1259 | len, | ||
1260 | GNUNET_i2s (&s->address->peer)); | ||
1237 | now = GNUNET_TIME_absolute_get (); | 1261 | now = GNUNET_TIME_absolute_get (); |
1238 | if (now.abs_value_us < s->next_receive.abs_value_us) | 1262 | if (now.abs_value_us < s->next_receive.abs_value_us) |
1239 | { | 1263 | { |
@@ -1428,6 +1452,52 @@ client_run (void *cls, | |||
1428 | } | 1452 | } |
1429 | 1453 | ||
1430 | 1454 | ||
1455 | #ifdef SO_TCPSTEALTH | ||
1456 | /** | ||
1457 | * Open TCP socket with TCP STEALTH enabled. | ||
1458 | */ | ||
1459 | static curl_socket_t | ||
1460 | open_tcp_stealth_socket_cb (void *clientp, | ||
1461 | curlsocktype purpose, | ||
1462 | struct curl_sockaddr *address) | ||
1463 | { | ||
1464 | struct Session *s = clientp; | ||
1465 | int ret; | ||
1466 | |||
1467 | switch (purpose) | ||
1468 | { | ||
1469 | case CURLSOCKTYPE_IPCXN: | ||
1470 | ret = socket (address->family, | ||
1471 | address->socktype, | ||
1472 | address->protocol); | ||
1473 | if (-1 == ret) | ||
1474 | return CURL_SOCKET_BAD; | ||
1475 | if ( ( (SOCK_STREAM != address->socktype) || | ||
1476 | ( (0 != address->protocol) && | ||
1477 | (IPPROTO_TCP != address->protocol))) ) | ||
1478 | return (curl_socket_t) ret; | ||
1479 | if ( (0 != setsockopt (ret, | ||
1480 | IPPROTO_TCP, | ||
1481 | SO_TCPSTEALTH, | ||
1482 | &s->target, | ||
1483 | sizeof (struct GNUNET_PeerIdentity))) ) | ||
1484 | { | ||
1485 | (void) close (ret); | ||
1486 | return CURL_SOCKET_BAD; | ||
1487 | } | ||
1488 | return (curl_socket_t) ret; | ||
1489 | case CURLSOCKTYPE_ACCEPT: | ||
1490 | GNUNET_break (0); | ||
1491 | return CURL_SOCKET_BAD; | ||
1492 | break; | ||
1493 | case CURLSOCKTYPE_LAST: | ||
1494 | GNUNET_break (0); | ||
1495 | return CURL_SOCKET_BAD; | ||
1496 | } | ||
1497 | } | ||
1498 | #endif | ||
1499 | |||
1500 | |||
1431 | /** | 1501 | /** |
1432 | * Connect GET request for a session | 1502 | * Connect GET request for a session |
1433 | * | 1503 | * |
@@ -1438,82 +1508,152 @@ static int | |||
1438 | client_connect_get (struct Session *s) | 1508 | client_connect_get (struct Session *s) |
1439 | { | 1509 | { |
1440 | CURLMcode mret; | 1510 | CURLMcode mret; |
1511 | struct HttpAddress *ha; | ||
1512 | uint32_t options; | ||
1441 | 1513 | ||
1514 | ha = (struct HttpAddress *) s->address->address; | ||
1515 | options = ntohl (ha->options); | ||
1442 | /* create get request */ | 1516 | /* create get request */ |
1443 | s->get.easyhandle = curl_easy_init (); | 1517 | s->get.easyhandle = curl_easy_init (); |
1444 | s->get.s = s; | 1518 | s->get.s = s; |
1519 | if (0 != (options & HTTP_OPTIONS_TCP_STEALTH)) | ||
1520 | { | ||
1521 | #ifdef SO_TCPSTEALTH | ||
1522 | curl_easy_setopt (s->get.easyhandle, | ||
1523 | CURLOPT_OPENSOCKETFUNCTION, | ||
1524 | &open_tcp_stealth_socket_cb); | ||
1525 | curl_easy_setopt (s->get.easyhandle, | ||
1526 | CURLOPT_OPENSOCKETDATA, | ||
1527 | s); | ||
1528 | #else | ||
1529 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1530 | "Cannot connect, TCP STEALTH needed and not supported by kernel.\n"); | ||
1531 | curl_easy_cleanup (s->get.easyhandle); | ||
1532 | s->get.easyhandle = NULL; | ||
1533 | s->get.s = NULL; | ||
1534 | return GNUNET_SYSERR; | ||
1535 | #endif | ||
1536 | } | ||
1537 | |||
1445 | #if VERBOSE_CURL | 1538 | #if VERBOSE_CURL |
1446 | curl_easy_setopt (s->get.easyhandle, CURLOPT_VERBOSE, 1L); | 1539 | curl_easy_setopt (s->get.easyhandle, |
1447 | curl_easy_setopt (s->get.easyhandle, CURLOPT_DEBUGFUNCTION, &client_log); | 1540 | CURLOPT_VERBOSE, |
1448 | curl_easy_setopt (s->get.easyhandle, CURLOPT_DEBUGDATA, &s->get); | 1541 | 1L); |
1542 | curl_easy_setopt (s->get.easyhandle, | ||
1543 | CURLOPT_DEBUGFUNCTION, | ||
1544 | &client_log); | ||
1545 | curl_easy_setopt (s->get.easyhandle, | ||
1546 | CURLOPT_DEBUGDATA, | ||
1547 | &s->get); | ||
1449 | #endif | 1548 | #endif |
1450 | #if BUILD_HTTPS | 1549 | #if BUILD_HTTPS |
1451 | curl_easy_setopt (s->get.easyhandle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); | 1550 | curl_easy_setopt (s->get.easyhandle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); |
1452 | { | 1551 | { |
1453 | struct HttpAddress *ha; | ||
1454 | |||
1455 | ha = (struct HttpAddress *) s->address->address; | ||
1456 | |||
1457 | if (HTTP_OPTIONS_VERIFY_CERTIFICATE == | 1552 | if (HTTP_OPTIONS_VERIFY_CERTIFICATE == |
1458 | (ntohl (ha->options) & HTTP_OPTIONS_VERIFY_CERTIFICATE)) | 1553 | (options & HTTP_OPTIONS_VERIFY_CERTIFICATE)) |
1459 | { | 1554 | { |
1460 | curl_easy_setopt (s->get.easyhandle, CURLOPT_SSL_VERIFYPEER, 1L); | 1555 | curl_easy_setopt (s->get.easyhandle, |
1461 | curl_easy_setopt (s->get.easyhandle, CURLOPT_SSL_VERIFYHOST, 2L); | 1556 | CURLOPT_SSL_VERIFYPEER, 1L); |
1557 | curl_easy_setopt (s->get.easyhandle, | ||
1558 | CURLOPT_SSL_VERIFYHOST, | ||
1559 | 2L); | ||
1462 | } | 1560 | } |
1463 | else | 1561 | else |
1464 | { | 1562 | { |
1465 | curl_easy_setopt (s->get.easyhandle, CURLOPT_SSL_VERIFYPEER, 0); | 1563 | curl_easy_setopt (s->get.easyhandle, |
1466 | curl_easy_setopt (s->get.easyhandle, CURLOPT_SSL_VERIFYHOST, 0); | 1564 | CURLOPT_SSL_VERIFYPEER, |
1565 | 0L); | ||
1566 | curl_easy_setopt (s->get.easyhandle, | ||
1567 | CURLOPT_SSL_VERIFYHOST, | ||
1568 | 0L); | ||
1467 | } | 1569 | } |
1468 | } | 1570 | } |
1469 | curl_easy_setopt (s->get.easyhandle, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS); | 1571 | curl_easy_setopt (s->get.easyhandle, |
1470 | curl_easy_setopt (s->get.easyhandle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS); | 1572 | CURLOPT_PROTOCOLS, |
1573 | CURLPROTO_HTTPS); | ||
1574 | curl_easy_setopt (s->get.easyhandle, | ||
1575 | CURLOPT_REDIR_PROTOCOLS, | ||
1576 | CURLPROTO_HTTPS); | ||
1471 | #else | 1577 | #else |
1472 | curl_easy_setopt (s->get.easyhandle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP); | 1578 | curl_easy_setopt (s->get.easyhandle, |
1473 | curl_easy_setopt (s->get.easyhandle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP); | 1579 | CURLOPT_PROTOCOLS, |
1580 | CURLPROTO_HTTP); | ||
1581 | curl_easy_setopt (s->get.easyhandle, | ||
1582 | CURLOPT_REDIR_PROTOCOLS, | ||
1583 | CURLPROTO_HTTP); | ||
1474 | #endif | 1584 | #endif |
1475 | 1585 | ||
1476 | if (NULL != s->plugin->proxy_hostname) | 1586 | if (NULL != s->plugin->proxy_hostname) |
1477 | { | 1587 | { |
1478 | curl_easy_setopt (s->get.easyhandle, CURLOPT_PROXY, s->plugin->proxy_hostname); | 1588 | curl_easy_setopt (s->get.easyhandle, |
1479 | curl_easy_setopt (s->get.easyhandle, CURLOPT_PROXYTYPE, s->plugin->proxytype); | 1589 | CURLOPT_PROXY, |
1590 | s->plugin->proxy_hostname); | ||
1591 | curl_easy_setopt (s->get.easyhandle, | ||
1592 | CURLOPT_PROXYTYPE, | ||
1593 | s->plugin->proxytype); | ||
1480 | if (NULL != s->plugin->proxy_username) | 1594 | if (NULL != s->plugin->proxy_username) |
1481 | curl_easy_setopt (s->get.easyhandle, CURLOPT_PROXYUSERNAME, | 1595 | curl_easy_setopt (s->get.easyhandle, |
1482 | s->plugin->proxy_username); | 1596 | CURLOPT_PROXYUSERNAME, |
1597 | s->plugin->proxy_username); | ||
1483 | if (NULL != s->plugin->proxy_password) | 1598 | if (NULL != s->plugin->proxy_password) |
1484 | curl_easy_setopt (s->get.easyhandle, CURLOPT_PROXYPASSWORD, | 1599 | curl_easy_setopt (s->get.easyhandle, |
1485 | s->plugin->proxy_password); | 1600 | CURLOPT_PROXYPASSWORD, |
1601 | s->plugin->proxy_password); | ||
1486 | if (GNUNET_YES == s->plugin->proxy_use_httpproxytunnel) | 1602 | if (GNUNET_YES == s->plugin->proxy_use_httpproxytunnel) |
1487 | curl_easy_setopt (s->get.easyhandle, CURLOPT_HTTPPROXYTUNNEL, | 1603 | curl_easy_setopt (s->get.easyhandle, |
1488 | s->plugin->proxy_use_httpproxytunnel); | 1604 | CURLOPT_HTTPPROXYTUNNEL, |
1605 | s->plugin->proxy_use_httpproxytunnel); | ||
1489 | } | 1606 | } |
1490 | 1607 | ||
1491 | if (GNUNET_YES == s->plugin->emulate_xhr) | 1608 | if (GNUNET_YES == s->plugin->emulate_xhr) |
1492 | { | 1609 | { |
1493 | char *url; | 1610 | char *url; |
1494 | 1611 | ||
1495 | GNUNET_asprintf(&url, "%s,1", s->url); | 1612 | GNUNET_asprintf (&url, |
1496 | curl_easy_setopt (s->get.easyhandle, CURLOPT_URL, url); | 1613 | "%s,1", |
1614 | s->url); | ||
1615 | curl_easy_setopt (s->get.easyhandle, | ||
1616 | CURLOPT_URL, | ||
1617 | url); | ||
1497 | GNUNET_free(url); | 1618 | GNUNET_free(url); |
1498 | } else | 1619 | } |
1499 | curl_easy_setopt (s->get.easyhandle, CURLOPT_URL, s->url); | 1620 | else |
1500 | //curl_easy_setopt (s->get.easyhandle, CURLOPT_HEADERFUNCTION, &curl_get_header_cb); | 1621 | { |
1501 | //curl_easy_setopt (s->get.easyhandle, CURLOPT_WRITEHEADER, ps); | 1622 | curl_easy_setopt (s->get.easyhandle, |
1502 | curl_easy_setopt (s->get.easyhandle, CURLOPT_READFUNCTION, client_send_cb); | 1623 | CURLOPT_URL, |
1503 | curl_easy_setopt (s->get.easyhandle, CURLOPT_READDATA, s); | 1624 | s->url); |
1504 | curl_easy_setopt (s->get.easyhandle, CURLOPT_WRITEFUNCTION, client_receive); | 1625 | } |
1505 | curl_easy_setopt (s->get.easyhandle, CURLOPT_WRITEDATA, s); | 1626 | curl_easy_setopt (s->get.easyhandle, |
1627 | CURLOPT_READFUNCTION, | ||
1628 | &client_send_cb); | ||
1629 | curl_easy_setopt (s->get.easyhandle, | ||
1630 | CURLOPT_READDATA, | ||
1631 | s); | ||
1632 | curl_easy_setopt (s->get.easyhandle, | ||
1633 | CURLOPT_WRITEFUNCTION, | ||
1634 | &client_receive); | ||
1635 | curl_easy_setopt (s->get.easyhandle, | ||
1636 | CURLOPT_WRITEDATA, | ||
1637 | s); | ||
1506 | /* No timeout by default, timeout done with session timeout */ | 1638 | /* No timeout by default, timeout done with session timeout */ |
1507 | curl_easy_setopt (s->get.easyhandle, CURLOPT_TIMEOUT, 0); | 1639 | curl_easy_setopt (s->get.easyhandle, |
1508 | curl_easy_setopt (s->get.easyhandle, CURLOPT_PRIVATE, s); | 1640 | CURLOPT_TIMEOUT, |
1509 | curl_easy_setopt (s->get.easyhandle, CURLOPT_CONNECTTIMEOUT_MS, | 1641 | 0L); |
1642 | curl_easy_setopt (s->get.easyhandle, | ||
1643 | CURLOPT_PRIVATE, s); | ||
1644 | curl_easy_setopt (s->get.easyhandle, | ||
1645 | CURLOPT_CONNECTTIMEOUT_MS, | ||
1510 | (long) (HTTP_CLIENT_NOT_VALIDATED_TIMEOUT.rel_value_us / 1000LL)); | 1646 | (long) (HTTP_CLIENT_NOT_VALIDATED_TIMEOUT.rel_value_us / 1000LL)); |
1511 | curl_easy_setopt (s->get.easyhandle, CURLOPT_BUFFERSIZE, | 1647 | curl_easy_setopt (s->get.easyhandle, CURLOPT_BUFFERSIZE, |
1512 | 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE); | 1648 | 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE); |
1513 | #if CURL_TCP_NODELAY | 1649 | #if CURL_TCP_NODELAY |
1514 | curl_easy_setopt (ps->recv_endpoint, CURLOPT_TCP_NODELAY, 1); | 1650 | curl_easy_setopt (ps->recv_endpoint, |
1651 | CURLOPT_TCP_NODELAY, | ||
1652 | 1L); | ||
1515 | #endif | 1653 | #endif |
1516 | curl_easy_setopt (s->get.easyhandle, CURLOPT_FOLLOWLOCATION, 0); | 1654 | curl_easy_setopt (s->get.easyhandle, |
1655 | CURLOPT_FOLLOWLOCATION, | ||
1656 | 0L); | ||
1517 | 1657 | ||
1518 | mret = curl_multi_add_handle (s->plugin->curl_multi_handle, | 1658 | mret = curl_multi_add_handle (s->plugin->curl_multi_handle, |
1519 | s->get.easyhandle); | 1659 | s->get.easyhandle); |
@@ -1526,14 +1666,14 @@ client_connect_get (struct Session *s) | |||
1526 | curl_easy_cleanup (s->get.easyhandle); | 1666 | curl_easy_cleanup (s->get.easyhandle); |
1527 | s->get.easyhandle = NULL; | 1667 | s->get.easyhandle = NULL; |
1528 | s->get.s = NULL; | 1668 | s->get.s = NULL; |
1529 | s->get.easyhandle = NULL; | ||
1530 | GNUNET_break (0); | 1669 | GNUNET_break (0); |
1531 | return GNUNET_SYSERR; | 1670 | return GNUNET_SYSERR; |
1532 | } | 1671 | } |
1533 | s->plugin->cur_requests++; | 1672 | s->plugin->cur_requests++; |
1534 | LOG (GNUNET_ERROR_TYPE_INFO, | 1673 | LOG (GNUNET_ERROR_TYPE_INFO, |
1535 | "GET request `%s' established, number of requests increased to %u\n", | 1674 | "GET request `%s' established, number of requests increased to %u\n", |
1536 | s->url, s->plugin->cur_requests); | 1675 | s->url, |
1676 | s->plugin->cur_requests); | ||
1537 | return GNUNET_OK; | 1677 | return GNUNET_OK; |
1538 | } | 1678 | } |
1539 | 1679 | ||
@@ -1548,19 +1688,51 @@ static int | |||
1548 | client_connect_put (struct Session *s) | 1688 | client_connect_put (struct Session *s) |
1549 | { | 1689 | { |
1550 | CURLMcode mret; | 1690 | CURLMcode mret; |
1691 | struct HttpAddress *ha; | ||
1692 | uint32_t options; | ||
1551 | 1693 | ||
1694 | ha = (struct HttpAddress *) s->address->address; | ||
1695 | options = ntohl (ha->options); | ||
1552 | /* create put request */ | 1696 | /* create put request */ |
1553 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1697 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1554 | "Session %p: Init PUT handle\n", s); | 1698 | "Session %p: Init PUT handle\n", |
1699 | s); | ||
1555 | s->put.easyhandle = curl_easy_init (); | 1700 | s->put.easyhandle = curl_easy_init (); |
1556 | s->put.s = s; | 1701 | s->put.s = s; |
1557 | #if VERBOSE_CURL | 1702 | #if VERBOSE_CURL |
1558 | curl_easy_setopt (s->put.easyhandle, CURLOPT_VERBOSE, 1L); | 1703 | curl_easy_setopt (s->put.easyhandle, |
1559 | curl_easy_setopt (s->put.easyhandle, CURLOPT_DEBUGFUNCTION, &client_log); | 1704 | CURLOPT_VERBOSE, |
1560 | curl_easy_setopt (s->put.easyhandle, CURLOPT_DEBUGDATA, &s->put); | 1705 | 1L); |
1706 | curl_easy_setopt (s->put.easyhandle, | ||
1707 | CURLOPT_DEBUGFUNCTION, | ||
1708 | &client_log); | ||
1709 | curl_easy_setopt (s->put.easyhandle, | ||
1710 | CURLOPT_DEBUGDATA, | ||
1711 | &s->put); | ||
1561 | #endif | 1712 | #endif |
1713 | if (0 != (options & HTTP_OPTIONS_TCP_STEALTH)) | ||
1714 | { | ||
1715 | #ifdef SO_TCPSTEALTH | ||
1716 | curl_easy_setopt (s->put.easyhandle, | ||
1717 | CURLOPT_OPENSOCKETFUNCTION, | ||
1718 | &open_tcp_stealth_socket_cb); | ||
1719 | curl_easy_setopt (s->put.easyhandle, | ||
1720 | CURLOPT_OPENSOCKETDATA, | ||
1721 | s); | ||
1722 | #else | ||
1723 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1724 | "Cannot connect, TCP STEALTH needed and not supported by kernel.\n"); | ||
1725 | curl_easy_cleanup (s->put.easyhandle); | ||
1726 | s->put.easyhandle = NULL; | ||
1727 | s->put.s = NULL; | ||
1728 | s->put.state = H_DISCONNECTED; | ||
1729 | return GNUNET_SYSERR; | ||
1730 | #endif | ||
1731 | } | ||
1562 | #if BUILD_HTTPS | 1732 | #if BUILD_HTTPS |
1563 | curl_easy_setopt (s->put.easyhandle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); | 1733 | curl_easy_setopt (s->put.easyhandle, |
1734 | CURLOPT_SSLVERSION, | ||
1735 | CURL_SSLVERSION_TLSv1); | ||
1564 | { | 1736 | { |
1565 | struct HttpAddress *ha; | 1737 | struct HttpAddress *ha; |
1566 | ha = (struct HttpAddress *) s->address->address; | 1738 | ha = (struct HttpAddress *) s->address->address; |
@@ -1568,48 +1740,86 @@ client_connect_put (struct Session *s) | |||
1568 | if (HTTP_OPTIONS_VERIFY_CERTIFICATE == | 1740 | if (HTTP_OPTIONS_VERIFY_CERTIFICATE == |
1569 | (ntohl (ha->options) & HTTP_OPTIONS_VERIFY_CERTIFICATE)) | 1741 | (ntohl (ha->options) & HTTP_OPTIONS_VERIFY_CERTIFICATE)) |
1570 | { | 1742 | { |
1571 | curl_easy_setopt (s->put.easyhandle, CURLOPT_SSL_VERIFYPEER, 1L); | 1743 | curl_easy_setopt (s->put.easyhandle, |
1572 | curl_easy_setopt (s->put.easyhandle, CURLOPT_SSL_VERIFYHOST, 2L); | 1744 | CURLOPT_SSL_VERIFYPEER, |
1745 | 1L); | ||
1746 | curl_easy_setopt (s->put.easyhandle, | ||
1747 | CURLOPT_SSL_VERIFYHOST, | ||
1748 | 2L); | ||
1573 | } | 1749 | } |
1574 | else | 1750 | else |
1575 | { | 1751 | { |
1576 | curl_easy_setopt (s->put.easyhandle, CURLOPT_SSL_VERIFYPEER, 0); | 1752 | curl_easy_setopt (s->put.easyhandle, |
1577 | curl_easy_setopt (s->put.easyhandle, CURLOPT_SSL_VERIFYHOST, 0); | 1753 | CURLOPT_SSL_VERIFYPEER, |
1754 | 0L); | ||
1755 | curl_easy_setopt (s->put.easyhandle, | ||
1756 | CURLOPT_SSL_VERIFYHOST, | ||
1757 | 0L); | ||
1578 | } | 1758 | } |
1579 | } | 1759 | } |
1580 | curl_easy_setopt (s->put.easyhandle, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS); | 1760 | curl_easy_setopt (s->put.easyhandle, |
1581 | curl_easy_setopt (s->put.easyhandle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS); | 1761 | CURLOPT_PROTOCOLS, |
1762 | CURLPROTO_HTTPS); | ||
1763 | curl_easy_setopt (s->put.easyhandle, | ||
1764 | CURLOPT_REDIR_PROTOCOLS, | ||
1765 | CURLPROTO_HTTPS); | ||
1582 | #else | 1766 | #else |
1583 | curl_easy_setopt (s->put.easyhandle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP); | 1767 | curl_easy_setopt (s->put.easyhandle, |
1584 | curl_easy_setopt (s->put.easyhandle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP); | 1768 | CURLOPT_PROTOCOLS, |
1769 | CURLPROTO_HTTP); | ||
1770 | curl_easy_setopt (s->put.easyhandle, | ||
1771 | CURLOPT_REDIR_PROTOCOLS, | ||
1772 | CURLPROTO_HTTP); | ||
1585 | #endif | 1773 | #endif |
1586 | if (s->plugin->proxy_hostname != NULL) | 1774 | if (NULL != s->plugin->proxy_hostname) |
1587 | { | 1775 | { |
1588 | curl_easy_setopt (s->put.easyhandle, CURLOPT_PROXY, s->plugin->proxy_hostname); | 1776 | curl_easy_setopt (s->put.easyhandle, |
1589 | curl_easy_setopt (s->put.easyhandle, CURLOPT_PROXYTYPE, s->plugin->proxytype); | 1777 | CURLOPT_PROXY, |
1778 | s->plugin->proxy_hostname); | ||
1779 | curl_easy_setopt (s->put.easyhandle, | ||
1780 | CURLOPT_PROXYTYPE, | ||
1781 | s->plugin->proxytype); | ||
1590 | if (NULL != s->plugin->proxy_username) | 1782 | if (NULL != s->plugin->proxy_username) |
1591 | curl_easy_setopt (s->put.easyhandle, CURLOPT_PROXYUSERNAME, | 1783 | curl_easy_setopt (s->put.easyhandle, |
1592 | s->plugin->proxy_username); | 1784 | CURLOPT_PROXYUSERNAME, |
1785 | s->plugin->proxy_username); | ||
1593 | if (NULL != s->plugin->proxy_password) | 1786 | if (NULL != s->plugin->proxy_password) |
1594 | curl_easy_setopt (s->put.easyhandle, CURLOPT_PROXYPASSWORD, | 1787 | curl_easy_setopt (s->put.easyhandle, |
1595 | s->plugin->proxy_password); | 1788 | CURLOPT_PROXYPASSWORD, |
1789 | s->plugin->proxy_password); | ||
1596 | if (GNUNET_YES == s->plugin->proxy_use_httpproxytunnel) | 1790 | if (GNUNET_YES == s->plugin->proxy_use_httpproxytunnel) |
1597 | curl_easy_setopt (s->put.easyhandle, CURLOPT_HTTPPROXYTUNNEL, | 1791 | curl_easy_setopt (s->put.easyhandle, |
1598 | s->plugin->proxy_use_httpproxytunnel); | 1792 | CURLOPT_HTTPPROXYTUNNEL, |
1793 | s->plugin->proxy_use_httpproxytunnel); | ||
1599 | } | 1794 | } |
1600 | 1795 | ||
1601 | curl_easy_setopt (s->put.easyhandle, CURLOPT_URL, s->url); | 1796 | curl_easy_setopt (s->put.easyhandle, |
1602 | curl_easy_setopt (s->put.easyhandle, CURLOPT_UPLOAD, 1L); | 1797 | CURLOPT_URL, |
1603 | //curl_easy_setopt (s->put.easyhandle, CURLOPT_HEADERFUNCTION, &client_curl_header); | 1798 | s->url); |
1604 | //curl_easy_setopt (s->put.easyhandle, CURLOPT_WRITEHEADER, ps); | 1799 | curl_easy_setopt (s->put.easyhandle, |
1605 | curl_easy_setopt (s->put.easyhandle, CURLOPT_READFUNCTION, client_send_cb); | 1800 | CURLOPT_UPLOAD, |
1606 | curl_easy_setopt (s->put.easyhandle, CURLOPT_READDATA, s); | 1801 | 1L); |
1607 | curl_easy_setopt (s->put.easyhandle, CURLOPT_WRITEFUNCTION, client_receive_put); | 1802 | curl_easy_setopt (s->put.easyhandle, |
1608 | curl_easy_setopt (s->put.easyhandle, CURLOPT_WRITEDATA, s); | 1803 | CURLOPT_READFUNCTION, |
1804 | &client_send_cb); | ||
1805 | curl_easy_setopt (s->put.easyhandle, | ||
1806 | CURLOPT_READDATA, | ||
1807 | s); | ||
1808 | curl_easy_setopt (s->put.easyhandle, | ||
1809 | CURLOPT_WRITEFUNCTION, | ||
1810 | &client_receive_put); | ||
1811 | curl_easy_setopt (s->put.easyhandle, | ||
1812 | CURLOPT_WRITEDATA, | ||
1813 | s); | ||
1609 | /* No timeout by default, timeout done with session timeout */ | 1814 | /* No timeout by default, timeout done with session timeout */ |
1610 | curl_easy_setopt (s->put.easyhandle, CURLOPT_TIMEOUT, 0); | 1815 | curl_easy_setopt (s->put.easyhandle, |
1611 | curl_easy_setopt (s->put.easyhandle, CURLOPT_PRIVATE, s); | 1816 | CURLOPT_TIMEOUT, |
1612 | curl_easy_setopt (s->put.easyhandle, CURLOPT_CONNECTTIMEOUT_MS, | 1817 | 0L); |
1818 | curl_easy_setopt (s->put.easyhandle, | ||
1819 | CURLOPT_PRIVATE, | ||
1820 | s); | ||
1821 | curl_easy_setopt (s->put.easyhandle, | ||
1822 | CURLOPT_CONNECTTIMEOUT_MS, | ||
1613 | (long) (HTTP_CLIENT_NOT_VALIDATED_TIMEOUT.rel_value_us / 1000LL)); | 1823 | (long) (HTTP_CLIENT_NOT_VALIDATED_TIMEOUT.rel_value_us / 1000LL)); |
1614 | curl_easy_setopt (s->put.easyhandle, CURLOPT_BUFFERSIZE, | 1824 | curl_easy_setopt (s->put.easyhandle, CURLOPT_BUFFERSIZE, |
1615 | 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE); | 1825 | 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE); |
@@ -1625,7 +1835,6 @@ client_connect_put (struct Session *s) | |||
1625 | s, curl_multi_strerror (mret)); | 1835 | s, curl_multi_strerror (mret)); |
1626 | curl_easy_cleanup (s->put.easyhandle); | 1836 | curl_easy_cleanup (s->put.easyhandle); |
1627 | s->put.easyhandle = NULL; | 1837 | s->put.easyhandle = NULL; |
1628 | s->put.easyhandle = NULL; | ||
1629 | s->put.s = NULL; | 1838 | s->put.s = NULL; |
1630 | s->put.state = H_DISCONNECTED; | 1839 | s->put.state = H_DISCONNECTED; |
1631 | return GNUNET_SYSERR; | 1840 | return GNUNET_SYSERR; |
@@ -1654,18 +1863,24 @@ client_connect (struct Session *s) | |||
1654 | int res = GNUNET_OK; | 1863 | int res = GNUNET_OK; |
1655 | 1864 | ||
1656 | /* create url */ | 1865 | /* create url */ |
1657 | if (NULL == http_common_plugin_address_to_string(plugin->protocol, | 1866 | if (NULL == |
1658 | s->address->address, s->address->address_length)) | 1867 | http_common_plugin_address_to_string(plugin->protocol, |
1659 | { | 1868 | s->address->address, |
1660 | LOG(GNUNET_ERROR_TYPE_DEBUG, "Invalid address peer `%s'\n", | 1869 | s->address->address_length)) |
1661 | GNUNET_i2s(&s->address->peer)); | 1870 | { |
1662 | return GNUNET_SYSERR; | 1871 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1663 | } | 1872 | "Invalid address peer `%s'\n", |
1873 | GNUNET_i2s(&s->address->peer)); | ||
1874 | return GNUNET_SYSERR; | ||
1875 | } | ||
1664 | 1876 | ||
1665 | GNUNET_asprintf(&s->url, "%s/%s;%u", | 1877 | GNUNET_asprintf(&s->url, |
1666 | http_common_plugin_address_to_url(NULL, s->address->address, | 1878 | "%s/%s;%u", |
1667 | s->address->address_length), | 1879 | http_common_plugin_address_to_url(NULL, |
1668 | GNUNET_i2s_full(plugin->env->my_identity), plugin->last_tag); | 1880 | s->address->address, |
1881 | s->address->address_length), | ||
1882 | GNUNET_i2s_full (plugin->env->my_identity), | ||
1883 | plugin->last_tag); | ||
1669 | 1884 | ||
1670 | plugin->last_tag++; | 1885 | plugin->last_tag++; |
1671 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1886 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1798,7 +2013,9 @@ http_client_plugin_get_session (void *cls, | |||
1798 | /* Determine network location */ | 2013 | /* Determine network location */ |
1799 | ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); | 2014 | ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); |
1800 | ats.value = htonl (GNUNET_ATS_NET_UNSPECIFIED); | 2015 | ats.value = htonl (GNUNET_ATS_NET_UNSPECIFIED); |
1801 | sa = http_common_socket_from_address (address->address, address->address_length, &res); | 2016 | sa = http_common_socket_from_address (address->address, |
2017 | address->address_length, | ||
2018 | &res); | ||
1802 | if (GNUNET_SYSERR == res) | 2019 | if (GNUNET_SYSERR == res) |
1803 | return NULL; | 2020 | return NULL; |
1804 | if (GNUNET_YES == res) | 2021 | if (GNUNET_YES == res) |
@@ -1975,7 +2192,6 @@ client_configure_plugin (struct HTTP_Client_Plugin *plugin) | |||
1975 | unsigned long long max_requests; | 2192 | unsigned long long max_requests; |
1976 | char *proxy_type; | 2193 | char *proxy_type; |
1977 | 2194 | ||
1978 | |||
1979 | /* Optional parameters */ | 2195 | /* Optional parameters */ |
1980 | if (GNUNET_OK != | 2196 | if (GNUNET_OK != |
1981 | GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, | 2197 | GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, |
@@ -1990,8 +2206,11 @@ client_configure_plugin (struct HTTP_Client_Plugin *plugin) | |||
1990 | plugin->max_requests); | 2206 | plugin->max_requests); |
1991 | 2207 | ||
1992 | /* Read proxy configuration */ | 2208 | /* Read proxy configuration */ |
1993 | if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, | 2209 | if (GNUNET_OK == |
1994 | plugin->name, "PROXY", &plugin->proxy_hostname)) | 2210 | GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, |
2211 | plugin->name, | ||
2212 | "PROXY", | ||
2213 | &plugin->proxy_hostname)) | ||
1995 | { | 2214 | { |
1996 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2215 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1997 | "Found proxy host: `%s'\n", | 2216 | "Found proxy host: `%s'\n", |
diff --git a/src/transport/plugin_transport_http_common.h b/src/transport/plugin_transport_http_common.h index 79c671862..ccb597b92 100644 --- a/src/transport/plugin_transport_http_common.h +++ b/src/transport/plugin_transport_http_common.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | (C) 2002-2013 Christian Grothoff (and other contributing authors) | 3 | (C) 2002-2014 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published |
@@ -21,6 +21,7 @@ | |||
21 | * @file transport/plugin_transport_http_common.c | 21 | * @file transport/plugin_transport_http_common.c |
22 | * @brief functionality shared by http client and server transport service plugin | 22 | * @brief functionality shared by http client and server transport service plugin |
23 | * @author Matthias Wachs | 23 | * @author Matthias Wachs |
24 | * @author Christian Grothoff | ||
24 | */ | 25 | */ |
25 | #include "platform.h" | 26 | #include "platform.h" |
26 | #include "gnunet_common.h" | 27 | #include "gnunet_common.h" |
@@ -72,7 +73,12 @@ enum HttpAddressOptions | |||
72 | * (if this bit is not set, it is probably just self- | 73 | * (if this bit is not set, it is probably just self- |
73 | * signed and not expected to be verified). | 74 | * signed and not expected to be verified). |
74 | */ | 75 | */ |
75 | HTTP_OPTIONS_VERIFY_CERTIFICATE = 1 | 76 | HTTP_OPTIONS_VERIFY_CERTIFICATE = 1, |
77 | |||
78 | /** | ||
79 | * Enable TCP Stealth-style port knocking. | ||
80 | */ | ||
81 | HTTP_OPTIONS_TCP_STEALTH = 2 | ||
76 | }; | 82 | }; |
77 | 83 | ||
78 | 84 | ||