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