aboutsummaryrefslogtreecommitdiff
path: root/src/ats
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-02-08 17:34:33 +0000
committerChristian Grothoff <christian@grothoff.org>2015-02-08 17:34:33 +0000
commit551ac76f62a2cb158d068636a442eeb24cf9d372 (patch)
tree34c0aee364ac34bec15bdd15b64419a3d1cdc374 /src/ats
parentae57507cbf872756895a1cf24cbfb64c7f930ee7 (diff)
downloadgnunet-551ac76f62a2cb158d068636a442eeb24cf9d372.tar.gz
gnunet-551ac76f62a2cb158d068636a442eeb24cf9d372.zip
-restructuring, adding comments
Diffstat (limited to 'src/ats')
-rw-r--r--src/ats/ats.conf.in2
-rw-r--r--src/ats/plugin_ats_proportional.c421
2 files changed, 197 insertions, 226 deletions
diff --git a/src/ats/ats.conf.in b/src/ats/ats.conf.in
index 7985a58f9..d9e867bde 100644
--- a/src/ats/ats.conf.in
+++ b/src/ats/ats.conf.in
@@ -8,7 +8,7 @@ ACCEPT_FROM6 = ::1;
8UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-ats.sock 8UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-ats.sock
9UNIX_MATCH_UID = NO 9UNIX_MATCH_UID = NO
10UNIX_MATCH_GID = YES 10UNIX_MATCH_GID = YES
11 11# PREFIX = valgrind
12# Designated assignment mode: PROPORTIONAL / MLP / RIL 12# Designated assignment mode: PROPORTIONAL / MLP / RIL
13MODE = proportional 13MODE = proportional
14 14
diff --git a/src/ats/plugin_ats_proportional.c b/src/ats/plugin_ats_proportional.c
index 312199e95..87afb400e 100644
--- a/src/ats/plugin_ats_proportional.c
+++ b/src/ats/plugin_ats_proportional.c
@@ -484,7 +484,9 @@ distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
484 GNUNET_break (0); 484 GNUNET_break (0);
485 LOG (GNUNET_ERROR_TYPE_WARNING, 485 LOG (GNUNET_ERROR_TYPE_WARNING,
486 "%s: Counted %u active addresses, but network says to have %u active addresses\n", 486 "%s: Counted %u active addresses, but network says to have %u active addresses\n",
487 net->desc, count_addresses, net->active_addresses); 487 net->desc,
488 count_addresses,
489 net->active_addresses);
488 for (aw = net->head; NULL != aw; aw = aw->next) 490 for (aw = net->head; NULL != aw; aw = aw->next)
489 { 491 {
490 if (GNUNET_YES != aw->addr->active) 492 if (GNUNET_YES != aw->addr->active)
@@ -499,8 +501,10 @@ distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
499 } 501 }
500 502
501 LOG (GNUNET_ERROR_TYPE_INFO, 503 LOG (GNUNET_ERROR_TYPE_INFO,
502 "Total relative preference %.3f for %u addresses in network %s\n", 504 "Total relative preference %.3f for %u addresses in network %s\n",
503 sum_relative_peer_prefences, net->active_addresses, net->desc); 505 sum_relative_peer_prefences,
506 net->active_addresses,
507 net->desc);
504 508
505 for (aw = net->head; NULL != aw; aw = aw->next) 509 for (aw = net->head; NULL != aw; aw = aw->next)
506 { 510 {
@@ -521,8 +525,11 @@ distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
521 525
522 LOG (GNUNET_ERROR_TYPE_INFO, 526 LOG (GNUNET_ERROR_TYPE_INFO,
523 "New quota for peer `%s' with weight (cur/total) %.3f/%.3f (in/out): %llu / %llu\n", 527 "New quota for peer `%s' with weight (cur/total) %.3f/%.3f (in/out): %llu / %llu\n",
524 GNUNET_i2s (&aw->addr->peer), peer_weight, total_weight, 528 GNUNET_i2s (&aw->addr->peer),
525 assigned_quota_in, assigned_quota_out); 529 peer_weight,
530 total_weight,
531 assigned_quota_in,
532 assigned_quota_out);
526 } 533 }
527 else 534 else
528 { 535 {
@@ -538,24 +545,140 @@ distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
538 if (assigned_quota_out > UINT32_MAX) 545 if (assigned_quota_out > UINT32_MAX)
539 assigned_quota_out = UINT32_MAX; 546 assigned_quota_out = UINT32_MAX;
540 547
541 /* Compare to current bandwidth assigned */ 548 /* Store for later propagation */
542 aw->calculated_quota_in = assigned_quota_in; 549 aw->calculated_quota_in = assigned_quota_in;
543 aw->calculated_quota_out = assigned_quota_out; 550 aw->calculated_quota_out = assigned_quota_out;
544 } 551 }
545 LOG(GNUNET_ERROR_TYPE_DEBUG, 552 LOG (GNUNET_ERROR_TYPE_DEBUG,
546 "Total bandwidth assigned is (in/out): %llu /%llu\n", quota_in_used, 553 "Total bandwidth assigned is (in/out): %llu /%llu\n",
547 quota_out_used); 554 quota_in_used,
555 quota_out_used);
548 if (quota_out_used > net->total_quota_out + 1) /* +1 is required due to rounding errors */ 556 if (quota_out_used > net->total_quota_out + 1) /* +1 is required due to rounding errors */
549 { 557 {
550 LOG(GNUNET_ERROR_TYPE_ERROR, 558 LOG (GNUNET_ERROR_TYPE_ERROR,
551 "Total outbound bandwidth assigned is larger than allowed (used/allowed) for %u active addresses: %llu / %llu\n", 559 "Total outbound bandwidth assigned is larger than allowed (used/allowed) for %u active addresses: %llu / %llu\n",
552 net->active_addresses, quota_out_used, net->total_quota_out); 560 net->active_addresses,
561 quota_out_used,
562 net->total_quota_out);
553 } 563 }
554 if (quota_in_used > net->total_quota_in + 1) /* +1 is required due to rounding errors */ 564 if (quota_in_used > net->total_quota_in + 1) /* +1 is required due to rounding errors */
555 { 565 {
556 LOG(GNUNET_ERROR_TYPE_ERROR, 566 LOG (GNUNET_ERROR_TYPE_ERROR,
557 "Total inbound bandwidth assigned is larger than allowed (used/allowed) for %u active addresses: %llu / %llu\n", 567 "Total inbound bandwidth assigned is larger than allowed (used/allowed) for %u active addresses: %llu / %llu\n",
558 net->active_addresses, quota_in_used, net->total_quota_in); 568 net->active_addresses,
569 quota_in_used,
570 net->total_quota_in);
571 }
572}
573
574
575/**
576 * Notify ATS service of bandwidth changes to addresses.
577 *
578 * @param s solver handle
579 * @param net the network to propagate changes in
580 */
581static void
582propagate_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
583 struct Network *net)
584{
585 struct AddressWrapper *cur;
586
587 for (cur = net->head; NULL != cur; cur = cur->next)
588 {
589 if ( (cur->addr->assigned_bw_in == cur->calculated_quota_in) &&
590 (cur->addr->assigned_bw_out == cur->calculated_quota_out) )
591 continue;
592 cur->addr->assigned_bw_in = cur->calculated_quota_in;
593 cur->addr->assigned_bw_out = cur->calculated_quota_out;
594
595 LOG (GNUNET_ERROR_TYPE_DEBUG,
596 "Bandwidth for %s address %p for peer `%s' changed to %u/%u\n",
597 (GNUNET_NO == cur->addr->active) ? "inactive" : "active",
598 cur->addr,
599 GNUNET_i2s (&cur->addr->peer),
600 cur->addr->assigned_bw_in,
601 cur->addr->assigned_bw_out);
602
603 /* Notify on change */
604 if (GNUNET_YES == cur->addr->active)
605 s->env->bandwidth_changed_cb (s->env->cls,
606 cur->addr);
607 }
608}
609
610
611/**
612 * Distribute bandwidth. The addresses have already been selected,
613 * this is merely distributed the bandwidth among the addresses.
614 *
615 * @param s the solver handle
616 * @param n the network, can be NULL for all networks
617 */
618static void
619distribute_bandwidth_in_network (struct GAS_PROPORTIONAL_Handle *s,
620 struct Network *n)
621{
622 unsigned int i;
623
624 if (GNUNET_YES == s->bulk_lock)
625 {
626 s->bulk_requests++;
627 return;
628 }
629 if (NULL != n)
630 {
631 LOG (GNUNET_ERROR_TYPE_DEBUG,
632 "Redistributing bandwidth in network %s with %u active and %u total addresses\n",
633 GNUNET_ATS_print_network_type(n->type),
634 n->active_addresses,
635 n->total_addresses);
636 s->env->info_cb (s->env->cls,
637 GAS_OP_SOLVE_START,
638 GAS_STAT_SUCCESS,
639 GAS_INFO_PROP_SINGLE);
640 distribute_bandwidth(s,
641 n);
642 s->env->info_cb (s->env->cls,
643 GAS_OP_SOLVE_STOP,
644 GAS_STAT_SUCCESS,
645 GAS_INFO_PROP_SINGLE);
646 s->env->info_cb (s->env->cls,
647 GAS_OP_SOLVE_UPDATE_NOTIFICATION_START,
648 GAS_STAT_SUCCESS,
649 GAS_INFO_PROP_SINGLE);
650 propagate_bandwidth (s,
651 n);
652
653 s->env->info_cb (s->env->cls,
654 GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP,
655 GAS_STAT_SUCCESS,
656 GAS_INFO_PROP_SINGLE);
657 }
658 else
659 {
660 s->env->info_cb (s->env->cls,
661 GAS_OP_SOLVE_START,
662 GAS_STAT_SUCCESS,
663 GAS_INFO_PROP_ALL);
664 for (i = 0; i < s->network_count; i++)
665 distribute_bandwidth (s,
666 &s->network_entries[i]);
667 s->env->info_cb (s->env->cls,
668 GAS_OP_SOLVE_STOP,
669 GAS_STAT_SUCCESS,
670 GAS_INFO_PROP_ALL);
671 s->env->info_cb (s->env->cls,
672 GAS_OP_SOLVE_UPDATE_NOTIFICATION_START,
673 GAS_STAT_SUCCESS,
674 GAS_INFO_PROP_ALL);
675 for (i = 0; i < s->network_count; i++)
676 propagate_bandwidth (s,
677 &s->network_entries[i]);
678 s->env->info_cb (s->env->cls,
679 GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP,
680 GAS_STAT_SUCCESS,
681 GAS_INFO_PROP_ALL);
559 } 682 }
560} 683}
561 684
@@ -599,12 +722,13 @@ find_quality_property_index (enum GNUNET_ATS_Property type)
599 722
600 723
601/** 724/**
602 * Find a "good" address to use for a peer by iterating over the addresses for this peer. 725 * Find a "good" address to use for a peer by iterating over the
603 * If we already have an existing address, we stick to it. 726 * addresses for this peer. If we already have an existing address,
604 * Otherwise, we pick by lowest distance and then by lowest latency. 727 * we stick to it. Otherwise, we pick by lowest distance and then by
728 * lowest latency.
605 * 729 *
606 * @param cls the `struct FindBestAddressCtx *' where we store the result 730 * @param cls the `struct FindBestAddressCtx *' where we store the result
607 * @param key unused 731 * @param key the peer we are trying to find the best address for
608 * @param value another `struct ATS_Address*` to consider using 732 * @param value another `struct ATS_Address*` to consider using
609 * @return #GNUNET_OK (continue to iterate) 733 * @return #GNUNET_OK (continue to iterate)
610 */ 734 */
@@ -615,57 +739,38 @@ find_best_address_it (void *cls,
615{ 739{
616 struct FindBestAddressCtx *ctx = cls; 740 struct FindBestAddressCtx *ctx = cls;
617 struct ATS_Address *current = value; 741 struct ATS_Address *current = value;
618 struct ATS_Address *current_best = current; 742 struct AddressWrapper *asi = current->solver_information;
619 struct AddressWrapper *asi;
620 struct GNUNET_TIME_Relative active_time; 743 struct GNUNET_TIME_Relative active_time;
621 struct GNUNET_TIME_Relative min_active_time;
622 double best_delay; 744 double best_delay;
623 double best_distance; 745 double best_distance;
624 double cur_delay; 746 double cur_delay;
625 double cur_distance; 747 double cur_distance;
626 int index; 748 int index;
627 749
628 current_best = NULL; 750 if (GNUNET_NO ==
629 asi = current->solver_information; 751 is_bandwidth_available_in_network (asi->network))
630 if (NULL == asi)
631 { 752 {
632 GNUNET_break (0); 753 /* There's no bandwidth available in this network,
754 so we cannot use this address. */
633 return GNUNET_OK; 755 return GNUNET_OK;
634 } 756 }
635
636 if (GNUNET_NO == is_bandwidth_available_in_network (asi->network))
637 {
638 return GNUNET_OK; /* There's no bandwidth available in this network */
639 }
640
641 if (NULL != ctx->best)
642 {
643 /* Compare current addresses with denominated 'best' address */
644 current_best = ctx->best;
645 }
646 else
647 {
648 /* We do not have a 'best' address so take this address */
649 LOG (GNUNET_ERROR_TYPE_DEBUG,
650 "Setting initial address %p\n",
651 current);
652 current_best = current;
653 goto end;
654 }
655
656 if (GNUNET_YES == current->active) 757 if (GNUNET_YES == current->active)
657 { 758 {
658 GNUNET_assert (asi->activated.abs_value_us != GNUNET_TIME_UNIT_ZERO_ABS.abs_value_us);
659 active_time = GNUNET_TIME_absolute_get_duration (asi->activated); 759 active_time = GNUNET_TIME_absolute_get_duration (asi->activated);
660 min_active_time.rel_value_us = ((double) GNUNET_TIME_UNIT_SECONDS.rel_value_us) * 760 if (active_time.rel_value_us <=
661 ctx->s->stability_factor; 761 ((double) GNUNET_TIME_UNIT_SECONDS.rel_value_us) * ctx->s->stability_factor)
662 if (active_time.rel_value_us <= min_active_time.rel_value_us)
663 { 762 {
664 /* Keep active address for stability reasons */ 763 /* Keep active address for stability reasons */
665 ctx->best = current; 764 ctx->best = current;
666 return GNUNET_NO; 765 return GNUNET_NO;
667 } 766 }
668 } 767 }
768 if (NULL == ctx->best)
769 {
770 /* We so far have nothing else, so go with it! */
771 ctx->best = current;
772 return GNUNET_OK;
773 }
669 774
670 /* Now compare ATS information */ 775 /* Now compare ATS information */
671 index = find_quality_property_index (GNUNET_ATS_QUALITY_NET_DISTANCE); 776 index = find_quality_property_index (GNUNET_ATS_QUALITY_NET_DISTANCE);
@@ -680,49 +785,37 @@ find_best_address_it (void *cls,
680 { 785 {
681 if (GNUNET_NO == ctx->best->active) 786 if (GNUNET_NO == ctx->best->active)
682 { 787 {
683 current_best = current; /* Use current */ 788 /* Activity doesn't influence the equation, use current */
789 ctx->best = current;
684 } 790 }
685 else if ((best_distance / cur_distance) > ctx->s->stability_factor) 791 else if ((best_distance / cur_distance) > ctx->s->stability_factor)
686 { 792 {
687 /* Best and active address performs worse */ 793 /* Distance change is significant, switch active address! */
688 current_best = current; 794 ctx->best = current;
689 } 795 }
690 } 796 }
691 else
692 {
693 /* Use current best */
694 current_best = ctx->best;
695 }
696 797
697 /* User connection with less delay */ 798 /* User connection with less delay */
698 if (cur_delay < best_delay) 799 if (cur_delay < best_delay)
699 { 800 {
700
701 if (GNUNET_NO == ctx->best->active) 801 if (GNUNET_NO == ctx->best->active)
702 { 802 {
703 current_best = current; /* Use current */ 803 /* Activity doesn't influence the equation, use current */
804 ctx->best = current;
704 } 805 }
705 else if ((best_delay / cur_delay) > ctx->s->stability_factor) 806 else if ((best_delay / cur_delay) > ctx->s->stability_factor)
706 { 807 {
707 /* Best and active address performs worse */ 808 /* Latency change is significant, switch active address! */
708 current_best = current; 809 ctx->best = current;
709 } 810 }
710 } 811 }
711 else
712 {
713 /* Use current best */
714 current_best = ctx->best;
715 }
716
717end:
718 ctx->best = current_best;
719 return GNUNET_OK; 812 return GNUNET_OK;
720} 813}
721 814
722 815
723/** 816/**
724 * Find the currently best address for a peer from the set of addresses available 817 * Find the currently best address for a peer from the set of
725 * or return NULL of no address is available 818 * addresses available or return NULL of no address is available.
726 * 819 *
727 * @param s the proportional handle 820 * @param s the proportional handle
728 * @param addresses the address hashmap 821 * @param addresses the address hashmap
@@ -747,53 +840,6 @@ get_best_address (struct GAS_PROPORTIONAL_Handle *s,
747 840
748 841
749/** 842/**
750 * Address map iterator to find current active address for peer.
751 * Asserts that only one address is active per peer.
752 *
753 * @param cls last active address
754 * @param key peer's key
755 * @param value address to check
756 * @return #GNUNET_NO on double active address else #GNUNET_YES;
757 */
758static int
759get_active_address_it (void *cls,
760 const struct GNUNET_PeerIdentity *key,
761 void *value)
762{
763 struct ATS_Address **dest = cls;
764 struct ATS_Address *aa = value;
765
766 if (GNUNET_YES != aa->active)
767 return GNUNET_OK;
768 GNUNET_assert (NULL == (*dest));
769 (*dest) = aa;
770 return GNUNET_OK;
771}
772
773
774/**
775 * Find current active address for peer
776 *
777 * @param s the solver handle
778 * @param peer the peer
779 * @return active address or NULL
780 */
781static struct ATS_Address *
782get_active_address (struct GAS_PROPORTIONAL_Handle *s,
783 const struct GNUNET_PeerIdentity *peer)
784{
785 struct ATS_Address *dest;
786
787 dest = NULL;
788 GNUNET_CONTAINER_multipeermap_get_multiple (s->env->addresses,
789 peer,
790 &get_active_address_it,
791 &dest);
792 return dest;
793}
794
795
796/**
797 * Decrease address count in network 843 * Decrease address count in network
798 * 844 *
799 * @param s the solver handle 845 * @param s the solver handle
@@ -829,124 +875,49 @@ address_decrement_active (struct GAS_PROPORTIONAL_Handle *s,
829 875
830 876
831/** 877/**
832 * Notify bandwidth changes to addresses 878 * Address map iterator to find current active address for peer.
879 * Asserts that only one address is active per peer.
833 * 880 *
834 * @param s solver handle 881 * @param cls last active address
835 * @param net the network to propagate changes in 882 * @param key peer's key
883 * @param value address to check
884 * @return #GNUNET_NO on double active address else #GNUNET_YES;
836 */ 885 */
837static void 886static int
838propagate_bandwidth (struct GAS_PROPORTIONAL_Handle *s, 887get_active_address_it (void *cls,
839 struct Network *net) 888 const struct GNUNET_PeerIdentity *key,
889 void *value)
840{ 890{
841 struct AddressWrapper *cur; 891 struct ATS_Address **dest = cls;
842 892 struct ATS_Address *aa = value;
843 for (cur = net->head; NULL != cur; cur = cur->next)
844 {
845 if ( (cur->addr->assigned_bw_in == cur->calculated_quota_in) &&
846 (cur->addr->assigned_bw_out == cur->calculated_quota_out) )
847 continue;
848 cur->addr->assigned_bw_in = cur->calculated_quota_in;
849 cur->addr->assigned_bw_out = cur->calculated_quota_out;
850
851 /* Reset for next iteration */
852 cur->calculated_quota_in = 0;
853 cur->calculated_quota_out = 0;
854 LOG (GNUNET_ERROR_TYPE_DEBUG,
855 "Bandwidth for %s address %p for peer `%s' changed to %u/%u\n",
856 (GNUNET_NO == cur->addr->active) ? "inactive" : "active",
857 cur->addr,
858 GNUNET_i2s (&cur->addr->peer),
859 cur->addr->assigned_bw_in,
860 cur->addr->assigned_bw_out);
861 893
862 /* Notify on change */ 894 if (GNUNET_YES != aa->active)
863 if (GNUNET_YES == cur->addr->active) 895 return GNUNET_OK;
864 s->env->bandwidth_changed_cb (s->env->cls, 896 GNUNET_assert (NULL == (*dest));
865 cur->addr); 897 (*dest) = aa;
866 } 898 return GNUNET_OK;
867} 899}
868 900
869 901
870/** 902/**
871 * Distribibute bandwidth 903 * Find current active address for peer
872 * 904 *
873 * @param s the solver handle 905 * @param s the solver handle
874 * @param n the network, can be NULL for all network 906 * @param peer the peer
907 * @return active address or NULL
875 */ 908 */
876static void 909static struct ATS_Address *
877distribute_bandwidth_in_network (struct GAS_PROPORTIONAL_Handle *s, 910get_active_address (struct GAS_PROPORTIONAL_Handle *s,
878 struct Network *n) 911 const struct GNUNET_PeerIdentity *peer)
879{ 912{
880 if (GNUNET_YES == s->bulk_lock) 913 struct ATS_Address *dest;
881 {
882 s->bulk_requests++;
883 return;
884 }
885
886 if (NULL != n)
887 {
888 LOG (GNUNET_ERROR_TYPE_INFO,
889 "Redistributing bandwidth in network %s with %u active and %u total addresses\n",
890 GNUNET_ATS_print_network_type(n->type),
891 n->active_addresses,
892 n->total_addresses);
893
894 s->env->info_cb (s->env->cls,
895 GAS_OP_SOLVE_START,
896 GAS_STAT_SUCCESS,
897 GAS_INFO_PROP_SINGLE);
898
899 /* Distribute */
900 distribute_bandwidth(s, n);
901
902 s->env->info_cb (s->env->cls,
903 GAS_OP_SOLVE_STOP,
904 GAS_STAT_SUCCESS,
905 GAS_INFO_PROP_SINGLE);
906 s->env->info_cb (s->env->cls,
907 GAS_OP_SOLVE_UPDATE_NOTIFICATION_START,
908 GAS_STAT_SUCCESS,
909 GAS_INFO_PROP_SINGLE);
910
911 /* Do propagation */
912 propagate_bandwidth (s, n);
913
914 s->env->info_cb (s->env->cls,
915 GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP,
916 GAS_STAT_SUCCESS,
917 GAS_INFO_PROP_SINGLE);
918 }
919 else
920 {
921 int i;
922 s->env->info_cb (s->env->cls,
923 GAS_OP_SOLVE_START,
924 GAS_STAT_SUCCESS,
925 GAS_INFO_PROP_ALL);
926 for (i = 0; i < s->network_count; i++)
927 {
928 /* Distribute */
929 distribute_bandwidth(s, &s->network_entries[i]);
930 }
931 914
932 s->env->info_cb (s->env->cls, 915 dest = NULL;
933 GAS_OP_SOLVE_STOP, 916 GNUNET_CONTAINER_multipeermap_get_multiple (s->env->addresses,
934 GAS_STAT_SUCCESS, 917 peer,
935 GAS_INFO_PROP_ALL); 918 &get_active_address_it,
936 s->env->info_cb (s->env->cls, 919 &dest);
937 GAS_OP_SOLVE_UPDATE_NOTIFICATION_START, 920 return dest;
938 GAS_STAT_SUCCESS,
939 GAS_INFO_PROP_ALL);
940 for (i = 0; i < s->network_count; i++)
941 {
942 /* Do propagation */
943 propagate_bandwidth(s, &s->network_entries[i]);
944 }
945 s->env->info_cb (s->env->cls,
946 GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP,
947 GAS_STAT_SUCCESS,
948 GAS_INFO_PROP_ALL);
949 }
950} 921}
951 922
952 923