-add tests
[oweals/gnunet.git] / src / ats / gnunet-service-ats_plugins.c
index 7e03a1a7e8ce9634d5ee0b015d47eb61d672fc58..f70c4cd9b84e1bb028921bbb098acaae46e9b02d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  This file is part of GNUnet.
- (C) 2011-2014 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2011-2014 GNUnet e.V.
 
  GNUnet is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published
@@ -14,8 +14,8 @@
 
  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.
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
  */
 
 /**
  */
 #include "platform.h"
 #include "gnunet_ats_plugin.h"
+#include "gnunet-service-ats_connectivity.h"
 #include "gnunet-service-ats_performance.h"
 #include "gnunet-service-ats_preferences.h"
 #include "gnunet-service-ats_plugins.h"
+#include "gnunet-service-ats_reservations.h"
 #include "gnunet-service-ats_scheduling.h"
 #include "gnunet-service-ats_normalization.h"
 
 
-/**
- * Configured ATS solver
- */
-static int ats_mode;
-
 /**
  * Solver handle.
  */
@@ -62,37 +59,27 @@ static char *plugin;
  * @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)
+GAS_plugin_notify_preference_changed (const struct GNUNET_PeerIdentity *peer,
+                                      enum GNUNET_ATS_PreferenceKind kind,
+                                      double pref_rel)
 {
-  /* Tell solver about update */
-  sf->s_pref (sf->cls, peer, kind, pref_rel);
+  sf->s_pref (sf->cls,
+              peer,
+              kind,
+              pref_rel);
 }
 
 
 /**
- * The relative value for a property changed
+ * The relative value for a property changed.
  *
- * @param address the peer
- * @param type the ATS type
- * @param prop_rel the new relative preference value
+ * @param address the peer for which a property changed
  */
 void
-GAS_normalized_property_changed (struct ATS_Address *address,
-                                uint32_t type,
-                                double prop_rel)
+GAS_plugin_notify_property_changed (struct ATS_Address *address)
 {
-  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);
   sf->s_address_update_property (sf->cls,
-                                 address,
-                                 type,
-                                 0,
-                                 prop_rel);
+                                 address);
 }
 
 
@@ -110,7 +97,7 @@ solver_info_cb (void *cls,
                enum GAS_Solver_Status status,
                enum GAS_Solver_Additional_Information add)
 {
-  char *add_info;
+  const char *add_info;
 
   switch (add) {
     case GAS_INFO_NONE:
@@ -134,63 +121,71 @@ solver_info_cb (void *cls,
   }
   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;
-    }
+  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");
+    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:
+    GNUNET_break (0);
+    break;
+  }
 }
 
 
