gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r35099 - in gnunet/src: ats include


From: gnunet
Subject: [GNUnet-SVN] r35099 - in gnunet/src: ats include
Date: Thu, 5 Feb 2015 13:52:20 +0100

Author: grothoff
Date: 2015-02-05 13:52:20 +0100 (Thu, 05 Feb 2015)
New Revision: 35099

Added:
   gnunet/src/ats/gnunet-service-ats_plugins.c
   gnunet/src/ats/gnunet-service-ats_plugins.h
   gnunet/src/ats/gnunet-service-ats_preferences.c
   gnunet/src/ats/gnunet-service-ats_preferences.h
Modified:
   gnunet/src/ats/Makefile.am
   gnunet/src/ats/gnunet-ats-solver-eval.c
   gnunet/src/ats/gnunet-service-ats.c
   gnunet/src/ats/gnunet-service-ats_addresses.c
   gnunet/src/ats/gnunet-service-ats_addresses.h
   gnunet/src/ats/gnunet-service-ats_connectivity.c
   gnunet/src/ats/gnunet-service-ats_connectivity.h
   gnunet/src/ats/gnunet-service-ats_normalization.c
   gnunet/src/ats/gnunet-service-ats_normalization.h
   gnunet/src/ats/gnunet-service-ats_performance.c
   gnunet/src/ats/gnunet-service-ats_scheduling.c
   gnunet/src/ats/gnunet-service-ats_scheduling.h
   gnunet/src/ats/perf_ats_solver.c
   gnunet/src/ats/plugin_ats_mlp.c
   gnunet/src/ats/plugin_ats_proportional.c
   gnunet/src/ats/plugin_ats_ril.c
   gnunet/src/include/gnunet_ats_plugin.h
   gnunet/src/include/gnunet_ats_service.h
Log:
big ATS refactoring, no serious semantic changes should stem from this

Modified: gnunet/src/ats/Makefile.am
===================================================================
--- gnunet/src/ats/Makefile.am  2015-02-05 00:53:22 UTC (rev 35098)
+++ gnunet/src/ats/Makefile.am  2015-02-05 12:52:20 UTC (rev 35099)
@@ -43,6 +43,12 @@
 
 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 @@
 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 @@
 #  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 @@
   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 @@
   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 \

Modified: gnunet/src/ats/gnunet-ats-solver-eval.c
===================================================================
--- gnunet/src/ats/gnunet-ats-solver-eval.c     2015-02-05 00:53:22 UTC (rev 
35098)
+++ gnunet/src/ats/gnunet-ats-solver-eval.c     2015-02-05 12:52:20 UTC (rev 
35099)
@@ -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 SolverHandle *sh;
 
 static struct TestPeer *peer_head;
+
 static struct TestPeer *peer_tail;
 
 static double default_properties[GNUNET_ATS_PropertyCount];
@@ -670,8 +679,7 @@
         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 @@
     return p->pref_abs;
   }
   else
-    return GAS_normalization_get_preferences_by_peer (id);
+    return GAS_normalization_get_preferences_by_peer (NULL,
+                                                     id);
 }
 
 
@@ -3058,99 +3067,11 @@
     a = find_address_by_ats_address (p, address);
     return a->prop_abs;
   }
-  return GAS_normalization_get_properties ((struct ATS_Address *) address);
+  return GAS_normalization_get_properties (NULL,
+                                          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);
-}
-
-
 struct SolverHandle *
 GNUNET_ATS_solvers_solver_start (enum GNUNET_ATS_Solvers type)
 {
@@ -3196,8 +3117,7 @@
 
 
   /* 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,

Modified: gnunet/src/ats/gnunet-service-ats.c
===================================================================
--- gnunet/src/ats/gnunet-service-ats.c 2015-02-05 00:53:22 UTC (rev 35098)
+++ gnunet/src/ats/gnunet-service-ats.c 2015-02-05 12:52:20 UTC (rev 35099)
@@ -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 @@
     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 @@
 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 @@
   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 @@
   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);
 }
 
 

Modified: gnunet/src/ats/gnunet-service-ats_addresses.c
===================================================================
--- gnunet/src/ats/gnunet-service-ats_addresses.c       2015-02-05 00:53:22 UTC 
(rev 35098)
+++ gnunet/src/ats/gnunet-service-ats_addresses.c       2015-02-05 12:52:20 UTC 
(rev 35099)
@@ -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,112 +216,15 @@
  */
 
 
-/**
- * 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.
  */
 static const struct GNUNET_BANDWIDTH_Value32NBO zero_bw;
@@ -613,7 +516,7 @@
   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 @@
 
   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 @@
 
 
 /**
- * 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 @@
   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 @@
 
   /* 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));
+    GNUNET_break (0);
+    GNUNET_free(new_address->plugin);
+    GNUNET_free_non_null(new_address->atsi);
+    GNUNET_free(new_address);
     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);
-    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,13 +731,7 @@
   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,
                            session_id);
@@ -963,7 +745,6 @@
     GNUNET_break (0);
     return;
   }
-
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Received `%s' for peer `%s' address \n",
               "ADDRESS UPDATE",
@@ -972,17 +753,6 @@
 
   /* 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 @@
                                    &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));
+    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_plugin_update_address (aa,
+                              atsi,
+                              atsi_count);
   }
   GNUNET_free_non_null (atsi_delta);
 }
@@ -1032,9 +792,6 @@
 {
   struct ATS_Address *ea;
 
-  if (GNUNET_NO == running)
-    return;
-
   /* Get existing address */
   ea = find_exact_address (peer,
                            session_id);
@@ -1054,11 +811,10 @@
               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,754 +824,31 @@
                                       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;
-}
-
-
-/**
  * 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 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 @@
   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 @@
 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 @@
 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 @@
               (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,

Modified: gnunet/src/ats/gnunet-service-ats_addresses.h
===================================================================
--- gnunet/src/ats/gnunet-service-ats_addresses.h       2015-02-05 00:53:22 UTC 
(rev 35098)
+++ gnunet/src/ats/gnunet-service-ats_addresses.h       2015-02-05 12:52:20 UTC 
(rev 35099)
@@ -216,40 +216,9 @@
  *    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
-};
-
-
 /*
  * How long will address suggestions blocked after a suggestion
  */
