convert fs publish to MQ
[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 (*GNUNET_SET_Continuation) (void *cls);
220
221
222 /**
223  * Callback for set operation results. Called for each element
224  * in the result set.
225  *
226  * @param cls closure
227  * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK
228  * @param status see `enum GNUNET_SET_Status`
229  */
230 typedef void (*GNUNET_SET_ResultIterator) (void *cls,
231                                            const struct GNUNET_SET_Element *element,
232                                            enum GNUNET_SET_Status status);
233
234 /**
235  * Iterator for set elements.
236  *
237  * @param cls closure
238  * @param element the current element, NULL if all elements have been
239  *        iterated over
240  * @return #GNUNET_YES to continue iterating, #GNUNET_NO to stop.
241  */
242 typedef int (*GNUNET_SET_ElementIterator) (void *cls,
243                                            const struct GNUNET_SET_Element *element);
244
245
246 /**
247  * Called when another peer wants to do a set operation with the
248  * local peer. If a listen error occurs, the @a request is NULL.
249  *
250  * @param cls closure
251  * @param other_peer the other peer
252  * @param context_msg message with application specific information from
253  *        the other peer
254  * @param request request from the other peer (never NULL), use GNUNET_SET_accept()
255  *        to accept it, otherwise the request will be refused
256  *        Note that we can't just return value from the listen callback,
257  *        as it is also necessary to specify the set we want to do the
258  *        operation with, whith sometimes can be derived from the context
259  *        message. It's necessary to specify the timeout.
260  */
261 typedef void
262 (*GNUNET_SET_ListenCallback) (void *cls,
263                               const struct GNUNET_PeerIdentity *other_peer,
264                               const struct GNUNET_MessageHeader *context_msg,
265                               struct GNUNET_SET_Request *request);
266
267
268
269 typedef void
270 (*GNUNET_SET_CopyReadyCallback) (void *cls,
271                                  struct GNUNET_SET_Handle *copy);
272
273
274 /**
275  * Create an empty set, supporting the specified operation.
276  *
277  * @param cfg configuration to use for connecting to the
278  *        set service
279  * @param op operation supported by the set
280  *        Note that the operation has to be specified
281  *        beforehand, as certain set operations need to maintain
282  *        data structures spefific to the operation
283  * @return a handle to the set
284  */
285 struct GNUNET_SET_Handle *
286 GNUNET_SET_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
287                    enum GNUNET_SET_OperationType op);
288
289
290 /**
291  * Add an element to the given set.
292  * After the element has been added (in the sense of being
293  * transmitted to the set service), @a cont will be called.
294  * Calls to #GNUNET_SET_add_element can be queued
295  *
296  * @param set set to add element to
297  * @param element element to add to the set
298  * @param cont continuation called after the element has been added
299  * @param cont_cls closure for @a cont
300  * @return #GNUNET_OK on success, #GNUNET_SYSERR if the
301  *         set is invalid (e.g. the set service crashed)
302  */
303 int
304 GNUNET_SET_add_element (struct GNUNET_SET_Handle *set,
305                         const struct GNUNET_SET_Element *element,
306                         GNUNET_SET_Continuation cont,
307                         void *cont_cls);
308
309
310 /**
311  * Remove an element to the given set.
312  * After the element has been removed (in the sense of the
313  * request being transmitted to the set service), cont will be called.
314  * Calls to remove_element can be queued
315  *
316  * @param set set to remove element from
317  * @param element element to remove from the set
318  * @param cont continuation called after the element has been removed
319  * @param cont_cls closure for @a cont
320  * @return #GNUNET_OK on success, #GNUNET_SYSERR if the
321  *         set is invalid (e.g. the set service crashed)
322  */
323 int
324 GNUNET_SET_remove_element (struct GNUNET_SET_Handle *set,
325                            const struct GNUNET_SET_Element *element,
326                            GNUNET_SET_Continuation cont,
327                            void *cont_cls);
328
329
330 void
331 GNUNET_SET_copy_lazy (struct GNUNET_SET_Handle *set,
332                       GNUNET_SET_CopyReadyCallback cb,
333                       void *cls);
334
335
336 /**
337  * Destroy the set handle, and free all associated resources.
338  * Iterations must have completed (or be explicitly canceled)
339  * before destroying the corresponding set.  Operations may
340  * still be pending when a set is destroyed.
341  *
342  * @param set set to destroy
343  */
344 void
345 GNUNET_SET_destroy (struct GNUNET_SET_Handle *set);
346
347
348 /**
349  * Prepare a set operation to be evaluated with another peer.
350  * The evaluation will not start until the client provides
351  * a local set with GNUNET_SET_commit().
352  *
353  * @param other_peer peer with the other set
354  * @param app_id hash for the application using the set
355  * @param context_msg additional information for the request
356  * @param result_mode specified how results will be returned,
357  *        see `enum GNUNET_SET_ResultMode`.
358  * @param result_cb called on error or success
359  * @param result_cls closure for @a result_cb
360  * @return a handle to cancel the operation
361  */
362 struct GNUNET_SET_OperationHandle *
363 GNUNET_SET_prepare (const struct GNUNET_PeerIdentity *other_peer,
364                     const struct GNUNET_HashCode *app_id,
365                     const struct GNUNET_MessageHeader *context_msg,
366                     enum GNUNET_SET_ResultMode result_mode,
367                     GNUNET_SET_ResultIterator result_cb,
368                     void *result_cls);
369
370
371 /**
372  * Wait for set operation requests for the given application ID.
373  * If the connection to the set service is lost, the listener is
374  * re-created transparently with exponential backoff.
375  *
376  * @param cfg configuration to use for connecting to
377  *            the set service
378  * @param operation operation we want to listen for
379  * @param app_id id of the application that handles set operation requests
380  * @param listen_cb called for each incoming request matching the operation
381  *                  and application id
382  * @param listen_cls handle for @a listen_cb
383  * @return a handle that can be used to cancel the listen operation
384  */
385 struct GNUNET_SET_ListenHandle *
386 GNUNET_SET_listen (const struct GNUNET_CONFIGURATION_Handle *cfg,
387                    enum GNUNET_SET_OperationType op_type,
388                    const struct GNUNET_HashCode *app_id,
389                    GNUNET_SET_ListenCallback listen_cb,
390                    void *listen_cls);
391
392
393 /**
394  * Cancel the given listen operation.  After calling cancel, the
395  * listen callback for this listen handle will not be called again.
396  *
397  * @param lh handle for the listen operation
398  */
399 void
400 GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh);
401
402
403 /**
404  * Accept a request we got via GNUNET_SET_listen().  Must be called during
405  * GNUNET_SET_listen(), as the `struct GNUNET_SET_Request` becomes invalid
406  * afterwards.
407  * Call GNUNET_SET_commit() to provide the local set to use for the operation,
408  * and to begin the exchange with the remote peer.
409  *
410  * @param request request to accept
411  * @param result_mode specified how results will be returned,
412  *        see `enum GNUNET_SET_ResultMode`.
413  * @param result_cb callback for the results
414  * @param result_cls closure for @a result_cb
415  * @return a handle to cancel the operation
416  */
417 struct GNUNET_SET_OperationHandle *
418 GNUNET_SET_accept (struct GNUNET_SET_Request *request,
419                    enum GNUNET_SET_ResultMode result_mode,
420                    GNUNET_SET_ResultIterator result_cb,
421                    void *result_cls);
422
423
424 /**
425  * Commit a set to be used with a set operation.
426  * This function is called once we have fully constructed
427  * the set that we want to use for the operation.  At this
428  * time, the P2P protocol can then begin to exchange the
429  * set information and call the result callback with the
430  * result information.
431  *
432  * @param oh handle to the set operation
433  * @param set the set to use for the operation
434  * @return #GNUNET_OK on success, #GNUNET_SYSERR if the
435  *         set is invalid (e.g. the set service crashed)
436  */
437 int
438 GNUNET_SET_commit (struct GNUNET_SET_OperationHandle *oh,
439                    struct GNUNET_SET_Handle *set);
440
441
442 /**
443  * Cancel the given set operation.  May not be called after the
444  * operation's `GNUNET_SET_ResultIterator` has been called with a
445  * status that indicates error, timeout or done.
446  *
447  * @param oh set operation to cancel
448  */
449 void
450 GNUNET_SET_operation_cancel (struct GNUNET_SET_OperationHandle *oh);
451
452
453 /**
454  * Iterate over all elements in the given set.
455  * Note that this operation involves transferring every element of the set
456  * from the service to the client, and is thus costly.
457  * Only one iteration per set may be active at the same time.
458  *
459  * @param set the set to iterate over
460  * @param iter the iterator to call for each element
461  * @param iter_cls closure for @a iter
462  * @return #GNUNET_YES if the iteration started successfuly,
463  *         #GNUNET_NO if another iteration was still active,
464  *         #GNUNET_SYSERR if the set is invalid (e.g. the server crashed, disconnected)
465  */
466 int
467 GNUNET_SET_iterate (struct GNUNET_SET_Handle *set,
468                     GNUNET_SET_ElementIterator iter,
469                     void *iter_cls);
470
471 /**
472  * Stop iteration over all elements in the given set.  Can only
473  * be called before the iteration has "naturally" completed its
474  * turn.
475  *
476  * @param set the set to stop iterating over
477  */
478 void
479 GNUNET_SET_iterate_cancel (struct GNUNET_SET_Handle *set);
480
481 /**
482  * Create a copy of an element.  The copy
483  * must be GNUNET_free-d by the caller.
484  *
485  * @param element the element to copy
486  * @return the copied element
487  */
488 struct GNUNET_SET_Element *
489 GNUNET_SET_element_dup (const struct GNUNET_SET_Element *element);
490
491 /**
492  * Hash a set element.
493  *
494  * @param element the element that should be hashed
495  * @param ret_hash a pointer to where the hash of @a element
496  *        should be stored
497  */
498 void
499 GNUNET_SET_element_hash (const struct GNUNET_SET_Element *element, struct GNUNET_HashCode *ret_hash);
500
501
502 #if 0                           /* keep Emacsens' auto-indent happy */
503 {
504 #endif
505 #ifdef __cplusplus
506 }
507 #endif
508
509 #endif
510
511 /** @} */  /* end of group */