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