@@ -362,18 +331,7 @@
    */
   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)
    */
   struct GNUNET_TIME_Absolute t_last_activity;
@@ -402,19 +360,18 @@
 
 
 /**
+ * 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,86 +437,9 @@
 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);
-
-
-/**
  * Iterator for #GAS_addresses_get_peer_info()
  *
  * @param p_it_cls closure closure

Modified: gnunet/src/ats/gnunet-service-ats_connectivity.c
===================================================================
--- gnunet/src/ats/gnunet-service-ats_connectivity.c    2015-02-05 00:53:22 UTC 
(rev 35098)
+++ gnunet/src/ats/gnunet-service-ats_connectivity.c    2015-02-05 12:52:20 UTC 
(rev 35099)
@@ -34,9 +34,125 @@
 #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.
  *
  * @param cls unused, NULL
@@ -83,4 +199,36 @@
   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 */

Modified: gnunet/src/ats/gnunet-service-ats_connectivity.h
===================================================================
--- gnunet/src/ats/gnunet-service-ats_connectivity.h    2015-02-05 00:53:22 UTC 
(rev 35098)
+++ gnunet/src/ats/gnunet-service-ats_connectivity.h    2015-02-05 12:52:20 UTC 
(rev 35099)
@@ -27,8 +27,26 @@
 #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.
  *
  * @param cls unused, NULL
@@ -54,5 +72,22 @@
                                    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 */

Modified: gnunet/src/ats/gnunet-service-ats_normalization.c
===================================================================
--- gnunet/src/ats/gnunet-service-ats_normalization.c   2015-02-05 00:53:22 UTC 
(rev 35098)
+++ gnunet/src/ats/gnunet-service-ats_normalization.c   2015-02-05 12:52:20 UTC 
(rev 35099)
@@ -23,118 +23,20 @@
  * @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
  */
 struct Property
@@ -147,490 +49,27 @@
 
 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 @@
 
 
 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 @@
       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 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 @@
   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 @@
   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 @@
   {
     /* 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 @@
 /**
  * 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 @@
   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 @@
     /* 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,70 +363,17 @@
     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
  */
 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 */

Modified: gnunet/src/ats/gnunet-service-ats_normalization.h
===================================================================
--- gnunet/src/ats/gnunet-service-ats_normalization.h   2015-02-05 00:53:22 UTC 
(rev 35098)
+++ gnunet/src/ats/gnunet-service-ats_normalization.h   2015-02-05 12:52:20 UTC 
(rev 35099)
@@ -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 @@
 /**
  * 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 @@
 
 /**
  * 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 */

Modified: gnunet/src/ats/gnunet-service-ats_performance.c
===================================================================
--- gnunet/src/ats/gnunet-service-ats_performance.c     2015-02-05 00:53:22 UTC 
(rev 35098)
+++ gnunet/src/ats/gnunet-service-ats_performance.c     2015-02-05 12:52:20 UTC 
(rev 35099)
@@ -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_tail;
 
+
 /**
  * Context for sending messages to performance clients.
  */
@@ -92,7 +93,6 @@
   return NULL;
 }
 
-
 /**
  * Unregister a client (which may have been a performance client,
  * but this is not assured).
@@ -108,7 +108,6 @@
   if (NULL == pc)
     return;
   GNUNET_CONTAINER_DLL_remove (pc_head, pc_tail, pc);
-  GAS_addresses_preference_client_disconnect (client);
   GNUNET_free (pc);
 }
 
@@ -593,112 +592,9 @@
 }
 
 
-/**
- * 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);
-}
-
-
-/**
  * Initialize performance subsystem.
  *
  * @param server handle to our server

Added: gnunet/src/ats/gnunet-service-ats_plugins.c
===================================================================
--- gnunet/src/ats/gnunet-service-ats_plugins.c                         (rev 0)
+++ gnunet/src/ats/gnunet-service-ats_plugins.c 2015-02-05 12:52:20 UTC (rev 
35099)
@@ -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 */

