Пример #1
0
/**
 * Get the transmission delay that should be applied for a
 * particular round.
 *
 * @param round_offset -1 for the previous round (random delay between 0 and 50ms)
 *                      0 for the current round (based on our proximity to time key)
 * @return delay that should be applied
 */
static struct GNUNET_TIME_Relative
get_transmit_delay (int round_offset)
{
  struct GNUNET_TIME_Relative ret;
  struct GNUNET_TIME_Absolute tgt;
  double dist_delay;
  uint32_t matching_bits;

  switch (round_offset)
  {
  case -1:
    /* previous round is randomized between 0 and 50 ms */
#if USE_RANDOM_DELAYS
    ret.rel_value_us = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
						 50);
#else
    ret = GNUNET_TIME_UNIT_ZERO;
#endif
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Transmitting previous round behind schedule in %s\n",
                GNUNET_STRINGS_relative_time_to_string (ret,
							GNUNET_YES));
    return ret;
  case 0:
    /* current round is based on best-known matching_bits */
    matching_bits =
        ntohl (size_estimate_messages[estimate_index].matching_bits);
    dist_delay = get_matching_bits_delay (matching_bits);
    dist_delay += get_delay_randomization (matching_bits).rel_value_us;
    ret.rel_value_us = (uint64_t) dist_delay;
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "For round %s, delay for %u matching bits is %s\n",
                GNUNET_STRINGS_absolute_time_to_string (current_timestamp),
                (unsigned int) matching_bits,
                GNUNET_STRINGS_relative_time_to_string (ret,
							GNUNET_YES));
    /* now consider round start time and add delay to it */
    tgt = GNUNET_TIME_absolute_add (current_timestamp,
				    ret);
    return GNUNET_TIME_absolute_get_remaining (tgt);
  }
  GNUNET_break (0);
  return GNUNET_TIME_UNIT_FOREVER_REL;
}
Пример #2
0
static void
print_info (const struct GNUNET_PeerIdentity *id, const char *transport,
    const char *addr, enum GNUNET_TRANSPORT_PeerState state,
    struct GNUNET_TIME_Absolute state_timeout)
{
  if ((GNUNET_YES == iterate_all) || (GNUNET_YES == monitor_connections) )
  {
    FPRINTF (stdout, _("Peer `%s': %s %s in state `%s' until %s\n"),
        GNUNET_i2s (id),
        (NULL == transport) ? "<none>" : transport,
        (NULL == transport) ? "<none>" : addr,
        GNUNET_TRANSPORT_ps2s (state),
        GNUNET_STRINGS_absolute_time_to_string (state_timeout));
  }
  else
  {
    /* Only connected peers, skip state */
    FPRINTF (stdout, _("Peer `%s': %s %s\n"), GNUNET_i2s (id), transport, addr);
  }

}
static void
monitor2_cb (void *cls,
	     const struct GNUNET_HELLO_Address *address,
	     struct GNUNET_TIME_Absolute last_validation,
	     struct GNUNET_TIME_Absolute valid_until,
	     struct GNUNET_TIME_Absolute next_validation,
	     enum GNUNET_TRANSPORT_ValidationState state)
{
  if ((NULL == address) || (NULL == p2))
    return;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Monitor 2: %s %s %s\n",
	      GNUNET_i2s (&address->peer),
	      GNUNET_TRANSPORT_vs2s(state),
	      GNUNET_STRINGS_absolute_time_to_string(valid_until));
  if (0 == memcmp (&address->peer,
		   &p1->id,
		   sizeof (p1->id)))
    p2_c++;
}
  dm->header.type = htons (GNUNET_MESSAGE_TYPE_DATASTORE_DATA);
  dm->rid = htonl (0);
  dm->size = htonl (size);
  dm->type = htonl (type);
  dm->priority = htonl (priority);
  dm->anonymity = htonl (anonymity);
  dm->replication = htonl (0);
  dm->reserved = htonl (0);
  dm->expiration = GNUNET_TIME_absolute_hton (expiration);
  dm->uid = GNUNET_htonll (uid);
  dm->key = *key;
  memcpy (&dm[1], data, size);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Transmitting `%s' message for `%s' of type %u with expiration %s (in: %s)\n",
              "DATA", GNUNET_h2s (key), type,
              GNUNET_STRINGS_absolute_time_to_string (expiration),
              GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (expiration),
						      GNUNET_YES));
  GNUNET_STATISTICS_update (stats, gettext_noop ("# results found"), 1,
                            GNUNET_NO);
  transmit (client, &dm->header);
  GNUNET_SERVER_client_drop (client);
  return GNUNET_OK;
}


