complete state reset functionality
[oweals/gnunet.git] / src / transport / gnunet-service-transport_neighbours_3way.c
index fd3ad37f97c8919ac4ca05db87f3accbcd182f18..516ef6b7063154f556592f73ede9e050664be5bc 100644 (file)
 #define KEEPALIVE_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 90)
 
 
+#define ATS_RESPONSE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
+
+
+#define SETUP_CONNECTION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
+
+
 /**
  * Entry in neighbours.
  */
@@ -284,6 +290,18 @@ struct NeighbourMapEntry
    */
   struct GNUNET_TIME_Absolute connect_ts;
 
+  /**
+   * Timeout for ATS
+   * We asked ATS for a new address for this peer
+   */
+  GNUNET_SCHEDULER_TaskIdentifier ats_suggest;
+
+  /**
+   * Task the resets the peer state after due to an pending
+   * unsuccessful connection setup
+   */
+  GNUNET_SCHEDULER_TaskIdentifier state_reset;
+
   /**
    * How often has the other peer (recently) violated the inbound
    * traffic limit?  Incremented by 10 per violation, decremented by 1
@@ -291,18 +309,11 @@ struct NeighbourMapEntry
    */
   unsigned int quota_violation_count;
 
-  /**
-   * Number of values in 'ats' array.
-   */
-  //unsigned int ats_count;
-
 
   /**
-   * Do we currently consider this neighbour connected? (as far as
-   * the connect/disconnect callbacks are concerned)?
+   * The current state of the peer
+   * Element of enum State
    */
-  //int is_connected;
-
   int state;
 
 };
@@ -400,6 +411,49 @@ print_state (int state)
   return NULL;
 }
 
+static int
+change (struct NeighbourMapEntry * n, int state, int line);
+
+static void
+ats_suggest_cancel (void *cls,
+    const struct GNUNET_SCHEDULER_TaskContext *tc);
+
+static void
+reset_task (void *cls,
+            const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct NeighbourMapEntry * n = cls;
+
+  n->state_reset = GNUNET_SCHEDULER_NO_TASK;
+
+#if DEBUG_TRANSPORT
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+      "Connection to peer `%s' %s failed in state `%s', resetting connection attempt \n",
+      GNUNET_i2s (&n->id), GST_plugins_a2s(n->plugin_name, n->addr, n->addrlen), print_state(n->state));
+#endif
+  GNUNET_STATISTICS_update (GST_stats,
+                            gettext_noop ("# failed connection attempts due to timeout"),
+                            1,
+                            GNUNET_NO);
+
+  /* resetting state */
+  n->state = S_NOT_CONNECTED;
+
+  /* destroying address */
+  GNUNET_ATS_address_destroyed (GST_ats,
+                                &n->id,
+                                n->plugin_name,
+                                n->addr,
+                                n->addrlen,
+                                NULL);
+
+  /* request new address */
+  if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK)
+    GNUNET_SCHEDULER_cancel(n->ats_suggest);
+  n->ats_suggest = GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, ats_suggest_cancel, n);
+  GNUNET_ATS_suggest_address(GST_ats, &n->id);
+}
+
 static int
 change (struct NeighbourMapEntry * n, int state, int line)
 {
@@ -414,13 +468,33 @@ change (struct NeighbourMapEntry * n, int state, int line)
         (state == S_DISCONNECT))
     {
       allowed = GNUNET_YES;
+
+      /* Schedule reset task */
+      if ((state == S_CONNECT_RECV) || (state == S_CONNECT_SENT) )
+      {
+        GNUNET_assert (n->state_reset == GNUNET_SCHEDULER_NO_TASK);
+        n->state_reset = GNUNET_SCHEDULER_add_delayed (SETUP_CONNECTION_TIMEOUT, &reset_task, n);
+      }
+
       break;
     }
     break;
   case S_CONNECT_RECV:
     if ((state == S_NOT_CONNECTED) || (state == S_DISCONNECT) ||
-        (state == S_CONNECTED))
+        (state == S_CONNECTED) || /* FIXME SENT -> RECV ISSUE!*/ (state == S_CONNECT_SENT))
     {
+      if ((state == S_CONNECTED) || (state == S_DISCONNECT) || (state == S_NOT_CONNECTED))
+      {
+#if DEBUG_TRANSPORT
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+            "Removed reset task for peer `%s' %s failed in state transition `%s' -> `%s' \n",
+            GNUNET_i2s (&n->id), GST_plugins_a2s(n->plugin_name, n->addr, n->addrlen), print_state(n->state), print_state(state));
+#endif
+        GNUNET_assert (n->state_reset != GNUNET_SCHEDULER_NO_TASK);
+        GNUNET_SCHEDULER_cancel (n->state_reset);
+        n->state_reset = GNUNET_SCHEDULER_NO_TASK;
+      }
+
       allowed = GNUNET_YES;
       break;
     }
