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