/**
 * Handle RESERVE-message.
 *
 * @param cls closure
 * @param client identification of the client
Пример #5
0
static void
process_validation_string (void *cls, const char *address)
{
  struct ValidationResolutionContext *vc = cls;
  char *s_valid;
  char *s_last;
  char *s_next;

  if (address != NULL )
  {
    if (GNUNET_TIME_UNIT_ZERO_ABS.abs_value_us == vc->valid_until.abs_value_us)
      s_valid = GNUNET_strdup("never");
    else
      s_valid = GNUNET_strdup(GNUNET_STRINGS_absolute_time_to_string (vc->valid_until));

    if (GNUNET_TIME_UNIT_ZERO_ABS.abs_value_us == vc->last_validation.abs_value_us)
      s_last = GNUNET_strdup("never");
    else
      s_last = GNUNET_strdup(GNUNET_STRINGS_absolute_time_to_string (vc->last_validation));

    if (GNUNET_TIME_UNIT_ZERO_ABS.abs_value_us == vc->next_validation.abs_value_us)
      s_next = GNUNET_strdup("never");
    else
      s_next = GNUNET_strdup(GNUNET_STRINGS_absolute_time_to_string (vc->next_validation));

    FPRINTF (stdout,
        _("Peer `%s' %s %s\n\t%s%s\n\t%s%s\n\t%s%s\n"),
        GNUNET_i2s (&vc->id), address,
        (monitor_validation) ? GNUNET_TRANSPORT_vs2s (vc->state) : "",
        "Valid until    : ", s_valid,
        "Last validation: ",s_last,
        "Next validation: ", s_next);
    GNUNET_free (s_valid);
    GNUNET_free (s_last);
    GNUNET_free (s_next);
    vc->printed = GNUNET_YES;
  }
  else
  {
    /* done */
    GNUNET_assert(address_resolutions > 0);
    address_resolutions--;
    if (GNUNET_NO == vc->printed)
    {
      if (numeric == GNUNET_NO)
      {
        /* Failed to resolve address, try numeric lookup */
        resolve_validation_address (&vc->id, vc->addrcp, GNUNET_NO,
           vc->last_validation, vc->valid_until, vc->next_validation,
           vc->state);
      }
      else
      {
        FPRINTF (stdout, _("Peer `%s' %s `%s' \n"),
            GNUNET_i2s (&vc->id), "<unable to resolve address>",
            GNUNET_TRANSPORT_vs2s (vc->state));
      }
    }
    GNUNET_free (vc->transport);
    GNUNET_free (vc->addrcp);
    GNUNET_CONTAINER_DLL_remove(vc_head, vc_tail, vc);
    GNUNET_free(vc);
    if ((0 == address_resolutions) && (iterate_validation))
    {
      if (GNUNET_SCHEDULER_NO_TASK != end)
      {
        GNUNET_SCHEDULER_cancel (end);
        end = GNUNET_SCHEDULER_NO_TASK;
      }
      if (GNUNET_SCHEDULER_NO_TASK != op_timeout)
      {
        GNUNET_SCHEDULER_cancel (op_timeout);
        op_timeout = GNUNET_SCHEDULER_NO_TASK;
      }
      ret = 0;
      end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL );
    }
  }
}
Пример #6
0
static int
check ()
{
  char buf[128];
  char *r;
  char *b;
  struct GNUNET_TIME_Absolute at;
  const char *hdir;

  sprintf (buf, "4 %s", _( /* size unit */ "b"));
  b = GNUNET_STRINGS_byte_size_fancy (4);
  WANT (buf, b);
  sprintf (buf, "10 %s", _( /* size unit */ "KiB"));
  b = GNUNET_STRINGS_byte_size_fancy (10240);
  WANT (buf, b);
  sprintf (buf, "10 %s", _( /* size unit */ "TiB"));
  b = GNUNET_STRINGS_byte_size_fancy (10240LL * 1024LL * 1024LL * 1024LL);
  WANT (buf, b);
  sprintf (buf, "4 %s", _( /* time unit */ "ms"));
  b = GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_relative_multiply
                                              (GNUNET_TIME_UNIT_MILLISECONDS,
                                               4));
  WANT (buf, b);
  sprintf (buf, "7 %s", _( /* time unit */ "s"));
  b = GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_relative_multiply
                                              (GNUNET_TIME_UNIT_MILLISECONDS,
                                               7 * 1000));
  WANT (buf, b);
  sprintf (buf, "7 %s", _( /* time unit */ "h"));
  b = GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_relative_multiply
                                              (GNUNET_TIME_UNIT_MILLISECONDS,
                                               7 * 60 * 60 * 1000));
  WANT (buf, b);
