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