986d7d7975cabb985cdacabae53e990bce9cbf66
[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    * Plugin name
123    * Equals configuration section: transport-http, transport-https
124    */
125   char *name;
126
127   /**
128    * Plugin protocol
129    * http, https
130    */
131   char *protocol;
132
133   /**
134    * Use IPv4?
135    * GNUNET_YES or GNUNET_NO
136    */
137   int ipv4;
138
139   /**
140    * Use IPv6?
141    * GNUNET_YES or GNUNET_NO
142    */
143   int ipv6;
144
145   /**
146    * Does plugin just use outbound connections and not accept inbound?
147    */
148
149   int client_only;
150
151   /**
152    * Port used
153    */
154   uint16_t port;
155
156   /**
157    * Maximum number of sockets the plugin can use
158    * Each http inbound /outbound connections are two connections
159    */
160   int max_connections;
161
162   /**
163    * Number of outbound sessions
164    */
165   unsigned int outbound_sessions;
166
167   /**
168    * Number of inbound sessions
169    */
170   unsigned int inbound_sessions;
171
172   /**
173    * Plugin HTTPS SSL/TLS options
174    * ----------------------------
175    */
176
177   /**
178    * libCurl TLS crypto init string, can be set to enhance performance
179    *
180    * Example:
181    *
182    * Use RC4-128 instead of AES:
183    * NONE:+VERS-TLS1.0:+ARCFOUR-128:+SHA1:+RSA:+COMP-NULL
184    *
185    */
186   char *crypto_init;
187
188   /**
189    * TLS key
190    */
191   char *key;
192
193   /**
194    * TLS certificate
195    */
196   char *cert;
197
198   /**
199    * Plugin values
200    * -------------
201    */
202
203   /**
204    * Current number of establishes connections
205    */
206   int cur_connections;
207
208   /**
209    * Last used unique HTTP connection tag
210    */
211   uint32_t last_tag;
212
213   /**
214    * Server handles
215    * --------------
216    */
217
218   /**
219    * MHD IPv4 daemon
220    */
221   struct MHD_Daemon *server_v4;
222
223   /**
224    * MHD IPv4 task
225    */
226   GNUNET_SCHEDULER_TaskIdentifier server_v4_task;
227
228   /**
229    * The IPv4 server is scheduled to run asap
230    */
231   int server_v4_immediately;
232
233   /**
234    * MHD IPv6 daemon
235    */
236   struct MHD_Daemon *server_v6;
237
238   /**
239    * MHD IPv4 task
240    */
241   GNUNET_SCHEDULER_TaskIdentifier server_v6_task;
242
243   /**
244    * The IPv6 server is scheduled to run asap
245    */
246
247   int server_v6_immediately;
248
249   /**
250    * IPv4 server socket to bind to
251    */
252   struct sockaddr_in *server_addr_v4;
253
254   /**
255    * IPv6 server socket to bind to
256    */
257   struct sockaddr_in6 *server_addr_v6;
258
259   /**
260    * Server semi connections
261    * A full session consists of 2 semi-connections: send and receive
262    * If not both directions are established the server keeps this sessions here
263    */
264   struct Session *server_semi_head;
265
266   struct Session *server_semi_tail;
267
268   /*
269    * Client handles
270    */
271
272   /**
273    * cURL Multihandle
274    */
275   CURLM *client_mh;
276
277   /**
278    * curl perform task
279    */
280   GNUNET_SCHEDULER_TaskIdentifier client_perform_task;
281
282 };
283
284 GNUNET_NETWORK_STRUCT_BEGIN
285
286 /**
287  * IPv4 addresses
288  */
289 struct IPv4HttpAddress
290 {
291   /**
292    * IPv4 address, in network byte order.
293    */
294   uint32_t ipv4_addr GNUNET_PACKED;
295
296   /**
297    * Port number, in network byte order.
298    */
299   uint16_t u4_port GNUNET_PACKED;
300 };
301
302 /**
303  * IPv4 addresses
304  */
305 struct IPv6HttpAddress
306 {
307   /**
308    * IPv6 address.
309    */
310   struct in6_addr ipv6_addr GNUNET_PACKED;
311
312   /**
313    * Port number, in network byte order.
314    */
315   uint16_t u6_port GNUNET_PACKED;
316 };
317 GNUNET_NETWORK_STRUCT_END
318
319
320 struct ServerConnection
321 {
322   /* _RECV or _SEND */
323   int direction;
324
325   /* Should this connection get disconnected? GNUNET_YES/NO  */
326   int disconnect;
327
328   /* The session this server connection belongs to */
329   struct Session *session;
330
331   /* The MHD connection */
332   struct MHD_Connection *mhd_conn;
333 };
334
335
336
337 /**
338  * Session handle for connections.
339  */
340 struct Session
341 {
342
343   /**
344    * Stored in a linked list.
345    */
346   struct Session *next;
347
348   /**
349    * Stored in a linked list.
350    */
351   struct Session *prev;
352
353   /**
354    * Pointer to the global plugin struct.
355    */
356   struct Plugin *plugin;
357
358   /**
359    * Address
360    */
361   void *addr;
362
363   /**
364    * Address length
365    */
366   size_t addrlen;
367
368   /**
369    * ATS network type in NBO
370    */
371   uint32_t ats_address_network_type;
372
373   /**
374    * To whom are we talking to
375    */
376   struct GNUNET_PeerIdentity target;
377
378   /**
379    * next pointer for double linked list
380    */
381   struct HTTP_Message *msg_head;
382
383   /**
384    * previous pointer for double linked list
385    */
386   struct HTTP_Message *msg_tail;
387
388
389   /**
390    * Message stream tokenizer for incoming data
391    */
392   struct GNUNET_SERVER_MessageStreamTokenizer *msg_tk;
393
394   /**
395    * Absolute time when to receive data again
396    * Used for receive throttling
397    */
398   struct GNUNET_TIME_Absolute next_receive;
399
400   /**
401    * Inbound or outbound connection
402    * Outbound: GNUNET_NO (client is used to send and receive)
403    * Inbound : GNUNET_YES (server is used to send and receive)
404    */
405   int inbound;
406
407   /**
408    * Unique HTTP/S connection tag for this connection
409    */
410   uint32_t tag;
411
412   /**
413    * Client handles
414    */
415
416   /**
417    * Client send handle
418    */
419   void *client_put;
420
421   /**
422    * Client receive handle
423    */
424   void *client_get;
425
426   /**
427    * Task to wake up client receive handle when receiving is allowed again
428    */
429   GNUNET_SCHEDULER_TaskIdentifier recv_wakeup_task;
430
431   /**
432    * Session timeout task
433    */
434   GNUNET_SCHEDULER_TaskIdentifier timeout_task;
435
436   /**
437    * Is client send handle paused since there are no data to send?
438    * GNUNET_YES/NO
439    */
440   int client_put_paused;
441
442   /**
443    * Server handles
444    */
445
446   /**
447    * Client send handle
448    */
449   struct ServerConnection *server_recv;
450
451   /**
452    * Client send handle
453    */
454   struct ServerConnection *server_send;
455 };
456
457 /**
458  *  Message to send using http
459  */
460 struct HTTP_Message
461 {
462   /**
463    * next pointer for double linked list
464    */
465   struct HTTP_Message *next;
466
467   /**
468    * previous pointer for double linked list
469    */
470   struct HTTP_Message *prev;
471
472   /**
473    * buffer containing data to send
474    */
475   char *buf;
476
477   /**
478    * amount of data already sent
479    */
480   size_t pos;
481
482   /**
483    * buffer length
484    */
485   size_t size;
486
487   /**
488    * Continuation function to call once the transmission buffer
489    * has again space available.  NULL if there is no
490    * continuation to call.
491    */
492   GNUNET_TRANSPORT_TransmitContinuation transmit_cont;
493
494   /**
495    * Closure for transmit_cont.
496    */
497   void *transmit_cont_cls;
498 };
499
500 struct Session *
501 create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
502                 const void *addr, size_t addrlen);
503
504 int
505 exist_session (struct Plugin *plugin, struct Session *s);
506
507 void
508 delete_session (struct Session *s);
509
510 int
511 exist_session (struct Plugin *plugin, struct Session *s);
512
513 struct GNUNET_TIME_Relative
514 http_plugin_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
515                      const struct GNUNET_MessageHeader *message,
516                      struct Session *session, const char *sender_address,
517                      uint16_t sender_address_len);
518
519 const char *
520 http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen);
521
522 int
523 client_disconnect (struct Session *s);
524
525 int
526 client_connect (struct Session *s);
527
528 int
529 client_send (struct Session *s, struct HTTP_Message *msg);
530
531 int
532 client_start (struct Plugin *plugin);
533
534 void
535 client_stop (struct Plugin *plugin);
536
537 int
538 server_disconnect (struct Session *s);
539
540 int
541 server_send (struct Session *s, struct HTTP_Message *msg);
542
543 int
544 server_start (struct Plugin *plugin);
545
546 void
547 server_stop (struct Plugin *plugin);
548
549 void
550 notify_session_end (void *cls, const struct GNUNET_PeerIdentity *peer,
551                     struct Session *s);
552
553 /* end of plugin_transport_http.h */