示例#1
0
/**
 * Type of a function to call when we receive a message
 * from the service.
 *
 * @param cls closure
 * @param msg message received, NULL on timeout or fatal error
 */
static void
message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
{
    struct GNUNET_NSE_Handle *h = cls;
    const struct GNUNET_NSE_ClientMessage *client_msg;

    if (msg == NULL)
    {
        /* Error, timeout, death */
        GNUNET_CLIENT_disconnect (h->client);
        h->client = NULL;
        h->reconnect_task =
            GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect, h);
        return;
    }
    if ((ntohs (msg->size) != sizeof (struct GNUNET_NSE_ClientMessage)) ||
            (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_NSE_ESTIMATE))
    {
        GNUNET_break (0);
        return;
    }
    client_msg = (const struct GNUNET_NSE_ClientMessage *) msg;
    h->recv_cb (h->recv_cb_cls, GNUNET_TIME_absolute_ntoh (client_msg->timestamp),
                GNUNET_ntoh_double (client_msg->size_estimate),
                GNUNET_ntoh_double (client_msg->std_deviation));
    GNUNET_CLIENT_receive (h->client, &message_handler, h,
                           GNUNET_TIME_UNIT_FOREVER_REL);
}
示例#2
0
/**
 * Task that triggers a NSE P2P transmission.
 *
 * @param cls the `struct NSEPeerEntry *`
 */
static void
transmit_task_cb (void *cls)
{
  struct NSEPeerEntry *peer_entry = cls;
  unsigned int idx;
  struct GNUNET_MQ_Envelope *env;

  peer_entry->transmit_task = NULL;
  idx = estimate_index;
  if (GNUNET_NO == peer_entry->previous_round)
  {
    idx = (idx + HISTORY_SIZE - 1) % HISTORY_SIZE;
    peer_entry->previous_round = GNUNET_YES;
    peer_entry->transmit_task
      = GNUNET_SCHEDULER_add_delayed (get_transmit_delay (0),
				      &transmit_task_cb,
				      peer_entry);
  }
  if ((0 == ntohl (size_estimate_messages[idx].hop_count)) &&
      (NULL != proof_task))
  {
    GNUNET_STATISTICS_update (stats,
                              "# flood messages not generated (no proof yet)",
                              1,
			      GNUNET_NO);
    return;
  }
  if (0 == ntohs (size_estimate_messages[idx].header.size))
  {
    GNUNET_STATISTICS_update (stats,
                              "# flood messages not generated (lack of history)",
                              1,
			      GNUNET_NO);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "In round %s, sending to `%s' estimate with %u bits\n",
              GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (size_estimate_messages[idx].timestamp)),
              GNUNET_i2s (peer_entry->id),
              (unsigned int) ntohl (size_estimate_messages[idx].matching_bits));
  if (0 == ntohl (size_estimate_messages[idx].hop_count))
    GNUNET_STATISTICS_update (stats,
			      "# flood messages started",
			      1,
			      GNUNET_NO);
  GNUNET_STATISTICS_update (stats,
			    "# flood messages transmitted",
			    1,
                            GNUNET_NO);
#if ENABLE_NSE_HISTOGRAM
  peer_entry->transmitted_messages++;
  peer_entry->last_transmitted_size
    = ntohl(size_estimate_messages[idx].matching_bits);
#endif
  env = GNUNET_MQ_msg_copy (&size_estimate_messages[idx].header);
  GNUNET_MQ_send (peer_entry->mq,
		  env);
}
/**
 * Function to handle a ring message incoming over cadet
 *
 * @param cls closure, NULL
 * @param channel the channel over which the message arrived
 * @param channel_ctx the channel context, can be NULL
 *                    or point to the `struct Channel`
 * @param message the incoming message
 * @return #GNUNET_OK
 */
static int
handle_cadet_ring_message (void *cls,
                           struct GNUNET_CADET_Channel *channel,
                           void **channel_ctx,
                           const struct GNUNET_MessageHeader *message)
{
  struct Channel *ch = *channel_ctx;
  struct Line *line = ch->line;
  const struct CadetPhoneRingMessage *msg;
  struct GNUNET_MQ_Envelope *env;
  struct ClientPhoneRingMessage *cring;
  struct CadetPhoneRingInfoPS rs;

  msg = (const struct CadetPhoneRingMessage *) message;
  rs.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING);
  rs.purpose.size = htonl (sizeof (struct CadetPhoneRingInfoPS));
  rs.line_port = line->line_port;
  rs.target_peer = my_identity;
  rs.expiration_time = msg->expiration_time;

  if (GNUNET_OK !=
      GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING,
                                  &rs.purpose,
                                  &msg->signature,
                                  &msg->caller_id))
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  if (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (msg->expiration_time)).rel_value_us)
  {
    /* ancient call, replay? */
    GNUNET_break_op (0);
    /* Note that our reliance on time here is awkward; better would be
       to use a more complex challenge-response protocol against
       replay attacks.  Left for future work ;-). */
    return GNUNET_SYSERR;
  }
  if (CS_CALLEE_INIT != ch->status)
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  GNUNET_CADET_receive_done (channel);
  ch->status = CS_CALLEE_RINGING;
  env = GNUNET_MQ_msg (cring,
                       GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING);
  cring->cid = ch->cid;
  cring->caller_id = msg->caller_id;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Sending RING message to client. CID is %u\n",
              (unsigned int) ch->cid);
  GNUNET_MQ_send (line->mq,
                  env);
  return GNUNET_OK;
}
示例#4
0
/**
 * Update our flood message to be sent (and our timestamps).
 *
 * @param cls unused
 */
static void
update_flood_message (void *cls)
{
  struct GNUNET_TIME_Relative offset;
  unsigned int i;

  flood_task = NULL;
  offset = GNUNET_TIME_absolute_get_remaining (next_timestamp);
  if (0 != offset.rel_value_us)
  {
    /* somehow run early, delay more */
    flood_task =
        GNUNET_SCHEDULER_add_delayed (offset,
				      &update_flood_message,
				      NULL);
    return;
  }
  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_us ==
	GNUNET_TIME_absolute_ntoh (next_message.timestamp).abs_value_us) &&
       (get_matching_bits (current_timestamp, &my_identity) <
	ntohl(next_message.matching_bits)) )
  {
    /* we received a message for this round way early, use it! */
    size_estimate_messages[estimate_index] = next_message;
    size_estimate_messages[estimate_index].hop_count =
        htonl (1 + ntohl (next_message.hop_count));
  }
  else
    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++)
    hop_count_max = GNUNET_MAX (ntohl (size_estimate_messages[i].hop_count),
				hop_count_max);
  GNUNET_CONTAINER_multipeermap_iterate (peers,
                                         &schedule_current_round,
                                         NULL);
  flood_task
    = GNUNET_SCHEDULER_add_at (next_timestamp,
                               &update_flood_message,
                               NULL);
}
示例#5
0
/**
 * Process a given reply that might match the given
 * request.
 *
 * @param cls the 'struct GNUNET_DHT_ClientResultMessage'
 * @param key query of the request
 * @param value the 'struct GNUNET_DHT_RouteHandle' of a request matching the same key
 * @return GNUNET_YES to continue to iterate over all results,
 *         GNUNET_NO if the reply is malformed
 */
static int
process_reply (void *cls, const GNUNET_HashCode * key, void *value)
{
  const struct GNUNET_DHT_ClientResultMessage *dht_msg = cls;
  struct GNUNET_DHT_GetHandle *get_handle = value;
  const struct GNUNET_PeerIdentity *put_path;
  const struct GNUNET_PeerIdentity *get_path;
  uint32_t put_path_length;
  uint32_t get_path_length;
  size_t data_length;
  size_t msize;
  size_t meta_length;
  const void *data;

  if (dht_msg->unique_id != get_handle->unique_id)
  {
    /* UID mismatch */
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Ignoring reply for %s: UID mismatch: %llu/%llu\n", GNUNET_h2s (key),
         dht_msg->unique_id, get_handle->unique_id);
    return GNUNET_YES;
  }
  msize = ntohs (dht_msg->header.size);
  put_path_length = ntohl (dht_msg->put_path_length);
  get_path_length = ntohl (dht_msg->get_path_length);
  meta_length =
      sizeof (struct GNUNET_DHT_ClientResultMessage) +
      sizeof (struct GNUNET_PeerIdentity) * (get_path_length + put_path_length);
  if ((msize < meta_length) ||
      (get_path_length >
       GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)) ||
      (put_path_length >
       GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
  {
    GNUNET_break (0);
    return GNUNET_NO;
  }
  data_length = msize - meta_length;
  LOG (GNUNET_ERROR_TYPE_DEBUG, "Giving %u byte reply for %s to application\n",
       (unsigned int) data_length, GNUNET_h2s (key));
  put_path = (const struct GNUNET_PeerIdentity *) &dht_msg[1];
  get_path = &put_path[put_path_length];
  data = &get_path[get_path_length];
  get_handle->iter (get_handle->iter_cls,
                    GNUNET_TIME_absolute_ntoh (dht_msg->expiration), key,
                    get_path, get_path_length, put_path, put_path_length,
                    ntohl (dht_msg->type), data_length, data);
  return GNUNET_YES;
}
示例#6
0
/**
 * Process a get response monitor message from the service.
 *
 * @param handle The DHT handle.
 * @param msg monitor get response message from the service
 * @return GNUNET_OK if everything went fine,
 *         GNUNET_SYSERR if the message is malformed.
 */
