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