diff options
22 files changed, 2348 insertions, 2586 deletions
diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am index 282af25c0c..123c868ed9 100644 --- a/src/ats/Makefile.am +++ b/src/ats/Makefile.am @@ -43,6 +43,12 @@ plugin_LTLIBRARIES = \ gnunet_ats_solver_eval_SOURCES = \ gnunet-ats-solver-eval.c gnunet-ats-solver-eval.h \ + gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \ + gnunet-service-ats_plugins.c gnunet-service-ats_plugins.h \ + gnunet-service-ats_performance.c gnunet-service-ats_performance.h \ + gnunet-service-ats_preferences.c gnunet-service-ats_preferences.h \ + gnunet-service-ats_reservations.c gnunet-service-ats_reservations.h \ + gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \ gnunet-service-ats_normalization.c gnunet_ats_solver_eval_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -101,9 +107,11 @@ libexec_PROGRAMS = \ gnunet_service_ats_SOURCES = \ gnunet-service-ats.c gnunet-service-ats.h\ gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \ + gnunet-service-ats_plugins.c gnunet-service-ats_plugins.h \ gnunet-service-ats_connectivity.c gnunet-service-ats_connectivity.h \ gnunet-service-ats_normalization.c gnunet-service-ats_normalization.h \ gnunet-service-ats_performance.c gnunet-service-ats_performance.h \ + gnunet-service-ats_preferences.c gnunet-service-ats_preferences.h \ gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \ gnunet-service-ats_reservations.c gnunet-service-ats_reservations.h gnunet_service_ats_LDADD = \ @@ -516,7 +524,16 @@ test_ats_solver_alternative_after_delete_address_ril_LDADD = \ # libgnunetats.la perf_ats_solver_mlp_SOURCES = \ - perf_ats_solver.c test_ats_api_common.c gnunet-service-ats_normalization.c + perf_ats_solver.c \ + test_ats_api_common.c \ + gnunet-service-ats_normalization.c \ + gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \ + gnunet-service-ats_performance.c gnunet-service-ats_performance.h \ + gnunet-service-ats_preferences.c gnunet-service-ats_preferences.h \ + gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \ + gnunet-service-ats_plugins.c gnunet-service-ats_plugins.h \ + gnunet-service-ats_reservations.c gnunet-service-ats_reservations.h + perf_ats_solver_mlp_LDADD = \ $(GN_LIBGLPK) \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -524,7 +541,16 @@ perf_ats_solver_mlp_LDADD = \ libgnunetats.la perf_ats_solver_proportional_SOURCES = \ - perf_ats_solver.c test_ats_api_common.c gnunet-service-ats_normalization.c + perf_ats_solver.c \ + test_ats_api_common.c \ + gnunet-service-ats_normalization.c \ + gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \ + gnunet-service-ats_preferences.c gnunet-service-ats_preferences.h \ + gnunet-service-ats_performance.c gnunet-service-ats_performance.h \ + gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \ + gnunet-service-ats_plugins.c gnunet-service-ats_plugins.h \ + gnunet-service-ats_reservations.c gnunet-service-ats_reservations.h + perf_ats_solver_proportional_LDADD = \ $(GN_LIBGLPK) \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -532,7 +558,16 @@ perf_ats_solver_proportional_LDADD = \ libgnunetats.la perf_ats_solver_ril_SOURCES = \ - perf_ats_solver.c test_ats_api_common.c gnunet-service-ats_normalization.c + perf_ats_solver.c \ + test_ats_api_common.c \ + gnunet-service-ats_normalization.c \ + gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \ + gnunet-service-ats_preferences.c gnunet-service-ats_preferences.h \ + gnunet-service-ats_performance.c gnunet-service-ats_performance.h \ + gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \ + gnunet-service-ats_plugins.c gnunet-service-ats_plugins.h \ + gnunet-service-ats_reservations.c gnunet-service-ats_reservations.h + perf_ats_solver_ril_LDADD = \ $(GN_LIBGLPK) \ $(top_builddir)/src/util/libgnunetutil.la \ diff --git a/src/ats/gnunet-ats-solver-eval.c b/src/ats/gnunet-ats-solver-eval.c index 58fe03e25e..6bf640f21b 100644 --- a/src/ats/gnunet-ats-solver-eval.c +++ b/src/ats/gnunet-ats-solver-eval.c @@ -26,9 +26,17 @@ #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet-ats-solver-eval.h" +#include "gnunet-service-ats_normalization.h" +#include "gnunet-service-ats_preferences.h" #define BIG_M_STRING "unlimited" +/** + * Handle for statistics. + */ +struct GNUNET_STATISTICS_Handle *GSA_stats; + + static struct Experiment *e; static struct LoggingHandle *l; @@ -36,6 +44,7 @@ static struct LoggingHandle *l; static struct SolverHandle *sh; static struct TestPeer *peer_head; + static struct TestPeer *peer_tail; static double default_properties[GNUNET_ATS_PropertyCount]; @@ -670,8 +679,7 @@ set_prop_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) pg->ats_property, prop_value, prop_value); } else - GAS_normalization_normalize_property (sh->addresses, - pg->test_address->ats_addr, &atsi, 1); + GAS_normalization_normalize_property (pg->test_address->ats_addr, &atsi, 1); sh->env.sf.s_bulk_stop (sh->solver); pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency, @@ -3040,7 +3048,8 @@ get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id) return p->pref_abs; } else - return GAS_normalization_get_preferences_by_peer (id); + return GAS_normalization_get_preferences_by_peer (NULL, + id); } @@ -3058,96 +3067,8 @@ get_property_cb (void *cls, const struct ATS_Address *address) a = find_address_by_ats_address (p, address); return a->prop_abs; } - return GAS_normalization_get_properties ((struct ATS_Address *) address); -} - - -static void -set_updated_property ( struct ATS_Address *address, uint32_t type, double prop_rel) -{ - struct TestPeer *p; - struct TestAddress *a; - - if (NULL == (p = find_peer_by_pid (&address->peer))) - { - GNUNET_break (0); - return; - } - - if (NULL == (a = find_address_by_ats_address (p, address))) - { - GNUNET_break (0); - return; - } - a->prop_norm[type] = prop_rel; - sh->env.sf.s_address_update_property (sh->solver, address, type, a->prop_abs [type], prop_rel); -} - - -static void -normalized_property_changed_cb (void *cls, struct ATS_Address *address, - uint32_t type, double prop_rel) -{ - struct TestPeer *p; - struct PreferenceGenerator *pg; - struct GNUNET_TIME_Relative duration; - uint32_t delta; - - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Normalized property %s for peer `%s' changed to %.3f \n", - GNUNET_ATS_print_property_type (type), GNUNET_i2s (&address->peer), - prop_rel); - - if (NULL != (p = find_peer_by_pid (&address->peer))) - { - for (pg = pref_gen_head; NULL != pg; pg = pg->next) - { - if (pg->peer == p->id) - { - duration = GNUNET_TIME_absolute_get_duration(pg->feedback_last_delay_update); - delta = duration.rel_value_us * pg->last_delay_value; - pg->feedback_delay_acc += delta; - - pg->last_delay_value = prop_rel; - pg->feedback_last_bw_update = GNUNET_TIME_absolute_get(); - } - } - - } - - set_updated_property (address, type, prop_rel); -} - -static void -set_updated_preference (const struct GNUNET_PeerIdentity *peer, - enum GNUNET_ATS_PreferenceKind kind, - double pref_rel) -{ - struct TestPeer *p; - - if (NULL == (p = find_peer_by_pid (peer))) - { - GNUNET_break (0); - return; - } - - p->pref_norm[kind] = pref_rel; - sh->env.sf.s_pref (sh->solver, peer, kind, pref_rel); -} - - -static void -normalized_preference_changed_cb (void *cls, - const struct GNUNET_PeerIdentity *peer, - enum GNUNET_ATS_PreferenceKind kind, - double pref_rel) -{ - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Normalized preference %s for peer `%s' changed to %.3f \n", - GNUNET_ATS_print_preference_type (kind), GNUNET_i2s (peer), - pref_rel); - - set_updated_preference(peer, kind, pref_rel); + return GAS_normalization_get_properties (NULL, + address); } @@ -3196,8 +3117,7 @@ GNUNET_ATS_solvers_solver_start (enum GNUNET_ATS_Solvers type) /* start normalization */ - GAS_normalization_start (&normalized_preference_changed_cb, NULL, - &normalized_property_changed_cb, NULL ); + GAS_normalization_start (); /* load quotas */ if (GNUNET_ATS_NetworkTypeCount != GNUNET_ATS_solvers_load_quotas (e->cfg, diff --git a/src/ats/gnunet-service-ats.c b/src/ats/gnunet-service-ats.c index 944db77f64..d54d09a332 100644 --- a/src/ats/gnunet-service-ats.c +++ b/src/ats/gnunet-service-ats.c @@ -17,7 +17,6 @@ Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /** * @file ats/gnunet-service-ats.c * @brief ats service @@ -29,9 +28,12 @@ #include "gnunet-service-ats.h" #include "gnunet-service-ats_addresses.h" #include "gnunet-service-ats_connectivity.h" +#include "gnunet-service-ats_normalization.h" #include "gnunet-service-ats_performance.h" +#include "gnunet-service-ats_preferences.h" #include "gnunet-service-ats_scheduling.h" #include "gnunet-service-ats_reservations.h" +#include "gnunet-service-ats_plugins.h" #include "ats.h" /** @@ -108,6 +110,9 @@ client_disconnect_handler (void *cls, return; GAS_scheduling_remove_client (client); GAS_performance_remove_client (client); + GAS_connectivity_remove_client (client); + GAS_normalization_preference_client_disconnect (client); + GAS_addresses_preference_client_disconnect (client); } @@ -121,9 +126,13 @@ static void cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { + GAS_plugins_done (); GAS_addresses_done (); + GAS_normalization_stop (); GAS_scheduling_done (); + GAS_connectivity_done (); GAS_performance_done (); + GAS_preference_done (); GAS_reservations_done (); GNUNET_SERVER_disconnect_notify_cancel (GSA_server, &client_disconnect_handler, @@ -180,10 +189,14 @@ run (void *cls, GSA_server = server; GSA_stats = GNUNET_STATISTICS_create ("ats", cfg); GAS_reservations_init (); + GAS_normalization_start (); + GAS_addresses_init (); if (GNUNET_OK != - GAS_addresses_init (cfg, GSA_stats)) + GAS_plugins_init (cfg)) { GNUNET_break (0); + GAS_addresses_done (); + GAS_normalization_stop (); GAS_reservations_done (); if (NULL != GSA_stats) { @@ -196,10 +209,12 @@ run (void *cls, GAS_scheduling_init (server); GNUNET_SERVER_disconnect_notify (server, - &client_disconnect_handler, NULL); + &client_disconnect_handler, + NULL); GNUNET_SERVER_add_handlers (server, handlers); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, - &cleanup_task, NULL); + &cleanup_task, + NULL); } diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c index 1d2c9d3e5f..9ef6a38387 100644 --- a/src/ats/gnunet-service-ats_addresses.c +++ b/src/ats/gnunet-service-ats_addresses.c @@ -26,11 +26,11 @@ */ #include "platform.h" #include "gnunet_ats_service.h" -#include "gnunet_ats_plugin.h" #include "gnunet-service-ats.h" #include "gnunet-service-ats_addresses.h" #include "gnunet-service-ats_normalization.h" #include "gnunet-service-ats_performance.h" +#include "gnunet-service-ats_plugins.h" #include "gnunet-service-ats_scheduling.h" #include "gnunet-service-ats_reservations.h" @@ -216,110 +216,13 @@ */ -/** - * Pending Address suggestion requests - */ -struct GAS_Addresses_Suggestion_Requests -{ - /** - * Next in DLL - */ - struct GAS_Addresses_Suggestion_Requests *next; - - /** - * Previous in DLL - */ - struct GAS_Addresses_Suggestion_Requests *prev; - - /** - * Peer ID - */ - struct GNUNET_PeerIdentity id; -}; - -/** - * Pending Address suggestion requests - */ -struct GAS_Addresses_Preference_Clients -{ - /** - * Next in DLL - */ - struct GAS_Addresses_Preference_Clients *next; - - /** - * Previous in DLL - */ - struct GAS_Addresses_Preference_Clients *prev; - - /** - * Peer ID - */ - void *client; -}; /** - * - */ -static struct GNUNET_STATISTICS_Handle *stats; - -/** * A multihashmap to store all addresses */ -static struct GNUNET_CONTAINER_MultiPeerMap *addresses; +struct GNUNET_CONTAINER_MultiPeerMap *GSA_addresses; -/** - * Is ATS addresses running - */ -static int running; - -/** - * Preferences clients - */ -static int pref_clients; - -/** - * Configured ATS solver - */ -static int ats_mode; - -/** - * Solver handle - */ -static void *solver; - -/** - * Address suggestion requests DLL head. - * FIXME: This must become a Multipeermap! O(n) operations - * galore instead of O(1)!!! - */ -static struct GAS_Addresses_Suggestion_Requests *pending_requests_head; - -/** - * Address suggestion requests DLL tail - */ -static struct GAS_Addresses_Suggestion_Requests *pending_requests_tail; - -/** - * Preference requests DLL head - */ -static struct GAS_Addresses_Preference_Clients *preference_clients_head; - -/** - * Preference requests DLL head - */ -static struct GAS_Addresses_Preference_Clients *preference_clients_tail; - -/** - * Solver functions - */ -static struct GNUNET_ATS_PluginEnvironment env; - -/** - * Solver plugin name as string - */ -static char *plugin; /** * Value we pass for zero bandwidth. @@ -613,7 +516,7 @@ find_equivalent_address (const struct GNUNET_PeerIdentity *peer, cac.exact_address = NULL; cac.base_address = NULL; cac.search = addr; - GNUNET_CONTAINER_multipeermap_get_multiple (addresses, + GNUNET_CONTAINER_multipeermap_get_multiple (GSA_addresses, peer, &compare_address_it, &cac); @@ -681,7 +584,7 @@ find_exact_address (const struct GNUNET_PeerIdentity *peer, fac.exact_address = NULL; fac.session_id = session_id; - GNUNET_CONTAINER_multipeermap_get_multiple (addresses, + GNUNET_CONTAINER_multipeermap_get_multiple (GSA_addresses, peer, &find_address_cb, &fac); return fac.exact_address; @@ -689,38 +592,6 @@ find_exact_address (const struct GNUNET_PeerIdentity *peer, /** - * Function allowing the solver to obtain normalized preference - * values from solver - * - * @param cls unused - * @param id the peer to return the normalized properties for - * @return array of double values with |GNUNET_ATS_PreferenceCount| elements - */ -const double * -get_preferences_cb (void *cls, - const struct GNUNET_PeerIdentity *id) -{ - return GAS_normalization_get_preferences_by_peer (id); -} - - -/** - * Function allowing the solver to obtain normalized property - * values for an address from solver - * - * @param cls unused - * @param address the address - * @return array of double values with |GNUNET_ATS_QualityPropertiesCount| elements - */ -const double * -get_property_cb (void *cls, - const struct ATS_Address *address) -{ - return GAS_normalization_get_properties (address); -} - - -/** * Extract an ATS performance info from an address * * @param address the address @@ -772,18 +643,11 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer, struct GNUNET_ATS_Information *atsi_delta; uint32_t atsi_delta_count; uint32_t addr_net; - uint32_t previous_session; - int c1; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' for peer `%s'\n", "ADDRESS ADD", GNUNET_i2s (peer)); - if (GNUNET_NO == running) - { - GNUNET_break (0); - return; - } new_address = create_address (peer, plugin_name, plugin_addr, @@ -802,127 +666,51 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer, /* Get existing address or address with session == 0 */ existing_address = find_equivalent_address (peer, new_address); - if (NULL == existing_address) + if (NULL != existing_address) { - /* Add a new address */ - new_address->t_added = GNUNET_TIME_absolute_get(); - new_address->t_last_activity = GNUNET_TIME_absolute_get(); - GNUNET_assert(GNUNET_OK == - GNUNET_CONTAINER_multipeermap_put (addresses, - peer, - new_address, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); - - GNUNET_STATISTICS_set (stats, - "# addresses", - GNUNET_CONTAINER_multipeermap_size (addresses), - GNUNET_NO); - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Adding new address %p for peer `%s', length %u, session id %u, %s\n", - new_address, - GNUNET_i2s (peer), - plugin_addr_len, - session_id, - GNUNET_ATS_print_network_type (addr_net)); - - /* Tell solver about new address */ - env.sf.s_add (solver, new_address, addr_net); - - env.sf.s_bulk_start (solver); - GAS_normalization_normalize_property (addresses, - new_address, - atsi, - atsi_count); - env.sf.s_bulk_stop (solver); - - /* Notify performance clients about new address */ - GAS_performance_notify_all_clients (&new_address->peer, new_address->plugin, - new_address->addr, new_address->addr_len, new_address->active, - new_address->atsi, new_address->atsi_count, - GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_out), - GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_in)); - return; - } - - /* FIXME: this case should probably not be allowed... */ - /* We have an existing address we can use, clean up new */ - GNUNET_free(new_address->plugin); - GNUNET_free_non_null(new_address->atsi); - GNUNET_free(new_address); - new_address = NULL; - - if (0 != existing_address->session_id) - { - /* Should not happen */ - GNUNET_break(0); + GNUNET_break (0); + GNUNET_free(new_address->plugin); + GNUNET_free_non_null(new_address->atsi); + GNUNET_free(new_address); return; } - - addr_net = get_performance_info (existing_address, GNUNET_ATS_NETWORK_TYPE); - if (GNUNET_ATS_VALUE_UNDEFINED == addr_net) - addr_net = GNUNET_ATS_NET_UNSPECIFIED; - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Found existing address for peer `%s' %p with new session %u in network %s\n", - GNUNET_i2s (peer), existing_address, session_id, - GNUNET_ATS_print_network_type (addr_net)); - /* We have an address without an session, update this address */ - existing_address->t_added = GNUNET_TIME_absolute_get(); - existing_address->t_last_activity = GNUNET_TIME_absolute_get(); - atsi_delta = NULL; - atsi_delta_count = 0; - if (GNUNET_YES - == disassemble_ats_information (existing_address, atsi, atsi_count, - &atsi_delta, &atsi_delta_count)) - { - /* Notify performance clients about properties */ - GAS_performance_notify_all_clients (&existing_address->peer, - existing_address->plugin, existing_address->addr, - existing_address->addr_len, existing_address->active, - existing_address->atsi, existing_address->atsi_count, - GNUNET_BANDWIDTH_value_init (existing_address->assigned_bw_out), - GNUNET_BANDWIDTH_value_init (existing_address->assigned_bw_in)); - - for (c1 = 0; c1 < atsi_delta_count; c1++) - { - if ((GNUNET_ATS_NETWORK_TYPE == ntohl (atsi_delta[c1].type)) - && (addr_net != ntohl (atsi_delta[c1].value))) - { - /* Network type changed */ - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Address for peer `%s' %p changed from network %s to %s\n", - GNUNET_i2s (peer), existing_address, - GNUNET_ATS_print_network_type (addr_net), - GNUNET_ATS_print_network_type (ntohl (atsi_delta[c1].value))); - env.sf.s_address_update_network (solver, existing_address, - ntohl (atsi_delta[c1].value), - get_performance_info (existing_address, GNUNET_ATS_NETWORK_TYPE)); - addr_net = get_performance_info (existing_address, - GNUNET_ATS_NETWORK_TYPE); - } - } - /* Notify solver about update with atsi information and session */ - env.sf.s_bulk_start (solver); - GAS_normalization_normalize_property (addresses, existing_address, - atsi, atsi_count); - env.sf.s_bulk_stop (solver); - } - GNUNET_free_non_null(atsi_delta); - - /* Notify solver about new session */ - if (existing_address->session_id == session_id) - return; /* possible, can both be 0 since address is revalidated */ - - previous_session = existing_address->session_id; - existing_address->session_id = session_id; - env.sf.s_address_update_session (solver, existing_address, - previous_session, session_id); - - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Updated existing address for peer `%s' %p length %u with new session %u in network %s\n", - GNUNET_i2s (peer), existing_address, existing_address->addr_len, - session_id, GNUNET_ATS_print_network_type (addr_net)); + /* Add a new address */ + new_address->t_added = GNUNET_TIME_absolute_get(); + new_address->t_last_activity = GNUNET_TIME_absolute_get(); + GNUNET_assert(GNUNET_OK == + GNUNET_CONTAINER_multipeermap_put (GSA_addresses, + peer, + new_address, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); + + GNUNET_STATISTICS_set (GSA_stats, + "# addresses", + GNUNET_CONTAINER_multipeermap_size (GSA_addresses), + GNUNET_NO); + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Adding new address %p for peer `%s', length %u, session id %u, %s\n", + new_address, + GNUNET_i2s (peer), + plugin_addr_len, + session_id, + GNUNET_ATS_print_network_type (addr_net)); + + /* Tell solver about new address */ + GAS_plugin_new_address (new_address, + addr_net, + atsi, + atsi_count); + /* Notify performance clients about new address */ + GAS_performance_notify_all_clients (&new_address->peer, + new_address->plugin, + new_address->addr, + new_address->addr_len, + new_address->active, + new_address->atsi, + new_address->atsi_count, + GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_out), + GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_in)); } @@ -943,12 +731,6 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, struct ATS_Address *aa; struct GNUNET_ATS_Information *atsi_delta; uint32_t atsi_delta_count; - uint32_t prev_session; - int c1; - - if (GNUNET_NO == running) - return; - GNUNET_assert (NULL != addresses); /* Get existing address */ aa = find_exact_address (peer, @@ -963,7 +745,6 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, GNUNET_break (0); return; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' for peer `%s' address \n", "ADDRESS UPDATE", @@ -972,17 +753,6 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, /* Update address */ aa->t_last_activity = GNUNET_TIME_absolute_get(); - if (session_id != aa->session_id) - { - /* Session changed */ - prev_session = aa->session_id; - aa->session_id = session_id; - env.sf.s_address_update_session (solver, - aa, - prev_session, - aa->session_id); - } - atsi_delta = NULL; atsi_delta_count = 0; if (GNUNET_YES == @@ -991,30 +761,20 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, &atsi_delta, &atsi_delta_count)) { - /* ATS properties changed */ - for (c1 = 0; c1 < atsi_delta_count; c1++) - { - if (GNUNET_ATS_NETWORK_TYPE == ntohl (atsi_delta[c1].type)) - { - /* Network type changed */ - env.sf.s_address_update_network (solver, aa, - ntohl (atsi_delta[c1].value), - get_performance_info (aa, GNUNET_ATS_NETWORK_TYPE)); - } - } - /* Notify performance clients about updated address */ - GAS_performance_notify_all_clients (&aa->peer, aa->plugin, aa->addr, - aa->addr_len, aa->active, aa->atsi, aa->atsi_count, - GNUNET_BANDWIDTH_value_init (aa->assigned_bw_out), - GNUNET_BANDWIDTH_value_init (aa->assigned_bw_in)); - - env.sf.s_bulk_start (solver); - GAS_normalization_normalize_property (addresses, - aa, - atsi, - atsi_count); - env.sf.s_bulk_stop (solver); + GAS_performance_notify_all_clients (&aa->peer, + aa->plugin, + aa->addr, + aa->addr_len, + aa->active, + aa->atsi, + aa->atsi_count, + GNUNET_BANDWIDTH_value_init (aa->assigned_bw_out), + GNUNET_BANDWIDTH_value_init (aa->assigned_bw_in)); + + GAS_plugin_update_address (aa, + atsi, + atsi_count); } GNUNET_free_non_null (atsi_delta); } @@ -1032,9 +792,6 @@ GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer, { struct ATS_Address *ea; - if (GNUNET_NO == running) - return; - /* Get existing address */ ea = find_exact_address (peer, session_id); @@ -1054,11 +811,10 @@ GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer, GNUNET_i2s (peer), ea, session_id); - GNUNET_CONTAINER_multipeermap_remove (addresses, + GNUNET_CONTAINER_multipeermap_remove (GSA_addresses, peer, ea); - - env.sf.s_del (solver, ea, GNUNET_NO); + GAS_plugin_delete_address (ea); GAS_performance_notify_all_clients (peer, ea->plugin, ea->addr, @@ -1068,607 +824,14 @@ GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer, zero_bw, zero_bw); free_address (ea); - GNUNET_STATISTICS_set (stats, + GNUNET_STATISTICS_set (GSA_stats, "# addresses", - GNUNET_CONTAINER_multipeermap_size (addresses), + GNUNET_CONTAINER_multipeermap_size (GSA_addresses), GNUNET_NO); } -/** - * Cancel address suggestions for a peer - * - * @param peer the peer id - */ -void -GAS_addresses_request_address_cancel (const struct GNUNET_PeerIdentity *peer) -{ - struct GAS_Addresses_Suggestion_Requests *cur = pending_requests_head; - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Received request: `%s' for peer %s\n", - "request_address_cancel", - GNUNET_i2s (peer)); - - while (NULL != cur) - { - if (0 == memcmp (peer, &cur->id, sizeof(cur->id))) - break; /* found */ - cur = cur->next; - } - - if (NULL == cur) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "No address requests pending for peer `%s', cannot remove!\n", - GNUNET_i2s (peer)); - return; - } - env.sf.s_get_stop (solver, peer); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Removed request pending for peer `%s\n", - GNUNET_i2s (peer)); - GNUNET_CONTAINER_DLL_remove (pending_requests_head, - pending_requests_tail, - cur); - GNUNET_free(cur); -} - - -/** - * Request address suggestions for a peer - * - * @param peer the peer id - */ -void -GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer) -{ - struct GAS_Addresses_Suggestion_Requests *cur = pending_requests_head; - struct ATS_Address *aa; - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Received `%s' for peer `%s'\n", - "REQUEST ADDRESS", - GNUNET_i2s (peer)); - - if (GNUNET_NO == running) - return; - while (NULL != cur) - { - if (0 == memcmp (peer, &cur->id, sizeof(cur->id))) - break; /* already suggesting */ - cur = cur->next; - } - if (NULL == cur) - { - cur = GNUNET_new (struct GAS_Addresses_Suggestion_Requests); - cur->id = *peer; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Adding new address suggestion request for `%s'\n", - GNUNET_i2s (peer)); - GNUNET_CONTAINER_DLL_insert (pending_requests_head, - pending_requests_tail, - cur); - } - - /* Get prefered address from solver */ - aa = (struct ATS_Address *) env.sf.s_get (solver, peer); - if (NULL == aa) - { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Cannot suggest address for peer `%s'\n", - GNUNET_i2s (peer)); - return; - } - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Suggesting address %p for peer `%s'\n", - aa, GNUNET_i2s (peer)); - - GAS_scheduling_transmit_address_suggestion (peer, - aa->session_id, - GNUNET_BANDWIDTH_value_init (aa->assigned_bw_out), - GNUNET_BANDWIDTH_value_init (aa->assigned_bw_in)); - - aa->block_interval = GNUNET_TIME_relative_add (aa->block_interval, - ATS_BLOCKING_DELTA); - aa->blocked_until = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), - aa->block_interval); - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Address %p ready for suggestion, block interval now %llu \n", aa, - aa->block_interval); -} - - -/** - * Solver information callback - * - * @param cls the closure - * @param op the operation - * @param status operation status - * @param add additional information - */ -static void -solver_info_cb (void *cls, - enum GAS_Solver_Operation op, - enum GAS_Solver_Status status, - enum GAS_Solver_Additional_Information add) -{ - char *add_info; - - switch (add) { - case GAS_INFO_NONE: - add_info = "GAS_INFO_NONE"; - break; - case GAS_INFO_FULL: - add_info = "GAS_INFO_MLP_FULL"; - break; - case GAS_INFO_UPDATED: - add_info = "GAS_INFO_MLP_UPDATED"; - break; - case GAS_INFO_PROP_ALL: - add_info = "GAS_INFO_PROP_ALL"; - break; - case GAS_INFO_PROP_SINGLE: - add_info = "GAS_INFO_PROP_SINGLE"; - break; - default: - add_info = "INVALID"; - break; - } - switch (op) - { - case GAS_OP_SOLVE_START: - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Solver notifies `%s' with result `%s' `%s'\n", "GAS_OP_SOLVE_START", - (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL", add_info); - return; - case GAS_OP_SOLVE_STOP: - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_STOP", - (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL", add_info); - return; - - case GAS_OP_SOLVE_SETUP_START: - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_START", - (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); - return; - - case GAS_OP_SOLVE_SETUP_STOP: - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_STOP", - (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); - return; - - case GAS_OP_SOLVE_MLP_LP_START: - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_START", - (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); - return; - case GAS_OP_SOLVE_MLP_LP_STOP: - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_STOP", - (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); - return; - - case GAS_OP_SOLVE_MLP_MLP_START: - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_START", - (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); - return; - case GAS_OP_SOLVE_MLP_MLP_STOP: - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_STOP", - (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); - return; - case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START: - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START", - (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); - return; - case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP: - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP", - (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); - return; - default: - break; - } -} - - -/** - * The preference changed for a peer - * - * @param cls NULL - * @param peer the peer - * @param kind the ATS kind - * @param pref_rel the new relative preference value - */ -static void -normalized_preference_changed_cb (void *cls, - const struct GNUNET_PeerIdentity *peer, - enum GNUNET_ATS_PreferenceKind kind, - double pref_rel) -{ - /* Tell solver about update */ - env.sf.s_pref (solver, peer, kind, pref_rel); -} - - -/** - * The relative value for a property changed - * - * @param cls NULL - * @param address the peer - * @param type the ATS type - * @param prop_rel the new relative preference value - */ -static void -normalized_property_changed_cb (void *cls, - struct ATS_Address *address, - uint32_t type, - double prop_rel) -{ - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Normalized property %s for peer `%s' changed to %.3f \n", - GNUNET_ATS_print_property_type (type), - GNUNET_i2s (&address->peer), - prop_rel); - env.sf.s_address_update_property (solver, - address, - type, - 0, - prop_rel); -} - - -static struct GAS_Addresses_Preference_Clients * -find_preference_client (void *client) -{ - struct GAS_Addresses_Preference_Clients *cur; - for (cur = preference_clients_head; NULL != cur; cur = cur->next) - if (cur->client == client) - return cur; - return NULL; -} - - -/** - * A performance client disconnected - * - * @param client the client - */ -void -GAS_addresses_preference_client_disconnect (void *client) -{ - struct GAS_Addresses_Preference_Clients *pc; - - if (NULL != (pc = find_preference_client (client))) - { - GNUNET_CONTAINER_DLL_remove (preference_clients_head, - preference_clients_tail, - pc); - GNUNET_free (pc); - GNUNET_assert (pref_clients > 0); - pref_clients --; - GNUNET_STATISTICS_set (stats, - "# active performance clients", - pref_clients, - GNUNET_NO); - } - GAS_normalization_preference_client_disconnect (client); -} - - -/** - * Change the preference for a peer - * - * @param client the client sending this request - * @param peer the peer id - * @param kind the preference kind to change - * @param score_abs the new preference score - */ -void -GAS_addresses_preference_change (void *client, - const struct GNUNET_PeerIdentity *peer, - enum GNUNET_ATS_PreferenceKind kind, - float score_abs) -{ - struct GAS_Addresses_Preference_Clients *pc; - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Received `%s' for peer `%s' for client %p\n", "CHANGE PREFERENCE", - GNUNET_i2s (peer), client); - - if (GNUNET_NO == running) - return; - - if (GNUNET_NO == - GNUNET_CONTAINER_multipeermap_contains (addresses, - peer)) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Received `%s' for unknown peer `%s' from client %p\n", - "CHANGE PREFERENCE", GNUNET_i2s (peer), client); - return; - } - - if (NULL == find_preference_client (client)) - { - pc = GNUNET_new (struct GAS_Addresses_Preference_Clients); - pc->client = client; - GNUNET_CONTAINER_DLL_insert (preference_clients_head, - preference_clients_tail, - pc); - pref_clients ++; - GNUNET_STATISTICS_set (stats, - "# active performance clients", - pref_clients, - GNUNET_NO); - } - - env.sf.s_bulk_start (solver); - /* Tell normalization about change, normalization will call callback if preference changed */ - GAS_normalization_normalize_preference (client, peer, kind, score_abs); - env.sf.s_bulk_stop (solver); -} - - -/** - * Change the preference for a peer - * - * @param application the client sending this request - * @param peer the peer id - * @param scope the time interval for this feedback: [now - scope .. now] - * @param kind the preference kind to change - * @param score_abs the new preference score - */ -void -GAS_addresses_preference_feedback (void *application, - const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_TIME_Relative scope, - enum GNUNET_ATS_PreferenceKind kind, - float score_abs) -{ - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Received `%s' for peer `%s' for client %p\n", - "PREFERENCE FEEDBACK", - GNUNET_i2s (peer), - application); - - if (GNUNET_NO == running) - return; - - if (GNUNET_NO == - GNUNET_CONTAINER_multipeermap_contains (addresses, - peer)) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Received `%s' for unknown peer `%s' from client %p\n", - "PREFERENCE FEEDBACK", GNUNET_i2s (peer), application); - return; - } - - env.sf.s_feedback (solver, application, peer, scope, kind, - score_abs); -} - - -/** - * Load quotas for networks from configuration - * - * @param cfg configuration handle - * @param out_dest where to write outbound quotas - * @param in_dest where to write inbound quotas - * @param dest_length length of inbound and outbound arrays - * @return number of networks loaded - */ -static unsigned int -load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg, - unsigned long long *out_dest, unsigned long long *in_dest, int dest_length) -{ - char * entry_in = NULL; - char * entry_out = NULL; - char * quota_out_str; - char * quota_in_str; - int c; - int res; - - for (c = 0; (c < GNUNET_ATS_NetworkTypeCount) && (c < dest_length); c++) - { - in_dest[c] = 0; - out_dest[c] = 0; - GNUNET_asprintf (&entry_out, - "%s_QUOTA_OUT", - GNUNET_ATS_print_network_type (c)); - GNUNET_asprintf (&entry_in, - "%s_QUOTA_IN", - GNUNET_ATS_print_network_type (c)); - - /* quota out */ - if (GNUNET_OK - == GNUNET_CONFIGURATION_get_value_string (cfg, "ats", entry_out, - "a_out_str)) - { - res = GNUNET_NO; - if (0 == strcmp (quota_out_str, GNUNET_ATS_MaxBandwidthString)) - { - out_dest[c] = GNUNET_ATS_MaxBandwidth; - res = GNUNET_YES; - } - if ((GNUNET_NO == res) - && (GNUNET_OK - == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, - &out_dest[c]))) - res = GNUNET_YES; - if ((GNUNET_NO == res) - && (GNUNET_OK - == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_out, - &out_dest[c]))) - res = GNUNET_YES; - - if (GNUNET_NO == res) - { - GNUNET_log(GNUNET_ERROR_TYPE_ERROR, - _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"), - GNUNET_ATS_print_network_type (c), - quota_out_str, - GNUNET_ATS_DefaultBandwidth); - out_dest[c] = GNUNET_ATS_DefaultBandwidth; - } - else - { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - _("Outbound quota configure for network `%s' is %llu\n"), - GNUNET_ATS_print_network_type (c), - out_dest[c]); - } - GNUNET_free(quota_out_str); - } - else - { - GNUNET_log(GNUNET_ERROR_TYPE_ERROR, - _("No outbound quota configured for network `%s', assigning default bandwidth %llu\n"), - GNUNET_ATS_print_network_type (c), - GNUNET_ATS_DefaultBandwidth); - out_dest[c] = GNUNET_ATS_DefaultBandwidth; - } - - /* quota in */ - if (GNUNET_OK - == GNUNET_CONFIGURATION_get_value_string (cfg, "ats", entry_in, - "a_in_str)) - { - res = GNUNET_NO; - if (0 == strcmp (quota_in_str, GNUNET_ATS_MaxBandwidthString)) - { - in_dest[c] = GNUNET_ATS_MaxBandwidth; - res = GNUNET_YES; - } - if ((GNUNET_NO == res) - && (GNUNET_OK - == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &in_dest[c]))) - res = GNUNET_YES; - if ((GNUNET_NO == res) - && (GNUNET_OK - == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_in, - &in_dest[c]))) - res = GNUNET_YES; - - if (GNUNET_NO == res) - { - GNUNET_log(GNUNET_ERROR_TYPE_ERROR, - _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"), - GNUNET_ATS_print_network_type (c), - quota_in_str, - GNUNET_ATS_DefaultBandwidth); - in_dest[c] = GNUNET_ATS_DefaultBandwidth; - } - else - { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - _("Inbound quota configured for network `%s' is %llu\n"), - GNUNET_ATS_print_network_type (c), - in_dest[c]); - } - GNUNET_free(quota_in_str); - } - else - { - GNUNET_log(GNUNET_ERROR_TYPE_ERROR, - _("No outbound quota configure for network `%s', assigning default bandwidth %llu\n"), - GNUNET_ATS_print_network_type (c), - GNUNET_ATS_DefaultBandwidth); - in_dest[c] = GNUNET_ATS_DefaultBandwidth; - } - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Loaded quota for network `%s' (in/out): %llu %llu\n", - GNUNET_ATS_print_network_type (c), - in_dest[c], - out_dest[c]); - GNUNET_free(entry_out); - GNUNET_free(entry_in); - } - return GNUNET_ATS_NetworkTypeCount; -} - - -/** - * Callback for solver to notify about assignment changes - * - * @param cls NULL - * @param address the address with changes - */ -static void -bandwidth_changed_cb (void *cls, struct ATS_Address *address) -{ - struct GAS_Addresses_Suggestion_Requests *cur; - uint32_t diff_out; - uint32_t diff_in; - - GNUNET_assert(address != NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Bandwidth assignment changed for peer %s \n", - GNUNET_i2s (&address->peer)); - - /* Notify performance clients about changes to address */ - GAS_performance_notify_all_clients (&address->peer, address->plugin, - address->addr, address->addr_len, address->active, address->atsi, - address->atsi_count, - GNUNET_BANDWIDTH_value_init (address->assigned_bw_out), - GNUNET_BANDWIDTH_value_init (address->assigned_bw_in)); - - for (cur = pending_requests_head;NULL != cur; cur = cur->next) - if (0 == memcmp (&address->peer, - &cur->id, - sizeof(cur->id))) - break; /* we have an address request pending*/ - if (NULL == cur) - { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Nobody is interested in peer `%s' :(\n", - GNUNET_i2s (&address->peer)); - return; - } - - if ((0 == address->assigned_bw_in) && (0 == address->assigned_bw_out)) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Telling transport to disconnect peer `%s'\n", - GNUNET_i2s (&address->peer)); - - /* Notify scheduling clients about suggestion */ - GAS_scheduling_transmit_address_suggestion (&address->peer, - address->session_id, - zero_bw, - zero_bw); - return; - } - - /* Do bandwidth stability check */ - diff_out = abs (address->assigned_bw_out - address->last_notified_bw_out); - diff_in = abs (address->assigned_bw_in - address->last_notified_bw_in); - - if ( (diff_out < htonl(GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__)) && - (diff_in < htonl(GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__)) ) - return; - - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Sending bandwidth update for peer `%s': %u %u\n", - GNUNET_i2s (&address->peer), address->assigned_bw_out, - address->assigned_bw_out); - - /* *Notify scheduling clients about suggestion */ - GAS_scheduling_transmit_address_suggestion (&address->peer, - address->session_id, - GNUNET_BANDWIDTH_value_init (address->assigned_bw_out), - GNUNET_BANDWIDTH_value_init (address->assigned_bw_in)); - - address->last_notified_bw_out = address->assigned_bw_out; - address->last_notified_bw_in = address->assigned_bw_in; -} /** @@ -1676,146 +839,16 @@ bandwidth_changed_cb (void *cls, struct ATS_Address *address) * known and current performance information. It has a solver component * responsible for the resource allocation. It tells the solver about changes * and receives updates when the solver changes the resource allocation. - * - * @param cfg configuration to use - * @param stats_ the statistics handle to use - * @return #GNUNET_OK on success, #GNUNET_SYSERR on error (failed to load - * solver plugin) */ -int -GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_STATISTICS_Handle *stats_) +void +GAS_addresses_init () { - unsigned long long quotas_in[GNUNET_ATS_NetworkTypeCount]; - unsigned long long quotas_out[GNUNET_ATS_NetworkTypeCount]; - char *mode_str; - char *plugin_short; - int c; - - running = GNUNET_NO; - stats = stats_; /* Initialize the addresses database */ - addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO); - pref_clients = 0; - - /* Figure out configured solution method */ - if (GNUNET_SYSERR == - GNUNET_CONFIGURATION_get_value_string (cfg, "ats", "MODE", &mode_str)) - { - GNUNET_log(GNUNET_ERROR_TYPE_WARNING, - "No resource assignment method configured, using proportional approach\n"); - ats_mode = MODE_PROPORTIONAL; - } - else - { - for (c = 0; c < strlen (mode_str); c++) - mode_str[c] = toupper (mode_str[c]); - if (0 == strcmp (mode_str, "PROPORTIONAL")) - ats_mode = MODE_PROPORTIONAL; - else if (0 == strcmp (mode_str, "MLP")) - { - ats_mode = MODE_MLP; -#if !HAVE_LIBGLPK - GNUNET_log(GNUNET_ERROR_TYPE_ERROR, - "Assignment method `%s' configured, but GLPK is not available, please install \n", - mode_str); - ats_mode = MODE_PROPORTIONAL; -#endif - } - else if (0 == strcmp (mode_str, "RIL")) - ats_mode = MODE_RIL; - else - { - GNUNET_log(GNUNET_ERROR_TYPE_ERROR, - "Invalid resource assignment method `%s' configured, using proportional approach\n", - mode_str); - ats_mode = MODE_PROPORTIONAL; - } - GNUNET_free(mode_str); - } - - load_quotas (cfg, quotas_out, quotas_in, GNUNET_ATS_NetworkTypeCount); - env.info_cb = &solver_info_cb; - env.info_cb_cls = NULL; - env.bandwidth_changed_cb = &bandwidth_changed_cb; - env.bw_changed_cb_cls = NULL; - env.get_preferences = &get_preferences_cb; - env.get_preference_cls = NULL; - env.get_property = &get_property_cb; - env.get_property_cls = NULL; - env.cfg = cfg; - env.stats = stats; - env.addresses = addresses; - - env.network_count = GNUNET_ATS_NetworkTypeCount; - int networks[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType; - for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++) - { - env.networks[c] = networks[c]; - env.out_quota[c] = quotas_out[c]; - env.in_quota[c] = quotas_in[c]; - } - - switch (ats_mode) { - case MODE_PROPORTIONAL: - plugin_short = "proportional"; - break; - case MODE_MLP: - plugin_short = "mlp"; - break; - case MODE_RIL: - plugin_short = "ril"; - break; - default: - plugin_short = NULL; - break; - } - GNUNET_asprintf (&plugin, - "libgnunet_plugin_ats_%s", - plugin_short); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Initializing solver `%s '`%s'\n", - plugin_short, - plugin); - if (NULL == (solver = GNUNET_PLUGIN_load (plugin, &env))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to initialize solver `%s'!\n"), - plugin); - return GNUNET_SYSERR; - } - - GNUNET_assert (NULL != env.sf.s_add); - GNUNET_assert (NULL != env.sf.s_address_update_property); - GNUNET_assert (NULL != env.sf.s_address_update_session); - GNUNET_assert (NULL != env.sf.s_address_update_network); - GNUNET_assert (NULL != env.sf.s_get); - GNUNET_assert (NULL != env.sf.s_get_stop); - GNUNET_assert (NULL != env.sf.s_pref); - GNUNET_assert (NULL != env.sf.s_feedback); - GNUNET_assert (NULL != env.sf.s_del); - GNUNET_assert (NULL != env.sf.s_bulk_start); - GNUNET_assert (NULL != env.sf.s_bulk_stop); - - - GAS_normalization_start (&normalized_preference_changed_cb, NULL, - &normalized_property_changed_cb, NULL); - - if (NULL == solver) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to initialize solver!\n")); - return GNUNET_SYSERR; - } - /* up and running */ - running = GNUNET_YES; - - GNUNET_STATISTICS_set (stats, + GSA_addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO); + GNUNET_STATISTICS_set (GSA_stats, "# addresses", - GNUNET_CONTAINER_multipeermap_size (addresses), + GNUNET_CONTAINER_multipeermap_size (GSA_addresses), GNUNET_NO); - - return GNUNET_OK; } @@ -1835,12 +868,12 @@ destroy_all_address_it (void *cls, struct ATS_Address *aa = value; /* Remove */ - GNUNET_assert(GNUNET_YES == - GNUNET_CONTAINER_multipeermap_remove (addresses, - key, - value)); + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multipeermap_remove (GSA_addresses, + key, + value)); /* Notify */ - env.sf.s_del (solver, aa, GNUNET_NO); + GAS_plugin_delete_address (aa); /* Destroy */ GAS_performance_notify_all_clients (&aa->peer, aa->plugin, @@ -1861,17 +894,14 @@ destroy_all_address_it (void *cls, void GAS_addresses_destroy_all () { - if (GNUNET_NO == running) - return; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Destroying all addresses\n"); - env.sf.s_bulk_start (solver); - if (NULL != addresses) - GNUNET_CONTAINER_multipeermap_iterate (addresses, + GAS_plugin_solver_lock (); + if (NULL != GSA_addresses) + GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, &destroy_all_address_it, NULL); - env.sf.s_bulk_start (solver); + GAS_plugin_solver_unlock (); } @@ -1881,41 +911,11 @@ GAS_addresses_destroy_all () void GAS_addresses_done () { - struct GAS_Addresses_Suggestion_Requests *cur; - struct GAS_Addresses_Preference_Clients *pcur; - GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Shutting down addresses\n"); - GAS_addresses_destroy_all (); - running = GNUNET_NO; - GNUNET_CONTAINER_multipeermap_destroy (addresses); - addresses = NULL; - while (NULL != (cur = pending_requests_head)) - { - GNUNET_CONTAINER_DLL_remove (pending_requests_head, - pending_requests_tail, - cur); - GNUNET_free(cur); - } - - while (NULL != (pcur = preference_clients_head)) - { - GNUNET_CONTAINER_DLL_remove (preference_clients_head, - preference_clients_tail, - pcur); - GNUNET_assert (pref_clients > 0); - pref_clients --; - GNUNET_STATISTICS_set (stats, - "# active performance clients", - pref_clients, - GNUNET_NO); - GNUNET_free (pcur); - } - GNUNET_PLUGIN_unload (plugin, - solver); - GNUNET_free (plugin); - /* Stop configured solution method */ - GAS_normalization_stop (); + GAS_addresses_destroy_all (); + GNUNET_CONTAINER_multipeermap_destroy (GSA_addresses); + GSA_addresses = NULL; } @@ -1990,15 +990,15 @@ GAS_addresses_get_peer_info (const struct GNUNET_PeerIdentity *peer, (NULL == peer) ? "all peers" : GNUNET_i2s (peer), - (unsigned int) GNUNET_CONTAINER_multipeermap_size (addresses)); + (unsigned int) GNUNET_CONTAINER_multipeermap_size (GSA_addresses)); pi_ctx.it = pi_it; pi_ctx.it_cls = pi_it_cls; if (NULL == peer) - GNUNET_CONTAINER_multipeermap_iterate (addresses, + GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, &peerinfo_it, &pi_ctx); else - GNUNET_CONTAINER_multipeermap_get_multiple (addresses, + GNUNET_CONTAINER_multipeermap_get_multiple (GSA_addresses, peer, &peerinfo_it, &pi_ctx); pi_it (pi_it_cls, diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h index 8892f77c4e..f26eb779d7 100644 --- a/src/ats/gnunet-service-ats_addresses.h +++ b/src/ats/gnunet-service-ats_addresses.h @@ -216,38 +216,7 @@ * The bandwidth assigned to a peer can be influenced by setting a preference * for a peer. The prefernce will be given to to the solver with s_pref which * has to take care of the preference value - - */ - -/** - * Available ressource assignment modes */ -enum ATS_Mode -{ - /** - * proportional mode: - * - * Assign each peer an equal amount of bandwidth (bw) - * - * bw_per_peer = bw_total / #active addresses - */ - MODE_PROPORTIONAL, - - /** - * MLP mode: - * - * Solve ressource assignment as an optimization problem - * Uses an mixed integer programming solver - */ - MODE_MLP, - - /** - * Reinforcement Learning mode: - * - * Solve resource assignment using a learning agent - */ - MODE_RIL -}; /* @@ -362,17 +331,6 @@ struct ATS_Address */ uint32_t last_notified_bw_out; - - /** - * Blocking interval - */ - struct GNUNET_TIME_Relative block_interval; - - /** - * Time when address can be suggested again - */ - struct GNUNET_TIME_Absolute blocked_until; - /** * Time when address had last activity (update, in uses) */ @@ -402,19 +360,18 @@ struct ATS_Address /** + * A multihashmap to store all addresses + */ +extern struct GNUNET_CONTAINER_MultiPeerMap *GSA_addresses; + + + +/** * Initialize address subsystem. The addresses subsystem manages the addresses - * known and current performance information. It has a solver component - * responsible for the resource allocation. It tells the solver about changes - * and receives updates when the solver changes the ressource allocation. - * - * @param cfg configuration to use - * @param stats the statistics handle to use - * @return #GNUNET_OK on success, #GNUNET_SYSERR on error (failed to load - * solver plugin) + * known and current performance information. */ -int -GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_STATISTICS_Handle *stats); +void +GAS_addresses_init (void); /** @@ -480,83 +437,6 @@ void GAS_addresses_destroy_all (void); -/** - * Request address suggestions for a peer - * - * @param peer the peer id - */ -void -GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer); - - -/** - * Cancel address suggestions for a peer - * - * @param peer the peer id - */ -void -GAS_addresses_request_address_cancel (const struct GNUNET_PeerIdentity *peer); - - -/** - * Reset suggestion backoff for a peer - * - * Suggesting addresses is blocked for ATS_BLOCKING_DELTA. Blocking can be - * reset using this function - * - * @param peer the peer id - */ -void -GAS_addresses_handle_backoff_reset (const struct GNUNET_PeerIdentity *peer); - - -/** - * A performance client disconnected - * - * @param client the client; FIXME: type!? - */ -void -GAS_addresses_preference_client_disconnect (void *client); - - -/** - * Change the preference for a peer - * - * @param client the client sending this request; FIXME: type!? - * @param peer the peer id - * @param kind the preference kind to change - * @param score_abs the new preference score - */ -void -GAS_addresses_preference_change (void *client, - const struct GNUNET_PeerIdentity *peer, - enum GNUNET_ATS_PreferenceKind kind, - float score_abs); - - -/** - * Application feedback on how good preference requirements are fulfilled - * for a specific preference in the given time scope [now - scope .. now] - * - * An application notifies ATS if (and only if) it has feedback information - * for a specific property. This value is valid until the feedback score is - * updated by the application. - * - * If the application has no feedback for this preference kind the application - * will not explicitly call. - * - * @param application the application sending this request; FIXME: type? - * @param peer the peer id - * @param scope the time interval this valid for: [now - scope .. now] - * @param kind the preference kind this feedback is intended for - * @param score_abs the new preference score - */ -void -GAS_addresses_preference_feedback (void *application, - const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_TIME_Relative scope, - enum GNUNET_ATS_PreferenceKind kind, - float score_abs); /** diff --git a/src/ats/gnunet-service-ats_connectivity.c b/src/ats/gnunet-service-ats_connectivity.c index da943f9847..4aee2ddb88 100644 --- a/src/ats/gnunet-service-ats_connectivity.c +++ b/src/ats/gnunet-service-ats_connectivity.c @@ -34,8 +34,124 @@ #include "gnunet-service-ats.h" #include "gnunet-service-ats_addresses.h" #include "gnunet-service-ats_connectivity.h" +#include "gnunet-service-ats_plugins.h" #include "ats.h" + +/** + * Pending Address suggestion requests + */ +struct GAS_Addresses_Suggestion_Requests +{ + /** + * Next in DLL + */ + struct GAS_Addresses_Suggestion_Requests *next; + + /** + * Previous in DLL + */ + struct GAS_Addresses_Suggestion_Requests *prev; + + /** + * Peer ID + */ + struct GNUNET_PeerIdentity id; +}; + + +/** + * Address suggestion requests DLL head. + * FIXME: This must become a Multipeermap! O(n) operations + * galore instead of O(1)!!! + */ +static struct GAS_Addresses_Suggestion_Requests *pending_requests_head; + +/** + * Address suggestion requests DLL tail + */ +static struct GAS_Addresses_Suggestion_Requests *pending_requests_tail; + + + + +/** + * Cancel address suggestions for a peer + * + * @param peer the peer id + */ +void +GAS_addresses_request_address_cancel (const struct GNUNET_PeerIdentity *peer) +{ + struct GAS_Addresses_Suggestion_Requests *cur = pending_requests_head; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received request: `%s' for peer %s\n", + "request_address_cancel", + GNUNET_i2s (peer)); + + while (NULL != cur) + { + if (0 == memcmp (peer, &cur->id, sizeof(cur->id))) + break; /* found */ + cur = cur->next; + } + + if (NULL == cur) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "No address requests pending for peer `%s', cannot remove!\n", + GNUNET_i2s (peer)); + return; + } + GAS_plugin_request_connect_stop (peer); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Removed request pending for peer `%s\n", + GNUNET_i2s (peer)); + GNUNET_CONTAINER_DLL_remove (pending_requests_head, + pending_requests_tail, + cur); + GNUNET_free (cur); +} + + +/** + * Request address suggestions for a peer + * + * @param peer the peer id + */ +void +GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer) +{ + struct GAS_Addresses_Suggestion_Requests *cur = pending_requests_head; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Received `%s' for peer `%s'\n", + "REQUEST ADDRESS", + GNUNET_i2s (peer)); + + while (NULL != cur) + { + if (0 == memcmp (peer, &cur->id, sizeof(cur->id))) + break; /* already suggesting */ + cur = cur->next; + } + if (NULL == cur) + { + cur = GNUNET_new (struct GAS_Addresses_Suggestion_Requests); + cur->id = *peer; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Adding new address suggestion request for `%s'\n", + GNUNET_i2s (peer)); + GNUNET_CONTAINER_DLL_insert (pending_requests_head, + pending_requests_tail, + cur); + } + GAS_plugin_request_connect_start (peer); +} + + + /** * Handle 'request address' messages from clients. * @@ -83,4 +199,36 @@ GAS_handle_request_address_cancel (void *cls, GNUNET_SERVER_receive_done (client, GNUNET_OK); } + +/** + * Unregister a client (which may have been a connectivity client, + * but this is not assured). + * + * @param client handle of the (now dead) client + */ +void +GAS_connectivity_remove_client (struct GNUNET_SERVER_Client *client) +{ + // FIXME +} + + +/** + * Shutdown connectivity subsystem. + */ +void +GAS_connectivity_done () +{ + struct GAS_Addresses_Suggestion_Requests *cur; + + while (NULL != (cur = pending_requests_head)) + { + GNUNET_CONTAINER_DLL_remove (pending_requests_head, + pending_requests_tail, + cur); + GNUNET_free(cur); + } +} + + /* end of gnunet-service-ats_connectivity.c */ diff --git a/src/ats/gnunet-service-ats_connectivity.h b/src/ats/gnunet-service-ats_connectivity.h index c6b50f445c..faa00ac405 100644 --- a/src/ats/gnunet-service-ats_connectivity.h +++ b/src/ats/gnunet-service-ats_connectivity.h @@ -27,6 +27,24 @@ #ifndef GNUNET_SERVICE_ATS_CONNECTIVITY_H #define GNUNET_SERVICE_ATS_CONNECTIVITY_H +/** + * Request address suggestions for a peer + * + * @param peer the peer id + */ +void +GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer); + + +/** + * Cancel address suggestions for a peer + * + * @param peer the peer id + */ +void +GAS_addresses_request_address_cancel (const struct GNUNET_PeerIdentity *peer); + + /** * Handle 'request address' messages from clients. @@ -54,5 +72,22 @@ GAS_handle_request_address_cancel (void *cls, const struct GNUNET_MessageHeader *message); +/** + * Unregister a client (which may have been a connectivity client, + * but this is not assured). + * + * @param client handle of the (now dead) client + */ +void +GAS_connectivity_remove_client (struct GNUNET_SERVER_Client *client); + + +/** + * Shutdown connectivity subsystem. + */ +void +GAS_connectivity_done (void); + + #endif /* end of gnunet-service-ats_connectivity.h */ diff --git a/src/ats/gnunet-service-ats_normalization.c b/src/ats/gnunet-service-ats_normalization.c index b4051c9fa7..7003f69e4e 100644 --- a/src/ats/gnunet-service-ats_normalization.c +++ b/src/ats/gnunet-service-ats_normalization.c @@ -23,116 +23,18 @@ * @brief ats service address: management of ATS properties and preferences normalization * @author Matthias Wachs * @author Christian Grothoff + * + * FIXME: rename to 'properties'! */ #include "platform.h" #include "gnunet_ats_service.h" #include "gnunet-service-ats_addresses.h" #include "gnunet-service-ats_normalization.h" +#include "gnunet-service-ats_plugins.h" #define LOG(kind,...) GNUNET_log_from (kind, "ats-normalization",__VA_ARGS__) -/** - * Preference client - */ -struct PreferenceClient -{ - /** - * Next in DLL - */ - struct PreferenceClient *prev; - - /** - * Next in DLL - */ - - struct PreferenceClient *next; - - /** - * Client handle - */ - void *client; - - /** - * Array of sum of absolute preferences for this client - */ - double f_abs_sum[GNUNET_ATS_PreferenceCount]; - - /** - * Array of sum of relative preferences for this client - */ - double f_rel_sum[GNUNET_ATS_PreferenceCount]; - - /** - * List of peer preferences for this client - */ - - /** - * Head of peer list - */ - struct PreferencePeer *p_head; - - /** - * Tail of peer list - */ - struct PreferencePeer *p_tail; -}; - -/** - * Preference peer - */ -struct PreferencePeer -{ - /** - * Next in DLL - */ - struct PreferencePeer *next; - - /** - * Previous in DLL - */ - struct PreferencePeer *prev; - - /** - * Client - */ - struct PreferenceClient *client; - - /** - * Peer id - */ - struct GNUNET_PeerIdentity id; - /** - * Absolute preference values for all preference types - */ - double f_abs[GNUNET_ATS_PreferenceCount]; - - /** - * Relative preference values for all preference types - */ - double f_rel[GNUNET_ATS_PreferenceCount]; - - /** - * Absolute point of time of next aging process - */ - struct GNUNET_TIME_Absolute next_aging[GNUNET_ATS_PreferenceCount]; -}; - -/** - * Relative preferences for a peer - */ -struct PeerRelative -{ - /** - * Relative preference values - */ - double f_rel[GNUNET_ATS_PreferenceCount]; - - /** - * Peer id - */ - struct GNUNET_PeerIdentity id; -}; /** * Quality Normalization @@ -147,490 +49,27 @@ struct Property static struct Property properties[GNUNET_ATS_QualityPropertiesCount]; - -/** - * Callback to call on changing preference values - */ -static GAS_Normalization_preference_changed_cb pref_changed_cb; - -/** - * Closure for callback to call on changing preference values - */ -static void *pref_changed_cb_cls; - -/** - * Callback to call on changing property values - */ -static GAS_Normalization_property_changed_cb prop_ch_cb; - -/** - * Closure for callback to call on changing property values - */ -static void *prop_ch_cb_cls; - -/** - * Hashmap to store peer information for preference normalization - */ -static struct GNUNET_CONTAINER_MultiPeerMap *preference_peers; - /** * Hashmap to store peer information for property normalization * FIXME: this map is not used! */ static struct GNUNET_CONTAINER_MultiPeerMap *property_peers; -/** - * Clients in DLL: head - */ -static struct PreferenceClient *pc_head; - -/** - * Clients in DLL: tail - */ -static struct PreferenceClient *pc_tail; - -/** - * Default values - */ -static struct PeerRelative defvalues; - -static struct GNUNET_SCHEDULER_Task * aging_task; - - -/** - * Update a peer - * - * @param id peer id - * @param kind the kind - * @param rp the relative peer struct - * @return the new relative preference - */ -static void -update_relative_values_for_peer (const struct GNUNET_PeerIdentity *id, - enum GNUNET_ATS_PreferenceKind kind, struct PeerRelative *rp) -{ - struct PreferenceClient *c_cur; - struct PreferencePeer *p_cur; - double f_rel_total; - double f_rel_sum; - double backup; - unsigned int peer_count; - - f_rel_sum = 0.0; - f_rel_total = 0.0; - peer_count = 0; - - /* For all clients */ - for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) - { - /* For peer entries with this id */ - for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next) - { - f_rel_sum += p_cur->f_rel[kind]; - if (0 == memcmp (id, &p_cur->id, sizeof(struct GNUNET_PeerIdentity))) - { - peer_count ++; - f_rel_total += p_cur->f_rel[kind]; - } - - } - } - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "%u clients have a total relative preference for peer `%s' `%s' of %.3f and for %s in total %.3f\n", - peer_count, GNUNET_i2s (id), - GNUNET_ATS_print_preference_type (kind), - f_rel_total, - GNUNET_ATS_print_preference_type (kind), - f_rel_sum); - - /* Find entry for the peer containing relative values in the hashmap */ - if (NULL != rp) - { - backup = rp->f_rel[kind]; - if (f_rel_sum > 0) - rp->f_rel[kind] = f_rel_total / f_rel_sum; - else - { - /* No client had any preferences for this type and any peer */ - rp->f_rel[kind] = DEFAULT_REL_PREFERENCE; - } - if ((backup != rp->f_rel[kind]) && (NULL != pref_changed_cb)) - { - pref_changed_cb (pref_changed_cb_cls, &rp->id, kind, rp->f_rel[kind]); - } - } -} - - -/** - * Recalculate preference for a specific ATS property - * - * @param c the preference client - * @param kind the preference kind - * @return the result - */ -static void -recalculate_relative_preferences (struct PreferenceClient *c, - enum GNUNET_ATS_PreferenceKind kind) -{ - struct PreferencePeer *p_cur; - - /* For this client: sum of absolute preference values for this preference */ - c->f_abs_sum[kind] = 0.0; - /* For this client: sum of relative preference values for this preference - * - * Note: this value should also be 1.0, but: - * if no preferences exist due to aging, this value can be 0.0 - * and the client can be removed */ - c->f_rel_sum[kind] = 0.0; - - for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next) - c->f_abs_sum[kind] += p_cur->f_abs[kind]; - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Client %p has sum of total preferences for %s of %.3f\n", - c->client, GNUNET_ATS_print_preference_type (kind), c->f_abs_sum[kind]); - - /* For all peers: calculate relative preference */ - for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next) - { - /* Calculate relative preference for specific kind */ - - /* Every application has a preference for each peer between - * [0 .. 1] in relative values - * and [0 .. inf] in absolute values */ - p_cur->f_rel[kind] = p_cur->f_abs[kind] / c->f_abs_sum[kind]; - c->f_rel_sum[kind] += p_cur->f_rel[kind]; - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Client %p has relative preference for %s for peer `%s' of %.3f\n", - c->client, - GNUNET_ATS_print_preference_type (kind), - GNUNET_i2s (&p_cur->id), - p_cur->f_rel[kind]); - } - -} - - -/** - * Update the absolute preference value for a peer - * @param c the client - * @param p the peer - * @param kind the preference kind - * @param score_abs the absolute value - * @return the new relative preference value - */ -static void -update_abs_preference (struct PreferenceClient *c, - struct PreferencePeer *p, - enum GNUNET_ATS_PreferenceKind kind, - float score_abs) -{ - double score = score_abs; - - /* Update preference value according to type */ - switch (kind) - { - case GNUNET_ATS_PREFERENCE_BANDWIDTH: - case GNUNET_ATS_PREFERENCE_LATENCY: - p->f_abs[kind] = score; - /* p->f_abs[kind] = (p->f_abs[kind] + score) / 2; */ - p->next_aging[kind] = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), - PREF_AGING_INTERVAL); - break; - case GNUNET_ATS_PREFERENCE_END: - break; - default: - break; - } -} - - -static int -update_iterator (void *cls, - const struct GNUNET_PeerIdentity *key, - void *value) -{ - enum GNUNET_ATS_PreferenceKind *kind = cls; - struct PeerRelative *pr = value; - - update_relative_values_for_peer (key, - (*kind), - pr); - return GNUNET_OK; -} - - -static void -run_preference_update (struct PreferenceClient *c_cur, - struct PreferencePeer *p_cur, - enum GNUNET_ATS_PreferenceKind kind, - float score_abs) -{ - double old_value; - /* Update relative value */ - old_value = p_cur->f_rel[kind]; - recalculate_relative_preferences (c_cur, kind); - if (p_cur->f_rel[kind] == old_value) - return; - - /* Relative preference value changed, recalculate for all peers */ - GNUNET_CONTAINER_multipeermap_iterate (preference_peers, &update_iterator, &kind); -} - - -/** - * Reduce absolute preferences since they got old - * - * @param cls the PreferencePeer - * @param tc context - */ -static void -preference_aging (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct PreferencePeer *p; - struct PreferenceClient *cur_client; - int i; - int values_to_update; - double backup; - - aging_task = NULL; - values_to_update = 0; - cur_client = NULL; - - for (cur_client = pc_head; NULL != cur_client; cur_client = cur_client->next) - { - for (p = cur_client->p_head; NULL != p; p = p->next) - { - /* Aging absolute values: */ - for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) - { - if (0 - == GNUNET_TIME_absolute_get_remaining (p->next_aging[i]).rel_value_us) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Aging preference for peer `%s'\n", GNUNET_i2s (&p->id)); - backup = p->f_abs[i]; - if (p->f_abs[i] > DEFAULT_ABS_PREFERENCE) - p->f_abs[i] *= PREF_AGING_FACTOR; - - if (p->f_abs[i] <= DEFAULT_ABS_PREFERENCE + PREF_EPSILON) - p->f_abs[i] = DEFAULT_ABS_PREFERENCE; - - if ( (p->f_abs[i] != DEFAULT_ABS_PREFERENCE) && - (backup != p->f_abs[i]) ) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Aged preference for peer `%s' from %.3f to %.3f\n", - GNUNET_i2s (&p->id), backup, p->f_abs[i]); - - run_preference_update(cur_client, p, i, p->f_abs[i]); - - p->next_aging[i] = GNUNET_TIME_absolute_add ( - GNUNET_TIME_absolute_get (), PREF_AGING_INTERVAL); - values_to_update++; - } - } - } - } - } - - if (values_to_update > 0) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Rescheduling aging task due to %u elements to age\n", - values_to_update); - aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL, - &preference_aging, NULL ); - } - else - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "No values to age left, not rescheduling aging task\n"); - -} - - -/** - * Normalize an updated preference value - * - * @param client the client with this preference - * @param peer the peer to change the preference for - * @param kind the kind to change the preference - * @param score_abs the normalized score - */ -void -GAS_normalization_normalize_preference (void *client, - const struct GNUNET_PeerIdentity *peer, - enum GNUNET_ATS_PreferenceKind kind, - float score_abs) -{ - struct PreferenceClient *c_cur; - struct PreferencePeer *p_cur; - struct PeerRelative *r_cur; - double old_value; - int i; - - GNUNET_assert(NULL != client); - GNUNET_assert(NULL != peer); - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Client %p changes preference for peer `%s' for `%s' to %.2f\n", - client, - GNUNET_i2s (peer), - GNUNET_ATS_print_preference_type (kind), - score_abs); - - if (kind >= GNUNET_ATS_PreferenceCount) - { - GNUNET_break(0); - return; - } - - /* Find preference client */ - for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) - { - if (client == c_cur->client) - break; - } - /* Not found: create new preference client */ - if (NULL == c_cur) - { - c_cur = GNUNET_new (struct PreferenceClient); - c_cur->client = client; - for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) - { - c_cur->f_abs_sum[i] = DEFAULT_ABS_PREFERENCE; - c_cur->f_rel_sum[i] = DEFAULT_REL_PREFERENCE; - } - - GNUNET_CONTAINER_DLL_insert(pc_head, pc_tail, c_cur); - LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding new client %p \n", c_cur); - } - - /* Find entry for peer */ - for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next) - if (0 == memcmp (&p_cur->id, peer, sizeof(p_cur->id))) - break; - - /* Not found: create new peer entry */ - if (NULL == p_cur) - { - p_cur = GNUNET_new (struct PreferencePeer); - p_cur->client = c_cur; - p_cur->id = (*peer); - for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) - { - /* Default value per peer absolute preference for a preference: 0 */ - p_cur->f_abs[i] = DEFAULT_ABS_PREFERENCE; - /* Default value per peer relative preference for a quality: 1.0 */ - p_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; - p_cur->next_aging[i] = GNUNET_TIME_UNIT_FOREVER_ABS; - } - LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding new peer %p for client %p \n", - p_cur, c_cur); - GNUNET_CONTAINER_DLL_insert(c_cur->p_head, c_cur->p_tail, p_cur); - } - - /* Create struct for peer */ - if (NULL == GNUNET_CONTAINER_multipeermap_get (preference_peers, peer)) - { - r_cur = GNUNET_new (struct PeerRelative); - r_cur->id = (*peer); - for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) - r_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; - GNUNET_assert( - GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (preference_peers, - &r_cur->id, r_cur, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - } - - /* Update absolute value */ - old_value = p_cur->f_abs[kind]; - update_abs_preference (c_cur, p_cur, kind, score_abs); - if (p_cur->f_abs[kind] == old_value) - return; - - run_preference_update (c_cur, p_cur, kind, score_abs); - - /* Start aging task */ - if (NULL == aging_task) - aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL, - &preference_aging, NULL ); - -} - - -/** - * Get the normalized preference values for a specific peer or - * the default values if - * - * @param id the peer - * @return pointer to the values, can be indexed with GNUNET_ATS_PreferenceKind, - * default preferences if peer does not exist - */ -const double * -GAS_normalization_get_preferences_by_peer (const struct GNUNET_PeerIdentity *id) -{ - GNUNET_assert(NULL != preference_peers); - GNUNET_assert(NULL != id); - - struct PeerRelative *rp; - if (NULL == (rp = GNUNET_CONTAINER_multipeermap_get (preference_peers, id))) - { - return defvalues.f_rel; - } - return rp->f_rel; -} - - -/** - * Get the normalized preference values for a specific client and peer - * - * @param client client - * @param peer the peer - * @param pref the preference type - * @return the value - */ -double -GAS_normalization_get_preferences_by_client (const void *client, - const struct GNUNET_PeerIdentity *peer, - enum GNUNET_ATS_PreferenceKind pref) -{ - struct PreferenceClient *c_cur; - struct PreferencePeer *p_cur; - - /* Find preference client */ - for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) - { - if (client == c_cur->client) - break; - } - if (NULL == c_cur) - return -1.0; - - for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next) - { - if (0 == memcmp (peer, &p_cur->id, sizeof (struct GNUNET_PeerIdentity))) - break; - } - if (NULL == p_cur) - return DEFAULT_REL_PREFERENCE; /* Not found, return default */ - - return p_cur->f_rel[pref]; -} /** * Get the normalized properties values for a specific peer or * the default values if * + * @param cls ignored * @param address the address * @return pointer to the values, can be indexed with GNUNET_ATS_PreferenceKind, * default preferences if peer does not exist */ const double * -GAS_normalization_get_properties (const struct ATS_Address *address) +GAS_normalization_get_properties (void *cls, + const struct ATS_Address *address) { static double norm_values[GNUNET_ATS_QualityPropertiesCount]; int i; @@ -742,7 +181,9 @@ find_min_max_it (void *cls, const struct GNUNET_PeerIdentity *h, void *k) static int -normalize_address (void *cls, const struct GNUNET_PeerIdentity *h, void *k) +normalize_address (void *cls, + const struct GNUNET_PeerIdentity *h, + void *k) { struct Property *p = cls; struct ATS_Address *address = k; @@ -769,9 +210,9 @@ normalize_address (void *cls, const struct GNUNET_PeerIdentity *h, void *k) address->atsin[p->prop_type].avg, p->min, p->max, address->atsin[p->prop_type].norm); - if (NULL != prop_ch_cb) - prop_ch_cb (prop_ch_cb_cls, address, p->atsi_type, - address->atsin[p->prop_type].norm); + GAS_normalized_property_changed (address, + p->atsi_type, + address->atsin[p->prop_type].norm); return GNUNET_OK; } @@ -781,14 +222,14 @@ normalize_address (void *cls, const struct GNUNET_PeerIdentity *h, void *k) * Normalize avg_value to a range of values between [1.0, 2.0] * based on min max values currently known. * - * @param addresses the address hashmap * @param p the property * @param address the address * @param avg_value the value to normalize */ static void -property_normalize (struct GNUNET_CONTAINER_MultiPeerMap *addresses, - struct Property *p, struct ATS_Address *address, uint32_t avg_value) +property_normalize (struct Property *p, + struct ATS_Address *address, + uint32_t avg_value) { struct FindMinMaxCtx find_ctx; int addr_count; @@ -797,8 +238,9 @@ property_normalize (struct GNUNET_CONTAINER_MultiPeerMap *addresses, find_ctx.p = p; find_ctx.max = 0; find_ctx.min = UINT32_MAX; - addr_count = GNUNET_CONTAINER_multipeermap_iterate (addresses, - &find_min_max_it, &find_ctx); + addr_count = GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, + &find_min_max_it, + &find_ctx); if (0 == addr_count) { GNUNET_break(0); @@ -808,19 +250,21 @@ property_normalize (struct GNUNET_CONTAINER_MultiPeerMap *addresses, limits_changed = GNUNET_NO; if (find_ctx.max != p->max) { - LOG(GNUNET_ERROR_TYPE_DEBUG, - "Normalizing %s: new maximum %u -> recalculate all values\n", - GNUNET_ATS_print_property_type (p->atsi_type), find_ctx.max); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Normalizing %s: new maximum %u -> recalculate all values\n", + GNUNET_ATS_print_property_type (p->atsi_type), + find_ctx.max); p->max = find_ctx.max; limits_changed = GNUNET_YES; } if ((find_ctx.min != p->min) && (find_ctx.min < p->max)) { - LOG(GNUNET_ERROR_TYPE_DEBUG, - "Normalizing %s: new minimum %u -> recalculate all values\n", - GNUNET_ATS_print_property_type (p->atsi_type), find_ctx.min, - find_ctx.max); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Normalizing %s: new minimum %u -> recalculate all values\n", + GNUNET_ATS_print_property_type (p->atsi_type), + find_ctx.min, + find_ctx.max); p->min = find_ctx.min; limits_changed = GNUNET_YES; } @@ -835,13 +279,13 @@ property_normalize (struct GNUNET_CONTAINER_MultiPeerMap *addresses, { /* normalize just this address */ normalize_address (p, &address->peer, address); - return; } else { /* limits changed, normalize all addresses */ - GNUNET_CONTAINER_multipeermap_iterate (addresses, &normalize_address, p); - return; + GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, + &normalize_address, + p); } } @@ -849,14 +293,12 @@ property_normalize (struct GNUNET_CONTAINER_MultiPeerMap *addresses, /** * Update and normalize atsi performance information * - * @param addresses hashmap containing all addresses * @param address the address to update * @param atsi the array of performance information * @param atsi_count the number of atsi information in the array */ void -GAS_normalization_normalize_property (struct GNUNET_CONTAINER_MultiPeerMap *addresses, - struct ATS_Address *address, +GAS_normalization_normalize_property (struct ATS_Address *address, const struct GNUNET_ATS_Information *atsi, uint32_t atsi_count) { @@ -867,9 +309,6 @@ GAS_normalization_normalize_property (struct GNUNET_CONTAINER_MultiPeerMap *addr uint32_t current_val; unsigned int existing_properties[] = GNUNET_ATS_QualityProperties; - GNUNET_assert (NULL != address); - GNUNET_assert (NULL != atsi); - LOG (GNUNET_ERROR_TYPE_DEBUG, "Updating %u elements for peer `%s'\n", atsi_count, @@ -901,70 +340,22 @@ GAS_normalization_normalize_property (struct GNUNET_CONTAINER_MultiPeerMap *addr /* Normalizing */ /* Check min, max */ cur_prop = &properties[c2]; - property_normalize (addresses, cur_prop, address, current_val); + property_normalize (cur_prop, address, current_val); } } -static void -free_client (struct PreferenceClient *pc) -{ - struct PreferencePeer *next_p; - struct PreferencePeer *p; - next_p = pc->p_head; - while (NULL != (p = next_p)) - { - next_p = p->next; - GNUNET_CONTAINER_DLL_remove(pc->p_head, pc->p_tail, p); - GNUNET_free(p); - } - GNUNET_free(pc); -} - - -/** - * A performance client disconnected - * - * @param client the client - */ -void -GAS_normalization_preference_client_disconnect (void *client) -{ - struct PreferenceClient *c_cur; - /* Find preference client */ - - for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) - { - if (client == c_cur->client) - break; - } - if (NULL == c_cur) - return; - - GNUNET_CONTAINER_DLL_remove(pc_head, pc_tail, c_cur); - free_client (c_cur); -} - /** * Start the normalization component - * - * @param pref_ch_cb callback to call on relative preference changing - * @param pref_ch_cb_cls cls for the preference callback - * @param property_ch_cb callback to call on relative property changing - * @param property_ch_cb_cls cls for the property callback */ void -GAS_normalization_start (GAS_Normalization_preference_changed_cb pref_ch_cb, - void *pref_ch_cb_cls, GAS_Normalization_property_changed_cb property_ch_cb, - void *property_ch_cb_cls) +GAS_normalization_start () { int c1; - int i; - preference_peers = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); - property_peers = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); unsigned int existing_properties[] = GNUNET_ATS_QualityProperties; + property_peers = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); for (c1 = 0; c1 < GNUNET_ATS_QualityPropertiesCount; c1++) { properties[c1].prop_type = c1; @@ -972,42 +363,9 @@ GAS_normalization_start (GAS_Normalization_preference_changed_cb pref_ch_cb, properties[c1].min = 0; properties[c1].max = 0; } - - pref_changed_cb = pref_ch_cb; - pref_changed_cb_cls = pref_ch_cb_cls; - prop_ch_cb = property_ch_cb; - prop_ch_cb_cls = pref_ch_cb_cls; - - pc_head = NULL; - pc_tail = NULL; - - for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) - defvalues.f_rel[i] = DEFAULT_REL_PREFERENCE; - aging_task = NULL; - return; } -/** - * Free a peer - * - * @param cls unused - * @param key the key - * @param value RelativePeer - * @return #GNUNET_OK to continue - */ -static int -free_peer (void *cls, const struct GNUNET_PeerIdentity *key, void *value) -{ - struct PeerRelative *rp = value; - if (GNUNET_YES - == GNUNET_CONTAINER_multipeermap_remove (preference_peers, key, value)) - GNUNET_free(rp); - else - GNUNET_break(0); - return GNUNET_OK; -} - /** * Stop the normalization component and free all items @@ -1015,27 +373,7 @@ free_peer (void *cls, const struct GNUNET_PeerIdentity *key, void *value) void GAS_normalization_stop () { - struct PreferenceClient *pc; - struct PreferenceClient *next_pc; - - if (NULL != aging_task) - { - GNUNET_SCHEDULER_cancel (aging_task); - aging_task = NULL; - } - - next_pc = pc_head; - while (NULL != (pc = next_pc)) - { - next_pc = pc->next; - GNUNET_CONTAINER_DLL_remove(pc_head, pc_tail, pc); - free_client (pc); - } - - GNUNET_CONTAINER_multipeermap_iterate (preference_peers, &free_peer, NULL ); - GNUNET_CONTAINER_multipeermap_destroy (preference_peers); GNUNET_CONTAINER_multipeermap_destroy (property_peers); - return; } /* end of gnunet-service-ats_normalization.c */ diff --git a/src/ats/gnunet-service-ats_normalization.h b/src/ats/gnunet-service-ats_normalization.h index 2cbf7ab77f..e542097c94 100644 --- a/src/ats/gnunet-service-ats_normalization.h +++ b/src/ats/gnunet-service-ats_normalization.h @@ -24,51 +24,37 @@ * @author Matthias Wachs * @author Christian Grothoff */ -#include "platform.h" +#ifndef GNUNET_SERVICE_ATS_NORMALIZATION_H +#define GNUNET_SERVICE_ATS_NORMALIZATION_H #include "gnunet_ats_service.h" -#define PREF_AGING_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) -#define PREF_AGING_FACTOR 0.95 -#define PREF_EPSILON 0.01 - -#define DEFAULT_REL_PREFERENCE 0.0 -#define DEFAULT_ABS_PREFERENCE 0.0 - #define DEFAULT_REL_QUALITY 1.0 -typedef void -(*GAS_Normalization_preference_changed_cb) (void *cls, - const struct GNUNET_PeerIdentity *peer, - enum GNUNET_ATS_PreferenceKind kind, - double pref_rel); - -typedef void -(*GAS_Normalization_property_changed_cb) (void *cls, - struct ATS_Address *peer, - uint32_t type, - double prop_rel); - /** * Get the normalized preference values for a specific peer * + * @param cls ignored * @param id the peer @return pointer to the values, can be indexed * with GNUNET_ATS_PreferenceKind, NULL if peer does not exist */ const double * -GAS_normalization_get_preferences_by_peer (const struct GNUNET_PeerIdentity *id); +GAS_normalization_get_preferences_by_peer (void *cls, + const struct GNUNET_PeerIdentity *id); /** * Get the normalized properties values for a specific peer or * the default values if * + * @param cls ignored * @param address the address * @return pointer to the values, can be indexed with GNUNET_ATS_PreferenceKind, * default preferences if peer does not exist */ const double * -GAS_normalization_get_properties (const struct ATS_Address *address); +GAS_normalization_get_properties (void *cls, + const struct ATS_Address *address); /** @@ -101,14 +87,12 @@ GAS_normalization_normalize_preference (void *client, /** * Update and normalize a atsi performance information * - * @param addresses hashmap containing all addresses * @param address the address to update * @param atsi the array of performance information * @param atsi_count the number of atsi information in the array */ void -GAS_normalization_normalize_property (struct GNUNET_CONTAINER_MultiPeerMap *addresses, - struct ATS_Address *address, +GAS_normalization_normalize_property (struct ATS_Address *address, const struct GNUNET_ATS_Information *atsi, uint32_t atsi_count); @@ -124,24 +108,16 @@ GAS_normalization_preference_client_disconnect (void *client); /** * Start the normalization component - * - * @param pref_ch_cb callback to call on relative preference changing - * @param pref_ch_cb_cls cls for the preference callback - * @param property_ch_cb callback to call on relative property changing - * @param property_ch_cb_cls cls for the property callback */ void -GAS_normalization_start (GAS_Normalization_preference_changed_cb pref_ch_cb, - void *pref_ch_cb_cls, - GAS_Normalization_property_changed_cb property_ch_cb, - void *property_ch_cb_cls); +GAS_normalization_start (void); /** * Stop the normalization component and free all items */ void -GAS_normalization_stop (); - +GAS_normalization_stop (void); +#endif /* end of gnunet-service-ats_normalization.h */ diff --git a/src/ats/gnunet-service-ats_performance.c b/src/ats/gnunet-service-ats_performance.c index e0a5cbdae9..c498212272 100644 --- a/src/ats/gnunet-service-ats_performance.c +++ b/src/ats/gnunet-service-ats_performance.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2011-2014 Christian Grothoff (and other contributing authors) + (C) 2011-2015 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -69,6 +69,7 @@ static struct PerformanceClient *pc_head; */ static struct PerformanceClient *pc_tail; + /** * Context for sending messages to performance clients. */ @@ -92,7 +93,6 @@ find_client (struct GNUNET_SERVER_Client *client) return NULL; } - /** * Unregister a client (which may have been a performance client, * but this is not assured). @@ -108,7 +108,6 @@ GAS_performance_remove_client (struct GNUNET_SERVER_Client *client) if (NULL == pc) return; GNUNET_CONTAINER_DLL_remove (pc_head, pc_tail, pc); - GAS_addresses_preference_client_disconnect (client); GNUNET_free (pc); } @@ -593,109 +592,6 @@ GAS_handle_reservation_request (void *cls, } -/** - * Handle 'preference change' messages from clients. - * - * @param cls unused, NULL - * @param client client that sent the request - * @param message the request message - */ -void -GAS_handle_preference_change (void *cls, - struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) -{ - const struct ChangePreferenceMessage *msg; - const struct PreferenceInformation *pi; - uint16_t msize; - uint32_t nump; - uint32_t i; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received `%s' message\n", - "PREFERENCE_CHANGE"); - msize = ntohs (message->size); - if (msize < sizeof (struct ChangePreferenceMessage)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } - msg = (const struct ChangePreferenceMessage *) message; - nump = ntohl (msg->num_preferences); - if (msize != - sizeof (struct ChangePreferenceMessage) + - nump * sizeof (struct PreferenceInformation)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } - GNUNET_STATISTICS_update (GSA_stats, - "# preference change requests processed", - 1, GNUNET_NO); - pi = (const struct PreferenceInformation *) &msg[1]; - for (i = 0; i < nump; i++) - GAS_addresses_preference_change (client, - &msg->peer, - (enum GNUNET_ATS_PreferenceKind) - ntohl (pi[i].preference_kind), - pi[i].preference_value); - GNUNET_SERVER_receive_done (client, GNUNET_OK); -} - - -/** - * Handle 'preference feedback' messages from clients. - * - * @param cls unused, NULL - * @param client client that sent the request - * @param message the request message - */ -void -GAS_handle_preference_feedback (void *cls, - struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) -{ - const struct FeedbackPreferenceMessage *msg; - const struct PreferenceInformation *pi; - uint16_t msize; - uint32_t nump; - uint32_t i; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received `%s' message\n", - "PREFERENCE_FEEDBACK"); - msize = ntohs (message->size); - if (msize < sizeof (struct FeedbackPreferenceMessage)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } - msg = (const struct FeedbackPreferenceMessage *) message; - nump = ntohl (msg->num_feedback); - if (msize != - sizeof (struct FeedbackPreferenceMessage) + - nump * sizeof (struct PreferenceInformation)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } - GNUNET_STATISTICS_update (GSA_stats, - "# preference feedbacks requests processed", - 1, GNUNET_NO); - pi = (const struct PreferenceInformation *) &msg[1]; - for (i = 0; i < nump; i++) - GAS_addresses_preference_feedback (client, - &msg->peer, - GNUNET_TIME_relative_ntoh(msg->scope), - (enum GNUNET_ATS_PreferenceKind) - ntohl (pi[i].preference_kind), - pi[i].preference_value); - GNUNET_SERVER_receive_done (client, GNUNET_OK); -} /** diff --git a/src/ats/gnunet-service-ats_plugins.c b/src/ats/gnunet-service-ats_plugins.c new file mode 100644 index 0000000000..1e234b56d8 --- /dev/null +++ b/src/ats/gnunet-service-ats_plugins.c @@ -0,0 +1,661 @@ +/* + This file is part of GNUnet. + (C) 2011-2014 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file ats/gnunet-service-ats_plugins.c + * @brief ats service plugin management + * @author Matthias Wachs + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_ats_service.h" +#include "gnunet-service-ats.h" +#include "gnunet_statistics_service.h" +#include "gnunet_ats_plugin.h" +#include "gnunet-service-ats_addresses.h" +#include "gnunet-service-ats_performance.h" +#include "gnunet-service-ats_plugins.h" +#include "gnunet-service-ats_scheduling.h" +#include "gnunet-service-ats_normalization.h" +#include "ats.h" + + + +/** + * Configured ATS solver + */ +static int ats_mode; + +/** + * Solver handle. FIXME: TYPE!? + */ +static void *solver; + +/** + * Solver functions. FIXME. + */ +static struct GNUNET_ATS_PluginEnvironment env; + +/** + * Solver plugin name as string + */ +static char *plugin; + + +/** + * The preference changed for a peer, update solver. + * + * @param peer the peer + * @param kind the ATS kind + * @param pref_rel the new relative preference value + */ +void +GAS_normalized_preference_changed (const struct GNUNET_PeerIdentity *peer, + enum GNUNET_ATS_PreferenceKind kind, + double pref_rel) +{ + /* Tell solver about update */ + env.sf.s_pref (solver, peer, kind, pref_rel); +} + + +/** + * The relative value for a property changed + * + * @param address the peer + * @param type the ATS type + * @param prop_rel the new relative preference value + */ +void +GAS_normalized_property_changed (struct ATS_Address *address, + uint32_t type, + double prop_rel) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Normalized property %s for peer `%s' changed to %.3f \n", + GNUNET_ATS_print_property_type (type), + GNUNET_i2s (&address->peer), + prop_rel); + env.sf.s_address_update_property (solver, + address, + type, + 0, + prop_rel); +} + + +/** + * Solver information callback + * + * @param cls the closure + * @param op the operation + * @param status operation status + * @param add additional information + */ +static void +solver_info_cb (void *cls, + enum GAS_Solver_Operation op, + enum GAS_Solver_Status status, + enum GAS_Solver_Additional_Information add) +{ + char *add_info; + + switch (add) { + case GAS_INFO_NONE: + add_info = "GAS_INFO_NONE"; + break; + case GAS_INFO_FULL: + add_info = "GAS_INFO_MLP_FULL"; + break; + case GAS_INFO_UPDATED: + add_info = "GAS_INFO_MLP_UPDATED"; + break; + case GAS_INFO_PROP_ALL: + add_info = "GAS_INFO_PROP_ALL"; + break; + case GAS_INFO_PROP_SINGLE: + add_info = "GAS_INFO_PROP_SINGLE"; + break; + default: + add_info = "INVALID"; + break; + } + switch (op) + { + case GAS_OP_SOLVE_START: + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Solver notifies `%s' with result `%s' `%s'\n", "GAS_OP_SOLVE_START", + (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL", add_info); + return; + case GAS_OP_SOLVE_STOP: + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_STOP", + (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL", add_info); + return; + + case GAS_OP_SOLVE_SETUP_START: + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_START", + (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); + return; + + case GAS_OP_SOLVE_SETUP_STOP: + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_STOP", + (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); + return; + + case GAS_OP_SOLVE_MLP_LP_START: + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_START", + (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); + return; + case GAS_OP_SOLVE_MLP_LP_STOP: + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_STOP", + (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); + return; + + case GAS_OP_SOLVE_MLP_MLP_START: + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_START", + (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); + return; + case GAS_OP_SOLVE_MLP_MLP_STOP: + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_STOP", + (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); + return; + case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START: + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START", + (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); + return; + case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP: + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP", + (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL"); + return; + default: + break; + } +} + + +/** + * Callback for solver to notify about assignment changes + * + * @param cls NULL + * @param address the address with changes + */ +static void +bandwidth_changed_cb (void *cls, + struct ATS_Address *address) +{ + uint32_t diff_out; + uint32_t diff_in; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Bandwidth assignment changed for peer %s \n", + GNUNET_i2s (&address->peer)); + + /* Notify performance clients about changes to address */ + GAS_performance_notify_all_clients (&address->peer, + address->plugin, + address->addr, + address->addr_len, + address->active, + address->atsi, + address->atsi_count, + GNUNET_BANDWIDTH_value_init (address->assigned_bw_out), + GNUNET_BANDWIDTH_value_init (address->assigned_bw_in)); + + if ( (0 == address->assigned_bw_in) && + (0 == address->assigned_bw_out) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Telling transport to disconnect peer `%s'\n", + GNUNET_i2s (&address->peer)); + + /* Notify scheduling clients about suggestion */ + GAS_scheduling_transmit_address_suggestion (&address->peer, + address->session_id, + GNUNET_BANDWIDTH_ZERO, + GNUNET_BANDWIDTH_ZERO); + return; + } + + /* Do bandwidth stability check */ + diff_out = abs (address->assigned_bw_out - address->last_notified_bw_out); + diff_in = abs (address->assigned_bw_in - address->last_notified_bw_in); + + if ( (diff_out < htonl(GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__)) && + (diff_in < htonl(GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__)) ) + return; + + GNUNET_log(GNUNET_ERROR_TYPE_INFO, + "Sending bandwidth update for peer `%s': %u %u\n", + GNUNET_i2s (&address->peer), address->assigned_bw_out, + address->assigned_bw_out); + + /* *Notify scheduling clients about suggestion */ + GAS_scheduling_transmit_address_suggestion (&address->peer, + address->session_id, + GNUNET_BANDWIDTH_value_init (address->assigned_bw_out), + GNUNET_BANDWIDTH_value_init (address->assigned_bw_in)); + + address->last_notified_bw_out = address->assigned_bw_out; + address->last_notified_bw_in = address->assigned_bw_in; +} + + +/** + * Load quotas for networks from configuration + * + * @param cfg configuration handle + * @param out_dest where to write outbound quotas + * @param in_dest where to write inbound quotas + * @param dest_length length of inbound and outbound arrays + * @return number of networks loaded + */ +static unsigned int +load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg, + unsigned long long *out_dest, unsigned long long *in_dest, int dest_length) +{ + char * entry_in = NULL; + char * entry_out = NULL; + char * quota_out_str; + char * quota_in_str; + int c; + int res; + + for (c = 0; (c < GNUNET_ATS_NetworkTypeCount) && (c < dest_length); c++) + { + in_dest[c] = 0; + out_dest[c] = 0; + GNUNET_asprintf (&entry_out, + "%s_QUOTA_OUT", + GNUNET_ATS_print_network_type (c)); + GNUNET_asprintf (&entry_in, + "%s_QUOTA_IN", + GNUNET_ATS_print_network_type (c)); + + /* quota out */ + if (GNUNET_OK + == GNUNET_CONFIGURATION_get_value_string (cfg, "ats", entry_out, + "a_out_str)) + { + res = GNUNET_NO; + if (0 == strcmp (quota_out_str, GNUNET_ATS_MaxBandwidthString)) + { + out_dest[c] = GNUNET_ATS_MaxBandwidth; + res = GNUNET_YES; + } + if ((GNUNET_NO == res) + && (GNUNET_OK + == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, + &out_dest[c]))) + res = GNUNET_YES; + if ((GNUNET_NO == res) + && (GNUNET_OK + == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_out, + &out_dest[c]))) + res = GNUNET_YES; + + if (GNUNET_NO == res) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"), + GNUNET_ATS_print_network_type (c), + quota_out_str, + GNUNET_ATS_DefaultBandwidth); + out_dest[c] = GNUNET_ATS_DefaultBandwidth; + } + else + { + GNUNET_log(GNUNET_ERROR_TYPE_INFO, + _("Outbound quota configure for network `%s' is %llu\n"), + GNUNET_ATS_print_network_type (c), + out_dest[c]); + } + GNUNET_free(quota_out_str); + } + else + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + _("No outbound quota configured for network `%s', assigning default bandwidth %llu\n"), + GNUNET_ATS_print_network_type (c), + GNUNET_ATS_DefaultBandwidth); + out_dest[c] = GNUNET_ATS_DefaultBandwidth; + } + + /* quota in */ + if (GNUNET_OK + == GNUNET_CONFIGURATION_get_value_string (cfg, "ats", entry_in, + "a_in_str)) + { + res = GNUNET_NO; + if (0 == strcmp (quota_in_str, GNUNET_ATS_MaxBandwidthString)) + { + in_dest[c] = GNUNET_ATS_MaxBandwidth; + res = GNUNET_YES; + } + if ((GNUNET_NO == res) + && (GNUNET_OK + == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &in_dest[c]))) + res = GNUNET_YES; + if ((GNUNET_NO == res) + && (GNUNET_OK + == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_in, + &in_dest[c]))) + res = GNUNET_YES; + + if (GNUNET_NO == res) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"), + GNUNET_ATS_print_network_type (c), + quota_in_str, + GNUNET_ATS_DefaultBandwidth); + in_dest[c] = GNUNET_ATS_DefaultBandwidth; + } + else + { + GNUNET_log(GNUNET_ERROR_TYPE_INFO, + _("Inbound quota configured for network `%s' is %llu\n"), + GNUNET_ATS_print_network_type (c), + in_dest[c]); + } + GNUNET_free(quota_in_str); + } + else + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + _("No outbound quota configure for network `%s', assigning default bandwidth %llu\n"), + GNUNET_ATS_print_network_type (c), + GNUNET_ATS_DefaultBandwidth); + in_dest[c] = GNUNET_ATS_DefaultBandwidth; + } + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Loaded quota for network `%s' (in/out): %llu %llu\n", + GNUNET_ATS_print_network_type (c), + in_dest[c], + out_dest[c]); + GNUNET_free(entry_out); + GNUNET_free(entry_in); + } + return GNUNET_ATS_NetworkTypeCount; +} + + +/** + * Initialize plugins subsystem. + * + * @param cfg configuration to use + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error (failed to load + * solver plugin) + */ +int +GAS_plugins_init (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + unsigned long long quotas_in[GNUNET_ATS_NetworkTypeCount]; + unsigned long long quotas_out[GNUNET_ATS_NetworkTypeCount]; + char *mode_str; + char *plugin_short; + int c; + + /* Figure out configured solution method */ + if (GNUNET_SYSERR == + GNUNET_CONFIGURATION_get_value_string (cfg, "ats", "MODE", &mode_str)) + { + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, + "No resource assignment method configured, using proportional approach\n"); + ats_mode = MODE_PROPORTIONAL; + } + else + { + for (c = 0; c < strlen (mode_str); c++) + mode_str[c] = toupper (mode_str[c]); + if (0 == strcmp (mode_str, "PROPORTIONAL")) + ats_mode = MODE_PROPORTIONAL; + else if (0 == strcmp (mode_str, "MLP")) + { + ats_mode = MODE_MLP; +#if !HAVE_LIBGLPK + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "Assignment method `%s' configured, but GLPK is not available, please install \n", + mode_str); + ats_mode = MODE_PROPORTIONAL; +#endif + } + else if (0 == strcmp (mode_str, "RIL")) + ats_mode = MODE_RIL; + else + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "Invalid resource assignment method `%s' configured, using proportional approach\n", + mode_str); + ats_mode = MODE_PROPORTIONAL; + } + GNUNET_free(mode_str); + } + + load_quotas (cfg, quotas_out, quotas_in, GNUNET_ATS_NetworkTypeCount); + env.info_cb = &solver_info_cb; + env.info_cb_cls = NULL; + env.bandwidth_changed_cb = &bandwidth_changed_cb; + env.bw_changed_cb_cls = NULL; + env.get_preferences = &GAS_normalization_get_preferences_by_peer; + env.get_preference_cls = NULL; + env.get_property = &GAS_normalization_get_properties; + env.get_property_cls = NULL; + env.cfg = cfg; + env.stats = GSA_stats; + env.addresses = GSA_addresses; + + env.network_count = GNUNET_ATS_NetworkTypeCount; + int networks[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType; + for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++) + { + env.networks[c] = networks[c]; + env.out_quota[c] = quotas_out[c]; + env.in_quota[c] = quotas_in[c]; + } + + switch (ats_mode) { + case MODE_PROPORTIONAL: + plugin_short = "proportional"; + break; + case MODE_MLP: + plugin_short = "mlp"; + break; + case MODE_RIL: + plugin_short = "ril"; + break; + default: + plugin_short = NULL; + break; + } + GNUNET_asprintf (&plugin, + "libgnunet_plugin_ats_%s", + plugin_short); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Initializing solver `%s '`%s'\n", + plugin_short, + plugin); + if (NULL == (solver = GNUNET_PLUGIN_load (plugin, &env))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to initialize solver `%s'!\n"), + plugin); + return GNUNET_SYSERR; + } + + + GNUNET_assert (NULL != env.sf.s_add); + GNUNET_assert (NULL != env.sf.s_address_update_property); + GNUNET_assert (NULL != env.sf.s_get); + GNUNET_assert (NULL != env.sf.s_get_stop); + GNUNET_assert (NULL != env.sf.s_pref); + GNUNET_assert (NULL != env.sf.s_feedback); + GNUNET_assert (NULL != env.sf.s_del); + GNUNET_assert (NULL != env.sf.s_bulk_start); + GNUNET_assert (NULL != env.sf.s_bulk_stop); + + if (NULL == solver) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to initialize solver!\n")); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * Shutdown address subsystem. + */ +void +GAS_plugins_done () +{ + GNUNET_PLUGIN_unload (plugin, + solver); + solver = NULL; + GNUNET_free (plugin); + plugin = NULL; +} + + +void +GAS_plugin_new_address (struct ATS_Address *new_address, + enum GNUNET_ATS_Network_Type addr_net, + const struct GNUNET_ATS_Information *atsi, + uint32_t atsi_count) +{ + env.sf.s_add (solver, new_address, addr_net); + env.sf.s_bulk_start (solver); + GAS_normalization_normalize_property (new_address, + atsi, + atsi_count); + env.sf.s_bulk_stop (solver); +} + + +void +GAS_plugin_update_address (struct ATS_Address *address, + const struct GNUNET_ATS_Information *atsi, + uint32_t atsi_count) +{ + env.sf.s_bulk_start (solver); + GAS_normalization_normalize_property (address, + atsi, + atsi_count); + env.sf.s_bulk_stop (solver); +} + + +void +GAS_plugin_delete_address (struct ATS_Address *address) +{ + env.sf.s_del (solver, address, GNUNET_NO); +} + + +void +GAS_plugin_update_preferences (void *client, + const struct GNUNET_PeerIdentity *peer, + enum GNUNET_ATS_PreferenceKind kind, + float score_abs) +{ + env.sf.s_bulk_start (solver); + /* Tell normalization about change, normalization will call callback if preference changed */ + GAS_normalization_normalize_preference (client, peer, kind, score_abs); + env.sf.s_bulk_stop (solver); +} + + +void +GAS_plugin_preference_feedback (void *application, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_TIME_Relative scope, + enum GNUNET_ATS_PreferenceKind kind, + float score_abs) +{ + env.sf.s_feedback (solver, + application, + peer, + scope, + kind, + score_abs); +} + + +void +GAS_plugin_solver_lock () +{ + env.sf.s_bulk_start (solver); +} + + +void +GAS_plugin_solver_unlock () +{ + env.sf.s_bulk_start (solver); +} + + +void +GAS_plugin_request_connect_start (const struct GNUNET_PeerIdentity *pid) +{ + const struct ATS_Address *aa; + + aa = env.sf.s_get (solver, pid); + if (NULL == aa) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Cannot suggest address for peer `%s'\n", + GNUNET_i2s (pid)); + return; + } + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Suggesting address %p for peer `%s'\n", + aa, + GNUNET_i2s (pid)); + + GAS_scheduling_transmit_address_suggestion (pid, + aa->session_id, + GNUNET_BANDWIDTH_value_init (aa->assigned_bw_out), + GNUNET_BANDWIDTH_value_init (aa->assigned_bw_in)); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Address %p ready for suggestion\n", + aa); +} + + +void +GAS_plugin_request_connect_stop (const struct GNUNET_PeerIdentity *pid) +{ + env.sf.s_get_stop (solver, pid); +} + + +/* end of gnunet-service-ats_plugins.c */ diff --git a/src/ats/gnunet-service-ats_plugins.h b/src/ats/gnunet-service-ats_plugins.h new file mode 100644 index 0000000000..a31024b1b6 --- /dev/null +++ b/src/ats/gnunet-service-ats_plugins.h @@ -0,0 +1,163 @@ +/* + This file is part of GNUnet. + (C) 2011-2014 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file ats/gnunet-service-ats_plugins.h + * @brief ats service plugin management + * @author Matthias Wachs + * @author Christian Grothoff + */ +#ifndef GNUNET_SERVICE_ATS_PLUGINS_H +#define GNUNET_SERVICE_ATS_PLUGINS_H + +#include "gnunet_util_lib.h" +#include "gnunet_ats_service.h" +#include "gnunet-service-ats.h" +#include "gnunet_statistics_service.h" +#include "ats.h" + + +/** + * Available ressource assignment modes + */ +enum ATS_Mode +{ + /** + * proportional mode: + * + * Assign each peer an equal amount of bandwidth (bw) + * + * bw_per_peer = bw_total / #active addresses + */ + MODE_PROPORTIONAL, + + /** + * MLP mode: + * + * Solve ressource assignment as an optimization problem + * Uses an mixed integer programming solver + */ + MODE_MLP, + + /** + * Reinforcement Learning mode: + * + * Solve resource assignment using a learning agent + */ + MODE_RIL +}; + + +/** + * Initialize address subsystem. The addresses subsystem manages the addresses + * known and current performance information. It has a solver component + * responsible for the resource allocation. It tells the solver about changes + * and receives updates when the solver changes the ressource allocation. + * + * @param cfg configuration to use + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error (failed to load + * solver plugin) + */ +int +GAS_plugins_init (const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Shutdown address subsystem. + */ +void +GAS_plugins_done (void); + + +/** + * The preference changed for a peer, update solver. + * + * @param peer the peer + * @param kind the ATS kind + * @param pref_rel the new relative preference value + */ +void +GAS_normalized_preference_changed (const struct GNUNET_PeerIdentity *peer, + enum GNUNET_ATS_PreferenceKind kind, + double pref_rel); + + +/** + * The relative value for a property changed + * + * @param address the peer + * @param type the ATS type + * @param prop_rel the new relative preference value + */ +void +GAS_normalized_property_changed (struct ATS_Address *address, + uint32_t type, + double prop_rel); + + +void +GAS_plugin_new_address (struct ATS_Address *new_address, + enum GNUNET_ATS_Network_Type addr_net, + const struct GNUNET_ATS_Information *atsi, + uint32_t atsi_count); + + +void +GAS_plugin_update_address (struct ATS_Address *address, + const struct GNUNET_ATS_Information *atsi, + uint32_t atsi_count); + + +void +GAS_plugin_update_preferences (void *client, + const struct GNUNET_PeerIdentity *peer, + enum GNUNET_ATS_PreferenceKind kind, + float score_abs); + + +void +GAS_plugin_preference_feedback (void *application, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_TIME_Relative scope, + enum GNUNET_ATS_PreferenceKind kind, + float score_abs); + + +void +GAS_plugin_delete_address (struct ATS_Address *address); + + +void +GAS_plugin_request_connect_start (const struct GNUNET_PeerIdentity *pid); + + +void +GAS_plugin_request_connect_stop (const struct GNUNET_PeerIdentity *pid); + + +void +GAS_plugin_solver_lock (void); + + +void +GAS_plugin_solver_unlock (void); + + +#endif diff --git a/src/ats/gnunet-service-ats_preferences.c b/src/ats/gnunet-service-ats_preferences.c new file mode 100644 index 0000000000..cf0082f9d0 --- /dev/null +++ b/src/ats/gnunet-service-ats_preferences.c @@ -0,0 +1,1004 @@ +/* + This file is part of GNUnet. + (C) 2011-2015 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file ats/gnunet-service-ats_performance.c + * @brief ats service, interaction with 'performance' API + * @author Matthias Wachs + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet-service-ats.h" +#include "gnunet-service-ats_addresses.h" +#include "gnunet-service-ats_performance.h" +#include "gnunet-service-ats_plugins.h" +#include "gnunet-service-ats_preferences.h" +#include "gnunet-service-ats_reservations.h" +#include "ats.h" + +#define LOG(kind,...) GNUNET_log_from (kind, "ats-preferencesx",__VA_ARGS__) + +#define PREF_AGING_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) +#define PREF_AGING_FACTOR 0.95 +#define PREF_EPSILON 0.01 + + +/** + * Relative preferences for a peer + */ +struct PeerRelative +{ + /** + * Relative preference values + */ + double f_rel[GNUNET_ATS_PreferenceCount]; + + /** + * Peer id + */ + struct GNUNET_PeerIdentity id; +}; + + +/** + * FIXME + */ +struct GAS_Addresses_Preference_Clients +{ + /** + * Next in DLL + */ + struct GAS_Addresses_Preference_Clients *next; + + /** + * Previous in DLL + */ + struct GAS_Addresses_Preference_Clients *prev; + + /** + * Peer ID + */ + void *client; +}; + + +/** + * Preference requests DLL head + */ +static struct GAS_Addresses_Preference_Clients *preference_clients_head; + +/** + * Preference requests DLL head + */ +static struct GAS_Addresses_Preference_Clients *preference_clients_tail; + +/** + * Preferences clients + */ +static int pref_clients; + +/** + * Default values + */ +static struct PeerRelative defvalues; + + + +/** + * Preference client + */ +struct PreferenceClient +{ + /** + * Next in DLL + */ + struct PreferenceClient *prev; + + /** + * Next in DLL + */ + + struct PreferenceClient *next; + + /** + * Client handle + */ + void *client; + + /** + * Array of sum of absolute preferences for this client + */ + double f_abs_sum[GNUNET_ATS_PreferenceCount]; + + /** + * Array of sum of relative preferences for this client + */ + double f_rel_sum[GNUNET_ATS_PreferenceCount]; + + /** + * List of peer preferences for this client + */ + + /** + * Head of peer list + */ + struct PreferencePeer *p_head; + + /** + * Tail of peer list + */ + struct PreferencePeer *p_tail; +}; + +/** + * Preference peer + */ +struct PreferencePeer +{ + /** + * Next in DLL + */ + struct PreferencePeer *next; + + /** + * Previous in DLL + */ + struct PreferencePeer *prev; + + /** + * Client + */ + struct PreferenceClient *client; + + /** + * Peer id + */ + struct GNUNET_PeerIdentity id; + + /** + * Absolute preference values for all preference types + */ + double f_abs[GNUNET_ATS_PreferenceCount]; + + /** + * Relative preference values for all preference types + */ + double f_rel[GNUNET_ATS_PreferenceCount]; + + /** + * Absolute point of time of next aging process + */ + struct GNUNET_TIME_Absolute next_aging[GNUNET_ATS_PreferenceCount]; +}; + + +/** + * Hashmap to store peer information for preference normalization + */ +static struct GNUNET_CONTAINER_MultiPeerMap *preference_peers; + + +/** + * Clients in DLL: head + */ +static struct PreferenceClient *pc_head; + +/** + * Clients in DLL: tail + */ +static struct PreferenceClient *pc_tail; + + + +static struct GNUNET_SCHEDULER_Task * aging_task; + + + + +static struct GAS_Addresses_Preference_Clients * +find_preference_client (void *client) +{ + struct GAS_Addresses_Preference_Clients *cur; + + for (cur = preference_clients_head; NULL != cur; cur = cur->next) + if (cur->client == client) + return cur; + return NULL; +} + + +/** + * Update a peer + * + * @param id peer id + * @param kind the kind + * @param rp the relative peer struct + * @return the new relative preference + */ +static void +update_relative_values_for_peer (const struct GNUNET_PeerIdentity *id, + enum GNUNET_ATS_PreferenceKind kind, + struct PeerRelative *rp) +{ + struct PreferenceClient *c_cur; + struct PreferencePeer *p_cur; + double f_rel_total; + double f_rel_sum; + double backup; + unsigned int peer_count; + + f_rel_sum = 0.0; + f_rel_total = 0.0; + peer_count = 0; + + /* For all clients */ + for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) + { + /* For peer entries with this id */ + for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next) + { + f_rel_sum += p_cur->f_rel[kind]; + if (0 == memcmp (id, &p_cur->id, sizeof(struct GNUNET_PeerIdentity))) + { + peer_count ++; + f_rel_total += p_cur->f_rel[kind]; + } + + } + } + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%u clients have a total relative preference for peer `%s' `%s' of %.3f and for %s in total %.3f\n", + peer_count, GNUNET_i2s (id), + GNUNET_ATS_print_preference_type (kind), + f_rel_total, + GNUNET_ATS_print_preference_type (kind), + f_rel_sum); + + /* Find entry for the peer containing relative values in the hashmap */ + if (NULL != rp) + { + backup = rp->f_rel[kind]; + if (f_rel_sum > 0) + rp->f_rel[kind] = f_rel_total / f_rel_sum; + else + { + /* No client had any preferences for this type and any peer */ + rp->f_rel[kind] = DEFAULT_REL_PREFERENCE; + } + if (backup != rp->f_rel[kind]) + GAS_normalized_preference_changed (&rp->id, kind, rp->f_rel[kind]); + } +} + + +static int +update_iterator (void *cls, + const struct GNUNET_PeerIdentity *key, + void *value) +{ + enum GNUNET_ATS_PreferenceKind *kind = cls; + struct PeerRelative *pr = value; + + update_relative_values_for_peer (key, + *kind, + pr); + return GNUNET_OK; +} + + + +/** + * Recalculate preference for a specific ATS property + * + * @param c the preference client + * @param kind the preference kind + * @return the result + */ +static void +recalculate_relative_preferences (struct PreferenceClient *c, + enum GNUNET_ATS_PreferenceKind kind) +{ + struct PreferencePeer *p_cur; + + /* For this client: sum of absolute preference values for this preference */ + c->f_abs_sum[kind] = 0.0; + /* For this client: sum of relative preference values for this preference + * + * Note: this value should also be 1.0, but: + * if no preferences exist due to aging, this value can be 0.0 + * and the client can be removed */ + c->f_rel_sum[kind] = 0.0; + + for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next) + c->f_abs_sum[kind] += p_cur->f_abs[kind]; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Client %p has sum of total preferences for %s of %.3f\n", + c->client, GNUNET_ATS_print_preference_type (kind), c->f_abs_sum[kind]); + + /* For all peers: calculate relative preference */ + for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next) + { + /* Calculate relative preference for specific kind */ + + /* Every application has a preference for each peer between + * [0 .. 1] in relative values + * and [0 .. inf] in absolute values */ + p_cur->f_rel[kind] = p_cur->f_abs[kind] / c->f_abs_sum[kind]; + c->f_rel_sum[kind] += p_cur->f_rel[kind]; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Client %p has relative preference for %s for peer `%s' of %.3f\n", + c->client, + GNUNET_ATS_print_preference_type (kind), + GNUNET_i2s (&p_cur->id), + p_cur->f_rel[kind]); + } + +} + + + +static void +run_preference_update (struct PreferenceClient *c_cur, + struct PreferencePeer *p_cur, + enum GNUNET_ATS_PreferenceKind kind, + float score_abs) +{ + double old_value; + + /* Update relative value */ + old_value = p_cur->f_rel[kind]; + recalculate_relative_preferences (c_cur, kind); + if (p_cur->f_rel[kind] == old_value) + return; + + /* Relative preference value changed, recalculate for all peers */ + GNUNET_CONTAINER_multipeermap_iterate (preference_peers, + &update_iterator, + &kind); +} + + + + +/** + * Reduce absolute preferences since they got old + * + * @param cls the PreferencePeer + * @param tc context + */ +static void +preference_aging (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct PreferencePeer *p; + struct PreferenceClient *cur_client; + int i; + int values_to_update; + double backup; + + aging_task = NULL; + values_to_update = 0; + cur_client = NULL; + + for (cur_client = pc_head; NULL != cur_client; cur_client = cur_client->next) + { + for (p = cur_client->p_head; NULL != p; p = p->next) + { + /* Aging absolute values: */ + for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) + { + if (0 + == GNUNET_TIME_absolute_get_remaining (p->next_aging[i]).rel_value_us) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Aging preference for peer `%s'\n", GNUNET_i2s (&p->id)); + backup = p->f_abs[i]; + if (p->f_abs[i] > DEFAULT_ABS_PREFERENCE) + p->f_abs[i] *= PREF_AGING_FACTOR; + + if (p->f_abs[i] <= DEFAULT_ABS_PREFERENCE + PREF_EPSILON) + p->f_abs[i] = DEFAULT_ABS_PREFERENCE; + + if ( (p->f_abs[i] != DEFAULT_ABS_PREFERENCE) && + (backup != p->f_abs[i]) ) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Aged preference for peer `%s' from %.3f to %.3f\n", + GNUNET_i2s (&p->id), backup, p->f_abs[i]); + + run_preference_update(cur_client, p, i, p->f_abs[i]); + + p->next_aging[i] = GNUNET_TIME_absolute_add ( + GNUNET_TIME_absolute_get (), PREF_AGING_INTERVAL); + values_to_update++; + } + } + } + } + } + + if (values_to_update > 0) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Rescheduling aging task due to %u elements to age\n", + values_to_update); + aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL, + &preference_aging, NULL ); + } + else + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "No values to age left, not rescheduling aging task\n"); + +} + + +/** + * Update the absolute preference value for a peer + * @param c the client + * @param p the peer + * @param kind the preference kind + * @param score_abs the absolute value + * @return the new relative preference value + */ +static void +update_abs_preference (struct PreferenceClient *c, + struct PreferencePeer *p, + enum GNUNET_ATS_PreferenceKind kind, + float score_abs) +{ + double score = score_abs; + + /* Update preference value according to type */ + switch (kind) + { + case GNUNET_ATS_PREFERENCE_BANDWIDTH: + case GNUNET_ATS_PREFERENCE_LATENCY: + p->f_abs[kind] = score; + /* p->f_abs[kind] = (p->f_abs[kind] + score) / 2; */ + p->next_aging[kind] = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), + PREF_AGING_INTERVAL); + break; + case GNUNET_ATS_PREFERENCE_END: + break; + default: + break; + } +} + + + + + +/** + * A performance client disconnected + * + * @param client the client + */ +void +GAS_addresses_preference_client_disconnect (void *client) +{ + struct GAS_Addresses_Preference_Clients *pc; + + if (NULL != (pc = find_preference_client (client))) + { + GNUNET_CONTAINER_DLL_remove (preference_clients_head, + preference_clients_tail, + pc); + GNUNET_free (pc); + GNUNET_assert (pref_clients > 0); + pref_clients --; + GNUNET_STATISTICS_set (GSA_stats, + "# active performance clients", + pref_clients, + GNUNET_NO); + } +} + + + +/** + * Change the preference for a peer + * + * @param client the client sending this request + * @param peer the peer id + * @param kind the preference kind to change + * @param score_abs the new preference score + */ +void +GAS_addresses_preference_change (void *client, + const struct GNUNET_PeerIdentity *peer, + enum GNUNET_ATS_PreferenceKind kind, + float score_abs) +{ + struct GAS_Addresses_Preference_Clients *pc; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Received `%s' for peer `%s' for client %p\n", "CHANGE PREFERENCE", + GNUNET_i2s (peer), client); + + if (GNUNET_NO == + GNUNET_CONTAINER_multipeermap_contains (GSA_addresses, + peer)) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Received `%s' for unknown peer `%s' from client %p\n", + "CHANGE PREFERENCE", GNUNET_i2s (peer), client); + return; + } + + if (NULL == find_preference_client (client)) + { + pc = GNUNET_new (struct GAS_Addresses_Preference_Clients); + pc->client = client; + GNUNET_CONTAINER_DLL_insert (preference_clients_head, + preference_clients_tail, + pc); + pref_clients ++; + GNUNET_STATISTICS_set (GSA_stats, + "# active performance clients", + pref_clients, + GNUNET_NO); + } + GAS_plugin_update_preferences (client, peer, kind, score_abs); +} + + +/** + * Handle 'preference change' messages from clients. + * + * @param cls unused, NULL + * @param client client that sent the request + * @param message the request message + */ +void +GAS_handle_preference_change (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + const struct ChangePreferenceMessage *msg; + const struct PreferenceInformation *pi; + uint16_t msize; + uint32_t nump; + uint32_t i; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received `%s' message\n", + "PREFERENCE_CHANGE"); + msize = ntohs (message->size); + if (msize < sizeof (struct ChangePreferenceMessage)) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + msg = (const struct ChangePreferenceMessage *) message; + nump = ntohl (msg->num_preferences); + if (msize != + sizeof (struct ChangePreferenceMessage) + + nump * sizeof (struct PreferenceInformation)) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + GNUNET_STATISTICS_update (GSA_stats, + "# preference change requests processed", + 1, GNUNET_NO); + pi = (const struct PreferenceInformation *) &msg[1]; + for (i = 0; i < nump; i++) + GAS_addresses_preference_change (client, + &msg->peer, + (enum GNUNET_ATS_PreferenceKind) + ntohl (pi[i].preference_kind), + pi[i].preference_value); + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} + + + + +/** + * Change the preference for a peer + * + * @param application the client sending this request + * @param peer the peer id + * @param scope the time interval for this feedback: [now - scope .. now] + * @param kind the preference kind to change + * @param score_abs the new preference score + */ +void +GAS_addresses_preference_feedback (void *application, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_TIME_Relative scope, + enum GNUNET_ATS_PreferenceKind kind, + float score_abs) +{ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Received `%s' for peer `%s' for client %p\n", + "PREFERENCE FEEDBACK", + GNUNET_i2s (peer), + application); + + if (GNUNET_NO == + GNUNET_CONTAINER_multipeermap_contains (GSA_addresses, + peer)) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Received `%s' for unknown peer `%s' from client %p\n", + "PREFERENCE FEEDBACK", + GNUNET_i2s (peer), + application); + return; + } + + GAS_plugin_preference_feedback (application, + peer, + scope, + kind, + score_abs); +} + + +/** + * Handle 'preference feedback' messages from clients. + * + * @param cls unused, NULL + * @param client client that sent the request + * @param message the request message + */ +void +GAS_handle_preference_feedback (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + const struct FeedbackPreferenceMessage *msg; + const struct PreferenceInformation *pi; + uint16_t msize; + uint32_t nump; + uint32_t i; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received `%s' message\n", + "PREFERENCE_FEEDBACK"); + msize = ntohs (message->size); + if (msize < sizeof (struct FeedbackPreferenceMessage)) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + msg = (const struct FeedbackPreferenceMessage *) message; + nump = ntohl (msg->num_feedback); + if (msize != + sizeof (struct FeedbackPreferenceMessage) + + nump * sizeof (struct PreferenceInformation)) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + GNUNET_STATISTICS_update (GSA_stats, + "# preference feedbacks requests processed", + 1, GNUNET_NO); + pi = (const struct PreferenceInformation *) &msg[1]; + for (i = 0; i < nump; i++) + GAS_addresses_preference_feedback (client, + &msg->peer, + GNUNET_TIME_relative_ntoh(msg->scope), + (enum GNUNET_ATS_PreferenceKind) + ntohl (pi[i].preference_kind), + pi[i].preference_value); + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} + + +/** + * Shutdown preferences subsystem. + */ +void +GAS_preference_init () +{ + int i; + + preference_peers = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); + for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) + defvalues.f_rel[i] = DEFAULT_REL_PREFERENCE; + +} + + +/** + * Free a peer + * + * @param cls unused + * @param key the key + * @param value RelativePeer + * @return #GNUNET_OK to continue + */ +static int +free_peer (void *cls, const struct GNUNET_PeerIdentity *key, void *value) +{ + struct PeerRelative *rp = value; + if (GNUNET_YES + == GNUNET_CONTAINER_multipeermap_remove (preference_peers, key, value)) + GNUNET_free(rp); + else + GNUNET_break(0); + return GNUNET_OK; +} + + +static void +free_client (struct PreferenceClient *pc) +{ + struct PreferencePeer *next_p; + struct PreferencePeer *p; + next_p = pc->p_head; + while (NULL != (p = next_p)) + { + next_p = p->next; + GNUNET_CONTAINER_DLL_remove(pc->p_head, pc->p_tail, p); + GNUNET_free(p); + } + GNUNET_free(pc); +} + + + + + +/** + * Shutdown preferences subsystem. + */ +void +GAS_preference_done () +{ + struct GAS_Addresses_Preference_Clients *pcur; + struct PreferenceClient *pc; + struct PreferenceClient *next_pc; + + if (NULL != aging_task) + { + GNUNET_SCHEDULER_cancel (aging_task); + aging_task = NULL; + } + + next_pc = pc_head; + while (NULL != (pc = next_pc)) + { + next_pc = pc->next; + GNUNET_CONTAINER_DLL_remove(pc_head, pc_tail, pc); + free_client (pc); + } + + GNUNET_CONTAINER_multipeermap_iterate (preference_peers, + &free_peer, NULL); + GNUNET_CONTAINER_multipeermap_destroy (preference_peers); + + while (NULL != (pcur = preference_clients_head)) + { + GNUNET_CONTAINER_DLL_remove (preference_clients_head, + preference_clients_tail, + pcur); + GNUNET_assert (pref_clients > 0); + pref_clients --; + GNUNET_STATISTICS_set (GSA_stats, + "# active performance clients", + pref_clients, + GNUNET_NO); + GNUNET_free (pcur); + } +} + + + + +/** + * Normalize an updated preference value + * + * @param client the client with this preference + * @param peer the peer to change the preference for + * @param kind the kind to change the preference + * @param score_abs the normalized score + */ +void +GAS_normalization_normalize_preference (void *client, + const struct GNUNET_PeerIdentity *peer, + enum GNUNET_ATS_PreferenceKind kind, + float score_abs) +{ + struct PreferenceClient *c_cur; + struct PreferencePeer *p_cur; + struct PeerRelative *r_cur; + double old_value; + int i; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Client changes preference for peer `%s' for `%s' to %.2f\n", + GNUNET_i2s (peer), + GNUNET_ATS_print_preference_type (kind), + score_abs); + + if (kind >= GNUNET_ATS_PreferenceCount) + { + GNUNET_break(0); + return; + } + + /* Find preference client */ + for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) + { + if (client == c_cur->client) + break; + } + /* Not found: create new preference client */ + if (NULL == c_cur) + { + c_cur = GNUNET_new (struct PreferenceClient); + c_cur->client = client; + for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) + { + c_cur->f_abs_sum[i] = DEFAULT_ABS_PREFERENCE; + c_cur->f_rel_sum[i] = DEFAULT_REL_PREFERENCE; + } + + GNUNET_CONTAINER_DLL_insert(pc_head, pc_tail, c_cur); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding new client %p \n", c_cur); + } + + /* Find entry for peer */ + for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next) + if (0 == memcmp (&p_cur->id, peer, sizeof(p_cur->id))) + break; + + /* Not found: create new peer entry */ + if (NULL == p_cur) + { + p_cur = GNUNET_new (struct PreferencePeer); + p_cur->client = c_cur; + p_cur->id = (*peer); + for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) + { + /* Default value per peer absolute preference for a preference: 0 */ + p_cur->f_abs[i] = DEFAULT_ABS_PREFERENCE; + /* Default value per peer relative preference for a quality: 1.0 */ + p_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; + p_cur->next_aging[i] = GNUNET_TIME_UNIT_FOREVER_ABS; + } + LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding new peer %p for client %p \n", + p_cur, c_cur); + GNUNET_CONTAINER_DLL_insert(c_cur->p_head, c_cur->p_tail, p_cur); + } + + /* Create struct for peer */ + if (NULL == GNUNET_CONTAINER_multipeermap_get (preference_peers, peer)) + { + r_cur = GNUNET_new (struct PeerRelative); + r_cur->id = (*peer); + for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) + r_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; + GNUNET_assert( + GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (preference_peers, + &r_cur->id, r_cur, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); + } + + /* Update absolute value */ + old_value = p_cur->f_abs[kind]; + update_abs_preference (c_cur, p_cur, kind, score_abs); + if (p_cur->f_abs[kind] == old_value) + return; + + run_preference_update (c_cur, p_cur, kind, score_abs); + + /* Start aging task */ + if (NULL == aging_task) + aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL, + &preference_aging, NULL ); + +} + + +/** + * Get the normalized preference values for a specific peer or + * the default values if + * + * @param cls ignored + * @param id the peer + * @return pointer to the values, can be indexed with GNUNET_ATS_PreferenceKind, + * default preferences if peer does not exist + */ +const double * +GAS_normalization_get_preferences_by_peer (void *cls, + const struct GNUNET_PeerIdentity *id) +{ + GNUNET_assert(NULL != preference_peers); + GNUNET_assert(NULL != id); + + struct PeerRelative *rp; + if (NULL == (rp = GNUNET_CONTAINER_multipeermap_get (preference_peers, id))) + { + return defvalues.f_rel; + } + return rp->f_rel; +} + + +/** + * Get the normalized preference values for a specific client and peer + * + * @param client client + * @param peer the peer + * @param pref the preference type + * @return the value + */ +double +GAS_normalization_get_preferences_by_client (const void *client, + const struct GNUNET_PeerIdentity *peer, + enum GNUNET_ATS_PreferenceKind pref) +{ + struct PreferenceClient *c_cur; + struct PreferencePeer *p_cur; + + /* Find preference client */ + for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) + { + if (client == c_cur->client) + break; + } + if (NULL == c_cur) + return -1.0; + + for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next) + { + if (0 == memcmp (peer, &p_cur->id, sizeof (struct GNUNET_PeerIdentity))) + break; + } + if (NULL == p_cur) + return DEFAULT_REL_PREFERENCE; /* Not found, return default */ + + return p_cur->f_rel[pref]; +} + + + +/** + * A performance client disconnected + * + * @param client the client + */ +void +GAS_normalization_preference_client_disconnect (void *client) +{ + struct PreferenceClient *c_cur; + /* Find preference client */ + + for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) + { + if (client == c_cur->client) + break; + } + if (NULL == c_cur) + return; + + GNUNET_CONTAINER_DLL_remove(pc_head, pc_tail, c_cur); + free_client (c_cur); +} + diff --git a/src/ats/gnunet-service-ats_preferences.h b/src/ats/gnunet-service-ats_preferences.h new file mode 100644 index 0000000000..bab604d214 --- /dev/null +++ b/src/ats/gnunet-service-ats_preferences.h @@ -0,0 +1,101 @@ +/* + This file is part of GNUnet. + (C) 2011-2014 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file ats/gnunet-service-ats_preferences.h + * @brief FIXME + * @author Matthias Wachs + * @author Christian Grothoff + */ +#ifndef GNUNET_SERVICE_ATS_PREFERENCES_H +#define GNUNET_SERVICE_ATS_PREFERENCES_H + +#include "gnunet_util_lib.h" +#include "gnunet_ats_service.h" +#include "gnunet-service-ats.h" +#include "gnunet_statistics_service.h" +#include "ats.h" + + +#define DEFAULT_ABS_PREFERENCE 0.0 + +#define DEFAULT_REL_PREFERENCE 0.0 + + + + +/** + * A preference client disconnected + * + * @param client the client; FIXME: type!? + */ +void +GAS_addresses_preference_client_disconnect (void *client); + + + + +/** + * Change the preference for a peer + * + * @param client the client sending this request; FIXME: type!? + * @param peer the peer id + * @param kind the preference kind to change + * @param score_abs the new preference score + */ +void +GAS_addresses_preference_change (void *client, + const struct GNUNET_PeerIdentity *peer, + enum GNUNET_ATS_PreferenceKind kind, + float score_abs); + + +/** + * Application feedback on how good preference requirements are fulfilled + * for a specific preference in the given time scope [now - scope .. now] + * + * An application notifies ATS if (and only if) it has feedback information + * for a specific property. This value is valid until the feedback score is + * updated by the application. + * + * If the application has no feedback for this preference kind the application + * will not explicitly call. + * + * @param application the application sending this request; FIXME: type? + * @param peer the peer id + * @param scope the time interval this valid for: [now - scope .. now] + * @param kind the preference kind this feedback is intended for + * @param score_abs the new preference score + */ +void +GAS_addresses_preference_feedback (void *application, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_TIME_Relative scope, + enum GNUNET_ATS_PreferenceKind kind, + float score_abs); + +/** + * Shutdown preferences subsystem. + */ +void +GAS_preference_done (void); + + +#endif diff --git a/src/ats/gnunet-service-ats_scheduling.c b/src/ats/gnunet-service-ats_scheduling.c index 9d7562e7b7..e1e60c063e 100644 --- a/src/ats/gnunet-service-ats_scheduling.c +++ b/src/ats/gnunet-service-ats_scheduling.c @@ -99,7 +99,8 @@ GAS_scheduling_transmit_address_suggestion (const struct GNUNET_PeerIdentity *pe if (NULL == my_client) return; GNUNET_STATISTICS_update (GSA_stats, - "# address suggestions made", 1, + "# address suggestions made", + 1, GNUNET_NO); msg.header.size = htons (sizeof (struct AddressSuggestionMessage)); msg.header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION); @@ -179,7 +180,7 @@ GAS_handle_address_add (void *cls, plugin_name, address, address_length, - ntohl(m->address_local_info), + ntohl (m->address_local_info), ntohl (m->session_id), atsi, ats_count); GNUNET_SERVER_receive_done (client, GNUNET_OK); diff --git a/src/ats/gnunet-service-ats_scheduling.h b/src/ats/gnunet-service-ats_scheduling.h index fe8adc8c5a..eab9819cfa 100644 --- a/src/ats/gnunet-service-ats_scheduling.h +++ b/src/ats/gnunet-service-ats_scheduling.h @@ -51,19 +51,6 @@ GAS_scheduling_remove_client (struct GNUNET_SERVER_Client *client); /** - * Handle 'reset backoff' messages from clients. - * - * @param cls unused, NULL - * @param client client that sent the request - * @param message the request message - */ -void -GAS_handle_reset_backoff (void *cls, - struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message); - - -/** * Transmit the given address suggestion and bandwidth update to all scheduling * clients. * @@ -106,19 +93,6 @@ GAS_handle_address_update (void *cls, /** - * Handle 'address in use' messages from clients. - * - * @param cls unused, NULL - * @param client client that sent the request - * @param message the request message - */ -void -GAS_handle_address_in_use (void *cls, - struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message); - - -/** * Handle 'address destroyed' messages from clients. * * @param cls unused, NULL diff --git a/src/ats/perf_ats_solver.c b/src/ats/perf_ats_solver.c index d25d5da58b..769acea99c 100644 --- a/src/ats/perf_ats_solver.c +++ b/src/ats/perf_ats_solver.c @@ -27,6 +27,7 @@ #include "gnunet_util_lib.h" #include "gnunet_statistics_service.h" #include "gnunet-service-ats_addresses.h" +#include "gnunet-service-ats_plugins.h" #include "gnunet-service-ats_normalization.h" #include "gnunet_ats_service.h" #include "gnunet_ats_plugin.h" @@ -40,6 +41,11 @@ /** + * Handle for statistics. + */ +struct GNUNET_STATISTICS_Handle *GSA_stats; + +/** * Handle for ATS address component */ struct PerfHandle @@ -385,7 +391,6 @@ perf_update_address (struct ATS_Address *cur) default: break; } - ph.env.sf.s_address_update_inuse (ph.solver, cur, GNUNET_YES); } @@ -411,22 +416,17 @@ bandwidth_changed_cb (void *cls, const double * get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id) { - return GAS_normalization_get_preferences_by_peer (id); + return GAS_normalization_get_preferences_by_peer (NULL, id); } const double * get_property_cb (void *cls, const struct ATS_Address *address) { - return GAS_normalization_get_properties ((struct ATS_Address *) address); + return GAS_normalization_get_properties (NULL, + address); } -static void -normalized_property_changed_cb (void *cls, struct ATS_Address *peer, - uint32_t type, double prop_rel) -{ - /* TODO */ -} static void perf_address_initial_update (void *solver, @@ -1284,7 +1284,7 @@ run (void *cls, char * const *args, const char *cfgfile, ph.env.out_quota[c], ph.env.in_quota[c]); } - GAS_normalization_start (NULL, NULL, &normalized_property_changed_cb, NULL ); + GAS_normalization_start (); GNUNET_asprintf (&plugin, "libgnunet_plugin_ats_%s", ph.ats_string); GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Initializing solver `%s'\n"), ph.ats_string); diff --git a/src/ats/plugin_ats_mlp.c b/src/ats/plugin_ats_mlp.c index 15fa5e6bd4..eeffb3454a 100644 --- a/src/ats/plugin_ats_mlp.c +++ b/src/ats/plugin_ats_mlp.c @@ -2043,131 +2043,6 @@ GAS_mlp_address_property_changed (void *solver, /** - * Transport session for this address has changed - * - * NOTE: values in addresses are already updated - * - * @param solver solver handle - * @param address the address - * @param cur_session the current session - * @param new_session the new session - */ -static void -GAS_mlp_address_session_changed (void *solver, - struct ATS_Address *address, - uint32_t cur_session, - uint32_t new_session) -{ - /* Nothing to do here */ - return; -} - - -/** - * Network scope for this address has changed - * - * NOTE: values in addresses are already updated - * - * @param solver solver handle - * @param address the address - * @param current_network the current network - * @param new_network the new network - */ -static void -GAS_mlp_address_change_network (void *solver, - struct ATS_Address *address, - uint32_t current_network, - uint32_t new_network) -{ - struct MLP_information *mlpi = address->solver_information; - struct GAS_MLP_Handle *mlp = solver; - int nets_avail[] = GNUNET_ATS_NetworkType; - int c1; - - GNUNET_assert (NULL != solver); - GNUNET_assert (NULL != address); - - if (GNUNET_ATS_NetworkTypeCount <= new_network) - { - GNUNET_break (0); - return; - } - - if (NULL == mlpi) - { - GNUNET_break (0); - return; - } - - if (mlpi->c_b == MLP_UNDEFINED) - return; /* This address is not yet in the matrix*/ - - if (NULL == - GNUNET_CONTAINER_multipeermap_get (mlp->requested_peers, - &address->peer)) - { - /* Peer is not requested, so no need to update problem */ - GNUNET_break (0); - return; - } - - if (current_network == new_network) - { - GNUNET_break (0); - return; - } - - for (c1 = 0; c1 < GNUNET_ATS_NetworkTypeCount ; c1 ++) - { - if (nets_avail[c1] == new_network) - break; - } - - if (GNUNET_ATS_NetworkTypeCount == c1) - { - /* Invalid network */ - GNUNET_break (0); - return; - } - - LOG (GNUNET_ERROR_TYPE_DEBUG, "Updating network for peer `%s' from `%s' to `%s'\n", - GNUNET_i2s (&address->peer), - GNUNET_ATS_print_network_type(current_network), - GNUNET_ATS_print_network_type(new_network)); - - for (c1 = 0; c1 < GNUNET_ATS_NetworkTypeCount; c1++) - { - if (mlp->pv.quota_index[c1] == current_network) - { - /* Remove from old network */ - mlp_create_problem_update_value (&mlp->p, - mlp->p.r_quota[c1], - mlpi->c_b, 0.0, __LINE__); - break; - } - } - - for (c1 = 0; c1 < GNUNET_ATS_NetworkTypeCount; c1++) - { - if (mlp->pv.quota_index[c1] == new_network) - { - /* Remove from old network */ - if (GNUNET_SYSERR == mlp_create_problem_update_value (&mlp->p, - mlp->p.r_quota[c1], - mlpi->c_b, 1.0, __LINE__)) - { - /* This quota did not exist in the problem, recreate */ - GNUNET_break (0); - } - break; - } - } - - mlp->stat_mlp_prob_changed = GNUNET_YES; -} - - -/** * Find the active address in the set of addresses of a peer * @param cls destination * @param key peer id @@ -2953,8 +2828,6 @@ libgnunet_plugin_ats_mlp_init (void *cls) mlp->env = env; env->sf.s_add = &GAS_mlp_address_add; env->sf.s_address_update_property = &GAS_mlp_address_property_changed; - env->sf.s_address_update_session = &GAS_mlp_address_session_changed; - env->sf.s_address_update_network = &GAS_mlp_address_change_network; env->sf.s_get = &GAS_mlp_get_preferred_address; env->sf.s_get_stop = &GAS_mlp_stop_get_preferred_address; env->sf.s_pref = &GAS_mlp_address_change_preference; diff --git a/src/ats/plugin_ats_proportional.c b/src/ats/plugin_ats_proportional.c index 7bcc948b7e..cc5a55ebb6 100644 --- a/src/ats/plugin_ats_proportional.c +++ b/src/ats/plugin_ats_proportional.c @@ -713,7 +713,6 @@ find_best_address_it (void *cls, struct FindBestAddressCtx *ctx = cls; struct ATS_Address *current = value; struct ATS_Address *current_best = current; - struct GNUNET_TIME_Absolute now; struct AddressSolverInformation *asi; struct GNUNET_TIME_Relative active_time; struct GNUNET_TIME_Relative min_active_time; @@ -727,20 +726,6 @@ find_best_address_it (void *cls, current_best = NULL; asi = current->solver_information; - now = GNUNET_TIME_absolute_get (); - - if ((current->active == GNUNET_NO) - && (current->blocked_until.abs_value_us - == GNUNET_TIME_absolute_max (now, current->blocked_until).abs_value_us)) - { - /* This address is blocked for suggestion */ - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Address %p blocked for suggestion for %s \n", - current, - GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_difference (now, current->blocked_until), - GNUNET_YES)); - return GNUNET_OK; - } if (NULL == asi) { GNUNET_break (0); @@ -1695,143 +1680,6 @@ GAS_proportional_address_property_changed (void *solver, } } -/** - * Transport session for this address has changed - * - * NOTE: values in addresses are already updated - * - * @param solver solver handle - * @param address the address - * @param cur_session the current session - * @param new_session the new session - */ -static void -GAS_proportional_address_session_changed (void *solver, - struct ATS_Address *address, - uint32_t cur_session, - uint32_t new_session) -{ - struct GAS_PROPORTIONAL_Handle *s = solver; - struct ATS_Address *best_address; - struct ATS_Address *active_address; - struct AddressSolverInformation *asi; - - if (cur_session != new_session) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Session changed from %u to %u\n", - cur_session, - new_session); - } - - if (NULL == address->solver_information) - { - GNUNET_break (0); - return; - } - - if (GNUNET_NO == - GNUNET_CONTAINER_multipeermap_contains (s->requests, &address->peer)) - return; /* Peer is not requested */ - - /* This peer is requested, find active and best address */ - active_address = get_active_address (s, s->addresses, &address->peer); - best_address = update_active_address (s, &address->peer); - - if ((NULL != best_address) && ((NULL != active_address) && - (GNUNET_YES == address_eq (active_address, best_address)))) - { - asi = best_address->solver_information; - GNUNET_assert (NULL != asi); - - /* We sticked to the same address, therefore redistribute */ - distribute_bandwidth_in_network (s, asi->network); - } -} - - -/** - * Network scope for this address has changed - * - * NOTE: values in addresses are already updated - * - * @param solver solver handle - * @param address the address - * @param current_network the current network - * @param new_network the new network - */ -static void -GAS_proportional_address_change_network (void *solver, - struct ATS_Address *address, - uint32_t current_network, - uint32_t new_network) -{ - struct GAS_PROPORTIONAL_Handle *s = solver; - struct AddressSolverInformation *asi; - int save_active = GNUNET_NO; - - if (current_network == new_network) - { - GNUNET_break(0); - return; - } - - asi = address->solver_information; - if (NULL == asi) - { - GNUNET_break(0); - return; - } - - /* Network changed */ - LOG(GNUNET_ERROR_TYPE_DEBUG, - "Network type changed, moving %s address from `%s' to `%s'\n", - (GNUNET_YES == address->active) ? "active" : "inactive", - GNUNET_ATS_print_network_type (current_network), - GNUNET_ATS_print_network_type (new_network)); - - - /* Start bulk to prevent disconnect */ - GAS_proportional_bulk_start(s); - - save_active = address->active; - - /* Disable and assign no bandwidth */ - address->active = GNUNET_NO; - address->assigned_bw_in = 0; /* no bandwidth assigned */ - address->assigned_bw_out = 0; /* no bandwidth assigned */ - - /* Remove from old network */ - GAS_proportional_address_delete (solver, address, GNUNET_NO); - - /* Set new network type */ - if (NULL == get_network (solver, new_network)) - { - /* Address changed to invalid network... */ - LOG(GNUNET_ERROR_TYPE_ERROR, - _("Invalid network type `%u' `%s': Disconnect!\n"), new_network, - GNUNET_ATS_print_network_type (new_network)); - s->bw_changed (s->bw_changed_cls, address); - } - else - { - /* Add to new network and update*/ - GAS_proportional_address_add (solver, address, new_network); - } - GAS_proportional_bulk_stop (s); - - if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (s->requests, &address->peer)) - return; /* Peer is not requested */ - - /* Find new address to suggest */ - if (GNUNET_YES == save_active) - { - /* No address available, therefore disconnect */ - if (NULL == update_active_address (s, &address->peer)) - s->bw_changed (s->bw_changed_cls, address); - } - -} /** * Add a new single address to a network @@ -1914,8 +1762,6 @@ libgnunet_plugin_ats_proportional_init (void *cls) s->env = env; env->sf.s_add = &GAS_proportional_address_add; env->sf.s_address_update_property = &GAS_proportional_address_property_changed; - env->sf.s_address_update_session = &GAS_proportional_address_session_changed; - env->sf.s_address_update_network = &GAS_proportional_address_change_network; env->sf.s_get = &GAS_proportional_get_preferred_address; env->sf.s_get_stop = &GAS_proportional_stop_get_preferred_address; env->sf.s_pref = &GAS_proportional_address_change_preference; diff --git a/src/ats/plugin_ats_ril.c b/src/ats/plugin_ats_ril.c index 5c396e82ee..31bed2a270 100644 --- a/src/ats/plugin_ats_ril.c +++ b/src/ats/plugin_ats_ril.c @@ -2386,74 +2386,6 @@ GAS_ril_address_property_changed (void *solver, /** - * Update the session of an address in the solver - * - * NOTE: values in addresses are already updated - * - * @param solver solver handle - * @param address the address - * @param cur_session the current session - * @param new_session the new session - */ -static void -GAS_ril_address_session_changed (void *solver, - struct ATS_Address *address, - uint32_t cur_session, - uint32_t new_session) -{ - LOG(GNUNET_ERROR_TYPE_DEBUG, - "API_address_session_changed()\n"); -} - - -/** - * Notify solver that the network an address is located in has changed - * - * NOTE: values in addresses are already updated - * - * @param solver solver handle - * @param address the address - * @param current_network the current network - * @param new_network the new network - */ -static void -GAS_ril_address_change_network (void *solver, - struct ATS_Address *address, - uint32_t current_network, - uint32_t new_network) -{ - struct GAS_RIL_Handle *s = solver; - struct RIL_Peer_Agent *agent; - - LOG(GNUNET_ERROR_TYPE_DEBUG, - "API_address_change_network() Network type changed, moving " - "%s address of peer %s from '%s' to '%s'\n", - (GNUNET_YES == address->active) ? "active" : "inactive", GNUNET_i2s (&address->peer), - GNUNET_ATS_print_network_type (current_network), GNUNET_ATS_print_network_type (new_network)); - - s->parameters.temperature = s->parameters.temperature_init; - s->parameters.epsilon = s->parameters.epsilon_init; - - if (address->active && !ril_network_is_active (solver, new_network)) - { - GAS_ril_address_delete (solver, address, GNUNET_NO); - return; - } - - agent = ril_get_agent (s, &address->peer, GNUNET_NO); - if (NULL == agent) - { - GNUNET_assert(!ril_network_is_active (solver, current_network)); - - GAS_ril_address_add (s, address, new_network); - return; - } - - address->solver_information = ril_get_network(solver, new_network); -} - - -/** * Give feedback about the current assignment * * @param solver the solver handle @@ -2850,8 +2782,6 @@ libgnunet_plugin_ats_ril_init (void *cls) env->sf.s_add = &GAS_ril_address_add; env->sf.s_address_update_property = &GAS_ril_address_property_changed; - env->sf.s_address_update_session = &GAS_ril_address_session_changed; - env->sf.s_address_update_network = &GAS_ril_address_change_network; env->sf.s_get = &GAS_ril_get_preferred_address; env->sf.s_get_stop = &GAS_ril_stop_get_preferred_address; env->sf.s_pref = &GAS_ril_address_change_preference; diff --git a/src/include/gnunet_ats_plugin.h b/src/include/gnunet_ats_plugin.h index 02875a0707..e2272fdc89 100644 --- a/src/include/gnunet_ats_plugin.h +++ b/src/include/gnunet_ats_plugin.h @@ -128,34 +128,6 @@ typedef void struct ATS_Address *address, uint32_t type, uint32_t abs_value, double rel_value); -/** - * Transport session for this address has changed - * - * NOTE: values in addresses are already updated - * - * @param solver solver handle - * @param address the address - * @param cur_session the current session - * @param new_session the new session - */ -typedef void -(*GAS_solver_address_session_changed) (void *solver, - struct ATS_Address *address, uint32_t cur_session, uint32_t new_session); - - -/** - * Network scope for this address has changed - * - * NOTE: values in addresses are already updated - * - * @param solver solver handle - * @param address the address - * @param current_network the current network - * @param new_network the new network - */ -typedef void -(*GAS_solver_address_network_changed) (void *solver, - struct ATS_Address *address, uint32_t current_network, uint32_t new_network); /** * Get the prefered address for a peer from solver @@ -201,16 +173,6 @@ struct GNUNET_ATS_SolverFunctions GAS_solver_address_property_changed s_address_update_property; /** - * Update the session of an address in the solver - */ - GAS_solver_address_session_changed s_address_update_session; - - /** - * Notify solver that the network an address is located in has changed - */ - GAS_solver_address_network_changed s_address_update_network; - - /** * Tell solver to notify ATS if the address to use changes for a specific * peer using the bandwidth changed callback * diff --git a/src/include/gnunet_ats_service.h b/src/include/gnunet_ats_service.h index 380a2a7af4..8c3c5361e6 100644 --- a/src/include/gnunet_ats_service.h +++ b/src/include/gnunet_ats_service.h @@ -704,14 +704,16 @@ struct GNUNET_ATS_ReservationContext; * @param amount reserve N bytes for receiving, negative * amounts can be used to undo a (recent) reservation; * @param rcb function to call with the resulting reservation information - * @param rcb_cls closure for info + * @param rcb_cls closure for @a rcb * @return NULL on error * @deprecated will be replaced soon */ struct GNUNET_ATS_ReservationContext * GNUNET_ATS_reserve_bandwidth (struct GNUNET_ATS_PerformanceHandle *ph, - const struct GNUNET_PeerIdentity *peer, int32_t amount, - GNUNET_ATS_ReservationCallback rcb, void *rcb_cls); + const struct GNUNET_PeerIdentity *peer, + int32_t amount, + GNUNET_ATS_ReservationCallback rcb, + void *rcb_cls); /** @@ -786,7 +788,8 @@ GNUNET_ATS_print_preference_type (uint32_t type); */ void GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *ph, - const struct GNUNET_PeerIdentity *peer, ...); + const struct GNUNET_PeerIdentity *peer, + ...); /** @@ -808,8 +811,9 @@ GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *p */ void GNUNET_ATS_performance_give_feedback (struct GNUNET_ATS_PerformanceHandle *ph, - const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_TIME_Relative scope, ...); + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_TIME_Relative scope, + ...); #endif /* end of file gnunet-service-transport_ats.h */ |