Added: gnunet/src/ats/gnunet-service-ats_plugins.h
===================================================================
--- gnunet/src/ats/gnunet-service-ats_plugins.h                         (rev 0)
+++ gnunet/src/ats/gnunet-service-ats_plugins.h 2015-02-05 12:52:20 UTC (rev 
35099)
@@ -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

Added: gnunet/src/ats/gnunet-service-ats_preferences.c
===================================================================
--- gnunet/src/ats/gnunet-service-ats_preferences.c                             
(rev 0)
+++ gnunet/src/ats/gnunet-service-ats_preferences.c     2015-02-05 12:52:20 UTC 
(rev 35099)
@@ -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);
+}
+

Added: gnunet/src/ats/gnunet-service-ats_preferences.h
===================================================================
--- gnunet/src/ats/gnunet-service-ats_preferences.h                             
(rev 0)
+++ gnunet/src/ats/gnunet-service-ats_preferences.h     2015-02-05 12:52:20 UTC 
(rev 35099)
@@ -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

Modified: gnunet/src/ats/gnunet-service-ats_scheduling.c
===================================================================
--- gnunet/src/ats/gnunet-service-ats_scheduling.c      2015-02-05 00:53:22 UTC 
(rev 35098)
+++ gnunet/src/ats/gnunet-service-ats_scheduling.c      2015-02-05 12:52:20 UTC 
(rev 35099)
@@ -99,7 +99,8 @@
   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 @@
                      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);

Modified: gnunet/src/ats/gnunet-service-ats_scheduling.h
===================================================================
--- gnunet/src/ats/gnunet-service-ats_scheduling.h      2015-02-05 00:53:22 UTC 
(rev 35098)
+++ gnunet/src/ats/gnunet-service-ats_scheduling.h      2015-02-05 12:52:20 UTC 
(rev 35099)
@@ -51,19 +51,6 @@
 
 
 /**
- * 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 @@
 
 
 /**
- * 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

Modified: gnunet/src/ats/perf_ats_solver.c
===================================================================
--- gnunet/src/ats/perf_ats_solver.c    2015-02-05 00:53:22 UTC (rev 35098)
+++ gnunet/src/ats/perf_ats_solver.c    2015-02-05 12:52:20 UTC (rev 35099)
@@ -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 @@
   default:
     break;
   }
-  ph.env.sf.s_address_update_inuse (ph.solver, cur, GNUNET_YES);
 }
 
 
@@ -411,22 +416,17 @@
 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 @@
         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);

Modified: gnunet/src/ats/plugin_ats_mlp.c
===================================================================
--- gnunet/src/ats/plugin_ats_mlp.c     2015-02-05 00:53:22 UTC (rev 35098)
+++ gnunet/src/ats/plugin_ats_mlp.c     2015-02-05 12:52:20 UTC (rev 35099)
@@ -2043,131 +2043,6 @@
 
 
 /**
- * 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 @@
   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;

Modified: gnunet/src/ats/plugin_ats_proportional.c
===================================================================
--- gnunet/src/ats/plugin_ats_proportional.c    2015-02-05 00:53:22 UTC (rev 
35098)
+++ gnunet/src/ats/plugin_ats_proportional.c    2015-02-05 12:52:20 UTC (rev 
35099)
@@ -713,7 +713,6 @@
   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 @@
 
   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,145 +1680,8 @@
   }
 }
 
-/**
- * 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
  *
  * @param solver the solver Handle
@@ -1914,8 +1762,6 @@
   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;

Modified: gnunet/src/ats/plugin_ats_ril.c
===================================================================
--- gnunet/src/ats/plugin_ats_ril.c     2015-02-05 00:53:22 UTC (rev 35098)
+++ gnunet/src/ats/plugin_ats_ril.c     2015-02-05 12:52:20 UTC (rev 35099)
@@ -2386,74 +2386,6 @@
 
 
 /**
- * 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 @@
 
   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;

Modified: gnunet/src/include/gnunet_ats_plugin.h
===================================================================
--- gnunet/src/include/gnunet_ats_plugin.h      2015-02-05 00:53:22 UTC (rev 
35098)
+++ gnunet/src/include/gnunet_ats_plugin.h      2015-02-05 12:52:20 UTC (rev 
35099)
@@ -128,36 +128,8 @@
     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
  *
  * @param solver the solver to use
@@ -201,16 +173,6 @@
   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
    *

Modified: gnunet/src/include/gnunet_ats_service.h
===================================================================
--- gnunet/src/include/gnunet_ats_service.h     2015-02-05 00:53:22 UTC (rev 
35098)
+++ gnunet/src/include/gnunet_ats_service.h     2015-02-05 12:52:20 UTC (rev 
35099)
@@ -704,14 +704,16 @@
  * @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 @@
  */
 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 @@
  */
 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 */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]