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