#ifndef MINGW
  hdir = getenv ("HOME");
#else
  hdir = getenv ("USERPROFILE");
#endif
  GNUNET_snprintf (buf, sizeof (buf), "%s%s", hdir, DIR_SEPARATOR_STR);
  b = GNUNET_STRINGS_filename_expand ("~");
  GNUNET_assert (b != NULL);
  WANT (buf, b);
  GNUNET_STRINGS_buffer_fill (buf, sizeof (buf), 3, "a", "btx", "c");
  WANTB ("a\0btx\0c", buf, 8);
  if (6 != GNUNET_STRINGS_buffer_tokenize (buf, sizeof (buf), 2, &r, &b))
    return 1;
  r = GNUNET_strdup (r);
  WANT ("a", r);
  b = GNUNET_strdup (b);
  WANT ("btx", b);
  if (0 != GNUNET_STRINGS_buffer_tokenize (buf, 2, 2, &r, &b))
    return 1;
  at.abs_value = 5000;
  r = GNUNET_STRINGS_absolute_time_to_string (at);
  /* r should be something like "Wed Dec 31 17:00:05 1969"
   * where the details of the day and hour depend on the timezone;
   * however, the "0:05 19" should always be there; hence: */
  if (NULL == strstr (r, "0:05 19"))
  {
    FPRINTF (stderr, "Got %s\n", r);
    GNUNET_break (0);
    GNUNET_free (r);
    return 1;
  }
  GNUNET_free (r);
  b = GNUNET_STRINGS_to_utf8 ("TEST", 4, "ASCII");
  WANT ("TEST", b);
#if ENABLE_NLS && HAVE_ICONV
  GNUNET_log_skip (2, GNUNET_NO);
  b = GNUNET_STRINGS_to_utf8 ("TEST", 4, "unknown");
  GNUNET_log_skip (0, GNUNET_YES);
  WANT ("TEST", b);
#endif
  return 0;
}
Пример #7
0
/**
 * Process a record that was stored in the namestore.
 *
 * @param cls closure
 * @param zone_key private key of the zone
 * @param rname name that is being mapped (at most 255 characters long)
 * @param rd_len number of entries in @a rd array
 * @param rd array of records with data to store
 */
static void
display_record (void *cls,
		const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
		const char *rname,
		unsigned int rd_len,
		const struct GNUNET_GNSRECORD_Data *rd)
{
  const char *typestring;
  char *s;
  unsigned int i;
  const char *ets;
  struct GNUNET_TIME_Absolute at;
  struct GNUNET_TIME_Relative rt;

  if (NULL == rname)
  {
    list_it = NULL;
    test_finished ();
    return;
  }
  if ( (NULL != name) &&
       (0 != strcmp (name, rname)) )
  {
    GNUNET_NAMESTORE_zone_iterator_next (list_it);
    return;
  }
  FPRINTF (stdout,
	   "%s:\n",
	   rname);
  for (i=0;i<rd_len;i++)
  {
    if ( (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) &&
         (0 != strcmp (rname,
                       "+")) )
      continue;
    typestring = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type);
    s = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
					  rd[i].data,
					  rd[i].data_size);
    if (NULL == s)
    {
      FPRINTF (stdout, _("\tCorrupt or unsupported record of type %u\n"),
	       (unsigned int) rd[i].record_type);
      continue;
    }
    if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
    {
      rt.rel_value_us = rd[i].expiration_time;
      ets = GNUNET_STRINGS_relative_time_to_string (rt, GNUNET_YES);
    }
    else
    {
      at.abs_value_us = rd[i].expiration_time;
      ets = GNUNET_STRINGS_absolute_time_to_string (at);
    }
    FPRINTF (stdout,
	     "\t%s: %s (%s)\t%s\t%s\n",
	     typestring,
	     s,
             ets,
             (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) ? "PRIVATE" : "PUBLIC",
             (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)) ? "SHADOW" : "");
    GNUNET_free (s);
  }
  FPRINTF (stdout, "%s", "\n");
  GNUNET_NAMESTORE_zone_iterator_next (list_it);
}
Пример #8
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);
}
/**
 * Run the given select statement and call 'proc' on the resulting
 * values (which must be in particular positions).
 *
 * @param plugin the plugin handle
 * @param stmt select statement to run
 * @param proc function to call on result
 * @param proc_cls closure for proc
 * @param ... arguments to initialize stmt
 */
