transport notifies about addresses in use
[oweals/gnunet.git] / src / transport / gnunet-service-transport_neighbours.c
index 14987d6dea6cf84d03f95ccb87f67b8edc03ff5a..e6b298f4f82f2979e25da3950045a5f85e55f29f 100644 (file)
@@ -426,12 +426,16 @@ reset_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   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",
+#endif
+  /* This jut a temporary debug message to check if a the value
+   * SETUP_CONNECTION_TIMEOUT was choosen to small for slow machines
+   */
+  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+              "Information for developers: 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,
@@ -478,7 +482,6 @@ change (struct NeighbourMapEntry *n, int state, int line)
             GNUNET_SCHEDULER_add_delayed (SETUP_CONNECTION_TIMEOUT, &reset_task,
                                           n);
       }
-
       break;
     }
     break;
@@ -857,10 +860,22 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
                   GNUNET_i2s (&n->id));
   }
 
+  if (is_connected(n))
+  {
+     GNUNET_ATS_address_in_use (GST_ats, &n->id, n->plugin_name,
+         n->addr, n->addrlen, n->session, GNUNET_NO);
+  }
+
 
   if (is_disconnecting (n))
     return;
   change_state (n, S_DISCONNECT);
+  GST_validation_set_address_use (&n->id,
+                                 n->plugin_name,
+                                 n->session,
+                                 n->addr,
+                                 n->addrlen,
+                                 GNUNET_NO);
 
   if (n->plugin_name != NULL)
   {
@@ -1133,6 +1148,9 @@ send_switch_address_continuation (void *cls,
     GNUNET_ATS_suggest_address (GST_ats, &n->id);
     return;
   }
+  /* Tell ATS that switching addresses was successful */
+  GNUNET_ATS_address_in_use (GST_ats, &n->id, n->plugin_name, n->addr,
+                             n->addrlen, n->addr, GNUNET_YES);
 }
 
 /**
@@ -1292,7 +1310,21 @@ GST_neighbours_switch_to_address_3way (const struct GNUNET_PeerIdentity *peer,
       return GNUNET_NO;
     }
   }
+  if (n->state == S_CONNECTED) 
+    GST_validation_set_address_use (&n->id,
+                                   n->plugin_name,
+                                   n->session,
+                                   n->addr,
+                                   n->addrlen,
+                                   GNUNET_NO);
+  /* This will be a connection switch, tell ATS about it */
+  if (n->state == S_CONNECTED)
+  {
+    GNUNET_ATS_address_in_use (GST_ats, &n->id, n->plugin_name, n->addr,
+                               n->addrlen, n->addr, GNUNET_NO);
+  }
 
+  /* set new address */
   GNUNET_free_non_null (n->addr);
   n->addr = GNUNET_malloc (address_len);
   memcpy (n->addr, address, address_len);
@@ -1306,6 +1338,14 @@ GST_neighbours_switch_to_address_3way (const struct GNUNET_PeerIdentity *peer,
   n->timeout_task =
       GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
                                     &neighbour_timeout_task, n);
