Пример #1
0
static void
register_hashcode (struct GNUNET_HashCode *hash)
{
  struct GNUNET_HashCode replicated;
  struct IBF_Key key;
  key = ibf_key_from_hashcode (hash);
  ibf_hashcode_from_key (key, &replicated);
  (void) GNUNET_CONTAINER_multihashmap_put (key_to_hashcode,
                                            &replicated,
                                            GNUNET_memdup (hash, sizeof *hash),
                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
}
/**
 * Parses a sensor reading message struct
 *
 * @param msg message header received
 * @param sensors multihashmap of loaded sensors
 * @return sensor reading struct or NULL if error
 */
static struct ClientSensorReading *
parse_reading_message (const struct GNUNET_MessageHeader *msg,
                       struct GNUNET_CONTAINER_MultiHashMap *sensors)
{
  uint16_t msg_size;
  uint16_t value_size;
  struct GNUNET_SENSOR_ValueMessage *vm;
  struct GNUNET_SENSOR_SensorInfo *sensor;
  struct ClientSensorReading *reading;

  msg_size = ntohs (msg->size);
  if (msg_size < sizeof (struct GNUNET_SENSOR_ValueMessage))
  {
    GNUNET_break_op (0);
    return NULL;
  }
  vm = (struct GNUNET_SENSOR_ValueMessage *) msg;
  value_size = ntohs (vm->value_size);
  if ((sizeof (struct GNUNET_SENSOR_ValueMessage) + value_size) != msg_size)
  {
    GNUNET_break_op (0);
    return NULL;
  }
  sensor = GNUNET_CONTAINER_multihashmap_get (sensors, &vm->sensorname_hash);
  if (NULL == sensor)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "Unknown sensor name in reading message.\n");
    return NULL;
  }
  if ((sensor->version_minor != ntohs (vm->sensorversion_minor)) ||
      (sensor->version_major != ntohs (vm->sensorversion_major)))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "Sensor version mismatch in reading message.\n");
    return NULL;
  }
  if (0 == strcmp (sensor->expected_datatype, "numeric") &&
      sizeof (double) != value_size)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "Invalid value size for a numerical sensor.\n");
    return NULL;
  }
  reading = GNUNET_new (struct ClientSensorReading);
  reading->sensor = sensor;
  reading->timestamp = vm->timestamp;
  reading->value_size = value_size;
  reading->value = GNUNET_memdup (&vm[1], value_size);
  return reading;
}
Пример #3
0
/**
 * Store a new entry in the PEERSTORE.
 * Note that stored entries can be lost in some cases
 * such as power failure.
 *
 * @param h Handle to the PEERSTORE service
 * @param sub_system name of the sub system
 * @param peer Peer Identity
 * @param key entry key
 * @param value entry value BLOB
 * @param size size of @e value
 * @param expiry absolute time after which the entry is (possibly) deleted
 * @param options options specific to the storage operation
 * @param cont Continuation function after the store request is sent
 * @param cont_cls Closure for @a cont
 */
struct GNUNET_PEERSTORE_StoreContext *
GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
                        const char *sub_system,
                        const struct GNUNET_PeerIdentity *peer, const char *key,
                        const void *value, size_t size,
                        struct GNUNET_TIME_Absolute expiry,
                        enum GNUNET_PEERSTORE_StoreOption options,
                        GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
{
  struct GNUNET_MQ_Envelope *ev;
  struct GNUNET_PEERSTORE_StoreContext *sc;

  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Storing value (size: %lu) for subsytem `%s', peer `%s', key `%s'\n",
       size, sub_system, GNUNET_i2s (peer), key);
  ev = PEERSTORE_create_record_mq_envelope (sub_system, peer, key, value, size,
                                            &expiry, options,
                                            GNUNET_MESSAGE_TYPE_PEERSTORE_STORE);
  sc = GNUNET_new (struct GNUNET_PEERSTORE_StoreContext);

  sc->sub_system = GNUNET_strdup (sub_system);
  sc->peer = *peer;
  sc->key = GNUNET_strdup (key);
  sc->value = GNUNET_memdup (value, size);
  sc->size = size;
  sc->expiry = expiry;
  sc->options = options;
  sc->cont = cont;
  sc->cont_cls = cont_cls;
  sc->h = h;

  GNUNET_CONTAINER_DLL_insert_tail (h->store_head, h->store_tail, sc);
  GNUNET_MQ_notify_sent (ev, &store_request_sent, sc);
  GNUNET_MQ_send (h->mq, ev);
  return sc;

}
Пример #4
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;
  }
}