aboutsummaryrefslogtreecommitdiff
path: root/src/ats/gnunet-service-ats_addresses.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ats/gnunet-service-ats_addresses.c')
-rw-r--r--src/ats/gnunet-service-ats_addresses.c1166
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 */
222struct 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 */
243struct 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 */
265static struct GNUNET_STATISTICS_Handle *stats;
266
267/**
268 * A multihashmap to store all addresses 222 * A multihashmap to store all addresses
269 */ 223 */
270static struct GNUNET_CONTAINER_MultiPeerMap *addresses; 224struct GNUNET_CONTAINER_MultiPeerMap *GSA_addresses;
271 225
272/**
273 * Is ATS addresses running
274 */
275static int running;
276
277/**
278 * Preferences clients
279 */
280static int pref_clients;
281
282/**
283 * Configured ATS solver
284 */
285static int ats_mode;
286
287/**
288 * Solver handle
289 */
290static 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 */
297static struct GAS_Addresses_Suggestion_Requests *pending_requests_head;
298
299/**
300 * Address suggestion requests DLL tail
301 */
302static struct GAS_Addresses_Suggestion_Requests *pending_requests_tail;
303
304/**
305 * Preference requests DLL head
306 */
307static struct GAS_Addresses_Preference_Clients *preference_clients_head;
308
309/**
310 * Preference requests DLL head
311 */
312static struct GAS_Addresses_Preference_Clients *preference_clients_tail;
313
314/**
315 * Solver functions
316 */
317static struct GNUNET_ATS_PluginEnvironment env;
318
319/**
320 * Solver plugin name as string
321 */
322static 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 */
699const double *
700get_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 */
715const double *
716get_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 */
1083void
1084GAS_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 */
1123void
1124GAS_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 */
1190static void
1191solver_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 */
1288static void
1289normalized_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 */
1307static void
1308normalized_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
1326static struct GAS_Addresses_Preference_Clients *
1327find_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 */
1343void
1344GAS_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 */
1373void
1374GAS_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 */
1428void
1429GAS_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 */
1468static unsigned int
1469load_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 &quota_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 &quota_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 */
1604static void
1605bandwidth_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 */
1685int 843void
1686GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg, 844GAS_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,
1861void 894void
1862GAS_addresses_destroy_all () 895GAS_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 ()
1881void 911void
1882GAS_addresses_done () 912GAS_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,