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