aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-transport_plugins.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-service-transport_plugins.c')
-rw-r--r--src/transport/gnunet-service-transport_plugins.c437
1 files changed, 0 insertions, 437 deletions
diff --git a/src/transport/gnunet-service-transport_plugins.c b/src/transport/gnunet-service-transport_plugins.c
deleted file mode 100644
index 218ef80ab..000000000
--- a/src/transport/gnunet-service-transport_plugins.c
+++ /dev/null
@@ -1,437 +0,0 @@
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
21/**
22 * @file transport/gnunet-service-transport_plugins.c
23 * @brief plugin management
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet-service-transport.h"
28#include "gnunet-service-transport_hello.h"
29#include "gnunet-service-transport_ats.h"
30#include "gnunet-service-transport_plugins.h"
31
32/**
33 * Entry in doubly-linked list of all of our plugins.
34 */
35struct TransportPlugin
36{
37 /**
38 * This is a doubly-linked list.
39 */
40 struct TransportPlugin *next;
41
42 /**
43 * This is a doubly-linked list.
44 */
45 struct TransportPlugin *prev;
46
47 /**
48 * API of the transport as returned by the plugin's
49 * initialization function.
50 */
51 struct GNUNET_TRANSPORT_PluginFunctions *api;
52
53 /**
54 * Short name for the plugin (e.g. "tcp").
55 */
56 char *short_name;
57
58 /**
59 * Name of the library (e.g. "gnunet_plugin_transport_tcp").
60 */
61 char *lib_name;
62
63 /**
64 * Environment this transport service is using
65 * for this plugin.
66 */
67 struct GNUNET_TRANSPORT_PluginEnvironment env;
68};
69
70/**
71 * Head of DLL of all loaded plugins.
72 */
73static struct TransportPlugin *plugins_head;
74
75/**
76 * Head of DLL of all loaded plugins.
77 */
78static struct TransportPlugin *plugins_tail;
79
80
81/**
82 * Function that will be called to update metrics for an address
83 *
84 * @param cls closure
85 * @param address address to update metrics for
86 * @param distance new distance
87 */
88static void
89plugin_env_update_distance (void *cls,
90 const struct GNUNET_HELLO_Address *address,
91 uint32_t distance)
92{
93 GST_ats_update_distance (address,
94 distance);
95}
96
97
98/**
99 * Function that will be called to figure if an address is an loopback,
100 * LAN, WAN etc. address
101 *
102 * @param cls closure
103 * @param addr binary address
104 * @param addrlen length of the @a addr
105 * @return type of the network @a addr belongs to
106 */
107static enum GNUNET_NetworkType
108plugin_env_address_to_type (void *cls,
109 const struct sockaddr *addr,
110 size_t addrlen)
111{
112 if (NULL == GST_is)
113 {
114 GNUNET_break (0);
115 return GNUNET_NT_UNSPECIFIED;
116 }
117 return GNUNET_NT_scanner_get_type (GST_is,
118 addr,
119 addrlen);
120}
121
122
123void
124GST_plugins_load (GNUNET_TRANSPORT_PluginReceiveCallback recv_cb,
125 GNUNET_TRANSPORT_AddressNotification address_cb,
126 GNUNET_TRANSPORT_SessionStart session_start_cb,
127 GNUNET_TRANSPORT_SessionEnd session_end_cb)
128{
129 struct TransportPlugin *plug;
130 struct TransportPlugin *next;
131 unsigned long long tneigh;
132 char *libname;
133 char *plugs;
134 char *pos;
135 int fail;
136
137 if (GNUNET_OK !=
138 GNUNET_CONFIGURATION_get_value_number (GST_cfg,
139 "TRANSPORT",
140 "NEIGHBOUR_LIMIT",
141 &tneigh))
142 {
143 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
144 _ ("Transport service is lacking NEIGHBOUR_LIMIT option.\n"));
145 return;
146 }
147 if (GNUNET_OK !=
148 GNUNET_CONFIGURATION_get_value_string (GST_cfg,
149 "TRANSPORT",
150 "PLUGINS",
151 &plugs))
152 return;
153 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
154 _ ("Starting transport plugins `%s'\n"),
155 plugs);
156 for (pos = strtok (plugs, " "); pos != NULL; pos = strtok (NULL, " "))
157 {
158 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
159 _ ("Loading `%s' transport plugin\n"),
160 pos);
161 GNUNET_asprintf (&libname,
162 "libgnunet_plugin_transport_%s",
163 pos);
164 plug = GNUNET_new (struct TransportPlugin);
165 plug->short_name = GNUNET_strdup (pos);
166 plug->lib_name = libname;
167 plug->env.cfg = GST_cfg;
168 plug->env.my_identity = &GST_my_identity;
169 plug->env.get_our_hello = &GST_hello_get;
170 plug->env.cls = plug->short_name;
171 plug->env.receive = recv_cb;
172 plug->env.notify_address = address_cb;
173 plug->env.session_start = session_start_cb;
174 plug->env.session_end = session_end_cb;
175 plug->env.get_address_type = &plugin_env_address_to_type;
176 plug->env.update_address_distance = &plugin_env_update_distance;
177 plug->env.max_connections = tneigh;
178 plug->env.stats = GST_stats;
179 GNUNET_CONTAINER_DLL_insert (plugins_head,
180 plugins_tail,
181 plug);
182 }
183 GNUNET_free (plugs);
184 next = plugins_head;
185 while (NULL != next)
186 {
187 plug = next;
188 next = plug->next;
189 plug->api = GNUNET_PLUGIN_load (plug->lib_name,
190 &plug->env);
191 if (NULL == plug->api)
192 {
193 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
194 _ ("Failed to load transport plugin for `%s'\n"),
195 plug->lib_name);
196 GNUNET_CONTAINER_DLL_remove (plugins_head,
197 plugins_tail,
198 plug);
199 GNUNET_free (plug->short_name);
200 GNUNET_free (plug->lib_name);
201 GNUNET_free (plug);
202 continue;
203 }
204 fail = GNUNET_NO;
205 if (NULL == plug->api->address_pretty_printer)
206 {
207 fail = GNUNET_YES;
208 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
209 _ ("Missing function `%s' in transport plugin for `%s'\n"),
210 "address_pretty_printer",
211 plug->lib_name);
212 }
213 if (NULL == plug->api->address_to_string)
214 {
215 fail = GNUNET_YES;
216 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
217 _ ("Missing function `%s' in transport plugin for `%s'\n"),
218 "address_to_string",
219 plug->lib_name);
220 }
221 if (NULL == plug->api->string_to_address)
222 {
223 fail = GNUNET_YES;
224 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
225 _ ("Missing function `%s' in transport plugin for `%s'\n"),
226 "string_to_address",
227 plug->lib_name);
228 }
229 if (NULL == plug->api->check_address)
230 {
231 fail = GNUNET_YES;
232 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
233 _ ("Missing function `%s' in transport plugin for `%s'\n"),
234 "check_address",
235 plug->lib_name);
236 }
237 if (NULL == plug->api->get_session)
238 {
239 fail = GNUNET_YES;
240 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
241 _ ("Missing function `%s' in transport plugin for `%s'\n"),
242 "get_session",
243 plug->lib_name);
244 }
245 if (NULL == plug->api->get_network)
246 {
247 fail = GNUNET_YES;
248 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
249 _ ("Missing function `%s' in transport plugin for `%s'\n"),
250 "get_network",
251 plug->lib_name);
252 }
253 if (NULL == plug->api->send)
254 {
255 fail = GNUNET_YES;
256 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
257 _ ("Missing function `%s' in transport plugin for `%s'\n"),
258 "send",
259 plug->lib_name);
260 }
261 if (NULL == plug->api->disconnect_peer)
262 {
263 fail = GNUNET_YES;
264 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
265 _ ("Missing function `%s' in transport plugin for `%s'\n"),
266 "disconnect_peer",
267 plug->lib_name);
268 }
269 if (NULL == plug->api->disconnect_session)
270 {
271 fail = GNUNET_YES;
272 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
273 _ ("Missing function `%s' in transport plugin for `%s'\n"),
274 "disconnect_session",
275 plug->lib_name);
276 }
277 if (NULL == plug->api->query_keepalive_factor)
278 {
279 fail = GNUNET_YES;
280 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
281 _ ("Missing function `%s' in transport plugin for `%s'\n"),
282 "query_keepalive_factor",
283 plug->lib_name);
284 }
285 if (NULL == plug->api->update_session_timeout)
286 {
287 fail = GNUNET_YES;
288 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
289 _ ("Missing function `%s' in transport plugin for `%s'\n"),
290 "update_session_timeout",
291 plug->lib_name);
292 }
293 if (GNUNET_YES == fail)
294 {
295 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
296 _ ("Did not load plugin `%s' due to missing functions\n"),
297 plug->lib_name);
298 GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api));
299 GNUNET_CONTAINER_DLL_remove (plugins_head,
300 plugins_tail,
301 plug);
302 GNUNET_free (plug->short_name);
303 GNUNET_free (plug->lib_name);
304 GNUNET_free (plug);
305 }
306 }
307}
308
309
310/**
311 * Unload all plugins
312 */
313void
314GST_plugins_unload ()
315{
316 struct TransportPlugin *plug;
317
318 while (NULL != (plug = plugins_head))
319 {
320 GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api));
321 GNUNET_free (plug->lib_name);
322 GNUNET_free (plug->short_name);
323 GNUNET_CONTAINER_DLL_remove (plugins_head, plugins_tail, plug);
324 GNUNET_free (plug);
325 }
326}
327
328
329/**
330 * Obtain the plugin API based on a plugin name.
331 *
332 * @param name name of the plugin
333 * @return the plugin's API, NULL if the plugin is not loaded
334 */
335struct GNUNET_TRANSPORT_PluginFunctions *
336GST_plugins_find (const char *name)
337{
338 struct TransportPlugin *pos;
339
340 for (pos = plugins_head; NULL != pos; pos = pos->next)
341 if (0 == strcmp (name, pos->short_name))
342 break;
343 if (NULL == pos)
344 return NULL;
345 return pos->api;
346}
347
348
349/**
350 * Obtain the plugin API based on a the stripped plugin name after the underscore.
351 *
352 * Example: GST_plugins_printer_find (http_client) will return all plugins
353 * starting with the prefix "http":
354 * http_client or server if loaded
355 *
356 * @param name name of the plugin
357 * @return the plugin's API, NULL if the plugin is not loaded
358 */
359struct GNUNET_TRANSPORT_PluginFunctions *
360GST_plugins_printer_find (const char *name)
361{
362 struct TransportPlugin *pos;
363 char *stripped = GNUNET_strdup (name);
364 char *sep = strchr (stripped, '_');
365
366 if (NULL != sep)
367 sep[0] = '\0';
368 for (pos = plugins_head; NULL != pos; pos = pos->next)
369 if (pos->short_name == strstr (pos->short_name, stripped))
370 break;
371 GNUNET_free (stripped);
372 if (NULL == pos)
373 return NULL;
374 return pos->api;
375}
376
377
378/**
379 * Convert a given address to a human-readable format. Note that the
380 * return value will be overwritten on the next call to this function.
381 *
382 * @param address the address to convert
383 * @return statically allocated (!) human-readable address
384 */
385const char *
386GST_plugins_a2s (const struct GNUNET_HELLO_Address *address)
387{
388 struct GNUNET_TRANSPORT_PluginFunctions *api;
389 static char unable_to_show[1024];
390 static const char *s;
391
392 if (NULL == address)
393 return "<NULL>";
394 if (0 == address->address_length)
395 return TRANSPORT_SESSION_INBOUND_STRING; /* Addresse with length 0 are inbound, address->address itself may be NULL */
396 api = GST_plugins_printer_find (address->transport_name);
397 if (NULL == api)
398 {
399 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
400 "Failed to find transport plugin `%s'\n",
401 address->transport_name);
402 return "<plugin unknown>";
403 }
404 if (0 == address->address_length)
405 {
406 GNUNET_snprintf (unable_to_show,
407 sizeof(unable_to_show),
408 "<unable to stringify %u-byte long address of %s transport>",
409 (unsigned int) address->address_length,
410 address->transport_name);
411 return unable_to_show;
412 }
413 return(NULL != (s = api->address_to_string (NULL,
414 address->address,
415 address->address_length))
416 ? s
417 : "<invalid>");
418}
419
420
421void
422GST_plugins_monitor_subscribe (GNUNET_TRANSPORT_SessionInfoCallback cb,
423 void *cb_cls)
424{
425 struct TransportPlugin *pos;
426
427 for (pos = plugins_head; NULL != pos; pos = pos->next)
428 if (NULL == pos->api->setup_monitor)
429 GNUNET_break (0);
430 else
431 pos->api->setup_monitor (pos->api->cls,
432 cb,
433 cb_cls);
434}
435
436
437/* end of file gnunet-service-transport_plugins.c */