gnunet-android

GNUnet for Android
Log | Files | Refs | README

gnunet_set_service.h (16189B)


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