fix div by zero
[oweals/gnunet.git] / src / transport / gnunet-service-transport_neighbours.c
index bbda715a24dd6ecbcf935540c8527e81d1307e9d..3965bc13ed4404b9ee51696bed9841e05956584d 100644 (file)
@@ -2,20 +2,18 @@
      This file is part of GNUnet.
      Copyright (C) 2010-2015 GNUnet e.V.
 
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     or (at your option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
+     Affero General Public License for more details.
+    
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 /**
@@ -181,7 +179,7 @@ struct GNUNET_ATS_SessionQuotaMessage
 
 
 /**
- * Message we send to the other peer to notify him that we intentionally
+ * Message we send to the other peer to notify it that we intentionally
  * are disconnecting (to reduce timeouts).  This is just a friendly
  * notification, peers must not rely on always receiving disconnect
  * messages.
@@ -616,6 +614,8 @@ neighbours_changed_notification (const struct GNUNET_PeerIdentity *peer,
                                  struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
                                  struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
 {
+  (void) bandwidth_in;
+  (void) bandwidth_out;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Notifying about change for peer `%s' with address `%s' in state `%s' timing out at %s\n",
               GNUNET_i2s (peer),
@@ -993,6 +993,10 @@ send_disconnect_cont (void *cls,
 {
   struct NeighbourMapEntry *n;
 
+  (void) cls;
+  (void) result;
+  (void) payload;
+  (void) physical;
   n = lookup_neighbour (target);
   if (NULL == n)
     return; /* already gone */
@@ -1131,10 +1135,12 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
  * our own receive rate and informs the neighbour about
  * the new quota.
  *
- * @param n neighbour entry to change qutoa for
+ * @param n neighbour entry to change quota for
  * @param quota new quota
+ * @return #GNUNET_YES if @a n is still valid, #GNUNET_NO if
+ *   @a n was freed
  */
-static void
+static int
 set_incoming_quota (struct NeighbourMapEntry *n,
                     struct GNUNET_BANDWIDTH_Value32NBO quota)
 {
@@ -1158,7 +1164,7 @@ set_incoming_quota (struct NeighbourMapEntry *n,
                                 GNUNET_TIME_UNIT_FOREVER_REL,
                                 GNUNET_NO,
                                 NULL, NULL);
-    return;
+    return GNUNET_YES;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Disconnecting peer `%s' due to SET_QUOTA\n",
@@ -1168,6 +1174,7 @@ set_incoming_quota (struct NeighbourMapEntry *n,
                               gettext_noop ("# disconnects due to quota of 0"),
                               1, GNUNET_NO);
   disconnect_neighbour (n);
+  return GNUNET_NO;
 }
 
 
@@ -1196,8 +1203,10 @@ set_primary_address (struct NeighbourMapEntry *n,
     if (n->primary_address.bandwidth_in.value__ != bandwidth_in.value__)
     {
       n->primary_address.bandwidth_in = bandwidth_in;
-      set_incoming_quota (n,
-                          bandwidth_in);
+      if (GNUNET_YES !=
+         set_incoming_quota (n,
+                             bandwidth_in))
+       return;
     }
     if (n->primary_address.bandwidth_out.value__ != bandwidth_out.value__)
     {
@@ -1237,8 +1246,10 @@ set_primary_address (struct NeighbourMapEntry *n,
   /* subsystems about address use */
   GST_validation_set_address_use (n->primary_address.address,
                                   GNUNET_YES);
-  set_incoming_quota (n,
-                      bandwidth_in);
+  if (GNUNET_YES !=
+      set_incoming_quota (n,
+                         bandwidth_in))
+    return;
   send_outbound_quota_to_clients (n);
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Neighbour `%s' switched to address `%s'\n",
@@ -1394,6 +1405,14 @@ try_transmission_to_peer (struct NeighbourMapEntry *n)
   }
   if (NULL == mq)
     return;                     /* no more messages */
+  if (NULL == n->primary_address.address)
+  {
+    /* transmit_send_continuation() caused us to drop session,
+       can't try transmission anymore. */
+    return;
+  }
+
+
   GNUNET_CONTAINER_DLL_remove (n->messages_head,
                                n->messages_tail,
                                mq);
@@ -1805,6 +1824,9 @@ send_session_syn_cont (void *cls,
 {
   struct NeighbourMapEntry *n;
 
+  (void) cls;
+  (void) size_payload;
+  (void) size_on_wire;
   n = lookup_neighbour (target);
   if (NULL == n)
   {
@@ -1978,6 +2000,9 @@ send_session_syn_ack_cont (void *cls,
 {
   struct NeighbourMapEntry *n;
 
+  (void) cls;
+  (void) size_payload;
+  (void) size_on_wire;
   n = lookup_neighbour (target);
   if (NULL == n)
   {
@@ -2118,6 +2143,8 @@ inbound_bw_tracker_update (void *cls)
               "New inbound delay for peer `%s' is %llu ms\n",
               GNUNET_i2s (&n->id),
               (unsigned long long) delay.rel_value_us / 1000LL);
+  if (NULL == n->primary_address.session)
+    return;
   papi->update_inbound_delay (papi->cls,
                               &n->id,
                               n->primary_address.session,
@@ -2136,13 +2163,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;
@@ -2250,6 +2282,7 @@ GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message,
   {
     /* This is a new neighbour and set to not connected */
     n = setup_neighbour (peer);
+    GNUNET_assert (NULL != n);
   }
 
   /* Remember this SYN message in neighbour */
@@ -2319,6 +2352,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;
@@ -2386,8 +2420,10 @@ try_run_fast_ats_update (const struct GNUNET_HELLO_Address *address,
   if (n->primary_address.bandwidth_in.value__ != bandwidth_in.value__)
   {
     n->primary_address.bandwidth_in = bandwidth_in;
-    set_incoming_quota (n,
-                        bandwidth_in);
+    if (GNUNET_YES !=
+       set_incoming_quota (n,
+                           bandwidth_in))
+      return GNUNET_NO;
   }
   if (n->primary_address.bandwidth_out.value__ != bandwidth_out.value__)
   {
@@ -2426,7 +2462,10 @@ switch_address_bl_check_cont (void *cls,
     goto cleanup;
 
   papi = GST_plugins_find (address->transport_name);
-  GNUNET_assert (NULL != papi);
+  if (NULL == papi) {
+    /* This can happen during shutdown. */
+    goto cleanup;
+  }
 
   if (GNUNET_NO == result)
   {
@@ -2496,6 +2535,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;
   }
 
@@ -2789,6 +2834,7 @@ send_utilization_data (void *cls,
   uint32_t bps_out;
   struct GNUNET_TIME_Relative delta;
 
+  (void) cls;
   if ( (GNUNET_YES != test_connected (n)) ||
        (NULL == n->primary_address.address) )
     return GNUNET_OK;
@@ -2819,11 +2865,12 @@ send_utilization_data (void *cls,
 /**
  * Task transmitting utilization in a regular interval
  *
- * @param cls the 'struct NeighbourMapEntry' for which we are running
+ * @param cls the `struct NeighbourMapEntry` for which we are running
  */
 static void
 utilization_transmission (void *cls)
 {
+  (void) cls;
   util_transmission_tk = NULL;
   GNUNET_CONTAINER_multipeermap_iterate (neighbours,
                                          &send_utilization_data,
@@ -3034,7 +3081,7 @@ master_task (void *cls)
 
 /**
  * Send a ACK message to the neighbour to confirm that we
- * got his SYN_ACK.
+ * got its SYN_ACK.
  *
  * @param n neighbour to send the ACK to
  */
@@ -3079,6 +3126,7 @@ GST_neighbours_handle_session_syn_ack (const struct GNUNET_MessageHeader *messag
   struct GNUNET_TIME_Absolute ts;
   struct NeighbourMapEntry *n;
 
+  (void) session;
   if (ntohs (message->size) != sizeof (struct TransportSynMessage))
   {
     GNUNET_break_op (0);
@@ -3352,6 +3400,7 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message,
 {
   struct NeighbourMapEntry *n;
 
+  (void) session;
   if (ntohs (message->size) != sizeof (struct GNUNET_MessageHeader))
   {
     GNUNET_break_op (0);
@@ -3625,6 +3674,7 @@ neighbours_iterate (void *cls,
   struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in;
   struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out;
 
+  (void) key;
   if (NULL != n->primary_address.address)
   {
     bandwidth_in = n->primary_address.bandwidth_in;
@@ -3717,6 +3767,7 @@ GST_neighbour_get_current_address (const struct GNUNET_PeerIdentity *peer)
 void
 GST_neighbours_start (unsigned int max_fds)
 {
+  (void) max_fds;
   neighbours = GNUNET_CONTAINER_multipeermap_create (NEIGHBOUR_TABLE_SIZE,
                                                      GNUNET_NO);
   util_transmission_tk = GNUNET_SCHEDULER_add_delayed (UTIL_TRANSMISSION_INTERVAL,
@@ -3740,6 +3791,8 @@ disconnect_all_neighbours (void *cls,
 {
   struct NeighbourMapEntry *n = value;
 
+  (void) cls;
+  (void) key;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Disconnecting peer `%4s' during shutdown\n",
               GNUNET_i2s (&n->id));