@@ -429,6 +503,18 @@ change (struct NeighbourMapEntry * n, int state, int line)
     if ((state == S_NOT_CONNECTED) || (state == S_CONNECTED) ||
         (state == S_DISCONNECT) || /* FIXME SENT -> RECV ISSUE!*/ (state == S_CONNECT_RECV))
     {
+      if ((state == S_CONNECTED) || (state == S_DISCONNECT) || (state == S_NOT_CONNECTED))
+      {
+#if DEBUG_TRANSPORT
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+            "Removed reset task for peer `%s' %s failed in state transition `%s' -> `%s' \n",
+            GNUNET_i2s (&n->id), GST_plugins_a2s(n->plugin_name, n->addr, n->addrlen), print_state(n->state), print_state(state));
+#endif
+        GNUNET_assert (n->state_reset != GNUNET_SCHEDULER_NO_TASK);
+        GNUNET_SCHEDULER_cancel (n->state_reset);
+        n->state_reset = GNUNET_SCHEDULER_NO_TASK;
+      }
+
       allowed = GNUNET_YES;
       break;
     }
@@ -466,8 +552,10 @@ change (struct NeighbourMapEntry * n, int state, int line)
   }
 
   n->state = state;
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "State for neighbour `%s' %X changed from `%s' to `%s' in line %u\n",
+#if DEBUG_TRANSPORT
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "State for neighbour `%s' %X changed from `%s' to `%s' in line %u\n",
       GNUNET_i2s (&n->id), n, old, new, line);
+#endif
   GNUNET_free (old);
   GNUNET_free (new);
   return GNUNET_OK;
@@ -669,15 +757,18 @@ GST_neighbours_start (void *cls, GNUNET_TRANSPORT_NotifyConnect connect_cb,
   neighbours = GNUNET_CONTAINER_multihashmap_create (NEIGHBOUR_TABLE_SIZE);
 }
 
-/*
+
 static void
 send_disconnect_cont (void *cls,
     const struct GNUNET_PeerIdentity * target,
     int result)
 {
+#if DEBUG_TRANSPORT
   struct NeighbourMapEntry *n = cls;
-
-}*/
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending DISCONNECT message to peer `%4s': %i\n",
+              GNUNET_i2s (&n->id), result);
+#endif
+}
 
 static int
 send_disconnect (struct NeighbourMapEntry *n)
@@ -704,10 +795,10 @@ send_disconnect (struct NeighbourMapEntry *n)
                                          &disconnect_msg.purpose,
                                          &disconnect_msg.signature));
 
-  ret = send_with_plugin(&n->id,
-      (const char *) &disconnect_msg, sizeof (disconnect_msg),
-      UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL, n->session, n->plugin_name, n->addr, n->addrlen,
-      GNUNET_YES, NULL, NULL);
+  ret = send_with_plugin(&n->id, (const char *) &disconnect_msg, sizeof (disconnect_msg),
+                          UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL,
+                          n->session, n->plugin_name, n->addr, n->addrlen,
+                          GNUNET_YES, &send_disconnect_cont, n);
 
   if (ret == GNUNET_SYSERR)
     return GNUNET_SYSERR;
@@ -729,9 +820,6 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
   struct MessageQueue *mq;
   int was_connected = is_connected(n);
 
-  if (is_disconnecting(n) == GNUNET_YES)
-    return;
-
   /* send DISCONNECT MESSAGE */
   if (is_connected(n) || is_connecting(n))
   {
@@ -774,6 +862,11 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
   GNUNET_assert (GNUNET_YES ==
                  GNUNET_CONTAINER_multihashmap_remove (neighbours,
                                                        &n->id.hashPubKey, n));
+  if (GNUNET_SCHEDULER_NO_TASK != n->ats_suggest)
+  {
+    GNUNET_SCHEDULER_cancel (n->ats_suggest);
+    n->ats_suggest = GNUNET_SCHEDULER_NO_TASK;
+  }
   if (GNUNET_SCHEDULER_NO_TASK != n->timeout_task)
   {
     GNUNET_SCHEDULER_cancel (n->timeout_task);
@@ -880,6 +973,22 @@ disconnect_all_neighbours (void *cls, const GNUNET_HashCode * key, void *value)
 }
 
 
+static void
+ats_suggest_cancel (void *cls,
+    const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct NeighbourMapEntry *n = cls;
+
+  n->ats_suggest = GNUNET_SCHEDULER_NO_TASK;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              " ATS did not suggested address to connect to peer `%s'\n",
+              GNUNET_i2s (&n->id));
+
+  disconnect_neighbour(n);
+}
+
+
 /**
  * Cleanup the neighbours subsystem.
  */
