fixing shutdown
[oweals/gnunet.git] / src / ats / gnunet-service-ats-solver_ril.c
index a47f1ff9a6807e13c59c658b3dd47c38f9f67ab6..9aecd1747a5b4ee0bae845646c99f272c56ec615 100755 (executable)
 
 enum RIL_Action_Type
 {
-  RIL_ACTION_BW_IN_DBL = 0,
-  RIL_ACTION_BW_OUT_DBL = 1,
+  RIL_ACTION_NOTHING = 0,
+  RIL_ACTION_BW_IN_DBL = 1,
   RIL_ACTION_BW_IN_HLV = 2,
-  RIL_ACTION_BW_OUT_HLV = 3,
-  RIL_ACTION_TYPE_NUM = 4
+  RIL_ACTION_BW_IN_INC = 3,
+  RIL_ACTION_BW_IN_DEC = 4,
+  RIL_ACTION_BW_OUT_DBL = 5,
+  RIL_ACTION_BW_OUT_HLV = 6,
+  RIL_ACTION_BW_OUT_INC = 7,
+  RIL_ACTION_BW_OUT_DEC = 8,
+  RIL_ACTION_TYPE_NUM = 9
 };
 //TODO! add the rest of the actions
 
 enum RIL_Algorithm
 {
-  RIL_ALGO_SARSA, RIL_ALGO_Q
+  RIL_ALGO_SARSA = 0, RIL_ALGO_Q = 1
 };
 
 enum RIL_E_Modification
@@ -315,7 +320,7 @@ agent_estimate_q (struct RIL_Peer_Agent *agent, double *state, int action)
 
   for (i = 0; i < agent->m; i++)
   {
-    result += state[i] * (agent->W)[agent->m][action];
+    result += state[i] * agent->W[action][i];
   }
 
   return result;
@@ -353,7 +358,7 @@ agent_get_action_best (struct RIL_Peer_Agent *agent, double *state)
   int i;
   int max_i = -1;
   double cur_q;
