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