Check that you are not present in trail twice
[oweals/gnunet.git] / src / transport / plugin_transport_http.h
index 84af33a59a1f29ec054f081e43d88f60e91ac7aa..ae0c784eef230b7311bf1fd87ee564f12a15bbe3 100644 (file)
@@ -23,6 +23,8 @@
  * @brief http transport service plugin
  * @author Matthias Wachs
  */
+#ifndef PLUGIN_TRANSPORT_HTTP_H
+#define PLUGIN_TRANSPORT_HTTP_H
 
 #include "platform.h"
 #include "gnunet_common.h"
 #include <curl/curl.h>
 
 
-#define DEBUG_HTTP GNUNET_YES
-#define VERBOSE_SERVER GNUNET_YES
-#define VERBOSE_CLIENT GNUNET_YES
+#define DEBUG_HTTP GNUNET_EXTRA_LOGGING
+#define VERBOSE_SERVER GNUNET_EXTRA_LOGGING
+#define VERBOSE_CLIENT GNUNET_EXTRA_LOGGING
+#define VERBOSE_CURL GNUNET_NO
 
 #if BUILD_HTTPS
 #define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_https_init
 #define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_http_done
 #endif
 
+#define INBOUND  GNUNET_YES
+#define OUTBOUND GNUNET_NO
 
-#define HTTP_NOT_VALIDATED_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
+
+#define HTTP_NOT_VALIDATED_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
 
 /**
  * Encapsulation of all of the state of the plugin.
  */
 struct Plugin
 {
+  /**
+   * General handles
+   * ---------------
+   */
+
   /**
    * Our environment.
    */
   struct GNUNET_TRANSPORT_PluginEnvironment *env;
 
   /**
-   * List of open sessions.
+   * Linked list of open sessions.
    */
+
   struct Session *head;
 
   struct Session *tail;
@@ -80,52 +92,195 @@ struct Plugin
   struct GNUNET_NAT_Handle *nat;
 
   /**
-   * ipv4 DLL head
+   * List of own addresses
    */
-  struct IPv4HttpAddressWrapper *ipv4_addr_head;
 
   /**
-   * ipv4 DLL tail
+   * IPv4 addresses DLL head
    */
-  struct IPv4HttpAddressWrapper *ipv4_addr_tail;
+  struct HttpAddressWrapper *addr_head;
 
   /**
-   * ipv6 DLL head
+   * IPv4 addresses DLL tail
    */
-  struct IPv6HttpAddressWrapper *ipv6_addr_head;
+  struct HttpAddressWrapper *addr_tail;
+
 
   /**
-   * ipv6 DLL tail
+   * Plugin configuration
+   * --------------------
    */
-  struct IPv6HttpAddressWrapper *ipv6_addr_tail;
 
+  /**
+   * External hostname the plugin can be connected to, can be different to
+   * the host's FQDN, used e.g. for reverse proxying
+   */
+  char *external_hostname;
 
-  /* Plugin configuration */
+  /**
+   * External hostname the plugin can be connected to, can be different to
+   * the host's FQDN, used e.g. for reverse proxying
+   */
+  struct HttpAddress *ext_addr;
 
+  /**
+   * External address length
+   */
+  size_t ext_addr_len;
+
+  /**
+   * Task calling transport service about external address
+   */
+  GNUNET_SCHEDULER_TaskIdentifier notify_ext_task;
+
+
+  /**
+   * Plugin name
+   * Equals configuration section: transport-http, transport-https
+   */
   char *name;
 
+  /**
+   * Plugin protocol
+   * http, https
+   */
   char *protocol;
 
+  /**
+   * Use IPv4?
+   * GNUNET_YES or GNUNET_NO
+   */
   int ipv4;
 
+  /**
+   * Use IPv6?
+   * GNUNET_YES or GNUNET_NO
+   */
   int ipv6;
 
+  /**
+   * Does plugin just use outbound connections and not accept inbound?
+   */
+
+  int client_only;
+
+  /**
+   * Port used
+   */
   uint16_t port;
 
+  /**
+   * Maximum number of sockets the plugin can use
+   * Each http inbound /outbound connections are two connections
+   */
   int max_connections;
 
-  /*
-   * Server handles
+  /**
+   * Number of outbound sessions
    */
+  unsigned int outbound_sessions;
 
-  struct MHD_Daemon *server_v4;
+  /**
+   * Number of inbound sessions
+   */
+  unsigned int inbound_sessions;
 
-  struct MHD_Daemon *server_v6;
+  /**
+   * Plugin HTTPS SSL/TLS options
+   * ----------------------------
+   */
 
+  /**
+   * libCurl TLS crypto init string, can be set to enhance performance
+   *
+   * Example:
+   *
+   * Use RC4-128 instead of AES:
+   * NONE:+VERS-TLS1.0:+ARCFOUR-128:+SHA1:+RSA:+COMP-NULL
+   *
+   */
   char *crypto_init;
+
+  /**
+   * TLS key
+   */
   char *key;
+
+  /**
+   * TLS certificate
+   */
   char *cert;
 
+  /**
+   * Plugin values
+   * -------------
+   */
+
+  /**
+   * Current number of establishes connections
+   */
+  int cur_connections;
+
+  /**
+   * Last used unique HTTP connection tag
+   */
+  uint32_t last_tag;
+
+  /**
+   * Server handles
+   * --------------
+   */
+
+  /**
+   * MHD IPv4 daemon
+   */
+  struct MHD_Daemon *server_v4;
+
+  /**
+   * MHD IPv4 task
+   */
+  GNUNET_SCHEDULER_TaskIdentifier server_v4_task;
+
+  /**
+   * The IPv4 server is scheduled to run asap
+   */
+  int server_v4_immediately;
+
+  /**
+   * MHD IPv6 daemon
+   */
+  struct MHD_Daemon *server_v6;
+
+  /**
+   * MHD IPv4 task
+   */
+  GNUNET_SCHEDULER_TaskIdentifier server_v6_task;
+
+  /**
+   * The IPv6 server is scheduled to run asap
+   */
+
+  int server_v6_immediately;
+
+  /**
+   * IPv4 server socket to bind to
+   */
+  struct sockaddr_in *server_addr_v4;
+
+  /**
+   * IPv6 server socket to bind to
+   */
+  struct sockaddr_in6 *server_addr_v6;
+
+  /**
+   * Server semi connections
+   * A full session consists of 2 semi-connections: send and receive
+   * If not both directions are established the server keeps this sessions here
+   */
+  struct Session *server_semi_head;
+
+  struct Session *server_semi_tail;
+
   /*
    * Client handles
    */
@@ -135,13 +290,91 @@ struct Plugin
    */
   CURLM *client_mh;
 
+  /**
+   * curl perform task
+   */
+  GNUNET_SCHEDULER_TaskIdentifier client_perform_task;
+
+};
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * HTTP addresses including a full URI
+ */
+struct HttpAddress
+{
+  /**
+   * Length of the address following in NBO
+   */
+  uint32_t addr_len GNUNET_PACKED;
+
+  /**
+   * Address following
+   */
+  void *addr GNUNET_PACKED;
 };
 
