changes
[oweals/gnunet.git] / src / transport / plugin_transport_http_client.c
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_client.c
23  * @brief HTTP/S client transport plugin
24  * @author Matthias Wachs
25  */
26
27 #if BUILD_HTTPS
28 #define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_https_client_init
29 #define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_https_client_done
30 #else
31 #define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_http_client_init
32 #define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_http_client_done
33 #endif
34
35
36 #include "platform.h"
37 #include "gnunet_protocols.h"
38 #include "gnunet_connection_lib.h"
39 #include "gnunet_server_lib.h"
40 #include "gnunet_service_lib.h"
41 #include "gnunet_statistics_service.h"
42 #include "gnunet_transport_service.h"
43 #include "gnunet_transport_plugin.h"
44
45 #define DEBUG_TEMPLATE GNUNET_EXTRA_LOGGING
46
47 /**
48  * After how long do we expire an address that we
49  * learned from another peer if it is not reconfirmed
50  * by anyone?
51  */
52 #define LEARNED_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 6)
53
54
55 /**
56  * Encapsulation of all of the state of the plugin.
57  */
58 struct HTTP_Client_Plugin;
59
60
61 /**
62  * Session handle for connections.
63  */
64 struct Session
65 {
66   /**
67    * To whom are we talking to (set to our identity
68    * if we are still waiting for the welcome message)
69    */
70   struct GNUNET_PeerIdentity sender;
71
72   /**
73    * Stored in a linked list.
74    */
75   struct Session *next;
76
77   /**
78    * Pointer to the global plugin struct.
79    */
80   struct HTTP_Client_Plugin *plugin;
81
82   /**
83    * The client (used to identify this connection)
84    */
85   /* void *client; */
86
87   /**
88    * Continuation function to call once the transmission buffer
89    * has again space available.  NULL if there is no
90    * continuation to call.
91    */
92   GNUNET_TRANSPORT_TransmitContinuation transmit_cont;
93
94   /**
95    * Closure for transmit_cont.
96    */
97   void *transmit_cont_cls;
98
99   /**
100    * At what time did we reset last_received last?
101    */
102   struct GNUNET_TIME_Absolute last_quota_update;
103
104   /**
105    * How many bytes have we received since the "last_quota_update"
106    * timestamp?
107    */
108   uint64_t last_received;
109
110   /**
111    * Number of bytes per ms that this peer is allowed
112    * to send to us.
113    */
114   uint32_t quota;
115
116 };
117
118 /**
119  * Encapsulation of all of the state of the plugin.
120  */
121 struct HTTP_Client_Plugin
122 {
123   /**
124    * Our environment.
125    */
126   struct GNUNET_TRANSPORT_PluginEnvironment *env;
127
128   /**
129    * List of open sessions.
130    */
131   struct Session *sessions;
132
133 };
134
135
136 /**
137  * Function that can be used by the transport service to transmit
138  * a message using the plugin.   Note that in the case of a
139  * peer disconnecting, the continuation MUST be called
140  * prior to the disconnect notification itself.  This function
141  * will be called with this peer's HELLO message to initiate
142  * a fresh connection to another peer.
143  *
144  * @param cls closure
145  * @param session which session must be used
146  * @param msgbuf the message to transmit
147  * @param msgbuf_size number of bytes in 'msgbuf'
148  * @param priority how important is the message (most plugins will
149  *                 ignore message priority and just FIFO)
150  * @param to how long to wait at most for the transmission (does not
151  *                require plugins to discard the message after the timeout,
152  *                just advisory for the desired delay; most plugins will ignore
153  *                this as well)
154  * @param cont continuation to call once the message has
155  *        been transmitted (or if the transport is ready
156  *        for the next transmission call; or if the
157  *        peer disconnected...); can be NULL
158  * @param cont_cls closure for cont
159  * @return number of bytes used (on the physical network, with overheads);
160  *         -1 on hard errors (i.e. address invalid); 0 is a legal value
161  *         and does NOT mean that the message was not transmitted (DV)
162  */
163 static ssize_t
164 http_client_plugin_send (void *cls,
165                   struct Session *session,
166                   const char *msgbuf, size_t msgbuf_size,
167                   unsigned int priority,
168                   struct GNUNET_TIME_Relative to,
169                   GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
170 {
171   struct HTTP_Client_Plugin *plugin = cls;
172   int bytes_sent = 0;
173
174   GNUNET_assert (plugin != NULL);
175   GNUNET_assert (session != NULL);
176
177   /*  struct Plugin *plugin = cls; */
178   return bytes_sent;
179 }
180
181
182
183 /**
184  * Function that can be used to force the plugin to disconnect
185  * from the given peer and cancel all previous transmissions
186  * (and their continuationc).
187  *
188  * @param cls closure
189  * @param target peer from which to disconnect
190  */
191 static void
192 http_client_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
193 {
194   // struct Plugin *plugin = cls;
195   // FIXME
196 }
197
198
199 /**
200  * Convert the transports address to a nice, human-readable
201  * format.
202  *
203  * @param cls closure
204  * @param type name of the transport that generated the address
205  * @param addr one of the addresses of the host, NULL for the last address
206  *        the specific address format depends on the transport
207  * @param addrlen length of the address
208  * @param numeric should (IP) addresses be displayed in numeric form?
209  * @param timeout after how long should we give up?
210  * @param asc function to call on each string
211  * @param asc_cls closure for asc
212  */
213 static void
214 http_client_plugin_address_pretty_printer (void *cls, const char *type,
215                                         const void *addr, size_t addrlen,
216                                         int numeric,
217                                         struct GNUNET_TIME_Relative timeout,
218                                         GNUNET_TRANSPORT_AddressStringCallback
219                                         asc, void *asc_cls)
220 {
221   asc (asc_cls, NULL);
222 }
223
224
225
226 /**
227  * Another peer has suggested an address for this
228  * peer and transport plugin.  Check that this could be a valid
229  * address.  If so, consider adding it to the list
230  * of addresses.
231  *
232  * @param cls closure
233  * @param addr pointer to the address
234  * @param addrlen length of addr
235  * @return GNUNET_OK if this is a plausible address for this peer
236  *         and transport
237  */
238 static int
239 http_client_plugin_address_suggested (void *cls, const void *addr, size_t addrlen)
240 {
241   /* struct Plugin *plugin = cls; */
242
243   /* check if the address is plausible; if so,
244    * add it to our list! */
245   return GNUNET_OK;
246 }
247
248
249 /**
250  * Function called for a quick conversion of the binary address to
251  * a numeric address.  Note that the caller must not free the
252  * address and that the next call to this function is allowed
253  * to override the address again.
254  *
255  * @param cls closure
256  * @param addr binary address
257  * @param addrlen length of the address
258  * @return string representing the same address
259  */
260 static const char *
261 http_client_plugin_address_to_string (void *cls, const void *addr, size_t addrlen)
262 {
263   GNUNET_break (0);
264   return NULL;
265 }
266
267
268
269
270 /**
271  * Entry point for the plugin.
272  */
273 void *
274 LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls)
275 {
276   struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
277   struct GNUNET_TRANSPORT_PluginFunctions *api;
278   struct HTTP_Client_Plugin *plugin;
279
280   plugin = GNUNET_malloc (sizeof (struct HTTP_Client_Plugin));
281   plugin->env = env;
282   api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
283   api->cls = plugin;
284   api->send = &http_client_plugin_send;
285   api->disconnect = &http_client_plugin_disconnect;
286   api->address_pretty_printer = &http_client_plugin_address_pretty_printer;
287   api->check_address = &http_client_plugin_address_suggested;
288   api->address_to_string = &http_client_plugin_address_to_string;
289   return api;
290 }
291
292
293 /**
294  * Exit point from the plugin.
295  */
296 void *
297 LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls)
298 {
299   struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
300   struct HTTP_Client_Plugin *plugin = api->cls;
301
302   GNUNET_free (plugin);
303   GNUNET_free (api);
304   return NULL;
305 }
306
307 /* end of plugin_transport_http_client.c */