aboutsummaryrefslogtreecommitdiff
path: root/src/ats/plugin_ats_proportional.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ats/plugin_ats_proportional.c')
-rw-r--r--src/ats/plugin_ats_proportional.c1070
1 files changed, 531 insertions, 539 deletions
diff --git a/src/ats/plugin_ats_proportional.c b/src/ats/plugin_ats_proportional.c
index 3fab09fb3..bdb5d6cf0 100644
--- a/src/ats/plugin_ats_proportional.c
+++ b/src/ats/plugin_ats_proportional.c
@@ -1,19 +1,19 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2011-2015 GNUnet e.V. 3 Copyright (C) 2011-2015 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 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, 7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 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/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19 */ 19 */
@@ -29,7 +29,7 @@
29#include "gnunet_ats_plugin.h" 29#include "gnunet_ats_plugin.h"
30#include "gnunet-service-ats_addresses.h" 30#include "gnunet-service-ats_addresses.h"
31 31
32#define LOG(kind,...) GNUNET_log_from (kind, "ats-proportional",__VA_ARGS__) 32#define LOG(kind, ...) GNUNET_log_from(kind, "ats-proportional", __VA_ARGS__)
33 33
34/** 34/**
35 * How much do we value stability over adaptation by default. A low 35 * How much do we value stability over adaptation by default. A low
@@ -58,8 +58,7 @@
58 * They are also stored in the respective `struct Network`'s linked 58 * They are also stored in the respective `struct Network`'s linked
59 * list. 59 * list.
60 */ 60 */
61struct AddressWrapper 61struct AddressWrapper {
62{
63 /** 62 /**
64 * Next in DLL 63 * Next in DLL
65 */ 64 */
@@ -75,7 +74,7 @@ struct AddressWrapper
75 */ 74 */
76 struct ATS_Address *addr; 75 struct ATS_Address *addr;
77 76
78 /** 77 /**
79 * Network scope this address is in 78 * Network scope this address is in
80 */ 79 */
81 struct Network *network; 80 struct Network *network;
@@ -94,15 +93,13 @@ struct AddressWrapper
94 * When was this address activated 93 * When was this address activated
95 */ 94 */
96 struct GNUNET_TIME_Absolute activated; 95 struct GNUNET_TIME_Absolute activated;
97
98}; 96};
99 97
100 98
101/** 99/**
102 * Representation of a network 100 * Representation of a network
103 */ 101 */
104struct Network 102struct Network {
105{
106 /** 103 /**
107 * Network description 104 * Network description
108 */ 105 */
@@ -152,16 +149,13 @@ struct Network
152 * Number of total addresses for this network 149 * Number of total addresses for this network
153 */ 150 */
154 unsigned int total_addresses; 151 unsigned int total_addresses;
155
156}; 152};
157 153
158 154
159/** 155/**
160 * A handle for the proportional solver 156 * A handle for the proportional solver
161 */ 157 */
162struct GAS_PROPORTIONAL_Handle 158struct GAS_PROPORTIONAL_Handle {
163{
164
165 /** 159 /**
166 * Our execution environment. 160 * Our execution environment.
167 */ 161 */
@@ -197,7 +191,6 @@ struct GAS_PROPORTIONAL_Handle
197 * Number of active addresses for solver 191 * Number of active addresses for solver
198 */ 192 */
199 unsigned int active_addresses; 193 unsigned int active_addresses;
200
201}; 194};
202 195
203 196
@@ -209,18 +202,18 @@ struct GAS_PROPORTIONAL_Handle
209 * @return #GNUNET_YES or #GNUNET_NO 202 * @return #GNUNET_YES or #GNUNET_NO
210 */ 203 */
211static int 204static int
212is_bandwidth_available_in_network (struct Network *net, 205is_bandwidth_available_in_network(struct Network *net,
213 int extra) 206 int extra)
214{ 207{
215 unsigned int na; 208 unsigned int na;
216 uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__); 209 uint32_t min_bw = ntohl(GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
217 210
218 GNUNET_assert (((int)net->active_addresses) + extra >= 0); 211 GNUNET_assert(((int)net->active_addresses) + extra >= 0);
219 na = net->active_addresses + extra; 212 na = net->active_addresses + extra;
220 if (0 == na) 213 if (0 == na)
221 return GNUNET_YES; 214 return GNUNET_YES;
222 if ( ((net->total_quota_in / na) > min_bw) && 215 if (((net->total_quota_in / na) > min_bw) &&
223 ((net->total_quota_out / na) > min_bw) ) 216 ((net->total_quota_out / na) > min_bw))
224 return GNUNET_YES; 217 return GNUNET_YES;
225 return GNUNET_NO; 218 return GNUNET_NO;
226} 219}
@@ -236,16 +229,16 @@ is_bandwidth_available_in_network (struct Network *net,
236 * @return #GNUNET_YES or #GNUNET_NO 229 * @return #GNUNET_YES or #GNUNET_NO
237 */ 230 */
238static int 231static int
239all_require_connectivity (struct GAS_PROPORTIONAL_Handle *s, 232all_require_connectivity(struct GAS_PROPORTIONAL_Handle *s,
240 struct Network *net, 233 struct Network *net,
241 unsigned int con) 234 unsigned int con)
242{ 235{
243 struct AddressWrapper *aw; 236 struct AddressWrapper *aw;
244 237
245 for (aw = net->head; NULL != aw; aw = aw->next) 238 for (aw = net->head; NULL != aw; aw = aw->next)
246 if (con > 239 if (con >
247 s->env->get_connectivity (s->env->cls, 240 s->env->get_connectivity(s->env->cls,
248 &aw->addr->peer)) 241 &aw->addr->peer))
249 return GNUNET_NO; 242 return GNUNET_NO;
250 return GNUNET_YES; 243 return GNUNET_YES;
251} 244}
@@ -261,10 +254,10 @@ all_require_connectivity (struct GAS_PROPORTIONAL_Handle *s,
261 * @param net the network type to update 254 * @param net the network type to update
262 */ 255 */
263static void 256static void
264distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s, 257distribute_bandwidth(struct GAS_PROPORTIONAL_Handle *s,
265 struct Network *net) 258 struct Network *net)
266{ 259{
267 const uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__); 260 const uint32_t min_bw = ntohl(GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
268 struct AddressWrapper *aw; 261 struct AddressWrapper *aw;
269 unsigned long long remaining_quota_in; 262 unsigned long long remaining_quota_in;
270 unsigned long long quota_out_used; 263 unsigned long long quota_out_used;
@@ -276,110 +269,110 @@ distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
276 double total_weight; 269 double total_weight;
277 const double *peer_relative_prefs; 270 const double *peer_relative_prefs;
278 271
279 LOG (GNUNET_ERROR_TYPE_INFO, 272 LOG(GNUNET_ERROR_TYPE_INFO,
280 "Recalculate quota for network type `%s' for %u addresses (in/out): %llu/%llu \n", 273 "Recalculate quota for network type `%s' for %u addresses (in/out): %llu/%llu \n",
281 net->desc, 274 net->desc,
282 net->active_addresses, 275 net->active_addresses,
283 net->total_quota_in, 276 net->total_quota_in,
284 net->total_quota_in); 277 net->total_quota_in);
285 278
286 if (0 == net->active_addresses) 279 if (0 == net->active_addresses)
287 return; /* no addresses to update */ 280 return; /* no addresses to update */
288 281
289 /* sanity checks */ 282 /* sanity checks */
290 if ((net->active_addresses * min_bw) > net->total_quota_in) 283 if ((net->active_addresses * min_bw) > net->total_quota_in)
291 { 284 {
292 GNUNET_break(0); 285 GNUNET_break(0);
293 return; 286 return;
294 } 287 }
295 if ((net->active_addresses * min_bw) > net->total_quota_out) 288 if ((net->active_addresses * min_bw) > net->total_quota_out)
296 { 289 {
297 GNUNET_break(0); 290 GNUNET_break(0);
298 return; 291 return;
299 } 292 }
300 293
301 /* Calculate sum of relative preference for active addresses in this 294 /* Calculate sum of relative preference for active addresses in this
302 network */ 295 network */
303 sum_relative_peer_prefences = 0.0; 296 sum_relative_peer_prefences = 0.0;
304 count_addresses = 0; 297 count_addresses = 0;
305 for (aw = net->head; NULL != aw; aw = aw->next) 298 for (aw = net->head; NULL != aw; aw = aw->next)
306 { 299 {
307 if (GNUNET_YES != aw->addr->active) 300 if (GNUNET_YES != aw->addr->active)
308 continue; 301 continue;
309 peer_relative_prefs = s->env->get_preferences (s->env->cls, 302 peer_relative_prefs = s->env->get_preferences(s->env->cls,
310 &aw->addr->peer); 303 &aw->addr->peer);
311 sum_relative_peer_prefences 304 sum_relative_peer_prefences
312 += peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH]; 305 += peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH];
313 count_addresses++; 306 count_addresses++;
314 } 307 }
315 if (count_addresses != net->active_addresses) 308 if (count_addresses != net->active_addresses)
316 { 309 {
317 GNUNET_break (0); 310 GNUNET_break(0);
318 LOG (GNUNET_ERROR_TYPE_WARNING, 311 LOG(GNUNET_ERROR_TYPE_WARNING,
319 "%s: Counted %u active addresses, expected %u active addresses\n", 312 "%s: Counted %u active addresses, expected %u active addresses\n",
320 net->desc, 313 net->desc,
321 count_addresses, 314 count_addresses,
322 net->active_addresses); 315 net->active_addresses);
323 /* try to fix... */ 316 /* try to fix... */
324 net->active_addresses = count_addresses; 317 net->active_addresses = count_addresses;
325 } 318 }
326 LOG (GNUNET_ERROR_TYPE_INFO, 319 LOG(GNUNET_ERROR_TYPE_INFO,
327 "Total relative preference %.3f for %u addresses in network %s\n", 320 "Total relative preference %.3f for %u addresses in network %s\n",
328 sum_relative_peer_prefences, 321 sum_relative_peer_prefences,
329 net->active_addresses, 322 net->active_addresses,
330 net->desc); 323 net->desc);
331 324
332 /* check how much we have to distribute */ 325 /* check how much we have to distribute */
333 remaining_quota_in = net->total_quota_in - (net->active_addresses * min_bw); 326 remaining_quota_in = net->total_quota_in - (net->active_addresses * min_bw);
334 remaining_quota_out = net->total_quota_out - (net->active_addresses * min_bw); 327 remaining_quota_out = net->total_quota_out - (net->active_addresses * min_bw);
335 LOG (GNUNET_ERROR_TYPE_DEBUG, 328 LOG(GNUNET_ERROR_TYPE_DEBUG,
336 "Proportionally distributable bandwidth (in/out): %llu/%llu\n", 329 "Proportionally distributable bandwidth (in/out): %llu/%llu\n",
337 remaining_quota_in, 330 remaining_quota_in,
338 remaining_quota_out); 331 remaining_quota_out);
339 332
340 /* distribute remaining quota; we do not do it exactly proportional, 333 /* distribute remaining quota; we do not do it exactly proportional,
341 but balance "even" distribution ("net->active_addresses") with 334 but balance "even" distribution ("net->active_addresses") with
342 the preference sum using the "prop_factor". */ 335 the preference sum using the "prop_factor". */
343 total_weight = net->active_addresses + 336 total_weight = net->active_addresses +
344 s->prop_factor * sum_relative_peer_prefences; 337 s->prop_factor * sum_relative_peer_prefences;
345 quota_out_used = 0; 338 quota_out_used = 0;
346 quota_in_used = 0; 339 quota_in_used = 0;
347 for (aw = net->head; NULL != aw; aw = aw->next) 340 for (aw = net->head; NULL != aw; aw = aw->next)
348 {
349 if (GNUNET_YES != aw->addr->active)
350 { 341 {
351 /* set to 0, just to be sure */ 342 if (GNUNET_YES != aw->addr->active)
352 aw->calculated_quota_in = 0; 343 {
353 aw->calculated_quota_out = 0; 344 /* set to 0, just to be sure */
354 continue; 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
359 LOG(GNUNET_ERROR_TYPE_INFO,
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;
355 } 368 }
356 peer_relative_prefs = s->env->get_preferences (s->env->cls, 369 LOG(GNUNET_ERROR_TYPE_DEBUG,
357 &aw->addr->peer); 370 "Total bandwidth assigned is (in/out): %llu /%llu\n",
358 peer_weight = 1.0 371 quota_in_used,
359 + s->prop_factor * peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH]; 372 quota_out_used);
360
361 aw->calculated_quota_in = min_bw
362 + (peer_weight / total_weight) * remaining_quota_in;
363 aw->calculated_quota_out = min_bw
364 + (peer_weight / total_weight) * remaining_quota_out;
365
366 LOG (GNUNET_ERROR_TYPE_INFO,
367 "New quotas for peer `%s' with weight (cur/total) %.3f/%.3f (in/out) are: %u/%u\n",
368 GNUNET_i2s (&aw->addr->peer),
369 peer_weight,
370 total_weight,
371 (unsigned int) aw->calculated_quota_in,
372 (unsigned int) aw->calculated_quota_out);
373 quota_in_used += aw->calculated_quota_in;
374 quota_out_used += aw->calculated_quota_out;
375 }
376 LOG (GNUNET_ERROR_TYPE_DEBUG,
377 "Total bandwidth assigned is (in/out): %llu /%llu\n",
378 quota_in_used,
379 quota_out_used);
380 /* +1 due to possible rounding errors */ 373 /* +1 due to possible rounding errors */
381 GNUNET_break (quota_out_used <= net->total_quota_out + 1); 374 GNUNET_break(quota_out_used <= net->total_quota_out + 1);
382 GNUNET_break (quota_in_used <= net->total_quota_in + 1); 375 GNUNET_break(quota_in_used <= net->total_quota_in + 1);
383} 376}
384 377
385 378
@@ -390,22 +383,22 @@ distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
390 * @param net the network to propagate changes in 383 * @param net the network to propagate changes in
391 */ 384 */
392static void 385static void
393propagate_bandwidth (struct GAS_PROPORTIONAL_Handle *s, 386propagate_bandwidth(struct GAS_PROPORTIONAL_Handle *s,
394 struct Network *net) 387 struct Network *net)
395{ 388{
396 struct AddressWrapper *cur; 389 struct AddressWrapper *cur;
397 390
398 for (cur = net->head; NULL != cur; cur = cur->next) 391 for (cur = net->head; NULL != cur; cur = cur->next)
399 { 392 {
400 if ( (cur->addr->assigned_bw_in == cur->calculated_quota_in) && 393 if ((cur->addr->assigned_bw_in == cur->calculated_quota_in) &&
401 (cur->addr->assigned_bw_out == cur->calculated_quota_out) ) 394 (cur->addr->assigned_bw_out == cur->calculated_quota_out))
402 continue; 395 continue;
403 cur->addr->assigned_bw_in = cur->calculated_quota_in; 396 cur->addr->assigned_bw_in = cur->calculated_quota_in;
404 cur->addr->assigned_bw_out = cur->calculated_quota_out; 397 cur->addr->assigned_bw_out = cur->calculated_quota_out;
405 if (GNUNET_YES == cur->addr->active) 398 if (GNUNET_YES == cur->addr->active)
406 s->env->bandwidth_changed_cb (s->env->cls, 399 s->env->bandwidth_changed_cb(s->env->cls,
407 cur->addr); 400 cur->addr);
408 } 401 }
409} 402}
410 403
411 404
@@ -417,81 +410,80 @@ propagate_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
417 * @param n the network, can be NULL for all networks 410 * @param n the network, can be NULL for all networks
418 */ 411 */
419static void 412static void
420distribute_bandwidth_in_network (struct GAS_PROPORTIONAL_Handle *s, 413distribute_bandwidth_in_network(struct GAS_PROPORTIONAL_Handle *s,
421 struct Network *n) 414 struct Network *n)
422{ 415{
423 unsigned int i; 416 unsigned int i;
424 417
425 if (0 != s->bulk_lock) 418 if (0 != s->bulk_lock)
426 { 419 {
427 s->bulk_requests++; 420 s->bulk_requests++;
428 return; 421 return;
429 } 422 }
430 if (NULL != n) 423 if (NULL != n)
431 { 424 {
432 LOG (GNUNET_ERROR_TYPE_DEBUG, 425 LOG(GNUNET_ERROR_TYPE_DEBUG,
433 "Redistributing bandwidth in network %s with %u active and %u total addresses\n", 426 "Redistributing bandwidth in network %s with %u active and %u total addresses\n",
434 GNUNET_NT_to_string(n->type), 427 GNUNET_NT_to_string(n->type),
435 n->active_addresses, 428 n->active_addresses,
436 n->total_addresses); 429 n->total_addresses);
437 s->env->info_cb (s->env->cls, 430 s->env->info_cb(s->env->cls,
438 GAS_OP_SOLVE_START, 431 GAS_OP_SOLVE_START,
439 GAS_STAT_SUCCESS, 432 GAS_STAT_SUCCESS,
440 GAS_INFO_PROP_SINGLE); 433 GAS_INFO_PROP_SINGLE);
441 distribute_bandwidth(s, 434 distribute_bandwidth(s,
442 n); 435 n);
443 s->env->info_cb (s->env->cls, 436 s->env->info_cb(s->env->cls,
444 GAS_OP_SOLVE_STOP, 437 GAS_OP_SOLVE_STOP,
445 GAS_STAT_SUCCESS, 438 GAS_STAT_SUCCESS,
446 GAS_INFO_PROP_SINGLE); 439 GAS_INFO_PROP_SINGLE);
447 s->env->info_cb (s->env->cls, 440 s->env->info_cb(s->env->cls,
448 GAS_OP_SOLVE_UPDATE_NOTIFICATION_START, 441 GAS_OP_SOLVE_UPDATE_NOTIFICATION_START,
449 GAS_STAT_SUCCESS, 442 GAS_STAT_SUCCESS,
450 GAS_INFO_PROP_SINGLE); 443 GAS_INFO_PROP_SINGLE);
451 propagate_bandwidth (s, 444 propagate_bandwidth(s,
452 n); 445 n);
453 446
454 s->env->info_cb (s->env->cls, 447 s->env->info_cb(s->env->cls,
455 GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP, 448 GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP,
456 GAS_STAT_SUCCESS, 449 GAS_STAT_SUCCESS,
457 GAS_INFO_PROP_SINGLE); 450 GAS_INFO_PROP_SINGLE);
458 } 451 }
459 else 452 else
460 { 453 {
461 LOG (GNUNET_ERROR_TYPE_DEBUG, 454 LOG(GNUNET_ERROR_TYPE_DEBUG,
462 "Redistributing bandwidth in all %u networks\n", 455 "Redistributing bandwidth in all %u networks\n",
463 s->env->network_count); 456 s->env->network_count);
464 s->env->info_cb (s->env->cls, 457 s->env->info_cb(s->env->cls,
465 GAS_OP_SOLVE_START, 458 GAS_OP_SOLVE_START,
466 GAS_STAT_SUCCESS, 459 GAS_STAT_SUCCESS,
467 GAS_INFO_PROP_ALL); 460 GAS_INFO_PROP_ALL);
468 for (i = 0; i < s->env->network_count; i++) 461 for (i = 0; i < s->env->network_count; i++)
469 distribute_bandwidth (s, 462 distribute_bandwidth(s,
463 &s->network_entries[i]);
464 s->env->info_cb(s->env->cls,
465 GAS_OP_SOLVE_STOP,
466 GAS_STAT_SUCCESS,
467 GAS_INFO_PROP_ALL);
468 s->env->info_cb(s->env->cls,
469 GAS_OP_SOLVE_UPDATE_NOTIFICATION_START,
470 GAS_STAT_SUCCESS,
471 GAS_INFO_PROP_ALL);
472 for (i = 0; i < s->env->network_count; i++)
473 propagate_bandwidth(s,
470 &s->network_entries[i]); 474 &s->network_entries[i]);
471 s->env->info_cb (s->env->cls, 475 s->env->info_cb(s->env->cls,
472 GAS_OP_SOLVE_STOP, 476 GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP,
473 GAS_STAT_SUCCESS, 477 GAS_STAT_SUCCESS,
474 GAS_INFO_PROP_ALL); 478 GAS_INFO_PROP_ALL);
475 s->env->info_cb (s->env->cls, 479 }
476 GAS_OP_SOLVE_UPDATE_NOTIFICATION_START,
477 GAS_STAT_SUCCESS,
478 GAS_INFO_PROP_ALL);
479 for (i = 0; i < s->env->network_count; i++)
480 propagate_bandwidth (s,
481 &s->network_entries[i]);
482 s->env->info_cb (s->env->cls,
483 GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP,
484 GAS_STAT_SUCCESS,
485 GAS_INFO_PROP_ALL);
486 }
487} 480}
488 481
489 482
490/** 483/**
491 * Context for finding the best address* Linked list of addresses in this network: head 484 * Context for finding the best address* Linked list of addresses in this network: head
492 */ 485 */
493struct FindBestAddressCtx 486struct FindBestAddressCtx {
494{
495 /** 487 /**
496 * The solver handle 488 * The solver handle
497 */ 489 */
@@ -516,9 +508,9 @@ struct FindBestAddressCtx
516 * @return #GNUNET_OK (continue to iterate) 508 * @return #GNUNET_OK (continue to iterate)
517 */ 509 */
518static int 510static int
519find_best_address_it (void *cls, 511find_best_address_it(void *cls,
520 const struct GNUNET_PeerIdentity *key, 512 const struct GNUNET_PeerIdentity *key,
521 void *value) 513 void *value)
522{ 514{
523 struct FindBestAddressCtx *ctx = cls; 515 struct FindBestAddressCtx *ctx = cls;
524 struct ATS_Address *current = value; 516 struct ATS_Address *current = value;
@@ -536,48 +528,48 @@ find_best_address_it (void *cls,
536 need = (GNUNET_YES == current->active) ? 0 : 1; 528 need = (GNUNET_YES == current->active) ? 0 : 1;
537 /* we save -1 slot if 'best' is active and belongs 529 /* we save -1 slot if 'best' is active and belongs
538 to the same network (as we would replace it) */ 530 to the same network (as we would replace it) */
539 if ( (NULL != ctx->best) && 531 if ((NULL != ctx->best) &&
540 (GNUNET_YES == ctx->best->active) && 532 (GNUNET_YES == ctx->best->active) &&
541 (((struct AddressWrapper *) ctx->best->solver_information)->network == 533 (((struct AddressWrapper *)ctx->best->solver_information)->network ==
542 asi->network) ) 534 asi->network))
543 need--; 535 need--;
544 /* we can gain -1 slot if this peers connectivity 536 /* we can gain -1 slot if this peers connectivity
545 requirement is higher than that of another peer 537 requirement is higher than that of another peer
546 in that network scope */ 538 in that network scope */
547 con = ctx->s->env->get_connectivity (ctx->s->env->cls, 539 con = ctx->s->env->get_connectivity(ctx->s->env->cls,
548 key); 540 key);
549 if (GNUNET_YES != 541 if (GNUNET_YES !=
550 all_require_connectivity (ctx->s, 542 all_require_connectivity(ctx->s,
551 asi->network, 543 asi->network,
552 con)) 544 con))
553 need--; 545 need--;
554 /* test if minimum bandwidth for 'current' would be available */ 546 /* test if minimum bandwidth for 'current' would be available */
555 bw_available 547 bw_available
556 = is_bandwidth_available_in_network (asi->network, 548 = is_bandwidth_available_in_network(asi->network,
557 need); 549 need);
558 if (! bw_available) 550 if (!bw_available)
559 { 551 {
560 /* Bandwidth for this address is unavailable, so we cannot use 552 /* Bandwidth for this address is unavailable, so we cannot use
561 it. */ 553 it. */
562 return GNUNET_OK; 554 return GNUNET_OK;
563 } 555 }
564 if (GNUNET_YES == current->active) 556 if (GNUNET_YES == current->active)
565 {
566 active_time = GNUNET_TIME_absolute_get_duration (asi->activated);
567 if (active_time.rel_value_us <=
568 ((double) GNUNET_TIME_UNIT_SECONDS.rel_value_us) * ctx->s->stability_factor)
569 { 557 {
570 /* Keep active address for stability reasons */ 558 active_time = GNUNET_TIME_absolute_get_duration(asi->activated);
571 ctx->best = current; 559 if (active_time.rel_value_us <=
572 return GNUNET_NO; 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 }
573 } 566 }
574 }
575 if (NULL == ctx->best) 567 if (NULL == ctx->best)
576 { 568 {
577 /* We so far have nothing else, so go with it! */ 569 /* We so far have nothing else, so go with it! */
578 ctx->best = current; 570 ctx->best = current;
579 return GNUNET_OK; 571 return GNUNET_OK;
580 } 572 }
581 573
582 /* Now compare ATS information */ 574 /* Now compare ATS information */
583 cur_distance = current->norm_distance.norm; 575 cur_distance = current->norm_distance.norm;
@@ -587,33 +579,33 @@ find_best_address_it (void *cls,
587 579
588 /* user shorter distance */ 580 /* user shorter distance */
589 if (cur_distance < best_distance) 581 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 { 582 {
598 /* Distance change is significant, switch active address! */ 583 if (GNUNET_NO == ctx->best->active)
599 ctx->best = current; 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 }
600 } 593 }
601 }
602 594
603 /* User connection with less delay */ 595 /* User connection with less delay */
604 if (cur_delay < best_delay) 596 if (cur_delay < best_delay)
605 {
606 if (GNUNET_NO == ctx->best->active)
607 { 597 {
608 /* Activity doesn't influence the equation, use current */ 598 if (GNUNET_NO == ctx->best->active)
609 ctx->best = current; 599 {
610 } 600 /* Activity doesn't influence the equation, use current */
611 else if ((best_delay / cur_delay) > ctx->s->stability_factor) 601 ctx->best = current;
612 { 602 }
613 /* Latency change is significant, switch active address! */ 603 else if ((best_delay / cur_delay) > ctx->s->stability_factor)
614 ctx->best = current; 604 {
605 /* Latency change is significant, switch active address! */
606 ctx->best = current;
607 }
615 } 608 }
616 }
617 return GNUNET_OK; 609 return GNUNET_OK;
618} 610}
619 611
@@ -628,18 +620,18 @@ find_best_address_it (void *cls,
628 * @return the address or NULL 620 * @return the address or NULL
629 */ 621 */
630struct ATS_Address * 622struct ATS_Address *
631get_best_address (struct GAS_PROPORTIONAL_Handle *s, 623get_best_address(struct GAS_PROPORTIONAL_Handle *s,
632 struct GNUNET_CONTAINER_MultiPeerMap *addresses, 624 struct GNUNET_CONTAINER_MultiPeerMap *addresses,
633 const struct GNUNET_PeerIdentity *id) 625 const struct GNUNET_PeerIdentity *id)
634{ 626{
635 struct FindBestAddressCtx fba_ctx; 627 struct FindBestAddressCtx fba_ctx;
636 628
637 fba_ctx.best = NULL; 629 fba_ctx.best = NULL;
638 fba_ctx.s = s; 630 fba_ctx.s = s;
639 GNUNET_CONTAINER_multipeermap_get_multiple (addresses, 631 GNUNET_CONTAINER_multipeermap_get_multiple(addresses,
640 id, 632 id,
641 &find_best_address_it, 633 &find_best_address_it,
642 &fba_ctx); 634 &fba_ctx);
643 return fba_ctx.best; 635 return fba_ctx.best;
644} 636}
645 637
@@ -651,21 +643,21 @@ get_best_address (struct GAS_PROPORTIONAL_Handle *s,
651 * @param net the network type 643 * @param net the network type
652 */ 644 */
653static void 645static void
654address_decrement_active (struct GAS_PROPORTIONAL_Handle *s, 646address_decrement_active(struct GAS_PROPORTIONAL_Handle *s,
655 struct Network *net) 647 struct Network *net)
656{ 648{
657 GNUNET_assert (net->active_addresses > 0); 649 GNUNET_assert(net->active_addresses > 0);
658 net->active_addresses--; 650 net->active_addresses--;
659 GNUNET_STATISTICS_update (s->env->stats, 651 GNUNET_STATISTICS_update(s->env->stats,
660 net->stat_active, 652 net->stat_active,
661 -1, 653 -1,
662 GNUNET_NO); 654 GNUNET_NO);
663 GNUNET_assert (s->active_addresses > 0); 655 GNUNET_assert(s->active_addresses > 0);
664 s->active_addresses--; 656 s->active_addresses--;
665 GNUNET_STATISTICS_update (s->env->stats, 657 GNUNET_STATISTICS_update(s->env->stats,
666 "# ATS addresses total", 658 "# ATS addresses total",
667 -1, 659 -1,
668 GNUNET_NO); 660 GNUNET_NO);
669} 661}
670 662
671 663
@@ -679,16 +671,16 @@ address_decrement_active (struct GAS_PROPORTIONAL_Handle *s,
679 * @return #GNUNET_NO on double active address else #GNUNET_YES; 671 * @return #GNUNET_NO on double active address else #GNUNET_YES;
680 */ 672 */
681static int 673static int
682get_active_address_it (void *cls, 674get_active_address_it(void *cls,
683 const struct GNUNET_PeerIdentity *key, 675 const struct GNUNET_PeerIdentity *key,
684 void *value) 676 void *value)
685{ 677{
686 struct ATS_Address **dest = cls; 678 struct ATS_Address **dest = cls;
687 struct ATS_Address *aa = value; 679 struct ATS_Address *aa = value;
688 680
689 if (GNUNET_YES != aa->active) 681 if (GNUNET_YES != aa->active)
690 return GNUNET_OK; 682 return GNUNET_OK;
691 GNUNET_assert (NULL == (*dest)); 683 GNUNET_assert(NULL == (*dest));
692 (*dest) = aa; 684 (*dest) = aa;
693 return GNUNET_OK; 685 return GNUNET_OK;
694} 686}
@@ -702,16 +694,16 @@ get_active_address_it (void *cls,
702 * @return active address or NULL 694 * @return active address or NULL
703 */ 695 */
704static struct ATS_Address * 696static struct ATS_Address *
705get_active_address (struct GAS_PROPORTIONAL_Handle *s, 697get_active_address(struct GAS_PROPORTIONAL_Handle *s,
706 const struct GNUNET_PeerIdentity *peer) 698 const struct GNUNET_PeerIdentity *peer)
707{ 699{
708 struct ATS_Address *dest; 700 struct ATS_Address *dest;
709 701
710 dest = NULL; 702 dest = NULL;
711 GNUNET_CONTAINER_multipeermap_get_multiple (s->env->addresses, 703 GNUNET_CONTAINER_multipeermap_get_multiple(s->env->addresses,
712 peer, 704 peer,
713 &get_active_address_it, 705 &get_active_address_it,
714 &dest); 706 &dest);
715 return dest; 707 return dest;
716} 708}
717 709
@@ -727,9 +719,9 @@ get_active_address (struct GAS_PROPORTIONAL_Handle *s,
727 * @param peer the peer to check 719 * @param peer the peer to check
728 */ 720 */
729static void 721static void
730update_active_address (struct GAS_PROPORTIONAL_Handle *s, 722update_active_address(struct GAS_PROPORTIONAL_Handle *s,
731 struct ATS_Address *current_address, 723 struct ATS_Address *current_address,
732 const struct GNUNET_PeerIdentity *peer) 724 const struct GNUNET_PeerIdentity *peer)
733{ 725{
734 struct ATS_Address *best_address; 726 struct ATS_Address *best_address;
735 struct AddressWrapper *asi_cur; 727 struct AddressWrapper *asi_cur;
@@ -739,9 +731,9 @@ update_active_address (struct GAS_PROPORTIONAL_Handle *s,
739 unsigned int a_con; 731 unsigned int a_con;
740 unsigned int con_min; 732 unsigned int con_min;
741 733
742 best_address = get_best_address (s, 734 best_address = get_best_address(s,
743 s->env->addresses, 735 s->env->addresses,
744 peer); 736 peer);
745 if (NULL != best_address) 737 if (NULL != best_address)
746 asi_best = best_address->solver_information; 738 asi_best = best_address->solver_information;
747 else 739 else
@@ -749,98 +741,98 @@ update_active_address (struct GAS_PROPORTIONAL_Handle *s,
749 if (current_address == best_address) 741 if (current_address == best_address)
750 return; /* no changes */ 742 return; /* no changes */
751 if (NULL != current_address) 743 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);
757 LOG (GNUNET_ERROR_TYPE_INFO,
758 "Disabling previous active address for peer `%s'\n",
759 GNUNET_i2s (peer));
760 asi_cur->activated = GNUNET_TIME_UNIT_ZERO_ABS;
761 current_address->active = GNUNET_NO;
762 current_address->assigned_bw_in = 0;
763 current_address->assigned_bw_out = 0;
764 address_decrement_active (s,
765 asi_cur->network);
766 if ( (NULL == best_address) ||
767 (asi_best->network != asi_cur->network) )
768 distribute_bandwidth_in_network (s,
769 asi_cur->network);
770 if (NULL == best_address)
771 { 744 {
772 /* We previously had an active address, but now we cannot 745 /* We switch to a new address (or to none);
773 * suggest one. Therefore we have to disconnect the peer. 746 mark old address as inactive. */
774 * The above call to "distribute_bandwidth_in_network() 747 asi_cur = current_address->solver_information;
775 * does not see 'current_address' so we need to trigger 748 GNUNET_assert(GNUNET_YES == current_address->active);
776 * the update here. */ 749 LOG(GNUNET_ERROR_TYPE_INFO,
777 LOG (GNUNET_ERROR_TYPE_DEBUG, 750 "Disabling previous active address for peer `%s'\n",
778 "Disconnecting peer `%s'.\n", 751 GNUNET_i2s(peer));
779 GNUNET_i2s (peer)); 752 asi_cur->activated = GNUNET_TIME_UNIT_ZERO_ABS;
780 s->env->bandwidth_changed_cb (s->env->cls, 753 current_address->active = GNUNET_NO;
781 current_address); 754 current_address->assigned_bw_in = 0;
782 return; 755 current_address->assigned_bw_out = 0;
756 address_decrement_active(s,
757 asi_cur->network);
758 if ((NULL == best_address) ||
759 (asi_best->network != asi_cur->network))
760 distribute_bandwidth_in_network(s,
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. */
769 LOG(GNUNET_ERROR_TYPE_DEBUG,
770 "Disconnecting peer `%s'.\n",
771 GNUNET_i2s(peer));
772 s->env->bandwidth_changed_cb(s->env->cls,
773 current_address);
774 return;
775 }
783 } 776 }
784 }
785 if (NULL == best_address) 777 if (NULL == best_address)
786 { 778 {
787 /* We do not have a new address, so we are done. */ 779 /* We do not have a new address, so we are done. */
788 LOG (GNUNET_ERROR_TYPE_DEBUG, 780 LOG(GNUNET_ERROR_TYPE_DEBUG,
789 "Cannot suggest address for peer `%s'\n", 781 "Cannot suggest address for peer `%s'\n",
790 GNUNET_i2s (peer)); 782 GNUNET_i2s(peer));
791 return; 783 return;
792 } 784 }
793 /* We do have a new address, activate it */ 785 /* We do have a new address, activate it */
794 LOG (GNUNET_ERROR_TYPE_DEBUG, 786 LOG(GNUNET_ERROR_TYPE_DEBUG,
795 "Selecting new address %p for peer `%s'\n", 787 "Selecting new address %p for peer `%s'\n",
796 best_address, 788 best_address,
797 GNUNET_i2s (peer)); 789 GNUNET_i2s(peer));
798 /* Mark address as active */ 790 /* Mark address as active */
799 best_address->active = GNUNET_YES; 791 best_address->active = GNUNET_YES;
800 asi_best->activated = GNUNET_TIME_absolute_get (); 792 asi_best->activated = GNUNET_TIME_absolute_get();
801 asi_best->network->active_addresses++; 793 asi_best->network->active_addresses++;
802 s->active_addresses++; 794 s->active_addresses++;
803 GNUNET_STATISTICS_update (s->env->stats, 795 GNUNET_STATISTICS_update(s->env->stats,
804 "# ATS active addresses total", 796 "# ATS active addresses total",
805 1, 797 1,
806 GNUNET_NO); 798 GNUNET_NO);
807 GNUNET_STATISTICS_update (s->env->stats, 799 GNUNET_STATISTICS_update(s->env->stats,
808 asi_best->network->stat_active, 800 asi_best->network->stat_active,
809 1, 801 1,
810 GNUNET_NO); 802 GNUNET_NO);
811 LOG (GNUNET_ERROR_TYPE_INFO, 803 LOG(GNUNET_ERROR_TYPE_INFO,
812 "Address %p for peer `%s' is now active\n", 804 "Address %p for peer `%s' is now active\n",
813 best_address, 805 best_address,
814 GNUNET_i2s (peer)); 806 GNUNET_i2s(peer));
815 807
816 if (GNUNET_NO == 808 if (GNUNET_NO ==
817 is_bandwidth_available_in_network (asi_best->network, 809 is_bandwidth_available_in_network(asi_best->network,
818 0)) 810 0))
819 {
820 /* we went over the maximum number of addresses for
821 this scope; remove the address with the smallest
822 connectivity requirement */
823 con_min = UINT32_MAX;
824 aw_min = NULL;
825 for (aw = asi_best->network->head; NULL != aw; aw = aw->next)
826 { 811 {
827 if ( (con_min > 812 /* we went over the maximum number of addresses for
828 (a_con = s->env->get_connectivity (s->env->cls, 813 this scope; remove the address with the smallest
829 &aw->addr->peer))) && 814 connectivity requirement */
830 (GNUNET_YES == aw->addr->active) ) 815 con_min = UINT32_MAX;
831 { 816 aw_min = NULL;
832 aw_min = aw; 817 for (aw = asi_best->network->head; NULL != aw; aw = aw->next)
833 con_min = a_con; 818 {
834 if (0 == con_min) 819 if ((con_min >
835 break; 820 (a_con = s->env->get_connectivity(s->env->cls,
836 } 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 }
830 update_active_address(s,
831 aw_min->addr,
832 &aw_min->addr->peer);
837 } 833 }
838 update_active_address (s, 834 distribute_bandwidth_in_network(s,
839 aw_min->addr, 835 asi_best->network);
840 &aw_min->addr->peer);
841 }
842 distribute_bandwidth_in_network (s,
843 asi_best->network);
844} 836}
845 837
846 838
@@ -853,17 +845,17 @@ update_active_address (struct GAS_PROPORTIONAL_Handle *s,
853 * @param pref_rel the normalized preference value for this kind over all clients 845 * @param pref_rel the normalized preference value for this kind over all clients
854 */ 846 */
855static void 847static void
856GAS_proportional_change_preference (void *solver, 848GAS_proportional_change_preference(void *solver,
857 const struct GNUNET_PeerIdentity *peer, 849 const struct GNUNET_PeerIdentity *peer,
858 enum GNUNET_ATS_PreferenceKind kind, 850 enum GNUNET_ATS_PreferenceKind kind,
859 double pref_rel) 851 double pref_rel)
860{ 852{
861 struct GAS_PROPORTIONAL_Handle *s = solver; 853 struct GAS_PROPORTIONAL_Handle *s = solver;
862 854
863 if (GNUNET_ATS_PREFERENCE_BANDWIDTH != kind) 855 if (GNUNET_ATS_PREFERENCE_BANDWIDTH != kind)
864 return; /* we do not care */ 856 return; /* we do not care */
865 distribute_bandwidth_in_network (s, 857 distribute_bandwidth_in_network(s,
866 NULL); 858 NULL);
867} 859}
868 860
869 861
@@ -878,12 +870,12 @@ GAS_proportional_change_preference (void *solver,
878 * @param score the score 870 * @param score the score
879 */ 871 */
880static void 872static void
881GAS_proportional_feedback (void *solver, 873GAS_proportional_feedback(void *solver,
882 struct GNUNET_SERVICE_Client *application, 874 struct GNUNET_SERVICE_Client *application,
883 const struct GNUNET_PeerIdentity *peer, 875 const struct GNUNET_PeerIdentity *peer,
884 const struct GNUNET_TIME_Relative scope, 876 const struct GNUNET_TIME_Relative scope,
885 enum GNUNET_ATS_PreferenceKind kind, 877 enum GNUNET_ATS_PreferenceKind kind,
886 double score) 878 double score)
887{ 879{
888 /* Proportional does not care about feedback */ 880 /* Proportional does not care about feedback */
889} 881}
@@ -896,15 +888,15 @@ GAS_proportional_feedback (void *solver,
896 * @param peer the identity of the peer 888 * @param peer the identity of the peer
897 */ 889 */
898static void 890static void
899GAS_proportional_start_get_address (void *solver, 891GAS_proportional_start_get_address(void *solver,
900 const struct GNUNET_PeerIdentity *peer) 892 const struct GNUNET_PeerIdentity *peer)
901{ 893{
902 struct GAS_PROPORTIONAL_Handle *s = solver; 894 struct GAS_PROPORTIONAL_Handle *s = solver;
903 895
904 update_active_address (s, 896 update_active_address(s,
905 get_active_address (s, 897 get_active_address(s,
906 peer), 898 peer),
907 peer); 899 peer);
908} 900}
909 901
910 902
@@ -915,20 +907,20 @@ GAS_proportional_start_get_address (void *solver,
915 * @param peer the peer 907 * @param peer the peer
916 */ 908 */
917static void 909static void
918GAS_proportional_stop_get_address (void *solver, 910GAS_proportional_stop_get_address(void *solver,
919 const struct GNUNET_PeerIdentity *peer) 911 const struct GNUNET_PeerIdentity *peer)
920{ 912{
921 struct GAS_PROPORTIONAL_Handle *s = solver; 913 struct GAS_PROPORTIONAL_Handle *s = solver;
922 struct ATS_Address *cur; 914 struct ATS_Address *cur;
923 struct AddressWrapper *asi; 915 struct AddressWrapper *asi;
924 916
925 cur = get_active_address (s, 917 cur = get_active_address(s,
926 peer); 918 peer);
927 if (NULL == cur) 919 if (NULL == cur)
928 return; 920 return;
929 asi = cur->solver_information; 921 asi = cur->solver_information;
930 distribute_bandwidth_in_network (s, 922 distribute_bandwidth_in_network(s,
931 asi->network); 923 asi->network);
932} 924}
933 925
934 926
@@ -938,13 +930,13 @@ GAS_proportional_stop_get_address (void *solver,
938 * @param solver the solver 930 * @param solver the solver
939 */ 931 */
940static void 932static void
941GAS_proportional_bulk_start (void *solver) 933GAS_proportional_bulk_start(void *solver)
942{ 934{
943 struct GAS_PROPORTIONAL_Handle *s = solver; 935 struct GAS_PROPORTIONAL_Handle *s = solver;
944 936
945 LOG (GNUNET_ERROR_TYPE_DEBUG, 937 LOG(GNUNET_ERROR_TYPE_DEBUG,
946 "Locking solver for bulk operation ...\n"); 938 "Locking solver for bulk operation ...\n");
947 GNUNET_assert (NULL != solver); 939 GNUNET_assert(NULL != solver);
948 s->bulk_lock++; 940 s->bulk_lock++;
949} 941}
950 942
@@ -955,27 +947,27 @@ GAS_proportional_bulk_start (void *solver)
955 * @param solver our `struct GAS_PROPORTIONAL_Handle *` 947 * @param solver our `struct GAS_PROPORTIONAL_Handle *`
956 */ 948 */
957static void 949static void
958GAS_proportional_bulk_stop (void *solver) 950GAS_proportional_bulk_stop(void *solver)
959{ 951{
960 struct GAS_PROPORTIONAL_Handle *s = solver; 952 struct GAS_PROPORTIONAL_Handle *s = solver;
961 953
962 LOG (GNUNET_ERROR_TYPE_DEBUG, 954 LOG(GNUNET_ERROR_TYPE_DEBUG,
963 "Unlocking solver from bulk operation ...\n"); 955 "Unlocking solver from bulk operation ...\n");
964 if (s->bulk_lock < 1) 956 if (s->bulk_lock < 1)
965 { 957 {
966 GNUNET_break(0); 958 GNUNET_break(0);
967 return; 959 return;
968 } 960 }
969 s->bulk_lock--; 961 s->bulk_lock--;
970 if ( (0 == s->bulk_lock) && 962 if ((0 == s->bulk_lock) &&
971 (0 < s->bulk_requests) ) 963 (0 < s->bulk_requests))
972 { 964 {
973 LOG (GNUNET_ERROR_TYPE_INFO, 965 LOG(GNUNET_ERROR_TYPE_INFO,
974 "No lock pending, recalculating\n"); 966 "No lock pending, recalculating\n");
975 distribute_bandwidth_in_network (s, 967 distribute_bandwidth_in_network(s,
976 NULL); 968 NULL);
977 s->bulk_requests = 0; 969 s->bulk_requests = 0;
978 } 970 }
979} 971}
980 972
981 973
@@ -986,14 +978,14 @@ GAS_proportional_bulk_stop (void *solver)
986 * @param address the address 978 * @param address the address
987 */ 979 */
988static void 980static void
989GAS_proportional_address_property_changed (void *solver, 981GAS_proportional_address_property_changed(void *solver,
990 struct ATS_Address *address) 982 struct ATS_Address *address)
991{ 983{
992 struct GAS_PROPORTIONAL_Handle *s = solver; 984 struct GAS_PROPORTIONAL_Handle *s = solver;
993 struct AddressWrapper *asi = address->solver_information; 985 struct AddressWrapper *asi = address->solver_information;
994 986
995 distribute_bandwidth_in_network (s, 987 distribute_bandwidth_in_network(s,
996 asi->network); 988 asi->network);
997} 989}
998 990
999 991
@@ -1005,43 +997,43 @@ GAS_proportional_address_property_changed (void *solver,
1005 * @param network network type of this address 997 * @param network network type of this address
1006 */ 998 */
1007static void 999static void
1008GAS_proportional_address_add (void *solver, 1000GAS_proportional_address_add(void *solver,
1009 struct ATS_Address *address, 1001 struct ATS_Address *address,
1010 uint32_t network) 1002 uint32_t network)
1011{ 1003{
1012 struct GAS_PROPORTIONAL_Handle *s = solver; 1004 struct GAS_PROPORTIONAL_Handle *s = solver;
1013 struct Network *net; 1005 struct Network *net;
1014 struct AddressWrapper *aw; 1006 struct AddressWrapper *aw;
1015 1007
1016 GNUNET_assert (network < s->env->network_count); 1008 GNUNET_assert(network < s->env->network_count);
1017 net = &s->network_entries[network]; 1009 net = &s->network_entries[network];
1018 net->total_addresses++; 1010 net->total_addresses++;
1019 1011
1020 aw = GNUNET_new (struct AddressWrapper); 1012 aw = GNUNET_new(struct AddressWrapper);
1021 aw->addr = address; 1013 aw->addr = address;
1022 aw->network = net; 1014 aw->network = net;
1023 address->solver_information = aw; 1015 address->solver_information = aw;
1024 GNUNET_CONTAINER_DLL_insert (net->head, 1016 GNUNET_CONTAINER_DLL_insert(net->head,
1025 net->tail, 1017 net->tail,
1026 aw); 1018 aw);
1027 GNUNET_STATISTICS_update (s->env->stats, 1019 GNUNET_STATISTICS_update(s->env->stats,
1028 "# ATS addresses total", 1020 "# ATS addresses total",
1029 1, 1021 1,
1030 GNUNET_NO); 1022 GNUNET_NO);
1031 GNUNET_STATISTICS_update (s->env->stats, 1023 GNUNET_STATISTICS_update(s->env->stats,
1032 net->stat_total, 1024 net->stat_total,
1033 1, 1025 1,
1034 GNUNET_NO); 1026 GNUNET_NO);
1035 update_active_address (s, 1027 update_active_address(s,
1036 get_active_address (s, 1028 get_active_address(s,
1037 &address->peer), 1029 &address->peer),
1038 &address->peer); 1030 &address->peer);
1039 LOG (GNUNET_ERROR_TYPE_INFO, 1031 LOG(GNUNET_ERROR_TYPE_INFO,
1040 "Added new address for `%s', now total %u and active %u addresses in network `%s'\n", 1032 "Added new address for `%s', now total %u and active %u addresses in network `%s'\n",
1041 GNUNET_i2s (&address->peer), 1033 GNUNET_i2s(&address->peer),
1042 net->total_addresses, 1034 net->total_addresses,
1043 net->active_addresses, 1035 net->active_addresses,
1044 net->desc); 1036 net->desc);
1045} 1037}
1046 1038
1047 1039
@@ -1057,45 +1049,45 @@ GAS_proportional_address_add (void *solver,
1057 * @param address the address to remove 1049 * @param address the address to remove
1058 */ 1050 */
1059static void 1051static void
1060GAS_proportional_address_delete (void *solver, 1052GAS_proportional_address_delete(void *solver,
1061 struct ATS_Address *address) 1053 struct ATS_Address *address)
1062{ 1054{
1063 struct GAS_PROPORTIONAL_Handle *s = solver; 1055 struct GAS_PROPORTIONAL_Handle *s = solver;
1064 struct AddressWrapper *aw = address->solver_information; 1056 struct AddressWrapper *aw = address->solver_information;
1065 struct Network *net = aw->network; 1057 struct Network *net = aw->network;
1066 1058
1067 LOG (GNUNET_ERROR_TYPE_DEBUG, 1059 LOG(GNUNET_ERROR_TYPE_DEBUG,
1068 "Deleting %s address for peer `%s' from network `%s' (total: %u/active: %u)\n", 1060 "Deleting %s address for peer `%s' from network `%s' (total: %u/active: %u)\n",
1069 (GNUNET_NO == address->active) ? "inactive" : "active", 1061 (GNUNET_NO == address->active) ? "inactive" : "active",
1070 GNUNET_i2s (&address->peer), 1062 GNUNET_i2s(&address->peer),
1071 net->desc, 1063 net->desc,
1072 net->total_addresses, 1064 net->total_addresses,
1073 net->active_addresses); 1065 net->active_addresses);
1074 1066
1075 GNUNET_CONTAINER_DLL_remove (net->head, 1067 GNUNET_CONTAINER_DLL_remove(net->head,
1076 net->tail, 1068 net->tail,
1077 aw); 1069 aw);
1078 GNUNET_assert (net->total_addresses > 0); 1070 GNUNET_assert(net->total_addresses > 0);
1079 net->total_addresses--; 1071 net->total_addresses--;
1080 GNUNET_STATISTICS_update (s->env->stats, 1072 GNUNET_STATISTICS_update(s->env->stats,
1081 net->stat_total, 1073 net->stat_total,
1082 -1, 1074 -1,
1083 GNUNET_NO); 1075 GNUNET_NO);
1084 if (GNUNET_YES == address->active) 1076 if (GNUNET_YES == address->active)
1085 { 1077 {
1086 /* Address was active, remove from network and update quotas */ 1078 /* Address was active, remove from network and update quotas */
1087 update_active_address (s, 1079 update_active_address(s,
1088 address, 1080 address,
1089 &address->peer); 1081 &address->peer);
1090 distribute_bandwidth_in_network (s, net); 1082 distribute_bandwidth_in_network(s, net);
1091 } 1083 }
1092 GNUNET_free (aw); 1084 GNUNET_free(aw);
1093 address->solver_information = NULL; 1085 address->solver_information = NULL;
1094 LOG (GNUNET_ERROR_TYPE_DEBUG, 1086 LOG(GNUNET_ERROR_TYPE_DEBUG,
1095 "After deleting address now total %u and active %u addresses in network `%s'\n", 1087 "After deleting address now total %u and active %u addresses in network `%s'\n",
1096 net->total_addresses, 1088 net->total_addresses,
1097 net->active_addresses, 1089 net->active_addresses,
1098 net->desc); 1090 net->desc);
1099} 1091}
1100 1092
1101 1093
@@ -1107,7 +1099,7 @@ GAS_proportional_address_delete (void *solver,
1107 * @return the `struct GAS_PROPORTIONAL_Handle` to pass as a closure 1099 * @return the `struct GAS_PROPORTIONAL_Handle` to pass as a closure
1108 */ 1100 */
1109void * 1101void *
1110libgnunet_plugin_ats_proportional_init (void *cls) 1102libgnunet_plugin_ats_proportional_init(void *cls)
1111{ 1103{
1112 static struct GNUNET_ATS_SolverFunctions sf; 1104 static struct GNUNET_ATS_SolverFunctions sf;
1113 struct GNUNET_ATS_PluginEnvironment *env = cls; 1105 struct GNUNET_ATS_PluginEnvironment *env = cls;
@@ -1116,7 +1108,7 @@ libgnunet_plugin_ats_proportional_init (void *cls)
1116 float f_tmp; 1108 float f_tmp;
1117 unsigned int c; 1109 unsigned int c;
1118 1110
1119 s = GNUNET_new (struct GAS_PROPORTIONAL_Handle); 1111 s = GNUNET_new(struct GAS_PROPORTIONAL_Handle);
1120 s->env = env; 1112 s->env = env;
1121 sf.cls = s; 1113 sf.cls = s;
1122 sf.s_add = &GAS_proportional_address_add; 1114 sf.s_add = &GAS_proportional_address_add;
@@ -1130,73 +1122,73 @@ libgnunet_plugin_ats_proportional_init (void *cls)
1130 sf.s_bulk_stop = &GAS_proportional_bulk_stop; 1122 sf.s_bulk_stop = &GAS_proportional_bulk_stop;
1131 s->stability_factor = PROP_STABILITY_FACTOR; 1123 s->stability_factor = PROP_STABILITY_FACTOR;
1132 if (GNUNET_SYSERR != 1124 if (GNUNET_SYSERR !=
1133 GNUNET_CONFIGURATION_get_value_float (env->cfg, 1125 GNUNET_CONFIGURATION_get_value_float(env->cfg,
1134 "ats", 1126 "ats",
1135 "PROP_STABILITY_FACTOR", 1127 "PROP_STABILITY_FACTOR",
1136 &f_tmp)) 1128 &f_tmp))
1137 {
1138 if ((f_tmp < 1.0) || (f_tmp > 2.0))
1139 {
1140 LOG (GNUNET_ERROR_TYPE_ERROR,
1141 _("Invalid %s configuration %f \n"),
1142 "PROP_STABILITY_FACTOR",
1143 f_tmp);
1144 }
1145 else
1146 { 1129 {
1147 s->stability_factor = f_tmp; 1130 if ((f_tmp < 1.0) || (f_tmp > 2.0))
1148 LOG (GNUNET_ERROR_TYPE_INFO, 1131 {
1149 "Using %s of %.3f\n", 1132 LOG(GNUNET_ERROR_TYPE_ERROR,
1150 "PROP_STABILITY_FACTOR", 1133 _("Invalid %s configuration %f \n"),
1151 f_tmp); 1134 "PROP_STABILITY_FACTOR",
1135 f_tmp);
1136 }
1137 else
1138 {
1139 s->stability_factor = f_tmp;
1140 LOG(GNUNET_ERROR_TYPE_INFO,
1141 "Using %s of %.3f\n",
1142 "PROP_STABILITY_FACTOR",
1143 f_tmp);
1144 }
1152 } 1145 }
1153 }
1154 s->prop_factor = PROPORTIONALITY_FACTOR; 1146 s->prop_factor = PROPORTIONALITY_FACTOR;
1155 if (GNUNET_SYSERR != 1147 if (GNUNET_SYSERR !=
1156 GNUNET_CONFIGURATION_get_value_float (env->cfg, 1148 GNUNET_CONFIGURATION_get_value_float(env->cfg,
1157 "ats", 1149 "ats",
1158 "PROP_PROPORTIONALITY_FACTOR", 1150 "PROP_PROPORTIONALITY_FACTOR",
1159 &f_tmp)) 1151 &f_tmp))
1160 {
1161 if (f_tmp < 1.0)
1162 { 1152 {
1163 LOG (GNUNET_ERROR_TYPE_ERROR, 1153 if (f_tmp < 1.0)
1164 _("Invalid %s configuration %f\n"), 1154 {
1165 "PROP_PROPORTIONALITY_FACTOR", 1155 LOG(GNUNET_ERROR_TYPE_ERROR,
1166 f_tmp); 1156 _("Invalid %s configuration %f\n"),
1157 "PROP_PROPORTIONALITY_FACTOR",
1158 f_tmp);
1159 }
1160 else
1161 {
1162 s->prop_factor = f_tmp;
1163 LOG(GNUNET_ERROR_TYPE_INFO,
1164 "Using %s of %.3f\n",
1165 "PROP_PROPORTIONALITY_FACTOR",
1166 f_tmp);
1167 }
1167 } 1168 }
1168 else
1169 {
1170 s->prop_factor = f_tmp;
1171 LOG (GNUNET_ERROR_TYPE_INFO,
1172 "Using %s of %.3f\n",
1173 "PROP_PROPORTIONALITY_FACTOR",
1174 f_tmp);
1175 }
1176 }
1177 1169
1178 s->network_entries = GNUNET_malloc (env->network_count * 1170 s->network_entries = GNUNET_malloc(env->network_count *
1179 sizeof (struct Network)); 1171 sizeof(struct Network));
1180 for (c = 0; c < env->network_count; c++) 1172 for (c = 0; c < env->network_count; c++)
1181 { 1173 {
1182 cur = &s->network_entries[c]; 1174 cur = &s->network_entries[c];
1183 cur->type = c; 1175 cur->type = c;
1184 cur->total_quota_in = env->in_quota[c]; 1176 cur->total_quota_in = env->in_quota[c];
1185 cur->total_quota_out = env->out_quota[c]; 1177 cur->total_quota_out = env->out_quota[c];
1186 cur->desc = GNUNET_NT_to_string (c); 1178 cur->desc = GNUNET_NT_to_string(c);
1187 GNUNET_asprintf (&cur->stat_total, 1179 GNUNET_asprintf(&cur->stat_total,
1188 "# ATS addresses %s total", 1180 "# ATS addresses %s total",
1189 cur->desc); 1181 cur->desc);
1190 GNUNET_asprintf (&cur->stat_active, 1182 GNUNET_asprintf(&cur->stat_active,
1191 "# ATS active addresses %s total", 1183 "# ATS active addresses %s total",
1192 cur->desc); 1184 cur->desc);
1193 LOG (GNUNET_ERROR_TYPE_INFO, 1185 LOG(GNUNET_ERROR_TYPE_INFO,
1194 "Added network %u `%s' (%llu/%llu)\n", 1186 "Added network %u `%s' (%llu/%llu)\n",
1195 c, 1187 c,
1196 cur->desc, 1188 cur->desc,
1197 cur->total_quota_in, 1189 cur->total_quota_in,
1198 cur->total_quota_out); 1190 cur->total_quota_out);
1199 } 1191 }
1200 return &sf; 1192 return &sf;
1201} 1193}
1202 1194
@@ -1207,7 +1199,7 @@ libgnunet_plugin_ats_proportional_init (void *cls)
1207 * @param cls return value from #libgnunet_plugin_ats_proportional_init() 1199 * @param cls return value from #libgnunet_plugin_ats_proportional_init()
1208 */ 1200 */
1209void * 1201void *
1210libgnunet_plugin_ats_proportional_done (void *cls) 1202libgnunet_plugin_ats_proportional_done(void *cls)
1211{ 1203{
1212 struct GNUNET_ATS_SolverFunctions *sf = cls; 1204 struct GNUNET_ATS_SolverFunctions *sf = cls;
1213 struct GAS_PROPORTIONAL_Handle *s = sf->cls; 1205 struct GAS_PROPORTIONAL_Handle *s = sf->cls;
@@ -1216,25 +1208,25 @@ libgnunet_plugin_ats_proportional_done (void *cls)
1216 unsigned int c; 1208 unsigned int c;
1217 1209
1218 for (c = 0; c < s->env->network_count; c++) 1210 for (c = 0; c < s->env->network_count; c++)
1219 {
1220 GNUNET_break (0 == s->network_entries[c].total_addresses);
1221 GNUNET_break (0 == s->network_entries[c].active_addresses);
1222 next = s->network_entries[c].head;
1223 while (NULL != (cur = next))
1224 { 1211 {
1225 next = cur->next; 1212 GNUNET_break(0 == s->network_entries[c].total_addresses);
1226 GNUNET_CONTAINER_DLL_remove (s->network_entries[c].head, 1213 GNUNET_break(0 == s->network_entries[c].active_addresses);
1227 s->network_entries[c].tail, 1214 next = s->network_entries[c].head;
1228 cur); 1215 while (NULL != (cur = next))
1229 GNUNET_free_non_null (cur->addr->solver_information); 1216 {
1230 GNUNET_free(cur); 1217 next = cur->next;
1218 GNUNET_CONTAINER_DLL_remove(s->network_entries[c].head,
1219 s->network_entries[c].tail,
1220 cur);
1221 GNUNET_free_non_null(cur->addr->solver_information);
1222 GNUNET_free(cur);
1223 }
1224 GNUNET_free(s->network_entries[c].stat_total);
1225 GNUNET_free(s->network_entries[c].stat_active);
1231 } 1226 }
1232 GNUNET_free (s->network_entries[c].stat_total); 1227 GNUNET_break(0 == s->active_addresses);
1233 GNUNET_free (s->network_entries[c].stat_active); 1228 GNUNET_free(s->network_entries);
1234 } 1229 GNUNET_free(s);
1235 GNUNET_break (0 == s->active_addresses);
1236 GNUNET_free (s->network_entries);
1237 GNUNET_free (s);
1238 return NULL; 1230 return NULL;
1239} 1231}
1240 1232