@@ -939,6 +1048,9 @@ send_connect_continuation (void *cls,
                                  n->addrlen,
                                  NULL);
 
+    if (n->ats_suggest!= GNUNET_SCHEDULER_NO_TASK)
+      GNUNET_SCHEDULER_cancel(n->ats_suggest);
+    n->ats_suggest = GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, ats_suggest_cancel, n);
     GNUNET_ATS_suggest_address(GST_ats, &n->id);
     return;
   }
@@ -978,13 +1090,6 @@ send_switch_address_continuation (void *cls,
               n->session);
 #endif
 
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Do not forget to fix this!\n");
-    /* FIXME: We have to change the state away from connected:
-     * If ATS can not suggest another address we do not get a callback
-     * but we still think we are connected
-     */
-    //change_state(n, S_NOT_CONNECTED);
-
     GNUNET_ATS_address_destroyed (GST_ats,
                                   &n->id,
                                   n->plugin_name,
@@ -992,6 +1097,9 @@ send_switch_address_continuation (void *cls,
                                   n->addrlen,
                                   NULL);
 
+    if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK)
+      GNUNET_SCHEDULER_cancel(n->ats_suggest);
+    n->ats_suggest = GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, ats_suggest_cancel, n);
     GNUNET_ATS_suggest_address(GST_ats, &n->id);
     return;
   }
@@ -1037,6 +1145,9 @@ send_connect_ack_continuation (void *cls,
                                   n->addrlen,
                                   NULL);
 
+    if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK)
+      GNUNET_SCHEDULER_cancel(n->ats_suggest);
+    n->ats_suggest = GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, ats_suggest_cancel, n);
     GNUNET_ATS_suggest_address(GST_ats, &n->id);
 }
 
@@ -1056,7 +1167,7 @@ send_connect_ack_continuation (void *cls,
  *         connection is not up (yet)
  */
 int
-GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
+GST_neighbours_switch_to_address_3way (const struct GNUNET_PeerIdentity *peer,
                                   const char *plugin_name, const void *address,
                                   size_t address_len, struct Session *session,
                                   const struct GNUNET_ATS_Information
@@ -1081,6 +1192,12 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
     return GNUNET_NO;
   }
 
+  if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK)
+  {
+    GNUNET_SCHEDULER_cancel(n->ats_suggest);
+    n->ats_suggest = GNUNET_SCHEDULER_NO_TASK;
+  }
+
 #if DEBUG_TRANSPORT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "ATS tells us to switch to plugin `%s' address '%s' session %X for %s peer `%s'\n",
@@ -1122,17 +1239,10 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
     connect_msg.timestamp =
         GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
 
-    ret = send_with_plugin (peer, (const char *) &connect_msg, msg_len, 0, GNUNET_TIME_UNIT_FOREVER_REL, session, plugin_name, address, address_len, GNUNET_YES, &send_connect_continuation, n);
-    if (ret == GNUNET_SYSERR)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Failed to send CONNECT_MESSAGE to `%4s' using plugin `%s' address '%s' session %X\n",
-                GNUNET_i2s (peer), plugin_name,
-                (address_len == 0) ? "<inbound>" : GST_plugins_a2s (plugin_name,
-                                                                    address,
-                                                                    address_len),
-                session);
-    }
+    ret = send_with_plugin (peer, (const char *) &connect_msg, msg_len, UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL,
+                            session, plugin_name, address, address_len,
+                            GNUNET_YES, &send_connect_continuation, n);
+
     return GNUNET_NO;
   }
   /* We received a CONNECT message and asked ATS for an address */
