Ejemplo n.º 1
0
static int
test_normal_rw ()
{
  char *msg;
  int64_t testNum;
  char *readResultString;
  char *fileName = GNUNET_DISK_mktemp ("gnunet_bio");
  struct GNUNET_BIO_WriteHandle *fileW;
  struct GNUNET_BIO_ReadHandle *fileR;
  struct GNUNET_CONTAINER_MetaData *metaDataW;
  struct GNUNET_CONTAINER_MetaData *metaDataR;

  metaDataW = GNUNET_CONTAINER_meta_data_create ();
  metaDataR = NULL;
  GNUNET_CONTAINER_meta_data_add_publication_date (metaDataW);

  fileW = GNUNET_BIO_write_open (fileName);
  GNUNET_assert (NULL != fileW);
  GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_string (fileW, TESTSTRING));
  GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_meta_data (fileW, metaDataW));
  GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int64 (fileW, TESTNUMBER64));
  GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW));

  fileR = GNUNET_BIO_read_open (fileName);
  GNUNET_assert (NULL != fileR);
  readResultString = NULL;
  GNUNET_assert (GNUNET_OK ==
                 GNUNET_BIO_read_string (fileR, "Read string error",
                                         &readResultString, 200));
  GNUNET_assert (NULL != readResultString);
  GNUNET_assert (0 == strcmp (TESTSTRING, readResultString));
  GNUNET_free (readResultString);
  GNUNET_assert (GNUNET_OK ==
                 GNUNET_BIO_read_meta_data (fileR, "Read meta error",
                                            &metaDataR));
  GNUNET_assert (GNUNET_YES ==
                 GNUNET_CONTAINER_meta_data_test_equal (metaDataR, metaDataW));
  GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_int64 (fileR, &testNum));
  GNUNET_BIO_read_close (fileR, &msg);
  GNUNET_CONTAINER_meta_data_destroy (metaDataW);
  GNUNET_CONTAINER_meta_data_destroy (metaDataR);
  GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName));
  GNUNET_free (fileName);
  return 0;
}
Ejemplo n.º 2
0
/**
 * Core handler for size estimate flooding messages.
 *
 * @param cls peer this message is from
 * @param incoming_flood received message
 */
static void
handle_p2p_estimate (void *cls,
		     const struct GNUNET_NSE_FloodMessage *incoming_flood)
{
  struct NSEPeerEntry *peer_entry = cls;
  struct GNUNET_TIME_Absolute ts;
  uint32_t matching_bits;
  unsigned int idx;

#if ENABLE_NSE_HISTOGRAM
  {
    uint64_t t;

    t = GNUNET_TIME_absolute_get().abs_value_us;
    if (NULL != lh)
      GNUNET_TESTBED_LOGGER_write (lh, &t, sizeof (uint64_t));
    if (NULL != histogram)
      GNUNET_BIO_write_int64 (histogram, t);
  }
#endif
  GNUNET_STATISTICS_update (stats,
			    "# flood messages received",
			    1,
			    GNUNET_NO);
  matching_bits = ntohl (incoming_flood->matching_bits);
#if DEBUG_NSE
  {
    char origin[5];
    char pred[5];
    struct GNUNET_PeerIdentity os;

    GNUNET_snprintf (origin,
		     sizeof (origin),
		     "%s",
		     GNUNET_i2s (&incoming_flood->origin));
    GNUNET_snprintf (pred,
		     sizeof (pred),
		     "%s",
		     GNUNET_i2s (peer_entry->id));
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Flood at %s from `%s' via `%s' at `%s' with bits %u\n",
                GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (incoming_flood->timestamp)),
                origin,
		pred,
		GNUNET_i2s (&my_identity),
                (unsigned int) matching_bits);
  }
#endif

#if ENABLE_NSE_HISTOGRAM
  peer_entry->received_messages++;
  if (peer_entry->transmitted_messages > 0 &&
      peer_entry->last_transmitted_size >= matching_bits)
    GNUNET_STATISTICS_update(stats,
			     "# cross messages",
			     1,
			     GNUNET_NO);
#endif

  ts = GNUNET_TIME_absolute_ntoh (incoming_flood->timestamp);
  if (ts.abs_value_us == current_timestamp.abs_value_us)
    idx = estimate_index;
  else if (ts.abs_value_us ==
           current_timestamp.abs_value_us - gnunet_nse_interval.rel_value_us)
    idx = (estimate_index + HISTORY_SIZE - 1) % HISTORY_SIZE;
  else if (ts.abs_value_us == next_timestamp.abs_value_us)
  {
    if (matching_bits <= ntohl (next_message.matching_bits))
      return;         /* ignore, simply too early/late */
    if (GNUNET_YES !=
	verify_message_crypto (incoming_flood))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  "Peer %s is likely ill-configured!\n",
                  GNUNET_i2s (peer_entry->id));
      GNUNET_break_op (0);
      return;
    }
    next_message = *incoming_flood;
    return;
  }
  else
  {
    GNUNET_STATISTICS_update (stats,
                              "# flood messages discarded (clock skew too large)",
                              1, GNUNET_NO);
    return;
  }
  if (0 == (memcmp (peer_entry->id,
		    &my_identity,
		    sizeof (struct GNUNET_PeerIdentity))))
  {
    /* send to self, update our own estimate IF this also comes from us! */
    if (0 ==
        memcmp (&incoming_flood->origin,
		&my_identity, sizeof (my_identity)))
      update_network_size_estimate ();
    return;
  }
  if (matching_bits ==
      ntohl (size_estimate_messages[idx].matching_bits))
  {
    /* 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;
    if (idx != estimate_index)
    {
      /* do not transmit information for the previous round to this peer
         anymore (but allow current round) */
      return;
    }
    /* got up-to-date information for current round, cancel transmission to
     * this peer altogether */
    if (NULL != peer_entry->transmit_task)
    {
      GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
      peer_entry->transmit_task = NULL;
    }
    return;
  }
  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 (NULL != peer_entry->transmit_task)
      GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
    peer_entry->transmit_task
      = GNUNET_SCHEDULER_add_now (&transmit_task_cb,
				  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)",
                              1,
			      GNUNET_NO);
    return;
  }
  if (GNUNET_YES !=
      verify_message_crypto (incoming_flood))
  {
    GNUNET_break_op (0);
    return;
  }
  GNUNET_assert (matching_bits >
                 ntohl (size_estimate_messages[idx].matching_bits));
  /* Cancel transmission in the other direction, as this peer clearly has
   * up-to-date information already.
   */
  peer_entry->previous_round = GNUNET_YES;
  if (idx == estimate_index)
  {
    /* cancel any activity for current round */
    if (NULL != peer_entry->transmit_task)
    {
      GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
      peer_entry->transmit_task = NULL;
    }
  }
  size_estimate_messages[idx] = *incoming_flood;
  size_estimate_messages[idx].hop_count =
      htonl (ntohl (incoming_flood->hop_count) + 1);
  hop_count_max =
      GNUNET_MAX (ntohl (incoming_flood->hop_count) + 1,
		  hop_count_max);
  GNUNET_STATISTICS_set (stats,
			 "# estimated network diameter",
			 hop_count_max, GNUNET_NO);

  /* have a new, better size estimate, inform clients */
  update_network_size_estimate ();

  /* flood to rest */
  GNUNET_CONTAINER_multipeermap_iterate (peers,
					 &update_flood_times,
                                         peer_entry);
}