Merge branch 'master' of ssh://gnunet.org/gnunet
[oweals/gnunet.git] / src / transport / gnunet-service-transport_neighbours.c
index 9d1c9459e7bd8701488b5acbfd8d268e46a2ed73..19f5fd0819aaf91e9803aff94b2466e9e67612c2 100644 (file)
@@ -26,8 +26,6 @@
 #include "platform.h"
 #include "gnunet_ats_service.h"
 #include "gnunet-service-transport_ats.h"
-#include "gnunet-service-transport_blacklist.h"
-#include "gnunet-service-transport_clients.h"
 #include "gnunet-service-transport_neighbours.h"
 #include "gnunet-service-transport_manipulation.h"
 #include "gnunet-service-transport_plugins.h"
@@ -515,6 +513,41 @@ print_ack_state (enum GST_ACK_State s)
 }
 
 
+/**
+ * Send information about a new outbound quota to our clients.
+ * Note that the outbound quota is enforced client-side (i.e.
+ * in libgnunettransport).
+ *
+ * @param n affected peer
+ */
+static void
+send_outbound_quota_to_clients (struct NeighbourMapEntry *n)
+{
+  struct QuotaSetMessage q_msg;
+  struct GNUNET_BANDWIDTH_Value32NBO bandwidth_min;
+
+  if (! GNUNET_TRANSPORT_is_connected (n->state))
+    return;
+#if IGNORE_INBOUND_QUOTA
+  bandwidth_min = n->primary_address.bandwidth_out;
+#else
+  bandwidth_min = GNUNET_BANDWIDTH_value_min (n->primary_address.bandwidth_out,
+                                              n->neighbour_receive_quota);
+#endif
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Sending outbound quota of %u Bps for peer `%s' to all clients\n",
+              ntohl (bandwidth_min.value__),
+              GNUNET_i2s (&n->id));
+  q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
+  q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
+  q_msg.quota = bandwidth_min;
+  q_msg.peer = n->id;
+  GST_clients_broadcast (&q_msg.header,
+                        GNUNET_NO);
+}
+
+
 /**
  * Notify our clients that another peer connected to us.
  *
@@ -627,40 +660,6 @@ test_connected (struct NeighbourMapEntry *n)
 }
 
 
-/**
- * Send information about a new outbound quota to our clients.
- * Note that the outbound quota is enforced client-side (i.e.
- * in libgnunettransport).
- *
- * @param n affected peer
- */
-static void
-send_outbound_quota_to_clients (struct NeighbourMapEntry *n)
-{
-  struct QuotaSetMessage q_msg;
-  struct GNUNET_BANDWIDTH_Value32NBO bandwidth_min;
-
-  if (! GNUNET_TRANSPORT_is_connected (n->state))
-    return;
-#if IGNORE_INBOUND_QUOTA
-  bandwidth_min = n->primary_address.bandwidth_out;
-#else
-  bandwidth_min = GNUNET_BANDWIDTH_value_min (n->primary_address.bandwidth_out,
-                                              n->neighbour_receive_quota);
-#endif
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Sending outbound quota of %u Bps for peer `%s' to all clients\n",
-              ntohl (bandwidth_min.value__),
-              GNUNET_i2s (&n->id));
-  q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
-  q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
-  q_msg.quota = bandwidth_min;
-  q_msg.peer = n->id;
-  GST_clients_broadcast (&q_msg.header, GNUNET_NO);
-}
-
-
 /**
  * We don't need a given neighbour address any more.
  * Release its resources and give appropriate notifications
@@ -736,9 +735,9 @@ set_state_and_timeout (struct NeighbourMapEntry *n,
   {
     /* new timeout is earlier, reschedule master task */
     GNUNET_SCHEDULER_cancel (n->task);
-    n->task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (timeout),
-                                            &master_task,
-                                            n);
+    n->task = GNUNET_SCHEDULER_add_at (timeout,
+                                       &master_task,
+                                       n);
   }
   n->timeout = timeout;
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -1151,17 +1150,18 @@ set_incoming_quota (struct NeighbourMapEntry *n,
     sqm.header.size = htons (sizeof (struct GNUNET_ATS_SessionQuotaMessage));
     sqm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_QUOTA);
     sqm.quota = quota.value__;
