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; }
/** * 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; }
/** * 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; } }