+/**
+ * IPv4 addresses
+ */
+struct IPv4HttpAddress
+{
+  /**
+   * IPv4 address, in network byte order.
+   */
+  uint32_t ipv4_addr GNUNET_PACKED;
+
+  /**
+   * Port number, in network byte order.
+   */
+  uint16_t u4_port GNUNET_PACKED;
+};
+
+/**
+ * IPv4 addresses
+ */
+struct IPv6HttpAddress
+{
+  /**
+   * IPv6 address.
+   */
+  struct in6_addr ipv6_addr GNUNET_PACKED;
+
+  /**
+   * Port number, in network byte order.
+   */
+  uint16_t u6_port GNUNET_PACKED;
+};
+GNUNET_NETWORK_STRUCT_END
+
+
+struct ServerRequest
+{
+  /* _RECV or _SEND */
+  int direction;
+
+  /* Should this connection get disconnected? GNUNET_YES/NO  */
+  int disconnect;
+
+  /* The session this server connection belongs to */
+  struct Session *session;
+
+  /* The MHD connection */
+  struct MHD_Connection *mhd_conn;
+};
+
+
+
 /**
  * Session handle for connections.
  */
 struct Session
 {
+  /**
+   * To whom are we talking to
+   */
+  struct GNUNET_PeerIdentity target;
 
   /**
    * Stored in a linked list.
@@ -159,59 +392,161 @@ struct Session
   struct Plugin *plugin;
 
   /**
-   * The client (used to identify this connection)
+   * Address
    */
-  /* void *client; */
+  void *addr;
 
   /**
-   * Continuation function to call once the transmission buffer
-   * has again space available.  NULL if there is no
-   * continuation to call.
+   * Address length
    */
-  GNUNET_TRANSPORT_TransmitContinuation transmit_cont;
-
-
-  void *addr;
-
   size_t addrlen;
 
   /**
-   * Closure for transmit_cont.
+   * ATS network type in NBO
    */
-  void *transmit_cont_cls;
+  uint32_t ats_address_network_type;
 
   /**
-   * To whom are we talking to (set to our identity
-   * if we are still waiting for the welcome message)
+   * next pointer for double linked list
    */
-  struct GNUNET_PeerIdentity target;
+  struct HTTP_Message *msg_head;
 
   /**
-   * At what time did we reset last_received last?
+   * previous pointer for double linked list
    */
-  //struct GNUNET_TIME_Absolute last_quota_update;
+  struct HTTP_Message *msg_tail;
+
 
   /**
-   * How many bytes have we received since the "last_quota_update"
-   * timestamp?
+   * Message stream tokenizer for incoming data
    */
-  //uint64_t last_received;
+  struct GNUNET_SERVER_MessageStreamTokenizer *msg_tk;
 
   /**
-   * Number of bytes per ms that this peer is allowed
-   * to send to us.
+   * Absolute time when to receive data again
+   * Used for receive throttling
    */
-  //uint32_t quota;
-
+  struct GNUNET_TIME_Absolute next_receive;
 
+  /**
+   * Inbound or outbound connection
+   * Outbound: GNUNET_NO (client is used to send and receive)
+   * Inbound : GNUNET_YES (server is used to send and receive)
+   */
   int inbound;
 
+  /**
+   * Unique HTTP/S connection tag for this connection
+   */
+  uint32_t tag;
+
+  /**
+   * Client handles
+   */
+
+  /**
+   * Client send handle
+   */
   void *client_put;
+
+  /**
+   * Client receive handle
+   */
   void *client_get;
 
+  /**
+   * Task to wake up client receive handle when receiving is allowed again
+   */
+  GNUNET_SCHEDULER_TaskIdentifier recv_wakeup_task;
 
+  /**
+   * Session timeout task
+   */
+  GNUNET_SCHEDULER_TaskIdentifier timeout_task;
+
+  /**
+   * Is client send handle paused since there are no data to send?
+   * GNUNET_YES/NO
+   */
+  int client_put_paused;
+
+  /**
+   * Server handles
+   */
+
+  /**
+   * Client send handle
+   */
+  struct ServerRequest *server_recv;
+
+  /**
+   * Client send handle
+   */
+  struct ServerRequest *server_send;
+};
+
+/**
+ *  Message to send using http
+ */
+struct HTTP_Message
+{
+  /**
+   * next pointer for double linked list
+   */
+  struct HTTP_Message *next;
+
+  /**
+   * previous pointer for double linked list
+   */
+  struct HTTP_Message *prev;
+
+  /**
+   * buffer containing data to send
+   */
+  char *buf;
+
+  /**
+   * amount of data already sent
+   */
+  size_t pos;
+
+  /**
+   * buffer length
+   */
+  size_t size;
+
+  /**
+   * Continuation function to call once the transmission buffer
+   * has again space available.  NULL if there is no
+   * continuation to call.
+   */
+  GNUNET_TRANSPORT_TransmitContinuation transmit_cont;
+
+  /**
+   * Closure for transmit_cont.
+   */
+  void *transmit_cont_cls;
 };
 