-    (void) send_with_session (n,
-                              &sqm,
-                              sizeof (sqm),
-                              UINT32_MAX - 1,
-                              GNUNET_TIME_UNIT_FOREVER_REL,
-                              GNUNET_NO,
-                              NULL, NULL);
+    if (NULL != n->primary_address.session)
+      (void) send_with_session (n,
+                                &sqm,
+                                sizeof (sqm),
+                                UINT32_MAX - 1,
+                                GNUNET_TIME_UNIT_FOREVER_REL,
+                                GNUNET_NO,
+                                NULL, NULL);
     return;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Disconnecting peer `%4s' due to SET_QUOTA\n",
+              "Disconnecting peer `%s' due to SET_QUOTA\n",
               GNUNET_i2s (&n->id));
   if (GNUNET_YES == test_connected (n))
     GNUNET_STATISTICS_update (GST_stats,
@@ -1766,7 +1766,7 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target,
   mq = GNUNET_malloc (sizeof (struct MessageQueue) + msg_size);
   mq->cont = cont;
   mq->cont_cls = cont_cls;
-  memcpy (&mq[1], msg, msg_size);
+  GNUNET_memcpy (&mq[1], msg, msg_size);
   mq->message_buf = (const char *) &mq[1];
   mq->message_buf_size = msg_size;
   mq->timeout = GNUNET_TIME_relative_to_absolute (timeout);
@@ -2136,13 +2136,18 @@ setup_neighbour (const struct GNUNET_PeerIdentity *peer)
 {
   struct NeighbourMapEntry *n;
 
+  if (0 ==
+      memcmp (&GST_my_identity,
+              peer,
+              sizeof (struct GNUNET_PeerIdentity)))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Cowardly refusing to consider myself my neighbour!\n");
+    return NULL;
+  }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Creating new neighbour entry for `%s'\n",
              GNUNET_i2s (peer));
-  GNUNET_assert (0 !=
-                 memcmp (&GST_my_identity,
-                         peer,
-                         sizeof (struct GNUNET_PeerIdentity)));
   n = GNUNET_new (struct NeighbourMapEntry);
   n->id = *peer;
   n->ack_state = ACK_UNDEFINED;
@@ -2237,11 +2242,20 @@ GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message,
   scm = (const struct TransportSynMessage *) message;
   GNUNET_break_op (0 == ntohl (scm->reserved));
   ts = GNUNET_TIME_absolute_ntoh (scm->timestamp);
+  if (0 ==
+      memcmp (&GST_my_identity,
+              peer,
+              sizeof (struct GNUNET_PeerIdentity)))
+  {
+    /* loopback connection-to-self, ignore */
+    return GNUNET_SYSERR;
+  }
   n = lookup_neighbour (peer);
   if (NULL == n)
   {
     /* This is a new neighbour and set to not connected */
     n = setup_neighbour (peer);
+    GNUNET_assert (NULL != n);
   }
 
   /* Remember this SYN message in neighbour */
@@ -2311,6 +2325,7 @@ GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message,
     /* Get rid of remains and re-try */
     free_neighbour (n);
     n = setup_neighbour (peer);
+    GNUNET_assert (NULL != n);
     /* Remember the SYN time stamp for ACK message */
     n->ack_state = ACK_SEND_SYN_ACK;
     n->connect_ack_timestamp = ts;
@@ -2488,6 +2503,12 @@ switch_address_bl_check_cont (void *cls,
   if (NULL == (n = lookup_neighbour (peer)))
   {
     n = setup_neighbour (peer);
+    if (NULL == n)
+    {
+      /* not sure how this can happen... */
+      GNUNET_break (0);
+      goto cleanup;
+    }
     n->state = GNUNET_TRANSPORT_PS_INIT_ATS;
   }