- improved error logging
[oweals/gnunet.git] / src / ats / gnunet-service-ats_addresses.c
index 73545e35255037884b0b9e20c9623907ba5e8caf..06eee9fb39040d55cae982e562eb51e576092391 100644 (file)
 #include "gnunet_ats_service.h"
 #include "gnunet-service-ats.h"
 #include "gnunet-service-ats_addresses.h"
-#include "gnunet-service-ats_addresses_mlp.h"
 #include "gnunet-service-ats_performance.h"
 #include "gnunet-service-ats_scheduling.h"
 #include "gnunet-service-ats_reservations.h"
+#if HAVE_LIBGLPK
+#include "gnunet-service-ats_addresses_mlp.h"
+#endif
 
-struct ATS_Address
+enum ATS_Mode
 {
-  struct GNUNET_PeerIdentity peer;
-
-  size_t addr_len;
-
-  uint32_t session_id;
-
-  uint32_t ats_count;
-
-  const void *addr;
-
-  char *plugin;
-
-  struct GNUNET_ATS_Information *ats;
-
-  struct GNUNET_TIME_Relative atsp_latency;
-
-  struct GNUNET_BANDWIDTH_Value32NBO atsp_utilization_in;
-
-  struct GNUNET_BANDWIDTH_Value32NBO atsp_utilization_out;
-
-  uint32_t atsp_distance;
-
-  uint32_t atsp_cost_wan;
-
-  uint32_t atsp_cost_lan;
-
-  uint32_t atsp_cost_wlan;
-
-  uint32_t atsp_network_type;
-
-  struct GNUNET_BANDWIDTH_Value32NBO assigned_bw_in;
-
-  struct GNUNET_BANDWIDTH_Value32NBO assigned_bw_out;
-
   /**
-   * Is this the active address for this peer?
+   * Assign each peer an equal amount of bandwidth (bw)
+   *
+   * bw_per_peer = bw_total / #active addresses
    */
-  int active;
-
-};
+  SIMPLE,
 
-enum ATS_Mode
-{
-       SIMPLE,
-       MLP
+  /**
+   * Use MLP solver to assign bandwidth
+   */
+  MLP
 };
 
 static struct GNUNET_CONTAINER_MultiHashMap *addresses;
 
+#if HAVE_LIBGLPK
+static struct GAS_MLP_Handle *mlp;
+#endif
+
 static unsigned long long wan_quota_in;
 
 static unsigned long long wan_quota_out;
@@ -92,6 +64,7 @@ static unsigned int active_addr_count;
 
 static int ats_mode;
 
+
 /**
  * Update a bandwidth assignment for a peer.  This trivial method currently
  * simply assigns the same share to all active connections.
@@ -106,6 +79,8 @@ update_bw_it (void *cls, const GNUNET_HashCode * key, void *value)
 {
   struct ATS_Address *aa = value;
 
+
+  /* Simple method */
   if (GNUNET_YES != aa->active)
     return GNUNET_OK;
   GNUNET_assert (active_addr_count > 0);
@@ -143,6 +118,46 @@ recalculate_assigned_bw ()
   GNUNET_CONTAINER_multihashmap_iterate (addresses, &update_bw_it, NULL);
 }
 
+/**
+ * Free the given address
+ * @param addr address to destroy
+ */
+static void
+free_address (struct ATS_Address *addr)
+{
+  GNUNET_free_non_null (addr->ats);
+  GNUNET_free (addr->plugin);
+  GNUNET_free (addr);
+}
+
+/**
+ * Create a ATS_address with the given information
+ * @param peer peer
+ * @param plugin_name plugin
+ * @param plugin_addr address
+ * @param plugin_addr_len address length
+ * @param session_id session
+ * @return the ATS_Address
+ */
+static struct ATS_Address *
+create_address (const struct GNUNET_PeerIdentity *peer,
+                const char *plugin_name,
+                const void *plugin_addr, size_t plugin_addr_len,
+                uint32_t session_id)
+{
+  struct ATS_Address *aa = NULL;
+
+  aa = GNUNET_malloc (sizeof (struct ATS_Address) + plugin_addr_len);
+  aa->peer = *peer;
+  aa->addr_len = plugin_addr_len;
+  aa->addr = &aa[1];
+  memcpy (&aa[1], plugin_addr, plugin_addr_len);
+  aa->plugin = GNUNET_strdup (plugin_name);
+  aa->session_id = session_id;
+
+  return aa;
+}
+
 
 /**
  * Destroy the given address.
@@ -160,15 +175,19 @@ destroy_address (struct ATS_Address *addr)
                  GNUNET_CONTAINER_multihashmap_remove (addresses,
                                                        &addr->peer.hashPubKey,
                                                        addr));
+
+#if HAVE_LIBGLPK
+  if (ats_mode == MLP)
+    GAS_mlp_address_delete (mlp, addresses, addr);
+#endif
+
   if (GNUNET_YES == addr->active)
   {
     active_addr_count--;
     addr->active = GNUNET_NO;
     ret = GNUNET_YES;
   }
-  GNUNET_free_non_null (addr->ats);
-  GNUNET_free (addr->plugin);
-  GNUNET_free (addr);
+  free_address (addr);
   return ret;
 }
 
@@ -231,16 +250,16 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
   struct ATS_Address *old;
   uint32_t i;
 
-  aa = GNUNET_malloc (sizeof (struct ATS_Address) + plugin_addr_len);
+  aa = create_address (peer,
+                       plugin_name,
+                       plugin_addr, plugin_addr_len,
+                       session_id);
+
+  aa->mlp_information = NULL;
   aa->ats = GNUNET_malloc (atsi_count * sizeof (struct GNUNET_ATS_Information));
-  aa->peer = *peer;
-  aa->addr_len = plugin_addr_len;
   aa->ats_count = atsi_count;
   memcpy (aa->ats, atsi, atsi_count * sizeof (struct GNUNET_ATS_Information));
-  aa->addr = &aa[1];
-  memcpy (&aa[1], plugin_addr, plugin_addr_len);
-  aa->plugin = GNUNET_strdup (plugin_name);
-  aa->session_id = session_id;
+
   old = find_address (peer, aa);
   if (old == NULL)
   {
@@ -300,6 +319,10 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
       GNUNET_break (0);
       break;
     }
+#if HAVE_LIBGLPK
+  if (ats_mode == MLP)
+    GAS_mlp_address_update (mlp, addresses, old);
+#endif
 }
 
 
@@ -353,27 +376,35 @@ destroy_by_session_id (void *cls, const GNUNET_HashCode * key, void *value)
 
   /* session == 0 and addrlen == 0 : destroy address */
   if (aa->addr_len == 0)
