diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2013-06-11 11:44:41 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2013-06-11 11:44:41 +0000 |
commit | 0c0a922873c6647d07e038496d62568547c23e0b (patch) | |
tree | ccaeb0a1130b933bc300866f0ac2774e75554c1f /src/ats/gnunet-service-ats-solver_proportional.c | |
parent | d9cee5d7b959ab6e04e26677f6d6f39195f80d37 (diff) | |
download | gnunet-0c0a922873c6647d07e038496d62568547c23e0b.tar.gz gnunet-0c0a922873c6647d07e038496d62568547c23e0b.zip |
changes
Diffstat (limited to 'src/ats/gnunet-service-ats-solver_proportional.c')
-rw-r--r-- | src/ats/gnunet-service-ats-solver_proportional.c | 227 |
1 files changed, 113 insertions, 114 deletions
diff --git a/src/ats/gnunet-service-ats-solver_proportional.c b/src/ats/gnunet-service-ats-solver_proportional.c index 261e5fb68..fc03390b0 100644 --- a/src/ats/gnunet-service-ats-solver_proportional.c +++ b/src/ats/gnunet-service-ats-solver_proportional.c | |||
@@ -211,6 +211,7 @@ | |||
211 | #define DEFAULT_PREFERENCE 1.0 | 211 | #define DEFAULT_PREFERENCE 1.0 |
212 | #define MIN_UPDATE_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) | 212 | #define MIN_UPDATE_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) |
213 | 213 | ||
214 | |||
214 | /** | 215 | /** |
215 | * A handle for the proportional solver | 216 | * A handle for the proportional solver |
216 | */ | 217 | */ |
@@ -258,6 +259,7 @@ struct GAS_PROPORTIONAL_Handle | |||
258 | struct PreferenceClient *pc_tail; | 259 | struct PreferenceClient *pc_tail; |
259 | }; | 260 | }; |
260 | 261 | ||
262 | |||
261 | /** | 263 | /** |
262 | * Representation of a network | 264 | * Representation of a network |
263 | */ | 265 | */ |
@@ -373,6 +375,7 @@ struct PreferenceClient | |||
373 | struct PreferencePeer *p_tail; | 375 | struct PreferencePeer *p_tail; |
374 | }; | 376 | }; |
375 | 377 | ||
378 | |||
376 | /** | 379 | /** |
377 | * Preference peer | 380 | * Preference peer |
378 | */ | 381 | */ |
@@ -592,13 +595,117 @@ update_quota_per_network (struct GAS_PROPORTIONAL_Handle *s, | |||
592 | } | 595 | } |
593 | 596 | ||
594 | 597 | ||
598 | /** | ||
599 | * Extract an ATS performance info from an address | ||
600 | * | ||
601 | * @param address the address | ||
602 | * @param type the type to extract in HBO | ||
603 | * @return the value in HBO or GNUNET_ATS_VALUE_UNDEFINED in HBO if value does not exist | ||
604 | */ | ||
605 | static int | ||
606 | get_performance_info (struct ATS_Address *address, uint32_t type); | ||
607 | |||
608 | /** | ||
609 | * Find a "good" address to use for a peer by iterating over the addresses for this peer. | ||
610 | * If we already have an existing address, we stick to it. | ||
611 | * Otherwise, we pick by lowest distance and then by lowest latency. | ||
612 | * | ||
613 | * @param cls the 'struct ATS_Address**' where we store the result | ||
614 | * @param key unused | ||
615 | * @param value another 'struct ATS_Address*' to consider using | ||
616 | * @return GNUNET_OK (continue to iterate) | ||
617 | */ | ||
618 | static int | ||
619 | find_address_it (void *cls, const struct GNUNET_HashCode * key, void *value) | ||
620 | { | ||
621 | struct ATS_Address **previous_p = cls; | ||
622 | struct ATS_Address *current = (struct ATS_Address *) value; | ||
623 | struct ATS_Address *previous = *previous_p; | ||
624 | struct GNUNET_TIME_Absolute now; | ||
625 | struct Network *net = (struct Network *) current->solver_information; | ||
626 | uint32_t p_distance_cur; | ||
627 | uint32_t p_distance_prev; | ||
628 | uint32_t p_delay_cur; | ||
629 | uint32_t p_delay_prev; | ||
630 | |||
631 | now = GNUNET_TIME_absolute_get(); | ||
632 | |||
633 | if (current->blocked_until.abs_value == GNUNET_TIME_absolute_max (now, current->blocked_until).abs_value) | ||
634 | { | ||
635 | /* This address is blocked for suggestion */ | ||
636 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
637 | "Address %p blocked for suggestion for %llu ms \n", | ||
638 | current, | ||
639 | GNUNET_TIME_absolute_get_difference(now, current->blocked_until).rel_value); | ||
640 | return GNUNET_OK; | ||
641 | } | ||
642 | |||
643 | if (GNUNET_NO == is_bandwidth_available_in_network (net)) | ||
644 | return GNUNET_OK; /* There's no bandwidth available in this network */ | ||
645 | |||
646 | if (NULL != previous) | ||
647 | { | ||
648 | GNUNET_assert (NULL != previous->plugin); | ||
649 | GNUNET_assert (NULL != current->plugin); | ||
650 | if (0 == strcmp (previous->plugin, current->plugin)) | ||
651 | { | ||
652 | if ((0 != previous->addr_len) && | ||
653 | (0 == current->addr_len)) | ||
654 | { | ||
655 | /* saved address was an outbound address, but we have an inbound address */ | ||
656 | *previous_p = current; | ||
657 | return GNUNET_OK; | ||
658 | } | ||
659 | if (0 == previous->addr_len) | ||
660 | { | ||
661 | /* saved address was an inbound address, so do not overwrite */ | ||
662 | return GNUNET_OK; | ||
663 | } | ||
664 | } | ||
665 | } | ||
666 | |||
667 | if (NULL == previous) | ||
668 | { | ||
669 | *previous_p = current; | ||
670 | return GNUNET_OK; | ||
671 | } | ||
672 | if ((ntohl (previous->assigned_bw_in.value__) == 0) && | ||
673 | (ntohl (current->assigned_bw_in.value__) > 0)) | ||
674 | { | ||
675 | /* stick to existing connection */ | ||
676 | *previous_p = current; | ||
677 | return GNUNET_OK; | ||
678 | } | ||
679 | |||
680 | p_distance_prev = get_performance_info (previous, GNUNET_ATS_QUALITY_NET_DISTANCE); | ||
681 | p_distance_cur = get_performance_info (current, GNUNET_ATS_QUALITY_NET_DISTANCE); | ||
682 | if ((p_distance_prev != GNUNET_ATS_VALUE_UNDEFINED) && (p_distance_cur != GNUNET_ATS_VALUE_UNDEFINED) && | ||
683 | (p_distance_prev > p_distance_cur)) | ||
684 | { | ||
685 | /* user shorter distance */ | ||
686 | *previous_p = current; | ||
687 | return GNUNET_OK; | ||
688 | } | ||
689 | |||
690 | p_delay_prev = get_performance_info (previous, GNUNET_ATS_QUALITY_NET_DELAY); | ||
691 | p_delay_cur = get_performance_info (current, GNUNET_ATS_QUALITY_NET_DELAY); | ||
692 | if ((p_delay_prev != GNUNET_ATS_VALUE_UNDEFINED) && (p_delay_cur != GNUNET_ATS_VALUE_UNDEFINED) && | ||
693 | (p_delay_prev > p_delay_cur)) | ||
694 | { | ||
695 | /* user lower latency */ | ||
696 | *previous_p = current; | ||
697 | return GNUNET_OK; | ||
698 | } | ||
699 | |||
700 | /* don't care */ | ||
701 | return GNUNET_OK; | ||
702 | } | ||
595 | 703 | ||
596 | /** | 704 | /** |
597 | * Helper functions | 705 | * Helper functions |
598 | * --------------------------- | 706 | * --------------------------- |
599 | */ | 707 | */ |
600 | 708 | ||
601 | |||
602 | /** | 709 | /** |
603 | * Update bandwidth assignment for all networks | 710 | * Update bandwidth assignment for all networks |
604 | * | 711 | * |
@@ -662,6 +769,7 @@ get_active_address_it (void *cls, const struct GNUNET_HashCode * key, void *valu | |||
662 | return GNUNET_OK; | 769 | return GNUNET_OK; |
663 | } | 770 | } |
664 | 771 | ||
772 | |||
665 | /** | 773 | /** |
666 | * Find current active address for peer | 774 | * Find current active address for peer |
667 | * | 775 | * |
@@ -683,6 +791,7 @@ get_active_address (void *solver, | |||
683 | return dest; | 791 | return dest; |
684 | } | 792 | } |
685 | 793 | ||
794 | |||
686 | static int | 795 | static int |
687 | free_pref (void *cls, | 796 | free_pref (void *cls, |
688 | const struct GNUNET_HashCode * key, | 797 | const struct GNUNET_HashCode * key, |
@@ -694,13 +803,6 @@ free_pref (void *cls, | |||
694 | } | 803 | } |
695 | 804 | ||
696 | 805 | ||
697 | |||
698 | |||
699 | |||
700 | |||
701 | |||
702 | |||
703 | |||
704 | static void | 806 | static void |
705 | addresse_increment (struct GAS_PROPORTIONAL_Handle *s, | 807 | addresse_increment (struct GAS_PROPORTIONAL_Handle *s, |
706 | struct Network *net, | 808 | struct Network *net, |
@@ -724,6 +826,7 @@ addresse_increment (struct GAS_PROPORTIONAL_Handle *s, | |||
724 | 826 | ||
725 | } | 827 | } |
726 | 828 | ||
829 | |||
727 | static int | 830 | static int |
728 | addresse_decrement (struct GAS_PROPORTIONAL_Handle *s, | 831 | addresse_decrement (struct GAS_PROPORTIONAL_Handle *s, |
729 | struct Network *net, | 832 | struct Network *net, |
@@ -781,6 +884,7 @@ addresse_decrement (struct GAS_PROPORTIONAL_Handle *s, | |||
781 | return res; | 884 | return res; |
782 | } | 885 | } |
783 | 886 | ||
887 | |||
784 | /** | 888 | /** |
785 | * Extract an ATS performance info from an address | 889 | * Extract an ATS performance info from an address |
786 | * | 890 | * |
@@ -807,117 +911,11 @@ get_performance_info (struct ATS_Address *address, uint32_t type) | |||
807 | 911 | ||
808 | 912 | ||
809 | 913 | ||
810 | |||
811 | |||
812 | |||
813 | |||
814 | |||
815 | |||
816 | /** | ||
817 | * Find a "good" address to use for a peer. If we already have an existing | ||
818 | * address, we stick to it. Otherwise, we pick by lowest distance and then | ||
819 | * by lowest latency. | ||
820 | * | ||
821 | * @param cls the 'struct ATS_Address**' where we store the result | ||
822 | * @param key unused | ||
823 | * @param value another 'struct ATS_Address*' to consider using | ||
824 | * @return GNUNET_OK (continue to iterate) | ||
825 | */ | ||
826 | static int | ||
827 | find_address_it (void *cls, const struct GNUNET_HashCode * key, void *value) | ||
828 | { | ||
829 | struct ATS_Address **previous_p = cls; | ||
830 | struct ATS_Address *current = (struct ATS_Address *) value; | ||
831 | struct ATS_Address *previous = *previous_p; | ||
832 | struct GNUNET_TIME_Absolute now; | ||
833 | struct Network *net = (struct Network *) current->solver_information; | ||
834 | uint32_t p_distance_cur; | ||
835 | uint32_t p_distance_prev; | ||
836 | uint32_t p_delay_cur; | ||
837 | uint32_t p_delay_prev; | ||
838 | |||
839 | now = GNUNET_TIME_absolute_get(); | ||
840 | |||
841 | if (current->blocked_until.abs_value == GNUNET_TIME_absolute_max (now, current->blocked_until).abs_value) | ||
842 | { | ||
843 | /* This address is blocked for suggestion */ | ||
844 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
845 | "Address %p blocked for suggestion for %llu ms \n", | ||
846 | current, | ||
847 | GNUNET_TIME_absolute_get_difference(now, current->blocked_until).rel_value); | ||
848 | return GNUNET_OK; | ||
849 | } | ||
850 | |||
851 | if (GNUNET_NO == is_bandwidth_available_in_network (net)) | ||
852 | return GNUNET_OK; /* There's no bandwidth available in this network */ | ||
853 | |||
854 | if (NULL != previous) | ||
855 | { | ||
856 | if ((0 == strcmp (previous->plugin, "tcp")) && | ||
857 | (0 == strcmp (current->plugin, "tcp"))) | ||
858 | { | ||
859 | if ((0 != previous->addr_len) && | ||
860 | (0 == current->addr_len)) | ||
861 | { | ||
862 | /* saved address was an outbound address, but we have an inbound address */ | ||
863 | *previous_p = current; | ||
864 | return GNUNET_OK; | ||
865 | } | ||
866 | if (0 == previous->addr_len) | ||
867 | { | ||
868 | /* saved address was an inbound address, so do not overwrite */ | ||
869 | return GNUNET_OK; | ||
870 | } | ||
871 | } | ||
872 | } | ||
873 | |||
874 | if (NULL == previous) | ||
875 | { | ||
876 | *previous_p = current; | ||
877 | return GNUNET_OK; | ||
878 | } | ||
879 | if ((ntohl (previous->assigned_bw_in.value__) == 0) && | ||
880 | (ntohl (current->assigned_bw_in.value__) > 0)) | ||
881 | { | ||
882 | /* stick to existing connection */ | ||
883 | *previous_p = current; | ||
884 | return GNUNET_OK; | ||
885 | } | ||
886 | |||
887 | p_distance_prev = get_performance_info (previous, GNUNET_ATS_QUALITY_NET_DISTANCE); | ||
888 | p_distance_cur = get_performance_info (current, GNUNET_ATS_QUALITY_NET_DISTANCE); | ||
889 | if ((p_distance_prev != GNUNET_ATS_VALUE_UNDEFINED) && (p_distance_cur != GNUNET_ATS_VALUE_UNDEFINED) && | ||
890 | (p_distance_prev > p_distance_cur)) | ||
891 | { | ||
892 | /* user shorter distance */ | ||
893 | *previous_p = current; | ||
894 | return GNUNET_OK; | ||
895 | } | ||
896 | |||
897 | p_delay_prev = get_performance_info (previous, GNUNET_ATS_QUALITY_NET_DELAY); | ||
898 | p_delay_cur = get_performance_info (current, GNUNET_ATS_QUALITY_NET_DELAY); | ||
899 | if ((p_delay_prev != GNUNET_ATS_VALUE_UNDEFINED) && (p_delay_cur != GNUNET_ATS_VALUE_UNDEFINED) && | ||
900 | (p_delay_prev > p_delay_cur)) | ||
901 | { | ||
902 | /* user lower latency */ | ||
903 | *previous_p = current; | ||
904 | return GNUNET_OK; | ||
905 | } | ||
906 | |||
907 | /* don't care */ | ||
908 | return GNUNET_OK; | ||
909 | } | ||
910 | |||
911 | |||
912 | |||
913 | |||
914 | |||
915 | /** | 914 | /** |
916 | * Preference calculation | 915 | * Preference calculation |
917 | * --------------------------- | 916 | * --------------------------- |
918 | */ | 917 | */ |
919 | 918 | ||
920 | |||
921 | static void | 919 | static void |
922 | recalculate_preferences (struct PreferencePeer *p) | 920 | recalculate_preferences (struct PreferencePeer *p) |
923 | { | 921 | { |
@@ -1038,6 +1036,7 @@ recalculate_preferences (struct PreferencePeer *p) | |||
1038 | } | 1036 | } |
1039 | } | 1037 | } |
1040 | 1038 | ||
1039 | |||
1041 | static void | 1040 | static void |
1042 | update_preference (struct PreferencePeer *p, | 1041 | update_preference (struct PreferencePeer *p, |
1043 | enum GNUNET_ATS_PreferenceKind kind, | 1042 | enum GNUNET_ATS_PreferenceKind kind, |