@@ -204,28 +199,31 @@ static void
 bandwidth_changed_cb (void *cls,
                      struct ATS_Address *address)
 {
-  uint32_t diff_out;
-  uint32_t diff_in;
+  long long diff_out;
+  long long diff_in;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Bandwidth assignment changed for peer %s \n",
-              GNUNET_i2s (&address->peer));
-
+              "Bandwidth assignment changed for peer %s to %u/%u\n",
+              GNUNET_i2s (&address->peer),
+              (unsigned int) address->assigned_bw_in,
+              (unsigned int) address->assigned_bw_out);
+  GAS_reservations_set_bandwidth (&address->peer,
+                                  GNUNET_BANDWIDTH_value_init (address->assigned_bw_in));
   /* 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,
+                                     &address->properties,
+                                      address->local_address_info,
                                      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,
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Telling transport to disconnect peer `%s'\n",
                 GNUNET_i2s (&address->peer));
 
@@ -238,17 +236,23 @@ bandwidth_changed_cb (void *cls,
   }
 
   /* 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__)) )
+  diff_out = llabs ((long long) address->assigned_bw_out -
+                    (long long) address->last_notified_bw_out);
+  diff_in = llabs ((long long) address->assigned_bw_in -
+                   (long long) 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__)) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Bandwidth change too small, not notifying client\n");
     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);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "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,
@@ -261,6 +265,108 @@ bandwidth_changed_cb (void *cls,
 }
 
 
+/**
+ * Convert quota from text to numeric value.
+ *
+ * @param quota_str the value found in the configuration
+ * @param direction direction of the quota
+ * @param network network the quota applies to
+ * @return numeric quota value to use
+ */
+static unsigned long long
+parse_quota (const char *quota_str,
+             const char *direction,
+             enum GNUNET_ATS_Network_Type network)
+{
+  int res;
+  unsigned long long ret;
+
+  res = GNUNET_NO;
+  if (0 == strcmp (quota_str, GNUNET_ATS_MaxBandwidthString))
+  {
+    ret = GNUNET_ATS_MaxBandwidth;
+    res = GNUNET_YES;
+  }
+  if ((GNUNET_NO == res) &&
+      (GNUNET_OK ==
+       GNUNET_STRINGS_fancy_size_to_bytes (quota_str,
+                                           &ret)))
+    res = GNUNET_YES;
+  if ((GNUNET_NO == res) &&
+      (1 ==
+       sscanf (quota_str,
+               "%llu",
+               &ret)))
+    res = GNUNET_YES;
+  if (GNUNET_NO == res)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("Could not load %s quota for network `%s':  `%s', assigning default bandwidth %llu\n"),
+                direction,
+                GNUNET_ATS_print_network_type (network),
+                quota_str,
+                (unsigned long long) GNUNET_ATS_DefaultBandwidth);
+    ret = GNUNET_ATS_DefaultBandwidth;
+  }
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                _("%s quota configured for network `%s' is %llu\n"),
+                direction,
+                GNUNET_ATS_print_network_type (network),
+                ret);
+  }
+  return ret;
+}
+
+
+/**
+ * Load quota value from the configuration @a cfg for the
+ * given network @a type and @a direction.
+ *
+ * @param cfg configuration to parse
+ * @param type network type to parse for
+ * @param direction traffic direction to parse for
+ * @return quota to apply
+ */
+static unsigned long long
+load_quota (const struct GNUNET_CONFIGURATION_Handle *cfg,
+            enum GNUNET_ATS_Network_Type type,
+            const char *direction)
+{
+  char *entry;
+  char *quota_str;
+  unsigned long long ret;
+
+  GNUNET_asprintf (&entry,
+                   "%s_QUOTA_%s",
+                   GNUNET_ATS_print_network_type (type),
+                   direction);
+  if (GNUNET_OK ==
+      GNUNET_CONFIGURATION_get_value_string (cfg,
+                                             "ats",
+                                             entry,
+                                             &quota_str))
+  {
+    ret = parse_quota (quota_str,
+                       direction,
+                       type);
+    GNUNET_free (quota_str);
+  }
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("No %s-quota configured for network `%s', assigning default bandwidth %llu\n"),
+                direction,
+                GNUNET_ATS_print_network_type (type),
+                (unsigned long long) GNUNET_ATS_DefaultBandwidth);
+    ret = GNUNET_ATS_DefaultBandwidth;
+  }
+  GNUNET_free (entry);
+  return ret;
+}
+
+
 /**
  * Load quotas for networks from configuration
  *
@@ -272,131 +378,27 @@ bandwidth_changed_cb (void *cls,
  */
 static unsigned int
 load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg,
-    unsigned long long *out_dest, unsigned long long *in_dest, int dest_length)
+             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;
+  unsigned int c;
 
   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);
+    in_dest[c] = load_quota (cfg,
+                             c,
+                             "out");
+    out_dest[c] = load_quota (cfg,
+                              c,
+                              "in");
+    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]);
   }
-  return GNUNET_ATS_NetworkTypeCount;
+  return c;
 }
 
 
@@ -408,90 +410,41 @@ load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg,
  *         solver plugin)
  */
 int
-GAS_plugins_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
+GAS_plugin_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
+      GNUNET_CONFIGURATION_get_value_string (cfg,
+                                             "ats",
+                                             "MODE",
+                                             &mode_str))
   {
-    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);
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "No resource assignment method configured, using proportional approach\n");
+    mode_str = GNUNET_strdup ("proportional");
   }
-
-  load_quotas (cfg, quotas_out, quotas_in, GNUNET_ATS_NetworkTypeCount);
   env.cls = NULL;
   env.info_cb = &solver_info_cb;
   env.bandwidth_changed_cb = &bandwidth_changed_cb;
-  env.get_preferences = &GAS_normalization_get_preferences_by_peer;
-  env.get_property = &GAS_normalization_get_properties;
+  env.get_preferences = &GAS_preference_get_by_peer;
+  env.get_connectivity = &GAS_connectivity_has_peer;
   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;
-  }
+  load_quotas (cfg,
+               env.out_quota,
+               env.in_quota,
+               GNUNET_ATS_NetworkTypeCount);
   GNUNET_asprintf (&plugin,
                    "libgnunet_plugin_ats_%s",
-                   plugin_short);
+                   mode_str);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Initializing solver `%s '`%s'\n",
-              plugin_short,
-              plugin);
+              "Initializing solver `%s'\n",
+              mode_str);
+  GNUNET_free (mode_str);
   if (NULL == (sf = GNUNET_PLUGIN_load (plugin, &env)))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -507,7 +460,7 @@ GAS_plugins_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
  * Shutdown address subsystem.
  */
 void
