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 
66 
71 
75  struct ATS_Address *addr;
76 
80  struct Network *network;
81 
86 
91 
96 };
97 
98 
102 struct Network {
106  const char *desc;
107 
111  char *stat_total;
112 
116  char *stat_active;
117 
122 
127 
131  unsigned long long total_quota_in;
132 
136  unsigned long long total_quota_out;
137 
142 
146  unsigned int active_addresses;
147 
151  unsigned int total_addresses;
152 };
153 
154 
163 
168 
172  double prop_factor;
173 
178 
182  unsigned int bulk_lock;
183 
188  unsigned int bulk_requests;
189 
193  unsigned int active_addresses;
194 };
195 
196 
204 static int
206  int extra)
207 {
208  unsigned int na;
209  uint32_t min_bw = ntohl(GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
210 
211  GNUNET_assert(((int)net->active_addresses) + extra >= 0);
212  na = net->active_addresses + extra;
213  if (0 == na)
214  return GNUNET_YES;
215  if (((net->total_quota_in / na) > min_bw) &&
216  ((net->total_quota_out / na) > min_bw))
217  return GNUNET_YES;
218  return GNUNET_NO;
219 }
220 
221 
231 static int
233  struct Network *net,
234  unsigned int con)
235 {
236  struct AddressWrapper *aw;
237 
238  for (aw = net->head; NULL != aw; aw = aw->next)
239  if (con >
240  s->env->get_connectivity(s->env->cls,
241  &aw->addr->peer))
242  return GNUNET_NO;
243  return GNUNET_YES;
244 }
245 
246 
256 static void
258  struct Network *net)
259 {
260  const uint32_t min_bw = ntohl(GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
261  struct AddressWrapper *aw;
262  unsigned long long remaining_quota_in;
263  unsigned long long quota_out_used;
264  unsigned long long remaining_quota_out;
265  unsigned long long quota_in_used;
266  unsigned int count_addresses;
267  double sum_relative_peer_prefences;
268  double peer_weight;
269  double total_weight;
270  const double *peer_relative_prefs;
271 
273  "Recalculate quota for network type `%s' for %u addresses (in/out): %llu/%llu \n",
274  net->desc,
275  net->active_addresses,
276  net->total_quota_in,
277  net->total_quota_in);
278 
279  if (0 == net->active_addresses)
280  return; /* no addresses to update */
281 
282  /* sanity checks */
283  if ((net->active_addresses * min_bw) > net->total_quota_in)
284  {
285  GNUNET_break(0);
286  return;
287  }
288  if ((net->active_addresses * min_bw) > net->total_quota_out)
289  {
290  GNUNET_break(0);
291  return;
292  }
293 
294  /* Calculate sum of relative preference for active addresses in this
295  network */
296  sum_relative_peer_prefences = 0.0;
297  count_addresses = 0;
298  for (aw = net->head; NULL != aw; aw = aw->next)
299  {
300  if (GNUNET_YES != aw->addr->active)
301  continue;
302  peer_relative_prefs = s->env->get_preferences(s->env->cls,
303  &aw->addr->peer);
304  sum_relative_peer_prefences
305  += peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH];
306  count_addresses++;
307  }
308  if (count_addresses != net->active_addresses)
309  {
310  GNUNET_break(0);
312  "%s: Counted %u active addresses, expected %u active addresses\n",
313  net->desc,
314  count_addresses,
315  net->active_addresses);
316  /* try to fix... */
318  }
320  "Total relative preference %.3f for %u addresses in network %s\n",
321  sum_relative_peer_prefences,
322  net->active_addresses,
323  net->desc);
324 
325  /* check how much we have to distribute */
326  remaining_quota_in = net->total_quota_in - (net->active_addresses * min_bw);
327  remaining_quota_out = net->total_quota_out - (net->active_addresses * min_bw);
329  "Proportionally distributable bandwidth (in/out): %llu/%llu\n",
330  remaining_quota_in,
331  remaining_quota_out);
332 
333  /* distribute remaining quota; we do not do it exactly proportional,
334  but balance "even" distribution ("net->active_addresses") with
335  the preference sum using the "prop_factor". */
336  total_weight = net->active_addresses +
337  s->prop_factor * sum_relative_peer_prefences;
338  quota_out_used = 0;
339  quota_in_used = 0;
340  for (aw = net->head; NULL != aw; aw = aw->next)
341  {
342  if (GNUNET_YES != aw->addr->active)
343  {
344  /* set to 0, just to be sure */
345  aw->calculated_quota_in = 0;
346  aw->calculated_quota_out = 0;
347  continue;
348  }
349  peer_relative_prefs = s->env->get_preferences(s->env->cls,
350  &aw->addr->peer);
351  peer_weight = 1.0
352  + s->prop_factor * peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH];
353 
354  aw->calculated_quota_in = min_bw
355  + (peer_weight / total_weight) * remaining_quota_in;
356  aw->calculated_quota_out = min_bw
357  + (peer_weight / total_weight) * remaining_quota_out;
358 
360  "New quotas for peer `%s' with weight (cur/total) %.3f/%.3f (in/out) are: %u/%u\n",
361  GNUNET_i2s(&aw->addr->peer),
362  peer_weight,
363  total_weight,
364  (unsigned int)aw->calculated_quota_in,
365  (unsigned int)aw->calculated_quota_out);
366  quota_in_used += aw->calculated_quota_in;
367  quota_out_used += aw->calculated_quota_out;
368  }
370  "Total bandwidth assigned is (in/out): %llu /%llu\n",
371  quota_in_used,
372  quota_out_used);
373  /* +1 due to possible rounding errors */
374  GNUNET_break(quota_out_used <= net->total_quota_out + 1);
375  GNUNET_break(quota_in_used <= net->total_quota_in + 1);
376 }
377 
378 
385 static void
387  struct Network *net)
388 {
389  struct AddressWrapper *cur;
390 
391  for (cur = net->head; NULL != cur; cur = cur->next)
392  {
393  if ((cur->addr->assigned_bw_in == cur->calculated_quota_in) &&
394  (cur->addr->assigned_bw_out == cur->calculated_quota_out))
395  continue;
398  if (GNUNET_YES == cur->addr->active)
400  cur->addr);
401  }
402 }
403 
404 
412 static void
414  struct Network *n)
415 {
416  unsigned int i;
417 
418  if (0 != s->bulk_lock)
419  {
420  s->bulk_requests++;
421  return;
422  }
423  if (NULL != n)
424  {
426  "Redistributing bandwidth in network %s with %u active and %u total addresses\n",
428  n->active_addresses,
429  n->total_addresses);
430  s->env->info_cb(s->env->cls,
435  n);
436  s->env->info_cb(s->env->cls,
440  s->env->info_cb(s->env->cls,
445  n);
446 
447  s->env->info_cb(s->env->cls,
451  }
452  else
453  {
455  "Redistributing bandwidth in all %u networks\n",
456  s->env->network_count);
457  s->env->info_cb(s->env->cls,
461  for (i = 0; i < s->env->network_count; i++)
463  &s->network_entries[i]);
464  s->env->info_cb(s->env->cls,
468  s->env->info_cb(s->env->cls,
472  for (i = 0; i < s->env->network_count; i++)
474  &s->network_entries[i]);
475  s->env->info_cb(s->env->cls,
479  }
480 }
481 
482 
491 
495  struct ATS_Address *best;
496 };
497 
498 
510 static int
512  const struct GNUNET_PeerIdentity *key,
513  void *value)
514 {
515  struct FindBestAddressCtx *ctx = cls;
516  struct ATS_Address *current = value;
517  struct AddressWrapper *asi = current->solver_information;
518  struct GNUNET_TIME_Relative active_time;
519  double best_delay;
520  double best_distance;
521  double cur_delay;
522  double cur_distance;
523  unsigned int con;
524  int bw_available;
525  int need;
526 
527  /* we need +1 slot if 'current' is not yet active */
528  need = (GNUNET_YES == current->active) ? 0 : 1;
529  /* we save -1 slot if 'best' is active and belongs
530  to the same network (as we would replace it) */
531  if ((NULL != ctx->best) &&
532  (GNUNET_YES == ctx->best->active) &&
533  (((struct AddressWrapper *)ctx->best->solver_information)->network ==
534  asi->network))
535  need--;
536  /* we can gain -1 slot if this peers connectivity
537  requirement is higher than that of another peer
538  in that network scope */
539  con = ctx->s->env->get_connectivity(ctx->s->env->cls,
540  key);
541  if (GNUNET_YES !=
543  asi->network,
544  con))
545  need--;
546  /* test if minimum bandwidth for 'current' would be available */
547  bw_available
549  need);
550  if (!bw_available)
551  {
552  /* Bandwidth for this address is unavailable, so we cannot use
553  it. */
554  return GNUNET_OK;
555  }
556  if (GNUNET_YES == current->active)
557  {
558  active_time = GNUNET_TIME_absolute_get_duration(asi->activated);
559  if (active_time.rel_value_us <=
560  ((double)GNUNET_TIME_UNIT_SECONDS.rel_value_us) * ctx->s->stability_factor)
561  {
562  /* Keep active address for stability reasons */
563  ctx->best = current;
564  return GNUNET_NO;
565  }
566  }
567  if (NULL == ctx->best)
568  {
569  /* We so far have nothing else, so go with it! */
570  ctx->best = current;
571  return GNUNET_OK;
572  }
573 
574  /* Now compare ATS information */
575  cur_distance = current->norm_distance.norm;
576  best_distance = ctx->best->norm_distance.norm;
577  cur_delay = current->norm_delay.norm;
578  best_delay = ctx->best->norm_delay.norm;
579 
580  /* user shorter distance */
581  if (cur_distance < best_distance)
582  {
583  if (GNUNET_NO == ctx->best->active)
584  {
585  /* Activity doesn't influence the equation, use current */
586  ctx->best = current;
587  }
588  else if ((best_distance / cur_distance) > ctx->s->stability_factor)
589  {
590  /* Distance change is significant, switch active address! */
591  ctx->best = current;
592  }
593  }
594 
595  /* User connection with less delay */
596  if (cur_delay < best_delay)
597  {
598  if (GNUNET_NO == ctx->best->active)
599  {
600  /* Activity doesn't influence the equation, use current */
601  ctx->best = current;
602  }
603  else if ((best_delay / cur_delay) > ctx->s->stability_factor)
604  {
605  /* Latency change is significant, switch active address! */
606  ctx->best = current;
607  }
608  }
609  return GNUNET_OK;
610 }
611 
612 
622 struct ATS_Address *
625  const struct GNUNET_PeerIdentity *id)
626 {
627  struct FindBestAddressCtx fba_ctx;
628 
629  fba_ctx.best = NULL;
630  fba_ctx.s = s;
632  id,
634  &fba_ctx);
635  return fba_ctx.best;
636 }
637 
638 
645 static void
647  struct Network *net)
648 {
650  net->active_addresses--;
652  net->stat_active,
653  -1,
654  GNUNET_NO);
656  s->active_addresses--;
658  "# ATS addresses total",
659  -1,
660  GNUNET_NO);
661 }
662 
663 
673 static int
675  const struct GNUNET_PeerIdentity *key,
676  void *value)
677 {
678  struct ATS_Address **dest = cls;
679  struct ATS_Address *aa = value;
680 
681  if (GNUNET_YES != aa->active)
682  return GNUNET_OK;
683  GNUNET_assert(NULL == (*dest));
684  (*dest) = aa;
685  return GNUNET_OK;
686 }
687 
688 
696 static struct ATS_Address *
698  const struct GNUNET_PeerIdentity *peer)
699 {
700  struct ATS_Address *dest;
701 
702  dest = NULL;
704  peer,
706  &dest);
707  return dest;
708 }
709 
710 
721 static void
723  struct ATS_Address *current_address,
724  const struct GNUNET_PeerIdentity *peer)
725 {
726  struct ATS_Address *best_address;
727  struct AddressWrapper *asi_cur;
728  struct AddressWrapper *asi_best;
729  struct AddressWrapper *aw;
730  struct AddressWrapper *aw_min;
731  unsigned int a_con;
732  unsigned int con_min;
733 
734  best_address = get_best_address(s,
735  s->env->addresses,
736  peer);
737  if (NULL != best_address)
738  asi_best = best_address->solver_information;
739  else
740  asi_best = NULL;
741  if (current_address == best_address)
742  return; /* no changes */
743  if (NULL != current_address)
744  {
745  /* We switch to a new address (or to none);
746  mark old address as inactive. */
747  asi_cur = current_address->solver_information;
748  GNUNET_assert(GNUNET_YES == current_address->active);
750  "Disabling previous active address for peer `%s'\n",
751  GNUNET_i2s(peer));
753  current_address->active = GNUNET_NO;
754  current_address->assigned_bw_in = 0;
755  current_address->assigned_bw_out = 0;
757  asi_cur->network);
758  if ((NULL == best_address) ||
759  (asi_best->network != asi_cur->network))
761  asi_cur->network);
762  if (NULL == best_address)
763  {
764  /* We previously had an active address, but now we cannot
765  * suggest one. Therefore we have to disconnect the peer.
766  * The above call to "distribute_bandwidth_in_network()
767  * does not see 'current_address' so we need to trigger
768  * the update here. */
770  "Disconnecting peer `%s'.\n",
771  GNUNET_i2s(peer));
773  current_address);
774  return;
775  }
776  }
777  if (NULL == best_address)
778  {
779  /* We do not have a new address, so we are done. */
781  "Cannot suggest address for peer `%s'\n",
782  GNUNET_i2s(peer));
783  return;
784  }
785  /* We do have a new address, activate it */
787  "Selecting new address %p for peer `%s'\n",
788  best_address,
789  GNUNET_i2s(peer));
790  /* Mark address as active */
791  best_address->active = GNUNET_YES;
792  asi_best->activated = GNUNET_TIME_absolute_get();
793  asi_best->network->active_addresses++;
794  s->active_addresses++;
796  "# ATS active addresses total",
797  1,
798  GNUNET_NO);
800  asi_best->network->stat_active,
801  1,
802  GNUNET_NO);
804  "Address %p for peer `%s' is now active\n",
805  best_address,
806  GNUNET_i2s(peer));
807 
808  if (GNUNET_NO ==
810  0))
811  {
812  /* we went over the maximum number of addresses for
813  this scope; remove the address with the smallest
814  connectivity requirement */
815  con_min = UINT32_MAX;
816  aw_min = NULL;
817  for (aw = asi_best->network->head; NULL != aw; aw = aw->next)
818  {
819  if ((con_min >
820  (a_con = s->env->get_connectivity(s->env->cls,
821  &aw->addr->peer))) &&
822  (GNUNET_YES == aw->addr->active))
823  {
824  aw_min = aw;
825  con_min = a_con;
826  if (0 == con_min)
827  break;
828  }
829  }
831  aw_min->addr,
832  &aw_min->addr->peer);
833  }
835  asi_best->network);
836 }
837 
838 
847 static void
849  const struct GNUNET_PeerIdentity *peer,
850  enum GNUNET_ATS_PreferenceKind kind,
851  double pref_rel)
852 {
853  struct GAS_PROPORTIONAL_Handle *s = solver;
854 
856  return; /* we do not care */
858  NULL);
859 }
860 
861 
872 static void
874  struct GNUNET_SERVICE_Client *application,
875  const struct GNUNET_PeerIdentity *peer,
876  const struct GNUNET_TIME_Relative scope,
877  enum GNUNET_ATS_PreferenceKind kind,
878  double score)
879 {
880  /* Proportional does not care about feedback */
881 }
882 
883 
890 static void
892  const struct GNUNET_PeerIdentity *peer)
893 {
894  struct GAS_PROPORTIONAL_Handle *s = solver;
895 
898  peer),
899  peer);
900 }
901 
902 
909 static void
911  const struct GNUNET_PeerIdentity *peer)
912 {
913  struct GAS_PROPORTIONAL_Handle *s = solver;
914  struct ATS_Address *cur;
915  struct AddressWrapper *asi;
916 
917  cur = get_active_address(s,
918  peer);
919  if (NULL == cur)
920  return;
921  asi = cur->solver_information;
923  asi->network);
924 }
925 
926 
932 static void
934 {
935  struct GAS_PROPORTIONAL_Handle *s = solver;
936 
938  "Locking solver for bulk operation ...\n");
939  GNUNET_assert(NULL != solver);
940  s->bulk_lock++;
941 }
942 
943 
949 static void
951 {
952  struct GAS_PROPORTIONAL_Handle *s = solver;
953 
955  "Unlocking solver from bulk operation ...\n");
956  if (s->bulk_lock < 1)
957  {
958  GNUNET_break(0);
959  return;
960  }
961  s->bulk_lock--;
962  if ((0 == s->bulk_lock) &&
963  (0 < s->bulk_requests))
964  {
966  "No lock pending, recalculating\n");
968  NULL);
969  s->bulk_requests = 0;
970  }
971 }
972 
973 
980 static void
982  struct ATS_Address *address)
983 {
984  struct GAS_PROPORTIONAL_Handle *s = solver;
985  struct AddressWrapper *asi = address->solver_information;
986 
988  asi->network);
989 }
990 
991 
999 static void
1001  struct ATS_Address *address,
1002  uint32_t network)
1003 {
1004  struct GAS_PROPORTIONAL_Handle *s = solver;
1005  struct Network *net;
1006  struct AddressWrapper *aw;
1007 
1008  GNUNET_assert(network < s->env->network_count);
1009  net = &s->network_entries[network];
1010  net->total_addresses++;
1011 
1012  aw = GNUNET_new(struct AddressWrapper);
1013  aw->addr = address;
1014  aw->network = net;
1015  address->solver_information = aw;
1017  net->tail,
1018  aw);
1020  "# ATS addresses total",
1021  1,
1022  GNUNET_NO);
1024  net->stat_total,
1025  1,
1026  GNUNET_NO);
1029  &address->peer),
1030  &address->peer);
1032  "Added new address for `%s', now total %u and active %u addresses in network `%s'\n",
1033  GNUNET_i2s(&address->peer),
1034  net->total_addresses,
1035  net->active_addresses,
1036  net->desc);
1037 }
1038 
1039 
1051 static void
1053  struct ATS_Address *address)
1054 {
1055  struct GAS_PROPORTIONAL_Handle *s = solver;
1056  struct AddressWrapper *aw = address->solver_information;
1057  struct Network *net = aw->network;
1058 
1060  "Deleting %s address for peer `%s' from network `%s' (total: %u/active: %u)\n",
1061  (GNUNET_NO == address->active) ? "inactive" : "active",
1062  GNUNET_i2s(&address->peer),
1063  net->desc,
1064  net->total_addresses,
1065  net->active_addresses);
1066 
1068  net->tail,
1069  aw);
1070  GNUNET_assert(net->total_addresses > 0);
1071  net->total_addresses--;
1073  net->stat_total,
1074  -1,
1075  GNUNET_NO);
1076  if (GNUNET_YES == address->active)
1077  {
1078  /* Address was active, remove from network and update quotas */
1080  address,
1081  &address->peer);
1083  }
1084  GNUNET_free(aw);
1085  address->solver_information = NULL;
1087  "After deleting address now total %u and active %u addresses in network `%s'\n",
1088  net->total_addresses,
1089  net->active_addresses,
1090  net->desc);
1091 }
1092 
1093 
1101 void *
1103 {
1104  static struct GNUNET_ATS_SolverFunctions sf;
1106  struct GAS_PROPORTIONAL_Handle *s;
1107  struct Network * cur;
1108  float f_tmp;
1109  unsigned int c;
1110 
1111  s = GNUNET_new(struct GAS_PROPORTIONAL_Handle);
1112  s->env = env;
1113  sf.cls = s;
1124  if (GNUNET_SYSERR !=
1126  "ats",
1127  "PROP_STABILITY_FACTOR",
1128  &f_tmp))
1129  {
1130  if ((f_tmp < 1.0) || (f_tmp > 2.0))
1131  {
1133  _("Invalid %s configuration %f \n"),
1134  "PROP_STABILITY_FACTOR",
1135  f_tmp);
1136  }
1137  else
1138  {
1139  s->stability_factor = f_tmp;
1141  "Using %s of %.3f\n",
1142  "PROP_STABILITY_FACTOR",
1143  f_tmp);
1144  }
1145  }
1147  if (GNUNET_SYSERR !=
1149  "ats",
1150  "PROP_PROPORTIONALITY_FACTOR",
1151  &f_tmp))
1152  {
1153  if (f_tmp < 1.0)
1154  {
1156  _("Invalid %s configuration %f\n"),
1157  "PROP_PROPORTIONALITY_FACTOR",
1158  f_tmp);
1159  }
1160  else
1161  {
1162  s->prop_factor = f_tmp;
1164  "Using %s of %.3f\n",
1165  "PROP_PROPORTIONALITY_FACTOR",
1166  f_tmp);
1167  }
1168  }
1169 
1171  sizeof(struct Network));
1172  for (c = 0; c < env->network_count; c++)
1173  {
1174  cur = &s->network_entries[c];
1175  cur->type = c;
1176  cur->total_quota_in = env->in_quota[c];
1177  cur->total_quota_out = env->out_quota[c];
1178  cur->desc = GNUNET_NT_to_string(c);
1180  "# ATS addresses %s total",
1181  cur->desc);
1183  "# ATS active addresses %s total",
1184  cur->desc);
1186  "Added network %u `%s' (%llu/%llu)\n",
1187  c,
1188  cur->desc,
1189  cur->total_quota_in,
1190  cur->total_quota_out);
1191  }
1192  return &sf;
1193 }
1194 
1195 
1201 void *
1203 {
1204  struct GNUNET_ATS_SolverFunctions *sf = cls;
1205  struct GAS_PROPORTIONAL_Handle *s = sf->cls;
1206  struct AddressWrapper *cur;
1207  struct AddressWrapper *next;
1208  unsigned int c;
1209 
1210  for (c = 0; c < s->env->network_count; c++)
1211  {
1214  next = s->network_entries[c].head;
1215  while (NULL != (cur = next))
1216  {
1217  next = cur->next;
1219  s->network_entries[c].tail,
1220  cur);
1222  GNUNET_free(cur);
1223  }
1226  }
1227  GNUNET_break(0 == s->active_addresses);
1229  GNUNET_free(s);
1230  return NULL;
1231 }
1232 
1233 
1234 /* 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: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.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
Handle to a client that is connected to a service.
Definition: service.c:246
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:76
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: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.