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