+struct Session *
+create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
+                const void *addr, size_t addrlen);
+
+int
+exist_session (struct Plugin *plugin, struct Session *s);
+
+void
+delete_session (struct Session *s);
+
+int
+exist_session (struct Plugin *plugin, struct Session *s);
+
+struct GNUNET_TIME_Relative
+http_plugin_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
+                     const struct GNUNET_MessageHeader *message,
+                     struct Session *session, const char *sender_address,
+                     uint16_t sender_address_len);
+
 const char *
 http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen);
 
@@ -222,7 +557,7 @@ int
 client_connect (struct Session *s);
 
 int
-client_send (struct Session *s, const char *msgbuf, size_t msgbuf_size);
+client_send (struct Session *s, struct HTTP_Message *msg);
 
 int
 client_start (struct Plugin *plugin);
@@ -234,7 +569,7 @@ int
 server_disconnect (struct Session *s);
 
 int
-server_send (struct Session *s, const char *msgbuf, size_t msgbuf_size);
+server_send (struct Session *s, struct HTTP_Message *msg);
 
 int
 server_start (struct Plugin *plugin);
@@ -242,4 +577,10 @@ server_start (struct Plugin *plugin);
 void
 server_stop (struct Plugin *plugin);
 
+void
+notify_session_end (void *cls, const struct GNUNET_PeerIdentity *peer,
+                    struct Session *s);
+
+/*#ifndef PLUGIN_TRANSPORT_HTTP_H*/
+#endif
 /* end of plugin_transport_http.h */