Avoid trying to disconnect a neighbour twice
[oweals/gnunet.git] / src / transport / gnunet-service-transport_neighbours.c
index 87dd9c2130b2eb0309644aca3e74d62eadbaf956..d8da8235b1cd6e6a671a3303881d0dd27c66399c 100644 (file)
@@ -391,7 +391,7 @@ struct NeighbourMapEntry
   /**
    * Time where we should cut the connection (timeout) if we don't
    * make progress in the state machine (or get a KEEPALIVE_RESPONSE
-   * if we are in #S_CONNECTED).
+   * if we are in #GNUNET_TRANSPORT_PS_CONNECTED).
    */
   struct GNUNET_TIME_Absolute timeout;
 
@@ -2140,6 +2140,7 @@ setup_neighbour (const struct GNUNET_PeerIdentity *peer)
   n->id = *peer;
   n->ack_state = ACK_UNDEFINED;
   n->last_util_transmission = GNUNET_TIME_absolute_get();
+  n->neighbour_receive_quota = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
   GNUNET_BANDWIDTH_tracker_init (&n->in_tracker,
                                  &inbound_bw_tracker_update,
                                  n,
@@ -2499,14 +2500,20 @@ try_run_fast_ats_update (const struct GNUNET_HELLO_Address *address,
                    GST_ats_is_known (n->primary_address.address,
                                      n->primary_address.session));
   }
-  n->primary_address.bandwidth_in = bandwidth_in;
-  n->primary_address.bandwidth_out = bandwidth_out;
-  GST_neighbours_set_incoming_quota (&address->peer,
-                                     bandwidth_in);
-  bandwidth_min = GNUNET_BANDWIDTH_value_min (bandwidth_out,
-                                              n->neighbour_receive_quota);
-  send_outbound_quota_to_clients (&address->peer,
-                                  bandwidth_min);
+  if (n->primary_address.bandwidth_in.value__ != bandwidth_in.value__)
+  {
+    n->primary_address.bandwidth_in = bandwidth_in;
+    GST_neighbours_set_incoming_quota (&address->peer,
+                                       bandwidth_in);
+  }
+  if (n->primary_address.bandwidth_out.value__ != bandwidth_out.value__)
+  {
+    n->primary_address.bandwidth_out = bandwidth_out;
+    bandwidth_min = GNUNET_BANDWIDTH_value_min (bandwidth_out,
+                                                n->neighbour_receive_quota);
+    send_outbound_quota_to_clients (&address->peer,
+                                    bandwidth_min);
+  }
   return GNUNET_OK;
 }
 
@@ -3568,7 +3575,9 @@ GST_neighbours_test_connected (const struct GNUNET_PeerIdentity *target)
 
 
 /**
- * Change the incoming quota for the given peer.
+ * Change the incoming quota for the given peer.  Updates
+ * our own receive rate and informs the neighbour about
+ * the new quota.
  *
  * @param neighbour identity of peer to change qutoa for
  * @param quota new quota
@@ -3592,7 +3601,21 @@ GST_neighbours_set_incoming_quota (const struct GNUNET_PeerIdentity *neighbour,
               ntohl (quota.value__), GNUNET_i2s (&n->id));
   GNUNET_BANDWIDTH_tracker_update_quota (&n->in_tracker, quota);
   if (0 != ntohl (quota.value__))
+  {
+    struct SessionQuotaMessage sqm;
+
+    sqm.header.size = htons (sizeof (struct 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);
     return;
+  }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Disconnecting peer `%4s' due to SET_QUOTA\n",
               GNUNET_i2s (&n->id));
@@ -3661,7 +3684,9 @@ GST_neighbours_handle_quota_message (const struct GNUNET_PeerIdentity *peer,
     /* gone already */
     return;
   }
-  n->neighbour_receive_quota = GNUNET_BANDWIDTH_value_init (ntohl (sqm->quota));
+  n->neighbour_receive_quota
+    = GNUNET_BANDWIDTH_value_max (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT,
+                                  GNUNET_BANDWIDTH_value_init (ntohl (sqm->quota)));
 
   bandwidth_min = GNUNET_BANDWIDTH_value_min (n->primary_address.bandwidth_out,
                                               n->neighbour_receive_quota);
@@ -3745,7 +3770,11 @@ GST_neighbours_handle_disconnect_message (const struct GNUNET_PeerIdentity *peer
     GNUNET_break_op (0);
     return;
   }
-  n->delayed_disconnect_task = GNUNET_SCHEDULER_add_now (&delayed_disconnect, n);
+  if (NULL == n->delayed_disconnect_task)
+  {
+    n->delayed_disconnect_task = GNUNET_SCHEDULER_add_now (&delayed_disconnect,
+                                                           n);
+  }
 }