-GAS_plugins_done ()
+GAS_plugin_done ()
 {
   GNUNET_PLUGIN_unload (plugin,
                         sf);
@@ -517,70 +470,65 @@ GAS_plugins_done ()
 }
 
 
+/**
+ * Tell the solver that the given address can now be used
+ * for talking to the respective peer.
+ *
+ * @param new_address the new address
+ */
 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)
-{
-  sf->s_add (sf->cls, new_address, addr_net);
-  sf->s_bulk_start (sf->cls);
-  GAS_normalization_normalize_property (new_address,
-                                       atsi,
-                                       atsi_count);
-  sf->s_bulk_stop (sf->cls);
-}
-
-
-void
-GAS_plugin_update_address (struct ATS_Address *address,
-                          const struct GNUNET_ATS_Information *atsi,
-                          uint32_t atsi_count)
+GAS_plugin_new_address (struct ATS_Address *new_address)
 {
-  sf->s_bulk_start (sf->cls);
-  GAS_normalization_normalize_property (address,
-                                       atsi,
-                                       atsi_count);
-  sf->s_bulk_stop (sf->cls);
+  sf->s_add (sf->cls,
+             new_address,
+             new_address->properties.scope); /* FIXME: remove 3rd arg here! */
 }
 
 
+/**
+ * Tell the solver that the given address is no longer valid
+ * can cannot be used any longer.
+ *
+ * @param address address that was deleted
+ */
 void
 GAS_plugin_delete_address (struct ATS_Address *address)
 {
-  sf->s_del (sf->cls, address, GNUNET_NO);
-}
-
-
-void
-GAS_plugin_update_preferences (void *client,
-                              const struct GNUNET_PeerIdentity *peer,
-                              enum GNUNET_ATS_PreferenceKind kind,
-                              float score_abs)
-{
-  sf->s_bulk_start (sf->cls);
-  /* Tell normalization about change, normalization will call callback if preference changed */
-  GAS_normalization_normalize_preference (client, peer, kind, score_abs);
-  sf->s_bulk_stop (sf->cls);
+  sf->s_del (sf->cls,
+             address);
 }
 
 
+/**
+ * Tell the solver that the given client has expressed its
+ * appreciation for the past performance of a given connection.
+ *
+ * @param application client providing the feedback
+ * @param peer peer the feedback is about
+ * @param scope timeframe the feedback applies to
+ * @param kind performance property the feedback relates to
+ * @param score_abs degree of the appreciation
+ */
 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)
+GAS_plugin_notify_feedback (struct GNUNET_SERVICE_Client *application,
+                            const struct GNUNET_PeerIdentity *peer,
+                            const struct GNUNET_TIME_Relative scope,
+                            enum GNUNET_ATS_PreferenceKind kind,
+                            float score_abs)
 {
   sf->s_feedback (sf->cls,
-                    application,
-                    peer,
-                    scope,
-                    kind,
-                     score_abs);
+                  application,
+                  peer,
+                  scope,
+                  kind,
+                  score_abs);
 }
 
 
+/**
+ * Stop instant solving, there are many state updates
+ * happening in bulk right now.
+ */
 void
 GAS_plugin_solver_lock ()
 {
@@ -588,46 +536,41 @@ GAS_plugin_solver_lock ()
 }
 
 
+/**
+ * Resume instant solving, we are done with the bulk state updates.
+ */
 void
 GAS_plugin_solver_unlock ()
 {
-  sf->s_bulk_start (sf->cls);
+  sf->s_bulk_stop (sf->cls);
 }
 
 
+/**
+ * Notify the plugin that a request to connect to
+ * a particular peer was given to us.
+ *
+ * @param pid identity of peer we now care about
+ */
 void
 GAS_plugin_request_connect_start (const struct GNUNET_PeerIdentity *pid)
 {
-  const struct ATS_Address *aa;
-
-  aa = sf->s_get (sf->cls, 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);
+  sf->s_get (sf->cls,
+             pid);
 }
 
 
+/**
+ * Notify the plugin that a request to connect to
+ * a particular peer was dropped.
+ *
+ * @param pid identity of peer we care now less about
+ */
 void
 GAS_plugin_request_connect_stop (const struct GNUNET_PeerIdentity *pid)
 {
-  sf->s_get_stop (sf->cls, pid);
+  sf->s_get_stop (sf->cls,
+                  pid);
 }