aboutsummaryrefslogtreecommitdiff
path: root/src/ats/gnunet-service-ats_plugins.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ats/gnunet-service-ats_plugins.c')
-rw-r--r--src/ats/gnunet-service-ats_plugins.c600
1 files changed, 0 insertions, 600 deletions
diff --git a/src/ats/gnunet-service-ats_plugins.c b/src/ats/gnunet-service-ats_plugins.c
deleted file mode 100644
index d8d6be11d..000000000
--- a/src/ats/gnunet-service-ats_plugins.c
+++ /dev/null
@@ -1,600 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011-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 ats/gnunet-service-ats_plugins.c
23 * @brief ats service plugin management
24 * @author Matthias Wachs
25 * @author Christian Grothoff
26 */
27#include "platform.h"
28#include "gnunet_ats_plugin.h"
29#include "gnunet-service-ats_connectivity.h"
30#include "gnunet-service-ats_performance.h"
31#include "gnunet-service-ats_preferences.h"
32#include "gnunet-service-ats_plugins.h"
33#include "gnunet-service-ats_reservations.h"
34#include "gnunet-service-ats_scheduling.h"
35#include "gnunet-service-ats_normalization.h"
36
37
38/**
39 * Solver handle.
40 */
41static struct GNUNET_ATS_SolverFunctions *sf;
42
43/**
44 * Solver environment.
45 */
46static struct GNUNET_ATS_PluginEnvironment env;
47
48/**
49 * Solver plugin name as string
50 */
51static char *plugin;
52
53
54/**
55 * The preference changed for a peer, update solver.
56 *
57 * @param peer the peer
58 * @param kind the ATS kind
59 * @param pref_rel the new relative preference value
60 */
61void
62GAS_plugin_notify_preference_changed (const struct GNUNET_PeerIdentity *peer,
63 enum GNUNET_ATS_PreferenceKind kind,
64 double pref_rel)
65{
66 sf->s_pref (sf->cls,
67 peer,
68 kind,
69 pref_rel);
70}
71
72
73/**
74 * The relative value for a property changed.
75 *
76 * @param address the peer for which a property changed
77 */
78void
79GAS_plugin_notify_property_changed (struct ATS_Address *address)
80{
81 sf->s_address_update_property (sf->cls,
82 address);
83}
84
85
86/**
87 * Solver information callback
88 *
89 * @param cls the closure
90 * @param op the operation
91 * @param status operation status
92 * @param add additional information
93 */
94static void
95solver_info_cb (void *cls,
96 enum GAS_Solver_Operation op,
97 enum GAS_Solver_Status status,
98 enum GAS_Solver_Additional_Information add)
99{
100 const char *add_info;
101
102 switch (add)
103 {
104 case GAS_INFO_NONE:
105 add_info = "GAS_INFO_NONE";
106 break;
107
108 case GAS_INFO_FULL:
109 add_info = "GAS_INFO_MLP_FULL";
110 break;
111
112 case GAS_INFO_UPDATED:
113 add_info = "GAS_INFO_MLP_UPDATED";
114 break;
115
116 case GAS_INFO_PROP_ALL:
117 add_info = "GAS_INFO_PROP_ALL";
118 break;
119
120 case GAS_INFO_PROP_SINGLE:
121 add_info = "GAS_INFO_PROP_SINGLE";
122 break;
123
124 default:
125 add_info = "INVALID";
126 break;
127 }
128 switch (op)
129 {
130 case GAS_OP_SOLVE_START:
131 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
132 "Solver notifies `%s' with result `%s' `%s'\n",
133 "GAS_OP_SOLVE_START",
134 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL",
135 add_info);
136 return;
137
138 case GAS_OP_SOLVE_STOP:
139 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
140 "Solver notifies `%s' with result `%s'\n",
141 "GAS_OP_SOLVE_STOP",
142 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
143 return;
144
145 case GAS_OP_SOLVE_SETUP_START:
146 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
147 "Solver notifies `%s' with result `%s'\n",
148 "GAS_OP_SOLVE_SETUP_START",
149 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
150 return;
151
152 case GAS_OP_SOLVE_SETUP_STOP:
153 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
154 "Solver notifies `%s' with result `%s'\n",
155 "GAS_OP_SOLVE_SETUP_STOP",
156 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
157 return;
158
159 case GAS_OP_SOLVE_MLP_LP_START:
160 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
161 "Solver notifies `%s' with result `%s'\n",
162 "GAS_OP_SOLVE_LP_START",
163 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
164 return;
165
166 case GAS_OP_SOLVE_MLP_LP_STOP:
167 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
168 "Solver notifies `%s' with result `%s'\n",
169 "GAS_OP_SOLVE_LP_STOP",
170 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
171 return;
172
173 case GAS_OP_SOLVE_MLP_MLP_START:
174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
175 "Solver notifies `%s' with result `%s'\n",
176 "GAS_OP_SOLVE_MLP_START",
177 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
178 return;
179
180 case GAS_OP_SOLVE_MLP_MLP_STOP:
181 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
182 "Solver notifies `%s' with result `%s'\n",
183 "GAS_OP_SOLVE_MLP_STOP",
184 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
185 return;
186
187 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START:
188 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
189 "Solver notifies `%s' with result `%s'\n",
190 "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START",
191 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
192 return;
193
194 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP:
195 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
196 "Solver notifies `%s' with result `%s'\n",
197 "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP",
198 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
199 return;
200
201 default:
202 GNUNET_break (0);
203 break;
204 }
205}
206
207
208/**
209 * Callback for solver to notify about assignment changes
210 *
211 * @param cls NULL
212 * @param address the address with changes
213 */
214static void
215bandwidth_changed_cb (void *cls,
216 struct ATS_Address *address)
217{
218 long long diff_out;
219 long long diff_in;
220
221 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
222 "Bandwidth assignment changed for peer %s to %u/%u\n",
223 GNUNET_i2s (&address->peer),
224 (unsigned int) address->assigned_bw_in,
225 (unsigned int) address->assigned_bw_out);
226 GAS_reservations_set_bandwidth (&address->peer,
227 GNUNET_BANDWIDTH_value_init (
228 address->assigned_bw_in));
229 /* Notify performance clients about changes to address */
230 GAS_performance_notify_all_clients (&address->peer,
231 address->plugin,
232 address->addr,
233 address->addr_len,
234 address->active,
235 &address->properties,
236 address->local_address_info,
237 GNUNET_BANDWIDTH_value_init (
238 address->assigned_bw_out),
239 GNUNET_BANDWIDTH_value_init (
240 address->assigned_bw_in));
241
242 if ((0 == address->assigned_bw_in) &&
243 (0 == address->assigned_bw_out))
244 {
245 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
246 "Telling transport to disconnect peer `%s'\n",
247 GNUNET_i2s (&address->peer));
248
249 /* Notify scheduling clients about suggestion */
250 GAS_scheduling_transmit_address_suggestion (&address->peer,
251 address->session_id,
252 GNUNET_BANDWIDTH_ZERO,
253 GNUNET_BANDWIDTH_ZERO);
254 return;
255 }
256
257 /* Do bandwidth stability check */
258 diff_out = llabs ((long long) address->assigned_bw_out
259 - (long long) address->last_notified_bw_out);
260 diff_in = llabs ((long long) address->assigned_bw_in
261 - (long long) address->last_notified_bw_in);
262 if ((diff_out < htonl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__)) &&
263 (diff_in < htonl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__)))
264 {
265 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
266 "Bandwidth change too small, not notifying client\n");
267 return;
268 }
269
270 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
271 "Sending bandwidth update for peer `%s': %u/%u\n",
272 GNUNET_i2s (&address->peer),
273 address->assigned_bw_out,
274 address->assigned_bw_out);
275
276 /* *Notify scheduling clients about suggestion */
277 GAS_scheduling_transmit_address_suggestion (&address->peer,
278 address->session_id,
279 GNUNET_BANDWIDTH_value_init (
280 address->assigned_bw_out),
281 GNUNET_BANDWIDTH_value_init (
282 address->assigned_bw_in));
283
284 address->last_notified_bw_out = address->assigned_bw_out;
285 address->last_notified_bw_in = address->assigned_bw_in;
286}
287
288
289/**
290 * Convert quota from text to numeric value.
291 *
292 * @param quota_str the value found in the configuration
293 * @param direction direction of the quota
294 * @param network network the quota applies to
295 * @return numeric quota value to use
296 */
297static unsigned long long
298parse_quota (const char *quota_str,
299 const char *direction,
300 enum GNUNET_NetworkType network)
301{
302 int res;
303 unsigned long long ret;
304
305 res = GNUNET_NO;
306 if (0 == strcmp (quota_str, GNUNET_ATS_MaxBandwidthString))
307 {
308 ret = GNUNET_ATS_MaxBandwidth;
309 res = GNUNET_YES;
310 }
311 if ((GNUNET_NO == res) &&
312 (GNUNET_OK ==
313 GNUNET_STRINGS_fancy_size_to_bytes (quota_str,
314 &ret)))
315 res = GNUNET_YES;
316 if ((GNUNET_NO == res) &&
317 (1 ==
318 sscanf (quota_str,
319 "%llu",
320 &ret)))
321 res = GNUNET_YES;
322 if (GNUNET_NO == res)
323 {
324 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
325 _ (
326 "Could not load %s quota for network `%s': `%s', assigning default bandwidth %llu\n"),
327 direction,
328 GNUNET_NT_to_string (network),
329 quota_str,
330 (unsigned long long) GNUNET_ATS_DefaultBandwidth);
331 ret = GNUNET_ATS_DefaultBandwidth;
332 }
333 else
334 {
335 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
336 _ ("%s quota configured for network `%s' is %llu\n"),
337 direction,
338 GNUNET_NT_to_string (network),
339 ret);
340 }
341 return ret;
342}
343
344
345/**
346 * Load quota value from the configuration @a cfg for the
347 * given network @a type and @a direction.
348 *
349 * @param cfg configuration to parse
350 * @param type network type to parse for
351 * @param direction traffic direction to parse for
352 * @return quota to apply
353 */
354static unsigned long long
355load_quota (const struct GNUNET_CONFIGURATION_Handle *cfg,
356 enum GNUNET_NetworkType type,
357 const char *direction)
358{
359 char *entry;
360 char *quota_str;
361 unsigned long long ret;
362
363 GNUNET_asprintf (&entry,
364 "%s_QUOTA_%s",
365 GNUNET_NT_to_string (type),
366 direction);
367 if (GNUNET_OK ==
368 GNUNET_CONFIGURATION_get_value_string (cfg,
369 "ats",
370 entry,
371 &quota_str))
372 {
373 ret = parse_quota (quota_str,
374 direction,
375 type);
376 GNUNET_free (quota_str);
377 }
378 else
379 {
380 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
381 _ (
382 "No %s-quota configured for network `%s', assigning default bandwidth %llu\n"),
383 direction,
384 GNUNET_NT_to_string (type),
385 (unsigned long long) GNUNET_ATS_DefaultBandwidth);
386 ret = GNUNET_ATS_DefaultBandwidth;
387 }
388 GNUNET_free (entry);
389 return ret;
390}
391
392
393/**
394 * Load quotas for networks from configuration
395 *
396 * @param cfg configuration handle
397 * @param out_dest where to write outbound quotas
398 * @param in_dest where to write inbound quotas
399 * @param dest_length length of inbound and outbound arrays
400 * @return number of networks loaded
401 */
402static unsigned int
403load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg,
404 unsigned long long *out_dest,
405 unsigned long long *in_dest,
406 int dest_length)
407{
408 unsigned int c;
409
410 for (c = 0; (c < GNUNET_NT_COUNT) && (c < dest_length); c++)
411 {
412 in_dest[c] = load_quota (cfg,
413 c,
414 "out");
415 out_dest[c] = load_quota (cfg,
416 c,
417 "in");
418 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
419 "Loaded quota for network `%s' (in/out): %llu %llu\n",
420 GNUNET_NT_to_string (c),
421 in_dest[c],
422 out_dest[c]);
423 }
424 return c;
425}
426
427
428/**
429 * Initialize plugins subsystem.
430 *
431 * @param cfg configuration to use
432 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error (failed to load
433 * solver plugin)
434 */
435int
436GAS_plugin_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
437{
438 char *mode_str;
439
440 /* Figure out configured solution method */
441 if (GNUNET_SYSERR ==
442 GNUNET_CONFIGURATION_get_value_string (cfg,
443 "ats",
444 "MODE",
445 &mode_str))
446 {
447 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
448 "No resource assignment method configured, using proportional approach\n");
449 mode_str = GNUNET_strdup ("proportional");
450 }
451 env.cls = NULL;
452 env.info_cb = &solver_info_cb;
453 env.bandwidth_changed_cb = &bandwidth_changed_cb;
454 env.get_preferences = &GAS_preference_get_by_peer;
455 env.get_connectivity = &GAS_connectivity_has_peer;
456 env.cfg = cfg;
457 env.stats = GSA_stats;
458 env.addresses = GSA_addresses;
459 env.network_count = GNUNET_NT_COUNT;
460 load_quotas (cfg,
461 env.out_quota,
462 env.in_quota,
463 GNUNET_NT_COUNT);
464 GNUNET_asprintf (&plugin,
465 "libgnunet_plugin_ats_%s",
466 mode_str);
467 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
468 "Initializing solver `%s'\n",
469 mode_str);
470 GNUNET_free (mode_str);
471 if (NULL == (sf = GNUNET_PLUGIN_load (plugin, &env)))
472 {
473 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
474 _ ("Failed to initialize solver `%s'!\n"),
475 plugin);
476 return GNUNET_SYSERR;
477 }
478 return GNUNET_OK;
479}
480
481
482/**
483 * Shutdown address subsystem.
484 */
485void
486GAS_plugin_done ()
487{
488 GNUNET_PLUGIN_unload (plugin,
489 sf);
490 sf = NULL;
491 GNUNET_free (plugin);
492 plugin = NULL;
493}
494
495
496/**
497 * Tell the solver that the given address can now be used
498 * for talking to the respective peer.
499 *
500 * @param new_address the new address
501 */
502void
503GAS_plugin_new_address (struct ATS_Address *new_address)
504{
505 sf->s_add (sf->cls,
506 new_address,
507 new_address->properties.scope); /* FIXME: remove 3rd arg here! */
508}
509
510
511/**
512 * Tell the solver that the given address is no longer valid
513 * can cannot be used any longer.
514 *
515 * @param address address that was deleted
516 */
517void
518GAS_plugin_delete_address (struct ATS_Address *address)
519{
520 sf->s_del (sf->cls,
521 address);
522}
523
524
525/**
526 * Tell the solver that the given client has expressed its
527 * appreciation for the past performance of a given connection.
528 *
529 * @param application client providing the feedback
530 * @param peer peer the feedback is about
531 * @param scope timeframe the feedback applies to
532 * @param kind performance property the feedback relates to
533 * @param score_abs degree of the appreciation
534 */
535void
536GAS_plugin_notify_feedback (struct GNUNET_SERVICE_Client *application,
537 const struct GNUNET_PeerIdentity *peer,
538 const struct GNUNET_TIME_Relative scope,
539 enum GNUNET_ATS_PreferenceKind kind,
540 float score_abs)
541{
542 sf->s_feedback (sf->cls,
543 application,
544 peer,
545 scope,
546 kind,
547 score_abs);
548}
549
550
551/**
552 * Stop instant solving, there are many state updates
553 * happening in bulk right now.
554 */
555void
556GAS_plugin_solver_lock ()
557{
558 sf->s_bulk_start (sf->cls);
559}
560
561
562/**
563 * Resume instant solving, we are done with the bulk state updates.
564 */
565void
566GAS_plugin_solver_unlock ()
567{
568 sf->s_bulk_stop (sf->cls);
569}
570
571
572/**
573 * Notify the plugin that a request to connect to
574 * a particular peer was given to us.
575 *
576 * @param pid identity of peer we now care about
577 */
578void
579GAS_plugin_request_connect_start (const struct GNUNET_PeerIdentity *pid)
580{
581 sf->s_get (sf->cls,
582 pid);
583}
584
585
586/**
587 * Notify the plugin that a request to connect to
588 * a particular peer was dropped.
589 *
590 * @param pid identity of peer we care now less about
591 */
592void
593GAS_plugin_request_connect_stop (const struct GNUNET_PeerIdentity *pid)
594{
595 sf->s_get_stop (sf->cls,
596 pid);
597}
598
599
600/* end of gnunet-service-ats_plugins.c */