push back
[oweals/gnunet.git] / src / nse / gnunet-service-nse.c
index 10ecac0262b5ef5177f8854dbde6146e3dcb9b9c..3d980ca26ae04eed46f6671d496b9c8a54c1ea1c 100644 (file)
 #include "gnunet_nse_service.h"
 #include "nse.h"
 
+/**
+ * Send messages on connect.
+ */
+#define SEND_ON_CONNECT GNUNET_YES
+
+/**
+ * Should we generate a histogram with the time stamps of when we received
+ * NSE messages to disk? (for performance evaluation only, not useful in
+ * production)
+ */
+#define ENABLE_HISTOGRAM GNUNET_YES
+
 /**
  * Over how many values do we calculate the weighted average?
  */
@@ -76,6 +88,11 @@ static struct GNUNET_TIME_Relative gnunet_nse_interval;
 static struct GNUNET_TIME_Relative proof_find_delay;
 
 
+#if ENABLE_HISTOGRAM
+static struct GNUNET_BIO_WriteHandle *wh;
+#endif
+
+
 /**
  * Per-peer information.
  */
@@ -291,10 +308,11 @@ setup_estimate_message (struct GNUNET_NSE_ClientMessage *em)
   mean = 0.0;
   sum = 0.0;
   sumweight = 0.0;
-  for (i=0;i<estimate_count; i++)
+  for (i = 0; i < estimate_count; i++)
     {
-      val = htonl (size_estimate_messages[(estimate_index - i + HISTORY_SIZE) % HISTORY_SIZE].matching_bits);
-      weight = estimate_count + 1 - i;
+      val = htonl (size_estimate_messages[(estimate_index - i + HISTORY_SIZE)
+          % HISTORY_SIZE].matching_bits);
+      weight = 1; /* was: estimate_count + 1 - i; */
 
       temp = weight + sumweight;
       q = val - mean;
@@ -314,11 +332,12 @@ setup_estimate_message (struct GNUNET_NSE_ClientMessage *em)
   em->header.type
     = htons (GNUNET_MESSAGE_TYPE_NSE_ESTIMATE);
   em->reserved = htonl (0);
-  em->size_estimate = mean - 0.5;
+  em->timestamp = GNUNET_TIME_absolute_hton(GNUNET_TIME_absolute_get());
+  em->size_estimate = mean - 1.0/3.0;
   em->std_deviation = std_dev;
   GNUNET_STATISTICS_set (stats, 
                         "# nodes in the network (estimate)",
-                        (uint64_t) pow (2, mean - 0.5), GNUNET_NO);
+                        (uint64_t) pow (2, mean - 1.0/3.0), GNUNET_NO);
 }
 
 
