rehash-service.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /* GNU Guix --- Functional package management for GNU
  2. Copyright © 2020 Maxime Devos <maxime.devos@student.kuleuven.be>
  3. This file is part of GNU Guix.
  4. GNU Guix is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or (at
  7. your option) any later version.
  8. GNU Guix is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. */
  14. #include <stdio.h>
  15. #include <gnunet/gnunet_config.h>
  16. #include <gnunet/gnunet_service_lib.h>
  17. #include <gnunet/gnunet_dht_service.h>
  18. #include "rehash_service.h"
  19. #include "extra_gnunet_protocols.h"
  20. #include "rehash.h"
  21. #include "rehash_crypto.h"
  22. #include "rehash_dht.h"
  23. static struct GNUNET_DHT_Handle *dht_handle;
  24. /**
  25. * Callback to initialise the rehash service
  26. */
  27. static void
  28. init_cb(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
  29. struct GNUNET_SERVICE_Handle *sh)
  30. {
  31. /* TODO: reasonable length */
  32. dht_handle = GNUNET_DHT_connect(cfg, 16);
  33. /* TODO: what to do */
  34. GNUNET_assert(dht_handle != NULL);
  35. }
  36. /**
  37. * Callback for when a client connects to the service.
  38. */
  39. static void *
  40. connect_cb(void *cls, struct GNUNET_SERVICE_Client *c,
  41. struct GNUNET_MQ_Handle *mq)
  42. {
  43. return c;
  44. }
  45. /**
  46. * Callback for when a client is disconnected from the service.
  47. */
  48. static void
  49. disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *c, void *internal_cls)
  50. {
  51. }
  52. static int
  53. check_get (void *cls, const struct GNUNET_REHASH_GetMessage *msg)
  54. {
  55. uint16_t header_size;
  56. uint32_t input_length; /* TODO perhaps uint16_t */
  57. header_size = ntohs(msg->header.size);
  58. input_length = ntohl(msg->input_length);
  59. if (header_size - sizeof(struct GNUNET_REHASH_GetMessage) != input_length)
  60. {
  61. GNUNET_break(0);
  62. return GNUNET_SYSERR;
  63. }
  64. /* Detect unsupported options */
  65. if (ntohl(msg->options) > 1)
  66. {
  67. GNUNET_break(0);
  68. return GNUNET_SYSERR;
  69. }
  70. return GNUNET_OK;
  71. }
  72. static void
  73. dht_get_iterator(void *cls,
  74. struct GNUNET_TIME_Absolute exp,
  75. const struct GNUNET_HashCode *key,
  76. const struct GNUNET_PeerIdentity *get_path,
  77. unsigned int get_path_length,
  78. const struct GNUNET_PeerIdentity *put_path,
  79. unsigned int put_path_length,
  80. enum GNUNET_BLOCK_Type type,
  81. size_t size,
  82. const void *data)
  83. {
  84. struct GNUNET_SERVICE_Client *client = cls;
  85. /* TODO: who should free get_path, put_path?*/
  86. /* TODO: send a GNUNET_REHASH_ResultMessage */
  87. struct GNUNET_MQ_Envelope *ev;
  88. struct GNUNET_REHASH_ResultMessage *msg;
  89. /* Prevent buffer overflow.
  90. TODO: less magic constants! */
  91. if (size > 64)
  92. {
  93. GNUNET_break(0);
  94. return;
  95. }
  96. /* Inform the client of the found message */
  97. ev = GNUNET_MQ_msg_extra (msg, size, GNUNET_MESSAGE_TYPE_REHASH_CLIENT_RESULT);
  98. msg->output_length = htonl (size);
  99. msg->exp = GNUNET_TIME_absolute_hton (exp);
  100. memcpy(&msg[1], data, size);
  101. GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), ev);
  102. }
  103. static void
  104. handle_get (void *cls, const struct GNUNET_REHASH_GetMessage *msg)
  105. {
  106. struct GNUNET_SERVICE_Client *c = cls;
  107. struct GNUNET_DHT_GetHandle *h;
  108. struct GNUNET_HashCode key;
  109. /* TODO: define protocols for anonymous GET */
  110. GNUNET_assert(ntohl(msg->anonymity_level) == 0);
  111. if (GNUNET_OK !=
  112. GNUNET_REHASH_obfuscated_query_from_hash
  113. (ntohl(msg->out_type),
  114. ntohl(msg->in_type),
  115. (const char *) &msg[1],
  116. ntohl(msg->input_length),
  117. &key))
  118. /* TODO bweh? disconnect? */
  119. return;
  120. /* TODO: desired replication level */
  121. h = GNUNET_REHASH_dht_get_start (dht_handle,
  122. &key,
  123. 1,
  124. GNUNET_DHT_RO_NONE,
  125. &dht_get_iterator,
  126. cls);
  127. GNUNET_SERVICE_client_continue(c);
  128. /* TODO: free h eventually */
  129. }
  130. static int
  131. check_get_stop (void *cls, const struct GNUNET_REHASH_GetStopMessage *msg)
  132. {
  133. GNUNET_assert(0);
  134. }
  135. static void
  136. handle_get_stop (void *cls, const struct GNUNET_REHASH_GetStopMessage *msg)
  137. {
  138. }
  139. static int
  140. check_put (void *cls, const struct GNUNET_REHASH_PutMessage *msg)
  141. {
  142. uint32_t input_length;
  143. uint32_t output_length;
  144. input_length = ntohl(msg->input_length);
  145. output_length = ntohl(msg->output_length);
  146. /* Prevent overflow TODO no magic values */
  147. if (input_length > 64)
  148. return GNUNET_SYSERR;
  149. if (output_length > 64)
  150. return GNUNET_SYSERR;
  151. if (input_length + output_length + sizeof(*msg)
  152. != msg->header.size)
  153. return GNUNET_SYSERR;
  154. /* TODO prevent saving of hashes of incorrect lengths */
  155. return GNUNET_OK;
  156. }
  157. static void
  158. handle_put (void *cls, const struct GNUNET_REHASH_PutMessage *msg)
  159. {
  160. struct GNUNET_DHT_PutHandle *h;
  161. struct GNUNET_HashCode query;
  162. char *dest;
  163. const char *out_data;
  164. const char *in_data;
  165. ssize_t expected_length;
  166. ssize_t serialised_length;
  167. GNUNET_assert(msg->anonymity_level == 0);
  168. /* TODO also put into datastore */
  169. if (GNUNET_OK !=
  170. GNUNET_REHASH_obfuscated_query_from_hash
  171. (ntohl(msg->out_type),
  172. ntohl(msg->in_type),
  173. (const char *) &msg[1],
  174. ntohl(msg->input_length),
  175. &query))
  176. {
  177. /* TODO: ? TODO */
  178. GNUNET_break(0);
  179. return;
  180. }
  181. in_data = (const char *) &msg[1];
  182. out_data = in_data + ntohl(msg->input_length);
  183. expected_length = GNUNET_REHASH_data_size_for_mapping
  184. (ntohl(msg->output_length));
  185. dest = GNUNET_malloc (expected_length);
  186. serialised_length = GNUNET_REHASH_data_for_mapping
  187. (ntohl(msg->out_type),
  188. ntohl(msg->in_type),
  189. out_data,
  190. in_data,
  191. ntohl(msg->output_length),
  192. ntohl(msg->input_length),
  193. dest,
  194. expected_length);
  195. if (serialised_length != expected_length)
  196. {
  197. GNUNET_free (dest);
  198. GNUNET_break (0);
  199. /* TODO error message */
  200. return;
  201. }
  202. h = GNUNET_REHASH_dht_put (dht_handle,
  203. &query,
  204. ntohl(msg->replication_level),
  205. GNUNET_DHT_RO_NONE,
  206. serialised_length,
  207. dest,
  208. GNUNET_TIME_absolute_ntoh(msg->expiration_time),
  209. /* TODO callback */
  210. NULL,
  211. NULL);
  212. GNUNET_free(dest);
  213. /* TODO free h eventually */
  214. }
  215. GNUNET_SERVICE_MAIN
  216. ("rehash",
  217. GNUNET_SERVICE_OPTION_NONE,
  218. &init_cb,
  219. &connect_cb,
  220. &disconnect_cb,
  221. NULL,
  222. /* TODO MQ handlers! */
  223. GNUNET_MQ_hd_var_size (get,
  224. GNUNET_MESSAGE_TYPE_REHASH_CLIENT_GET,
  225. struct GNUNET_REHASH_GetMessage,
  226. NULL),
  227. GNUNET_MQ_hd_var_size (get_stop,
  228. GNUNET_MESSAGE_TYPE_REHASH_CLIENT_GET_STOP,
  229. struct GNUNET_REHASH_GetStopMessage,
  230. NULL),
  231. GNUNET_MQ_hd_var_size (put,
  232. GNUNET_MESSAGE_TYPE_REHASH_CLIENT_PUT,
  233. struct GNUNET_REHASH_PutMessage,
  234. NULL),
  235. GNUNET_MQ_handler_end ());