GNUnet  0.10.x
plugin_ats_proportional.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2011-2015 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  */
26 #include "platform.h"
28 #include "gnunet_ats_service.h"
29 #include "gnunet_ats_plugin.h"
31 
32 #define LOG(kind,...) GNUNET_log_from (kind, "ats-proportional",__VA_ARGS__)
33 
40 #define PROP_STABILITY_FACTOR 1.25
41 
42 
51 #define PROPORTIONALITY_FACTOR 2.0
52 
53 
62 {
67 
72 
76  struct ATS_Address *addr;
77 
81  struct Network *network;
82 
87 
92 
97 
98 };
99 
100 
104 struct Network
105 {
109  const char *desc;
110 
114  char *stat_total;
115 
119  char *stat_active;
120 
125 
130 
134  unsigned long long total_quota_in;
135 
139  unsigned long long total_quota_out;
140 
145 
149  unsigned int active_addresses;
150 
154  unsigned int total_addresses;
155 
156 };
157 
158 
163 {
164 
169 
174 
178  double prop_factor;
179 
184 
188  unsigned int bulk_lock;
189 
194  unsigned int bulk_requests;
195 
199  unsigned int active_addresses;
200 
201 };
202 
203 
211 static int
213  int extra)
214 {
215  unsigned int na;
216  uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
217 
218  GNUNET_assert (((int)net->active_addresses) + extra >= 0);
219  na = net->active_addresses + extra;
220  if (0 == na)
221  return GNUNET_YES;
222  if ( ((net->total_quota_in / na) > min_bw) &&
223  ((net->total_quota_out / na) > min_bw) )
224  return GNUNET_YES;
225  return GNUNET_NO;
226 }
227 
228 
238 static int
240  struct Network *net,
241  unsigned int con)
242 {
243  struct AddressWrapper *aw;
244 
245  for (aw = net->head; NULL != aw; aw = aw->next)
246  if (con >
247  s->env->get_connectivity (s->env->cls,
248  &aw->addr->peer))
249  return GNUNET_NO;
250  return GNUNET_YES;
251 }
252 
253 
263 static void
265  struct Network *net)
266 {
267  const uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
268  struct AddressWrapper *aw;
269  unsigned long long remaining_quota_in;
270  unsigned long long quota_out_used;
271  unsigned long long remaining_quota_out;
272  unsigned long long quota_in_used;
273  unsigned int count_addresses;
274  double sum_relative_peer_prefences;
275  double peer_weight;
276  double total_weight;
277  const double *peer_relative_prefs;
278 
280  "Recalculate quota for network type `%s' for %u addresses (in/out): %llu/%llu \n",
281  net->desc,
282  net->active_addresses,
283  net->total_quota_in,
284  net->total_quota_in);
285 
286  if (0 == net->active_addresses)
287  return; /* no addresses to update */
288 
289  /* sanity checks */
290  if ((net->active_addresses * min_bw) > net->total_quota_in)
291  {
292  GNUNET_break(0);
293  return;
294  }
295  if ((net->active_addresses * min_bw) > net->total_quota_out)
296  {
297  GNUNET_break(0);
298  return;
299  }
300 
301  /* Calculate sum of relative preference for active addresses in this
302  network */
303  sum_relative_peer_prefences = 0.0;
304  count_addresses = 0;
305  for (aw = net->head; NULL != aw; aw = aw->next)
306  {
307  if (GNUNET_YES != aw->addr->active)
308  continue;
309  peer_relative_prefs = s->env->get_preferences (s->env->cls,
310  &aw->addr->peer);
311  sum_relative_peer_prefences
312  += peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH];
313  count_addresses++;
314  }
315  if (count_addresses != net->active_addresses)
316  {
317  GNUNET_break (0);
319  "%s: Counted %u active addresses, expected %u active addresses\n",
320  net->desc,
321  count_addresses,
322  net->active_addresses);
323  /* try to fix... */
325  }
327  "Total relative preference %.3f for %u addresses in network %s\n",
328  sum_relative_peer_prefences,
329  net->active_addresses,
330  net->desc);
331 
332  /* check how much we have to distribute */
333  remaining_quota_in = net->total_quota_in - (net->active_addresses * min_bw);
334  remaining_quota_out = net->total_quota_out - (net->active_addresses * min_bw);
336  "Proportionally distributable bandwidth (in/out): %llu/%llu\n",
337  remaining_quota_in,
338  remaining_quota_out);
339 
340  /* distribute remaining quota; we do not do it exactly proportional,
341  but balance "even" distribution ("net->active_addresses") with
342  the preference sum using the "prop_factor". */
343  total_weight = net->active_addresses +
344  s->prop_factor * sum_relative_peer_prefences;
345  quota_out_used = 0;
346  quota_in_used = 0;
347  for (aw = net->head; NULL != aw; aw = aw->next)
348  {
349  if (GNUNET_YES != aw->addr->active)
350  {
351  /* set to 0, just to be sure */
352  aw->calculated_quota_in = 0;
353  aw->calculated_quota_out = 0;
354  continue;
355  }
356  peer_relative_prefs = s->env->get_preferences (s->env->cls,
357  &aw->addr->peer);
358  peer_weight = 1.0
359  + s->prop_factor * peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH];
360 
361  aw->calculated_quota_in = min_bw
362  + (peer_weight / total_weight) * remaining_quota_in;
363  aw->calculated_quota_out = min_bw
364  + (peer_weight / total_weight) * remaining_quota_out;
365 
367  "New quotas for peer `%s' with weight (cur/total) %.3f/%.3f (in/out) are: %u/%u\n",
368  GNUNET_i2s (&aw->addr->peer),
369  peer_weight,
370  total_weight,
371  (unsigned int) aw->calculated_quota_in,
372  (unsigned int) aw->calculated_quota_out);
373  quota_in_used += aw->calculated_quota_in;
374  quota_out_used += aw->calculated_quota_out;
375  }
377  "Total bandwidth assigned is (in/out): %llu /%llu\n",
378  quota_in_used,
379  quota_out_used);
380  /* +1 due to possible rounding errors */
381  GNUNET_break (quota_out_used <= net->total_quota_out + 1);
382  GNUNET_break (quota_in_used <= net->total_quota_in + 1);
383 }
384 
385 
392 static void
394  struct Network *net)
395 {
396  struct AddressWrapper *cur;
397 
398  for (cur = net->head; NULL != cur; cur = cur->next)
399  {
400  if ( (cur->addr->assigned_bw_in == cur->calculated_quota_in) &&
401  (cur->addr->assigned_bw_out == cur->calculated_quota_out) )
402  continue;
405  if (GNUNET_YES == cur->addr->active)
406  s->env->bandwidth_changed_cb (s->env->cls,
407  cur->addr);
408  }
409 }
410 
411 
419 static void
421  struct Network *n)
422 {
423  unsigned int i;
424 
425  if (0 != s->bulk_lock)
426  {
427  s->bulk_requests++;
428  return;
429  }
430  if (NULL != n)
431  {
433  "Redistributing bandwidth in network %s with %u active and %u total addresses\n",
435  n->active_addresses,
436  n->total_addresses);
437  s->env->info_cb (s->env->cls,
442  n);
443  s->env->info_cb (s->env->cls,
447  s->env->info_cb (s->env->cls,
452  n);
453 
454  s->env->info_cb (s->env->cls,
458  }
459  else
460  {
462  "Redistributing bandwidth in all %u networks\n",
463  s->env->network_count);
464  s->env->info_cb (s->env->cls,
468  for (i = 0; i < s->env->network_count; i++)
470  &s->network_entries[i]);
471  s->env->info_cb (s->env->cls,
475  s->env->info_cb (s->env->cls,
479  for (i = 0; i < s->env->network_count; i++)
481  &s->network_entries[i]);
482  s->env->info_cb (s->env->cls,
486  }
487 }
488 
489 
494 {
499 
503  struct ATS_Address *best;
504 };
505 
506 
518 static int
520  const struct GNUNET_PeerIdentity *key,
521  void *value)
522 {
523  struct FindBestAddressCtx *ctx = cls;
524  struct ATS_Address *current = value;
525  struct AddressWrapper *asi = current->solver_information;
526  struct GNUNET_TIME_Relative active_time;
527  double best_delay;
528  double best_distance;
529  double cur_delay;
530  double cur_distance;
531  unsigned int con;
532  int bw_available;
533  int need;
534 
535  /* we need +1 slot if 'current' is not yet active */
536  need = (GNUNET_YES == current->active) ? 0 : 1;
537  /* we save -1 slot if 'best' is active and belongs
538  to the same network (as we would replace it) */
539  if ( (NULL != ctx->best) &&
540  (GNUNET_YES == ctx->best->active) &&
541  (((struct AddressWrapper *) ctx->best->solver_information)->network ==
542  asi->network) )
543  need--;
544  /* we can gain -1 slot if this peers connectivity
545  requirement is higher than that of another peer
546  in that network scope */
547  con = ctx->s->env->get_connectivity (ctx->s->env->cls,
548  key);
549  if (GNUNET_YES !=
551  asi->network,
552  con))
553  need--;
554  /* test if minimum bandwidth for 'current' would be available */
555  bw_available
557  need);
558  if (! bw_available)
559  {
560  /* Bandwidth for this address is unavailable, so we cannot use
561  it. */
562  return GNUNET_OK;
563  }
564  if (GNUNET_YES == current->active)
565  {
566  active_time = GNUNET_TIME_absolute_get_duration (asi->activated);
567  if (active_time.rel_value_us <=
568  ((double) GNUNET_TIME_UNIT_SECONDS.rel_value_us) * ctx->s->stability_factor)
569  {
570  /* Keep active address for stability reasons */
571  ctx->best = current;
572  return GNUNET_NO;
573  }
574  }
575  if (NULL == ctx->best)
576  {
577  /* We so far have nothing else, so go with it! */
578  ctx->best = current;
579  return GNUNET_OK;
580  }
581 
582  /* Now compare ATS information */
583  cur_distance = current->norm_distance.norm;
584  best_distance = ctx->best->norm_distance.norm;
585  cur_delay = current->norm_delay.norm;
586  best_delay = ctx->best->norm_delay.norm;
587 
588  /* user shorter distance */
589  if (cur_distance < best_distance)
590  {
591  if (GNUNET_NO == ctx->best->active)
592  {
593  /* Activity doesn't influence the equation, use current */
594  ctx->best = current;
595  }
596  else if ((best_distance / cur_distance) > ctx->s->stability_factor)
597  {
598  /* Distance change is significant, switch active address! */
599  ctx->best = current;
600  }
601  }
602 
603  /* User connection with less delay */
604  if (cur_delay < best_delay)
605  {
606  if (GNUNET_NO == ctx->best->active)
607  {
608  /* Activity doesn't influence the equation, use current */
609  ctx->best = current;
610  }
611  else if ((best_delay / cur_delay) > ctx->s->stability_factor)
612  {
613  /* Latency change is significant, switch active address! */
614  ctx->best = current;
615  }
616  }
617  return GNUNET_OK;
618 }
619 
620 
630 struct ATS_Address *
633  const struct GNUNET_PeerIdentity *id)
634 {
635  struct FindBestAddressCtx fba_ctx;
636 
637  fba_ctx.best = NULL;
638  fba_ctx.s = s;
640  id,
642  &fba_ctx);
643  return fba_ctx.best;
644 }
645 
646 
653 static void
655  struct Network *net)
656 {
657  GNUNET_assert (net->active_addresses > 0);
658  net->active_addresses--;
660  net->stat_active,
661  -1,
662  GNUNET_NO);
664  s->active_addresses--;
666  "# ATS addresses total",
667  -1,
668  GNUNET_NO);
669 }
670 
671 
681 static int
683  const struct GNUNET_PeerIdentity *key,
684  void *value)
685 {
686  struct ATS_Address **dest = cls;
687  struct ATS_Address *aa = value;
688 
689  if (GNUNET_YES != aa->active)
690  return GNUNET_OK;
691  GNUNET_assert (NULL == (*dest));
692  (*dest) = aa;
693  return GNUNET_OK;
694 }
695 
696 
704 static struct ATS_Address *
706  const struct GNUNET_PeerIdentity *peer)
707 {
708  struct ATS_Address *dest;
709 
710  dest = NULL;
712  peer,
714  &dest);
715  return dest;
716 }
717 
718 
729 static void
731  struct ATS_Address *current_address,
732  const struct GNUNET_PeerIdentity *peer)
733 {
734  struct ATS_Address *best_address;
735  struct AddressWrapper *asi_cur;
736  struct AddressWrapper *asi_best;
737  struct AddressWrapper *aw;
738  struct AddressWrapper *aw_min;
739  unsigned int a_con;
740  unsigned int con_min;
741 
742  best_address = get_best_address (s,
743  s->env->addresses,
744  peer);
745  if (NULL != best_address)
746  asi_best = best_address->solver_information;
747  else
748  asi_best = NULL;
749  if (current_address == best_address)
750  return; /* no changes */
751  if (NULL != current_address)
752  {
753  /* We switch to a new address (or to none);
754  mark old address as inactive. */
755  asi_cur = current_address->solver_information;
756  GNUNET_assert (GNUNET_YES == current_address->active);
758  "Disabling previous active address for peer `%s'\n",
759  GNUNET_i2s (peer));
761  current_address->active = GNUNET_NO;
762  current_address->assigned_bw_in = 0;
763  current_address->assigned_bw_out = 0;
765  asi_cur->network);
766  if ( (NULL == best_address) ||
767  (asi_best->network != asi_cur->network) )
769  asi_cur->network);
770  if (NULL == best_address)
771  {
772  /* We previously had an active address, but now we cannot
773  * suggest one. Therefore we have to disconnect the peer.
774  * The above call to "distribute_bandwidth_in_network()
775  * does not see 'current_address' so we need to trigger
776  * the update here. */
778  "Disconnecting peer `%s'.\n",
779  GNUNET_i2s (peer));
780  s->env->bandwidth_changed_cb (s->env->cls,
781  current_address);
782  return;
783  }
784  }
785  if (NULL == best_address)
786  {
787  /* We do not have a new address, so we are done. */
789  "Cannot suggest address for peer `%s'\n",
790  GNUNET_i2s (peer));
791  return;
792  }
793  /* We do have a new address, activate it */
795  "Selecting new address %p for peer `%s'\n",
796  best_address,
797  GNUNET_i2s (peer));
798  /* Mark address as active */
799  best_address->active = GNUNET_YES;
800  asi_best->activated = GNUNET_TIME_absolute_get ();
801  asi_best->network->active_addresses++;
802  s->active_addresses++;
804  "# ATS active addresses total",
805  1,
806  GNUNET_NO);
808  asi_best->network->stat_active,
809  1,
810  GNUNET_NO);
812  "Address %p for peer `%s' is now active\n",
813  best_address,
814  GNUNET_i2s (peer));
815 
816  if (GNUNET_NO ==
818  0))
819  {
820  /* we went over the maximum number of addresses for
821  this scope; remove the address with the smallest
822  connectivity requirement */
823  con_min = UINT32_MAX;
824  aw_min = NULL;
825  for (aw = asi_best->network->head; NULL != aw; aw = aw->next)
826  {
827  if ( (con_min >
828  (a_con = s->env->get_connectivity (s->env->cls,
829  &aw->addr->peer))) &&
830  (GNUNET_YES == aw->addr->active) )
831  {
832  aw_min = aw;
833  con_min = a_con;
834  if (0 == con_min)
835  break;
836  }
837  }
839  aw_min->addr,
840  &aw_min->addr->peer);
841  }
843  asi_best->network);
844 }
845 
846 
855 static void
857  const struct GNUNET_PeerIdentity *peer,
858  enum GNUNET_ATS_PreferenceKind kind,
859  double pref_rel)
860 {
861  struct GAS_PROPORTIONAL_Handle *s = solver;
862 
864  return; /* we do not care */
866  NULL);
867 }
868 
869 
880 static void
882  struct GNUNET_SERVICE_Client *application,
883  const struct GNUNET_PeerIdentity *peer,
884  const struct GNUNET_TIME_Relative scope,
885  enum GNUNET_ATS_PreferenceKind kind,
886  double score)
887 {
888  /* Proportional does not care about feedback */
889 }
890 
891 
898 static void
900  const struct GNUNET_PeerIdentity *peer)
901 {
902  struct GAS_PROPORTIONAL_Handle *s = solver;
903 
906  peer),
907  peer);
908 }
909 
910 
917 static void
919  const struct GNUNET_PeerIdentity *peer)
920 {
921  struct GAS_PROPORTIONAL_Handle *s = solver;
922  struct ATS_Address *cur;
923  struct AddressWrapper *asi;
924 
925  cur = get_active_address (s,
926  peer);
927  if (NULL == cur)
928  return;
929  asi = cur->solver_information;
931  asi->network);
932 }
933 
934 
940 static void
942 {
943  struct GAS_PROPORTIONAL_Handle *s = solver;
944 
946  "Locking solver for bulk operation ...\n");
947  GNUNET_assert (NULL != solver);
948  s->bulk_lock++;
949 }
950 
951 
957 static void
959 {
960  struct GAS_PROPORTIONAL_Handle *s = solver;
961 
963  "Unlocking solver from bulk operation ...\n");
964  if (s->bulk_lock < 1)
965  {
966  GNUNET_break(0);
967  return;
968  }
969  s->bulk_lock--;
970  if ( (0 == s->bulk_lock) &&
971  (0 < s->bulk_requests) )
972  {
974  "No lock pending, recalculating\n");
976  NULL);
977  s->bulk_requests = 0;
978  }
979 }
980 
981 
988 static void
990  struct ATS_Address *address)
991 {
992  struct GAS_PROPORTIONAL_Handle *s = solver;
993  struct AddressWrapper *asi = address->solver_information;
994 
996  asi->network);
997 }
998 
999 
1007 static void
1009  struct ATS_Address *address,
1010  uint32_t network)
1011 {
1012  struct GAS_PROPORTIONAL_Handle *s = solver;
1013  struct Network *net;
1014  struct AddressWrapper *aw;
1015 
1016  GNUNET_assert (network < s->env->network_count);
1017  net = &s->network_entries[network];
1018  net->total_addresses++;
1019 
1020  aw = GNUNET_new (struct AddressWrapper);
1021  aw->addr = address;
1022  aw->network = net;
1023  address->solver_information = aw;
1025  net->tail,
1026  aw);
1028  "# ATS addresses total",
1029  1,
1030  GNUNET_NO);
1032  net->stat_total,
1033  1,
1034  GNUNET_NO);
1036  get_active_address (s,
1037  &address->peer),
1038  &address->peer);
1040  "Added new address for `%s', now total %u and active %u addresses in network `%s'\n",
1041  GNUNET_i2s (&address->peer),
1042  net->total_addresses,
1043  net->active_addresses,
1044  net->desc);
1045 }
1046 
1047 
1059 static void
1061  struct ATS_Address *address)
1062 {
1063  struct GAS_PROPORTIONAL_Handle *s = solver;
1064  struct AddressWrapper *aw = address->solver_information;
1065  struct Network *net = aw->network;
1066 
1068  "Deleting %s address for peer `%s' from network `%s' (total: %u/active: %u)\n",
1069  (GNUNET_NO == address->active) ? "inactive" : "active",
1070  GNUNET_i2s (&address->peer),
1071  net->desc,
1072  net->total_addresses,
1073  net->active_addresses);
1074 
1076  net->tail,
1077  aw);
1078  GNUNET_assert (net->total_addresses > 0);
1079  net->total_addresses--;
1081  net->stat_total,
1082  -1,
1083  GNUNET_NO);
1084  if (GNUNET_YES == address->active)
1085  {
1086  /* Address was active, remove from network and update quotas */
1088  address,
1089  &address->peer);
1091  }
1092  GNUNET_free (aw);
1093  address->solver_information = NULL;
1095  "After deleting address now total %u and active %u addresses in network `%s'\n",
1096  net->total_addresses,
1097  net->active_addresses,
1098  net->desc);
1099 }
1100 
1101 
1109 void *
1111 {
1112  static struct GNUNET_ATS_SolverFunctions sf;
1114  struct GAS_PROPORTIONAL_Handle *s;
1115  struct Network * cur;
1116  float f_tmp;
1117  unsigned int c;
1118 
1119  s = GNUNET_new (struct GAS_PROPORTIONAL_Handle);
1120  s->env = env;
1121  sf.cls = s;
1132  if (GNUNET_SYSERR !=
1134  "ats",
1135  "PROP_STABILITY_FACTOR",
1136  &f_tmp))
1137  {
1138  if ((f_tmp < 1.0) || (f_tmp > 2.0))
1139  {
1141  _("Invalid %s configuration %f \n"),
1142  "PROP_STABILITY_FACTOR",
1143  f_tmp);
1144  }
1145  else
1146  {
1147  s->stability_factor = f_tmp;
1149  "Using %s of %.3f\n",
1150  "PROP_STABILITY_FACTOR",
1151  f_tmp);
1152  }
1153  }
1155  if (GNUNET_SYSERR !=
1157  "ats",
1158  "PROP_PROPORTIONALITY_FACTOR",
1159  &f_tmp))
1160  {
1161  if (f_tmp < 1.0)
1162  {
1164  _("Invalid %s configuration %f\n"),
1165  "PROP_PROPORTIONALITY_FACTOR",
1166  f_tmp);
1167  }
1168  else
1169  {
1170  s->prop_factor = f_tmp;
1172  "Using %s of %.3f\n",
1173  "PROP_PROPORTIONALITY_FACTOR",
1174  f_tmp);
1175  }
1176  }
1177 
1179  sizeof (struct Network));
1180  for (c = 0; c < env->network_count; c++)
1181  {
1182  cur = &s->network_entries[c];
1183  cur->type = c;
1184  cur->total_quota_in = env->in_quota[c];
1185  cur->total_quota_out = env->out_quota[c];
1186  cur->desc = GNUNET_NT_to_string (c);
1187  GNUNET_asprintf (&cur->stat_total,
1188  "# ATS addresses %s total",
1189  cur->desc);
1191  "# ATS active addresses %s total",
1192  cur->desc);
1194  "Added network %u `%s' (%llu/%llu)\n",
1195  c,
1196  cur->desc,
1197  cur->total_quota_in,
1198  cur->total_quota_out);
1199  }
1200  return &sf;
1201 }
1202 
1203 
1209 void *
1211 {
1212  struct GNUNET_ATS_SolverFunctions *sf = cls;
1213  struct GAS_PROPORTIONAL_Handle *s = sf->cls;
1214  struct AddressWrapper *cur;
1215  struct AddressWrapper *next;
1216  unsigned int c;
1217 
1218  for (c = 0; c < s->env->network_count; c++)
1219  {
1222  next = s->network_entries[c].head;
1223  while (NULL != (cur = next))
1224  {
1225  next = cur->next;
1227  s->network_entries[c].tail,
1228  cur);
1230  GNUNET_free(cur);
1231  }
1234  }
1235  GNUNET_break (0 == s->active_addresses);
1237  GNUNET_free (s);
1238  return NULL;
1239 }
1240 
1241 
1242 /* end of plugin_ats_proportional.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
GAS_solver_stop_get_preferred_address s_get_stop
Tell solver stop notifying ATS about changes for this peers.
unsigned int total_addresses
Number of total addresses for this network.
After the problem was finished, start notifications about changes to addresses.
A handle for the proportional solver.
static int count_addresses(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Address iterator that counts the remaining addresses.
struct ATS_Address * best
The currently best address.
GAS_solver_address_add s_add
Add a new address for a peer to the solver.
struct GNUNET_TIME_Absolute activated
When was this address activated.
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
struct AddressWrapper * next
Next in DLL.
uint64_t rel_value_us
The actual value.
The proportional solver had to recalculate for a single network.
const char * GNUNET_NT_to_string(enum GNUNET_NetworkType net)
Convert a enum GNUNET_NetworkType to a string.
Definition: nt.c:43
unsigned long long total_quota_out
Total outbound quota.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct GNUNET_STATISTICS_Handle * stats
Statistics handle to be used by the solver.
uint32_t calculated_quota_out
Outbound quota.
int active
Is this the active address for this peer?
static void GAS_proportional_feedback(void *solver, struct GNUNET_SERVICE_Client *application, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_TIME_Relative scope, enum GNUNET_ATS_PreferenceKind kind, double score)
Get application feedback for a peer.
GAS_get_preferences get_preferences
ATS addresses function to obtain preference values.
#define PROPORTIONALITY_FACTOR
Default value to assume for the proportionality factor, if none is given in the configuration.
struct GNUNET_PeerIdentity peer
Peer ID this address is for.
Address information stored for the proportional solver in the solver_information member of struct GNU...
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
The proportional solver had to recalculate for all networks.
#define GNUNET_TIME_UNIT_SECONDS
One second.
static void address_decrement_active(struct GAS_PROPORTIONAL_Handle *s, struct Network *net)
Decrease number of active addresses in network.
void * libgnunet_plugin_ats_proportional_done(void *cls)
Function used to unload the plugin.
const char * desc
Network description.
static void GAS_proportional_start_get_address(void *solver, const struct GNUNET_PeerIdentity *peer)
Get the preferred address for a specific peer.
GAS_solver_address_feedback_preference s_feedback
Give feedback about the current assignment.
int GNUNET_CONFIGURATION_get_value_float(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, float *number)
Get a configuration value that should be a floating point number.
static void GAS_proportional_change_preference(void *solver, const struct GNUNET_PeerIdentity *peer, enum GNUNET_ATS_PreferenceKind kind, double pref_rel)
The preferences for a peer in the problem changed.
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...
double prop_factor
Proportionality factor.
#define GNUNET_NO
Definition: gnunet_common.h:81
static struct GNUNET_CONTAINER_MultiPeerMap * addresses
Hashmap to store addresses.
Definition: gnunet-ats.c:146
#define PROP_STABILITY_FACTOR
How much do we value stability over adaptation by default.
#define LOG(kind,...)
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GAS_PROPORTIONAL_Handle * s
The solver handle.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct Network * network
Network scope this address is in.
char * stat_active
String for statistics active addresses.
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:35
static void update_active_address(struct GAS_PROPORTIONAL_Handle *s, struct ATS_Address *current_address, const struct GNUNET_PeerIdentity *peer)
Update active address for a peer.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
Handle to a client that is connected to a service.
Definition: service.c:249
uint32_t assigned_bw_in
Inbound bandwidth assigned by solver.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
A solution iteration has been started.
static char * value
Value of the record to add/remove.
static void propagate_bandwidth(struct GAS_PROPORTIONAL_Handle *s, struct Network *net)
Notify ATS service of bandwidth changes to addresses.
struct AddressWrapper * prev
Previous in DLL.
struct GNUNET_ATS_PluginEnvironment * env
Our execution environment.
static enum GNUNET_NetworkType scope
Which network scope do we belong to?
GAS_solver_address_delete s_del
Delete an address in the solver.
static void distribute_bandwidth_in_network(struct GAS_PROPORTIONAL_Handle *s, struct Network *n)
Distribute bandwidth.
static int all_require_connectivity(struct GAS_PROPORTIONAL_Handle *s, struct Network *net, unsigned int con)
Test if all peers in this network require connectivity at level at least con.
Representation of a network (to be expanded...)
struct AddressWrapper * head
Linked list of addresses in this network: head.
struct ATS_Address * get_best_address(struct GAS_PROPORTIONAL_Handle *s, struct GNUNET_CONTAINER_MultiPeerMap *addresses, const struct GNUNET_PeerIdentity *id)
Find the currently best address for a peer from the set of addresses available or return NULL of no a...
static int find_best_address_it(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Find a "good" address to use for a peer by iterating over the addresses for this peer.
Internal representation of the hash map.
unsigned int bulk_requests
Number of changes made while solver was locked.
uint32_t calculated_quota_in
Inbound quota.
GAS_solver_address_change_preference s_pref
Change relative preference for quality in solver.
void * libgnunet_plugin_ats_proportional_init(void *cls)
Function invoked when the plugin is loaded.
static void GAS_proportional_address_delete(void *solver, struct ATS_Address *address)
Remove an address from the solver.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
static void GAS_proportional_address_property_changed(void *solver, struct ATS_Address *address)
Transport properties for this address have changed.
char * stat_total
String for statistics total addresses.
enum GNUNET_NetworkType type
ATS network type.
static int get_active_address_it(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Address map iterator to find current active address for peer.
static void distribute_bandwidth(struct GAS_PROPORTIONAL_Handle *s, struct Network *net)
Update bandwidth assigned to peers in this network.
Address with additional information.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
struct GNUNET_HashCode key
The key used in the DHT.
unsigned long long total_quota_in
Total inbound quota.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
void * solver_information
Solver-specific information for this address.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
void * cls
Closure to pass to all solver functions in this struct.
unsigned int active_addresses
Number of active addresses for solver.
ats service address management
struct Network * network_entries
Networks array.
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.
GAS_solver_bulk_start s_bulk_start
Start a bulk operation.
The identity of the host (wraps the signing key of the peer).
uint32_t assigned_bw_out
Outbound bandwidth assigned by solver.
static void GAS_proportional_bulk_start(void *solver)
Start a bulk operation.
static struct ATS_Address * get_active_address(struct GAS_PROPORTIONAL_Handle *s, const struct GNUNET_PeerIdentity *peer)
Find current active address for peer.
static void GAS_proportional_bulk_stop(void *solver)
Bulk operation done.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:373
static int is_bandwidth_available_in_network(struct Network *net, int extra)
Test if bandwidth is available in this network to add an additional address.
static void GAS_proportional_address_add(void *solver, struct ATS_Address *address, uint32_t network)
Add a new single address to a network.
static void GAS_proportional_stop_get_address(void *solver, const struct GNUNET_PeerIdentity *peer)
Stop notifying about address and bandwidth changes for this peer.
Automatic transport selection and outbound bandwidth determination.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration handle to be used by the solver.
GAS_solver_information_callback info_cb
Callback for solver to call with status information, can be NULL.
Change the peer&#39;s bandwidth value (value per byte of bandwidth in the goal function) to the given amo...
Context for finding the best address* Linked list of addresses in this network: head.
struct GAS_NormalizationInfo norm_delay
Normalized delay information for this address.
unsigned long long out_quota[6]
Array of configured outbound quotas Order according to networks in network array. ...
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
void * cls
Closure to pass to all callbacks in this struct.
struct ATS_Address * addr
The address.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
struct AddressWrapper * tail
Linked list of addresses in this network: tail.
static struct GNUNET_ATS_SolverFunctions * sf
Solver handle.
GNUNET_ATS_PreferenceKind
Enum defining all known preference categories.
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 ...
GAS_solver_bulk_stop s_bulk_stop
Bulk operation done.
unsigned int bulk_lock
Bulk lock counter.
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 char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
double norm
Normalized values from queue to a range of values [1.0...2.0].
int GNUNET_CONTAINER_multipeermap_get_multiple(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map that match a particular key.
unsigned int active_addresses
Number of active addresses for this network.
unsigned int network_count
Number of networks available, size of the out_quota and in_quota arrays.
double stability_factor
Stability factor.
#define GNUNET_malloc(size)
Wrapper around malloc.
struct GAS_NormalizationInfo norm_distance
Normalized distance information for this address.
#define GNUNET_free(ptr)
Wrapper around free.
GAS_get_connectivity get_connectivity
ATS addresses function to obtain preference values.
Time for relative time used by GNUnet, in microseconds.