static int
process_monitor_get_resp_message (struct GNUNET_DHT_Handle *handle,
                                  const struct GNUNET_DHT_MonitorGetRespMessage
                                  *msg)
{
  struct GNUNET_DHT_MonitorHandle *h;
  struct GNUNET_PeerIdentity *path;
  uint32_t getl;
  uint32_t putl;
  size_t msize;

  msize = ntohs (msg->header.size);
  path = (struct GNUNET_PeerIdentity *) &msg[1];
  getl = ntohl (msg->get_path_length);
  putl = ntohl (msg->put_path_length);
  if ( (getl + putl < getl) ||
       ( ((msize - sizeof (struct GNUNET_DHT_MonitorGetRespMessage)) / sizeof (struct GNUNET_PeerIdentity)) < getl + putl) )
  {
    GNUNET_break (0);
    return GNUNET_SYSERR;
  }
  for (h = handle->monitor_head; NULL != h; h = h->next)
  {
    int type_ok;
    int key_ok;

    type_ok = (GNUNET_BLOCK_TYPE_ANY == h->type) || (h->type == ntohl(msg->type));
    key_ok = (NULL == h->key) || (0 == memcmp (h->key, &msg->key,
					       sizeof (GNUNET_HashCode)));
    if (type_ok && key_ok && (NULL != h->get_resp_cb))
      h->get_resp_cb (h->cb_cls,
                      (enum GNUNET_BLOCK_Type) ntohl(msg->type),
                      path, getl,
                      &path[getl], putl,
                      GNUNET_TIME_absolute_ntoh(msg->expiration_time),
                      &msg->key,
                      (void *) &path[getl + putl],
                      msize -
                      sizeof (struct GNUNET_DHT_MonitorGetRespMessage) -
                      sizeof (struct GNUNET_PeerIdentity) * (putl + getl));
  }
  return GNUNET_OK;
}
示例#7
0
static int
expire_blocks (void *cls,
               const struct GNUNET_HashCode *key,
               void *value)
{
  struct Plugin *plugin = cls;
  struct FlatFileEntry *entry = value;
  struct GNUNET_TIME_Absolute now;
  struct GNUNET_TIME_Absolute expiration;

  now = GNUNET_TIME_absolute_get ();
  expiration = GNUNET_TIME_absolute_ntoh (entry->block->expiration_time);

  if (0 == GNUNET_TIME_absolute_get_difference (now,
                                                expiration).rel_value_us)
  {
    GNUNET_CONTAINER_multihashmap_remove_all (plugin->hm, key);
  }
  return GNUNET_YES;
}
示例#8
0
/**
 * Handles messages received from the service.  Calls the proper client
 * callback.
 */
static void
process_result (struct GNUNET_CHAT_Room *room,
                const struct GNUNET_MessageHeader *reply)
{
  struct LeaveNotificationMessage *leave_msg;
  struct JoinNotificationMessage *join_msg;
  struct ReceiveNotificationMessage *received_msg;
  struct ConfirmationReceiptMessage *receipt;
  struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
  GNUNET_HashCode id;
  const GNUNET_HashCode *sender;
  struct GNUNET_CONTAINER_MetaData *meta;
  struct GNUNET_CHAT_SendReceiptContext *src;
  struct MemberList *pos;
  struct MemberList *prev;
  struct GNUNET_CRYPTO_AesSessionKey key;
  char decrypted_msg[MAX_MESSAGE_LENGTH];
  uint16_t size;
  uint16_t meta_len;
  uint16_t msg_len;
  char *message_content;

  size = ntohs (reply->size);
  switch (ntohs (reply->type))
  {
  case GNUNET_MESSAGE_TYPE_CHAT_JOIN_NOTIFICATION:
#if DEBUG_CHAT
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a join notification\n");
#endif
    if (size < sizeof (struct JoinNotificationMessage))
    {
      GNUNET_break (0);
      return;
    }
    join_msg = (struct JoinNotificationMessage *) reply;
    meta_len = size - sizeof (struct JoinNotificationMessage);
    meta =
        GNUNET_CONTAINER_meta_data_deserialize ((const char *) &join_msg[1],
                                                meta_len);
    if (NULL == meta)
    {
      GNUNET_break (0);
      return;
    }
    pos = GNUNET_malloc (sizeof (struct MemberList));
    pos->meta = meta;
    GNUNET_CRYPTO_hash (&join_msg->public_key,
                        sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
                        &pos->id);
    GNUNET_PSEUDONYM_add (room->cfg, &pos->id, meta);
    pos->next = room->members;
    room->members = pos;
    if (GNUNET_NO == room->is_joined)
    {
      GNUNET_CRYPTO_rsa_key_get_public (room->my_private_key, &pkey);
      if (0 ==
          memcmp (&join_msg->public_key, &pkey,
                  sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))
      {
        room->join_callback (room->join_callback_cls);
        room->is_joined = GNUNET_YES;
      }
      else
      {
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                    _("The current user must be the the first one joined\n"));
        GNUNET_break (0);
        return;
      }
    }
    else
      room->member_list_callback (room->member_list_callback_cls, meta,
                                  &join_msg->public_key,
                                  ntohl (join_msg->msg_options));
    break;
  case GNUNET_MESSAGE_TYPE_CHAT_LEAVE_NOTIFICATION:
#if DEBUG_CHAT
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a leave notification\n");
#endif
    if (size < sizeof (struct LeaveNotificationMessage))
    {
      GNUNET_break (0);
      return;
    }
    leave_msg = (struct LeaveNotificationMessage *) reply;
    room->member_list_callback (room->member_list_callback_cls, NULL,
                                &leave_msg->user, GNUNET_CHAT_MSG_OPTION_NONE);
    GNUNET_CRYPTO_hash (&leave_msg->user,
                        sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
                        &id);
    prev = NULL;
    pos = room->members;
    while ((NULL != pos) &&
           (0 != memcmp (&pos->id, &id, sizeof (GNUNET_HashCode))))
    {
      prev = pos;
      pos = pos->next;
    }
    GNUNET_assert (NULL != pos);
    if (NULL == prev)
      room->members = pos->next;
    else
      prev->next = pos->next;
    GNUNET_CONTAINER_meta_data_destroy (pos->meta);
    GNUNET_free (pos);
    break;
  case GNUNET_MESSAGE_TYPE_CHAT_MESSAGE_NOTIFICATION:
#if DEBUG_CHAT
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a message notification\n");
#endif
    if (size <= sizeof (struct ReceiveNotificationMessage))
    {
      GNUNET_break (0);
      return;
    }
    received_msg = (struct ReceiveNotificationMessage *) reply;
    if (0 != (ntohl (received_msg->msg_options) & GNUNET_CHAT_MSG_ACKNOWLEDGED))
    {
      src = GNUNET_malloc (sizeof (struct GNUNET_CHAT_SendReceiptContext));
      src->chat_room = room;
      src->received_msg = GNUNET_memdup (received_msg, size);
      GNUNET_CLIENT_notify_transmit_ready (room->client,
                                           sizeof (struct
                                                   ConfirmationReceiptMessage),
                                           GNUNET_CONSTANTS_SERVICE_TIMEOUT,
                                           GNUNET_YES,
                                           &transmit_acknowledge_request, src);
    }
    msg_len = size - sizeof (struct ReceiveNotificationMessage);
    if (0 != (ntohl (received_msg->msg_options) & GNUNET_CHAT_MSG_PRIVATE))
    {
      if (-1 ==
          GNUNET_CRYPTO_rsa_decrypt (room->my_private_key,
                                     &received_msg->encrypted_key, &key,
                                     sizeof (struct
                                             GNUNET_CRYPTO_AesSessionKey)))
      {
        GNUNET_break (0);
        return;
      }
      msg_len =
          GNUNET_CRYPTO_aes_decrypt (&received_msg[1], msg_len, &key,
                                     (const struct
                                      GNUNET_CRYPTO_AesInitializationVector *)
                                     INITVALUE, decrypted_msg);
      message_content = decrypted_msg;
    }
    else
    {
      message_content = GNUNET_malloc (msg_len + 1);
      memcpy (message_content, &received_msg[1], msg_len);
    }
    message_content[msg_len] = '\0';
    if (0 != (ntohl (received_msg->msg_options) & GNUNET_CHAT_MSG_ANONYMOUS))
    {
      sender = NULL;
      meta = NULL;
    }
    else
    {
      pos = room->members;
      while ((NULL != pos) &&
             (0 !=
              memcmp (&pos->id, &received_msg->sender,
                      sizeof (GNUNET_HashCode))))
        pos = pos->next;
      GNUNET_assert (NULL != pos);
      sender = &received_msg->sender;
      meta = pos->meta;
    }
    room->message_callback (room->message_callback_cls, room, sender, meta,
                            message_content,
                            GNUNET_TIME_absolute_ntoh (received_msg->timestamp),
                            ntohl (received_msg->msg_options));
    if (message_content != decrypted_msg)
      GNUNET_free (message_content);
    break;
  case GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_NOTIFICATION:
#if DEBUG_CHAT
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a confirmation receipt\n");
#endif
    if (size < sizeof (struct ConfirmationReceiptMessage))
    {
      GNUNET_break (0);
      return;
    }
    receipt = (struct ConfirmationReceiptMessage *) reply;
    if (NULL != room->confirmation_callback)
      room->confirmation_callback (room->confirmation_cls, room,
                                   ntohl (receipt->sequence_number),
                                   GNUNET_TIME_absolute_ntoh
                                   (receipt->timestamp), &receipt->target);
    break;
  default:
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unknown message type: '%u'\n"),
                ntohs (reply->type));
    GNUNET_break_op (0);
    break;
  }
}
/**
 * We've received a PONG.  Check if it matches a pending PING and
 * mark the respective address as confirmed.
 *
 * @param sender peer sending the PONG
 * @param hdr the PONG
 */