+  if (n->state == S_CONNECTED)
+    GST_validation_set_address_use (&n->id,
+                                   n->plugin_name,
+                                   n->session,
+                                   n->addr,
+                                   n->addrlen,
+                                   GNUNET_YES);
+
 
   if (n->state == S_DISCONNECT)
   {
@@ -1331,6 +1371,7 @@ GST_neighbours_switch_to_address_3way (const struct GNUNET_PeerIdentity *peer,
                           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 */
@@ -1389,6 +1430,29 @@ GST_neighbours_switch_to_address_3way (const struct GNUNET_PeerIdentity *peer,
 }
 
 
+/**
+ * Obtain current latency information for the given neighbour.
+ *
+ * @param peer 
+ * @return observed latency of the address, FOREVER if the address was
+ *         never successfully validated
+ */
+struct GNUNET_TIME_Relative
+GST_neighbour_get_latency (const struct GNUNET_PeerIdentity *peer)
+{
+  struct NeighbourMapEntry *n;
+
+  n = lookup_neighbour (peer);
+  if (NULL == n)
+    return GNUNET_TIME_UNIT_FOREVER_REL;
+  return GST_validation_get_address_latency (peer,
+                                            n->plugin_name,
+                                            n->session,
+                                            n->addr,
+                                            n->addrlen);
+}
+
+
 /**
  * Create an entry in the neighbour map for the given peer
  *
@@ -2013,14 +2077,15 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
   n = lookup_neighbour (peer);
   if (NULL == n)
     n = setup_neighbour (peer);
-/*
-  if (n->state != S_CONNECT_SENT)
+
+  if (!is_connecting(n))
   {
-    GNUNET_break (0);
-    send_disconnect(&n->id, n->plugin_name, n->addr, n->addrlen, n->session);
+    GNUNET_STATISTICS_update (GST_stats,
+        gettext_noop ("# unexpected CONNECT_ACK messages"), 1,
+        GNUNET_NO);
     return;
   }
-*/
+
   if (NULL != session)
     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
                      "transport-ats",
@@ -2031,10 +2096,18 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
 
   was_connected = is_connected (n);
   if (!is_connected (n))
+  {
     change_state (n, S_CONNECTED);
+    GST_validation_set_address_use (&n->id,
+                                   n->plugin_name,
+                                   n->session,
+                                   n->addr,
+                                   n->addrlen,
+                                   GNUNET_YES);
+  }
 
-  GNUNET_ATS_address_in_use (GST_ats, peer, plugin_name, sender_address,
-                             sender_address_len, session, GNUNET_YES);
+  GNUNET_ATS_address_in_use (GST_ats, &n->id, n->plugin_name, n->addr,
+                             n->addrlen, n->addr, GNUNET_YES);
 
 #if DEBUG_TRANSPORT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2133,6 +2206,13 @@ GST_neighbours_handle_ack (const struct GNUNET_MessageHeader *message,
   if (is_connected (n))
     return;
 
+  if (!is_connecting(n))
+  {
+    GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# unexpected ACK messages"), 1,
+                              GNUNET_NO);
+    return;
+  }
+
   if (NULL != session)
     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
                      "transport-ats",
@@ -2144,8 +2224,8 @@ GST_neighbours_handle_ack (const struct GNUNET_MessageHeader *message,
   was_connected = is_connected (n);
   change_state (n, S_CONNECTED);
 
-  GNUNET_ATS_address_in_use (GST_ats, peer, plugin_name, sender_address,
-                             sender_address_len, session, GNUNET_YES);
+  GNUNET_ATS_address_in_use (GST_ats, &n->id, n->plugin_name, n->addr,
+                             n->addrlen, n->addr, GNUNET_YES);
 
   GST_neighbours_set_incoming_quota (&n->id, n->bandwidth_in);
 
@@ -2156,6 +2236,12 @@ GST_neighbours_handle_ack (const struct GNUNET_MessageHeader *message,
 
   if (!was_connected)
   {
+    GST_validation_set_address_use (&n->id,
+                                   n->plugin_name,
+                                   n->session,
+                                   n->addr,
+                                   n->addrlen,
+                                   GNUNET_YES);
     neighbours_connected++;
     GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1,
                               GNUNET_NO);
@@ -2315,19 +2401,20 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message,
   /* do blacklist check */
   bcc =
       GNUNET_malloc (sizeof (struct BlackListCheckContext) +
-                     sizeof (struct GNUNET_ATS_Information) * ats_count +
+                     sizeof (struct GNUNET_ATS_Information) * (ats_count + 1) +
                      sender_address_len + strlen (plugin_name) + 1);
 
   bcc->ts = GNUNET_TIME_absolute_ntoh (scm->timestamp);
 
-  bcc->ats_count = ats_count;
+  bcc->ats_count = ats_count + 1;
   bcc->sender_address_len = sender_address_len;
   bcc->session = session;
 
   bcc->ats = (struct GNUNET_ATS_Information *) &bcc[1];
   memcpy (bcc->ats, ats, sizeof (struct GNUNET_ATS_Information) * ats_count);
-
-  bcc->sender_address = (char *) &bcc->ats[ats_count];
+  bcc->ats[ats_count].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY);
+  bcc->ats[ats_count].value = htonl ((uint32_t) GST_neighbour_get_latency (peer).rel_value);
+  bcc->sender_address = (char *) &bcc->ats[ats_count + 1];
   memcpy (bcc->sender_address, sender_address, sender_address_len);
 
   bcc->plugin_name = &bcc->sender_address[sender_address_len];