X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Finclude%2Fgnunet_set_service.h;h=ac54153e16b8364c7701ab9d2edb450e8b37257b;hb=6e626937fd5133188d2bd06f280a1b889219eef2;hp=78dc7b7d03ef253cec235a962ab8ac73e73da22f;hpb=63321de7f2e730f590a5b0560bed321e26738b3f;p=oweals%2Fgnunet.git diff --git a/src/include/gnunet_set_service.h b/src/include/gnunet_set_service.h index 78dc7b7d0..ac54153e1 100644 --- a/src/include/gnunet_set_service.h +++ b/src/include/gnunet_set_service.h @@ -1,60 +1,339 @@ -// FIXME: copyright, etc. +/* + This file is part of GNUnet + Copyright (C) 2013, 2014 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +/** + * @author Florian Dold + * @author Christian Grothoff + * + * @file + * Two-peer set operations + * + * @defgroup set Set service + * Two-peer set operations + * + * @see [Documentation](https://gnunet.org/set-subsystem) + * + * @{ + */ + +#ifndef GNUNET_SET_SERVICE_H +#define GNUNET_SET_SERVICE_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +#include "gnunet_common.h" +#include "gnunet_time_lib.h" +#include "gnunet_configuration_lib.h" + + +/** + * Maximum size of a context message for set operation requests. + */ +#define GNUNET_SET_CONTEXT_MESSAGE_MAX_SIZE ((1<<16) - 1024) + + +/** + * Opaque handle to a set. + */ +struct GNUNET_SET_Handle; + +/** + * Opaque handle to a set operation request from another peer. + */ +struct GNUNET_SET_Request; + +/** + * Opaque handle to a listen operation. + */ +struct GNUNET_SET_ListenHandle; + +/** + * Opaque handle to a set operation. + */ +struct GNUNET_SET_OperationHandle; + /** * The operation that a set set supports. */ -enum GNUNET_SET_Operation +enum GNUNET_SET_OperationType { + /** + * A purely local set that does not support any operation. + */ + GNUNET_SET_OPERATION_NONE, + /** * Set intersection, only return elements that are in both sets. */ GNUNET_SET_OPERATION_INTERSECTION, + /** * Set union, return all elements that are in at least one of the sets. */ GNUNET_SET_OPERATION_UNION }; + /** * Status for the result callback */ enum GNUNET_SET_Status { /** - * Everything went ok. + * Everything went ok, we are transmitting an element of the + * result (in set, or to be removed from set, depending on + * the `enum GNUNET_SET_ResultMode`). + * + * Only applies to + * #GNUNET_SET_RESULT_FULL, + * #GNUNET_SET_RESULT_ADDED, + * #GNUNET_SET_RESULT_REMOVED, */ GNUNET_SET_STATUS_OK, + /** - * There was a timeout. + * Element should be added to the result set + * of the local peer, i.e. the local peer is + * missing an element. + * + * Only applies to #GNUNET_SET_RESULT_SYMMETRIC */ - GNUNET_SET_STATUS_TIMEOUT, - /* - * The other peer refused to to the operation with us + GNUNET_SET_STATUS_ADD_LOCAL, + + /** + * Element should be added to the result set + * of the remote peer, i.e. the remote peer is + * missing an element. + * + * Only applies to #GNUNET_SET_RESULT_SYMMETRIC */ - GNUNET_SET_STATUS_REFUSED + GNUNET_SET_STATUS_ADD_REMOTE, + + /** + * The other peer refused to to the operation with us, + * or something went wrong. + */ + GNUNET_SET_STATUS_FAILURE, + + /** + * Success, all elements have been returned (but the other peer + * might still be receiving some from us, so we are not done). Only + * used during UNION operation. + */ + GNUNET_SET_STATUS_HALF_DONE, + + /** + * Success, all elements have been sent (and received). + */ + GNUNET_SET_STATUS_DONE }; -// FIXME: comment + + +/** + * The way results are given to the client. + */ +enum GNUNET_SET_ResultMode +{ + /** + * Client gets every element in the resulting set. + * + * Only supported for set intersection. + */ + GNUNET_SET_RESULT_FULL, + + /** + * Client gets notified of the required changes + * for both the local and the remote set. + * + * Only supported for set + */ + GNUNET_SET_RESULT_SYMMETRIC, + + /** + * Client gets only elements that have been removed from the set. + * + * Only supported for set intersection. + */ + GNUNET_SET_RESULT_REMOVED, + + /** + * Client gets only elements that have been added to the set. + * + * Only supported for set union. + */ + GNUNET_SET_RESULT_ADDED +}; + + +/** + * Element stored in a set. + */ struct GNUNET_SET_Element { /** * Number of bytes in the buffer pointed to by data. */ uint16_t size; + /** * Application-specific element type. */ - uint16_t type; + uint16_t element_type; + /** * Actual data of the element */ - void *data; + const void *data; }; +/** + * Possible options to pass to a set operation. + * + * Used as tag for struct #GNUNET_SET_Option. + */ +enum GNUNET_SET_OptionType +{ + /** + * List terminator. + */ + GNUNET_SET_OPTION_END=0, + /** + * Fail set operations when the other peer shows weird behavior + * that might by a Byzantine fault. + * + * For set union, 'v.num' is a lower bound on elements + * that the other peer must have in common with us. + */ + GNUNET_SET_OPTION_BYZANTINE=1, + /** + * Do not use the optimized set operation, but send full sets. + * Might trigger Byzantine fault detection. + */ + GNUNET_SET_OPTION_FORCE_FULL=2, + /** + * Only use optimized set operations, even though for this + * particular set operation they might be much slower. + * Might trigger Byzantine fault detection. + */ + GNUNET_SET_OPTION_FORCE_DELTA=4, +}; + + +/** + * Option for set operations. + */ +struct GNUNET_SET_Option +{ + /** + * Type of the option. + */ + enum GNUNET_SET_OptionType type; + + /** + * Value for the option, only used with some options. + */ + union { + uint64_t num; + } v; +}; + + +/** + * Continuation used for some of the set operations + * + * @param cls closure + */ +typedef void +(*GNUNET_SET_Continuation) (void *cls); + + +/** + * Callback for set operation results. Called for each element + * in the result set. + * + * @param cls closure + * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK + * @param current_size current set size + * @param status see `enum GNUNET_SET_Status` + */ +typedef void +(*GNUNET_SET_ResultIterator) (void *cls, + const struct GNUNET_SET_Element *element, + uint64_t current_size, + enum GNUNET_SET_Status status); + +/** + * Iterator for set elements. + * + * @param cls closure + * @param element the current element, NULL if all elements have been + * iterated over + * @return #GNUNET_YES to continue iterating, #GNUNET_NO to stop. + */ +typedef int +(*GNUNET_SET_ElementIterator) (void *cls, + const struct GNUNET_SET_Element *element); + + +/** + * Called when another peer wants to do a set operation with the + * local peer. If a listen error occurs, the @a request is NULL. + * + * @param cls closure + * @param other_peer the other peer + * @param context_msg message with application specific information from + * the other peer + * @param request request from the other peer (never NULL), use GNUNET_SET_accept() + * to accept it, otherwise the request will be refused + * Note that we can't just return value from the listen callback, + * as it is also necessary to specify the set we want to do the + * operation with, whith sometimes can be derived from the context + * message. It's necessary to specify the timeout. + */ +typedef void +(*GNUNET_SET_ListenCallback) (void *cls, + const struct GNUNET_PeerIdentity *other_peer, + const struct GNUNET_MessageHeader *context_msg, + struct GNUNET_SET_Request *request); + + + +typedef void +(*GNUNET_SET_CopyReadyCallback) (void *cls, + struct GNUNET_SET_Handle *copy); + + /** * Create an empty set, supporting the specified operation. * + * @param cfg configuration to use for connecting to the + * set service * @param op operation supported by the set * Note that the operation has to be specified * beforehand, as certain set operations need to maintain @@ -62,135 +341,237 @@ struct GNUNET_SET_Element * @return a handle to the set */ struct GNUNET_SET_Handle * -GNUNET_SET_create (enum GNUNET_SET_Operation op); +GNUNET_SET_create (const struct GNUNET_CONFIGURATION_Handle *cfg, + enum GNUNET_SET_OperationType op); -// FIXME: comment -void +/** + * Add an element to the given set. + * After the element has been added (in the sense of being + * transmitted to the set service), @a cont will be called. + * Calls to #GNUNET_SET_add_element can be queued + * + * @param set set to add element to + * @param element element to add to the set + * @param cont continuation called after the element has been added + * @param cont_cls closure for @a cont + * @return #GNUNET_OK on success, #GNUNET_SYSERR if the + * set is invalid (e.g. the set service crashed) + */ +int GNUNET_SET_add_element (struct GNUNET_SET_Handle *set, const struct GNUNET_SET_Element *element, GNUNET_SET_Continuation cont, void *cont_cls); -// FIXME: comment -void +/** + * Remove an element to the given set. + * After the element has been removed (in the sense of the + * request being transmitted to the set service), cont will be called. + * Calls to remove_element can be queued + * + * @param set set to remove element from + * @param element element to remove from the set + * @param cont continuation called after the element has been removed + * @param cont_cls closure for @a cont + * @return #GNUNET_OK on success, #GNUNET_SYSERR if the + * set is invalid (e.g. the set service crashed) + */ +int GNUNET_SET_remove_element (struct GNUNET_SET_Handle *set, const struct GNUNET_SET_Element *element, GNUNET_SET_Continuation cont, void *cont_cls); -// FIXME: comment -struct GNUNET_SET_Handle * -GNUNET_SET_clone (struct GNUNET_SET_Handle *set); - - -// FIXME: comment void -GNUNET_SET_destroy (struct GNUNET_SET_Handle *set); - +GNUNET_SET_copy_lazy (struct GNUNET_SET_Handle *set, + GNUNET_SET_CopyReadyCallback cb, + void *cls); /** - * Callback for set operation results. Called for each element - * in the result set. -// FIXME: might want a way to just get the 'additional/removd' elements + * Destroy the set handle, and free all associated resources. + * Iterations must have completed (or be explicitly canceled) + * before destroying the corresponding set. Operations may + * still be pending when a set is destroyed. * - * @param cls closure - * @param element element, or NULL to indicate that all elements - * have been passed to the callback - * Only valid if (status==GNUNET_SET_STATUS_OK) holds. - * @param status see enum GNUNET_SET_Status + * @param set set to destroy */ -typedef void -(*GNUNET_SET_ResultIterator) (void *cls, - struct GNUNET_SET_Element *element, - enum GNUNET_SET_ResultStatus status); +void +GNUNET_SET_destroy (struct GNUNET_SET_Handle *set); /** - * Evaluate a set operation with our set and the set of another peer. + * Prepare a set operation to be evaluated with another peer. + * The evaluation will not start until the client provides + * a local set with GNUNET_SET_commit(). * * @param other_peer peer with the other set * @param app_id hash for the application using the set * @param context_msg additional information for the request + * @param result_mode specified how results will be returned, + * see `enum GNUNET_SET_ResultMode`. * @param result_cb called on error or success - * @param result_cls closure for result_cb + * @param result_cls closure for @a result_cb * @return a handle to cancel the operation */ struct GNUNET_SET_OperationHandle * -GNUNET_SET_evaluate (const struct GNUNET_PeerIdentity *other_peer, - const struct GNUNET_HashCode *app_id, - const struct GNUNET_MessageHeader *context_msg, - struct GNUNET_TIME_Relative timeout, - GNUNET_SET_ResultIterator result_cb, - void *result_cls); +GNUNET_SET_prepare (const struct GNUNET_PeerIdentity *other_peer, + const struct GNUNET_HashCode *app_id, + const struct GNUNET_MessageHeader *context_msg, + enum GNUNET_SET_ResultMode result_mode, + struct GNUNET_SET_Option options[], + GNUNET_SET_ResultIterator result_cb, + void *result_cls); /** - * Called when another peer wants to do a set operation with the - * local peer + * Wait for set operation requests for the given application ID. + * If the connection to the set service is lost, the listener is + * re-created transparently with exponential backoff. * - * @param other_peer the other peer - * @param context_msg message with application specific information from - * the other peer - * @param request request from the other peer, use GNUNET_SET_accept - * to accept it, otherwise the request will be refused - * Note that we don't use a return value here, as it is also - * necessary to specify the set we want to do the operation with, - * whith sometimes can be derived from the context message. - * Also necessary to specify the timeout. - */ -typedef void -(*GNUNET_SET_ListenCallback) (void *cls, - const struct GNUNET_PeerIdentity *other_peer, - const struct GNUNET_MessageHeader *context_msg, - struct GNUNET_SET_Request *request); - - -/** - * Wait for set operation requests for the given application id - * + * @param cfg configuration to use for connecting to + * the set service * @param operation operation we want to listen for * @param app_id id of the application that handles set operation requests * @param listen_cb called for each incoming request matching the operation * and application id - * @param listen_cls handle for listen_cb + * @param listen_cls handle for @a listen_cb * @return a handle that can be used to cancel the listen operation */ struct GNUNET_SET_ListenHandle * -GNUNET_SET_listen (enum GNUNET_SET_Operation operation, +GNUNET_SET_listen (const struct GNUNET_CONFIGURATION_Handle *cfg, + enum GNUNET_SET_OperationType op_type, const struct GNUNET_HashCode *app_id, GNUNET_SET_ListenCallback listen_cb, void *listen_cls); - -// FIXME: comment +/** + * Cancel the given listen operation. After calling cancel, the + * listen callback for this listen handle will not be called again. + * Note that cancelling a listen operation will automatically reject + * all operations that have not yet been accepted. + * + * @param lh handle for the listen operation + */ void GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh); /** - * Accept a request we got via GNUNET_SET_listen + * Accept a request we got via GNUNET_SET_listen(). Must be called during + * GNUNET_SET_listen(), as the `struct GNUNET_SET_Request` becomes invalid + * afterwards. + * Call GNUNET_SET_commit() to provide the local set to use for the operation, + * and to begin the exchange with the remote peer. * * @param request request to accept - * @param set set used for the requested operation - * @param timeout timeout for the set operation + * @param result_mode specified how results will be returned, + * see `enum GNUNET_SET_ResultMode`. * @param result_cb callback for the results - * @param cls closure for result_cb + * @param result_cls closure for @a result_cb + * @return a handle to cancel the operation */ struct GNUNET_SET_OperationHandle * GNUNET_SET_accept (struct GNUNET_SET_Request *request, - struct GNUNET_SET_Handle *set, - struct GNUNET_TIME_Relative timeout, + enum GNUNET_SET_ResultMode result_mode, + struct GNUNET_SET_Option options[], GNUNET_SET_ResultIterator result_cb, - void *cls) + void *result_cls); -// FIXME: comment +/** + * Commit a set to be used with a set operation. + * This function is called once we have fully constructed + * the set that we want to use for the operation. At this + * time, the P2P protocol can then begin to exchange the + * set information and call the result callback with the + * result information. + * + * @param oh handle to the set operation + * @param set the set to use for the operation + * @return #GNUNET_OK on success, #GNUNET_SYSERR if the + * set is invalid (e.g. the set service crashed) + */ +int +GNUNET_SET_commit (struct GNUNET_SET_OperationHandle *oh, + struct GNUNET_SET_Handle *set); + + +/** + * Cancel the given set operation. May not be called after the + * operation's `GNUNET_SET_ResultIterator` has been called with a + * status that indicates error, timeout or done. + * + * @param oh set operation to cancel + */ void -GNUNET_SET_operation_cancel (struct GNUNET_SET_OperationHandle *op); - +GNUNET_SET_operation_cancel (struct GNUNET_SET_OperationHandle *oh); + + +/** + * Iterate over all elements in the given set. + * Note that this operation involves transferring every element of the set + * from the service to the client, and is thus costly. + * Only one iteration per set may be active at the same time. + * + * @param set the set to iterate over + * @param iter the iterator to call for each element + * @param iter_cls closure for @a iter + * @return #GNUNET_YES if the iteration started successfuly, + * #GNUNET_NO if another iteration was still active, + * #GNUNET_SYSERR if the set is invalid (e.g. the server crashed, disconnected) + */ +int +GNUNET_SET_iterate (struct GNUNET_SET_Handle *set, + GNUNET_SET_ElementIterator iter, + void *iter_cls); + + +/** + * Stop iteration over all elements in the given set. Can only + * be called before the iteration has "naturally" completed its + * turn. + * + * @param set the set to stop iterating over + */ +void +GNUNET_SET_iterate_cancel (struct GNUNET_SET_Handle *set); + + +/** + * Create a copy of an element. The copy + * must be GNUNET_free-d by the caller. + * + * @param element the element to copy + * @return the copied element + */ +struct GNUNET_SET_Element * +GNUNET_SET_element_dup (const struct GNUNET_SET_Element *element); + + +/** + * Hash a set element. + * + * @param element the element that should be hashed + * @param ret_hash a pointer to where the hash of @a element + * should be stored + */ +void +GNUNET_SET_element_hash (const struct GNUNET_SET_Element *element, + struct GNUNET_HashCode *ret_hash); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +#endif +/** @} */ /* end of group */