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