paragraph for gnunet devs that don't know how to use the web
[oweals/gnunet.git] / src / transport / plugin_transport_http.h
1 /*
2      This file is part of GNUnet
3      Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your 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      Affero General Public License for more details.
14     
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /**
20  * @file transport/plugin_transport_http.h
21  * @brief http transport service plugin
22  * @author Matthias Wachs
23  */
24 #ifndef PLUGIN_TRANSPORT_HTTP_H
25 #define PLUGIN_TRANSPORT_HTTP_H
26
27 #include "platform.h"
28 #include "gnunet_common.h"
29 #include "gnunet_constants.h"
30 #include "gnunet_protocols.h"
31 #include "gnunet_connection_lib.h"
32 #include "gnunet_service_lib.h"
33 #include "gnunet_statistics_service.h"
34 #include "gnunet_transport_service.h"
35 #include "gnunet_resolver_service.h"
36 #include "gnunet_server_lib.h"
37 #include "gnunet_container_lib.h"
38 #include "gnunet_transport_plugin.h"
39 #include "gnunet_os_lib.h"
40 #include "gnunet_nat_lib.h"
41 #include "microhttpd.h"
42 #if HAVE_CURL_CURL_H
43 #include <curl/curl.h>
44 #elif HAVE_GNURL_CURL_H
45 #include <gnurl/curl.h>
46 #endif
47
48
49 #define DEBUG_HTTP GNUNET_EXTRA_LOGGING
50 #define VERBOSE_SERVER GNUNET_EXTRA_LOGGING
51 #define VERBOSE_CLIENT GNUNET_EXTRA_LOGGING
52 #define VERBOSE_CURL GNUNET_NO
53
54 #if BUILD_HTTPS
55 #define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_https_init
56 #define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_https_done
57 #else
58 #define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_http_init
59 #define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_http_done
60 #endif
61
62 #define INBOUND  GNUNET_YES
63 #define OUTBOUND GNUNET_NO
64
65
66 #define HTTP_NOT_VALIDATED_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
67
68 /**
69  * Encapsulation of all of the state of the plugin.
70  */
71 struct Plugin
72 {
73   /**
74    * Our environment.
75    */
76   struct GNUNET_TRANSPORT_PluginEnvironment *env;
77
78   /**
79    * Head of linked list of open sessions.
80    */
81   struct GNUNET_ATS_Session *head;
82
83   /**
84    * Tail of linked list of open sessions.
85    */
86   struct GNUNET_ATS_Session *tail;
87
88   /**
89    * NAT handle & address management
90    */
91   struct GNUNET_NAT_Handle *nat;
92
93   /**
94    * Our own IPv4 addresses DLL head
95    */
96   struct HttpAddressWrapper *addr_head;
97
98   /**
99    * Our own IPv4 addresses DLL tail
100    */
101   struct HttpAddressWrapper *addr_tail;
102
103   /**
104    * External hostname the plugin can be connected to, can be different to
105    * the host's FQDN, used e.g. for reverse proxying
106    */
107   char *external_hostname;
108
109   /**
110    * External hostname the plugin can be connected to, can be different to
111    * the host's FQDN, used e.g. for reverse proxying
112    */
113   struct HttpAddress *ext_addr;
114
115   /**
116    * External address length
117    */
118   size_t ext_addr_len;
119
120   /**
121    * Task calling transport service about external address
122    */
123   struct GNUNET_SCHEDULER_Task * notify_ext_task;
124
125   /**
126    * Plugin name.
127    * Equals configuration section: transport-http, transport-https
128    */
129   char *name;
130
131   /**
132    * Plugin protocol
133    * http, https
134    */
135   char *protocol;
136
137   /**
138    * Use IPv4? #GNUNET_YES or #GNUNET_NO
139    */
140   int ipv4;
141
142   /**
143    * Use IPv6? #GNUNET_YES or #GNUNET_NO
144    */
145   int ipv6;
146
147   /**
148    * Does plugin just use outbound connections and not accept inbound?
149    */
150   int client_only;
151
152   /**
153    * Port used
154    */
155   uint16_t port;
156
157   /**
158    * Maximum number of sockets the plugin can use
159    * Each http inbound /outbound connections are two connections
160    */
161   int max_connections;
162
163   /**
164    * Number of outbound sessions
165    */
166   unsigned int outbound_sessions;
167
168   /**
169    * Number of inbound sessions
170    */
171   unsigned int inbound_sessions;
172
173   /**
174    * libCurl TLS crypto init string, can be set to enhance performance
175    *
176    * Example:
177    *
178    * Use RC4-128 instead of AES:
179    * NONE:+VERS-TLS1.0:+ARCFOUR-128:+SHA1:+RSA:+COMP-NULL
180    */
181   char *crypto_init;
182
183   /**
184    * TLS key
185    */
186   char *key;
187
188   /**
189    * TLS certificate
190    */
191   char *cert;
192
193   /**
194    * Current number of establishes connections
195    */
196   int cur_connections;
197
198   /**
199    * Last used unique HTTP connection tag
200    */
201   uint32_t last_tag;
202
203   /**
204    * MHD IPv4 daemon
205    */
206   struct MHD_Daemon *server_v4;
207
208   /**
209    * MHD IPv4 task
210    */
211   struct GNUNET_SCHEDULER_Task * server_v4_task;
212
213   /**
214    * The IPv4 server is scheduled to run asap
215    */
216   int server_v4_immediately;
217
218   /**
219    * MHD IPv6 daemon
220    */
221   struct MHD_Daemon *server_v6;
222
223   /**
224    * MHD IPv4 task
225    */
226   struct GNUNET_SCHEDULER_Task * server_v6_task;
227
228   /**
229    * The IPv6 server is scheduled to run asap
230    */
231   int server_v6_immediately;
232
233   /**
234    * IPv4 server socket to bind to
235    */
236   struct sockaddr_in *server_addr_v4;
237
238   /**
239    * IPv6 server socket to bind to
240    */
241   struct sockaddr_in6 *server_addr_v6;
242
243   /**
244    * Head of server semi connections
245    * A full session consists of 2 semi-connections: send and receive
246    * If not both directions are established the server keeps this sessions here
247    */
248   struct GNUNET_ATS_Session *server_semi_head;
249
250   /**
251    * Tail of server semi connections
252    * A full session consists of 2 semi-connections: send and receive
253    * If not both directions are established the server keeps this sessions here
254    */
255   struct GNUNET_ATS_Session *server_semi_tail;
256
257   /**
258    * cURL Multihandle
259    */
260   CURLM *client_mh;
261
262   /**
263    * curl perform task
264    */
265   struct GNUNET_SCHEDULER_Task * client_perform_task;
266
267 };
268
269 GNUNET_NETWORK_STRUCT_BEGIN
270
271 /**
272  * HTTP addresses including a full URI
273  */
274 struct HttpAddress
275 {
276   /**
277    * Length of the address following in NBO
278    */
279   uint32_t addr_len GNUNET_PACKED;
280
281   /**
282    * Address following
283    */
284   void *addr GNUNET_PACKED;
285 };
286
287 /**
288  * IPv4 addresses
289  */
290 struct IPv4HttpAddress
291 {
292   /**
293    * IPv4 address, in network byte order.
294    */
295   uint32_t ipv4_addr GNUNET_PACKED;
296
297   /**
298    * Port number, in network byte order.
299    */
300   uint16_t u4_port GNUNET_PACKED;
301 };
302
303 /**
304  * IPv4 addresses
305  */
306 struct IPv6HttpAddress
307 {
308   /**
309    * IPv6 address.
310    */
311   struct in6_addr ipv6_addr GNUNET_PACKED;
312
313   /**
314    * Port number, in network byte order.
315    */
316   uint16_t u6_port GNUNET_PACKED;
317 };
318 GNUNET_NETWORK_STRUCT_END
319
320
321 struct ServerRequest
322 {
323   /**
324    * _RECV or _SEND
325    */
326   int direction;
327
328   /**
329    * Should this connection get disconnected? #GNUNET_YES / #GNUNET_NO
330    */
331   int disconnect;
332
333   /**
334    * The session this server connection belongs to
335    */
336   struct GNUNET_ATS_Session *session;
337
338   /**
339    * The MHD connection
340    */
341   struct MHD_Connection *mhd_conn;
342 };
343
344
345 /**
346  * Session handle for connections.
347  */
348 struct GNUNET_ATS_Session
349 {
350   /**
351    * To whom are we talking to
352    */
353   struct GNUNET_PeerIdentity target;
354
355   /**
356    * Stored in a linked list.
357    */
358   struct GNUNET_ATS_Session *next;
359
360   /**
361    * Stored in a linked list.
362    */
363   struct GNUNET_ATS_Session *prev;
364
365   /**
366    * Pointer to the global plugin struct.
367    */
368   struct Plugin *plugin;
369
370   /**
371    * Address
372    */
373   void *addr;
374
375   /**
376    * Address length
377    */
378   size_t addrlen;
379
380   /**
381    * ATS network type in NBO
382    */
383   uint32_t ats_address_network_type;
384
385   /**
386    * next pointer for double linked list
387    */
388   struct HTTP_Message *msg_head;
389
390   /**
391    * previous pointer for double linked list
392    */
393   struct HTTP_Message *msg_tail;
394
395   /**
396    * Message stream tokenizer for incoming data
397    */
398   struct GNUNET_SERVER_MessageStreamTokenizer *msg_tk;
399
400   /**
401    * Absolute time when to receive data again
402    * Used for receive throttling
403    */
404   struct GNUNET_TIME_Absolute next_receive;
405
406   /**
407    * Inbound or outbound connection
408    * Outbound: #GNUNET_NO (client is used to send and receive)
409    * Inbound : #GNUNET_YES (server is used to send and receive)
410    */
411   int inbound;
412
413   /**
414    * Unique HTTP/S connection tag for this connection
415    */
416   uint32_t tag;
417
418   /**
419    * Client send handle
420    */
421   void *client_put;
422
423   /**
424    * Client receive handle
425    */
426   void *client_get;
427
428   /**
429    * Task to wake up client receive handle when receiving is allowed again
430    */
431   struct GNUNET_SCHEDULER_Task * recv_wakeup_task;
432
433   /**
434    * Session timeout task
435    */
436   struct GNUNET_SCHEDULER_Task * timeout_task;
437
438   /**
439    * Is client send handle paused since there are no data to send?
440    * #GNUNET_YES or #GNUNET_NO
441    */
442   int client_put_paused;
443
444   /**
445    * Client send handle
446    */
447   struct ServerRequest *server_recv;
448
449   /**
450    * Client send handle
451    */
452   struct ServerRequest *server_send;
453 };
454
455
456 /**
457  *  Message to send using http
458  */
459 struct HTTP_Message
460 {
461   /**
462    * next pointer for double linked list
463    */
464   struct HTTP_Message *next;
465
466   /**
467    * previous pointer for double linked list
468    */
469   struct HTTP_Message *prev;
470
471   /**
472    * buffer containing data to send
473    */
474   char *buf;
475
476   /**
477    * amount of data already sent
478    */
479   size_t pos;
480
481   /**
482    * buffer length
483    */
484   size_t size;
485
486   /**
487    * Continuation function to call once the transmission buffer
488    * has again space available.  NULL if there is no
489    * continuation to call.
490    */
491   GNUNET_TRANSPORT_TransmitContinuation transmit_cont;
492
493   /**
494    * Closure for @e transmit_cont.
495    */
496   void *transmit_cont_cls;
497 };
498
499
500 struct GNUNET_ATS_Session *
501 create_session (struct Plugin *plugin,
502                 const struct GNUNET_PeerIdentity *target,
503                 const void *addr,
504                 size_t addrlen);
505
506
507 int
508 exist_session (struct Plugin *plugin,
509                struct GNUNET_ATS_Session *s);
510
511
512 void
513 delete_session (struct GNUNET_ATS_Session *s);
514
515
516 int
517 exist_session (struct Plugin *plugin,
518                struct GNUNET_ATS_Session *s);
519
520
521 struct GNUNET_TIME_Relative
522 http_plugin_receive (void *cls,
523                      const struct GNUNET_PeerIdentity *peer,
524                      const struct GNUNET_MessageHeader *message,
525                      struct GNUNET_ATS_Session *session,
526                      const char *sender_address,
527                      uint16_t sender_address_len);
528
529
530 const char *
531 http_plugin_address_to_string (void *cls,
532                                const void *addr,
533                                size_t addrlen);
534
535
536 int
537 client_disconnect (struct GNUNET_ATS_Session *s);
538
539
540 int
541 client_connect (struct GNUNET_ATS_Session *s);
542
543
544 int
545 client_send (struct GNUNET_ATS_Session *s, struct HTTP_Message *msg);
546
547
548 int
549 client_start (struct Plugin *plugin);
550
551
552 void
553 client_stop (struct Plugin *plugin);
554
555
556 int
557 server_disconnect (struct GNUNET_ATS_Session *s);
558
559
560 int
561 server_send (struct GNUNET_ATS_Session *s, struct HTTP_Message *msg);
562
563
564 int
565 server_start (struct Plugin *plugin);
566
567
568 void
569 server_stop (struct Plugin *plugin);
570
571
572 void
573 notify_session_end (void *cls,
574                     const struct GNUNET_PeerIdentity *peer,
575                     struct GNUNET_ATS_Session *s);
576
577
578 /*#ifndef PLUGIN_TRANSPORT_HTTP_H*/
579 #endif
580 /* end of plugin_transport_http.h */