migrate peerstore to new service MQ API
[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
6       it under the terms of the GNU General Public License as published
7       by the Free Software Foundation; either version 3, or (at your
8       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       General Public License for more details.
14
15       You should have received a copy of the GNU General Public License
16       along with GNUnet; see the file COPYING.  If not, write to the
17       Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18       Boston, MA 02110-1301, USA.
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 remove 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  * The way results are given to the client.
158  */
159 enum GNUNET_SET_ResultMode
160 {
161   /**
162    * Client gets every element in the resulting set.
163    *
164    * Only supported for set intersection.
165    */
166   GNUNET_SET_RESULT_FULL,
167
168   /**
169    * Client gets notified of the required changes
170    * for both the local and the remote set.
171    *
172    * Only supported for set
173    */
174   GNUNET_SET_RESULT_SYMMETRIC,
175
176   /**
177    * Client gets only elements that have been removed from the set.
178    *
179    * Only supported for set intersection.
180    */
181   GNUNET_SET_RESULT_REMOVED,
182
183   /**
184    * Client gets only elements that have been removed from the set.
185    *
186    * Only supported for set union.
187    */
188   GNUNET_SET_RESULT_ADDED
189 };
190
191
192 /**
193  * Element stored in a set.
194  */
195 struct GNUNET_SET_Element
196 {
197   /**
198    * Number of bytes in the buffer pointed to by data.
199    */
200   uint16_t size;
201
202   /**
203    * Application-specific element type.
204    */
205   uint16_t element_type;
206
207   /**
208    * Actual data of the element
209    */
210   const void *data;
211 };
212
213
214 /**
215  * Continuation used for some of the set operations
216  *
217  * @param cls closure
218  */
219 typedef void
220 (*GNUNET_SET_Continuation) (void *cls);
221
222
223 /**
224  * Callback for set operation results. Called for each element
225  * in the result set.
226  *
227  * @param cls closure
228  * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK
229  * @param status see `enum GNUNET_SET_Status`
230  */
231 typedef void
232 (*GNUNET_SET_ResultIterator) (void *cls,
233                               const struct GNUNET_SET_Element *element,
234                               enum GNUNET_SET_Status status);
235
236 /**
237  * Iterator for set elements.
238  *
239  * @param cls closure
240  * @param element the current element, NULL if all elements have been
241  *        iterated over
242  * @return #GNUNET_YES to continue iterating, #GNUNET_NO to stop.
243  */
244 typedef int
245 (*GNUNET_SET_ElementIterator) (void *cls,
246                                const struct GNUNET_SET_Element *element);
247
248
249 /**
250  * Called when another peer wants to do a set operation with the
251  * local peer. If a listen error occurs, the @a request is NULL.
252  *
253  * @param cls closure
254  * @param other_peer the other peer
255  * @param context_msg message with application specific information from
256  *        the other peer
257  * @param request request from the other peer (never NULL), use GNUNET_SET_accept()
258  *        to accept it, otherwise the request will be refused
259  *        Note that we can't just return value from the listen callback,
260  *        as it is also necessary to specify the set we want to do the
261  *        operation with, whith sometimes can be derived from the context
262  *        message. It's necessary to specify the timeout.
263  */
264 typedef void
265 (*GNUNET_SET_ListenCallback) (void *cls,
266                               const struct GNUNET_PeerIdentity *other_peer,
267                               const struct GNUNET_MessageHeader *context_msg,
268                               struct GNUNET_SET_Request *request);
269
270
271
272 typedef void
273 (*GNUNET_SET_CopyReadyCallback) (void *cls,
274                                  struct GNUNET_SET_Handle *copy);
275
276
277 /**
278  * Create an empty set, supporting the specified operation.
279  *
280  * @param cfg configuration to use for connecting to the
281  *        set service
282  * @param op operation supported by the set
283  *        Note that the operation has to be specified
284  *        beforehand, as certain set operations need to maintain
285  *        data structures spefific to the operation
286  * @return a handle to the set
287  */
288 struct GNUNET_SET_Handle *
289 GNUNET_SET_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
290                    enum GNUNET_SET_OperationType op);
291
292
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
313 /**
314  * Remove an element to the given set.
315  * After the element has been removed (in the sense of the
316  * request being transmitted to the set service), cont will be called.
317  * Calls to remove_element can be queued
318  *
319  * @param set set to remove element from
320  * @param element element to remove from the set
321  * @param cont continuation called after the element has been removed
322  * @param cont_cls closure for @a cont
323  * @return #GNUNET_OK on success, #GNUNET_SYSERR if the
324  *         set is invalid (e.g. the set service crashed)
325  */
326 int
327 GNUNET_SET_remove_element (struct GNUNET_SET_Handle *set,
328                            const struct GNUNET_SET_Element *element,
329                            GNUNET_SET_Continuation cont,
330                            void *cont_cls);
331
332
333 void
334 GNUNET_SET_copy_lazy (struct GNUNET_SET_Handle *set,
335                       GNUNET_SET_CopyReadyCallback cb,
336                       void *cls);
337
338
339 /**
340  * Destroy the set handle, and free all associated resources.
341  * Iterations must have completed (or be explicitly canceled)
342  * before destroying the corresponding set.  Operations may
343  * still be pending when a set is destroyed.
344  *
345  * @param set set to destroy
346  */
347 void
348 GNUNET_SET_destroy (struct GNUNET_SET_Handle *set);
349
350
351 /**
352  * Prepare a set operation to be evaluated with another peer.
353  * The evaluation will not start until the client provides
354  * a local set with GNUNET_SET_commit().
355  *
356  * @param other_peer peer with the other set
357  * @param app_id hash for the application using the set
358  * @param context_msg additional information for the request
359  * @param result_mode specified how results will be returned,
360  *        see `enum GNUNET_SET_ResultMode`.
361  * @param result_cb called on error or success
362  * @param result_cls closure for @a result_cb
363  * @return a handle to cancel the operation
364  */
365 struct GNUNET_SET_OperationHandle *
366 GNUNET_SET_prepare (const struct GNUNET_PeerIdentity *other_peer,
367                     const struct GNUNET_HashCode *app_id,
368                     const struct GNUNET_MessageHeader *context_msg,
369                     enum GNUNET_SET_ResultMode result_mode,
370                     GNUNET_SET_ResultIterator result_cb,
371                     void *result_cls);
372
373
374 /**
375  * Wait for set operation requests for the given application ID.
376  * If the connection to the set service is lost, the listener is
377  * re-created transparently with exponential backoff.
378  *
379  * @param cfg configuration to use for connecting to
380  *            the set service
381  * @param operation operation we want to listen for
382  * @param app_id id of the application that handles set operation requests
383  * @param listen_cb called for each incoming request matching the operation
384  *                  and application id
385  * @param listen_cls handle for @a listen_cb
386  * @return a handle that can be used to cancel the listen operation
387  */
388 struct GNUNET_SET_ListenHandle *
389 GNUNET_SET_listen (const struct GNUNET_CONFIGURATION_Handle *cfg,
390                    enum GNUNET_SET_OperationType op_type,
391                    const struct GNUNET_HashCode *app_id,
392                    GNUNET_SET_ListenCallback listen_cb,
393                    void *listen_cls);
394
395
396 /**
397  * Cancel the given listen operation.  After calling cancel, the
398  * listen callback for this listen handle will not be called again.
399  *
400  * @param lh handle for the listen operation
401  */
402 void
403 GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh);
404
405
406 /**
407  * Accept a request we got via GNUNET_SET_listen().  Must be called during
408  * GNUNET_SET_listen(), as the `struct GNUNET_SET_Request` becomes invalid
409  * afterwards.
410  * Call GNUNET_SET_commit() to provide the local set to use for the operation,
411  * and to begin the exchange with the remote peer.
412  *
413  * @param request request to accept
414  * @param result_mode specified how results will be returned,
415  *        see `enum GNUNET_SET_ResultMode`.
416  * @param result_cb callback for the results
417  * @param result_cls closure for @a result_cb
418  * @return a handle to cancel the operation
419  */
420 struct GNUNET_SET_OperationHandle *
421 GNUNET_SET_accept (struct GNUNET_SET_Request *request,
422                    enum GNUNET_SET_ResultMode result_mode,
423                    GNUNET_SET_ResultIterator result_cb,
424                    void *result_cls);
425
426
427 /**
428  * Commit a set to be used with a set operation.
429  * This function is called once we have fully constructed
430  * the set that we want to use for the operation.  At this
431  * time, the P2P protocol can then begin to exchange the
432  * set information and call the result callback with the
433  * result information.
434  *
435  * @param oh handle to the set operation
436  * @param set the set to use for the operation
437  * @return #GNUNET_OK on success, #GNUNET_SYSERR if the
438  *         set is invalid (e.g. the set service crashed)
439  */
440 int
441 GNUNET_SET_commit (struct GNUNET_SET_OperationHandle *oh,
442                    struct GNUNET_SET_Handle *set);
443
444
445 /**
446  * Cancel the given set operation.  May not be called after the
447  * operation's `GNUNET_SET_ResultIterator` has been called with a
448  * status that indicates error, timeout or done.
449  *
450  * @param oh set operation to cancel
451  */
452 void
453 GNUNET_SET_operation_cancel (struct GNUNET_SET_OperationHandle *oh);
454
455
456 /**
457  * Iterate over all elements in the given set.
458  * Note that this operation involves transferring every element of the set
459  * from the service to the client, and is thus costly.
460  * Only one iteration per set may be active at the same time.
461  *
462  * @param set the set to iterate over
463  * @param iter the iterator to call for each element
464  * @param iter_cls closure for @a iter
465  * @return #GNUNET_YES if the iteration started successfuly,
466  *         #GNUNET_NO if another iteration was still active,
467  *         #GNUNET_SYSERR if the set is invalid (e.g. the server crashed, disconnected)
468  */
469 int
470 GNUNET_SET_iterate (struct GNUNET_SET_Handle *set,
471                     GNUNET_SET_ElementIterator iter,
472                     void *iter_cls);
473
474 /**
475  * Stop iteration over all elements in the given set.  Can only
476  * be called before the iteration has "naturally" completed its
477  * turn.
478  *
479  * @param set the set to stop iterating over
480  */
481 void
482 GNUNET_SET_iterate_cancel (struct GNUNET_SET_Handle *set);
483
484 /**
485  * Create a copy of an element.  The copy
486  * must be GNUNET_free-d by the caller.
487  *
488  * @param element the element to copy
489  * @return the copied element
490  */
491 struct GNUNET_SET_Element *
492 GNUNET_SET_element_dup (const struct GNUNET_SET_Element *element);
493
494 /**
495  * Hash a set element.
496  *
497  * @param element the element that should be hashed
498  * @param ret_hash a pointer to where the hash of @a element
499  *        should be stored
500  */
501 void
502 GNUNET_SET_element_hash (const struct GNUNET_SET_Element *element, struct GNUNET_HashCode *ret_hash);
503
504
505 #if 0                           /* keep Emacsens' auto-indent happy */
506 {
507 #endif
508 #ifdef __cplusplus
509 }
510 #endif
511
512 #endif
513
514 /** @} */  /* end of group */