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