-  double max_q = DBL_MIN;
+  double max_q = -DBL_MAX;
 
   for (i = 0; i < agent->n; i++)
   {
@@ -397,7 +402,7 @@ agent_update_weights (struct RIL_Peer_Agent *agent,
 {
   int i;
   double delta;
-  double *theta = (agent->W)[agent->a_old];
+  double *theta = agent->W[agent->a_old];
 
   delta = reward + agent_estimate_q (agent, s_next, a_prime)
       - agent_estimate_q (agent, agent->s_old, agent->a_old);
@@ -445,6 +450,44 @@ agent_modify_eligibility (struct RIL_Peer_Agent *agent,
   }
 }
 
+static void
+envi_change_active_address (struct GAS_RIL_Handle *solver,
+    struct RIL_Peer_Agent *agent,
+    struct ATS_Address *new_address,
+    unsigned long long new_bw_in,
+    unsigned long long new_bw_out)
+{
+  int notify = GNUNET_NO;
+
+  if (agent->address != new_address)
+  {
+    agent->address->active = GNUNET_NO;
+    agent->address = new_address;
+    agent->address->active = GNUNET_YES;
+    agent->address->assigned_bw_in.value__ = htonl (agent->bw_in);
+    agent->address->assigned_bw_out.value__ = htonl (agent->bw_out);
+    notify |= GNUNET_YES;
+  }
+  if (agent->bw_in != new_bw_in)
+  {
+    agent->bw_in = new_bw_in;
+    agent->address->assigned_bw_in.value__ = htonl (new_bw_out);
+    notify |= GNUNET_YES;
+  }
+  if (agent->bw_out != new_bw_out)
+  {
+    agent->bw_out = new_bw_out;
+    agent->address->assigned_bw_out.value__ = htonl (new_bw_out);
+    notify |= GNUNET_YES;
+  }
+
+  if (notify)
+  {
+    solver->callbacks->bw_changed (solver->callbacks->bw_changed_cls,
+        agent->address);
+  }
+}
+
 /**
  * Allocates a state vector and fills it with the features present
  * @param solver the solver handle
@@ -457,13 +500,13 @@ envi_get_state (struct GAS_RIL_Handle *solver)
   struct RIL_Network *net;
   double *state = GNUNET_malloc (sizeof (double) * solver->networks_count * 4);
 
-  for (i = 0; i < solver->networks_count; i += 4)
+  for (i = 0; i < solver->networks_count; i++)
   {
-    net = (&solver->network_entries)[i];
-    state[i] = (double) net->bw_in_assigned;
-    state[i + 1] = (double) net->bw_in_available;
-    state[i + 2] = (double) net->bw_out_assigned;
-    state[i + 3] = (double) net->bw_out_available;
+    net = &solver->network_entries[i];
+    state[i * 4 + 0] = (double) net->bw_in_assigned;
+    state[i * 4 + 1] = (double) net->bw_in_available;
+    state[i * 4 + 2] = (double) net->bw_out_assigned;
+    state[i * 4 + 3] = (double) net->bw_out_available;
   }
 
   return state;
@@ -490,17 +533,13 @@ envi_action_bw_double (struct GAS_RIL_Handle *solver,
 {
   if (direction_in)
   {
-    agent->bw_in *= 2;
-    agent->address->assigned_bw_in.value__ = htonl (agent->bw_in);
-    solver->callbacks->bw_changed (solver->callbacks->bw_changed_cls,
-        agent->address);
+    envi_change_active_address (solver, agent, agent->address, agent->bw_in * 2,
+        agent->bw_out);
   }
   else
   {
-    agent->bw_out *= 2;
-    agent->address->assigned_bw_out.value__ = htonl (agent->bw_out);
-    solver->callbacks->bw_changed (solver->callbacks->bw_changed_cls,
-        agent->address);
+    envi_change_active_address (solver, agent, agent->address, agent->bw_in,
+        agent->bw_out * 2);
   }
 }
 
@@ -509,24 +548,69 @@ envi_action_bw_halven (struct GAS_RIL_Handle *solver,
     struct RIL_Peer_Agent *agent,
     int direction_in)
 {
-  if ((direction_in && 1 == agent->bw_in)
-      || (!direction_in && 1 == agent->bw_out))
+  uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
+  unsigned long long new_bw;
+
+  if (direction_in)
   {
-    return;
+    new_bw = agent->bw_in / 2;
+    if (new_bw < min_bw)
+      new_bw = min_bw;
+    envi_change_active_address (solver, agent, agent->address, new_bw,
+        agent->bw_out);
+  }
+  else
+  {
+    new_bw = agent->bw_out / 2;
+    if (new_bw < min_bw)
+      new_bw = min_bw;
+    envi_change_active_address (solver, agent, agent->address, agent->bw_in,
+        new_bw);
+  }
+}
+
+static void
+envi_action_bw_inc (struct GAS_RIL_Handle *solver,
+    struct RIL_Peer_Agent *agent,
+    int direction_in)
+{
+  uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
+
+  if (direction_in)
+  {
+    envi_change_active_address (solver, agent, agent->address,
+        agent->bw_in + (5 * min_bw), agent->bw_out);
   }
+  else
+  {
+    envi_change_active_address (solver, agent, agent->address, agent->bw_in,
+        agent->bw_out + (5 * min_bw));
+  }
+}
+
+static void
+envi_action_bw_dec (struct GAS_RIL_Handle *solver,
+    struct RIL_Peer_Agent *agent,
+    int direction_in)
+{
+  uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
+  unsigned long long new_bw;
+
   if (direction_in)
   {
-    agent->bw_in /= 2;
-    agent->address->assigned_bw_in.value__ = htonl (agent->bw_in);
-    solver->callbacks->bw_changed (solver->callbacks->bw_changed_cls,
-        agent->address);
+    new_bw = agent->bw_in - (5 * min_bw);
+    if (new_bw < min_bw)
+      new_bw = min_bw;
+    envi_change_active_address (solver, agent, agent->address, new_bw,
+        agent->bw_out);
   }
   else
   {
-    agent->bw_out /= 2;
-    agent->address->assigned_bw_out.value__ = htonl (agent->bw_out);
-    solver->callbacks->bw_changed (solver->callbacks->bw_changed_cls,
-        agent->address);
+    new_bw = agent->bw_out - (5 * min_bw);
+    if (new_bw < min_bw)
+      new_bw = min_bw;
+    envi_change_active_address (solver, agent, agent->address, agent->bw_in,
+        new_bw);
   }
 }
 
@@ -542,18 +626,35 @@ envi_do_action (struct GAS_RIL_Handle *solver,
 {
   switch (action)
   {
+  case RIL_ACTION_NOTHING:
+    break;
   case RIL_ACTION_BW_IN_DBL:
     envi_action_bw_double (solver, agent, GNUNET_YES);
     break;
   case RIL_ACTION_BW_IN_HLV:
     envi_action_bw_halven (solver, agent, GNUNET_YES);
     break;
+  case RIL_ACTION_BW_IN_INC:
+    envi_action_bw_inc (solver, agent, GNUNET_YES);
+    break;
+  case RIL_ACTION_BW_IN_DEC:
+    envi_action_bw_dec (solver, agent, GNUNET_YES);
+    break;
   case RIL_ACTION_BW_OUT_DBL:
     envi_action_bw_double (solver, agent, GNUNET_NO);
     break;
   case RIL_ACTION_BW_OUT_HLV:
     envi_action_bw_halven (solver, agent, GNUNET_NO);
     break;
+  case RIL_ACTION_BW_OUT_INC:
+    envi_action_bw_inc (solver, agent, GNUNET_NO);
+    break;
+  case RIL_ACTION_BW_OUT_DEC:
+    envi_action_bw_dec (solver, agent, GNUNET_NO);
+    break;
+  default:
+    // error - action does not exist
+    GNUNET_assert(GNUNET_NO);
   }
 }
 
@@ -574,6 +675,9 @@ agent_step (struct RIL_Peer_Agent *agent)
   s_next = envi_get_state (agent->envi);
   reward = envi_get_reward (agent->envi, agent);
 
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "agent_step() with algorithm %s\n",
+      agent->envi->parameters.algorithm ? "Q" : "SARSA");
+
   switch (agent->envi->parameters.algorithm)
   {
   case RIL_ALGO_SARSA:
@@ -586,14 +690,16 @@ agent_step (struct RIL_Peer_Agent *agent)
     {
       a_next = agent_get_action_best (agent, s_next);
     }
-    //updates weights with selected action (on-policy)
-    agent_update_weights (agent, reward, s_next, a_next);
+    //updates weights with selected action (on-policy), if not first step
+    if (-1 != agent->a_old)
+      agent_update_weights (agent, reward, s_next, a_next);
     break;
 
   case RIL_ALGO_Q:
-    //updates weights with best action, disregarding actually selected action (off-policy)
+    //updates weights with best action, disregarding actually selected action (off-policy), if not first step
     a_next = agent_get_action_best (agent, s_next);
-    agent_update_weights (agent, reward, s_next, a_next);
+    if (-1 != agent->a_old)
+      agent_update_weights (agent, reward, s_next, a_next);
     if (agent_decide_exploration (agent))
     {
       a_next = agent_get_action_explore (agent, s_next);
@@ -670,7 +776,7 @@ agent_init (void *s, const struct GNUNET_PeerIdentity *peer)
   agent->W = (double **) GNUNET_malloc (sizeof (double) * agent->n);
   for (i = 0; i < agent->n; i++)
   {
-    (agent->W)[i] = (double *) GNUNET_malloc (sizeof (double) * agent->m);
+    agent->W[i] = (double *) GNUNET_malloc (sizeof (double) * agent->m);
   }
   agent->a_old = -1;
   agent->e = (double *) GNUNET_malloc (sizeof (double) * agent->m);
@@ -694,45 +800,68 @@ agent_die (struct GAS_RIL_Handle *solver, struct RIL_Peer_Agent *agent)
 
   for (i = 0; i < agent->n; i++)
   {
-    GNUNET_free((agent->W)[i]);
+    GNUNET_free(agent->W[i]);
   }
   GNUNET_free(agent->W);
   GNUNET_free(agent->e);
   GNUNET_free(agent->s_old);
 }
 
-/**
- * Counts the (active) agents
- * @param solver solver handle
- * @param active_only whether only active agents should be counted
- * @return number of agents
- */
-static int
-ril_count_agents (struct GAS_RIL_Handle *solver, int active_only)
+static void
+ril_remove_agent (struct GAS_RIL_Handle *s, struct RIL_Peer_Agent *agent)
 {
-  int c;
-  struct RIL_Peer_Agent *cur;
+  struct RIL_Peer_Agent *cur_agent;
+  struct RIL_Peer_Agent *next_agent;
 
-  c = 0;
-  for (cur = solver->agents_head; NULL != cur; cur = cur->next)
+  cur_agent = s->agents_head;
+  while (NULL != cur_agent)
   {
-    if ((!active_only) || (active_only && cur->active))
+    next_agent = cur_agent->next;
+
+    if (agent == cur_agent)
     {
-      c += 1;
+      GNUNET_CONTAINER_DLL_remove(s->agents_head, s->agents_tail, cur_agent);
+      agent_die (s, cur_agent);
     }
+
+    cur_agent = next_agent;
   }
-  return c;
 }
 
+/**
+ * Counts the (active) agents
+ * @param solver solver handle
+ * @param active_only whether only active agents should be counted
+ * @return number of agents
+ */
+//static int
+//ril_count_agents (struct GAS_RIL_Handle *solver, int active_only)
+//{
+//  int c;
+//  struct RIL_Peer_Agent *cur;
+//
+//  c = 0;
+//  for (cur = solver->agents_head; NULL != cur; cur = cur->next)
+//  {
+//    if ((!active_only) || (active_only && cur->active))
+//    {
+//      c += 1;
+//    }
+//  }
+//  return c;
+//}
+
 /**
  * Returns the agent for a peer
  * @param s solver handle
  * @param peer identity of the peer
+ * @param create whether to create an agent if none is allocated yet
  * @return agent
  */
 static struct RIL_Peer_Agent *
 ril_get_agent (struct GAS_RIL_Handle *solver,
-    const struct GNUNET_PeerIdentity *peer)
+    const struct GNUNET_PeerIdentity *peer,
+    int create)
 {
   struct RIL_Peer_Agent *cur;
 
@@ -744,7 +873,19 @@ ril_get_agent (struct GAS_RIL_Handle *solver,
     }
   }
 
-  return agent_init (solver, peer);
+  if (create)
+    return agent_init (solver, peer);
+  return NULL ;
+}
+
+static int
+ril_network_is_active (struct RIL_Network *network)
+{
+  uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
+
+  if (network->bw_out_available < min_bw)
+    return GNUNET_NO;
+  return GNUNET_YES;
 }
 
 /**
@@ -760,26 +901,50 @@ ril_init_agents_it (void *cls, const struct GNUNET_HashCode *key, void *value)
 {
   struct GAS_RIL_Handle *solver = cls;
   struct ATS_Address *address = value;
-  struct RIL_Peer_Agent *agent;
+  struct RIL_Peer_Agent *agent = NULL;
   uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
 
-  agent = ril_get_agent (solver, &address->peer);
+  if (ril_network_is_active (address->solver_information))
+  {
+    agent = ril_get_agent (solver, &address->peer, GNUNET_YES);
 
-  GNUNET_assert(NULL != agent);
+    GNUNET_assert(NULL != agent);
 
-  if (NULL == agent->address)
-  {
-    agent->address = address;
-    agent->address->active = GNUNET_YES;
-    agent->bw_in = min_bw;
-    agent->address->assigned_bw_in.value__ = htonl (min_bw);
-    agent->bw_out = min_bw;
-    agent->address->assigned_bw_out.value__ = htonl (min_bw);
+    if (NULL == agent->address)
+    {
+      agent->address = address;
+      agent->address->active = GNUNET_YES;
+      agent->bw_in = min_bw;
+      agent->address->assigned_bw_in.value__ = htonl (min_bw);
+      agent->bw_out = min_bw;
+      agent->address->assigned_bw_out.value__ = htonl (min_bw);
+    }
   }
-
   return GNUNET_YES;
 }
 
+static void
+ril_get_new_address_or_delete (struct GAS_RIL_Handle *solver,
+    struct RIL_Peer_Agent *agent)
+{
+  uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
+  //get new address for agent or delete agent
+
+  agent->address = NULL; //forget current address
+  GNUNET_CONTAINER_multihashmap_iterate (solver->addresses, &ril_init_agents_it,
+      solver); //put another address
+
+  if (NULL == agent->address) //no other address available
+  {
+    agent->active = GNUNET_NO;
+    ril_remove_agent (solver, agent);
+  }
+  else
+  {
+    envi_change_active_address (solver, agent, agent->address, min_bw, min_bw);
+  }
+}
+
 /**
  * Lookup network struct by type
  *
@@ -791,13 +956,15 @@ static struct RIL_Network *
 ril_get_network (struct GAS_RIL_Handle *s, uint32_t type)
 {
   int i;
+
   for (i = 0; i < s->networks_count; i++)
   {
-    if (s->network_entries[i].type == type) {
+    if (s->network_entries[i].type == type)
+    {
       return &s->network_entries[i];
     }
   }
-  return NULL;
+  return NULL ;
 }
 
 /**
@@ -820,7 +987,7 @@ GAS_ril_address_change_preference (void *s,
     double pref_rel)
 {
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-      "API_address_change_preference() Preference `%s' for peer `%s' changed to %.2f \n",
+      "API_address_change_preference() Preference '%s' for peer '%s' changed to %.2f \n",
       GNUNET_ATS_print_preference_type (kind), GNUNET_i2s (peer), pref_rel);
   /*
    * Nothing to do here. Preferences are considered during reward calculation.
@@ -893,13 +1060,10 @@ GAS_ril_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
     solver->step_time = RIL_DEFAULT_STEP_TIME;
   }
   if (GNUNET_OK
-      != GNUNET_CONFIGURATION_get_value_string (cfg, "ats", "RIL_ALGORITHM",
-          &string))
+      == GNUNET_CONFIGURATION_get_value_string (cfg, "ats", "RIL_ALGORITHM",
+          &string) && NULL != string && 0 == strcmp (string, "SARSA"))
   {
-    if (0 == strcmp (string, "SARSA"))
-    {
-      solver->parameters.algorithm = RIL_ALGO_SARSA;
-    }
+    solver->parameters.algorithm = RIL_ALGO_SARSA;
   }
   else
   {
@@ -910,7 +1074,6 @@ GAS_ril_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
           &tmp))
   {
     solver->parameters.gamma = (double) tmp / 100;
-    ;
   }
   else
   {
@@ -921,7 +1084,6 @@ GAS_ril_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
           "RIL_GRADIENT_STEP_SIZE", &tmp))
   {
     solver->parameters.alpha = (double) tmp / 100;
-    ;
   }
   else
   {
@@ -932,7 +1094,6 @@ GAS_ril_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
           &tmp))
   {
     solver->parameters.lambda = (double) tmp / 100;
-    ;
   }
   else
   {
@@ -964,13 +1125,6 @@ GAS_ril_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
     cur->bw_out_assigned = 0;
   }
 
-  c = GNUNET_CONTAINER_multihashmap_iterate (addresses, &ril_init_agents_it,
-      solver);
-
-  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-      "API_init() Solving ATS for %d addresses and %d peers\n", c,
-      ril_count_agents(solver, GNUNET_NO));
-
   solver->next_step = GNUNET_SCHEDULER_add_delayed (
       GNUNET_TIME_relative_multiply (GNUNET_TIME_relative_get_millisecond_ (),
           1000), &ril_periodic_step, solver);
@@ -1030,6 +1184,8 @@ GAS_ril_address_add (void *solver,
    * and action vector
    */
 
