GNUnet  0.10.x
gnunet-service-transport_plugins.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2010-2014 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your 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  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19 */
20 
26 #include "platform.h"
31 
35 struct TransportPlugin
36 {
40  struct TransportPlugin *next;
41 
45  struct TransportPlugin *prev;
46 
52 
56  char *short_name;
57 
61  char *lib_name;
62 
68 
69 };
70 
75 
80 
81 
90 static void
92  const struct GNUNET_HELLO_Address *address,
93  uint32_t distance)
94 {
95  GST_ats_update_distance (address,
96  distance);
97 }
98 
99 
109 static enum GNUNET_NetworkType
111  const struct sockaddr *addr,
112  size_t addrlen)
113 {
114  if (NULL == GST_is)
115  {
116  GNUNET_break(0);
117  return GNUNET_NT_UNSPECIFIED;
118  }
120  addr,
121  addrlen);
122 }
123 
124 
137 void
140  GNUNET_TRANSPORT_SessionStart session_start_cb,
141  GNUNET_TRANSPORT_SessionEnd session_end_cb)
142 {
143  struct TransportPlugin *plug;
144  struct TransportPlugin *next;
145  unsigned long long tneigh;
146  char *libname;
147  char *plugs;
148  char *pos;
149  int fail;
150 
151  if (GNUNET_OK !=
153  "TRANSPORT",
154  "NEIGHBOUR_LIMIT",
155  &tneigh))
156  {
158  _("Transport service is lacking NEIGHBOUR_LIMIT option.\n"));
159  return;
160  }
161  if (GNUNET_OK !=
163  "TRANSPORT",
164  "PLUGINS",
165  &plugs))
166  return;
168  _("Starting transport plugins `%s'\n"),
169  plugs);
170  for (pos = strtok (plugs, " "); pos != NULL; pos = strtok (NULL, " "))
171  {
173  _("Loading `%s' transport plugin\n"),
174  pos);
175  GNUNET_asprintf (&libname,
176  "libgnunet_plugin_transport_%s",
177  pos);
178  plug = GNUNET_new (struct TransportPlugin);
179  plug->short_name = GNUNET_strdup (pos);
180  plug->lib_name = libname;
181  plug->env.cfg = GST_cfg;
184  plug->env.cls = plug->short_name;
185  plug->env.receive = recv_cb;
186  plug->env.notify_address = address_cb;
187  plug->env.session_start = session_start_cb;
188  plug->env.session_end = session_end_cb;
191  plug->env.max_connections = tneigh;
192  plug->env.stats = GST_stats;
193  GNUNET_CONTAINER_DLL_insert (plugins_head,
194  plugins_tail,
195  plug);
196  }
197  GNUNET_free (plugs);
198  next = plugins_head;
199  while (NULL != next)
200  {
201  plug = next;
202  next = plug->next;
203  plug->api = GNUNET_PLUGIN_load (plug->lib_name,
204  &plug->env);
205  if (NULL == plug->api)
206  {
208  _("Failed to load transport plugin for `%s'\n"),
209  plug->lib_name);
210  GNUNET_CONTAINER_DLL_remove (plugins_head,
211  plugins_tail,
212  plug);
213  GNUNET_free (plug->short_name);
214  GNUNET_free (plug->lib_name);
215  GNUNET_free (plug);
216  continue;
217  }
218  fail = GNUNET_NO;
219  if (NULL == plug->api->address_pretty_printer)
220  {
221  fail = GNUNET_YES;
223  _("Missing function `%s' in transport plugin for `%s'\n"),
224  "address_pretty_printer",
225  plug->lib_name);
226  }
227  if (NULL == plug->api->address_to_string)
228  {
229  fail = GNUNET_YES;
231  _("Missing function `%s' in transport plugin for `%s'\n"),
232  "address_to_string",
233  plug->lib_name);
234  }
235  if (NULL == plug->api->string_to_address)
236  {
237  fail = GNUNET_YES;
239  _("Missing function `%s' in transport plugin for `%s'\n"),
240  "string_to_address",
241  plug->lib_name);
242  }
243  if (NULL == plug->api->check_address)
244  {
245  fail = GNUNET_YES;
247  _("Missing function `%s' in transport plugin for `%s'\n"),
248  "check_address",
249  plug->lib_name);
250  }
251  if (NULL == plug->api->get_session)
252  {
253  fail = GNUNET_YES;
255  _("Missing function `%s' in transport plugin for `%s'\n"),
256  "get_session",
257  plug->lib_name);
258  }
259  if (NULL == plug->api->get_network)
260  {
261  fail = GNUNET_YES;
263  _("Missing function `%s' in transport plugin for `%s'\n"),
264  "get_network",
265  plug->lib_name);
266  }
267  if (NULL == plug->api->send)
268  {
269  fail = GNUNET_YES;
271  _("Missing function `%s' in transport plugin for `%s'\n"),
272  "send",
273  plug->lib_name);
274  }
275  if (NULL == plug->api->disconnect_peer)
276  {
277  fail = GNUNET_YES;
279  _("Missing function `%s' in transport plugin for `%s'\n"),
280  "disconnect_peer",
281  plug->lib_name);
282  }
283  if (NULL == plug->api->disconnect_session)
284  {
285  fail = GNUNET_YES;
287  _("Missing function `%s' in transport plugin for `%s'\n"),
288  "disconnect_session",
289  plug->lib_name);
290  }
291  if (NULL == plug->api->query_keepalive_factor)
292  {
293  fail = GNUNET_YES;
295  _("Missing function `%s' in transport plugin for `%s'\n"),
296  "query_keepalive_factor",
297  plug->lib_name);
298  }
299  if (NULL == plug->api->update_session_timeout)
300  {
301  fail = GNUNET_YES;
303  _("Missing function `%s' in transport plugin for `%s'\n"),
304  "update_session_timeout",
305  plug->lib_name);
306  }
307  if (GNUNET_YES == fail)
308  {
310  _("Did not load plugin `%s' due to missing functions\n"),
311  plug->lib_name);
312  GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api));
313  GNUNET_CONTAINER_DLL_remove (plugins_head,
314  plugins_tail,
315  plug);
316  GNUNET_free (plug->short_name);
317  GNUNET_free (plug->lib_name);
318  GNUNET_free (plug);
319  }
320  }
321 }
322 
323 
327 void
329 {
330  struct TransportPlugin *plug;
331 
332  while (NULL != (plug = plugins_head))
333  {
334  GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api));
335  GNUNET_free (plug->lib_name);
336  GNUNET_free (plug->short_name);
337  GNUNET_CONTAINER_DLL_remove (plugins_head, plugins_tail, plug);
338  GNUNET_free (plug);
339  }
340 }
341 
342 
350 GST_plugins_find (const char *name)
351 {
352  struct TransportPlugin *pos;
353 
354  for (pos = plugins_head; NULL != pos; pos = pos->next)
355  if (0 == strcmp (name, pos->short_name))
356  break;
357  if (NULL == pos)
358  return NULL;
359  return pos->api;
360 }
361 
362 
375 {
376  struct TransportPlugin *pos;
377  char *stripped = GNUNET_strdup (name);
378  char *sep = strchr (stripped, '_');
379 
380  if (NULL != sep)
381  sep[0] = '\0';
382  for (pos = plugins_head; NULL != pos; pos = pos->next)
383  if (pos->short_name == strstr (pos->short_name, stripped))
384  break;
385  GNUNET_free (stripped);
386  if (NULL == pos)
387  return NULL;
388  return pos->api;
389 }
390 
391 
399 const char *
401 {
403  static char unable_to_show[1024];
404  static const char *s;
405 
406  if (NULL == address)
407  return "<NULL>";
408  if (0 == address->address_length)
409  return TRANSPORT_SESSION_INBOUND_STRING; /* Addresse with length 0 are inbound, address->address itself may be NULL */
410  api = GST_plugins_printer_find (address->transport_name);
411  if (NULL == api)
412  {
414  "Failed to find transport plugin `%s'\n",
415  address->transport_name);
416  return "<plugin unknown>";
417  }
418  if (0 == address->address_length)
419  {
420  GNUNET_snprintf (unable_to_show,
421  sizeof (unable_to_show),
422  "<unable to stringify %u-byte long address of %s transport>",
423  (unsigned int) address->address_length,
424  address->transport_name);
425  return unable_to_show;
426  }
427  return (NULL != (s = api->address_to_string (NULL,
428  address->address,
429  address->address_length))
430  ? s
431  : "<invalid>");
432 }
433 
434 
441 void
443  void *cb_cls)
444 {
445  struct TransportPlugin *pos;
446 
447  for (pos = plugins_head; NULL != pos; pos = pos->next)
448  if (NULL == pos->api->setup_monitor)
449  GNUNET_break (0);
450  else
451  pos->api->setup_monitor (pos->api->cls,
452  cb,
453  cb_cls);
454 }
455 
456 
457 /* end of file gnunet-service-transport_plugins.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static struct GNUNET_PeerIdentity GST_my_identity
Our public key.
size_t address_length
Number of bytes in address.
void(* GNUNET_TRANSPORT_SessionEnd)(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_ATS_Session *session)
Function that will be called whenever the plugin internally cleans up a session pointer and hence the...
enum GNUNET_NetworkType GNUNET_NT_scanner_get_type(struct GNUNET_NT_InterfaceScanner *is, const struct sockaddr *addr, socklen_t addrlen)
Returns where the address is located: loopback, LAN or WAN.
Definition: nt.c:303
char * short_name
Short name for the plugin (i.e.
GNUNET_TRANSPORT_CreateSession get_session
Function that will be called tell the plugin to create a session object.
struct TransportPlugin * prev
This is a doubly-linked list.
GNUNET_TRANSPORT_AddressToString address_to_string
Function that will be called to convert a binary address to a string (numeric conversion only)...
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
const void * address
Binary representation of the address (plugin-specific).
void(* GNUNET_TRANSPORT_AddressNotification)(void *cls, int add_remove, const struct GNUNET_HELLO_Address *address)
Function that will be called for each address the transport is aware that it might be reachable under...
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GST_plugins_monitor_subscribe(GNUNET_TRANSPORT_SessionInfoCallback cb, void *cb_cls)
Register callback with all plugins to monitor their status.
GNUNET_TRANSPORT_SessionStart session_start
Function called by the plugin when a new (incoming) session was created not explicitly created using ...
struct TransportPlugin * next
This is a doubly-linked list.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
void GST_plugins_load(GNUNET_TRANSPORT_PluginReceiveCallback recv_cb, GNUNET_TRANSPORT_AddressNotification address_cb, GNUNET_TRANSPORT_SessionStart session_start_cb, GNUNET_TRANSPORT_SessionEnd session_end_cb)
Load and initialize all plugins.
void GST_ats_update_distance(const struct GNUNET_HELLO_Address *address, uint32_t distance)
Notify ATS about DV distance change to an address.
GNUNET_TRANSPORT_TransmitFunction send
Function that the transport service will use to transmit data to another peer.
GNUNET_TRANSPORT_DisconnectPeerFunction disconnect_peer
Function that can be used to force the plugin to disconnect from the given peer and cancel all previo...
GNUNET_TRANSPORT_AddressToType get_address_type
Function that will be called to figure if an address is an loopback, LAN, WAN etc.
GNUNET_TRANSPORT_DisconnectSessionFunction disconnect_session
Function that can be used to force the plugin to disconnect from the given peer and cancel all previo...
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
GNUNET_TRANSPORT_SessionMonitorSetup setup_monitor
Function to monitor the sessions managed by the plugin.
const struct GNUNET_PeerIdentity * my_identity
Identity of this peer.
interfacing between transport and ATS service
#define TRANSPORT_SESSION_INBOUND_STRING
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static enum GNUNET_NetworkType plugin_env_address_to_type(void *cls, const struct sockaddr *addr, size_t addrlen)
Function that will be called to figure if an address is an loopback, LAN, WAN etc.
struct GNUNET_TRANSPORT_PluginFunctions * GST_plugins_printer_find(const char *name)
Obtain the plugin API based on a the stripped plugin name after the underscore.
uint32_t max_connections
What is the maximum number of connections that this transport should allow? Transports that do not ha...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:35
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static void plugin_env_update_distance(void *cls, const struct GNUNET_HELLO_Address *address, uint32_t distance)
Function that will be called to update metrics for an address.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
void * GNUNET_PLUGIN_unload(const char *library_name, void *arg)
Unload plugin (runs the "done" callback and returns whatever "done" returned).
Definition: plugin.c:258
static void address_cb(void *cls, void **app_ctx, int add_remove, enum GNUNET_NAT_AddressClass ac, const struct sockaddr *addr, socklen_t addrlen)
Signature of the callback passed to GNUNET_NAT_register() for a function to call whenever our set of ...
Definition: gnunet-nat.c:122
GNUNET_TRANSPORT_SessionEnd session_end
Function that must be called by the plugin when a non-NULL session handle stops being valid (is destr...
GNUNET_TRANSPORT_PluginReceiveCallback receive
Function that should be called by the transport plugin whenever a message is received.
GNUNET_TRANSPORT_UpdateSessionTimeout update_session_timeout
Function that will be called whenever the transport service wants to notify the plugin that a session...
struct GNUNET_NT_InterfaceScanner * GST_is
Interface scanner determines our LAN address range(s).
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
static struct GNUNET_STATISTICS_Handle * GST_stats
Statistics handle.
void * cls
Closure for the various callbacks.
void * cls
Closure for all of the callbacks.
static struct TransportPlugin * plugins_head
Head of DLL of all loaded plugins.
GNUNET_TRANSPORT_GetHelloCallback get_our_hello
Function that returns our HELLO.
GNUNET_TRANSPORT_StringToAddress string_to_address
Function that will be called to convert a string address to binary (numeric conversion only)...
struct GNUNET_TRANSPORT_PluginEnvironment env
Environment this transport service is using for this plugin.
The transport service will pass a pointer to a struct of this type as the first and only argument to ...
GNUNET_TRANSPORT_GetNetworkType get_network
Function to obtain the network type for a session.
struct GNUNET_TIME_Relative(* GNUNET_TRANSPORT_PluginReceiveCallback)(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_ATS_Session *session, const struct GNUNET_MessageHeader *message)
Function called by the transport for each received message.
const char * transport_name
Name of the transport plugin enabling the communication using this address.
static struct TransportPlugin * plugins_tail
Head of DLL of all loaded plugins.
void(* GNUNET_TRANSPORT_SessionInfoCallback)(void *cls, struct GNUNET_ATS_Session *session, const struct GNUNET_TRANSPORT_SessionInfo *info)
Function called by the plugin with information about the current sessions managed by the plugin (for ...
const char * GST_plugins_a2s(const struct GNUNET_HELLO_Address *address)
Convert a given address to a human-readable format.
struct GNUNET_TRANSPORT_PluginFunctions * GST_plugins_find(const char *name)
Obtain the plugin API based on a plugin name.
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
const char * name
char * lib_name
Name of the library (i.e.
GNUNET_TRANSPORT_UpdateAddressDistance update_address_distance
Function that will be called by DV to update distance for an address.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
const struct GNUNET_MessageHeader * GST_hello_get()
Obtain this peers HELLO message.
GNUNET_TRANSPORT_QueryKeepaliveFactorFunction query_keepalive_factor
Function that is used to query keepalive factor.
Entry in doubly-linked list of all of our plugins.
struct GNUNET_TRANSPORT_PluginFunctions * api
API of the transport as returned by the plugin&#39;s initialization function.
void GST_plugins_unload()
Unload all plugins.
An address for communicating with a peer.
struct GNUNET_STATISTICS_Handle * stats
Handle for reporting statistics.
#define GNUNET_log(kind,...)
GNUNET_TRANSPORT_AddressNotification notify_address
Function that must be called by each plugin to notify the transport service about the addresses under...
GNUNET_TRANSPORT_AddressPrettyPrinter address_pretty_printer
Function to pretty-print addresses.
#define GNUNET_YES
Definition: gnunet_common.h:80
static const struct GNUNET_CONFIGURATION_Handle * GST_cfg
Configuration handle.
void * GNUNET_PLUGIN_load(const char *library_name, void *arg)
Setup plugin (runs the "init" callback and returns whatever "init" returned).
Definition: plugin.c:210
void(* GNUNET_TRANSPORT_SessionStart)(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_ATS_Session *session, enum GNUNET_NetworkType net)
Plugin tells transport service about a new inbound session.
GNUNET_TRANSPORT_CheckAddress check_address
Function that will be called to check if a binary address for this plugin is well-formed and correspo...
static char * address
GNS address for this phone.
#define GNUNET_free(ptr)
Wrapper around free.
Category of last resort.
Definition: gnunet_nt_lib.h:40