@@ -1145,7 +1255,9 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
     connect_msg.reserved = htonl (0);
     connect_msg.timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
 
-    ret = send_with_plugin(&n->id, (const void *) &connect_msg, msg_len, 0, GNUNET_TIME_UNIT_FOREVER_REL, session, plugin_name, address, address_len, GNUNET_YES, &send_connect_ack_continuation, n);
+    ret = send_with_plugin(&n->id, (const void *) &connect_msg, msg_len, UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL,
+                           session, plugin_name, address, address_len,
+                           GNUNET_YES, &send_connect_ack_continuation, n);
     if (ret == GNUNET_SYSERR)
     {
       change_state (n, S_NOT_CONNECTED);
@@ -1164,7 +1276,9 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
     connect_msg.timestamp =
         GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
 
-    ret = send_with_plugin (peer, (const char *) &connect_msg, msg_len, 0, GNUNET_TIME_UNIT_FOREVER_REL, session, plugin_name, address, address_len, GNUNET_YES, &send_switch_address_continuation, n);
+    ret = send_with_plugin (peer, (const char *) &connect_msg, msg_len, UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL,
+                            session, plugin_name, address, address_len,
+                            GNUNET_YES, &send_switch_address_continuation, n);
     if (ret == GNUNET_SYSERR)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1177,8 +1291,12 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
     }
     return GNUNET_NO;
   }
-
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid connection state to switch addresses %u ", n->state);
+  else if (n->state == S_CONNECT_SENT)
+  {
+      //FIXME
+     return GNUNET_NO;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid connection state to switch addresses %u \n", n->state);
   GNUNET_break_op (0);
   return GNUNET_NO;
 }
@@ -1253,10 +1371,10 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target)
               "Asking ATS for suggested address to connect to peer `%s'\n",
               GNUNET_i2s (&n->id));
 #endif
+
    GNUNET_ATS_suggest_address (GST_ats, &n->id);
 }
 
-
 /**
  * Test if we're connected to the given peer.
  *
@@ -1313,15 +1431,15 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
   if ((!is_connected(n)) && (!is_connecting(n)))
     return;
 
-  // FIXME: switch address what is the state
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Do not forget to fix this!\n");
-
   /* We are connected, so ask ATS to switch addresses */
   GNUNET_SCHEDULER_cancel (n->timeout_task);
   n->timeout_task =
       GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_DISCONNECT_SESSION_TIMEOUT,
                                     &neighbour_timeout_task, n);
   /* try QUICKLY to re-establish a connection, reduce timeout! */
+  if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK)
+    GNUNET_SCHEDULER_cancel(n->ats_suggest);
+  n->ats_suggest = GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, ats_suggest_cancel, n);
   GNUNET_ATS_suggest_address (GST_ats, peer);
 }
 
@@ -1444,9 +1562,6 @@ GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity
   }
   if (!is_connected(n))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-               _("Plugin gave us %d bytes of data but somehow the session is not marked as UP yet!\n"),
-               (int) size);
     *do_forward = GNUNET_SYSERR;
     return GNUNET_TIME_UNIT_ZERO;
   }
@@ -1747,16 +1862,15 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
   const struct SessionConnectMessage *scm;
   struct QuotaSetMessage q_msg;
   struct GNUNET_MessageHeader msg;
-  struct GNUNET_TIME_Absolute ts;
   struct NeighbourMapEntry *n;
   size_t msg_len;
   size_t ret;
+  int was_connected;
 
 #if DEBUG_TRANSPORT
-#endif
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
       "Received CONNECT_ACK message from peer `%s'\n", GNUNET_i2s (peer));
-
+#endif
 
   if (ntohs (message->size) != sizeof (struct SessionConnectMessage))
   {
@@ -1766,7 +1880,6 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
 
   scm = (const struct SessionConnectMessage *) message;
   GNUNET_break_op (ntohl (scm->reserved) == 0);
-  ts = GNUNET_TIME_absolute_ntoh (scm->timestamp);
   n = lookup_neighbour (peer);
   if (NULL == n)
     n = setup_neighbour (peer);
@@ -1790,7 +1903,9 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
                              plugin_name, sender_address, sender_address_len,
                              session, ats, ats_count);
 