void
GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender,
                            const struct GNUNET_MessageHeader *hdr)
{
  const struct TransportPongMessage *pong;
  struct ValidationEntry *ve;
  const char *tname;
  const char *addr;
  size_t addrlen;
  size_t slen;
  size_t size;
  struct GNUNET_HELLO_Message *hello;
  struct GNUNET_HELLO_Address address;

  if (ntohs (hdr->size) < sizeof (struct TransportPongMessage))
  {
    GNUNET_break_op (0);
    return;
  }
  GNUNET_STATISTICS_update (GST_stats,
                            gettext_noop ("# PONG messages received"), 1,
                            GNUNET_NO);

  pong = (const struct TransportPongMessage *) hdr;
  tname = (const char *) &pong[1];
  size = ntohs (hdr->size) - sizeof (struct TransportPongMessage);
  addr = memchr (tname, '\0', size);
  if (NULL == addr)
  {
    GNUNET_break_op (0);
    return;
  }
  addr++;
  slen = strlen (tname) + 1;
  addrlen = size - slen;
  address.peer = *sender;
  address.address = addr;
  address.address_length = addrlen;
  address.transport_name = tname;
  ve = find_validation_entry (NULL, &address);
  if ((NULL == ve) || (ve->expecting_pong == GNUNET_NO))
  {
    GNUNET_STATISTICS_update (GST_stats,
                              gettext_noop
                              ("# PONGs dropped, no matching pending validation"),
                              1, GNUNET_NO);
    return;
  }
  /* now check that PONG is well-formed */
  if (0 != memcmp (&ve->pid, sender, sizeof (struct GNUNET_PeerIdentity)))
  {
    GNUNET_break_op (0);
    return;
  }

  if (GNUNET_OK !=
      GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN,
                                &pong->purpose, &pong->signature,
                                &ve->public_key))
  {
    GNUNET_break_op (0);
    return;
  }

  if (GNUNET_TIME_absolute_get_remaining
      (GNUNET_TIME_absolute_ntoh (pong->expiration)).rel_value == 0)
  {
    GNUNET_STATISTICS_update (GST_stats,
                              gettext_noop
                              ("# PONGs dropped, signature expired"), 1,
                              GNUNET_NO);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Address validated for peer `%s' with plugin `%s': `%s'\n",

              GNUNET_i2s (sender), tname, GST_plugins_a2s (ve->address));
  /* validity achieved, remember it! */
  ve->expecting_pong = GNUNET_NO;
  ve->valid_until = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION);
  ve->latency = GNUNET_TIME_absolute_get_duration (ve->send_time);
  {
    struct GNUNET_ATS_Information ats;

    ats.type = htonl (GNUNET_ATS_QUALITY_NET_DELAY);
    ats.value = htonl ((uint32_t) ve->latency.rel_value);
    GNUNET_ATS_address_update (GST_ats, ve->address, NULL, &ats, 1);
  }
  /* build HELLO to store in PEERINFO */
  ve->copied = GNUNET_NO;
  hello = GNUNET_HELLO_create (&ve->public_key, &add_valid_peer_address, ve);
  GNUNET_PEERINFO_add_peer (GST_peerinfo, hello, NULL, NULL);
  GNUNET_free (hello);
}
/**
 * Function called with responses from the service.
 *
 * @param cls our 'struct GNUNET_TRANSPORT_PeerMonitoringContext*'
 * @param msg NULL on timeout or error, otherwise presumably a
 *        message with the human-readable address
 */
static void
peer_response_processor (void *cls, const struct GNUNET_MessageHeader *msg)
{
  struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
  struct PeerIterateResponseMessage *pir_msg;
  struct GNUNET_HELLO_Address *address;
  const char *addr;
  const char *transport_name;
  uint16_t size;
  size_t alen;
  size_t tlen;

  if (msg == NULL)
  {
    if (pal_ctx->one_shot)
    {
      /* Disconnect */
      pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
          GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
      GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
    }
    else
    {
      reconnect_peer_ctx (pal_ctx);
    }
    return;
  }
  size = ntohs (msg->size);
  GNUNET_break (ntohs (msg->type) ==
      GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE);
  if (size == sizeof (struct GNUNET_MessageHeader))
  {
    /* Done! */
    if (pal_ctx->one_shot)
    {
      pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
          GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
      GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
    }
    else
    {
      reconnect_peer_ctx (pal_ctx);
    }
    return;
  }

  if ((size < sizeof (struct PeerIterateResponseMessage)) ||
      (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE))
  {
    GNUNET_break (0);
    if (pal_ctx->one_shot)
    {
      pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
          GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
      GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
    }
    else
    {
      reconnect_peer_ctx (pal_ctx);
    }
    return;
  }

  pir_msg = (struct PeerIterateResponseMessage *) msg;
  tlen = ntohl (pir_msg->pluginlen);
  alen = ntohl (pir_msg->addrlen);

  if (size != sizeof (struct PeerIterateResponseMessage) + tlen + alen)
  {
    GNUNET_break (0);
    if (pal_ctx->one_shot)
    {
      pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
          GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
      GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
    }
    else
    {
      reconnect_peer_ctx (pal_ctx);
    }
    return;
  }

  if ( (0 == tlen) && (0 == alen) )
  {
    /* No address available */
    pal_ctx->cb (pal_ctx->cb_cls, &pir_msg->peer, NULL,
        ntohl(pir_msg->state),
        GNUNET_TIME_absolute_ntoh (pir_msg->state_timeout));
  }
  else
  {
    if (0 == tlen)
    {
      GNUNET_break (0); /* This must not happen: address without plugin */
      return;
    }
    addr = (const char *) &pir_msg[1];
    transport_name = &addr[alen];

    if (transport_name[tlen - 1] != '\0')
    {
      /* Corrupt plugin name */
      GNUNET_break (0);
      if (pal_ctx->one_shot)
      {
        pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
            GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
        GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
      }
      else
      {
        reconnect_peer_ctx (pal_ctx);
      }
      return;
    }

    /* notify client */
    address = GNUNET_HELLO_address_allocate (&pir_msg->peer,
        transport_name, addr, alen, ntohl(pir_msg->local_address_info));
    pal_ctx->cb (pal_ctx->cb_cls, &pir_msg->peer, address,
        ntohl(pir_msg->state),
        GNUNET_TIME_absolute_ntoh (pir_msg->state_timeout));
    GNUNET_HELLO_address_free (address);

  }

  /* expect more replies */
  GNUNET_CLIENT_receive (pal_ctx->client, &peer_response_processor,
                         pal_ctx,
                         GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout));
}
示例#11
0
/**
 * Cache a block in the datastore.
 *
 * @param cls closure (internal context for the plugin)
 * @param block block to cache
 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 */
