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