GNUnet  0.19.4
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;
222  "No bandwidth available in network\n");
223  return GNUNET_NO;
224 }
225 
226 
236 static int
238  struct Network *net,
239  unsigned int con)
240 {
241  struct AddressWrapper *aw;
242 
243  for (aw = net->head; NULL != aw; aw = aw->next)
244  if (con >
245  s->env->get_connectivity (s->env->cls,
246  &aw->addr->peer))
247  return GNUNET_NO;
248  return GNUNET_YES;
249 }
250 
251 
261 static void
263  struct Network *net)
264 {
265  const uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
266  struct AddressWrapper *aw;
267  unsigned long long remaining_quota_in;
268  unsigned long long quota_out_used;
269  unsigned long long remaining_quota_out;
270  unsigned long long quota_in_used;
271  unsigned int count_addresses;
272  double sum_relative_peer_prefences;
273  double peer_weight;
274  double total_weight;
275  const double *peer_relative_prefs;
276 
278  "Recalculate quota for network type `%s' for %u addresses (in/out): %llu/%llu \n",
279  net->desc,
280  net->active_addresses,
281  net->total_quota_in,
282  net->total_quota_in);
283 
284  if (0 == net->active_addresses)
285  return; /* no addresses to update */
286 
287  /* sanity checks */
288  if ((net->active_addresses * min_bw) > net->total_quota_in)
289  {
290  GNUNET_break (0);
291  return;
292  }
293  if ((net->active_addresses * min_bw) > net->total_quota_out)
294  {
295  GNUNET_break (0);
296  return;
297  }
298 
299  /* Calculate sum of relative preference for active addresses in this
300  network */
301  sum_relative_peer_prefences = 0.0;
302  count_addresses = 0;
303  for (aw = net->head; NULL != aw; aw = aw->next)
304  {
305  if (GNUNET_YES != aw->addr->active)
306  continue;
307  peer_relative_prefs = s->env->get_preferences (s->env->cls,
308  &aw->addr->peer);
309  sum_relative_peer_prefences
310  += peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH];
311  count_addresses++;
312  }
313  if (count_addresses != net->active_addresses)
314  {
315  GNUNET_break (0);
317  "%s: Counted %u active addresses, expected %u active addresses\n",
318  net->desc,
320  net->active_addresses);
321  /* try to fix... */
323  }
325  "Total relative preference %.3f for %u addresses in network %s\n",
326  sum_relative_peer_prefences,
327  net->active_addresses,
328  net->desc);
329 
330  /* check how much we have to distribute */
331  remaining_quota_in = net->total_quota_in - (net->active_addresses * min_bw);
332  remaining_quota_out = net->total_quota_out - (net->active_addresses * min_bw);
334  "Proportionally distributable bandwidth (in/out): %llu/%llu\n",
335  remaining_quota_in,
336  remaining_quota_out);
337 
338  /* distribute remaining quota; we do not do it exactly proportional,
339  but balance "even" distribution ("net->active_addresses") with
340  the preference sum using the "prop_factor". */
341  total_weight = net->active_addresses
342  + s->prop_factor * sum_relative_peer_prefences;
343  quota_out_used = 0;
344  quota_in_used = 0;
345  for (aw = net->head; NULL != aw; aw = aw->next)
346  {
347  if (GNUNET_YES != aw->addr->active)
348  {
349  /* set to 0, just to be sure */
350  aw->calculated_quota_in = 0;
351  aw->calculated_quota_out = 0;
352  continue;
353  }
354  peer_relative_prefs = s->env->get_preferences (s->env->cls,
355  &aw->addr->peer);
356  peer_weight = 1.0
357  + s->prop_factor
358  * peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH];
359 
360  aw->calculated_quota_in = min_bw
361  + (peer_weight / total_weight)
362  * remaining_quota_in;
363  aw->calculated_quota_out = min_bw
364  + (peer_weight / total_weight)
365  * remaining_quota_out;
366 
368  "New quotas for peer `%s' with weight (cur/total) %.3f/%.3f (in/out) are: %u/%u\n",
369  GNUNET_i2s (&aw->addr->peer),
370  peer_weight,
371  total_weight,
372  (unsigned int) aw->calculated_quota_in,
373  (unsigned int) aw->calculated_quota_out);
374  quota_in_used += aw->calculated_quota_in;
375  quota_out_used += aw->calculated_quota_out;
376  }
378  "Total bandwidth assigned is (in/out): %llu /%llu\n",
379  quota_in_used,
380  quota_out_used);
381  /* +1 due to possible rounding errors */
382  GNUNET_break (quota_out_used <= net->total_quota_out + 1);
383  GNUNET_break (quota_in_used <= net->total_quota_in + 1);
384 }
385 
386 
393 static void
395  struct Network *net)
396 {
397  struct AddressWrapper *cur;
398 
399  for (cur = net->head; NULL != cur; cur = cur->next)
400  {
401  if ((cur->addr->assigned_bw_in == cur->calculated_quota_in) &&
402  (cur->addr->assigned_bw_out == cur->calculated_quota_out))
403  continue;
406  if (GNUNET_YES == cur->addr->active)
407  s->env->bandwidth_changed_cb (s->env->cls,
408  cur->addr);
409  }
410 }
411 
412 
420 static void
422  struct Network *n)
423 {
424  unsigned int i;
425 
426  if (0 != s->bulk_lock)
427  {
428  s->bulk_requests++;
429  return;
430  }
431  if (NULL != n)
432  {
434  "Redistributing bandwidth in network %s with %u active and %u total addresses\n",
436  n->active_addresses,
437  n->total_addresses);
438  s->env->info_cb (s->env->cls,
443  n);
444  s->env->info_cb (s->env->cls,
448  s->env->info_cb (s->env->cls,
453  n);
454 
455  s->env->info_cb (s->env->cls,
459  }
460  else
461  {
463  "Redistributing bandwidth in all %u networks\n",
464  s->env->network_count);
465  s->env->info_cb (s->env->cls,
469  for (i = 0; i < s->env->network_count; i++)
471  &s->network_entries[i]);
472  s->env->info_cb (s->env->cls,
476  s->env->info_cb (s->env->cls,
480  for (i = 0; i < s->env->network_count; i++)
482  &s->network_entries[i]);
483  s->env->info_cb (s->env->cls,
487  }
488 }
489 
490 
495 {
500 
504  struct ATS_Address *best;
505 };
506 
507 
519 static int
521  const struct GNUNET_PeerIdentity *key,
522  void *value)
523 {
524  struct FindBestAddressCtx *ctx = cls;
525  struct ATS_Address *current = value;
526  struct AddressWrapper *asi = current->solver_information;
527  struct GNUNET_TIME_Relative active_time;
528  double best_delay;
529  double best_distance;
530  double cur_delay;
531  double cur_distance;
532  unsigned int con;
533  int bw_available;
534  int need;
535 
536  /* we need +1 slot if 'current' is not yet active */
537  need = (GNUNET_YES == current->active) ? 0 : 1;
538  /* we save -1 slot if 'best' is active and belongs
539  to the same network (as we would replace it) */
540  if ((NULL != ctx->best) &&
541  (GNUNET_YES == ctx->best->active) &&
542  (((struct AddressWrapper *) ctx->best->solver_information)->network ==
543  asi->network))
544  need--;
545  /* we can gain -1 slot if this peers connectivity
546  requirement is higher than that of another peer
547  in that network scope */
548  con = ctx->s->env->get_connectivity (ctx->s->env->cls,
549  key);
550  if (GNUNET_YES !=
552  asi->network,
553  con))
554  need--;
555  /* test if minimum bandwidth for 'current' would be available */
556  bw_available
558  need);
559  if (! bw_available)
560  {
561  /* Bandwidth for this address is unavailable, so we cannot use
562  it. */
563  return GNUNET_OK;
564  }
565  if (GNUNET_YES == current->active)
566  {
567  active_time = GNUNET_TIME_absolute_get_duration (asi->activated);
568  if (active_time.rel_value_us <=
569  ((double) GNUNET_TIME_UNIT_SECONDS.rel_value_us)
570  * ctx->s->stability_factor)
571  {
572  /* Keep active address for stability reasons */
573  ctx->best = current;
574  return GNUNET_NO;
575  }
576  }
577  if (NULL == ctx->best)
578  {
579  /* We so far have nothing else, so go with it! */
580  ctx->best = current;
581  return GNUNET_OK;
582  }
583 
584  /* Now compare ATS information */
585  cur_distance = current->norm_distance.norm;
586  best_distance = ctx->best->norm_distance.norm;
587  cur_delay = current->norm_delay.norm;
588  best_delay = ctx->best->norm_delay.norm;
589 
590  /* user shorter distance */
591  if (cur_distance < best_distance)
592  {
593  if (GNUNET_NO == ctx->best->active)
594  {
595  /* Activity doesn't influence the equation, use current */
596  ctx->best = current;
597  }
598  else if ((best_distance / cur_distance) > ctx->s->stability_factor)
599  {
600  /* Distance change is significant, switch active address! */
601  ctx->best = current;
602  }
603  }
604 
605  /* User connection with less delay */
606  if (cur_delay < best_delay)
607  {
608  if (GNUNET_NO == ctx->best->active)
609  {
610  /* Activity doesn't influence the equation, use current */
611  ctx->best = current;
612  }
613  else if ((best_delay / cur_delay) > ctx->s->stability_factor)
614  {
615  /* Latency change is significant, switch active address! */
616  ctx->best = current;
617  }
618  }
619  return GNUNET_OK;
620 }
621 
622 
632 struct ATS_Address *
635  const struct GNUNET_PeerIdentity *id)
636 {
637  struct FindBestAddressCtx fba_ctx;
638 
639  fba_ctx.best = NULL;
640  fba_ctx.s = s;
642  id,
644  &fba_ctx);
645  return fba_ctx.best;
646 }
647 
648 
655 static void
657  struct Network *net)
658 {
659  GNUNET_assert (net->active_addresses > 0);
660  net->active_addresses--;
662  net->stat_active,
663  -1,
664  GNUNET_NO);
666  s->active_addresses--;
668  "# ATS addresses total",
669  -1,
670  GNUNET_NO);
671 }
672 
673 
683 static int
685  const struct GNUNET_PeerIdentity *key,
686  void *value)
687 {
688  struct ATS_Address **dest = cls;
689  struct ATS_Address *aa = value;
690 
691  if (GNUNET_YES != aa->active)
692  return GNUNET_OK;
693  GNUNET_assert (NULL == (*dest));
694  (*dest) = aa;
695  return GNUNET_OK;
696 }
697 
698 
706 static struct ATS_Address *
708  const struct GNUNET_PeerIdentity *peer)
709 {
710  struct ATS_Address *dest;
711 
712  dest = NULL;
714  peer,
716  &dest);
717  return dest;
718 }
719 
720 
731 static void
733  struct ATS_Address *current_address,
734  const struct GNUNET_PeerIdentity *peer)
735 {
736  struct ATS_Address *best_address;
737  struct AddressWrapper *asi_cur;
738  struct AddressWrapper *asi_best;
739  struct AddressWrapper *aw;
740  struct AddressWrapper *aw_min;
741  unsigned int a_con;
742  unsigned int con_min;
743 
744  best_address = get_best_address (s,
745  s->env->addresses,
746  peer);
747  if (NULL != best_address)
748  asi_best = best_address->solver_information;
749  else
750  asi_best = NULL;
751  if (current_address == best_address)
752  return; /* no changes */
753  if (NULL != current_address)
754  {
755  /* We switch to a new address (or to none);
756  mark old address as inactive. */
757  asi_cur = current_address->solver_information;
758  GNUNET_assert (GNUNET_YES == current_address->active);
760  "Disabling previous active address for peer `%s'\n",
761  GNUNET_i2s (peer));
763  current_address->active = GNUNET_NO;
764  current_address->assigned_bw_in = 0;
765  current_address->assigned_bw_out = 0;
767  asi_cur->network);
768  if ((NULL == best_address) ||
769  (asi_best->network != asi_cur->network))
771  asi_cur->network);
772  if (NULL == best_address)
773  {
774  /* We previously had an active address, but now we cannot
775  * suggest one. Therefore we have to disconnect the peer.
776  * The above call to "distribute_bandwidth_in_network()
777  * does not see 'current_address' so we need to trigger
778  * the update here. */LOG (GNUNET_ERROR_TYPE_DEBUG,
779  "Disconnecting peer `%s'.\n",
780  GNUNET_i2s (peer));
781  s->env->bandwidth_changed_cb (s->env->cls,
782  current_address);
783  return;
784  }
785  }
786  if (NULL == best_address)
787  {
788  /* We do not have a new address, so we are done. */
790  "Cannot suggest address for peer `%s'\n",
791  GNUNET_i2s (peer));
792  return;
793  }
794  /* We do have a new address, activate it */
796  "Selecting new address %p for peer `%s'\n",
797  best_address,
798  GNUNET_i2s (peer));
799  /* Mark address as active */
800  best_address->active = GNUNET_YES;
801  asi_best->activated = GNUNET_TIME_absolute_get ();
802  asi_best->network->active_addresses++;
803  s->active_addresses++;
805  "# ATS active addresses total",
806  1,
807  GNUNET_NO);
809  asi_best->network->stat_active,
810  1,
811  GNUNET_NO);
813  "Address %p for peer `%s' is now active\n",
814  best_address,
815  GNUNET_i2s (peer));
816 
817  if (GNUNET_NO ==
819  0))
820  {
821  /* we went over the maximum number of addresses for
822  this scope; remove the address with the smallest
823  connectivity requirement */
824  con_min = UINT32_MAX;
825  aw_min = NULL;
826  for (aw = asi_best->network->head; NULL != aw; aw = aw->next)
827  {
828  if ((con_min >
829  (a_con = s->env->get_connectivity (s->env->cls,
830  &aw->addr->peer))) &&
831  (GNUNET_YES == aw->addr->active))
832  {
833  aw_min = aw;
834  con_min = a_con;
835  if (0 == con_min)
836  break;
837  }
838  }
840  aw_min->addr,
841  &aw_min->addr->peer);
842  }
844  asi_best->network);
845 }
846 
847 
856 static void
858  const struct GNUNET_PeerIdentity *peer,
859  enum GNUNET_ATS_PreferenceKind kind,
860  double pref_rel)
861 {
862  struct GAS_PROPORTIONAL_Handle *s = solver;
863 
865  return; /* we do not care */
867  NULL);
868 }
869 
870 
881 static void
883  struct GNUNET_SERVICE_Client *application,
884  const struct GNUNET_PeerIdentity *peer,
885  const struct GNUNET_TIME_Relative scope,
886  enum GNUNET_ATS_PreferenceKind kind,
887  double score)
888 {
889  /* Proportional does not care about feedback */
890 }
891 
892 
899 static void
901  const struct GNUNET_PeerIdentity *peer)
902 {
903  struct GAS_PROPORTIONAL_Handle *s = solver;
904 
907  peer),
908  peer);
909 }
910 
911 
918 static void
920  const struct GNUNET_PeerIdentity *peer)
921 {
922  struct GAS_PROPORTIONAL_Handle *s = solver;
923  struct ATS_Address *cur;
924  struct AddressWrapper *asi;
925 
926  cur = get_active_address (s,
927  peer);
928  if (NULL == cur)
929  return;
930  asi = cur->solver_information;
932  asi->network);
933 }
934 
935 
941 static void
943 {
944  struct GAS_PROPORTIONAL_Handle *s = solver;
945 
947  "Locking solver for bulk operation ...\n");
948  GNUNET_assert (NULL != solver);
949  s->bulk_lock++;
950 }
951 
952 
958 static void
960 {
961  struct GAS_PROPORTIONAL_Handle *s = solver;
962 
964  "Unlocking solver from bulk operation ...\n");
965  if (s->bulk_lock < 1)
966  {
967  GNUNET_break (0);
968  return;
969  }
970  s->bulk_lock--;
971  if ((0 == s->bulk_lock) &&
972  (0 < s->bulk_requests))
973  {
975  "No lock pending, recalculating\n");
977  NULL);
978  s->bulk_requests = 0;
979  }
980 }
981 
982 
989 static void
991  struct ATS_Address *address)
992 {
993  struct GAS_PROPORTIONAL_Handle *s = solver;
994  struct AddressWrapper *asi = address->solver_information;
995 
997  asi->network);
998 }
999 
1000 
1008 static void
1010  struct ATS_Address *address,
1011  uint32_t network)
1012 {
1013  struct GAS_PROPORTIONAL_Handle *s = solver;
1014  struct Network *net;
1015  struct AddressWrapper *aw;
1016 
1017  GNUNET_assert (network < s->env->network_count);
1018  net = &s->network_entries[network];
1019  net->total_addresses++;
1020 
1021  aw = GNUNET_new (struct AddressWrapper);
1022  aw->addr = address;
1023  aw->network = net;
1024  address->solver_information = aw;
1026  net->tail,
1027  aw);
1029  "# ATS addresses total",
1030  1,
1031  GNUNET_NO);
1033  net->stat_total,
1034  1,
1035  GNUNET_NO);
1037  get_active_address (s,
1038  &address->peer),
1039  &address->peer);
1041  "Added new address for `%s', now total %u and active %u addresses in network `%s'\n",
1042  GNUNET_i2s (&address->peer),
1043  net->total_addresses,
1044  net->active_addresses,
1045  net->desc);
1046 }
1047 
1048 
1060 static void
1062  struct ATS_Address *address)
1063 {
1064  struct GAS_PROPORTIONAL_Handle *s = solver;
1065  struct AddressWrapper *aw = address->solver_information;
1066  struct Network *net = aw->network;
1067 
1069  "Deleting %s address for peer `%s' from network `%s' (total: %u/active: %u)\n",
1070  (GNUNET_NO == address->active) ? "inactive" : "active",
1071  GNUNET_i2s (&address->peer),
1072  net->desc,
1073  net->total_addresses,
1074  net->active_addresses);
1075 
1077  net->tail,
1078  aw);
1079  GNUNET_assert (net->total_addresses > 0);
1080  net->total_addresses--;
1082  net->stat_total,
1083  -1,
1084  GNUNET_NO);
1085  if (GNUNET_YES == address->active)
1086  {
1087  /* Address was active, remove from network and update quotas */
1089  address,
1090  &address->peer);
1092  }
1093  GNUNET_free (aw);
1094  address->solver_information = NULL;
1096  "After deleting address now total %u and active %u addresses in network `%s'\n",
1097  net->total_addresses,
1098  net->active_addresses,
1099  net->desc);
1100 }
1101 
1102 
1110 void *
1112 {
1113  static struct GNUNET_ATS_SolverFunctions sf;
1115  struct GAS_PROPORTIONAL_Handle *s;
1116  struct Network *cur;
1117  float f_tmp;
1118  unsigned int c;
1119 
1120  s = GNUNET_new (struct GAS_PROPORTIONAL_Handle);
1121  s->env = env;
1122  sf.cls = s;
1133  if (GNUNET_SYSERR !=
1135  "ats",
1136  "PROP_STABILITY_FACTOR",
1137  &f_tmp))
1138  {
1139  if ((f_tmp < 1.0) || (f_tmp > 2.0))
1140  {
1142  _ ("Invalid %s configuration %f \n"),
1143  "PROP_STABILITY_FACTOR",
1144  f_tmp);
1145  }
1146  else
1147  {
1148  s->stability_factor = f_tmp;
1150  "Using %s of %.3f\n",
1151  "PROP_STABILITY_FACTOR",
1152  f_tmp);
1153  }
1154  }
1156  if (GNUNET_SYSERR !=
1158  "ats",
1159  "PROP_PROPORTIONALITY_FACTOR",
1160  &f_tmp))
1161  {
1162  if (f_tmp < 1.0)
1163  {
1165  _ ("Invalid %s configuration %f\n"),
1166  "PROP_PROPORTIONALITY_FACTOR",
1167  f_tmp);
1168  }
1169  else
1170  {
1171  s->prop_factor = f_tmp;
1173  "Using %s of %.3f\n",
1174  "PROP_PROPORTIONALITY_FACTOR",
1175  f_tmp);
1176  }
1177  }
1178 
1179  s->network_entries = GNUNET_malloc (env->network_count
1180  * sizeof(struct Network));
1181  for (c = 0; c < env->network_count; c++)
1182  {
1183  cur = &s->network_entries[c];
1184  cur->type = c;
1185  cur->total_quota_in = env->in_quota[c];
1186  cur->total_quota_out = env->out_quota[c];
1187  cur->desc = GNUNET_NT_to_string (c);
1188  GNUNET_asprintf (&cur->stat_total,
1189  "# ATS addresses %s total",
1190  cur->desc);
1192  "# ATS active addresses %s total",
1193  cur->desc);
1195  "Added network %u `%s' (%llu/%llu)\n",
1196  c,
1197  cur->desc,
1198  cur->total_quota_in,
1199  cur->total_quota_out);
1200  }
1201  return &sf;
1202 }
1203 
1204 
1210 void *
1212 {
1213  struct GNUNET_ATS_SolverFunctions *sf = cls;
1214  struct GAS_PROPORTIONAL_Handle *s = sf->cls;
1215  struct AddressWrapper *cur;
1216  struct AddressWrapper *next;
1217  unsigned int c;
1218 
1219  for (c = 0; c < s->env->network_count; c++)
1220  {
1223  next = s->network_entries[c].head;
1224  while (NULL != (cur = next))
1225  {
1226  next = cur->next;
1228  s->network_entries[c].tail,
1229  cur);
1231  GNUNET_free (cur);
1232  }
1235  }
1236  GNUNET_break (0 == s->active_addresses);
1238  GNUNET_free (s);
1239  return NULL;
1240 }
1241 
1242 
1243 /* end of plugin_ats_proportional.c */
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct GNUNET_CONTAINER_MultiPeerMap * addresses
Hashmap to store addresses.
Definition: gnunet-ats.c:146
static char * address
GNS address for this phone.
struct GNUNET_HashCode key
The key used in the DHT.
static char * value
Value of the record to add/remove.
ats service address management
static struct GNUNET_ATS_SolverFunctions * sf
Solver handle.
static int count_addresses(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Address iterator that counts the remaining addresses.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
API for the ATS solvers.
Automatic transport selection and outbound bandwidth determination.
API to create, modify and access statistics.
@ GAS_STAT_SUCCESS
Success.
@ GAS_OP_SOLVE_UPDATE_NOTIFICATION_START
After the problem was finished, start notifications about changes to addresses.
@ GAS_OP_SOLVE_START
A solution iteration has been started.
@ GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP
After the problem was finished, notifications about changes to addresses are done.
@ GAS_OP_SOLVE_STOP
A solution iteration has been finished.
@ GAS_INFO_PROP_ALL
The proportional solver had to recalculate for all networks.
@ GAS_INFO_PROP_SINGLE
The proportional solver had to recalculate for a single network.
GNUNET_ATS_PreferenceKind
Enum defining all known preference categories.
@ GNUNET_ATS_PREFERENCE_BANDWIDTH
Change the peer's bandwidth value (value per byte of bandwidth in the goal function) to the given amo...
enum GNUNET_GenericReturnValue 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.
#define GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT
Bandwidth (in/out) to assume initially (before either peer has communicated any particular preference...
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
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.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:39
const char * GNUNET_NT_to_string(enum GNUNET_NetworkType net)
Convert a enum GNUNET_NetworkType to a string.
Definition: nt.c:38
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 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:436
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
static void GAS_proportional_address_delete(void *solver, struct ATS_Address *address)
Remove an address from the solver.
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_address_property_changed(void *solver, struct ATS_Address *address)
Transport properties for this address have changed.
static void distribute_bandwidth(struct GAS_PROPORTIONAL_Handle *s, struct Network *net)
Update bandwidth assigned to peers in this network.
static void propagate_bandwidth(struct GAS_PROPORTIONAL_Handle *s, struct Network *net)
Notify ATS service of bandwidth changes to addresses.
void * libgnunet_plugin_ats_proportional_done(void *cls)
Function used to unload the plugin.
static void GAS_proportional_stop_get_address(void *solver, const struct GNUNET_PeerIdentity *peer)
Stop notifying about address and bandwidth changes for this peer.
#define PROPORTIONALITY_FACTOR
Default value to assume for the proportionality factor, if none is given in the configuration.
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 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.
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.
static void distribute_bandwidth_in_network(struct GAS_PROPORTIONAL_Handle *s, struct Network *n)
Distribute bandwidth.
static void GAS_proportional_address_add(void *solver, struct ATS_Address *address, uint32_t network)
Add a new single address to a network.
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.
#define PROP_STABILITY_FACTOR
How much do we value stability over adaptation by default.
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 void GAS_proportional_start_get_address(void *solver, const struct GNUNET_PeerIdentity *peer)
Get the preferred address for a specific peer.
#define LOG(kind,...)
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.
void * libgnunet_plugin_ats_proportional_init(void *cls)
Function invoked when the plugin is loaded.
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.
static void GAS_proportional_bulk_start(void *solver)
Start a bulk operation.
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 GAS_proportional_bulk_stop(void *solver)
Bulk operation done.
static void address_decrement_active(struct GAS_PROPORTIONAL_Handle *s, struct Network *net)
Decrease number of active addresses in network.
static enum GNUNET_NetworkType scope
Which network scope do we belong to?
Address with additional information.
struct GAS_NormalizationInfo norm_delay
Normalized delay information for this address.
uint32_t assigned_bw_in
Inbound bandwidth assigned by solver.
struct GNUNET_PeerIdentity peer
Peer ID this address is for.
int active
Is this the active address for this peer?
void * solver_information
Solver-specific information for this address.
uint32_t assigned_bw_out
Outbound bandwidth assigned by solver.
struct GAS_NormalizationInfo norm_distance
Normalized distance information for this address.
Address information stored for the proportional solver in the solver_information member of struct GNU...
struct ATS_Address * addr
The address.
struct AddressWrapper * prev
Previous in DLL.
uint32_t calculated_quota_in
Inbound quota.
struct Network * network
Network scope this address is in.
struct AddressWrapper * next
Next in DLL.
struct GNUNET_TIME_Absolute activated
When was this address activated.
uint32_t calculated_quota_out
Outbound quota.
Context for finding the best address* Linked list of addresses in this network: head.
struct ATS_Address * best
The currently best address.
struct GAS_PROPORTIONAL_Handle * s
The solver handle.
double norm
Normalized values from queue to a range of values [1.0...2.0].
A handle for the proportional solver.
double prop_factor
Proportionality factor.
double stability_factor
Stability factor.
struct Network * network_entries
Networks array.
unsigned int bulk_requests
Number of changes made while solver was locked.
unsigned int active_addresses
Number of active addresses for solver.
struct GNUNET_ATS_PluginEnvironment * env
Our execution environment.
unsigned int bulk_lock
Bulk lock counter.
The ATS plugin will pass a pointer to a struct of this type as to the initialization function of the ...
void * cls
Closure to pass to all callbacks in this struct.
GAS_solver_information_callback info_cb
Callback for solver to call with status information, can be NULL.
GAS_get_preferences get_preferences
ATS addresses function to obtain preference values.
struct GNUNET_CONTAINER_MultiPeerMap * addresses
Hashmap containing all addresses available.
GAS_get_connectivity get_connectivity
ATS addresses function to obtain preference values.
unsigned int network_count
Number of networks available, size of the out_quota and in_quota arrays.
GAS_bandwidth_changed_cb bandwidth_changed_cb
ATS addresses callback to be notified about bandwidth assignment changes.
struct GNUNET_STATISTICS_Handle * stats
Statistics handle to be used by the solver.
GAS_solver_address_feedback_preference s_feedback
Give feedback about the current assignment.
GAS_solver_address_property_changed s_address_update_property
Update the properties of an address in the solver.
GAS_solver_address_add s_add
Add a new address for a peer to the solver.
void * cls
Closure to pass to all solver functions in this struct.
GAS_solver_bulk_start s_bulk_start
Start a bulk operation.
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...
GAS_solver_bulk_stop s_bulk_stop
Bulk operation done.
GAS_solver_address_change_preference s_pref
Change relative preference for quality in solver.
GAS_solver_stop_get_preferred_address s_get_stop
Tell solver stop notifying ATS about changes for this peers.
GAS_solver_address_delete s_del
Delete an address in the solver.
Internal representation of the hash map.
The identity of the host (wraps the signing key of the peer).
Handle to a client that is connected to a service.
Definition: service.c:252
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Representation of a network.
unsigned int active_addresses
Number of active addresses for this network.
struct AddressWrapper * tail
Linked list of addresses in this network: tail.
unsigned long long total_quota_in
Total inbound quota.
char * stat_active
String for statistics active addresses.
struct AddressWrapper * head
Linked list of addresses in this network: head.
const char * desc
Network description.
enum GNUNET_NetworkType type
ATS network type.
char * stat_total
String for statistics total addresses.
unsigned long long total_quota_out
Total outbound quota.
unsigned int total_addresses
Number of total addresses for this network.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.