plugin_transport_http.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  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. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file transport/plugin_transport_http.h
  19. * @brief http transport service plugin
  20. * @author Matthias Wachs
  21. */
  22. #ifndef PLUGIN_TRANSPORT_HTTP_H
  23. #define PLUGIN_TRANSPORT_HTTP_H
  24. #include "platform.h"
  25. #include "gnunet_common.h"
  26. #include "gnunet_constants.h"
  27. #include "gnunet_protocols.h"
  28. #include "gnunet_connection_lib.h"
  29. #include "gnunet_service_lib.h"
  30. #include "gnunet_statistics_service.h"
  31. #include "gnunet_transport_service.h"
  32. #include "gnunet_resolver_service.h"
  33. #include "gnunet_server_lib.h"
  34. #include "gnunet_container_lib.h"
  35. #include "gnunet_transport_plugin.h"
  36. #include "gnunet_os_lib.h"
  37. #include "gnunet_nat_lib.h"
  38. #include "microhttpd.h"
  39. #if HAVE_CURL_CURL_H
  40. #include <curl/curl.h>
  41. #elif HAVE_GNURL_CURL_H
  42. #include <gnurl/curl.h>
  43. #endif
  44. #define DEBUG_HTTP GNUNET_EXTRA_LOGGING
  45. #define VERBOSE_SERVER GNUNET_EXTRA_LOGGING
  46. #define VERBOSE_CLIENT GNUNET_EXTRA_LOGGING
  47. #define VERBOSE_CURL GNUNET_NO
  48. #if BUILD_HTTPS
  49. #define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_https_init
  50. #define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_https_done
  51. #else
  52. #define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_http_init
  53. #define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_http_done
  54. #endif
  55. #define INBOUND GNUNET_YES
  56. #define OUTBOUND GNUNET_NO
  57. #define HTTP_NOT_VALIDATED_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
  58. /**
  59. * Encapsulation of all of the state of the plugin.
  60. */
  61. struct Plugin
  62. {
  63. /**
  64. * Our environment.
  65. */
  66. struct GNUNET_TRANSPORT_PluginEnvironment *env;
  67. /**
  68. * Head of linked list of open sessions.
  69. */
  70. struct Session *head;
  71. /**
  72. * Tail of linked list of open sessions.
  73. */
  74. struct Session *tail;
  75. /**
  76. * NAT handle & address management
  77. */
  78. struct GNUNET_NAT_Handle *nat;
  79. /**
  80. * Our own IPv4 addresses DLL head
  81. */
  82. struct HttpAddressWrapper *addr_head;
  83. /**
  84. * Our own IPv4 addresses DLL tail
  85. */
  86. struct HttpAddressWrapper *addr_tail;
  87. /**
  88. * External hostname the plugin can be connected to, can be different to
  89. * the host's FQDN, used e.g. for reverse proxying
  90. */
  91. char *external_hostname;
  92. /**
  93. * External hostname the plugin can be connected to, can be different to
  94. * the host's FQDN, used e.g. for reverse proxying
  95. */
  96. struct HttpAddress *ext_addr;
  97. /**
  98. * External address length
  99. */
  100. size_t ext_addr_len;
  101. /**
  102. * Task calling transport service about external address
  103. */
  104. struct GNUNET_SCHEDULER_Task * notify_ext_task;
  105. /**
  106. * Plugin name.
  107. * Equals configuration section: transport-http, transport-https
  108. */
  109. char *name;
  110. /**
  111. * Plugin protocol
  112. * http, https
  113. */
  114. char *protocol;
  115. /**
  116. * Use IPv4? #GNUNET_YES or #GNUNET_NO
  117. */
  118. int ipv4;
  119. /**
  120. * Use IPv6? #GNUNET_YES or #GNUNET_NO
  121. */
  122. int ipv6;
  123. /**
  124. * Does plugin just use outbound connections and not accept inbound?
  125. */
  126. int client_only;
  127. /**
  128. * Port used
  129. */
  130. uint16_t port;
  131. /**
  132. * Maximum number of sockets the plugin can use
  133. * Each http inbound /outbound connections are two connections
  134. */
  135. int max_connections;
  136. /**
  137. * Number of outbound sessions
  138. */
  139. unsigned int outbound_sessions;
  140. /**
  141. * Number of inbound sessions
  142. */
  143. unsigned int inbound_sessions;
  144. /**
  145. * libCurl TLS crypto init string, can be set to enhance performance
  146. *
  147. * Example:
  148. *
  149. * Use RC4-128 instead of AES:
  150. * NONE:+VERS-TLS1.0:+ARCFOUR-128:+SHA1:+RSA:+COMP-NULL
  151. */
  152. char *crypto_init;
  153. /**
  154. * TLS key
  155. */
  156. char *key;
  157. /**
  158. * TLS certificate
  159. */
  160. char *cert;
  161. /**
  162. * Current number of establishes connections
  163. */
  164. int cur_connections;
  165. /**
  166. * Last used unique HTTP connection tag
  167. */
  168. uint32_t last_tag;
  169. /**
  170. * MHD IPv4 daemon
  171. */
  172. struct MHD_Daemon *server_v4;
  173. /**
  174. * MHD IPv4 task
  175. */
  176. struct GNUNET_SCHEDULER_Task * server_v4_task;
  177. /**
  178. * The IPv4 server is scheduled to run asap
  179. */
  180. int server_v4_immediately;
  181. /**
  182. * MHD IPv6 daemon
  183. */
  184. struct MHD_Daemon *server_v6;
  185. /**
  186. * MHD IPv4 task
  187. */
  188. struct GNUNET_SCHEDULER_Task * server_v6_task;
  189. /**
  190. * The IPv6 server is scheduled to run asap
  191. */
  192. int server_v6_immediately;
  193. /**
  194. * IPv4 server socket to bind to
  195. */
  196. struct sockaddr_in *server_addr_v4;
  197. /**
  198. * IPv6 server socket to bind to
  199. */
  200. struct sockaddr_in6 *server_addr_v6;
  201. /**
  202. * Head of server semi connections
  203. * A full session consists of 2 semi-connections: send and receive
  204. * If not both directions are established the server keeps this sessions here
  205. */
  206. struct Session *server_semi_head;
  207. /**
  208. * Tail of server semi connections
  209. * A full session consists of 2 semi-connections: send and receive
  210. * If not both directions are established the server keeps this sessions here
  211. */
  212. struct Session *server_semi_tail;
  213. /**
  214. * cURL Multihandle
  215. */
  216. CURLM *client_mh;
  217. /**
  218. * curl perform task
  219. */
  220. struct GNUNET_SCHEDULER_Task * client_perform_task;
  221. };
  222. GNUNET_NETWORK_STRUCT_BEGIN
  223. /**
  224. * HTTP addresses including a full URI
  225. */
  226. struct HttpAddress
  227. {
  228. /**
  229. * Length of the address following in NBO
  230. */
  231. uint32_t addr_len GNUNET_PACKED;
  232. /**
  233. * Address following
  234. */
  235. void *addr GNUNET_PACKED;
  236. };
  237. /**
  238. * IPv4 addresses
  239. */
  240. struct IPv4HttpAddress
  241. {
  242. /**
  243. * IPv4 address, in network byte order.
  244. */
  245. uint32_t ipv4_addr GNUNET_PACKED;
  246. /**
  247. * Port number, in network byte order.
  248. */
  249. uint16_t u4_port GNUNET_PACKED;
  250. };
  251. /**
  252. * IPv4 addresses
  253. */
  254. struct IPv6HttpAddress
  255. {
  256. /**
  257. * IPv6 address.
  258. */
  259. struct in6_addr ipv6_addr GNUNET_PACKED;
  260. /**
  261. * Port number, in network byte order.
  262. */
  263. uint16_t u6_port GNUNET_PACKED;
  264. };
  265. GNUNET_NETWORK_STRUCT_END
  266. struct ServerRequest
  267. {
  268. /**
  269. * _RECV or _SEND
  270. */
  271. int direction;
  272. /**
  273. * Should this connection get disconnected? #GNUNET_YES / #GNUNET_NO
  274. */
  275. int disconnect;
  276. /**
  277. * The session this server connection belongs to
  278. */
  279. struct Session *session;
  280. /**
  281. * The MHD connection
  282. */
  283. struct MHD_Connection *mhd_conn;
  284. };
  285. /**
  286. * Session handle for connections.
  287. */
  288. struct Session
  289. {
  290. /**
  291. * To whom are we talking to
  292. */
  293. struct GNUNET_PeerIdentity target;
  294. /**
  295. * Stored in a linked list.
  296. */
  297. struct Session *next;
  298. /**
  299. * Stored in a linked list.
  300. */
  301. struct Session *prev;
  302. /**
  303. * Pointer to the global plugin struct.
  304. */
  305. struct Plugin *plugin;
  306. /**
  307. * Address
  308. */
  309. void *addr;
  310. /**
  311. * Address length
  312. */
  313. size_t addrlen;
  314. /**
  315. * ATS network type in NBO
  316. */
  317. uint32_t ats_address_network_type;
  318. /**
  319. * next pointer for double linked list
  320. */
  321. struct HTTP_Message *msg_head;
  322. /**
  323. * previous pointer for double linked list
  324. */
  325. struct HTTP_Message *msg_tail;
  326. /**
  327. * Message stream tokenizer for incoming data
  328. */
  329. struct GNUNET_SERVER_MessageStreamTokenizer *msg_tk;
  330. /**
  331. * Absolute time when to receive data again
  332. * Used for receive throttling
  333. */
  334. struct GNUNET_TIME_Absolute next_receive;
  335. /**
  336. * Inbound or outbound connection
  337. * Outbound: #GNUNET_NO (client is used to send and receive)
  338. * Inbound : #GNUNET_YES (server is used to send and receive)
  339. */
  340. int inbound;
  341. /**
  342. * Unique HTTP/S connection tag for this connection
  343. */
  344. uint32_t tag;
  345. /**
  346. * Client send handle
  347. */
  348. void *client_put;
  349. /**
  350. * Client receive handle
  351. */
  352. void *client_get;
  353. /**
  354. * Task to wake up client receive handle when receiving is allowed again
  355. */
  356. struct GNUNET_SCHEDULER_Task * recv_wakeup_task;
  357. /**
  358. * Session timeout task
  359. */
  360. struct GNUNET_SCHEDULER_Task * timeout_task;
  361. /**
  362. * Is client send handle paused since there are no data to send?
  363. * #GNUNET_YES or #GNUNET_NO
  364. */
  365. int client_put_paused;
  366. /**
  367. * Client send handle
  368. */
  369. struct ServerRequest *server_recv;
  370. /**
  371. * Client send handle
  372. */
  373. struct ServerRequest *server_send;
  374. };
  375. /**
  376. * Message to send using http
  377. */
  378. struct HTTP_Message
  379. {
  380. /**
  381. * next pointer for double linked list
  382. */
  383. struct HTTP_Message *next;
  384. /**
  385. * previous pointer for double linked list
  386. */
  387. struct HTTP_Message *prev;
  388. /**
  389. * buffer containing data to send
  390. */
  391. char *buf;
  392. /**
  393. * amount of data already sent
  394. */
  395. size_t pos;
  396. /**
  397. * buffer length
  398. */
  399. size_t size;
  400. /**
  401. * Continuation function to call once the transmission buffer
  402. * has again space available. NULL if there is no
  403. * continuation to call.
  404. */
  405. GNUNET_TRANSPORT_TransmitContinuation transmit_cont;
  406. /**
  407. * Closure for @e transmit_cont.
  408. */
  409. void *transmit_cont_cls;
  410. };
  411. struct Session *
  412. create_session (struct Plugin *plugin,
  413. const struct GNUNET_PeerIdentity *target,
  414. const void *addr,
  415. size_t addrlen);
  416. int
  417. exist_session (struct Plugin *plugin,
  418. struct Session *s);
  419. void
  420. delete_session (struct Session *s);
  421. int
  422. exist_session (struct Plugin *plugin,
  423. struct Session *s);
  424. struct GNUNET_TIME_Relative
  425. http_plugin_receive (void *cls,
  426. const struct GNUNET_PeerIdentity *peer,
  427. const struct GNUNET_MessageHeader *message,
  428. struct Session *session,
  429. const char *sender_address,
  430. uint16_t sender_address_len);
  431. const char *
  432. http_plugin_address_to_string (void *cls,
  433. const void *addr,
  434. size_t addrlen);
  435. int
  436. client_disconnect (struct Session *s);
  437. int
  438. client_connect (struct Session *s);
  439. int
  440. client_send (struct Session *s, struct HTTP_Message *msg);
  441. int
  442. client_start (struct Plugin *plugin);
  443. void
  444. client_stop (struct Plugin *plugin);
  445. int
  446. server_disconnect (struct Session *s);
  447. int
  448. server_send (struct Session *s, struct HTTP_Message *msg);
  449. int
  450. server_start (struct Plugin *plugin);
  451. void
  452. server_stop (struct Plugin *plugin);
  453. void
  454. notify_session_end (void *cls,
  455. const struct GNUNET_PeerIdentity *peer,
  456. struct Session *s);
  457. /*#ifndef PLUGIN_TRANSPORT_HTTP_H*/
  458. #endif
  459. /* end of plugin_transport_http.h */