gnunet_set_service.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. /*
  2. This file is part of GNUnet
  3. Copyright (C) 2013, 2014 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet 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 GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @author Florian Dold
  18. * @author Christian Grothoff
  19. *
  20. * @file
  21. * Two-peer set operations
  22. *
  23. * @defgroup set Set service
  24. * Two-peer set operations
  25. *
  26. * @see [Documentation](https://gnunet.org/set-subsystem)
  27. *
  28. * @{
  29. */
  30. #ifndef GNUNET_SET_SERVICE_H
  31. #define GNUNET_SET_SERVICE_H
  32. #ifdef __cplusplus
  33. extern "C"
  34. {
  35. #if 0 /* keep Emacsens' auto-indent happy */
  36. }
  37. #endif
  38. #endif
  39. #include "gnunet_common.h"
  40. #include "gnunet_time_lib.h"
  41. #include "gnunet_configuration_lib.h"
  42. /**
  43. * Maximum size of a context message for set operation requests.
  44. */
  45. #define GNUNET_SET_CONTEXT_MESSAGE_MAX_SIZE ((1<<16) - 1024)
  46. /**
  47. * Opaque handle to a set.
  48. */
  49. struct GNUNET_SET_Handle;
  50. /**
  51. * Opaque handle to a set operation request from another peer.
  52. */
  53. struct GNUNET_SET_Request;
  54. /**
  55. * Opaque handle to a listen operation.
  56. */
  57. struct GNUNET_SET_ListenHandle;
  58. /**
  59. * Opaque handle to a set operation.
  60. */
  61. struct GNUNET_SET_OperationHandle;
  62. /**
  63. * The operation that a set set supports.
  64. */
  65. enum GNUNET_SET_OperationType
  66. {
  67. /**
  68. * A purely local set that does not support any operation.
  69. */
  70. GNUNET_SET_OPERATION_NONE,
  71. /**
  72. * Set intersection, only return elements that are in both sets.
  73. */
  74. GNUNET_SET_OPERATION_INTERSECTION,
  75. /**
  76. * Set union, return all elements that are in at least one of the sets.
  77. */
  78. GNUNET_SET_OPERATION_UNION
  79. };
  80. /**
  81. * Status for the result callback
  82. */
  83. enum GNUNET_SET_Status
  84. {
  85. /**
  86. * Everything went ok, we are transmitting an element of the
  87. * result (in set, or to be removed from set, depending on
  88. * the `enum GNUNET_SET_ResultMode`).
  89. *
  90. * Only applies to
  91. * #GNUNET_SET_RESULT_FULL,
  92. * #GNUNET_SET_RESULT_ADDED,
  93. * #GNUNET_SET_RESULT_REMOVED,
  94. */
  95. GNUNET_SET_STATUS_OK,
  96. /**
  97. * Element should be added to the result set
  98. * of the local peer, i.e. the local peer is
  99. * missing an element.
  100. *
  101. * Only applies to #GNUNET_SET_RESULT_SYMMETRIC
  102. */
  103. GNUNET_SET_STATUS_ADD_LOCAL,
  104. /**
  105. * Element should be added to the result set
  106. * of the remote peer, i.e. the remote peer is
  107. * missing an element.
  108. *
  109. * Only applies to #GNUNET_SET_RESULT_SYMMETRIC
  110. */
  111. GNUNET_SET_STATUS_ADD_REMOTE,
  112. /**
  113. * The other peer refused to to the operation with us,
  114. * or something went wrong.
  115. */
  116. GNUNET_SET_STATUS_FAILURE,
  117. /**
  118. * Success, all elements have been returned (but the other peer
  119. * might still be receiving some from us, so we are not done). Only
  120. * used during UNION operation.
  121. */
  122. GNUNET_SET_STATUS_HALF_DONE,
  123. /**
  124. * Success, all elements have been sent (and received).
  125. */
  126. GNUNET_SET_STATUS_DONE
  127. };
  128. /**
  129. * The way results are given to the client.
  130. */
  131. enum GNUNET_SET_ResultMode
  132. {
  133. /**
  134. * Client gets every element in the resulting set.
  135. *
  136. * Only supported for set intersection.
  137. */
  138. GNUNET_SET_RESULT_FULL,
  139. /**
  140. * Client gets notified of the required changes
  141. * for both the local and the remote set.
  142. *
  143. * Only supported for set
  144. */
  145. GNUNET_SET_RESULT_SYMMETRIC,
  146. /**
  147. * Client gets only elements that have been removed from the set.
  148. *
  149. * Only supported for set intersection.
  150. */
  151. GNUNET_SET_RESULT_REMOVED,
  152. /**
  153. * Client gets only elements that have been added to the set.
  154. *
  155. * Only supported for set union.
  156. */
  157. GNUNET_SET_RESULT_ADDED
  158. };
  159. /**
  160. * Element stored in a set.
  161. */
  162. struct GNUNET_SET_Element
  163. {
  164. /**
  165. * Number of bytes in the buffer pointed to by data.
  166. */
  167. uint16_t size;
  168. /**
  169. * Application-specific element type.
  170. */
  171. uint16_t element_type;
  172. /**
  173. * Actual data of the element
  174. */
  175. const void *data;
  176. };
  177. /**
  178. * Possible options to pass to a set operation.
  179. *
  180. * Used as tag for struct #GNUNET_SET_Option.
  181. */
  182. enum GNUNET_SET_OptionType
  183. {
  184. /**
  185. * List terminator.
  186. */
  187. GNUNET_SET_OPTION_END=0,
  188. /**
  189. * Fail set operations when the other peer shows weird behavior
  190. * that might by a Byzantine fault.
  191. *
  192. * For set union, 'v.num' is a lower bound on elements
  193. * that the other peer must have in common with us.
  194. */
  195. GNUNET_SET_OPTION_BYZANTINE=1,
  196. /**
  197. * Do not use the optimized set operation, but send full sets.
  198. * Might trigger Byzantine fault detection.
  199. */
  200. GNUNET_SET_OPTION_FORCE_FULL=2,
  201. /**
  202. * Only use optimized set operations, even though for this
  203. * particular set operation they might be much slower.
  204. * Might trigger Byzantine fault detection.
  205. */
  206. GNUNET_SET_OPTION_FORCE_DELTA=4,
  207. };
  208. /**
  209. * Option for set operations.
  210. */
  211. struct GNUNET_SET_Option
  212. {
  213. /**
  214. * Type of the option.
  215. */
  216. enum GNUNET_SET_OptionType type;
  217. /**
  218. * Value for the option, only used with some options.
  219. */
  220. union {
  221. uint64_t num;
  222. } v;
  223. };
  224. /**
  225. * Continuation used for some of the set operations
  226. *
  227. * @param cls closure
  228. */
  229. typedef void
  230. (*GNUNET_SET_Continuation) (void *cls);
  231. /**
  232. * Callback for set operation results. Called for each element
  233. * in the result set.
  234. *
  235. * @param cls closure
  236. * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK
  237. * @param current_size current set size
  238. * @param status see `enum GNUNET_SET_Status`
  239. */
  240. typedef void
  241. (*GNUNET_SET_ResultIterator) (void *cls,
  242. const struct GNUNET_SET_Element *element,
  243. uint64_t current_size,
  244. enum GNUNET_SET_Status status);
  245. /**
  246. * Iterator for set elements.
  247. *
  248. * @param cls closure
  249. * @param element the current element, NULL if all elements have been
  250. * iterated over
  251. * @return #GNUNET_YES to continue iterating, #GNUNET_NO to stop.
  252. */
  253. typedef int
  254. (*GNUNET_SET_ElementIterator) (void *cls,
  255. const struct GNUNET_SET_Element *element);
  256. /**
  257. * Called when another peer wants to do a set operation with the
  258. * local peer. If a listen error occurs, the @a request is NULL.
  259. *
  260. * @param cls closure
  261. * @param other_peer the other peer
  262. * @param context_msg message with application specific information from
  263. * the other peer
  264. * @param request request from the other peer (never NULL), use GNUNET_SET_accept()
  265. * to accept it, otherwise the request will be refused
  266. * Note that we can't just return value from the listen callback,
  267. * as it is also necessary to specify the set we want to do the
  268. * operation with, whith sometimes can be derived from the context
  269. * message. It's necessary to specify the timeout.
  270. */
  271. typedef void
  272. (*GNUNET_SET_ListenCallback) (void *cls,
  273. const struct GNUNET_PeerIdentity *other_peer,
  274. const struct GNUNET_MessageHeader *context_msg,
  275. struct GNUNET_SET_Request *request);
  276. typedef void
  277. (*GNUNET_SET_CopyReadyCallback) (void *cls,
  278. struct GNUNET_SET_Handle *copy);
  279. /**
  280. * Create an empty set, supporting the specified operation.
  281. *
  282. * @param cfg configuration to use for connecting to the
  283. * set service
  284. * @param op operation supported by the set
  285. * Note that the operation has to be specified
  286. * beforehand, as certain set operations need to maintain
  287. * data structures spefific to the operation
  288. * @return a handle to the set
  289. */
  290. struct GNUNET_SET_Handle *
  291. GNUNET_SET_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
  292. enum GNUNET_SET_OperationType op);
  293. /**
  294. * Add an element to the given set.
  295. * After the element has been added (in the sense of being
  296. * transmitted to the set service), @a cont will be called.
  297. * Calls to #GNUNET_SET_add_element can be queued
  298. *
  299. * @param set set to add element to
  300. * @param element element to add to the set
  301. * @param cont continuation called after the element has been added
  302. * @param cont_cls closure for @a cont
  303. * @return #GNUNET_OK on success, #GNUNET_SYSERR if the
  304. * set is invalid (e.g. the set service crashed)
  305. */
  306. int
  307. GNUNET_SET_add_element (struct GNUNET_SET_Handle *set,
  308. const struct GNUNET_SET_Element *element,
  309. GNUNET_SET_Continuation cont,
  310. void *cont_cls);
  311. /**
  312. * Remove an element to the given set.
  313. * After the element has been removed (in the sense of the
  314. * request being transmitted to the set service), cont will be called.
  315. * Calls to remove_element can be queued
  316. *
  317. * @param set set to remove element from
  318. * @param element element to remove from the set
  319. * @param cont continuation called after the element has been removed
  320. * @param cont_cls closure for @a cont
  321. * @return #GNUNET_OK on success, #GNUNET_SYSERR if the
  322. * set is invalid (e.g. the set service crashed)
  323. */
  324. int
  325. GNUNET_SET_remove_element (struct GNUNET_SET_Handle *set,
  326. const struct GNUNET_SET_Element *element,
  327. GNUNET_SET_Continuation cont,
  328. void *cont_cls);
  329. void
  330. GNUNET_SET_copy_lazy (struct GNUNET_SET_Handle *set,
  331. GNUNET_SET_CopyReadyCallback cb,
  332. void *cls);
  333. /**
  334. * Destroy the set handle, and free all associated resources.
  335. * Iterations must have completed (or be explicitly canceled)
  336. * before destroying the corresponding set. Operations may
  337. * still be pending when a set is destroyed.
  338. *
  339. * @param set set to destroy
  340. */
  341. void
  342. GNUNET_SET_destroy (struct GNUNET_SET_Handle *set);
  343. /**
  344. * Prepare a set operation to be evaluated with another peer.
  345. * The evaluation will not start until the client provides
  346. * a local set with GNUNET_SET_commit().
  347. *
  348. * @param other_peer peer with the other set
  349. * @param app_id hash for the application using the set
  350. * @param context_msg additional information for the request
  351. * @param result_mode specified how results will be returned,
  352. * see `enum GNUNET_SET_ResultMode`.
  353. * @param result_cb called on error or success
  354. * @param result_cls closure for @a result_cb
  355. * @return a handle to cancel the operation
  356. */
  357. struct GNUNET_SET_OperationHandle *
  358. GNUNET_SET_prepare (const struct GNUNET_PeerIdentity *other_peer,
  359. const struct GNUNET_HashCode *app_id,
  360. const struct GNUNET_MessageHeader *context_msg,
  361. enum GNUNET_SET_ResultMode result_mode,
  362. struct GNUNET_SET_Option options[],
  363. GNUNET_SET_ResultIterator result_cb,
  364. void *result_cls);
  365. /**
  366. * Wait for set operation requests for the given application ID.
  367. * If the connection to the set service is lost, the listener is
  368. * re-created transparently with exponential backoff.
  369. *
  370. * @param cfg configuration to use for connecting to
  371. * the set service
  372. * @param operation operation we want to listen for
  373. * @param app_id id of the application that handles set operation requests
  374. * @param listen_cb called for each incoming request matching the operation
  375. * and application id
  376. * @param listen_cls handle for @a listen_cb
  377. * @return a handle that can be used to cancel the listen operation
  378. */
  379. struct GNUNET_SET_ListenHandle *
  380. GNUNET_SET_listen (const struct GNUNET_CONFIGURATION_Handle *cfg,
  381. enum GNUNET_SET_OperationType op_type,
  382. const struct GNUNET_HashCode *app_id,
  383. GNUNET_SET_ListenCallback listen_cb,
  384. void *listen_cls);
  385. /**
  386. * Cancel the given listen operation. After calling cancel, the
  387. * listen callback for this listen handle will not be called again.
  388. * Note that cancelling a listen operation will automatically reject
  389. * all operations that have not yet been accepted.
  390. *
  391. * @param lh handle for the listen operation
  392. */
  393. void
  394. GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh);
  395. /**
  396. * Accept a request we got via GNUNET_SET_listen(). Must be called during
  397. * GNUNET_SET_listen(), as the `struct GNUNET_SET_Request` becomes invalid
  398. * afterwards.
  399. * Call GNUNET_SET_commit() to provide the local set to use for the operation,
  400. * and to begin the exchange with the remote peer.
  401. *
  402. * @param request request to accept
  403. * @param result_mode specified how results will be returned,
  404. * see `enum GNUNET_SET_ResultMode`.
  405. * @param result_cb callback for the results
  406. * @param result_cls closure for @a result_cb
  407. * @return a handle to cancel the operation
  408. */
  409. struct GNUNET_SET_OperationHandle *
  410. GNUNET_SET_accept (struct GNUNET_SET_Request *request,
  411. enum GNUNET_SET_ResultMode result_mode,
  412. struct GNUNET_SET_Option options[],
  413. GNUNET_SET_ResultIterator result_cb,
  414. void *result_cls);
  415. /**
  416. * Commit a set to be used with a set operation.
  417. * This function is called once we have fully constructed
  418. * the set that we want to use for the operation. At this
  419. * time, the P2P protocol can then begin to exchange the
  420. * set information and call the result callback with the
  421. * result information.
  422. *
  423. * @param oh handle to the set operation
  424. * @param set the set to use for the operation
  425. * @return #GNUNET_OK on success, #GNUNET_SYSERR if the
  426. * set is invalid (e.g. the set service crashed)
  427. */
  428. int
  429. GNUNET_SET_commit (struct GNUNET_SET_OperationHandle *oh,
  430. struct GNUNET_SET_Handle *set);
  431. /**
  432. * Cancel the given set operation. May not be called after the
  433. * operation's `GNUNET_SET_ResultIterator` has been called with a
  434. * status that indicates error, timeout or done.
  435. *
  436. * @param oh set operation to cancel
  437. */
  438. void
  439. GNUNET_SET_operation_cancel (struct GNUNET_SET_OperationHandle *oh);
  440. /**
  441. * Iterate over all elements in the given set.
  442. * Note that this operation involves transferring every element of the set
  443. * from the service to the client, and is thus costly.
  444. * Only one iteration per set may be active at the same time.
  445. *
  446. * @param set the set to iterate over
  447. * @param iter the iterator to call for each element
  448. * @param iter_cls closure for @a iter
  449. * @return #GNUNET_YES if the iteration started successfuly,
  450. * #GNUNET_NO if another iteration was still active,
  451. * #GNUNET_SYSERR if the set is invalid (e.g. the server crashed, disconnected)
  452. */
  453. int
  454. GNUNET_SET_iterate (struct GNUNET_SET_Handle *set,
  455. GNUNET_SET_ElementIterator iter,
  456. void *iter_cls);
  457. /**
  458. * Stop iteration over all elements in the given set. Can only
  459. * be called before the iteration has "naturally" completed its
  460. * turn.
  461. *
  462. * @param set the set to stop iterating over
  463. */
  464. void
  465. GNUNET_SET_iterate_cancel (struct GNUNET_SET_Handle *set);
  466. /**
  467. * Create a copy of an element. The copy
  468. * must be GNUNET_free-d by the caller.
  469. *
  470. * @param element the element to copy
  471. * @return the copied element
  472. */
  473. struct GNUNET_SET_Element *
  474. GNUNET_SET_element_dup (const struct GNUNET_SET_Element *element);
  475. /**
  476. * Hash a set element.
  477. *
  478. * @param element the element that should be hashed
  479. * @param ret_hash a pointer to where the hash of @a element
  480. * should be stored
  481. */
  482. void
  483. GNUNET_SET_element_hash (const struct GNUNET_SET_Element *element,
  484. struct GNUNET_HashCode *ret_hash);
  485. #if 0 /* keep Emacsens' auto-indent happy */
  486. {
  487. #endif
  488. #ifdef __cplusplus
  489. }
  490. #endif
  491. #endif
  492. /** @} */ /* end of group */