aboutsummaryrefslogtreecommitdiff
path: root/src/ats/gnunet-service-ats-solver_proportional.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2013-06-11 11:44:41 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2013-06-11 11:44:41 +0000
commit0c0a922873c6647d07e038496d62568547c23e0b (patch)
treeccaeb0a1130b933bc300866f0ac2774e75554c1f /src/ats/gnunet-service-ats-solver_proportional.c
parentd9cee5d7b959ab6e04e26677f6d6f39195f80d37 (diff)
downloadgnunet-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.c227
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 */
605static int
606get_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 */
618static int
619find_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
686static int 795static int
687free_pref (void *cls, 796free_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
704static void 806static void
705addresse_increment (struct GAS_PROPORTIONAL_Handle *s, 807addresse_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
727static int 830static int
728addresse_decrement (struct GAS_PROPORTIONAL_Handle *s, 831addresse_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 */
826static int
827find_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
921static void 919static void
922recalculate_preferences (struct PreferencePeer *p) 920recalculate_preferences (struct PreferencePeer *p)
923{ 921{
@@ -1038,6 +1036,7 @@ recalculate_preferences (struct PreferencePeer *p)
1038 } 1036 }
1039} 1037}
1040 1038
1039
1041static void 1040static void
1042update_preference (struct PreferencePeer *p, 1041update_preference (struct PreferencePeer *p,
1043 enum GNUNET_ATS_PreferenceKind kind, 1042 enum GNUNET_ATS_PreferenceKind kind,