+  address->solver_information = ril_get_network (s, network);
+
   /*
    * reiterate all addresses, create new agent if necessary and give the agent the address
    */
@@ -1067,17 +1223,24 @@ GAS_ril_address_delete (void *solver,
   struct GAS_RIL_Handle *s = solver;
   struct RIL_Peer_Agent *agent;
 
-  agent = ril_get_agent (s, &address->peer);
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+      "API_address_delete() deleting %s address %p for peer '%s'\n",
+      address->active ? "active" : "inactive", address,
+      GNUNET_i2s (&address->peer));
 
-  if (0 == memcmp (agent->address->addr, address->addr, address->addr_len)) //if used address deleted
+  agent = ril_get_agent (s, &address->peer, GNUNET_NO);
+
+  if (NULL == agent)
   {
-    agent->address = NULL; //delete address
-    GNUNET_CONTAINER_multihashmap_iterate (s->addresses, &ril_init_agents_it,
-        solver); //put another address
-    if (NULL == agent->address) //no other address available
-    {
-      agent->active = GNUNET_NO;
-    }
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+        "API_address_delete() deleting address for unallocated agent\n");
+    return;
+  }
+
+  if (address == agent->address) //if used address deleted
+  {
+    address->active = GNUNET_NO;
+    ril_get_new_address_or_delete (s, agent);
   }
 
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
@@ -1103,7 +1266,7 @@ GAS_ril_address_property_changed (void *solver,
     double rel_value)
 {
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-      "API_address_property_changed() Property `%s' for peer `%s' address %p changed "
+      "API_address_property_changed() Property '%s' for peer '%s' address %p changed "
           "to %.2f \n", GNUNET_ATS_print_property_type (type),
       GNUNET_i2s (&address->peer), address, rel_value);
   /*
@@ -1180,29 +1343,50 @@ GAS_ril_address_change_network (void *solver,
 
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
       "API_address_change_network() Network type changed, moving "
-          "%s address of peer %s from `%s' to `%s'\n",
+          "%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));
 
-  agent = ril_get_agent (s, &address->peer);
+  address->solver_information = ril_get_network (solver, new_network);
 
   if (address->active)
   {
+    agent = ril_get_agent (solver, &address->peer, GNUNET_NO);
+
     //remove from old network
     net = ril_get_network (s, current_network);
     net->bw_in_assigned -= agent->bw_in;
     net->bw_out_assigned -= agent->bw_out;
 
-    //add to new network
-    net = ril_get_network (s, new_network);
-    net->bw_in_assigned += agent->bw_in;
-    net->bw_out_assigned += agent->bw_out;
+    if (ril_network_is_active (ril_get_network (s, new_network)))
+    {
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "New network is active\n");
+      //add to new network
+      net = ril_get_network (s, new_network);
+      net->bw_in_assigned += agent->bw_in;
+      net->bw_out_assigned += agent->bw_out;
+
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+          "API_address_change_network() Moved %d inbound and %d "
+              "outbound\n", agent->bw_in, agent->bw_out);
+    }
+    else //new network for this address is not active => address must not be considered
+    {
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "New network is not active\n");
 
-    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-        "API_address_change_network() Moved %d inbound and %d "
-            "outbound\n", agent->bw_in, agent->bw_out);
+      net = agent->address->solver_information;
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Before: active address %p is %s\n",
+          agent->address, GNUNET_ATS_print_network_type (net->type));
+
+      address->active = GNUNET_NO;
+      ril_get_new_address_or_delete (s, agent);
+
+      net = agent->address->solver_information;
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "After: active address %p is %s\n",
+          agent->address, GNUNET_ATS_print_network_type (net->type));
+    }
   }
 }
 
@@ -1225,7 +1409,6 @@ GAS_ril_address_preference_feedback (void *solver,
     double score)
 {
   //TODO! collect reward until next reward calculation
-  //TODO! Find out application
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
       "API_address_preference_feedback() Peer '%s' got a feedback of %+.3f from application %s for "
           "preference %s for %d seconds\n", GNUNET_i2s (peer), "UNKNOWN",
@@ -1246,7 +1429,8 @@ GAS_ril_bulk_start (void *solver)
    * bandwidth assignment triggered anyway. Therefore, changes to addresses can come and go as
    * they want. Consideration: Step-pause during bulk-start-stop period...
    */