-  change_state (n, S_CONNECTED);
+  was_connected = is_connected(n);
+  if (!is_connected(n))
+    change_state (n, S_CONNECTED);
 
 #if DEBUG_TRANSPORT
   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -1799,18 +1914,15 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
 #endif
   GST_neighbours_set_incoming_quota(&n->id, n->bandwidth_in);
 
-  n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
-                                                      &neighbour_keepalive_task,
-                                                      n);
   /* send ACK (ACK)*/
   msg_len =  sizeof (msg);
   msg.size = htons (msg_len);
   msg.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK);
 
-  ret = send_with_plugin (&n->id, (const char *) &msg, msg_len, 0,
-      GNUNET_TIME_UNIT_FOREVER_REL,
-      n->session, n->plugin_name, n->addr, n->addrlen,
-      GNUNET_YES, NULL, NULL);
+  ret = send_with_plugin (&n->id, (const char *) &msg, msg_len, UINT32_MAX,
+                          GNUNET_TIME_UNIT_FOREVER_REL,
+                          n->session, n->plugin_name, n->addr, n->addrlen,
+                          GNUNET_YES, NULL, NULL);
 
   if (ret == GNUNET_SYSERR)
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1821,21 +1933,30 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
                                                                  n->addrlen),
               n->session);
 
-  neighbours_connected++;
-  GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1,
-                            GNUNET_NO);
-  connect_notify_cb (callback_cls, &n->id, ats, ats_count);
+
+  if (!was_connected)
+  {
+    if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK)
+      n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
+                                                        &neighbour_keepalive_task,
+                                                        n);
+
+    neighbours_connected++;
+    GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1,
+                              GNUNET_NO);
+    connect_notify_cb (callback_cls, &n->id, ats, ats_count);
 
 #if DEBUG_TRANSPORT
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Sending outbound quota of %u Bps for peer `%s' to all clients\n",
-              ntohl (n->bandwidth_out.value__), GNUNET_i2s (peer));
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Sending outbound quota of %u Bps for peer `%s' to all clients\n",
+                ntohl (n->bandwidth_out.value__), GNUNET_i2s (peer));
 #endif
-  q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
-  q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
-  q_msg.quota = n->bandwidth_out;
-  q_msg.peer = (*peer);
-  GST_clients_broadcast (&q_msg.header, GNUNET_NO);
+    q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
+    q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
+    q_msg.quota = n->bandwidth_out;
+    q_msg.peer = (*peer);
+    GST_clients_broadcast (&q_msg.header, GNUNET_NO);
+  }
 }
 
 void
@@ -1869,14 +1990,14 @@ GST_neighbours_handle_ack (const struct GNUNET_MessageHeader *message,
   }
 // FIXME check this
 //  if (n->state != S_CONNECT_RECV)
-  if (is_connecting(n))
+/*  if (is_connecting(n))
   {
     send_disconnect (n);
     change_state (n, S_DISCONNECT);
     GNUNET_break (0);
     return;
   }
-
+*/
   if (is_connected(n))
     return;
 
@@ -1896,7 +2017,8 @@ GST_neighbours_handle_ack (const struct GNUNET_MessageHeader *message,
 
   GST_neighbours_set_incoming_quota(&n->id, n->bandwidth_in);
 
-  n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
+  if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK)
+    n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
                                                       &neighbour_keepalive_task,
                                                       n);
 
@@ -1978,14 +2100,15 @@ handle_connect_blacklist_cont (void *cls,
   }
 
   GNUNET_free (bcc);
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-      "Blacklist check due to CONNECT message: `%s'\n");
 /*
   if (n->state != S_NOT_CONNECTED)
     return;*/
   change_state (n, S_CONNECT_RECV);
 
   /* Ask ATS for an address to connect via that address */
+  if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK)
+    GNUNET_SCHEDULER_cancel(n->ats_suggest);
+  n->ats_suggest = GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, ats_suggest_cancel, n);
   GNUNET_ATS_suggest_address(GST_ats, peer);
 }
 
@@ -2017,10 +2140,9 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message,
   struct BlackListCheckContext * bcc = NULL;
 
 #if DEBUG_TRANSPORT
-#endif
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
       "Received CONNECT message from peer `%s'\n", GNUNET_i2s (peer));
-
+#endif
 
   if (ntohs (message->size) != sizeof (struct SessionConnectMessage))
   {