GNUnet  0.11.x
gnunet-service-ats_plugins.c
Go to the documentation of this file.
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 
27 #include "platform.h"
28 #include "gnunet_ats_plugin.h"
36 
37 
42 
47 
51 static char *plugin;
52 
53 
61 void
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 
78 void
80 {
82  address);
83 }
84 
85 
94 static void
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 
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:
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:
140  "Solver notifies `%s' with result `%s'\n",
141  "GAS_OP_SOLVE_STOP",
142  (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
143  return;
144 
147  "Solver notifies `%s' with result `%s'\n",
148  "GAS_OP_SOLVE_SETUP_START",
149  (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
150  return;
151 
154  "Solver notifies `%s' with result `%s'\n",
155  "GAS_OP_SOLVE_SETUP_STOP",
156  (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
157  return;
158 
161  "Solver notifies `%s' with result `%s'\n",
162  "GAS_OP_SOLVE_LP_START",
163  (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
164  return;
165 
168  "Solver notifies `%s' with result `%s'\n",
169  "GAS_OP_SOLVE_LP_STOP",
170  (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
171  return;
172 
175  "Solver notifies `%s' with result `%s'\n",
176  "GAS_OP_SOLVE_MLP_START",
177  (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
178  return;
179 
182  "Solver notifies `%s' with result `%s'\n",
183  "GAS_OP_SOLVE_MLP_STOP",
184  (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
185  return;
186 
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 
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 
214 static void
216  struct ATS_Address *address)
217 {
218  long long diff_out;
219  long long diff_in;
220 
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);
228  address->assigned_bw_in));
229  /* Notify performance clients about changes to address */
231  address->plugin,
232  address->addr,
233  address->addr_len,
234  address->active,
235  &address->properties,
236  address->local_address_info,
238  address->assigned_bw_out),
240  address->assigned_bw_in));
241 
242  if ((0 == address->assigned_bw_in) &&
243  (0 == address->assigned_bw_out))
244  {
246  "Telling transport to disconnect peer `%s'\n",
247  GNUNET_i2s (&address->peer));
248 
249  /* Notify scheduling clients about suggestion */
251  address->session_id,
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  {
266  "Bandwidth change too small, not notifying client\n");
267  return;
268  }
269 
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 */
278  address->session_id,
280  address->assigned_bw_out),
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 
297 static unsigned long long
298 parse_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  {
309  res = GNUNET_YES;
310  }
311  if ((GNUNET_NO == res) &&
312  (GNUNET_OK ==
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  {
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);
332  }
333  else
334  {
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 
354 static unsigned long long
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 ==
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  {
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);
387  }
388  GNUNET_free (entry);
389  return ret;
390 }
391 
392 
402 static unsigned int
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");
419  "Loaded quota for network `%s' (in/out): %llu %llu\n",
421  in_dest[c],
422  out_dest[c]);
423  }
424  return c;
425 }
426 
427 
435 int
437 {
438  char *mode_str;
439 
440  /* Figure out configured solution method */
441  if (GNUNET_SYSERR ==
443  "ats",
444  "MODE",
445  &mode_str))
446  {
448  "No resource assignment method configured, using proportional approach\n");
449  mode_str = GNUNET_strdup ("proportional");
450  }
451  env.cls = NULL;
456  env.cfg = cfg;
457  env.stats = GSA_stats;
460  load_quotas (cfg,
461  env.out_quota,
462  env.in_quota,
465  "libgnunet_plugin_ats_%s",
466  mode_str);
468  "Initializing solver `%s'\n",
469  mode_str);
470  GNUNET_free (mode_str);
471  if (NULL == (sf = GNUNET_PLUGIN_load (plugin, &env)))
472  {
474  _ ("Failed to initialize solver `%s'!\n"),
475  plugin);
476  return GNUNET_SYSERR;
477  }
478  return GNUNET_OK;
479 }
480 
481 
485 void
487 {
489  sf);
490  sf = NULL;
492  plugin = NULL;
493 }
494 
495 
502 void
503 GAS_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 
517 void
519 {
520  sf->s_del (sf->cls,
521  address);
522 }
523 
524 
535 void
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 
555 void
557 {
558  sf->s_bulk_start (sf->cls);
559 }
560 
561 
565 void
567 {
568  sf->s_bulk_stop (sf->cls);
569 }
570 
571 
578 void
580 {
581  sf->s_get (sf->cls,
582  pid);
583 }
584 
585 
592 void
594 {
595  sf->s_get_stop (sf->cls,
596  pid);
597 }
598 
599 
600 /* end of gnunet-service-ats_plugins.c */
GAS_solver_stop_get_preferred_address s_get_stop
Tell solver stop notifying ATS about changes for this peers.
Solving of the LP problem was started MLP solver only.
After the problem was finished, start notifications about changes to addresses.
#define GNUNET_ATS_MaxBandwidthString
Textual equivalent for GNUNET_ATS_MaxBandwidth.
GAS_solver_address_add s_add
Add a new address for a peer to the solver.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
const char * GNUNET_NT_to_string(enum GNUNET_NetworkType net)
Convert a enum GNUNET_NetworkType to a string.
Definition: nt.c:44
The proportional solver had to recalculate for a single network.
uint32_t session_id
Session ID, can never be 0.
struct GNUNET_ATS_Properties properties
ATS performance information for this address.
The setup of the problem as a preparation to solve it was started.
void GAS_plugin_delete_address(struct ATS_Address *address)
Tell the solver that the given address is no longer valid can cannot be used any longer.
void GAS_plugin_new_address(struct ATS_Address *new_address)
Tell the solver that the given address can now be used for talking to the respective peer...
int active
Is this the active address for this peer?
GAS_get_preferences get_preferences
ATS addresses function to obtain preference values.
static unsigned long long parse_quota(const char *quota_str, const char *direction, enum GNUNET_NetworkType network)
Convert quota from text to numeric value.
void GAS_plugin_notify_feedback(struct GNUNET_SERVICE_Client *application, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_TIME_Relative scope, enum GNUNET_ATS_PreferenceKind kind, float score_abs)
Tell the solver that the given client has expressed its appreciation for the past performance of a gi...
struct GNUNET_PeerIdentity peer
Peer ID this address is for.
void GAS_plugin_solver_lock()
Stop instant solving, there are many state updates happening in bulk right now.
GAS_Solver_Status
Status of a GAS_Solver_Operation operation.
The proportional solver had to recalculate for all networks.
No more specific information.
const void * addr
Address (in plugin-specific binary format).
uint32_t last_notified_bw_out
Outbound bandwidth assigned by solver in NBO.
GAS_solver_address_feedback_preference s_feedback
Give feedback about the current assignment.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
ats service address: management of ATS properties and preferences normalization
GAS_solver_address_property_changed s_address_update_property
Update the properties of an address in the solver.
#define GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT
Bandwidth (in/out) to assume initially (before either peer has communicated any particular preference...
int GNUNET_STRINGS_fancy_size_to_bytes(const char *fancy_size, unsigned long long *size)
Convert a given fancy human-readable size to bytes.
Definition: strings.c:319
ats service plugin management
#define GNUNET_NO
Definition: gnunet_common.h:78
static unsigned int load_quotas(const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned long long *out_dest, unsigned long long *in_dest, int dest_length)
Load quotas for networks from configuration.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
A full solution process is performed Quite specific to the MLP solver.
size_t addr_len
Address length, number of bytes in addr.
char * plugin
Plugin name.
Solving of the LP problem is done MLP solver only.
void GAS_plugin_notify_preference_changed(const struct GNUNET_PeerIdentity *peer, enum GNUNET_ATS_PreferenceKind kind, double pref_rel)
The preference changed for a peer, update solver.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct GNUNET_STATISTICS_Handle * GSA_stats
Handle for statistics.
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...
struct GNUNET_STATISTICS_Handle * stats
Statistics handle to be used by the solver.
ats service, interaction with &#39;performance&#39; API
enum GNUNET_ABD_AlgoDirectionFlags direction
API enum, filled and passed for collect/verify.
Definition: gnunet-abd.c:172
void GAS_reservations_set_bandwidth(const struct GNUNET_PeerIdentity *peer, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
Set the amount of bandwidth the other peer could currently transmit to us (as far as we know) to the ...
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
void GAS_performance_notify_all_clients(const struct GNUNET_PeerIdentity *peer, const char *plugin_name, const void *plugin_addr, size_t plugin_addr_len, int active, const struct GNUNET_ATS_Properties *prop, enum GNUNET_HELLO_AddressInfo local_address_info, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
Transmit the given performance information to all performance clients.
void * GNUNET_PLUGIN_unload(const char *library_name, void *arg)
Unload plugin (runs the "done" callback and returns whatever "done" returned).
Definition: plugin.c:256
GAS_Solver_Operation
Operation codes for solver information callback.
Handle to a client that is connected to a service.
Definition: service.c:250
void GAS_plugin_solver_unlock()
Resume instant solving, we are done with the bulk state updates.
uint32_t assigned_bw_in
Inbound bandwidth assigned by solver.
Solving of the MLP problem is done MLP solver only.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
ats service, inbound bandwidth reservation management
A solution iteration has been started.
void GAS_plugin_notify_property_changed(struct ATS_Address *address)
The relative value for a property changed.
void GAS_scheduling_transmit_address_suggestion(const struct GNUNET_PeerIdentity *peer, uint32_t session_id, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
Transmit the given address suggestion and bandwidth update to all scheduling clients.
static enum GNUNET_NetworkType scope
Which network scope do we belong to?
GAS_Solver_Additional_Information
Status of the operation.
int GAS_plugin_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize plugins subsystem.
GAS_solver_address_delete s_del
Delete an address in the solver.
Solving of the MLP problem was started MLP solver only.
uint16_t status
See PRISM_STATUS_*-constants.
static void bandwidth_changed_cb(void *cls, struct ATS_Address *address)
Callback for solver to notify about assignment changes.
#define GNUNET_ATS_DefaultBandwidth
Default bandwidth assigned to a network : 64 KB/s.
static void solver_info_cb(void *cls, enum GAS_Solver_Operation op, enum GAS_Solver_Status status, enum GAS_Solver_Additional_Information add)
Solver information callback.
unsigned int GAS_connectivity_has_peer(void *cls, const struct GNUNET_PeerIdentity *peer)
Is the given peer in the list of peers for which we have an address request?
void * cls
Closure to pass to all solver functions in this struct.
GAS_solver_address_change_preference s_pref
Change relative preference for quality in solver.
static unsigned long long load_quota(const struct GNUNET_CONFIGURATION_Handle *cfg, enum GNUNET_NetworkType type, const char *direction)
Load quota value from the configuration cfg for the given network type and direction.
static int res
static char * plugin
Solver plugin name as string.
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.
#define GNUNET_ATS_MaxBandwidth
Maximum bandwidth assigned to a network : 4095 MB/s.
Address with additional information.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
void GAS_plugin_request_connect_start(const struct GNUNET_PeerIdentity *pid)
Notify the plugin that a request to connect to a particular peer was given to us. ...
void GAS_plugin_done()
Shutdown address subsystem.
struct GNUNET_CONTAINER_MultiPeerMap * GSA_addresses
A multihashmap to store all addresses.
ats service, interaction with &#39;connecivity&#39; API
void * cls
Closure to pass to all callbacks in this struct.
manage preferences expressed by clients
struct GNUNET_BANDWIDTH_Value32NBO GNUNET_BANDWIDTH_value_init(uint32_t bytes_per_second)
Create a new bandwidth value.
Definition: bandwidth.c:39
static int add
Desired action is to add a record.
GAS_solver_get_preferred_address s_get
Tell solver to notify ATS if the address to use changes for a specific peer using the bandwidth chang...
unsigned long long in_quota[6]
Array of configured inbound quotas Order according to networks in network array.
A solution iteration has been finished.
enum GNUNET_NetworkType scope
Which network scope does the respective address belong to? This property does not change...
GAS_solver_bulk_start s_bulk_start
Start a bulk operation.
The identity of the host (wraps the signing key of the peer).
#define GNUNET_BANDWIDTH_ZERO
Convenience definition to use for 0-bandwidth.
static struct GNUNET_ATS_PluginEnvironment env
Solver environment.
uint32_t assigned_bw_out
Outbound bandwidth assigned by solver.
configuration data
Definition: configuration.c:85
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration handle to be used by the solver.
#define GNUNET_log(kind,...)
GAS_solver_information_callback info_cb
Callback for solver to call with status information, can be NULL.
The setup of the problem as a preparation to solve is finished.
unsigned long long out_quota[6]
Array of configured outbound quotas Order according to networks in network array. ...
An existing solution was reused Quite specific to the MLP solver.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
void GAS_plugin_request_connect_stop(const struct GNUNET_PeerIdentity *pid)
Notify the plugin that a request to connect to a particular peer was dropped.
#define GNUNET_YES
Definition: gnunet_common.h:77
void * GNUNET_PLUGIN_load(const char *library_name, void *arg)
Setup plugin (runs the "init" callback and returns whatever "init" returned).
Definition: plugin.c:207
ats service, interaction with &#39;scheduling&#39; API
static struct GNUNET_ATS_SolverFunctions * sf
Solver handle.
GNUNET_ATS_PreferenceKind
Enum defining all known preference categories.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct GNUNET_CONTAINER_MultiPeerMap * addresses
Hashmap containing all addresses available.
The ATS plugin will pass a pointer to a struct of this type as to the initialization function of the ...
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
GAS_solver_bulk_stop s_bulk_stop
Bulk operation done.
static char * address
GNS address for this phone.
GAS_bandwidth_changed_cb bandwidth_changed_cb
ATS addresses callback to be notified about bandwidth assignment changes.
After the problem was finished, notifications about changes to addresses are done.
const double * GAS_preference_get_by_peer(void *cls, const struct GNUNET_PeerIdentity *id)
Get the normalized preference values for a specific peer or the default values if.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_NT_COUNT
unsigned int network_count
Number of networks available, size of the out_quota and in_quota arrays.
enum GNUNET_HELLO_AddressInfo local_address_info
Field to store local flags.
uint32_t last_notified_bw_in
Inbound bandwidth assigned by solver in NBO.
GAS_get_connectivity get_connectivity
ATS addresses function to obtain preference values.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.