GNUnet  0.11.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 
103 struct Network
104 {
108  const char *desc;
109 
113  char *stat_total;
114 
118  char *stat_active;
119 
124 
129 
133  unsigned long long total_quota_in;
134 
138  unsigned long long total_quota_out;
139 
144 
148  unsigned int active_addresses;
149 
153  unsigned int total_addresses;
154 };
155 
156 
161 {
166 
171 
175  double prop_factor;
176 
181 
185  unsigned int bulk_lock;
186 
191  unsigned int bulk_requests;
192 
196  unsigned int active_addresses;
197 };
198 
199 
207 static int
209  int extra)
210 {
211  unsigned int na;
212  uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
213 
214  GNUNET_assert (((int) net->active_addresses) + extra >= 0);
215  na = net->active_addresses + extra;
216  if (0 == na)
217  return GNUNET_YES;
218  if (((net->total_quota_in / na) > min_bw) &&
219  ((net->total_quota_out / na) > min_bw))
220  return GNUNET_YES;
221  return GNUNET_NO;
222 }
223 
224 
234 static int
236  struct Network *net,
237  unsigned int con)
238 {
239  struct AddressWrapper *aw;
240 
241  for (aw = net->head; NULL != aw; aw = aw->next)
242  if (con >
243  s->env->get_connectivity (s->env->cls,
244  &aw->addr->peer))
245  return GNUNET_NO;
246  return GNUNET_YES;
247 }
248 
249 
259 static void
261  struct Network *net)
262 {
263  const uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
264  struct AddressWrapper *aw;
265  unsigned long long remaining_quota_in;
266  unsigned long long quota_out_used;
267  unsigned long long remaining_quota_out;
268  unsigned long long quota_in_used;
269  unsigned int count_addresses;
270  double sum_relative_peer_prefences;
271  double peer_weight;
272  double total_weight;
273  const double *peer_relative_prefs;
274 
276  "Recalculate quota for network type `%s' for %u addresses (in/out): %llu/%llu \n",
277  net->desc,
278  net->active_addresses,
279  net->total_quota_in,
280  net->total_quota_in);
281 
282  if (0 == net->active_addresses)
283  return; /* no addresses to update */
284 
285  /* sanity checks */
286  if ((net->active_addresses * min_bw) > net->total_quota_in)
287  {
288  GNUNET_break (0);
289  return;
290  }
291  if ((net->active_addresses * min_bw) > net->total_quota_out)
292  {
293  GNUNET_break (0);
294  return;
295  }
296 
297  /* Calculate sum of relative preference for active addresses in this
298  network */
299  sum_relative_peer_prefences = 0.0;
300  count_addresses = 0;
301  for (aw = net->head; NULL != aw; aw = aw->next)
302  {
303  if (GNUNET_YES != aw->addr->active)
304  continue;
305  peer_relative_prefs = s->env->get_preferences (s->env->cls,
306  &aw->addr->peer);
307  sum_relative_peer_prefences
308  += peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH];
309  count_addresses++;
310  }
311  if (count_addresses != net->active_addresses)
312  {
313  GNUNET_break (0);
315  "%s: Counted %u active addresses, expected %u active addresses\n",
316  net->desc,
317  count_addresses,
318  net->active_addresses);
319  /* try to fix... */
321  }
323  "Total relative preference %.3f for %u addresses in network %s\n",
324  sum_relative_peer_prefences,
325  net->active_addresses,
326  net->desc);
327 
328  /* check how much we have to distribute */
329  remaining_quota_in = net->total_quota_in - (net->active_addresses * min_bw);
330  remaining_quota_out = net->total_quota_out - (net->active_addresses * min_bw);
332  "Proportionally distributable bandwidth (in/out): %llu/%llu\n",
333  remaining_quota_in,
334  remaining_quota_out);
335 
336  /* distribute remaining quota; we do not do it exactly proportional,
337  but balance "even" distribution ("net->active_addresses") with
338  the preference sum using the "prop_factor". */
339  total_weight = net->active_addresses
340  + s->prop_factor * sum_relative_peer_prefences;
341  quota_out_used = 0;
342  quota_in_used = 0;
343  for (aw = net->head; NULL != aw; aw = aw->next)
344  {
345  if (GNUNET_YES != aw->addr->active)
346  {
347  /* set to 0, just to be sure */
348  aw->calculated_quota_in = 0;
349  aw->calculated_quota_out = 0;
350  continue;
351  }
352  peer_relative_prefs = s->env->get_preferences (s->env->cls,
353  &aw->addr->peer);
354  peer_weight = 1.0
355  + s->prop_factor
356  * peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH];
357 
358  aw->calculated_quota_in = min_bw
359  + (peer_weight / total_weight)
360  * remaining_quota_in;
361  aw->calculated_quota_out = min_bw
362  + (peer_weight / total_weight)
363  * remaining_quota_out;
364 
366  "New quotas for peer `%s' with weight (cur/total) %.3f/%.3f (in/out) are: %u/%u\n",
367  GNUNET_i2s (&aw->addr->peer),
368  peer_weight,
369  total_weight,
370  (unsigned int) aw->calculated_quota_in,
371  (unsigned int) aw->calculated_quota_out);
372  quota_in_used += aw->calculated_quota_in;
373  quota_out_used += aw->calculated_quota_out;
374  }
376  "Total bandwidth assigned is (in/out): %llu /%llu\n",
377  quota_in_used,
378  quota_out_used);
379  /* +1 due to possible rounding errors */
380  GNUNET_break (quota_out_used <= net->total_quota_out + 1);
381  GNUNET_break (quota_in_used <= net->total_quota_in + 1);
382 }
383 
384 
391 static void
393  struct Network *net)
394 {
395  struct AddressWrapper *cur;
396 
397  for (cur = net->head; NULL != cur; cur = cur->next)
398  {
399  if ((cur->addr->assigned_bw_in == cur->calculated_quota_in) &&
400  (cur->addr->assigned_bw_out == cur->calculated_quota_out))
401  continue;
404  if (GNUNET_YES == cur->addr->active)
405  s->env->bandwidth_changed_cb (s->env->cls,
406  cur->addr);
407  }
408 }
409 
410 
418 static void
420  struct Network *n)
421 {
422  unsigned int i;
423 
424  if (0 != s->bulk_lock)
425  {
426  s->bulk_requests++;
427  return;
428  }
429  if (NULL != n)
430  {
432  "Redistributing bandwidth in network %s with %u active and %u total addresses\n",
434  n->active_addresses,
435  n->total_addresses);
436  s->env->info_cb (s->env->cls,
441  n);
442  s->env->info_cb (s->env->cls,
446  s->env->info_cb (s->env->cls,
451  n);
452 
453  s->env->info_cb (s->env->cls,
457  }
458  else
459  {
461  "Redistributing bandwidth in all %u networks\n",
462  s->env->network_count);
463  s->env->info_cb (s->env->cls,
467  for (i = 0; i < s->env->network_count; i++)
469  &s->network_entries[i]);
470  s->env->info_cb (s->env->cls,
474  s->env->info_cb (s->env->cls,
478  for (i = 0; i < s->env->network_count; i++)
480  &s->network_entries[i]);
481  s->env->info_cb (s->env->cls,
485  }
486 }
487 
488 
493 {
498 
502  struct ATS_Address *best;
503 };
504 
505 
517 static int
519  const struct GNUNET_PeerIdentity *key,
520  void *value)
521 {
522  struct FindBestAddressCtx *ctx = cls;
523  struct ATS_Address *current = value;
524  struct AddressWrapper *asi = current->solver_information;
525  struct GNUNET_TIME_Relative active_time;
526  double best_delay;
527  double best_distance;
528  double cur_delay;
529  double cur_distance;
530  unsigned int con;
531  int bw_available;
532  int need;
533 
534  /* we need +1 slot if 'current' is not yet active */
535  need = (GNUNET_YES == current->active) ? 0 : 1;
536  /* we save -1 slot if 'best' is active and belongs
537  to the same network (as we would replace it) */
538  if ((NULL != ctx->best) &&
539  (GNUNET_YES == ctx->best->active) &&
540  (((struct AddressWrapper *) ctx->best->solver_information)->network ==
541  asi->network))
542  need--;
543  /* we can gain -1 slot if this peers connectivity
544  requirement is higher than that of another peer
545  in that network scope */
546  con = ctx->s->env->get_connectivity (ctx->s->env->cls,
547  key);
548  if (GNUNET_YES !=
550  asi->network,
551  con))
552  need--;
553  /* test if minimum bandwidth for 'current' would be available */
554  bw_available
556  need);
557  if (! bw_available)
558  {
559  /* Bandwidth for this address is unavailable, so we cannot use
560  it. */
561  return GNUNET_OK;
562  }
563  if (GNUNET_YES == current->active)
564  {
565  active_time = GNUNET_TIME_absolute_get_duration (asi->activated);
566  if (active_time.rel_value_us <=
567  ((double) GNUNET_TIME_UNIT_SECONDS.rel_value_us)
568  * 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. */LOG (GNUNET_ERROR_TYPE_DEBUG,
777  "Disconnecting peer `%s'.\n",
778  GNUNET_i2s (peer));
779  s->env->bandwidth_changed_cb (s->env->cls,
780  current_address);
781  return;
782  }
783  }
784  if (NULL == best_address)
785  {
786  /* We do not have a new address, so we are done. */
788  "Cannot suggest address for peer `%s'\n",
789  GNUNET_i2s (peer));
790  return;
791  }
792  /* We do have a new address, activate it */
794  "Selecting new address %p for peer `%s'\n",
795  best_address,
796  GNUNET_i2s (peer));
797  /* Mark address as active */
798  best_address->active = GNUNET_YES;
799  asi_best->activated = GNUNET_TIME_absolute_get ();
800  asi_best->network->active_addresses++;
801  s->active_addresses++;
803  "# ATS active addresses total",
804  1,
805  GNUNET_NO);
807  asi_best->network->stat_active,
808  1,
809  GNUNET_NO);
811  "Address %p for peer `%s' is now active\n",
812  best_address,
813  GNUNET_i2s (peer));
814 
815  if (GNUNET_NO ==
817  0))
818  {
819  /* we went over the maximum number of addresses for
820  this scope; remove the address with the smallest
821  connectivity requirement */
822  con_min = UINT32_MAX;
823  aw_min = NULL;
824  for (aw = asi_best->network->head; NULL != aw; aw = aw->next)
825  {
826  if ((con_min >
827  (a_con = s->env->get_connectivity (s->env->cls,
828  &aw->addr->peer))) &&
829  (GNUNET_YES == aw->addr->active))
830  {
831  aw_min = aw;
832  con_min = a_con;
833  if (0 == con_min)
834  break;
835  }
836  }
838  aw_min->addr,
839  &aw_min->addr->peer);
840  }
842  asi_best->network);
843 }
844 
845 
854 static void
856  const struct GNUNET_PeerIdentity *peer,
857  enum GNUNET_ATS_PreferenceKind kind,
858  double pref_rel)
859 {
860  struct GAS_PROPORTIONAL_Handle *s = solver;
861 
863  return; /* we do not care */
865  NULL);
866 }
867 
868 
879 static void
881  struct GNUNET_SERVICE_Client *application,
882  const struct GNUNET_PeerIdentity *peer,
883  const struct GNUNET_TIME_Relative scope,
884  enum GNUNET_ATS_PreferenceKind kind,
885  double score)
886 {
887  /* Proportional does not care about feedback */
888 }
889 
890 
897 static void
899  const struct GNUNET_PeerIdentity *peer)
900 {
901  struct GAS_PROPORTIONAL_Handle *s = solver;
902 
905  peer),
906  peer);
907 }
908 
909 
916 static void
918  const struct GNUNET_PeerIdentity *peer)
919 {
920  struct GAS_PROPORTIONAL_Handle *s = solver;
921  struct ATS_Address *cur;
922  struct AddressWrapper *asi;
923 
924  cur = get_active_address (s,
925  peer);
926  if (NULL == cur)
927  return;
928  asi = cur->solver_information;
930  asi->network);
931 }
932 
933 
939 static void
941 {
942  struct GAS_PROPORTIONAL_Handle *s = solver;
943 
945  "Locking solver for bulk operation ...\n");
946  GNUNET_assert (NULL != solver);
947  s->bulk_lock++;
948 }
949 
950 
956 static void
958 {
959  struct GAS_PROPORTIONAL_Handle *s = solver;
960 
962  "Unlocking solver from bulk operation ...\n");
963  if (s->bulk_lock < 1)
964  {
965  GNUNET_break (0);
966  return;
967  }
968  s->bulk_lock--;
969  if ((0 == s->bulk_lock) &&
970  (0 < s->bulk_requests))
971  {
973  "No lock pending, recalculating\n");
975  NULL);
976  s->bulk_requests = 0;
977  }
978 }
979 
980 
987 static void
989  struct ATS_Address *address)
990 {
991  struct GAS_PROPORTIONAL_Handle *s = solver;
992  struct AddressWrapper *asi = address->solver_information;
993 
995  asi->network);
996 }
997 
998 
1006 static void
1008  struct ATS_Address *address,
1009  uint32_t network)
1010 {
1011  struct GAS_PROPORTIONAL_Handle *s = solver;
1012  struct Network *net;
1013  struct AddressWrapper *aw;
1014 
1015  GNUNET_assert (network < s->env->network_count);
1016  net = &s->network_entries[network];
1017  net->total_addresses++;
1018 
1019  aw = GNUNET_new (struct AddressWrapper);
1020  aw->addr = address;
1021  aw->network = net;
1022  address->solver_information = aw;
1024  net->tail,
1025  aw);
1027  "# ATS addresses total",
1028  1,
1029  GNUNET_NO);
1031  net->stat_total,
1032  1,
1033  GNUNET_NO);
1035  get_active_address (s,
1036  &address->peer),
1037  &address->peer);
1039  "Added new address for `%s', now total %u and active %u addresses in network `%s'\n",
1040  GNUNET_i2s (&address->peer),
1041  net->total_addresses,
1042  net->active_addresses,
1043  net->desc);
1044 }
1045 
1046 
1058 static void
1060  struct ATS_Address *address)
1061 {
1062  struct GAS_PROPORTIONAL_Handle *s = solver;
1063  struct AddressWrapper *aw = address->solver_information;
1064  struct Network *net = aw->network;
1065 
1067  "Deleting %s address for peer `%s' from network `%s' (total: %u/active: %u)\n",
1068  (GNUNET_NO == address->active) ? "inactive" : "active",
1069  GNUNET_i2s (&address->peer),
1070  net->desc,
1071  net->total_addresses,
1072  net->active_addresses);
1073 
1075  net->tail,
1076  aw);
1077  GNUNET_assert (net->total_addresses > 0);
1078  net->total_addresses--;
1080  net->stat_total,
1081  -1,
1082  GNUNET_NO);
1083  if (GNUNET_YES == address->active)
1084  {
1085  /* Address was active, remove from network and update quotas */
1087  address,
1088  &address->peer);
1090  }
1091  GNUNET_free (aw);
1092  address->solver_information = NULL;
1094  "After deleting address now total %u and active %u addresses in network `%s'\n",
1095  net->total_addresses,
1096  net->active_addresses,
1097  net->desc);
1098 }
1099 
1100 
1108 void *
1110 {
1111  static struct GNUNET_ATS_SolverFunctions sf;
1113  struct GAS_PROPORTIONAL_Handle *s;
1114  struct Network *cur;
1115  float f_tmp;
1116  unsigned int c;
1117 
1118  s = GNUNET_new (struct GAS_PROPORTIONAL_Handle);
1119  s->env = env;
1120  sf.cls = s;
1131  if (GNUNET_SYSERR !=
1133  "ats",
1134  "PROP_STABILITY_FACTOR",
1135  &f_tmp))
1136  {
1137  if ((f_tmp < 1.0) || (f_tmp > 2.0))
1138  {
1140  _ ("Invalid %s configuration %f \n"),
1141  "PROP_STABILITY_FACTOR",
1142  f_tmp);
1143  }
1144  else
1145  {
1146  s->stability_factor = f_tmp;
1148  "Using %s of %.3f\n",
1149  "PROP_STABILITY_FACTOR",
1150  f_tmp);
1151  }
1152  }
1154  if (GNUNET_SYSERR !=
1156  "ats",
1157  "PROP_PROPORTIONALITY_FACTOR",
1158  &f_tmp))
1159  {
1160  if (f_tmp < 1.0)
1161  {
1163  _ ("Invalid %s configuration %f\n"),
1164  "PROP_PROPORTIONALITY_FACTOR",
1165  f_tmp);
1166  }
1167  else
1168  {
1169  s->prop_factor = f_tmp;
1171  "Using %s of %.3f\n",
1172  "PROP_PROPORTIONALITY_FACTOR",
1173  f_tmp);
1174  }
1175  }
1176 
1178  * sizeof(struct Network));
1179  for (c = 0; c < env->network_count; c++)
1180  {
1181  cur = &s->network_entries[c];
1182  cur->type = c;
1183  cur->total_quota_in = env->in_quota[c];
1184  cur->total_quota_out = env->out_quota[c];
1185  cur->desc = GNUNET_NT_to_string (c);
1186  GNUNET_asprintf (&cur->stat_total,
1187  "# ATS addresses %s total",
1188  cur->desc);
1190  "# ATS active addresses %s total",
1191  cur->desc);
1193  "Added network %u `%s' (%llu/%llu)\n",
1194  c,
1195  cur->desc,
1196  cur->total_quota_in,
1197  cur->total_quota_out);
1198  }
1199  return &sf;
1200 }
1201 
1202 
1208 void *
1210 {
1211  struct GNUNET_ATS_SolverFunctions *sf = cls;
1212  struct GAS_PROPORTIONAL_Handle *s = sf->cls;
1213  struct AddressWrapper *cur;
1214  struct AddressWrapper *next;
1215  unsigned int c;
1216 
1217  for (c = 0; c < s->env->network_count; c++)
1218  {
1221  next = s->network_entries[c].head;
1222  while (NULL != (cur = next))
1223  {
1224  next = cur->next;
1226  s->network_entries[c].tail,
1227  cur);
1229  GNUNET_free (cur);
1230  }
1233  }
1234  GNUNET_break (0 == s->active_addresses);
1236  GNUNET_free (s);
1237  return NULL;
1238 }
1239 
1240 
1241 /* 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:44
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.
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:78
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:75
#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.
struct GNUNET_STATISTICS_Handle * stats
Statistics handle to be used by the solver.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
Handle to a client that is connected to a service.
Definition: service.c:250
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.
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.
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.
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:76
void * solver_information
Solver-specific information for this address.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
unsigned int active_addresses
Number of active addresses for solver.
void * cls
Closure to pass to all callbacks in this struct.
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:375
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
struct ATS_Address * addr
The address.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
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.