static int
namecache_sqlite_cache_block (void *cls,
			      const struct GNUNET_GNSRECORD_Block *block)
{
  struct Plugin *plugin = cls;
  struct GNUNET_HashCode query;
  struct GNUNET_TIME_Absolute expiration;
  int64_t dval;
  size_t block_size;
  int n;

  namecache_sqlite_expire_blocks (plugin);
  GNUNET_CRYPTO_hash (&block->derived_key,
		      sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
		      &query);
  expiration = GNUNET_TIME_absolute_ntoh (block->expiration_time);
  dval = (int64_t) expiration.abs_value_us;
  if (dval < 0)
    dval = INT64_MAX;
  block_size = ntohl (block->purpose.size) +
    sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) +
    sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
  if (block_size > 64 * 65536)
  {
    GNUNET_break (0);
    return GNUNET_SYSERR;
  }

  /* delete old version of the block */
  if ( (SQLITE_OK !=
        sqlite3_bind_blob (plugin->delete_block, 1,
                           &query, sizeof (struct GNUNET_HashCode),
                           SQLITE_STATIC)) ||
       (SQLITE_OK !=
        sqlite3_bind_int64 (plugin->delete_block,
                            2, dval)) )
  {
    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                "sqlite3_bind_XXXX");
    if (SQLITE_OK != sqlite3_reset (plugin->delete_block))
      LOG_SQLITE (plugin,
                  GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                  "sqlite3_reset");
    return GNUNET_SYSERR;
  }
  n = sqlite3_step (plugin->delete_block);
  switch (n)
  {
  case SQLITE_DONE:
    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Old block deleted\n");
    break;
  case SQLITE_BUSY:
    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
                "sqlite3_step");
    break;
  default:
    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                "sqlite3_step");
    break;
  }
  if (SQLITE_OK != sqlite3_reset (plugin->delete_block))
    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
		"sqlite3_reset");

  /* insert new version of the block */
  if ((SQLITE_OK !=
       sqlite3_bind_blob (plugin->cache_block, 1,
			  &query, sizeof (struct GNUNET_HashCode),
			  SQLITE_STATIC)) ||
      (SQLITE_OK !=
       sqlite3_bind_blob (plugin->cache_block, 2,
			  block, block_size,
			  SQLITE_STATIC)) ||
      (SQLITE_OK !=
       sqlite3_bind_int64 (plugin->cache_block, 3,
			   dval)))
  {
    LOG_SQLITE (plugin,
		GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
		"sqlite3_bind_XXXX");
    if (SQLITE_OK != sqlite3_reset (plugin->cache_block))
      LOG_SQLITE (plugin,
		  GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
		  "sqlite3_reset");
    return GNUNET_SYSERR;

  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Caching block under derived key `%s'\n",
	      GNUNET_h2s_full (&query));
  n = sqlite3_step (plugin->cache_block);
  if (SQLITE_OK != sqlite3_reset (plugin->cache_block))
    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
		"sqlite3_reset");
  switch (n)
  {
  case SQLITE_DONE:
    LOG (GNUNET_ERROR_TYPE_DEBUG,
	 "Record stored\n");
    return GNUNET_OK;
  case SQLITE_BUSY:
    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
		"sqlite3_step");
    return GNUNET_NO;
  default:
    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
		"sqlite3_step");
    return GNUNET_SYSERR;
  }
}
/**
 * Functions with this signature are called whenever a
 * complete reply is received.
 *
 * Do not call GNUNET_SERVER_mst_destroy in callback
 *
 * @param cls closure with the 'struct StreamHandle'
 * @param client identification of the client, NULL
 * @param message the actual message
 * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing
 */
static int
reply_cb (void *cls,
	  void *client,
	  const struct GNUNET_MessageHeader *message)
{
  struct StreamHandle *sh = cls;
  const struct StreamReplyMessage *srm;
  struct HandleReplyClosure hrc;
  uint16_t msize;
  enum GNUNET_BLOCK_Type type;
  struct GNUNET_HashCode query;

  msize = ntohs (message->size);
  switch (ntohs (message->type))
  {
  case GNUNET_MESSAGE_TYPE_FS_STREAM_REPLY:
    if (sizeof (struct StreamReplyMessage) > msize)
    {
      GNUNET_break_op (0);
      reset_stream_async (sh);
      return GNUNET_SYSERR;
    }
    srm = (const struct StreamReplyMessage *) message;
    msize -= sizeof (struct StreamReplyMessage);
    type = (enum GNUNET_BLOCK_Type) ntohl (srm->type);
    if (GNUNET_YES !=
	GNUNET_BLOCK_get_key (GSF_block_ctx,
			      type,
			      &srm[1], msize, &query))
    {
      GNUNET_break_op (0); 
      reset_stream_async (sh);
      return GNUNET_SYSERR;
    }
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
		"Received reply `%s' via stream\n",
		GNUNET_h2s (&query));
    GNUNET_STATISTICS_update (GSF_stats,
			      gettext_noop ("# replies received via stream"), 1,
			      GNUNET_NO);
    hrc.data = &srm[1];
    hrc.data_size = msize;
    hrc.expiration = GNUNET_TIME_absolute_ntoh (srm->expiration);
    hrc.type = type;
    hrc.found = GNUNET_NO;
    GNUNET_CONTAINER_multihashmap_get_multiple (sh->waiting_map,
						&query,
						&handle_reply,
						&hrc);
    if (GNUNET_NO == hrc.found)
    {
      GNUNET_STATISTICS_update (GSF_stats,
				gettext_noop ("# replies received via stream dropped"), 1,
				GNUNET_NO);
      return GNUNET_OK;
    }
    return GNUNET_OK;
  default:
    GNUNET_break_op (0);
    reset_stream_async (sh);
    return GNUNET_SYSERR;
  }
}
/**
 * Function called with responses from the service.
 *
 * @param cls our `struct GNUNET_TRANSPORT_ValidationMonitoringContext *`
 * @param msg NULL on timeout or error, otherwise presumably a
 *        message with the human-readable address
 */
