- fix error messages
[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_util_lib.h"
29 #include "gnunet_protocols.h"
30 #include "gnunet_statistics_service.h"
31 #include "gnunet_transport_service.h"
32 #include "gnunet_transport_plugin.h"
33
34 #define LOG(kind,...) GNUNET_log_from (kind, "transport-template",__VA_ARGS__)
35
36 /**
37  * After how long do we expire an address that we
38  * learned from another peer if it is not reconfirmed
39  * by anyone?
40  */
41 #define LEARNED_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 6)
42
43 #define PLUGIN_NAME "template"
44
45 /**
46  * Encapsulation of all of the state of the plugin.
47  */
48 struct Plugin;
49
50
51 /**
52  * Session handle for connections.
53  */
54 struct Session
55 {
56   /**
57    * To whom are we talking to (set to our identity
58    * if we are still waiting for the welcome message)
59    */
60   struct GNUNET_PeerIdentity sender;
61
62   /**
63    * Stored in a linked list.
64    */
65   struct Session *next;
66
67   /**
68    * Pointer to the global plugin struct.
69    */
70   struct Plugin *plugin;
71
72   /**
73    * The client (used to identify this connection)
74    */
75   /* void *client; */
76
77   /**
78    * Continuation function to call once the transmission buffer
79    * has again space available.  NULL if there is no
80    * continuation to call.
81    */
82   GNUNET_TRANSPORT_TransmitContinuation transmit_cont;
83
84   /**
85    * Closure for transmit_cont.
86    */
87   void *transmit_cont_cls;
88
89   /**
90    * At what time did we reset last_received last?
91    */
92   struct GNUNET_TIME_Absolute last_quota_update;
93
94   /**
95    * How many bytes have we received since the "last_quota_update"
96    * timestamp?
97    */
98   uint64_t last_received;
99
100   /**
101    * Number of bytes per ms that this peer is allowed
102    * to send to us.
103    */
104   uint32_t quota;
105
106 };
107
108 GNUNET_NETWORK_STRUCT_BEGIN
109
110 struct TemplateAddress
111 {
112         /**
113          * Address options in NBO
114          */
115         uint32_t options GNUNET_PACKED;
116
117         /* Add address here */
118 };
119
120 GNUNET_NETWORK_STRUCT_END
121
122 /**
123  * Encapsulation of all of the state of the plugin.
124  */
125 struct Plugin
126 {
127   /**
128    * Our environment.
129    */
130   struct GNUNET_TRANSPORT_PluginEnvironment *env;
131
132   /**
133    * List of open sessions.
134    */
135   struct Session *sessions;
136
137   /**
138    * Options in HBO to be used with addresses
139    */
140
141 };
142
143
144 /**
145  * Function that can be used by the transport service to transmit
146  * a message using the plugin.   Note that in the case of a
147  * peer disconnecting, the continuation MUST be called
148  * prior to the disconnect notification itself.  This function
149  * will be called with this peer's HELLO message to initiate
150  * a fresh connection to another peer.
151  *
152  * @param cls closure
153  * @param session which session must be used
154  * @param msgbuf the message to transmit
155  * @param msgbuf_size number of bytes in @a msgbuf
156  * @param priority how important is the message (most plugins will
157  *                 ignore message priority and just FIFO)
158  * @param to how long to wait at most for the transmission (does not
159  *                require plugins to discard the message after the timeout,
160  *                just advisory for the desired delay; most plugins will ignore
161  *                this as well)
162  * @param cont continuation to call once the message has
163  *        been transmitted (or if the transport is ready
164  *        for the next transmission call; or if the
165  *        peer disconnected...); can be NULL
166  * @param cont_cls closure for @a cont
167  * @return number of bytes used (on the physical network, with overheads);
168  *         -1 on hard errors (i.e. address invalid); 0 is a legal value
169  *         and does NOT mean that the message was not transmitted (DV)
170  */
171 static ssize_t
172 template_plugin_send (void *cls,
173                   struct Session *session,
174                   const char *msgbuf, size_t msgbuf_size,
175                   unsigned int priority,
176                   struct GNUNET_TIME_Relative to,
177                   GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
178 {
179   struct Plugin *plugin = cls;
180   int bytes_sent = 0;
181
182   GNUNET_assert (plugin != NULL);
183   GNUNET_assert (session != NULL);
184
185   /*  struct Plugin *plugin = cls; */
186   return bytes_sent;
187 }
188
189
190 /**
191  * Function that can be used to force the plugin to disconnect
192  * from the given peer and cancel all previous transmissions
193  * (and their continuationc).
194  *
195  * @param cls closure
196  * @param target peer from which to disconnect
197  */
198 static void
199 template_plugin_disconnect_peer (void *cls,
200                                  const struct GNUNET_PeerIdentity *target)
201 {
202   // struct Plugin *plugin = cls;
203   // FIXME
204 }
205
206
207 /**
208  * Function that can be used to force the plugin to disconnect
209  * from the given peer and cancel all previous transmissions
210  * (and their continuationc).
211  *
212  * @param cls closure
213  * @param session session from which to disconnect
214  * @return #GNUNET_OK on success
215  */
216 static int
217 template_plugin_disconnect_session (void *cls,
218                                     struct Session *session)
219 {
220   // struct Plugin *plugin = cls;
221   // FIXME
222   return GNUNET_SYSERR;
223 }
224
225
226 /**
227  * Function that is called to get the keepalive factor.
228  * GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT is divided by this number to
229  * calculate the interval between keepalive packets.
230  *
231  * @param cls closure with the `struct Plugin`
232  * @return keepalive factor
233  */
234 static unsigned int
235 template_plugin_query_keepalive_factor (void *cls)
236 {
237   return 3;
238 }
239
240
241 /**
242  * Function obtain the network type for a session
243  *
244  * @param cls closure ('struct Plugin*')
245  * @param session the session
246  * @return the network type in HBO or GNUNET_SYSERR
247  */
248 static enum GNUNET_ATS_Network_Type
249 template_plugin_get_network (void *cls,
250                              struct Session *session)
251 {
252   GNUNET_assert (NULL != session);
253   return GNUNET_ATS_NET_UNSPECIFIED; /* Change to correct network type */
254 }
255
256
257 /**
258  * Convert the transports address to a nice, human-readable
259  * format.
260  *
261  * @param cls closure
262  * @param type name of the transport that generated the address
263  * @param addr one of the addresses of the host, NULL for the last address
264  *        the specific address format depends on the transport
265  * @param addrlen length of the address
266  * @param numeric should (IP) addresses be displayed in numeric form?
267  * @param timeout after how long should we give up?
268  * @param asc function to call on each string
269  * @param asc_cls closure for asc
270  */
271 static void
272 template_plugin_address_pretty_printer (void *cls, const char *type,
273                                         const void *addr, size_t addrlen,
274                                         int numeric,
275                                         struct GNUNET_TIME_Relative timeout,
276                                         GNUNET_TRANSPORT_AddressStringCallback
277                                         asc, void *asc_cls)
278 {
279   if (0 == addrlen)
280   {
281     asc (asc_cls, TRANSPORT_SESSION_INBOUND_STRING);
282   }
283   asc (asc_cls, NULL);
284 }
285
286
287
288 /**
289  * Another peer has suggested an address for this
290  * peer and transport plugin.  Check that this could be a valid
291  * address.  If so, consider adding it to the list
292  * of addresses.
293  *
294  * @param cls closure
295  * @param addr pointer to the address
296  * @param addrlen length of addr
297  * @return #GNUNET_OK if this is a plausible address for this peer
298  *         and transport
299  */
300 static int
301 template_plugin_address_suggested (void *cls, const void *addr, size_t addrlen)
302 {
303   /* struct Plugin *plugin = cls; */
304
305   /* check if the address is belonging to the plugin*/
306   return GNUNET_OK;
307 }
308
309
310 /**
311  * Function called for a quick conversion of the binary address to
312  * a numeric address.  Note that the caller must not free the
313  * address and that the next call to this function is allowed
314  * to override the address again.
315  *
316  * @param cls closure
317  * @param addr binary address
318  * @param addrlen length of the address
319  * @return string representing the same address
320  */
321 static const char *
322 template_plugin_address_to_string (void *cls, const void *addr, size_t addrlen)
323 {
324   /*
325    * Print address in format template.options.address
326    */
327
328   if (0 == addrlen)
329   {
330     return TRANSPORT_SESSION_INBOUND_STRING;
331   }
332
333   GNUNET_break (0);
334   return NULL;
335 }
336
337
338 /**
339  * Function called to convert a string address to
340  * a binary address.
341  *
342  * @param cls closure ('struct Plugin*')
343  * @param addr string address
344  * @param addrlen length of the @a addr
345  * @param buf location to store the buffer
346  * @param added location to store the number of bytes in the buffer.
347  *        If the function returns #GNUNET_SYSERR, its contents are undefined.
348  * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
349  */
350 static int
351 template_plugin_string_to_address (void *cls,
352                                    const char *addr,
353                                    uint16_t addrlen,
354                                    void **buf, size_t *added)
355 {
356   /*
357    * Parse string in format template.options.address
358    */
359   GNUNET_break (0);
360   return GNUNET_SYSERR;
361 }
362
363
364 /**
365  * Create a new session to transmit data to the target
366  * This session will used to send data to this peer and the plugin will
367  * notify us by calling the env->session_end function
368  *
369  * @param cls closure
370  * @param address pointer to the GNUNET_HELLO_Address
371  * @return the session if the address is valid, NULL otherwise
372  */
373 static struct Session *
374 template_plugin_get_session (void *cls,
375                         const struct GNUNET_HELLO_Address *address)
376 {
377   GNUNET_break (0);
378   return NULL;
379 }
380
381 static void
382 template_plugin_update_session_timeout (void *cls,
383                                   const struct GNUNET_PeerIdentity *peer,
384                                   struct Session *session)
385 {
386
387 }
388
389 /**
390  * Entry point for the plugin.
391  */
392 void *
393 libgnunet_plugin_transport_template_init (void *cls)
394 {
395   struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
396   struct GNUNET_TRANSPORT_PluginFunctions *api;
397   struct Plugin *plugin;
398
399   if (NULL == env->receive)
400   {
401     /* run in 'stub' mode (i.e. as part of gnunet-peerinfo), don't fully
402        initialze the plugin or the API */
403     api = GNUNET_new (struct GNUNET_TRANSPORT_PluginFunctions);
404     api->cls = NULL;
405     api->address_to_string = &template_plugin_address_to_string;
406     api->string_to_address = &template_plugin_string_to_address;
407     api->address_pretty_printer = &template_plugin_address_pretty_printer;
408     return api;
409   }
410
411   plugin = GNUNET_new (struct Plugin);
412   plugin->env = env;
413   api = GNUNET_new (struct GNUNET_TRANSPORT_PluginFunctions);
414   api->cls = plugin;
415   api->send = &template_plugin_send;
416   api->disconnect_peer = &template_plugin_disconnect_peer;
417   api->disconnect_session = &template_plugin_disconnect_session;
418   api->query_keepalive_factor = &template_plugin_query_keepalive_factor;
419   api->address_pretty_printer = &template_plugin_address_pretty_printer;
420   api->check_address = &template_plugin_address_suggested;
421   api->address_to_string = &template_plugin_address_to_string;
422   api->string_to_address = &template_plugin_string_to_address;
423   api->get_session = &template_plugin_get_session;
424   api->get_network = &template_plugin_get_network;
425   api->update_session_timeout = &template_plugin_update_session_timeout;
426   LOG (GNUNET_ERROR_TYPE_INFO, "Template plugin successfully loaded\n");
427   return api;
428 }
429
430
431 /**
432  * Exit point from the plugin.
433  */
434 void *
435 libgnunet_plugin_transport_template_done (void *cls)
436 {
437   struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
438   struct Plugin *plugin = api->cls;
439
440   GNUNET_free (plugin);
441   GNUNET_free (api);
442   return NULL;
443 }
444
445 /* end of plugin_transport_template.c */