+  {
     (void) destroy_address (aa);
+  }
+  else
+  {
+    /* session was set to 0, update address */
+#if HAVE_LIBGLPK
+  if (ats_mode == MLP)
+    GAS_mlp_address_update (mlp, addresses, aa);
+#endif
+  }
 
   return GNUNET_OK;
 }
 
-
 void
 GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer,
                        const char *plugin_name, const void *plugin_addr,
                        size_t plugin_addr_len, uint32_t session_id)
 {
-  struct ATS_Address aa;
+  struct ATS_Address *aa;
 
   GNUNET_break (0 < strlen (plugin_name));
-  aa.peer = *peer;
-  aa.addr_len = plugin_addr_len;
-  aa.addr = plugin_addr;
-  aa.plugin = (char *) plugin_name;
-  aa.session_id = session_id;
+  aa = create_address (peer, plugin_name, plugin_addr, plugin_addr_len, session_id);
+
   GNUNET_CONTAINER_multihashmap_get_multiple (addresses, &peer->hashPubKey,
-                                              &destroy_by_session_id, &aa);
+                                              &destroy_by_session_id, aa);
+
+  free_address (aa);
 }
 
 
@@ -428,10 +459,27 @@ GAS_addresses_in_use (const struct GNUNET_PeerIdentity *peer,
                       const char *plugin_name, const void *plugin_addr,
                       size_t plugin_addr_len, uint32_t session_id, int in_use)
 {
-
+#if DEBUG_ATS
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Received `%s' message for peer `%s': %i\n", "ADDRESS_IN_USE",
               GNUNET_i2s (peer), in_use);
+#endif
+
+  struct ATS_Address *aa;
+  struct ATS_Address *old;
+
+  aa = create_address(peer, plugin_name, plugin_addr, plugin_addr_len, session_id);
+  old = find_address (peer, aa);
+  free_address (aa);
+
+  GNUNET_assert (old != NULL);
+  GNUNET_assert (in_use != old->used);
+  old->used = in_use;
+
+#if HAVE_LIBGLPK
+  if (ats_mode == MLP)
+     GAS_mlp_address_update (mlp, addresses, old);
+#endif
 }
 
 void
@@ -482,9 +530,11 @@ GAS_addresses_change_preference (const struct GNUNET_PeerIdentity *peer,
  * Initialize address subsystem.
  *
  * @param cfg configuration to use
+ * @param stats the statistics handle to use
  */
 void
-GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
+GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
+                    const struct GNUNET_STATISTICS_Handle *stats)
 {
   GNUNET_assert (GNUNET_OK ==
                  GNUNET_CONFIGURATION_get_value_size (cfg, "ats",
@@ -495,21 +545,21 @@ GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
                                                       "WAN_QUOTA_OUT",
                                                       &wan_quota_out));
 
-
-
   switch (GNUNET_CONFIGURATION_get_value_yesno (cfg, "ats", "MLP"))
   {
        /* MLP = YES */
        case GNUNET_YES:
-#if !HAVE_LIBGLPK
-               GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP mode was configured, but libglpk is not installed, switching to simple mode");
-               ats_mode = SIMPLE;
-               break;
+#if HAVE_LIBGLPK
+          ats_mode = MLP;
+          /* Init the MLP solver with default values */
+          mlp = GAS_mlp_init (cfg, stats, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS);
+          break;
 #else
-               ats_mode = MLP;
-               GAS_mlp_init ();
+
+          GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP mode was configured, but libglpk is not installed, switching to simple mode");
+          ats_mode = SIMPLE;
+          break;
 #endif
-               break;
        /* MLP = NO */
        case GNUNET_NO:
                ats_mode = SIMPLE;
@@ -565,7 +615,7 @@ GAS_addresses_done ()
 #if HAVE_LIBGLPK
   if (ats_mode == MLP)
   {
-    GAS_mlp_done ();
+    GAS_mlp_done (mlp);
   }
 #endif