aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ats/Makefile.am41
-rw-r--r--src/ats/gnunet-ats-solver-eval.c110
-rw-r--r--src/ats/gnunet-service-ats.c23
-rw-r--r--src/ats/gnunet-service-ats_addresses.c1166
-rw-r--r--src/ats/gnunet-service-ats_addresses.h140
-rw-r--r--src/ats/gnunet-service-ats_connectivity.c148
-rw-r--r--src/ats/gnunet-service-ats_connectivity.h35
-rw-r--r--src/ats/gnunet-service-ats_normalization.c730
-rw-r--r--src/ats/gnunet-service-ats_normalization.h48
-rw-r--r--src/ats/gnunet-service-ats_performance.c108
-rw-r--r--src/ats/gnunet-service-ats_plugins.c661
-rw-r--r--src/ats/gnunet-service-ats_plugins.h163
-rw-r--r--src/ats/gnunet-service-ats_preferences.c1004
-rw-r--r--src/ats/gnunet-service-ats_preferences.h101
-rw-r--r--src/ats/gnunet-service-ats_scheduling.c5
-rw-r--r--src/ats/gnunet-service-ats_scheduling.h26
-rw-r--r--src/ats/perf_ats_solver.c20
-rw-r--r--src/ats/plugin_ats_mlp.c127
-rw-r--r--src/ats/plugin_ats_proportional.c154
-rw-r--r--src/ats/plugin_ats_ril.c70
-rw-r--r--src/include/gnunet_ats_plugin.h38
-rw-r--r--src/include/gnunet_ats_service.h16
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,
- &quota_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,
- &quota_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,
+ &quota_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,
+ &quota_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 */