static void
val_response_processor (void *cls,
                        const struct GNUNET_MessageHeader *msg)
{
  struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx = cls;
  struct ValidationIterateResponseMessage *vr_msg;
  struct GNUNET_HELLO_Address *address;
  const char *addr;
  const char *transport_name;
  size_t size;
  size_t tlen;
  size_t alen;

  if (NULL == msg)
  {
    if (val_ctx->one_shot)
    {
      /* Disconnect */
      val_ctx->cb (val_ctx->cb_cls, NULL,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_TIMEOUT);
      GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
    }
    else
    {
      reconnect_val_ctx (val_ctx);
    }
    return;
  }
  size = ntohs (msg->size);
  GNUNET_break (ntohs (msg->type) ==
      GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE);

  if (size == sizeof (struct GNUNET_MessageHeader))
  {
    /* Done! */
    if (val_ctx->one_shot)
    {
      val_ctx->cb (val_ctx->cb_cls, NULL,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
      GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
    }
    else
    {
      reconnect_val_ctx (val_ctx);
    }
    return;
  }

  if ((size < sizeof (struct ValidationIterateResponseMessage)) ||
      (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE))
  {
    GNUNET_break (0);
    if (val_ctx->one_shot)
    {
      val_ctx->cb (val_ctx->cb_cls, NULL,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
      GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
    }
    else
    {
      reconnect_val_ctx (val_ctx);
    }
    return;
  }

  vr_msg = (struct ValidationIterateResponseMessage *) msg;
  tlen = ntohl (vr_msg->pluginlen);
  alen = ntohl (vr_msg->addrlen);

  if (size != sizeof (struct ValidationIterateResponseMessage) + tlen + alen)
  {
    GNUNET_break (0);
    if (val_ctx->one_shot)
    {
      val_ctx->cb (val_ctx->cb_cls, NULL,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
      GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
    }
    else
    {
      reconnect_val_ctx (val_ctx);
    }
    return;
  }
  if (0 == tlen)
  {
    GNUNET_break (0); /* This must not happen: address without plugin */
    return;
  }
  addr = (const char *) &vr_msg[1];
  transport_name = &addr[alen];
  
  if (transport_name[tlen - 1] != '\0')
  {
    /* Corrupt plugin name */
    GNUNET_break (0);
    if (val_ctx->one_shot)
    {
      val_ctx->cb (val_ctx->cb_cls,
		   NULL,
		   GNUNET_TIME_UNIT_ZERO_ABS,
		   GNUNET_TIME_UNIT_ZERO_ABS,
		   GNUNET_TIME_UNIT_ZERO_ABS,
		   GNUNET_TRANSPORT_VS_NONE);
      GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
    }
    else
    {
      reconnect_val_ctx (val_ctx);
    }
    return;
  }
  
  /* notify client */
  address = GNUNET_HELLO_address_allocate (&vr_msg->peer,
					   transport_name,
					   addr, alen,
					   ntohl (vr_msg->local_address_info));
  val_ctx->cb (val_ctx->cb_cls,
	       address,
	       GNUNET_TIME_absolute_ntoh (vr_msg->last_validation),
	       GNUNET_TIME_absolute_ntoh (vr_msg->valid_until),
	       GNUNET_TIME_absolute_ntoh (vr_msg->next_validation),
	       ntohl(vr_msg->state));
  GNUNET_HELLO_address_free (address);
  /* expect more replies */
  GNUNET_CLIENT_receive (val_ctx->client,
                         &val_response_processor,
                         val_ctx,
                         GNUNET_TIME_absolute_get_remaining (val_ctx->timeout));
}
/**
 * Handle a response
 *
 * @param peer the source
 * @param message the message
 */
static void
handle_stop (const struct GNUNET_PeerIdentity *peer,
	     const struct GNUNET_MessageHeader *message)
{
	uint16_t size;
	uint32_t name_len;
	const struct GED_stop_message *msg;
	const char *name;
	struct Node *n;
	struct Experiment *e;

	if (NULL == peer)
	{
		GNUNET_break (0);
		return;
	}
	if (NULL == message)
	{
		GNUNET_break (0);
		return;
	}

	size = ntohs (message->size);
	if (size < sizeof (struct GED_stop_message))
	{
		GNUNET_break (0);
		return;
	}
	msg = (const struct GED_stop_message *) message;
	name_len = ntohl (msg->len_name);
	if (size != sizeof (struct GED_start_message) + name_len)
	{
		GNUNET_break (0);
		return;
	}

	n = get_node (peer);
	if (NULL == n)
	{
		GNUNET_break (0);
		return;
	}
	name = (const char *) &msg[1];
	if (name[name_len-1] != '\0')
	{
		GNUNET_break (0);
		return;
	}

	if (name_len != strlen (name) + 1)
	{
		GNUNET_break (0);
		return;
	}

	e = GED_experiments_find (&msg->issuer, name, GNUNET_TIME_absolute_ntoh(msg->version_nbo));
	if (NULL == e)
	{
		GNUNET_break (0);
		return;
	}
	GED_scheduler_handle_stop (n, e);
}
示例#15
0
/**
 * Process a given reply that might match the given
 * request.
 *
 * @param cls the `struct GNUNET_DHT_ClientResultMessage`
 * @param key query of the request
 * @param value the `struct GNUNET_DHT_RouteHandle` of a request matching the same key
 * @return #GNUNET_YES to continue to iterate over all results,
 *         #GNUNET_NO if the reply is malformed or we found a matching request
 */
static int
process_reply (void *cls,
	       const struct GNUNET_HashCode *key,
	       void *value)
{
  const struct GNUNET_DHT_ClientResultMessage *dht_msg = cls;
  struct GNUNET_DHT_GetHandle *get_handle = value;
  const struct GNUNET_PeerIdentity *put_path;
  const struct GNUNET_PeerIdentity *get_path;
  struct GNUNET_HashCode hc;
  uint32_t put_path_length;
  uint32_t get_path_length;
  size_t data_length;
  size_t msize;
  size_t meta_length;
  const void *data;

  if (dht_msg->unique_id != get_handle->unique_id)
  {
    /* UID mismatch */
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Ignoring reply for %s: UID mismatch: %llu/%llu\n", GNUNET_h2s (key),
         dht_msg->unique_id, get_handle->unique_id);
    return GNUNET_YES;
  }
  msize = ntohs (dht_msg->header.size);
  put_path_length = ntohl (dht_msg->put_path_length);
  get_path_length = ntohl (dht_msg->get_path_length);
  meta_length =
      sizeof (struct GNUNET_DHT_ClientResultMessage) +
      sizeof (struct GNUNET_PeerIdentity) * (get_path_length + put_path_length);
  if ((msize < meta_length) ||
      (get_path_length >
       GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)) ||
      (put_path_length >
       GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
  {
    GNUNET_break (0);
    return GNUNET_NO;
  }
  data_length = msize - meta_length;
  LOG (GNUNET_ERROR_TYPE_DEBUG, "Giving %u byte reply for %s to application\n",
       (unsigned int) data_length, GNUNET_h2s (key));
  put_path = (const struct GNUNET_PeerIdentity *) &dht_msg[1];
  get_path = &put_path[put_path_length];
  data = &get_path[get_path_length];
  /* remember that we've seen this result */
  GNUNET_CRYPTO_hash (data, data_length, &hc);
  if (get_handle->seen_results_size == get_handle->seen_results_end)
    GNUNET_array_grow (get_handle->seen_results,
		       get_handle->seen_results_size,
		       get_handle->seen_results_size * 2 + 1);
  GNUNET_assert (get_handle->seen_results_end == get_handle->seen_results_transmission_offset);
  get_handle->seen_results[get_handle->seen_results_end++] = hc;
  /* no need to block it explicitly, service already knows about it! */
  get_handle->seen_results_transmission_offset++;
  get_handle->iter (get_handle->iter_cls,
                    GNUNET_TIME_absolute_ntoh (dht_msg->expiration), key,
                    get_path, get_path_length, put_path, put_path_length,
                    ntohl (dht_msg->type), data_length, data);
  return GNUNET_NO;
}
示例#16
0
/**
 * Type of a function to call when we receive a message
 * from the service.
 *
 * @param cls closure
 * @param msg message received, NULL on timeout or fatal error
 */
static void
process_status_message (void *cls, const struct GNUNET_MessageHeader *msg)
{
  struct GNUNET_DATASTORE_Handle *h = cls;
  struct GNUNET_DATASTORE_QueueEntry *qe;
  struct StatusContext rc;
  const struct StatusMessage *sm;
  const char *emsg;
  int32_t status;
  int was_transmitted;

  if (NULL == (qe = h->queue_head))
  {
    GNUNET_break (0);
    do_disconnect (h);
    return;
  }
  rc = qe->qc.sc;
  if (msg == NULL)
  {
    was_transmitted = qe->was_transmitted;
    free_queue_entry (qe);
    if (was_transmitted == GNUNET_YES)
      do_disconnect (h);
    else
      process_queue (h);
    if (rc.cont != NULL)
      rc.cont (rc.cont_cls, GNUNET_SYSERR,
	       GNUNET_TIME_UNIT_ZERO_ABS,
               _("Failed to receive status response from database."));
    return;
  }
  GNUNET_assert (GNUNET_YES == qe->was_transmitted);
  free_queue_entry (qe);
  if ((ntohs (msg->size) < sizeof (struct StatusMessage)) ||
      (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_DATASTORE_STATUS))
  {
    GNUNET_break (0);
    h->retry_time = GNUNET_TIME_UNIT_ZERO;
    do_disconnect (h);
    if (rc.cont != NULL)
      rc.cont (rc.cont_cls, GNUNET_SYSERR,
	       GNUNET_TIME_UNIT_ZERO_ABS,
               _("Error reading response from datastore service"));
    return;
  }
  sm = (const struct StatusMessage *) msg;
  status = ntohl (sm->status);
  emsg = NULL;
  if (ntohs (msg->size) > sizeof (struct StatusMessage))
  {
    emsg = (const char *) &sm[1];
    if (emsg[ntohs (msg->size) - sizeof (struct StatusMessage) - 1] != '\0')
    {
      GNUNET_break (0);
      emsg = _("Invalid error message received from datastore service");
    }
  }
  if ((status == GNUNET_SYSERR) && (emsg == NULL))
  {
    GNUNET_break (0);
    emsg = _("Invalid error message received from datastore service");
  }
  LOG (GNUNET_ERROR_TYPE_DEBUG, "Received status %d/%s\n", (int) status, emsg);
  GNUNET_STATISTICS_update (h->stats,
                            gettext_noop ("# status messages received"), 1,
                            GNUNET_NO);
  h->retry_time = GNUNET_TIME_UNIT_ZERO;
  process_queue (h);
  if (rc.cont != NULL)
    rc.cont (rc.cont_cls, status, 
	     GNUNET_TIME_absolute_ntoh (sm->min_expiration),
	     emsg);
}
示例#17
0
/**
 * Iterate over all of the addresses in the HELLO.
 *
 * @param msg HELLO to iterate over
 * @param return_modified if a modified copy should be returned,
 *         otherwise NULL will be returned
 * @param it iterator to call on each address
 * @param it_cls closure for it
 */
struct GNUNET_HELLO_Message *
GNUNET_HELLO_iterate_addresses (const struct GNUNET_HELLO_Message *msg,
                                int return_modified,
                                GNUNET_HELLO_AddressIterator it, void *it_cls)
{
  struct GNUNET_HELLO_Address address;
  uint16_t msize;
  struct GNUNET_HELLO_Message *ret;
  const char *inptr;
  size_t insize;
  size_t esize;
  size_t wpos;
  char *woff;
  uint16_t alen;
  struct GNUNET_TIME_AbsoluteNBO expire;
  int iret;

  msize = GNUNET_HELLO_size (msg);
  if ((msize < sizeof (struct GNUNET_HELLO_Message)) ||
      (ntohs (msg->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
    return NULL;
  ret = NULL;
  if (return_modified)
  {
    ret = GNUNET_malloc (msize);
    memcpy (ret, msg, msize);
  }
  inptr = (const char *) &msg[1];
  insize = msize - sizeof (struct GNUNET_HELLO_Message);
  wpos = 0;
  woff = (ret != NULL) ? (char *) &ret[1] : NULL;
  GNUNET_CRYPTO_hash (&msg->publicKey,
                      sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
                      &address.peer.hashPubKey);
  while (insize > 0)
  {
    esize = get_hello_address_size (inptr, insize, &alen);
    if (esize == 0)
    {
      GNUNET_break (0);
      GNUNET_free_non_null (ret);
      return NULL;
    }
    memcpy (&expire,
            &inptr[esize - alen - sizeof (struct GNUNET_TIME_AbsoluteNBO)],
            sizeof (struct GNUNET_TIME_AbsoluteNBO));
    address.address = &inptr[esize - alen];
    address.address_length = alen;
    address.transport_name = inptr;
    iret = it (it_cls, &address, GNUNET_TIME_absolute_ntoh (expire));
    if (iret == GNUNET_SYSERR)
    {
      if (ret != NULL)
        ret->header.size = ntohs (sizeof (struct GNUNET_HELLO_Message) + wpos);
      return ret;
    }
    if ((iret == GNUNET_OK) && (ret != NULL))
    {
      memcpy (woff, inptr, esize);
      woff += esize;
      wpos += esize;
    }
    insize -= esize;
    inptr += esize;
  }
  if (ret != NULL)
    ret->header.size = ntohs (sizeof (struct GNUNET_HELLO_Message) + wpos);
  return ret;
}
示例#18
0
/**
 * Function called to validate a reply or a request of type
 * #GNUNET_BLOCK_TYPE_REGEX_ACCEPT.
 * For request evaluation, pass "NULL" for the reply_block.
 * Note that it is assumed that the reply has already been
 * matched to the key (and signatures checked) as it would
 * be done with the #GNUNET_BLOCK_get_key() function.
 *
 * @param cls closure
 * @param type block type
 * @param eo control flags
 * @param query original query (hash)
 * @param bf pointer to bloom filter associated with query; possibly updated (!)
 * @param bf_mutator mutation value for bf
 * @param xquery extrended query data (can be NULL, depending on type)
 * @param xquery_size number of bytes in @a xquery
 * @param reply_block response to validate
 * @param reply_block_size number of bytes in @a reply_block
 * @return characterization of result
 */
static enum GNUNET_BLOCK_EvaluationResult
evaluate_block_regex_accept (void *cls,
                             enum GNUNET_BLOCK_Type type,
                             enum GNUNET_BLOCK_EvaluationOptions eo,
                             const struct GNUNET_HashCode * query,
                             struct GNUNET_CONTAINER_BloomFilter **bf,
                             int32_t bf_mutator, const void *xquery,
                             size_t xquery_size, const void *reply_block,
                             size_t reply_block_size)
{
  const struct RegexAcceptBlock *rba;

  if (0 != xquery_size)
  {
    GNUNET_break_op (0);
    return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID;
  }
  if (NULL == reply_block)
    return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
  if (sizeof (struct RegexAcceptBlock) != reply_block_size)
  {
    GNUNET_break_op(0);
    return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
  }
  rba = reply_block;
  if (ntohl (rba->purpose.size) !=
      sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
      sizeof (struct GNUNET_TIME_AbsoluteNBO) +
      sizeof (struct GNUNET_HashCode))
  {
    GNUNET_break_op(0);
    return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
  }
  if (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (rba->expiration_time)).rel_value_us)
  {
    /* technically invalid, but can happen without an error, so
       we're nice by reporting it as a 'duplicate' */
    return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE;
  }
  if (GNUNET_OK !=
      GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_REGEX_ACCEPT,
				&rba->purpose,
				&rba->signature,
				&rba->peer.public_key))
  {
    GNUNET_break_op(0);
    return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
  }
  if (NULL != bf)
  {
    struct GNUNET_HashCode chash;
    struct GNUNET_HashCode mhash;

    GNUNET_CRYPTO_hash (reply_block, reply_block_size, &chash);
    GNUNET_BLOCK_mingle_hash (&chash, bf_mutator, &mhash);
    if (NULL != *bf)
    {
      if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (*bf, &mhash))
        return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE;
    }
    else
    {
      *bf = GNUNET_CONTAINER_bloomfilter_init (NULL, 8, GNUNET_CONSTANTS_BLOOMFILTER_K);
    }
    GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash);
  }
  return GNUNET_BLOCK_EVALUATION_OK_MORE;
}
示例#19
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);
}
示例#20
0
/**
 * Type of a function to call when we receive a message
 * from the service.
 *
 * @param cls closure
 * @param msg message received, NULL on timeout or fatal error
 */
