diff options
Diffstat (limited to 'src/ats/gnunet-service-ats_addresses.c')
-rw-r--r-- | src/ats/gnunet-service-ats_addresses.c | 1166 |
1 files changed, 83 insertions, 1083 deletions
diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c index 1d2c9d3e5..9ef6a3838 100644 --- a/src/ats/gnunet-service-ats_addresses.c +++ b/src/ats/gnunet-service-ats_addresses.c | |||
@@ -26,11 +26,11 @@ | |||
26 | */ | 26 | */ |
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_ats_service.h" | 28 | #include "gnunet_ats_service.h" |
29 | #include "gnunet_ats_plugin.h" | ||
30 | #include "gnunet-service-ats.h" | 29 | #include "gnunet-service-ats.h" |
31 | #include "gnunet-service-ats_addresses.h" | 30 | #include "gnunet-service-ats_addresses.h" |
32 | #include "gnunet-service-ats_normalization.h" | 31 | #include "gnunet-service-ats_normalization.h" |
33 | #include "gnunet-service-ats_performance.h" | 32 | #include "gnunet-service-ats_performance.h" |
33 | #include "gnunet-service-ats_plugins.h" | ||
34 | #include "gnunet-service-ats_scheduling.h" | 34 | #include "gnunet-service-ats_scheduling.h" |
35 | #include "gnunet-service-ats_reservations.h" | 35 | #include "gnunet-service-ats_reservations.h" |
36 | 36 | ||
@@ -216,110 +216,13 @@ | |||
216 | */ | 216 | */ |
217 | 217 | ||
218 | 218 | ||
219 | /** | ||
220 | * Pending Address suggestion requests | ||
221 | */ | ||
222 | struct GAS_Addresses_Suggestion_Requests | ||
223 | { | ||
224 | /** | ||
225 | * Next in DLL | ||
226 | */ | ||
227 | struct GAS_Addresses_Suggestion_Requests *next; | ||
228 | |||
229 | /** | ||
230 | * Previous in DLL | ||
231 | */ | ||
232 | struct GAS_Addresses_Suggestion_Requests *prev; | ||
233 | |||
234 | /** | ||
235 | * Peer ID | ||
236 | */ | ||
237 | struct GNUNET_PeerIdentity id; | ||
238 | }; | ||
239 | |||
240 | /** | ||
241 | * Pending Address suggestion requests | ||
242 | */ | ||
243 | struct GAS_Addresses_Preference_Clients | ||
244 | { | ||
245 | /** | ||
246 | * Next in DLL | ||
247 | */ | ||
248 | struct GAS_Addresses_Preference_Clients *next; | ||
249 | |||
250 | /** | ||
251 | * Previous in DLL | ||
252 | */ | ||
253 | struct GAS_Addresses_Preference_Clients *prev; | ||
254 | |||
255 | /** | ||
256 | * Peer ID | ||
257 | */ | ||
258 | void *client; | ||
259 | }; | ||
260 | 219 | ||
261 | 220 | ||
262 | /** | 221 | /** |
263 | * | ||
264 | */ | ||
265 | static struct GNUNET_STATISTICS_Handle *stats; | ||
266 | |||
267 | /** | ||
268 | * A multihashmap to store all addresses | 222 | * A multihashmap to store all addresses |
269 | */ | 223 | */ |
270 | static struct GNUNET_CONTAINER_MultiPeerMap *addresses; | 224 | struct GNUNET_CONTAINER_MultiPeerMap *GSA_addresses; |
271 | 225 | ||
272 | /** | ||
273 | * Is ATS addresses running | ||
274 | */ | ||
275 | static int running; | ||
276 | |||
277 | /** | ||
278 | * Preferences clients | ||
279 | */ | ||
280 | static int pref_clients; | ||
281 | |||
282 | /** | ||
283 | * Configured ATS solver | ||
284 | */ | ||
285 | static int ats_mode; | ||
286 | |||
287 | /** | ||
288 | * Solver handle | ||
289 | */ | ||
290 | static void *solver; | ||
291 | |||
292 | /** | ||
293 | * Address suggestion requests DLL head. | ||
294 | * FIXME: This must become a Multipeermap! O(n) operations | ||
295 | * galore instead of O(1)!!! | ||
296 | */ | ||
297 | static struct GAS_Addresses_Suggestion_Requests *pending_requests_head; | ||
298 | |||
299 | /** | ||
300 | * Address suggestion requests DLL tail | ||
301 | */ | ||
302 | static struct GAS_Addresses_Suggestion_Requests *pending_requests_tail; | ||
303 | |||
304 | /** | ||
305 | * Preference requests DLL head | ||
306 | */ | ||
307 | static struct GAS_Addresses_Preference_Clients *preference_clients_head; | ||
308 | |||
309 | /** | ||
310 | * Preference requests DLL head | ||
311 | */ | ||
312 | static struct GAS_Addresses_Preference_Clients *preference_clients_tail; | ||
313 | |||
314 | /** | ||
315 | * Solver functions | ||
316 | */ | ||
317 | static struct GNUNET_ATS_PluginEnvironment env; | ||
318 | |||
319 | /** | ||
320 | * Solver plugin name as string | ||
321 | */ | ||
322 | static char *plugin; | ||
323 | 226 | ||
324 | /** | 227 | /** |
325 | * Value we pass for zero bandwidth. | 228 | * Value we pass for zero bandwidth. |
@@ -613,7 +516,7 @@ find_equivalent_address (const struct GNUNET_PeerIdentity *peer, | |||
613 | cac.exact_address = NULL; | 516 | cac.exact_address = NULL; |
614 | cac.base_address = NULL; | 517 | cac.base_address = NULL; |
615 | cac.search = addr; | 518 | cac.search = addr; |
616 | GNUNET_CONTAINER_multipeermap_get_multiple (addresses, | 519 | GNUNET_CONTAINER_multipeermap_get_multiple (GSA_addresses, |
617 | peer, | 520 | peer, |
618 | &compare_address_it, &cac); | 521 | &compare_address_it, &cac); |
619 | 522 | ||
@@ -681,7 +584,7 @@ find_exact_address (const struct GNUNET_PeerIdentity *peer, | |||
681 | 584 | ||
682 | fac.exact_address = NULL; | 585 | fac.exact_address = NULL; |
683 | fac.session_id = session_id; | 586 | fac.session_id = session_id; |
684 | GNUNET_CONTAINER_multipeermap_get_multiple (addresses, | 587 | GNUNET_CONTAINER_multipeermap_get_multiple (GSA_addresses, |
685 | peer, | 588 | peer, |
686 | &find_address_cb, &fac); | 589 | &find_address_cb, &fac); |
687 | return fac.exact_address; | 590 | return fac.exact_address; |
@@ -689,38 +592,6 @@ find_exact_address (const struct GNUNET_PeerIdentity *peer, | |||
689 | 592 | ||
690 | 593 | ||
691 | /** | 594 | /** |
692 | * Function allowing the solver to obtain normalized preference | ||
693 | * values from solver | ||
694 | * | ||
695 | * @param cls unused | ||
696 | * @param id the peer to return the normalized properties for | ||
697 | * @return array of double values with |GNUNET_ATS_PreferenceCount| elements | ||
698 | */ | ||
699 | const double * | ||
700 | get_preferences_cb (void *cls, | ||
701 | const struct GNUNET_PeerIdentity *id) | ||
702 | { | ||
703 | return GAS_normalization_get_preferences_by_peer (id); | ||
704 | } | ||
705 | |||
706 | |||
707 | /** | ||
708 | * Function allowing the solver to obtain normalized property | ||
709 | * values for an address from solver | ||
710 | * | ||
711 | * @param cls unused | ||
712 | * @param address the address | ||
713 | * @return array of double values with |GNUNET_ATS_QualityPropertiesCount| elements | ||
714 | */ | ||
715 | const double * | ||
716 | get_property_cb (void *cls, | ||
717 | const struct ATS_Address *address) | ||
718 | { | ||
719 | return GAS_normalization_get_properties (address); | ||
720 | } | ||
721 | |||
722 | |||
723 | /** | ||
724 | * Extract an ATS performance info from an address | 595 | * Extract an ATS performance info from an address |
725 | * | 596 | * |
726 | * @param address the address | 597 | * @param address the address |
@@ -772,18 +643,11 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer, | |||
772 | struct GNUNET_ATS_Information *atsi_delta; | 643 | struct GNUNET_ATS_Information *atsi_delta; |
773 | uint32_t atsi_delta_count; | 644 | uint32_t atsi_delta_count; |
774 | uint32_t addr_net; | 645 | uint32_t addr_net; |
775 | uint32_t previous_session; | ||
776 | int c1; | ||
777 | 646 | ||
778 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 647 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
779 | "Received `%s' for peer `%s'\n", | 648 | "Received `%s' for peer `%s'\n", |
780 | "ADDRESS ADD", | 649 | "ADDRESS ADD", |
781 | GNUNET_i2s (peer)); | 650 | GNUNET_i2s (peer)); |
782 | if (GNUNET_NO == running) | ||
783 | { | ||
784 | GNUNET_break (0); | ||
785 | return; | ||
786 | } | ||
787 | new_address = create_address (peer, | 651 | new_address = create_address (peer, |
788 | plugin_name, | 652 | plugin_name, |
789 | plugin_addr, | 653 | plugin_addr, |
@@ -802,127 +666,51 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer, | |||
802 | 666 | ||
803 | /* Get existing address or address with session == 0 */ | 667 | /* Get existing address or address with session == 0 */ |
804 | existing_address = find_equivalent_address (peer, new_address); | 668 | existing_address = find_equivalent_address (peer, new_address); |
805 | if (NULL == existing_address) | 669 | if (NULL != existing_address) |
806 | { | 670 | { |
807 | /* Add a new address */ | 671 | GNUNET_break (0); |
808 | new_address->t_added = GNUNET_TIME_absolute_get(); | 672 | GNUNET_free(new_address->plugin); |
809 | new_address->t_last_activity = GNUNET_TIME_absolute_get(); | 673 | GNUNET_free_non_null(new_address->atsi); |
810 | GNUNET_assert(GNUNET_OK == | 674 | GNUNET_free(new_address); |
811 | GNUNET_CONTAINER_multipeermap_put (addresses, | ||
812 | peer, | ||
813 | new_address, | ||
814 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); | ||
815 | |||
816 | GNUNET_STATISTICS_set (stats, | ||
817 | "# addresses", | ||
818 | GNUNET_CONTAINER_multipeermap_size (addresses), | ||
819 | GNUNET_NO); | ||
820 | |||
821 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
822 | "Adding new address %p for peer `%s', length %u, session id %u, %s\n", | ||
823 | new_address, | ||
824 | GNUNET_i2s (peer), | ||
825 | plugin_addr_len, | ||
826 | session_id, | ||
827 | GNUNET_ATS_print_network_type (addr_net)); | ||
828 | |||
829 | /* Tell solver about new address */ | ||
830 | env.sf.s_add (solver, new_address, addr_net); | ||
831 | |||
832 | env.sf.s_bulk_start (solver); | ||
833 | GAS_normalization_normalize_property (addresses, | ||
834 | new_address, | ||
835 | atsi, | ||
836 | atsi_count); | ||
837 | env.sf.s_bulk_stop (solver); | ||
838 | |||
839 | /* Notify performance clients about new address */ | ||
840 | GAS_performance_notify_all_clients (&new_address->peer, new_address->plugin, | ||
841 | new_address->addr, new_address->addr_len, new_address->active, | ||
842 | new_address->atsi, new_address->atsi_count, | ||
843 | GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_out), | ||
844 | GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_in)); | ||
845 | return; | ||
846 | } | ||
847 | |||
848 | /* FIXME: this case should probably not be allowed... */ | ||
849 | /* We have an existing address we can use, clean up new */ | ||
850 | GNUNET_free(new_address->plugin); | ||
851 | GNUNET_free_non_null(new_address->atsi); | ||
852 | GNUNET_free(new_address); | ||
853 | new_address = NULL; | ||
854 | |||
855 | if (0 != existing_address->session_id) | ||
856 | { | ||
857 | /* Should not happen */ | ||
858 | GNUNET_break(0); | ||
859 | return; | 675 | return; |
860 | } | 676 | } |
861 | 677 | /* Add a new address */ | |
862 | addr_net = get_performance_info (existing_address, GNUNET_ATS_NETWORK_TYPE); | 678 | new_address->t_added = GNUNET_TIME_absolute_get(); |
863 | if (GNUNET_ATS_VALUE_UNDEFINED == addr_net) | 679 | new_address->t_last_activity = GNUNET_TIME_absolute_get(); |
864 | addr_net = GNUNET_ATS_NET_UNSPECIFIED; | 680 | GNUNET_assert(GNUNET_OK == |
865 | 681 | GNUNET_CONTAINER_multipeermap_put (GSA_addresses, | |
866 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 682 | peer, |
867 | "Found existing address for peer `%s' %p with new session %u in network %s\n", | 683 | new_address, |
868 | GNUNET_i2s (peer), existing_address, session_id, | 684 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); |
869 | GNUNET_ATS_print_network_type (addr_net)); | 685 | |
870 | /* We have an address without an session, update this address */ | 686 | GNUNET_STATISTICS_set (GSA_stats, |
871 | existing_address->t_added = GNUNET_TIME_absolute_get(); | 687 | "# addresses", |
872 | existing_address->t_last_activity = GNUNET_TIME_absolute_get(); | 688 | GNUNET_CONTAINER_multipeermap_size (GSA_addresses), |
873 | atsi_delta = NULL; | 689 | GNUNET_NO); |
874 | atsi_delta_count = 0; | 690 | |
875 | if (GNUNET_YES | 691 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
876 | == disassemble_ats_information (existing_address, atsi, atsi_count, | 692 | "Adding new address %p for peer `%s', length %u, session id %u, %s\n", |
877 | &atsi_delta, &atsi_delta_count)) | 693 | new_address, |
878 | { | 694 | GNUNET_i2s (peer), |
879 | /* Notify performance clients about properties */ | 695 | plugin_addr_len, |
880 | GAS_performance_notify_all_clients (&existing_address->peer, | 696 | session_id, |
881 | existing_address->plugin, existing_address->addr, | 697 | GNUNET_ATS_print_network_type (addr_net)); |
882 | existing_address->addr_len, existing_address->active, | 698 | |
883 | existing_address->atsi, existing_address->atsi_count, | 699 | /* Tell solver about new address */ |
884 | GNUNET_BANDWIDTH_value_init (existing_address->assigned_bw_out), | 700 | GAS_plugin_new_address (new_address, |
885 | GNUNET_BANDWIDTH_value_init (existing_address->assigned_bw_in)); | 701 | addr_net, |
886 | 702 | atsi, | |
887 | for (c1 = 0; c1 < atsi_delta_count; c1++) | 703 | atsi_count); |
888 | { | 704 | /* Notify performance clients about new address */ |
889 | if ((GNUNET_ATS_NETWORK_TYPE == ntohl (atsi_delta[c1].type)) | 705 | GAS_performance_notify_all_clients (&new_address->peer, |
890 | && (addr_net != ntohl (atsi_delta[c1].value))) | 706 | new_address->plugin, |
891 | { | 707 | new_address->addr, |
892 | /* Network type changed */ | 708 | new_address->addr_len, |
893 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 709 | new_address->active, |
894 | "Address for peer `%s' %p changed from network %s to %s\n", | 710 | new_address->atsi, |
895 | GNUNET_i2s (peer), existing_address, | 711 | new_address->atsi_count, |
896 | GNUNET_ATS_print_network_type (addr_net), | 712 | GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_out), |
897 | GNUNET_ATS_print_network_type (ntohl (atsi_delta[c1].value))); | 713 | GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_in)); |
898 | env.sf.s_address_update_network (solver, existing_address, | ||
899 | ntohl (atsi_delta[c1].value), | ||
900 | get_performance_info (existing_address, GNUNET_ATS_NETWORK_TYPE)); | ||
901 | addr_net = get_performance_info (existing_address, | ||
902 | GNUNET_ATS_NETWORK_TYPE); | ||
903 | } | ||
904 | } | ||
905 | /* Notify solver about update with atsi information and session */ | ||
906 | env.sf.s_bulk_start (solver); | ||
907 | GAS_normalization_normalize_property (addresses, existing_address, | ||
908 | atsi, atsi_count); | ||
909 | env.sf.s_bulk_stop (solver); | ||
910 | } | ||
911 | GNUNET_free_non_null(atsi_delta); | ||
912 | |||
913 | /* Notify solver about new session */ | ||
914 | if (existing_address->session_id == session_id) | ||
915 | return; /* possible, can both be 0 since address is revalidated */ | ||
916 | |||
917 | previous_session = existing_address->session_id; | ||
918 | existing_address->session_id = session_id; | ||
919 | env.sf.s_address_update_session (solver, existing_address, | ||
920 | previous_session, session_id); | ||
921 | |||
922 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
923 | "Updated existing address for peer `%s' %p length %u with new session %u in network %s\n", | ||
924 | GNUNET_i2s (peer), existing_address, existing_address->addr_len, | ||
925 | session_id, GNUNET_ATS_print_network_type (addr_net)); | ||
926 | } | 714 | } |
927 | 715 | ||
928 | 716 | ||
@@ -943,12 +731,6 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, | |||
943 | struct ATS_Address *aa; | 731 | struct ATS_Address *aa; |
944 | struct GNUNET_ATS_Information *atsi_delta; | 732 | struct GNUNET_ATS_Information *atsi_delta; |
945 | uint32_t atsi_delta_count; | 733 | uint32_t atsi_delta_count; |
946 | uint32_t prev_session; | ||
947 | int c1; | ||
948 | |||
949 | if (GNUNET_NO == running) | ||
950 | return; | ||
951 | GNUNET_assert (NULL != addresses); | ||
952 | 734 | ||
953 | /* Get existing address */ | 735 | /* Get existing address */ |
954 | aa = find_exact_address (peer, | 736 | aa = find_exact_address (peer, |
@@ -963,7 +745,6 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, | |||
963 | GNUNET_break (0); | 745 | GNUNET_break (0); |
964 | return; | 746 | return; |
965 | } | 747 | } |
966 | |||
967 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 748 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
968 | "Received `%s' for peer `%s' address \n", | 749 | "Received `%s' for peer `%s' address \n", |
969 | "ADDRESS UPDATE", | 750 | "ADDRESS UPDATE", |
@@ -972,17 +753,6 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, | |||
972 | 753 | ||
973 | /* Update address */ | 754 | /* Update address */ |
974 | aa->t_last_activity = GNUNET_TIME_absolute_get(); | 755 | aa->t_last_activity = GNUNET_TIME_absolute_get(); |
975 | if (session_id != aa->session_id) | ||
976 | { | ||
977 | /* Session changed */ | ||
978 | prev_session = aa->session_id; | ||
979 | aa->session_id = session_id; | ||
980 | env.sf.s_address_update_session (solver, | ||
981 | aa, | ||
982 | prev_session, | ||
983 | aa->session_id); | ||
984 | } | ||
985 | |||
986 | atsi_delta = NULL; | 756 | atsi_delta = NULL; |
987 | atsi_delta_count = 0; | 757 | atsi_delta_count = 0; |
988 | if (GNUNET_YES == | 758 | if (GNUNET_YES == |
@@ -991,30 +761,20 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, | |||
991 | &atsi_delta, | 761 | &atsi_delta, |
992 | &atsi_delta_count)) | 762 | &atsi_delta_count)) |
993 | { | 763 | { |
994 | /* ATS properties changed */ | ||
995 | for (c1 = 0; c1 < atsi_delta_count; c1++) | ||
996 | { | ||
997 | if (GNUNET_ATS_NETWORK_TYPE == ntohl (atsi_delta[c1].type)) | ||
998 | { | ||
999 | /* Network type changed */ | ||
1000 | env.sf.s_address_update_network (solver, aa, | ||
1001 | ntohl (atsi_delta[c1].value), | ||
1002 | get_performance_info (aa, GNUNET_ATS_NETWORK_TYPE)); | ||
1003 | } | ||
1004 | } | ||
1005 | |||
1006 | /* Notify performance clients about updated address */ | 764 | /* Notify performance clients about updated address */ |
1007 | GAS_performance_notify_all_clients (&aa->peer, aa->plugin, aa->addr, | 765 | GAS_performance_notify_all_clients (&aa->peer, |
1008 | aa->addr_len, aa->active, aa->atsi, aa->atsi_count, | 766 | aa->plugin, |
1009 | GNUNET_BANDWIDTH_value_init (aa->assigned_bw_out), | 767 | aa->addr, |
1010 | GNUNET_BANDWIDTH_value_init (aa->assigned_bw_in)); | 768 | aa->addr_len, |
1011 | 769 | aa->active, | |
1012 | env.sf.s_bulk_start (solver); | 770 | aa->atsi, |
1013 | GAS_normalization_normalize_property (addresses, | 771 | aa->atsi_count, |
1014 | aa, | 772 | GNUNET_BANDWIDTH_value_init (aa->assigned_bw_out), |
1015 | atsi, | 773 | GNUNET_BANDWIDTH_value_init (aa->assigned_bw_in)); |
1016 | atsi_count); | 774 | |
1017 | env.sf.s_bulk_stop (solver); | 775 | GAS_plugin_update_address (aa, |
776 | atsi, | ||
777 | atsi_count); | ||
1018 | } | 778 | } |
1019 | GNUNET_free_non_null (atsi_delta); | 779 | GNUNET_free_non_null (atsi_delta); |
1020 | } | 780 | } |
@@ -1032,9 +792,6 @@ GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer, | |||
1032 | { | 792 | { |
1033 | struct ATS_Address *ea; | 793 | struct ATS_Address *ea; |
1034 | 794 | ||
1035 | if (GNUNET_NO == running) | ||
1036 | return; | ||
1037 | |||
1038 | /* Get existing address */ | 795 | /* Get existing address */ |
1039 | ea = find_exact_address (peer, | 796 | ea = find_exact_address (peer, |
1040 | session_id); | 797 | session_id); |
@@ -1054,11 +811,10 @@ GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer, | |||
1054 | GNUNET_i2s (peer), | 811 | GNUNET_i2s (peer), |
1055 | ea, | 812 | ea, |
1056 | session_id); | 813 | session_id); |
1057 | GNUNET_CONTAINER_multipeermap_remove (addresses, | 814 | GNUNET_CONTAINER_multipeermap_remove (GSA_addresses, |
1058 | peer, | 815 | peer, |
1059 | ea); | 816 | ea); |
1060 | 817 | GAS_plugin_delete_address (ea); | |
1061 | env.sf.s_del (solver, ea, GNUNET_NO); | ||
1062 | GAS_performance_notify_all_clients (peer, | 818 | GAS_performance_notify_all_clients (peer, |
1063 | ea->plugin, | 819 | ea->plugin, |
1064 | ea->addr, | 820 | ea->addr, |
@@ -1068,607 +824,14 @@ GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer, | |||
1068 | zero_bw, | 824 | zero_bw, |
1069 | zero_bw); | 825 | zero_bw); |
1070 | free_address (ea); | 826 | free_address (ea); |
1071 | GNUNET_STATISTICS_set (stats, | 827 | GNUNET_STATISTICS_set (GSA_stats, |
1072 | "# addresses", | 828 | "# addresses", |
1073 | GNUNET_CONTAINER_multipeermap_size (addresses), | 829 | GNUNET_CONTAINER_multipeermap_size (GSA_addresses), |
1074 | GNUNET_NO); | 830 | GNUNET_NO); |
1075 | } | 831 | } |
1076 | 832 | ||
1077 | 833 | ||
1078 | /** | ||
1079 | * Cancel address suggestions for a peer | ||
1080 | * | ||
1081 | * @param peer the peer id | ||
1082 | */ | ||
1083 | void | ||
1084 | GAS_addresses_request_address_cancel (const struct GNUNET_PeerIdentity *peer) | ||
1085 | { | ||
1086 | struct GAS_Addresses_Suggestion_Requests *cur = pending_requests_head; | ||
1087 | |||
1088 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1089 | "Received request: `%s' for peer %s\n", | ||
1090 | "request_address_cancel", | ||
1091 | GNUNET_i2s (peer)); | ||
1092 | |||
1093 | while (NULL != cur) | ||
1094 | { | ||
1095 | if (0 == memcmp (peer, &cur->id, sizeof(cur->id))) | ||
1096 | break; /* found */ | ||
1097 | cur = cur->next; | ||
1098 | } | ||
1099 | |||
1100 | if (NULL == cur) | ||
1101 | { | ||
1102 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1103 | "No address requests pending for peer `%s', cannot remove!\n", | ||
1104 | GNUNET_i2s (peer)); | ||
1105 | return; | ||
1106 | } | ||
1107 | env.sf.s_get_stop (solver, peer); | ||
1108 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1109 | "Removed request pending for peer `%s\n", | ||
1110 | GNUNET_i2s (peer)); | ||
1111 | GNUNET_CONTAINER_DLL_remove (pending_requests_head, | ||
1112 | pending_requests_tail, | ||
1113 | cur); | ||
1114 | GNUNET_free(cur); | ||
1115 | } | ||
1116 | |||
1117 | |||
1118 | /** | ||
1119 | * Request address suggestions for a peer | ||
1120 | * | ||
1121 | * @param peer the peer id | ||
1122 | */ | ||
1123 | void | ||
1124 | GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer) | ||
1125 | { | ||
1126 | struct GAS_Addresses_Suggestion_Requests *cur = pending_requests_head; | ||
1127 | struct ATS_Address *aa; | ||
1128 | |||
1129 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1130 | "Received `%s' for peer `%s'\n", | ||
1131 | "REQUEST ADDRESS", | ||
1132 | GNUNET_i2s (peer)); | ||
1133 | |||
1134 | if (GNUNET_NO == running) | ||
1135 | return; | ||
1136 | while (NULL != cur) | ||
1137 | { | ||
1138 | if (0 == memcmp (peer, &cur->id, sizeof(cur->id))) | ||
1139 | break; /* already suggesting */ | ||
1140 | cur = cur->next; | ||
1141 | } | ||
1142 | if (NULL == cur) | ||
1143 | { | ||
1144 | cur = GNUNET_new (struct GAS_Addresses_Suggestion_Requests); | ||
1145 | cur->id = *peer; | ||
1146 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1147 | "Adding new address suggestion request for `%s'\n", | ||
1148 | GNUNET_i2s (peer)); | ||
1149 | GNUNET_CONTAINER_DLL_insert (pending_requests_head, | ||
1150 | pending_requests_tail, | ||
1151 | cur); | ||
1152 | } | ||
1153 | |||
1154 | /* Get prefered address from solver */ | ||
1155 | aa = (struct ATS_Address *) env.sf.s_get (solver, peer); | ||
1156 | if (NULL == aa) | ||
1157 | { | ||
1158 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Cannot suggest address for peer `%s'\n", | ||
1159 | GNUNET_i2s (peer)); | ||
1160 | return; | ||
1161 | } | ||
1162 | |||
1163 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Suggesting address %p for peer `%s'\n", | ||
1164 | aa, GNUNET_i2s (peer)); | ||
1165 | |||
1166 | GAS_scheduling_transmit_address_suggestion (peer, | ||
1167 | aa->session_id, | ||
1168 | GNUNET_BANDWIDTH_value_init (aa->assigned_bw_out), | ||
1169 | GNUNET_BANDWIDTH_value_init (aa->assigned_bw_in)); | ||
1170 | |||
1171 | aa->block_interval = GNUNET_TIME_relative_add (aa->block_interval, | ||
1172 | ATS_BLOCKING_DELTA); | ||
1173 | aa->blocked_until = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), | ||
1174 | aa->block_interval); | ||
1175 | |||
1176 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1177 | "Address %p ready for suggestion, block interval now %llu \n", aa, | ||
1178 | aa->block_interval); | ||
1179 | } | ||
1180 | |||
1181 | |||
1182 | /** | ||
1183 | * Solver information callback | ||
1184 | * | ||
1185 | * @param cls the closure | ||
1186 | * @param op the operation | ||
1187 | * @param status operation status | ||
1188 | * @param add additional information | ||
1189 | */ | ||
1190 | static void | ||
1191 | solver_info_cb (void *cls, | ||
1192 | enum GAS_Solver_Operation op, | ||
1193 | enum GAS_Solver_Status status, | ||
1194 | enum GAS_Solver_Additional_Information add) | ||
1195 | { | ||
1196 | char *add_info; | ||
1197 | |||
1198 | switch (add) { | ||
1199 | case GAS_INFO_NONE: | ||
1200 | add_info = "GAS_INFO_NONE"; | ||
1201 | break; | ||
1202 | case GAS_INFO_FULL: | ||
1203 | add_info = "GAS_INFO_MLP_FULL"; | ||
1204 | break; | ||
1205 | case GAS_INFO_UPDATED: | ||
1206 | add_info = "GAS_INFO_MLP_UPDATED"; | ||
1207 | break; | ||
1208 | case GAS_INFO_PROP_ALL: | ||
1209 | add_info = "GAS_INFO_PROP_ALL"; | ||
1210 | break; | ||
1211 | case GAS_INFO_PROP_SINGLE: | ||
1212 | add_info = "GAS_INFO_PROP_SINGLE"; | ||
1213 | break; | ||
1214 | default: | ||
1215 | add_info = "INVALID"; | ||
1216 | break; | ||
1217 | } | ||
1218 | switch (op) | ||
1219 | { | ||
1220 | case GAS_OP_SOLVE_START: | ||
1221 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1222 | "Solver notifies `%s' with result `%s' `%s'\n", "GAS_OP_SOLVE_START", | ||
1223 | (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL", add_info); | ||
1224 | return; | ||
1225 | case GAS_OP_SOLVE_STOP: | ||
1226 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1227 | "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_STOP", | ||
1228 | (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL", add_info); | ||
1229 | return; | ||
1230 | |||
1231 | case GAS_OP_SOLVE_SETUP_START: | ||
1232 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1233 | "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_START", | ||
1234 | (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); | ||
1235 | return; | ||
1236 | |||
1237 | case GAS_OP_SOLVE_SETUP_STOP: | ||
1238 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1239 | "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_STOP", | ||
1240 | (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); | ||
1241 | return; | ||
1242 | |||
1243 | case GAS_OP_SOLVE_MLP_LP_START: | ||
1244 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1245 | "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_START", | ||
1246 | (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); | ||
1247 | return; | ||
1248 | case GAS_OP_SOLVE_MLP_LP_STOP: | ||
1249 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1250 | "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_STOP", | ||
1251 | (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); | ||
1252 | return; | ||
1253 | |||
1254 | case GAS_OP_SOLVE_MLP_MLP_START: | ||
1255 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1256 | "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_START", | ||
1257 | (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); | ||
1258 | return; | ||
1259 | case GAS_OP_SOLVE_MLP_MLP_STOP: | ||
1260 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1261 | "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_STOP", | ||
1262 | (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); | ||
1263 | return; | ||
1264 | case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START: | ||
1265 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1266 | "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START", | ||
1267 | (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); | ||
1268 | return; | ||
1269 | case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP: | ||
1270 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1271 | "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP", | ||
1272 | (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); | ||
1273 | return; | ||
1274 | default: | ||
1275 | break; | ||
1276 | } | ||
1277 | } | ||
1278 | |||
1279 | |||
1280 | /** | ||
1281 | * The preference changed for a peer | ||
1282 | * | ||
1283 | * @param cls NULL | ||
1284 | * @param peer the peer | ||
1285 | * @param kind the ATS kind | ||
1286 | * @param pref_rel the new relative preference value | ||
1287 | */ | ||
1288 | static void | ||
1289 | normalized_preference_changed_cb (void *cls, | ||
1290 | const struct GNUNET_PeerIdentity *peer, | ||
1291 | enum GNUNET_ATS_PreferenceKind kind, | ||
1292 | double pref_rel) | ||
1293 | { | ||
1294 | /* Tell solver about update */ | ||
1295 | env.sf.s_pref (solver, peer, kind, pref_rel); | ||
1296 | } | ||
1297 | |||
1298 | |||
1299 | /** | ||
1300 | * The relative value for a property changed | ||
1301 | * | ||
1302 | * @param cls NULL | ||
1303 | * @param address the peer | ||
1304 | * @param type the ATS type | ||
1305 | * @param prop_rel the new relative preference value | ||
1306 | */ | ||
1307 | static void | ||
1308 | normalized_property_changed_cb (void *cls, | ||
1309 | struct ATS_Address *address, | ||
1310 | uint32_t type, | ||
1311 | double prop_rel) | ||
1312 | { | ||
1313 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1314 | "Normalized property %s for peer `%s' changed to %.3f \n", | ||
1315 | GNUNET_ATS_print_property_type (type), | ||
1316 | GNUNET_i2s (&address->peer), | ||
1317 | prop_rel); | ||
1318 | env.sf.s_address_update_property (solver, | ||
1319 | address, | ||
1320 | type, | ||
1321 | 0, | ||
1322 | prop_rel); | ||
1323 | } | ||
1324 | |||
1325 | |||
1326 | static struct GAS_Addresses_Preference_Clients * | ||
1327 | find_preference_client (void *client) | ||
1328 | { | ||
1329 | struct GAS_Addresses_Preference_Clients *cur; | ||
1330 | 834 | ||
1331 | for (cur = preference_clients_head; NULL != cur; cur = cur->next) | ||
1332 | if (cur->client == client) | ||
1333 | return cur; | ||
1334 | return NULL; | ||
1335 | } | ||
1336 | |||
1337 | |||
1338 | /** | ||
1339 | * A performance client disconnected | ||
1340 | * | ||
1341 | * @param client the client | ||
1342 | */ | ||
1343 | void | ||
1344 | GAS_addresses_preference_client_disconnect (void *client) | ||
1345 | { | ||
1346 | struct GAS_Addresses_Preference_Clients *pc; | ||
1347 | |||
1348 | if (NULL != (pc = find_preference_client (client))) | ||
1349 | { | ||
1350 | GNUNET_CONTAINER_DLL_remove (preference_clients_head, | ||
1351 | preference_clients_tail, | ||
1352 | pc); | ||
1353 | GNUNET_free (pc); | ||
1354 | GNUNET_assert (pref_clients > 0); | ||
1355 | pref_clients --; | ||
1356 | GNUNET_STATISTICS_set (stats, | ||
1357 | "# active performance clients", | ||
1358 | pref_clients, | ||
1359 | GNUNET_NO); | ||
1360 | } | ||
1361 | GAS_normalization_preference_client_disconnect (client); | ||
1362 | } | ||
1363 | |||
1364 | |||
1365 | /** | ||
1366 | * Change the preference for a peer | ||
1367 | * | ||
1368 | * @param client the client sending this request | ||
1369 | * @param peer the peer id | ||
1370 | * @param kind the preference kind to change | ||
1371 | * @param score_abs the new preference score | ||
1372 | */ | ||
1373 | void | ||
1374 | GAS_addresses_preference_change (void *client, | ||
1375 | const struct GNUNET_PeerIdentity *peer, | ||
1376 | enum GNUNET_ATS_PreferenceKind kind, | ||
1377 | float score_abs) | ||
1378 | { | ||
1379 | struct GAS_Addresses_Preference_Clients *pc; | ||
1380 | |||
1381 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1382 | "Received `%s' for peer `%s' for client %p\n", "CHANGE PREFERENCE", | ||
1383 | GNUNET_i2s (peer), client); | ||
1384 | |||
1385 | if (GNUNET_NO == running) | ||
1386 | return; | ||
1387 | |||
1388 | if (GNUNET_NO == | ||
1389 | GNUNET_CONTAINER_multipeermap_contains (addresses, | ||
1390 | peer)) | ||
1391 | { | ||
1392 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1393 | "Received `%s' for unknown peer `%s' from client %p\n", | ||
1394 | "CHANGE PREFERENCE", GNUNET_i2s (peer), client); | ||
1395 | return; | ||
1396 | } | ||
1397 | |||
1398 | if (NULL == find_preference_client (client)) | ||
1399 | { | ||
1400 | pc = GNUNET_new (struct GAS_Addresses_Preference_Clients); | ||
1401 | pc->client = client; | ||
1402 | GNUNET_CONTAINER_DLL_insert (preference_clients_head, | ||
1403 | preference_clients_tail, | ||
1404 | pc); | ||
1405 | pref_clients ++; | ||
1406 | GNUNET_STATISTICS_set (stats, | ||
1407 | "# active performance clients", | ||
1408 | pref_clients, | ||
1409 | GNUNET_NO); | ||
1410 | } | ||
1411 | |||
1412 | env.sf.s_bulk_start (solver); | ||
1413 | /* Tell normalization about change, normalization will call callback if preference changed */ | ||
1414 | GAS_normalization_normalize_preference (client, peer, kind, score_abs); | ||
1415 | env.sf.s_bulk_stop (solver); | ||
1416 | } | ||
1417 | |||
1418 | |||
1419 | /** | ||
1420 | * Change the preference for a peer | ||
1421 | * | ||
1422 | * @param application the client sending this request | ||
1423 | * @param peer the peer id | ||
1424 | * @param scope the time interval for this feedback: [now - scope .. now] | ||
1425 | * @param kind the preference kind to change | ||
1426 | * @param score_abs the new preference score | ||
1427 | */ | ||
1428 | void | ||
1429 | GAS_addresses_preference_feedback (void *application, | ||
1430 | const struct GNUNET_PeerIdentity *peer, | ||
1431 | const struct GNUNET_TIME_Relative scope, | ||
1432 | enum GNUNET_ATS_PreferenceKind kind, | ||
1433 | float score_abs) | ||
1434 | { | ||
1435 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1436 | "Received `%s' for peer `%s' for client %p\n", | ||
1437 | "PREFERENCE FEEDBACK", | ||
1438 | GNUNET_i2s (peer), | ||
1439 | application); | ||
1440 | |||
1441 | if (GNUNET_NO == running) | ||
1442 | return; | ||
1443 | |||
1444 | if (GNUNET_NO == | ||
1445 | GNUNET_CONTAINER_multipeermap_contains (addresses, | ||
1446 | peer)) | ||
1447 | { | ||
1448 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1449 | "Received `%s' for unknown peer `%s' from client %p\n", | ||
1450 | "PREFERENCE FEEDBACK", GNUNET_i2s (peer), application); | ||
1451 | return; | ||
1452 | } | ||
1453 | |||
1454 | env.sf.s_feedback (solver, application, peer, scope, kind, | ||
1455 | score_abs); | ||
1456 | } | ||
1457 | |||
1458 | |||
1459 | /** | ||
1460 | * Load quotas for networks from configuration | ||
1461 | * | ||
1462 | * @param cfg configuration handle | ||
1463 | * @param out_dest where to write outbound quotas | ||
1464 | * @param in_dest where to write inbound quotas | ||
1465 | * @param dest_length length of inbound and outbound arrays | ||
1466 | * @return number of networks loaded | ||
1467 | */ | ||
1468 | static unsigned int | ||
1469 | load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
1470 | unsigned long long *out_dest, unsigned long long *in_dest, int dest_length) | ||
1471 | { | ||
1472 | char * entry_in = NULL; | ||
1473 | char * entry_out = NULL; | ||
1474 | char * quota_out_str; | ||
1475 | char * quota_in_str; | ||
1476 | int c; | ||
1477 | int res; | ||
1478 | |||
1479 | for (c = 0; (c < GNUNET_ATS_NetworkTypeCount) && (c < dest_length); c++) | ||
1480 | { | ||
1481 | in_dest[c] = 0; | ||
1482 | out_dest[c] = 0; | ||
1483 | GNUNET_asprintf (&entry_out, | ||
1484 | "%s_QUOTA_OUT", | ||
1485 | GNUNET_ATS_print_network_type (c)); | ||
1486 | GNUNET_asprintf (&entry_in, | ||
1487 | "%s_QUOTA_IN", | ||
1488 | GNUNET_ATS_print_network_type (c)); | ||
1489 | |||
1490 | /* quota out */ | ||
1491 | if (GNUNET_OK | ||
1492 | == GNUNET_CONFIGURATION_get_value_string (cfg, "ats", entry_out, | ||
1493 | "a_out_str)) | ||
1494 | { | ||
1495 | res = GNUNET_NO; | ||
1496 | if (0 == strcmp (quota_out_str, GNUNET_ATS_MaxBandwidthString)) | ||
1497 | { | ||
1498 | out_dest[c] = GNUNET_ATS_MaxBandwidth; | ||
1499 | res = GNUNET_YES; | ||
1500 | } | ||
1501 | if ((GNUNET_NO == res) | ||
1502 | && (GNUNET_OK | ||
1503 | == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, | ||
1504 | &out_dest[c]))) | ||
1505 | res = GNUNET_YES; | ||
1506 | if ((GNUNET_NO == res) | ||
1507 | && (GNUNET_OK | ||
1508 | == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_out, | ||
1509 | &out_dest[c]))) | ||
1510 | res = GNUNET_YES; | ||
1511 | |||
1512 | if (GNUNET_NO == res) | ||
1513 | { | ||
1514 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1515 | _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"), | ||
1516 | GNUNET_ATS_print_network_type (c), | ||
1517 | quota_out_str, | ||
1518 | GNUNET_ATS_DefaultBandwidth); | ||
1519 | out_dest[c] = GNUNET_ATS_DefaultBandwidth; | ||
1520 | } | ||
1521 | else | ||
1522 | { | ||
1523 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
1524 | _("Outbound quota configure for network `%s' is %llu\n"), | ||
1525 | GNUNET_ATS_print_network_type (c), | ||
1526 | out_dest[c]); | ||
1527 | } | ||
1528 | GNUNET_free(quota_out_str); | ||
1529 | } | ||
1530 | else | ||
1531 | { | ||
1532 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1533 | _("No outbound quota configured for network `%s', assigning default bandwidth %llu\n"), | ||
1534 | GNUNET_ATS_print_network_type (c), | ||
1535 | GNUNET_ATS_DefaultBandwidth); | ||
1536 | out_dest[c] = GNUNET_ATS_DefaultBandwidth; | ||
1537 | } | ||
1538 | |||
1539 | /* quota in */ | ||
1540 | if (GNUNET_OK | ||
1541 | == GNUNET_CONFIGURATION_get_value_string (cfg, "ats", entry_in, | ||
1542 | "a_in_str)) | ||
1543 | { | ||
1544 | res = GNUNET_NO; | ||
1545 | if (0 == strcmp (quota_in_str, GNUNET_ATS_MaxBandwidthString)) | ||
1546 | { | ||
1547 | in_dest[c] = GNUNET_ATS_MaxBandwidth; | ||
1548 | res = GNUNET_YES; | ||
1549 | } | ||
1550 | if ((GNUNET_NO == res) | ||
1551 | && (GNUNET_OK | ||
1552 | == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &in_dest[c]))) | ||
1553 | res = GNUNET_YES; | ||
1554 | if ((GNUNET_NO == res) | ||
1555 | && (GNUNET_OK | ||
1556 | == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_in, | ||
1557 | &in_dest[c]))) | ||
1558 | res = GNUNET_YES; | ||
1559 | |||
1560 | if (GNUNET_NO == res) | ||
1561 | { | ||
1562 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1563 | _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"), | ||
1564 | GNUNET_ATS_print_network_type (c), | ||
1565 | quota_in_str, | ||
1566 | GNUNET_ATS_DefaultBandwidth); | ||
1567 | in_dest[c] = GNUNET_ATS_DefaultBandwidth; | ||
1568 | } | ||
1569 | else | ||
1570 | { | ||
1571 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
1572 | _("Inbound quota configured for network `%s' is %llu\n"), | ||
1573 | GNUNET_ATS_print_network_type (c), | ||
1574 | in_dest[c]); | ||
1575 | } | ||
1576 | GNUNET_free(quota_in_str); | ||
1577 | } | ||
1578 | else | ||
1579 | { | ||
1580 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1581 | _("No outbound quota configure for network `%s', assigning default bandwidth %llu\n"), | ||
1582 | GNUNET_ATS_print_network_type (c), | ||
1583 | GNUNET_ATS_DefaultBandwidth); | ||
1584 | in_dest[c] = GNUNET_ATS_DefaultBandwidth; | ||
1585 | } | ||
1586 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1587 | "Loaded quota for network `%s' (in/out): %llu %llu\n", | ||
1588 | GNUNET_ATS_print_network_type (c), | ||
1589 | in_dest[c], | ||
1590 | out_dest[c]); | ||
1591 | GNUNET_free(entry_out); | ||
1592 | GNUNET_free(entry_in); | ||
1593 | } | ||
1594 | return GNUNET_ATS_NetworkTypeCount; | ||
1595 | } | ||
1596 | |||
1597 | |||
1598 | /** | ||
1599 | * Callback for solver to notify about assignment changes | ||
1600 | * | ||
1601 | * @param cls NULL | ||
1602 | * @param address the address with changes | ||
1603 | */ | ||
1604 | static void | ||
1605 | bandwidth_changed_cb (void *cls, struct ATS_Address *address) | ||
1606 | { | ||
1607 | struct GAS_Addresses_Suggestion_Requests *cur; | ||
1608 | uint32_t diff_out; | ||
1609 | uint32_t diff_in; | ||
1610 | |||
1611 | GNUNET_assert(address != NULL); | ||
1612 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1613 | "Bandwidth assignment changed for peer %s \n", | ||
1614 | GNUNET_i2s (&address->peer)); | ||
1615 | |||
1616 | /* Notify performance clients about changes to address */ | ||
1617 | GAS_performance_notify_all_clients (&address->peer, address->plugin, | ||
1618 | address->addr, address->addr_len, address->active, address->atsi, | ||
1619 | address->atsi_count, | ||
1620 | GNUNET_BANDWIDTH_value_init (address->assigned_bw_out), | ||
1621 | GNUNET_BANDWIDTH_value_init (address->assigned_bw_in)); | ||
1622 | |||
1623 | for (cur = pending_requests_head;NULL != cur; cur = cur->next) | ||
1624 | if (0 == memcmp (&address->peer, | ||
1625 | &cur->id, | ||
1626 | sizeof(cur->id))) | ||
1627 | break; /* we have an address request pending*/ | ||
1628 | if (NULL == cur) | ||
1629 | { | ||
1630 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
1631 | "Nobody is interested in peer `%s' :(\n", | ||
1632 | GNUNET_i2s (&address->peer)); | ||
1633 | return; | ||
1634 | } | ||
1635 | |||
1636 | if ((0 == address->assigned_bw_in) && (0 == address->assigned_bw_out)) | ||
1637 | { | ||
1638 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1639 | "Telling transport to disconnect peer `%s'\n", | ||
1640 | GNUNET_i2s (&address->peer)); | ||
1641 | |||
1642 | /* Notify scheduling clients about suggestion */ | ||
1643 | GAS_scheduling_transmit_address_suggestion (&address->peer, | ||
1644 | address->session_id, | ||
1645 | zero_bw, | ||
1646 | zero_bw); | ||
1647 | return; | ||
1648 | } | ||
1649 | |||
1650 | /* Do bandwidth stability check */ | ||
1651 | diff_out = abs (address->assigned_bw_out - address->last_notified_bw_out); | ||
1652 | diff_in = abs (address->assigned_bw_in - address->last_notified_bw_in); | ||
1653 | |||
1654 | if ( (diff_out < htonl(GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__)) && | ||
1655 | (diff_in < htonl(GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__)) ) | ||
1656 | return; | ||
1657 | |||
1658 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
1659 | "Sending bandwidth update for peer `%s': %u %u\n", | ||
1660 | GNUNET_i2s (&address->peer), address->assigned_bw_out, | ||
1661 | address->assigned_bw_out); | ||
1662 | |||
1663 | /* *Notify scheduling clients about suggestion */ | ||
1664 | GAS_scheduling_transmit_address_suggestion (&address->peer, | ||
1665 | address->session_id, | ||
1666 | GNUNET_BANDWIDTH_value_init (address->assigned_bw_out), | ||
1667 | GNUNET_BANDWIDTH_value_init (address->assigned_bw_in)); | ||
1668 | |||
1669 | address->last_notified_bw_out = address->assigned_bw_out; | ||
1670 | address->last_notified_bw_in = address->assigned_bw_in; | ||
1671 | } | ||
1672 | 835 | ||
1673 | 836 | ||
1674 | /** | 837 | /** |
@@ -1676,146 +839,16 @@ bandwidth_changed_cb (void *cls, struct ATS_Address *address) | |||
1676 | * known and current performance information. It has a solver component | 839 | * known and current performance information. It has a solver component |
1677 | * responsible for the resource allocation. It tells the solver about changes | 840 | * responsible for the resource allocation. It tells the solver about changes |
1678 | * and receives updates when the solver changes the resource allocation. | 841 | * and receives updates when the solver changes the resource allocation. |
1679 | * | ||
1680 | * @param cfg configuration to use | ||
1681 | * @param stats_ the statistics handle to use | ||
1682 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error (failed to load | ||
1683 | * solver plugin) | ||
1684 | */ | 842 | */ |
1685 | int | 843 | void |
1686 | GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg, | 844 | GAS_addresses_init () |
1687 | struct GNUNET_STATISTICS_Handle *stats_) | ||
1688 | { | 845 | { |
1689 | unsigned long long quotas_in[GNUNET_ATS_NetworkTypeCount]; | ||
1690 | unsigned long long quotas_out[GNUNET_ATS_NetworkTypeCount]; | ||
1691 | char *mode_str; | ||
1692 | char *plugin_short; | ||
1693 | int c; | ||
1694 | |||
1695 | running = GNUNET_NO; | ||
1696 | stats = stats_; | ||
1697 | /* Initialize the addresses database */ | 846 | /* Initialize the addresses database */ |
1698 | addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO); | 847 | GSA_addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO); |
1699 | pref_clients = 0; | 848 | GNUNET_STATISTICS_set (GSA_stats, |
1700 | |||
1701 | /* Figure out configured solution method */ | ||
1702 | if (GNUNET_SYSERR == | ||
1703 | GNUNET_CONFIGURATION_get_value_string (cfg, "ats", "MODE", &mode_str)) | ||
1704 | { | ||
1705 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | ||
1706 | "No resource assignment method configured, using proportional approach\n"); | ||
1707 | ats_mode = MODE_PROPORTIONAL; | ||
1708 | } | ||
1709 | else | ||
1710 | { | ||
1711 | for (c = 0; c < strlen (mode_str); c++) | ||
1712 | mode_str[c] = toupper (mode_str[c]); | ||
1713 | if (0 == strcmp (mode_str, "PROPORTIONAL")) | ||
1714 | ats_mode = MODE_PROPORTIONAL; | ||
1715 | else if (0 == strcmp (mode_str, "MLP")) | ||
1716 | { | ||
1717 | ats_mode = MODE_MLP; | ||
1718 | #if !HAVE_LIBGLPK | ||
1719 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1720 | "Assignment method `%s' configured, but GLPK is not available, please install \n", | ||
1721 | mode_str); | ||
1722 | ats_mode = MODE_PROPORTIONAL; | ||
1723 | #endif | ||
1724 | } | ||
1725 | else if (0 == strcmp (mode_str, "RIL")) | ||
1726 | ats_mode = MODE_RIL; | ||
1727 | else | ||
1728 | { | ||
1729 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1730 | "Invalid resource assignment method `%s' configured, using proportional approach\n", | ||
1731 | mode_str); | ||
1732 | ats_mode = MODE_PROPORTIONAL; | ||
1733 | } | ||
1734 | GNUNET_free(mode_str); | ||
1735 | } | ||
1736 | |||
1737 | load_quotas (cfg, quotas_out, quotas_in, GNUNET_ATS_NetworkTypeCount); | ||
1738 | env.info_cb = &solver_info_cb; | ||
1739 | env.info_cb_cls = NULL; | ||
1740 | env.bandwidth_changed_cb = &bandwidth_changed_cb; | ||
1741 | env.bw_changed_cb_cls = NULL; | ||
1742 | env.get_preferences = &get_preferences_cb; | ||
1743 | env.get_preference_cls = NULL; | ||
1744 | env.get_property = &get_property_cb; | ||
1745 | env.get_property_cls = NULL; | ||
1746 | env.cfg = cfg; | ||
1747 | env.stats = stats; | ||
1748 | env.addresses = addresses; | ||
1749 | |||
1750 | env.network_count = GNUNET_ATS_NetworkTypeCount; | ||
1751 | int networks[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType; | ||
1752 | for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++) | ||
1753 | { | ||
1754 | env.networks[c] = networks[c]; | ||
1755 | env.out_quota[c] = quotas_out[c]; | ||
1756 | env.in_quota[c] = quotas_in[c]; | ||
1757 | } | ||
1758 | |||
1759 | switch (ats_mode) { | ||
1760 | case MODE_PROPORTIONAL: | ||
1761 | plugin_short = "proportional"; | ||
1762 | break; | ||
1763 | case MODE_MLP: | ||
1764 | plugin_short = "mlp"; | ||
1765 | break; | ||
1766 | case MODE_RIL: | ||
1767 | plugin_short = "ril"; | ||
1768 | break; | ||
1769 | default: | ||
1770 | plugin_short = NULL; | ||
1771 | break; | ||
1772 | } | ||
1773 | GNUNET_asprintf (&plugin, | ||
1774 | "libgnunet_plugin_ats_%s", | ||
1775 | plugin_short); | ||
1776 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1777 | "Initializing solver `%s '`%s'\n", | ||
1778 | plugin_short, | ||
1779 | plugin); | ||
1780 | if (NULL == (solver = GNUNET_PLUGIN_load (plugin, &env))) | ||
1781 | { | ||
1782 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1783 | _("Failed to initialize solver `%s'!\n"), | ||
1784 | plugin); | ||
1785 | return GNUNET_SYSERR; | ||
1786 | } | ||
1787 | |||
1788 | GNUNET_assert (NULL != env.sf.s_add); | ||
1789 | GNUNET_assert (NULL != env.sf.s_address_update_property); | ||
1790 | GNUNET_assert (NULL != env.sf.s_address_update_session); | ||
1791 | GNUNET_assert (NULL != env.sf.s_address_update_network); | ||
1792 | GNUNET_assert (NULL != env.sf.s_get); | ||
1793 | GNUNET_assert (NULL != env.sf.s_get_stop); | ||
1794 | GNUNET_assert (NULL != env.sf.s_pref); | ||
1795 | GNUNET_assert (NULL != env.sf.s_feedback); | ||
1796 | GNUNET_assert (NULL != env.sf.s_del); | ||
1797 | GNUNET_assert (NULL != env.sf.s_bulk_start); | ||
1798 | GNUNET_assert (NULL != env.sf.s_bulk_stop); | ||
1799 | |||
1800 | |||
1801 | GAS_normalization_start (&normalized_preference_changed_cb, NULL, | ||
1802 | &normalized_property_changed_cb, NULL); | ||
1803 | |||
1804 | if (NULL == solver) | ||
1805 | { | ||
1806 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1807 | _("Failed to initialize solver!\n")); | ||
1808 | return GNUNET_SYSERR; | ||
1809 | } | ||
1810 | /* up and running */ | ||
1811 | running = GNUNET_YES; | ||
1812 | |||
1813 | GNUNET_STATISTICS_set (stats, | ||
1814 | "# addresses", | 849 | "# addresses", |
1815 | GNUNET_CONTAINER_multipeermap_size (addresses), | 850 | GNUNET_CONTAINER_multipeermap_size (GSA_addresses), |
1816 | GNUNET_NO); | 851 | GNUNET_NO); |
1817 | |||
1818 | return GNUNET_OK; | ||
1819 | } | 852 | } |
1820 | 853 | ||
1821 | 854 | ||
@@ -1835,12 +868,12 @@ destroy_all_address_it (void *cls, | |||
1835 | struct ATS_Address *aa = value; | 868 | struct ATS_Address *aa = value; |
1836 | 869 | ||
1837 | /* Remove */ | 870 | /* Remove */ |
1838 | GNUNET_assert(GNUNET_YES == | 871 | GNUNET_assert (GNUNET_YES == |
1839 | GNUNET_CONTAINER_multipeermap_remove (addresses, | 872 | GNUNET_CONTAINER_multipeermap_remove (GSA_addresses, |
1840 | key, | 873 | key, |
1841 | value)); | 874 | value)); |
1842 | /* Notify */ | 875 | /* Notify */ |
1843 | env.sf.s_del (solver, aa, GNUNET_NO); | 876 | GAS_plugin_delete_address (aa); |
1844 | /* Destroy */ | 877 | /* Destroy */ |
1845 | GAS_performance_notify_all_clients (&aa->peer, | 878 | GAS_performance_notify_all_clients (&aa->peer, |
1846 | aa->plugin, | 879 | aa->plugin, |
@@ -1861,17 +894,14 @@ destroy_all_address_it (void *cls, | |||
1861 | void | 894 | void |
1862 | GAS_addresses_destroy_all () | 895 | GAS_addresses_destroy_all () |
1863 | { | 896 | { |
1864 | if (GNUNET_NO == running) | ||
1865 | return; | ||
1866 | |||
1867 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 897 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1868 | "Destroying all addresses\n"); | 898 | "Destroying all addresses\n"); |
1869 | env.sf.s_bulk_start (solver); | 899 | GAS_plugin_solver_lock (); |
1870 | if (NULL != addresses) | 900 | if (NULL != GSA_addresses) |
1871 | GNUNET_CONTAINER_multipeermap_iterate (addresses, | 901 | GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, |
1872 | &destroy_all_address_it, | 902 | &destroy_all_address_it, |
1873 | NULL); | 903 | NULL); |
1874 | env.sf.s_bulk_start (solver); | 904 | GAS_plugin_solver_unlock (); |
1875 | } | 905 | } |
1876 | 906 | ||
1877 | 907 | ||
@@ -1881,41 +911,11 @@ GAS_addresses_destroy_all () | |||
1881 | void | 911 | void |
1882 | GAS_addresses_done () | 912 | GAS_addresses_done () |
1883 | { | 913 | { |
1884 | struct GAS_Addresses_Suggestion_Requests *cur; | ||
1885 | struct GAS_Addresses_Preference_Clients *pcur; | ||
1886 | |||
1887 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 914 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, |
1888 | "Shutting down addresses\n"); | 915 | "Shutting down addresses\n"); |
1889 | GAS_addresses_destroy_all (); | 916 | GAS_addresses_destroy_all (); |
1890 | running = GNUNET_NO; | 917 | GNUNET_CONTAINER_multipeermap_destroy (GSA_addresses); |
1891 | GNUNET_CONTAINER_multipeermap_destroy (addresses); | 918 | GSA_addresses = NULL; |
1892 | addresses = NULL; | ||
1893 | while (NULL != (cur = pending_requests_head)) | ||
1894 | { | ||
1895 | GNUNET_CONTAINER_DLL_remove (pending_requests_head, | ||
1896 | pending_requests_tail, | ||
1897 | cur); | ||
1898 | GNUNET_free(cur); | ||
1899 | } | ||
1900 | |||
1901 | while (NULL != (pcur = preference_clients_head)) | ||
1902 | { | ||
1903 | GNUNET_CONTAINER_DLL_remove (preference_clients_head, | ||
1904 | preference_clients_tail, | ||
1905 | pcur); | ||
1906 | GNUNET_assert (pref_clients > 0); | ||
1907 | pref_clients --; | ||
1908 | GNUNET_STATISTICS_set (stats, | ||
1909 | "# active performance clients", | ||
1910 | pref_clients, | ||
1911 | GNUNET_NO); | ||
1912 | GNUNET_free (pcur); | ||
1913 | } | ||
1914 | GNUNET_PLUGIN_unload (plugin, | ||
1915 | solver); | ||
1916 | GNUNET_free (plugin); | ||
1917 | /* Stop configured solution method */ | ||
1918 | GAS_normalization_stop (); | ||
1919 | } | 919 | } |
1920 | 920 | ||
1921 | 921 | ||
@@ -1990,15 +990,15 @@ GAS_addresses_get_peer_info (const struct GNUNET_PeerIdentity *peer, | |||
1990 | (NULL == peer) | 990 | (NULL == peer) |
1991 | ? "all peers" | 991 | ? "all peers" |
1992 | : GNUNET_i2s (peer), | 992 | : GNUNET_i2s (peer), |
1993 | (unsigned int) GNUNET_CONTAINER_multipeermap_size (addresses)); | 993 | (unsigned int) GNUNET_CONTAINER_multipeermap_size (GSA_addresses)); |
1994 | pi_ctx.it = pi_it; | 994 | pi_ctx.it = pi_it; |
1995 | pi_ctx.it_cls = pi_it_cls; | 995 | pi_ctx.it_cls = pi_it_cls; |
1996 | if (NULL == peer) | 996 | if (NULL == peer) |
1997 | GNUNET_CONTAINER_multipeermap_iterate (addresses, | 997 | GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, |
1998 | &peerinfo_it, | 998 | &peerinfo_it, |
1999 | &pi_ctx); | 999 | &pi_ctx); |
2000 | else | 1000 | else |
2001 | GNUNET_CONTAINER_multipeermap_get_multiple (addresses, | 1001 | GNUNET_CONTAINER_multipeermap_get_multiple (GSA_addresses, |
2002 | peer, | 1002 | peer, |
2003 | &peerinfo_it, &pi_ctx); | 1003 | &peerinfo_it, &pi_ctx); |
2004 | pi_it (pi_it_cls, | 1004 | pi_it (pi_it_cls, |