123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- /* GNU Guix --- Functional package management for GNU
- Copyright © 2020 Maxime Devos <maxime.devos@student.kuleuven.be>
- This file is part of GNU Guix.
- GNU Guix is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or (at
- your option) any later version.
- GNU Guix is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. */
- #include <stdio.h>
- #include <gnunet/gnunet_config.h>
- #include <gnunet/gnunet_service_lib.h>
- #include <gnunet/gnunet_dht_service.h>
- #include "rehash_service.h"
- #include "extra_gnunet_protocols.h"
- #include "rehash.h"
- #include "rehash_crypto.h"
- #include "rehash_dht.h"
- static struct GNUNET_DHT_Handle *dht_handle;
- /**
- * Callback to initialise the rehash service
- */
- static void
- init_cb(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
- struct GNUNET_SERVICE_Handle *sh)
- {
- /* TODO: reasonable length */
- dht_handle = GNUNET_DHT_connect(cfg, 16);
- /* TODO: what to do */
- GNUNET_assert(dht_handle != NULL);
- }
- /**
- * Callback for when a client connects to the service.
- */
- static void *
- connect_cb(void *cls, struct GNUNET_SERVICE_Client *c,
- struct GNUNET_MQ_Handle *mq)
- {
- return c;
- }
- /**
- * Callback for when a client is disconnected from the service.
- */
- static void
- disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *c, void *internal_cls)
- {
- }
- static int
- check_get (void *cls, const struct GNUNET_REHASH_GetMessage *msg)
- {
- uint16_t header_size;
- uint32_t input_length; /* TODO perhaps uint16_t */
- header_size = ntohs(msg->header.size);
- input_length = ntohl(msg->input_length);
- if (header_size - sizeof(struct GNUNET_REHASH_GetMessage) != input_length)
- {
- GNUNET_break(0);
- return GNUNET_SYSERR;
- }
- /* Detect unsupported options */
- if (ntohl(msg->options) > 1)
- {
- GNUNET_break(0);
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
- }
- static void
- dht_get_iterator(void *cls,
- struct GNUNET_TIME_Absolute exp,
- const struct GNUNET_HashCode *key,
- const struct GNUNET_PeerIdentity *get_path,
- unsigned int get_path_length,
- const struct GNUNET_PeerIdentity *put_path,
- unsigned int put_path_length,
- enum GNUNET_BLOCK_Type type,
- size_t size,
- const void *data)
- {
- struct GNUNET_SERVICE_Client *client = cls;
- /* TODO: who should free get_path, put_path?*/
- /* TODO: send a GNUNET_REHASH_ResultMessage */
- struct GNUNET_MQ_Envelope *ev;
- struct GNUNET_REHASH_ResultMessage *msg;
- /* Prevent buffer overflow.
- TODO: less magic constants! */
- if (size > 64)
- {
- GNUNET_break(0);
- return;
- }
- /* Inform the client of the found message */
- ev = GNUNET_MQ_msg_extra (msg, size, GNUNET_MESSAGE_TYPE_REHASH_CLIENT_RESULT);
- msg->output_length = htonl (size);
- msg->exp = GNUNET_TIME_absolute_hton (exp);
- memcpy(&msg[1], data, size);
- GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), ev);
- }
- static void
- handle_get (void *cls, const struct GNUNET_REHASH_GetMessage *msg)
- {
- struct GNUNET_SERVICE_Client *c = cls;
- struct GNUNET_DHT_GetHandle *h;
- struct GNUNET_HashCode key;
- /* TODO: define protocols for anonymous GET */
- GNUNET_assert(ntohl(msg->anonymity_level) == 0);
- if (GNUNET_OK !=
- GNUNET_REHASH_obfuscated_query_from_hash
- (ntohl(msg->out_type),
- ntohl(msg->in_type),
- (const char *) &msg[1],
- ntohl(msg->input_length),
- &key))
- /* TODO bweh? disconnect? */
- return;
- /* TODO: desired replication level */
- h = GNUNET_REHASH_dht_get_start (dht_handle,
- &key,
- 1,
- GNUNET_DHT_RO_NONE,
- &dht_get_iterator,
- cls);
- GNUNET_SERVICE_client_continue(c);
- /* TODO: free h eventually */
- }
- static int
- check_get_stop (void *cls, const struct GNUNET_REHASH_GetStopMessage *msg)
- {
- GNUNET_assert(0);
- }
- static void
- handle_get_stop (void *cls, const struct GNUNET_REHASH_GetStopMessage *msg)
- {
- }
- static int
- check_put (void *cls, const struct GNUNET_REHASH_PutMessage *msg)
- {
- uint32_t input_length;
- uint32_t output_length;
- input_length = ntohl(msg->input_length);
- output_length = ntohl(msg->output_length);
- /* Prevent overflow TODO no magic values */
- if (input_length > 64)
- return GNUNET_SYSERR;
- if (output_length > 64)
- return GNUNET_SYSERR;
- if (input_length + output_length + sizeof(*msg)
- != msg->header.size)
- return GNUNET_SYSERR;
- /* TODO prevent saving of hashes of incorrect lengths */
- return GNUNET_OK;
- }
- static void
- handle_put (void *cls, const struct GNUNET_REHASH_PutMessage *msg)
- {
- struct GNUNET_DHT_PutHandle *h;
- struct GNUNET_HashCode query;
- char *dest;
- const char *out_data;
- const char *in_data;
- ssize_t expected_length;
- ssize_t serialised_length;
- GNUNET_assert(msg->anonymity_level == 0);
- /* TODO also put into datastore */
- if (GNUNET_OK !=
- GNUNET_REHASH_obfuscated_query_from_hash
- (ntohl(msg->out_type),
- ntohl(msg->in_type),
- (const char *) &msg[1],
- ntohl(msg->input_length),
- &query))
- {
- /* TODO: ? TODO */
- GNUNET_break(0);
- return;
- }
- in_data = (const char *) &msg[1];
- out_data = in_data + ntohl(msg->input_length);
- expected_length = GNUNET_REHASH_data_size_for_mapping
- (ntohl(msg->output_length));
- dest = GNUNET_malloc (expected_length);
- serialised_length = GNUNET_REHASH_data_for_mapping
- (ntohl(msg->out_type),
- ntohl(msg->in_type),
- out_data,
- in_data,
- ntohl(msg->output_length),
- ntohl(msg->input_length),
- dest,
- expected_length);
- if (serialised_length != expected_length)
- {
- GNUNET_free (dest);
- GNUNET_break (0);
- /* TODO error message */
- return;
- }
- h = GNUNET_REHASH_dht_put (dht_handle,
- &query,
- ntohl(msg->replication_level),
- GNUNET_DHT_RO_NONE,
- serialised_length,
- dest,
- GNUNET_TIME_absolute_ntoh(msg->expiration_time),
- /* TODO callback */
- NULL,
- NULL);
- GNUNET_free(dest);
- /* TODO free h eventually */
- }
- GNUNET_SERVICE_MAIN
- ("rehash",
- GNUNET_SERVICE_OPTION_NONE,
- &init_cb,
- &connect_cb,
- &disconnect_cb,
- NULL,
- /* TODO MQ handlers! */
- GNUNET_MQ_hd_var_size (get,
- GNUNET_MESSAGE_TYPE_REHASH_CLIENT_GET,
- struct GNUNET_REHASH_GetMessage,
- NULL),
- GNUNET_MQ_hd_var_size (get_stop,
- GNUNET_MESSAGE_TYPE_REHASH_CLIENT_GET_STOP,
- struct GNUNET_REHASH_GetStopMessage,
- NULL),
- GNUNET_MQ_hd_var_size (put,
- GNUNET_MESSAGE_TYPE_REHASH_CLIENT_PUT,
- struct GNUNET_REHASH_PutMessage,
- NULL),
- GNUNET_MQ_handler_end ());
|