@@ -689,7 +708,7 @@ update_flood_message(void *cls,
     setup_flood_message (estimate_index, current_timestamp);
   next_message.matching_bits = htonl (0); /* reset for 'next' round */
   hop_count_max = 0;
-  for (i=0;i<HISTORY_SIZE;i++)
+  for (i = 0; i < HISTORY_SIZE; i++)
     hop_count_max = GNUNET_MAX (ntohl (size_estimate_messages[i].hop_count),
                                hop_count_max);
   GNUNET_CONTAINER_multihashmap_iterate (peers,
@@ -802,9 +821,11 @@ find_proof (void *cls,
       if (nse_work_required <= count_leading_zeroes(&result))
        {
          my_proof = counter;
-         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                     _("Proof of work found: %llu!\n"),
+#if DEBUG_NSE
+         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                     "Proof of work found: %llu!\n",
                      (unsigned long long) GNUNET_ntohll (counter));
+#endif
          for (i=0;i<HISTORY_SIZE;i++)      
            if (ntohl (size_estimate_messages[i].hop_count) == 0) 
              {
@@ -902,7 +923,9 @@ update_flood_times (void *cls,
     {
       /* still stuck in previous round, no point to update, check that 
         we are active here though... */
+#if SEND_ON_CONNECT
       GNUNET_break (peer_entry->transmit_task != GNUNET_SCHEDULER_NO_TASK);
+#endif
       return GNUNET_OK; 
     }
   if (peer_entry->transmit_task != GNUNET_SCHEDULER_NO_TASK)
@@ -939,6 +962,10 @@ handle_p2p_size_estimate(void *cls,
   uint32_t matching_bits;  
   unsigned int idx;
 
+#if ENABLE_HISTOGRAM
+  if (NULL != wh)
+    GNUNET_BIO_write_int64 (wh, GNUNET_TIME_absolute_get ().abs_value);
+#endif
   incoming_flood = (const struct GNUNET_NSE_FloodMessage *) message;
   GNUNET_STATISTICS_update (stats, 
                            "# flood messages received", 
@@ -976,7 +1003,9 @@ handle_p2p_size_estimate(void *cls,
       GNUNET_break (0);
       return GNUNET_OK;
     }
+
   ts = GNUNET_TIME_absolute_ntoh (incoming_flood->timestamp);
+
   if (ts.abs_value == current_timestamp.abs_value)
     idx = estimate_index;
   else if (ts.abs_value == current_timestamp.abs_value - gnunet_nse_interval.rel_value)
@@ -1000,7 +1029,6 @@ handle_p2p_size_estimate(void *cls,
                                 "# flood messages discarded (clock skew too large)",
                                1,
                                 GNUNET_NO);
-      GNUNET_break_op (0);
       return GNUNET_OK;
     }
   if (0 == (memcmp (peer, &my_identity, sizeof(struct GNUNET_PeerIdentity))))
@@ -1040,6 +1068,14 @@ handle_p2p_size_estimate(void *cls,
     }
   if (matching_bits <= ntohl (size_estimate_messages[idx].matching_bits)) 
     {
+      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 (peer_entry->transmit_task != GNUNET_SCHEDULER_NO_TASK)
+       GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
+      peer_entry->transmit_task = GNUNET_SCHEDULER_add_now (&transmit_task,
+                                                           peer_entry);          
       /* Not closer than our most recent message, no need to do work here */
       GNUNET_STATISTICS_update (stats,
                                 "# flood messages ignored (had closer already)",
@@ -1094,9 +1130,11 @@ handle_core_connect(void *cls, const struct GNUNET_PeerIdentity *peer,
                                     &peer->hashPubKey,
                                     peer_entry,
                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+#if SEND_ON_CONNECT
   peer_entry->transmit_task = GNUNET_SCHEDULER_add_delayed (get_transmit_delay (-1),
                                                            &transmit_task,
                                                            peer_entry);
+#endif
 }
 
 
@@ -1181,6 +1219,13 @@ shutdown_task(void *cls,
       GNUNET_CRYPTO_rsa_key_free (my_private_key);
       my_private_key = NULL;
     }
+#if ENABLE_HISTOGRAM
+  if (wh != NULL)
+    {
+      GNUNET_BIO_write_close (wh);
+      wh = NULL;
+    }
+#endif
 }
 
 
@@ -1215,7 +1260,7 @@ core_init (void *cls, struct GNUNET_CORE_Handle *server,
   current_timestamp.abs_value = (now.abs_value / gnunet_nse_interval.rel_value) * gnunet_nse_interval.rel_value;
   next_timestamp.abs_value = current_timestamp.abs_value + gnunet_nse_interval.rel_value;
   
-  for (i=0;i<HISTORY_SIZE;i++)
+  for (i = 0; i < HISTORY_SIZE; i++)
     {
       prev_time.abs_value = current_timestamp.abs_value - (HISTORY_SIZE - i - 1) * gnunet_nse_interval.rel_value;
       setup_flood_message (i, prev_time);
@@ -1346,6 +1391,16 @@ run(void *cls, struct GNUNET_SERVER_Handle *server,
                                 core_handlers); /* Register these handlers */
   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
                                &shutdown_task, NULL);
+#if ENABLE_HISTOGRAM
+  if (GNUNET_OK == 
+      GNUNET_CONFIGURATION_get_value_filename (cfg,
+                                              "NSE", "HISTOGRAM",
+                                              &proof))
+    {
+      wh = GNUNET_BIO_write_open (proof);
+      GNUNET_free (proof);
+    }
+#endif
   if (coreAPI == NULL)
     {
       GNUNET_SCHEDULER_shutdown ();