static void
execute_select (struct Plugin *plugin, struct GNUNET_MYSQL_StatementHandle *stmt,
                PluginDatumProcessor proc, void *proc_cls, ...)
{
  va_list ap;
  int ret;
  unsigned int type;
  unsigned int priority;
  unsigned int anonymity;
  unsigned long long exp;
  unsigned long hashSize;
  unsigned long size;
  unsigned long long uid;
  char value[GNUNET_DATASTORE_MAX_VALUE_SIZE];
  struct GNUNET_HashCode key;
  struct GNUNET_TIME_Absolute expiration;
  MYSQL_BIND rbind[7];

  hashSize = sizeof (struct GNUNET_HashCode);
  memset (rbind, 0, sizeof (rbind));
  rbind[0].buffer_type = MYSQL_TYPE_LONG;
  rbind[0].buffer = &type;
  rbind[0].is_unsigned = 1;
  rbind[1].buffer_type = MYSQL_TYPE_LONG;
  rbind[1].buffer = &priority;
  rbind[1].is_unsigned = 1;
  rbind[2].buffer_type = MYSQL_TYPE_LONG;
  rbind[2].buffer = &anonymity;
  rbind[2].is_unsigned = 1;
  rbind[3].buffer_type = MYSQL_TYPE_LONGLONG;
  rbind[3].buffer = &exp;
  rbind[3].is_unsigned = 1;
  rbind[4].buffer_type = MYSQL_TYPE_BLOB;
  rbind[4].buffer = &key;
  rbind[4].buffer_length = hashSize;
  rbind[4].length = &hashSize;
  rbind[5].buffer_type = MYSQL_TYPE_BLOB;
  rbind[5].buffer = value;
  rbind[5].buffer_length = size = sizeof (value);
  rbind[5].length = &size;
  rbind[6].buffer_type = MYSQL_TYPE_LONGLONG;
  rbind[6].buffer = &uid;
  rbind[6].is_unsigned = 1;

  va_start (ap, proc_cls);
  ret = GNUNET_MYSQL_statement_run_prepared_select_va (plugin->mc, stmt, 7, rbind, NULL, NULL, ap);
  va_end (ap);
  if (ret <= 0)
  {
    proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
    return;
  }
  GNUNET_assert (size <= sizeof (value));
  if ((rbind[4].buffer_length != sizeof (struct GNUNET_HashCode)) ||
      (hashSize != sizeof (struct GNUNET_HashCode)))
  {
    GNUNET_break (0);
    proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
    return;
  }
  expiration.abs_value_us = exp;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Found %u-byte value under key `%s' with prio %u, anon %u, expire %s selecting from gn090 table\n",
              (unsigned int) size, GNUNET_h2s (&key),
	      priority, anonymity,
	      GNUNET_STRINGS_absolute_time_to_string (expiration));
  GNUNET_assert (size < MAX_DATUM_SIZE);
  ret =
      proc (proc_cls, &key, size, value, type, priority, anonymity, expiration,
            uid);
  if (ret == GNUNET_NO)
  {
    do_delete_entry (plugin, uid);
    if (size != 0)
      plugin->env->duc (plugin->env->cls, -size);
  }
}