static void
process_result_message (void *cls, const struct GNUNET_MessageHeader *msg)
{
  struct GNUNET_DATASTORE_Handle *h = cls;
  struct GNUNET_DATASTORE_QueueEntry *qe;
  struct ResultContext rc;
  const struct DataMessage *dm;
  int was_transmitted;

  if (NULL == msg)
  {
    qe = h->queue_head;
    GNUNET_assert (NULL != qe);
    rc = qe->qc.rc;
    was_transmitted = qe->was_transmitted;
    free_queue_entry (qe);
    if (GNUNET_YES == was_transmitted)
    {
      LOG (GNUNET_ERROR_TYPE_WARNING,
           _("Failed to receive response from database.\n"));
      do_disconnect (h);
    }
    else
    {
      process_queue (h);
    }
    if (NULL != rc.proc)
      rc.proc (rc.proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS,
               0);
    return;
  }
  if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_DATASTORE_DATA_END)
  {
    GNUNET_break (ntohs (msg->size) == sizeof (struct GNUNET_MessageHeader));
    qe = h->queue_head;
    rc = qe->qc.rc;
    GNUNET_assert (GNUNET_YES == qe->was_transmitted);
    free_queue_entry (qe);
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Received end of result set, new queue size is %u\n", h->queue_size);
    h->retry_time = GNUNET_TIME_UNIT_ZERO;
    h->result_count = 0;
    process_queue (h);
    if (rc.proc != NULL)
      rc.proc (rc.proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS,
               0);
    return;
  }
  qe = h->queue_head;
  GNUNET_assert (NULL != qe);
  rc = qe->qc.rc;
  if (GNUNET_YES != qe->was_transmitted)
  {
    GNUNET_break (0);
    free_queue_entry (qe);
    h->retry_time = GNUNET_TIME_UNIT_ZERO;
    do_disconnect (h);
    if (rc.proc != NULL)
      rc.proc (rc.proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS,
               0);
    return;
  }
  if ((ntohs (msg->size) < sizeof (struct DataMessage)) ||
      (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_DATASTORE_DATA) ||
      (ntohs (msg->size) !=
       sizeof (struct DataMessage) +
       ntohl (((const struct DataMessage *) msg)->size)))
  {
    GNUNET_break (0);
    free_queue_entry (qe);
    h->retry_time = GNUNET_TIME_UNIT_ZERO;
    do_disconnect (h);
    if (rc.proc != NULL)
      rc.proc (rc.proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS,
               0);
    return;
  }
#if INSANE_STATISTICS
  GNUNET_STATISTICS_update (h->stats, gettext_noop ("# Results received"), 1,
                            GNUNET_NO);
