-removing 2nd argument from GNUNET_CLIENT_disconnect as it was virtually always GNUNE...
[oweals/gnunet.git] / src / nse / gnunet-service-nse.c
index bf78e23718ed609f5c785d7f432331078e542c9d..6a7248cb563b31333287e120d16aac30adce15f0 100644 (file)
@@ -59,7 +59,7 @@
  * production).  The associated code should also probably be removed
  * once we're done with experiments.
  */
-#define ENABLE_HISTOGRAM GNUNET_NO
+#define ENABLE_HISTOGRAM GNUNET_YES
 
 /**
  * Over how many values do we calculate the weighted average?
@@ -569,14 +569,14 @@ transmit_ready (void *cls, size_t size, void *buf)
   unsigned int idx;
 
   peer_entry->th = NULL;
-  if (buf == NULL)
+  if (NULL == buf)
   {
     /* client disconnected */
     return 0;
   }
   GNUNET_assert (size >= sizeof (struct GNUNET_NSE_FloodMessage));
   idx = estimate_index;
-  if (peer_entry->previous_round == GNUNET_NO)
+  if (GNUNET_NO == peer_entry->previous_round)
   {
     idx = (idx + HISTORY_SIZE - 1) % HISTORY_SIZE;
     peer_entry->previous_round = GNUNET_YES;
@@ -635,6 +635,7 @@ transmit_task_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   struct NSEPeerEntry *peer_entry = cls;
 
   peer_entry->transmit_task = GNUNET_SCHEDULER_NO_TASK;
+
   GNUNET_assert (NULL == peer_entry->th);
   peer_entry->th =
       GNUNET_CORE_notify_transmit_ready (coreAPI, GNUNET_NO, NSE_PRIORITY,
@@ -713,12 +714,12 @@ schedule_current_round (void *cls, const GNUNET_HashCode * key, void *value)
   struct NSEPeerEntry *peer_entry = value;
   struct GNUNET_TIME_Relative delay;
 
-  if (peer_entry->th != NULL)
+  if (NULL != peer_entry->th)
   {
     peer_entry->previous_round = GNUNET_NO;
     return GNUNET_OK;
   }
-  if (peer_entry->transmit_task != GNUNET_SCHEDULER_NO_TASK)
+  if (GNUNET_SCHEDULER_NO_TASK != peer_entry->transmit_task)
   {
     GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
     peer_entry->previous_round = GNUNET_NO;
@@ -762,15 +763,15 @@ update_flood_message (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
         GNUNET_SCHEDULER_add_delayed (offset, &update_flood_message, NULL);
     return;
   }
-  current_timestamp = next_timestamp;
-  next_timestamp =
-      GNUNET_TIME_absolute_add (current_timestamp, gnunet_nse_interval);
   estimate_index = (estimate_index + 1) % HISTORY_SIZE;
   if (estimate_count < HISTORY_SIZE)
     estimate_count++;
+  current_timestamp = next_timestamp;
+  next_timestamp =
+      GNUNET_TIME_absolute_add (current_timestamp, gnunet_nse_interval);
   if ((current_timestamp.abs_value ==
       GNUNET_TIME_absolute_ntoh (next_message.timestamp).abs_value) &&
-      (get_matching_bits (current_timestamp, &my_identity) >
+      (get_matching_bits (current_timestamp, &my_identity) <
       ntohl(next_message.matching_bits)))
   {
     /* we received a message for this round way early, use it! */
@@ -979,7 +980,11 @@ update_flood_times (void *cls, const GNUNET_HashCode * key, void *value)
   {
     /* still stuck in previous round, no point to update, check that
      * we are active here though... */
-    GNUNET_break (peer_entry->transmit_task != GNUNET_SCHEDULER_NO_TASK);
+    if (GNUNET_SCHEDULER_NO_TASK == peer_entry->transmit_task &&
+                  NULL == peer_entry->th)
+    {
+        GNUNET_break (0);
+    }
     return GNUNET_OK;
   }
   if (peer_entry->transmit_task != GNUNET_SCHEDULER_NO_TASK)
@@ -1061,8 +1066,7 @@ handle_p2p_size_estimate (void *cls, const struct GNUNET_PeerIdentity *peer,
   else if (ts.abs_value ==
            current_timestamp.abs_value - gnunet_nse_interval.rel_value)
     idx = (estimate_index + HISTORY_SIZE - 1) % HISTORY_SIZE;
-  else if (ts.abs_value ==
-           next_timestamp.abs_value - gnunet_nse_interval.rel_value)
+  else if (ts.abs_value == next_timestamp.abs_value)
   {
     if (matching_bits <= ntohl (next_message.matching_bits))
       return GNUNET_OK;         /* ignore, simply too early/late */
@@ -1118,8 +1122,9 @@ handle_p2p_size_estimate (void *cls, const struct GNUNET_PeerIdentity *peer,
   }
   if (matching_bits < ntohl (size_estimate_messages[idx].matching_bits))
   {
-    if ((idx < estimate_index) && (peer_entry->previous_round == GNUNET_YES))
+    if ((idx < estimate_index) && (peer_entry->previous_round == GNUNET_YES)) {
       peer_entry->previous_round = GNUNET_NO;
+    }
     /* push back our result now, that peer is spreading bad information... */
     if (NULL == peer_entry->th)
     {
@@ -1144,6 +1149,11 @@ handle_p2p_size_estimate (void *cls, const struct GNUNET_PeerIdentity *peer,
   /* cancel transmission from us to this peer for this round */
   if (idx == estimate_index)
   {
+      /* Cancel transmission in the other direction, as this peer clearly has
+       up-to-date information already. Even if we didn't talk to this peer in
+       the previous round, we should no longer send it stale information as it
+       told us about the current round! */
+      peer_entry->previous_round = GNUNET_YES;
       /* cancel any activity for current round */
       if (peer_entry->transmit_task != GNUNET_SCHEDULER_NO_TASK)
       {
@@ -1182,7 +1192,8 @@ handle_p2p_size_estimate (void *cls, const struct GNUNET_PeerIdentity *peer,
 
 
 /**
- * Method called whenever a peer connects.
+ * Method called whenever a peer connects. Sets up the PeerEntry and
+ * schedules the initial size info transmission to this peer.
  *
  * @param cls closure
  * @param peer peer identity this notification is about
@@ -1214,7 +1225,8 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer,
 
 
 /**
- * Method called whenever a peer disconnects.
+ * Method called whenever a peer disconnects. Deletes the PeerEntry and cancels
+ * any pending transmission requests to that peer.
  *
  * @param cls closure
  * @param peer peer identity this notification is about
@@ -1237,8 +1249,10 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
   GNUNET_assert (GNUNET_YES ==
                  GNUNET_CONTAINER_multihashmap_remove (peers, &peer->hashPubKey,
                                                        pos));
-  if (pos->transmit_task != GNUNET_SCHEDULER_NO_TASK)
+  if (pos->transmit_task != GNUNET_SCHEDULER_NO_TASK) {
     GNUNET_SCHEDULER_cancel (pos->transmit_task);
+    pos->transmit_task = GNUNET_SCHEDULER_NO_TASK;
+  }
   if (pos->th != NULL)
   {
     GNUNET_CORE_notify_transmit_ready_cancel (pos->th);
@@ -1318,7 +1332,7 @@ core_init (void *cls, struct GNUNET_CORE_Handle *server,
   struct GNUNET_TIME_Absolute now;
   struct GNUNET_TIME_Absolute prev_time;
 
-  if (server == NULL)
+  if (NULL == server)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection to core FAILED!\n");
     GNUNET_SCHEDULER_shutdown ();
@@ -1337,9 +1351,11 @@ core_init (void *cls, struct GNUNET_CORE_Handle *server,
   estimate_count = 0;
   if (GNUNET_YES == check_proof_of_work (&my_public_key, my_proof))
   {
+    int idx = (estimate_index + HISTORY_SIZE - 1) % HISTORY_SIZE;
     prev_time.abs_value =
         current_timestamp.abs_value - gnunet_nse_interval.rel_value;
-    setup_flood_message (estimate_index, prev_time);
+    setup_flood_message (idx, prev_time);
+    setup_flood_message (estimate_index, current_timestamp);
     estimate_count++;
   }
   flood_task =