-  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "API_bulk_start()\n");
+
+  //GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "API_bulk_start()\n");
 }
 
 /**
@@ -1259,7 +1443,8 @@ GAS_ril_bulk_stop (void *solver)
   /*
    * bulk counter down, see bulk_start()
    */
-  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "API_bulk_stop()\n");
+
+  //GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "API_bulk_stop()\n");
 }
 
 /**
@@ -1278,7 +1463,16 @@ GAS_ril_get_preferred_address (void *solver,
   struct GAS_RIL_Handle *s = solver;
   struct RIL_Peer_Agent *agent;
 
-  agent = ril_get_agent (s, peer);
+  agent = ril_get_agent (s, peer, GNUNET_NO);
+
+  if (NULL == agent)
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+        "API_get_preferred_address() No agent for peer '%s' do not suggest address\n",
+        GNUNET_i2s (peer));
+    return NULL ;
+  }
+
   agent->active = GNUNET_YES;
 
   GNUNET_assert(NULL != agent->address);
@@ -1303,7 +1497,7 @@ GAS_ril_stop_get_preferred_address (void *solver,
   struct GAS_RIL_Handle *s = solver;
   struct RIL_Peer_Agent *agent;
 
-  agent = ril_get_agent (s, peer);
+  agent = ril_get_agent (s, peer, GNUNET_NO);
   agent->active = GNUNET_NO;
 
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,