#endif
  dm = (const struct DataMessage *) msg;
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Received result %llu with type %u and size %u with key %s\n",
       (unsigned long long) GNUNET_ntohll (dm->uid), ntohl (dm->type),
       ntohl (dm->size), GNUNET_h2s (&dm->key));
  free_queue_entry (qe);
  h->retry_time = GNUNET_TIME_UNIT_ZERO;
  process_queue (h);
  if (rc.proc != NULL)
    rc.proc (rc.proc_cls, &dm->key, ntohl (dm->size), &dm[1], ntohl (dm->type),
             ntohl (dm->priority), ntohl (dm->anonymity),
             GNUNET_TIME_absolute_ntoh (dm->expiration),
             GNUNET_ntohll (dm->uid));
}
示例#21
0
static void
handle_lookup_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
                             struct LookupNameResponseMessage * msg,
                             size_t size)
{
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n",
              "LOOKUP_NAME_RESPONSE");

  struct GNUNET_NAMESTORE_Handle *h = qe->nsh;

  /* Operation done, remove */
  GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);


  char *name;
  char * rd_tmp;

  struct GNUNET_CRYPTO_RsaSignature *signature = NULL;
  struct GNUNET_TIME_Absolute expire;
  struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key_tmp;
  size_t exp_msg_len;
  size_t msg_len = 0;
  size_t name_len = 0;
  size_t rd_len = 0;
  int contains_sig = GNUNET_NO;
  int rd_count = 0;

  rd_len = ntohs (msg->rd_len);
  rd_count = ntohs (msg->rd_count);
  msg_len = ntohs (msg->gns_header.header.size);
  name_len = ntohs (msg->name_len);
  contains_sig = ntohs (msg->contains_sig);
  expire = GNUNET_TIME_absolute_ntoh(msg->expire);

  exp_msg_len = sizeof (struct LookupNameResponseMessage) +
      sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) +
      name_len + rd_len;

  if (msg_len != exp_msg_len)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Message size describes with `%u' bytes but calculated size is %u bytes \n",
                msg_len, exp_msg_len);
    GNUNET_break_op (0);
    return;
  }

  name = (char *) &msg[1];
  if (name_len > 0)
  {
    GNUNET_assert ('\0' == name[name_len -1]);
    GNUNET_assert ((name_len - 1) == strlen(name));
  }
  rd_tmp = &name[name_len];

  /* deserialize records */
  struct GNUNET_NAMESTORE_RecordData rd[rd_count];
  if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize(rd_len, rd_tmp, rd_count, rd))
  {
    GNUNET_break_op (0);
    return;
  }


  /* reset values if values not contained */
  if (contains_sig == GNUNET_NO)
    signature = NULL;
  else
    signature = &msg->signature;
  if (name_len == 0)
    name = NULL;

  if (name != NULL)
      public_key_tmp =  &msg->public_key;
  else
      public_key_tmp = NULL;

  if (qe->proc != NULL)
  {
    qe->proc (qe->proc_cls, public_key_tmp, expire, name, rd_count, (rd_count > 0) ? rd : NULL, signature);
  }
  GNUNET_free (qe);
}
示例#22
0
int
main (int argc, char *argv[])
{
  struct GNUNET_TIME_Absolute now;
  struct GNUNET_TIME_AbsoluteNBO nown;
  struct GNUNET_TIME_Absolute future;
  struct GNUNET_TIME_Absolute past;
  struct GNUNET_TIME_Absolute last;
  struct GNUNET_TIME_Absolute forever;
  struct GNUNET_TIME_Absolute zero;
  struct GNUNET_TIME_Relative rel;
  struct GNUNET_TIME_Relative relForever;
  struct GNUNET_TIME_Relative relUnit;
  struct GNUNET_TIME_RelativeNBO reln;
  unsigned int i;

  GNUNET_log_setup ("test-time", "WARNING", NULL);
  forever = GNUNET_TIME_UNIT_FOREVER_ABS;
  relForever = GNUNET_TIME_UNIT_FOREVER_REL;
  relUnit = GNUNET_TIME_UNIT_MILLISECONDS;
  zero.abs_value_us = 0;

  last = now = GNUNET_TIME_absolute_get ();
  while (now.abs_value_us == last.abs_value_us)
    now = GNUNET_TIME_absolute_get ();
  GNUNET_assert (now.abs_value_us > last.abs_value_us);

  /* test overflow checking in multiply */
  rel = GNUNET_TIME_UNIT_MILLISECONDS;
  GNUNET_log_skip (1, GNUNET_NO);
  for (i = 0; i < 55; i++)
    rel = GNUNET_TIME_relative_multiply (rel, 2);
  GNUNET_log_skip (0, GNUNET_NO);
  GNUNET_assert (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us);
  /*check zero */
  rel.rel_value_us = (UINT64_MAX) - 1024;
  GNUNET_assert (GNUNET_TIME_UNIT_ZERO.rel_value_us ==
                 GNUNET_TIME_relative_multiply (rel, 0).rel_value_us);

  /* test infinity-check for relative to absolute */
  GNUNET_log_skip (1, GNUNET_NO);
  last = GNUNET_TIME_relative_to_absolute (rel);
  GNUNET_assert (last.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us);
  GNUNET_log_skip (0, GNUNET_YES);

  /* check relative to absolute */
  rel.rel_value_us = 1000000;
  GNUNET_assert (GNUNET_TIME_absolute_get ().abs_value_us <
                 GNUNET_TIME_relative_to_absolute (rel).abs_value_us);
  /*check forever */
  rel.rel_value_us = UINT64_MAX;
  GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us ==
                 GNUNET_TIME_relative_to_absolute (rel).abs_value_us);
  /* check overflow for r2a */
  rel.rel_value_us = (UINT64_MAX) - 1024;
  GNUNET_log_skip (1, GNUNET_NO);
  last = GNUNET_TIME_relative_to_absolute (rel);
  GNUNET_log_skip (0, GNUNET_NO);
  GNUNET_assert (last.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us);

  /* check overflow for relative add */
  GNUNET_log_skip (1, GNUNET_NO);
  rel = GNUNET_TIME_relative_add (rel, rel);
  GNUNET_log_skip (0, GNUNET_NO);
  GNUNET_assert (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us);

  GNUNET_log_skip (1, GNUNET_NO);
  rel = GNUNET_TIME_relative_add (relForever, relForever);
  GNUNET_log_skip (0, GNUNET_NO);
  GNUNET_assert (rel.rel_value_us == relForever.rel_value_us);

  GNUNET_log_skip (1, GNUNET_NO);
  rel = GNUNET_TIME_relative_add (relUnit, relUnit);
  GNUNET_assert (rel.rel_value_us == 2 * relUnit.rel_value_us);

  /* check relation check in get_duration */
  future.abs_value_us = now.abs_value_us + 1000000;
  GNUNET_assert (GNUNET_TIME_absolute_get_difference (now, future).rel_value_us ==
                 1000000);
  GNUNET_assert (GNUNET_TIME_absolute_get_difference (future, now).rel_value_us ==
                 0);

  GNUNET_assert (GNUNET_TIME_absolute_get_difference (zero, forever).rel_value_us
                 == forever.abs_value_us);

  past.abs_value_us = now.abs_value_us - 1000000;
  rel = GNUNET_TIME_absolute_get_duration (future);
  GNUNET_assert (rel.rel_value_us == 0);
  rel = GNUNET_TIME_absolute_get_duration (past);
  GNUNET_assert (rel.rel_value_us >= 1000000);

  /* check get remaining */
  rel = GNUNET_TIME_absolute_get_remaining (now);
  GNUNET_assert (rel.rel_value_us == 0);
  rel = GNUNET_TIME_absolute_get_remaining (past);
  GNUNET_assert (rel.rel_value_us == 0);
  rel = GNUNET_TIME_absolute_get_remaining (future);
  GNUNET_assert (rel.rel_value_us > 0);
  GNUNET_assert (rel.rel_value_us <= 1000000);
  forever = GNUNET_TIME_UNIT_FOREVER_ABS;
  GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us ==
                 GNUNET_TIME_absolute_get_remaining (forever).rel_value_us);

  /* check endianess */
  reln = GNUNET_TIME_relative_hton (rel);
  GNUNET_assert (rel.rel_value_us == GNUNET_TIME_relative_ntoh (reln).rel_value_us);
  nown = GNUNET_TIME_absolute_hton (now);
  GNUNET_assert (now.abs_value_us == GNUNET_TIME_absolute_ntoh (nown).abs_value_us);

  /* check absolute addition */
  future = GNUNET_TIME_absolute_add (now, GNUNET_TIME_UNIT_SECONDS);
  GNUNET_assert (future.abs_value_us == now.abs_value_us + 1000 * 1000LL);

  future = GNUNET_TIME_absolute_add (forever, GNUNET_TIME_UNIT_ZERO);
  GNUNET_assert (future.abs_value_us == forever.abs_value_us);

  rel.rel_value_us = (UINT64_MAX) - 1024;
  now.abs_value_us = rel.rel_value_us;
  future = GNUNET_TIME_absolute_add (now, rel);
  GNUNET_assert (future.abs_value_us == forever.abs_value_us);

  /* check zero */
  future = GNUNET_TIME_absolute_add (now, GNUNET_TIME_UNIT_ZERO);
  GNUNET_assert (future.abs_value_us == now.abs_value_us);

  GNUNET_assert (forever.abs_value_us ==
                 GNUNET_TIME_absolute_subtract (forever,
                                                GNUNET_TIME_UNIT_MINUTES).abs_value_us);
  /*check absolute subtract */
  now.abs_value_us = 50000;
  rel.rel_value_us = 100000;
  GNUNET_assert (GNUNET_TIME_UNIT_ZERO_ABS.abs_value_us ==
                 (GNUNET_TIME_absolute_subtract (now, rel)).abs_value_us);
  rel.rel_value_us = 10000;
  GNUNET_assert (40000 == (GNUNET_TIME_absolute_subtract (now, rel)).abs_value_us);

  /*check relative divide */
  GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us ==
                 (GNUNET_TIME_relative_divide (rel, 0)).rel_value_us);

  rel = GNUNET_TIME_UNIT_FOREVER_REL;
  GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us ==
                 (GNUNET_TIME_relative_divide (rel, 2)).rel_value_us);

  rel = GNUNET_TIME_relative_divide (relUnit, 2);
  GNUNET_assert (rel.rel_value_us == relUnit.rel_value_us / 2);


  /* check Return absolute time of 0ms */
  zero = GNUNET_TIME_UNIT_ZERO_ABS;

  /* check GNUNET_TIME_calculate_eta */
  last.abs_value_us = GNUNET_TIME_absolute_get ().abs_value_us - 1024;
  forever = GNUNET_TIME_UNIT_FOREVER_ABS;
  forever.abs_value_us = forever.abs_value_us - 1024;
  GNUNET_assert (GNUNET_TIME_UNIT_ZERO_ABS.abs_value_us ==
                 GNUNET_TIME_calculate_eta (forever, 50000, 100000).rel_value_us);
  /* check zero */
  GNUNET_log_skip (1, GNUNET_NO);
  GNUNET_assert (GNUNET_TIME_UNIT_ZERO.rel_value_us ==
                 (GNUNET_TIME_calculate_eta (last, 60000, 50000)).rel_value_us);
  GNUNET_log_skip (0, GNUNET_YES);
  /*check forever */
  GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us ==
                 (GNUNET_TIME_calculate_eta (last, 0, 50000)).rel_value_us);

  /*check relative subtract */
  now = GNUNET_TIME_absolute_get ();
  rel.rel_value_us = now.abs_value_us;
  relForever.rel_value_us = rel.rel_value_us + 1024;
  GNUNET_assert (1024 ==
                 GNUNET_TIME_relative_subtract (relForever, rel).rel_value_us);
  /*check zero */
  GNUNET_assert (GNUNET_TIME_UNIT_ZERO.rel_value_us ==
                 GNUNET_TIME_relative_subtract (rel, relForever).rel_value_us);
  /*check forever */
  rel.rel_value_us = UINT64_MAX;
  GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us ==
                 GNUNET_TIME_relative_subtract (rel, relForever).rel_value_us);

  /*check GNUNET_TIME_relative_min */
  now = GNUNET_TIME_absolute_get ();
  rel.rel_value_us = now.abs_value_us;
  relForever.rel_value_us = rel.rel_value_us - 1024;
  GNUNET_assert (relForever.rel_value_us ==
                 GNUNET_TIME_relative_min (rel, relForever).rel_value_us);

  /*check GNUNET_TIME_relative_max */
  GNUNET_assert (rel.rel_value_us ==
                 GNUNET_TIME_relative_max (rel, relForever).rel_value_us);

  /*check GNUNET_TIME_absolute_min */
  now = GNUNET_TIME_absolute_get ();
  last.abs_value_us = now.abs_value_us - 1024;
  GNUNET_assert (last.abs_value_us ==
                 GNUNET_TIME_absolute_min (now, last).abs_value_us);

  /*check  GNUNET_TIME_absolute_max */
  GNUNET_assert (now.abs_value_us ==
                 GNUNET_TIME_absolute_max (now, last).abs_value_us);

  return 0;
}
示例#23
0
static void
handle_zone_to_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
                             struct ZoneToNameResponseMessage* msg,
                             size_t size)
{
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n",
              "ZONE_TO_NAME_RESPONSE");

  struct GNUNET_NAMESTORE_Handle *h = qe->nsh;
  /* Operation done, remove */
  GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);

  int res = ntohs (msg->res);

  struct GNUNET_TIME_Absolute expire;
  size_t name_len;
  size_t rd_ser_len;
  unsigned int rd_count;

  char * name_tmp;
  char * rd_tmp;

  if (res == GNUNET_SYSERR)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "An error occured during zone to name operation\n");
    if (qe->proc != NULL)
      qe->proc (qe->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL);
  }
  else if (res == GNUNET_NO)
  {
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore has no result for zone to name mapping \n");
      if (qe->proc != NULL)
        qe->proc (qe->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL);
  }
  else if (res == GNUNET_YES)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore has result for zone to name mapping \n");

    name_len = ntohs (msg->name_len);
    rd_count = ntohs (msg->rd_count);
    rd_ser_len = ntohs (msg->rd_len);
    expire = GNUNET_TIME_absolute_ntoh(msg->expire);

    name_tmp = (char *) &msg[1];
    if (name_len > 0)
    {
      GNUNET_assert ('\0' == name_tmp[name_len -1]);
      GNUNET_assert (name_len -1 == strlen(name_tmp));
    }
    rd_tmp = &name_tmp[name_len];

    struct GNUNET_NAMESTORE_RecordData rd[rd_count];
    if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_tmp, rd_count, rd))
    {
      GNUNET_break_op (0);
      return;
    }

    if (qe->proc != NULL)
      qe->proc (qe->proc_cls, &msg->zone_key, expire, name_tmp, rd_count, rd, &msg->signature);
  }
  else
    GNUNET_break_op (0);

  GNUNET_free (qe);
}
/**
 * Handler for PUT messages.
 *
 * @param cls closure for the service
 * @param client the client we received this message from
 * @param message the actual message received
 */
static void
handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client,
                      const struct GNUNET_MessageHeader *message)
{
  const struct GNUNET_DHT_ClientPutMessage *dht_msg;
  struct GNUNET_CONTAINER_BloomFilter *peer_bf;
  uint16_t size;
  struct PendingMessage *pm;
  struct GNUNET_DHT_ClientPutConfirmationMessage *conf;

  size = ntohs (message->size);
  if (size < sizeof (struct GNUNET_DHT_ClientPutMessage))
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  GNUNET_STATISTICS_update (GDS_stats,
                            gettext_noop
                            ("# PUT requests received from clients"), 1,
                            GNUNET_NO);
  dht_msg = (const struct GNUNET_DHT_ClientPutMessage *) message;
  LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, "XDHT CLIENT-PUT %s @ %u\n",
               GNUNET_h2s (&dht_msg->key), getpid ());
  /* give to local clients */
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Handling local PUT of %u-bytes for query %s\n",
       size - sizeof (struct GNUNET_DHT_ClientPutMessage),
       GNUNET_h2s (&dht_msg->key));
  GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
                            &dht_msg->key, 0, NULL, 0, NULL,
                            ntohl (dht_msg->type),
                            size - sizeof (struct GNUNET_DHT_ClientPutMessage),
                            &dht_msg[1]);
  /* store locally */
  GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
                            &dht_msg->key, 0, NULL, ntohl (dht_msg->type),
                            size - sizeof (struct GNUNET_DHT_ClientPutMessage),
                            &dht_msg[1]);
  /* route to other peers */
  peer_bf =
      GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE,
                                         GNUNET_CONSTANTS_BLOOMFILTER_K);

  GDS_NEIGHBOURS_handle_put (ntohl (dht_msg->type), ntohl (dht_msg->options),
                             ntohl (dht_msg->desired_replication_level),
                             GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
                             0 /* hop count */ ,
                             peer_bf, &dht_msg->key, 0, NULL, &dht_msg[1],
                             size -
                             sizeof (struct GNUNET_DHT_ClientPutMessage));
  GDS_CLIENTS_process_put (ntohl (dht_msg->options),
                           ntohl (dht_msg->type),
                           0,
                           ntohl (dht_msg->desired_replication_level),
                           1,
                           GDS_NEIGHBOURS_get_id(),
                           GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
                           &dht_msg->key,
                           &dht_msg[1],
                           size - sizeof (struct GNUNET_DHT_ClientPutMessage));
  GNUNET_CONTAINER_bloomfilter_free (peer_bf);
  pm = GNUNET_malloc (sizeof (struct PendingMessage) +
		      sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage));
  conf = (struct GNUNET_DHT_ClientPutConfirmationMessage *) &pm[1];
  conf->header.size = htons (sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage));
  conf->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT_OK);
  conf->reserved = htonl (0);
  conf->unique_id = dht_msg->unique_id;
  pm->msg = &conf->header;
  add_pending_message (find_active_client (client), pm);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
示例#25
0
static void
handle_zone_iteration_response (struct GNUNET_NAMESTORE_ZoneIterator *ze,
                                struct ZoneIterationResponseMessage *msg,
                                size_t size)
{
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n",
              "ZONE_ITERATION_RESPONSE");

  struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubdummy;
  size_t msg_len = 0;
  size_t exp_msg_len = 0;
  size_t name_len = 0;
  size_t rd_len = 0;
  unsigned rd_count = 0;

  char *name_tmp;
  char *rd_ser_tmp;
  struct GNUNET_TIME_Absolute expire;

  msg_len = ntohs (msg->gns_header.header.size);
  rd_len = ntohs (msg->rd_len);
  rd_count = ntohs (msg->rd_count);
  name_len = ntohs (msg->name_len);
  expire = GNUNET_TIME_absolute_ntoh (msg->expire);

  exp_msg_len = sizeof (struct ZoneIterationResponseMessage) + name_len + rd_len;
  if (msg_len != exp_msg_len)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Message size describes with `%u' bytes but calculated size is %u bytes \n",
                msg_len, exp_msg_len);
    GNUNET_break_op (0);
    return;
  }
  if (0 != ntohs (msg->reserved))
  {
    GNUNET_break_op (0);
    return;
  }

  memset (&pubdummy, '\0', sizeof (pubdummy));
  if ((0 == name_len) && (0 == (memcmp (&msg->public_key, &pubdummy, sizeof (pubdummy)))))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration is completed!\n");

    GNUNET_CONTAINER_DLL_remove(ze->h->z_head, ze->h->z_tail, ze);

    if (ze->proc != NULL)
      ze->proc(ze->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL , 0, NULL, NULL);

    GNUNET_free (ze);
    return;
  }

  name_tmp = (char *) &msg[1];
  if ((name_tmp[name_len -1] != '\0') || (name_len > 256))
  {
    GNUNET_break_op (0);
    return;
  }
  rd_ser_tmp = (char *) &name_tmp[name_len];
  struct GNUNET_NAMESTORE_RecordData rd[rd_count];
  if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize (rd_len, rd_ser_tmp, rd_count, rd))
  {
    GNUNET_break_op (0);
    return;
  }

  if (ze->proc != NULL)
    ze->proc(ze->proc_cls, &msg->public_key, expire, name_tmp, rd_count, rd, &msg->signature);
}