/* This file is part of GNUnet Copyright (C) 2013-2017 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 */ /** * @file set/gnunet-service-setu.h * @brief common components for the implementation the different set operations * @author Florian Dold * @author Christian Grothoff */ #ifndef GNUNET_SERVICE_SETU_H_PRIVATE #define GNUNET_SERVICE_SETU_H_PRIVATE #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_protocols.h" #include "gnunet_applications.h" #include "gnunet_core_service.h" #include "gnunet_cadet_service.h" #include "gnunet_setu_service.h" #include "setu.h" /** * Implementation-specific set state. Used as opaque pointer, and * specified further in the respective implementation. */ struct SetState; /** * Implementation-specific set operation. Used as opaque pointer, and * specified further in the respective implementation. */ struct OperationState; /** * A set that supports a specific operation with other peers. */ struct Set; /** * Information about an element element in the set. All elements are * stored in a hash-table from their hash-code to their 'struct * Element', so that the remove and add operations are reasonably * fast. */ struct ElementEntry; /** * Operation context used to execute a set operation. */ struct Operation; /** * Information about an element element in the set. All elements are * stored in a hash-table from their hash-code to their `struct * Element`, so that the remove and add operations are reasonably * fast. */ struct ElementEntry { /** * The actual element. The data for the element * should be allocated at the end of this struct. */ struct GNUNET_SETU_Element element; /** * Hash of the element. For set union: Will be used to derive the * different IBF keys for different salts. */ struct GNUNET_HashCode element_hash; /** * First generation that includes this element. */ unsigned int generation; /** * #GNUNET_YES if the element is a remote element, and does not belong * to the operation's set. */ int remote; }; /** * A listener is inhabited by a client, and waits for evaluation * requests from remote peers. */ struct Listener; /** * State we keep per client. */ struct ClientState { /** * Set, if associated with the client, otherwise NULL. */ struct Set *set; /** * Listener, if associated with the client, otherwise NULL. */ struct Listener *listener; /** * Client handle. */ struct GNUNET_SERVICE_Client *client; /** * Message queue. */ struct GNUNET_MQ_Handle *mq; }; /** * Operation context used to execute a set operation. */ struct Operation { /** * Kept in a DLL of the listener, if @e listener is non-NULL. */ struct Operation *next; /** * Kept in a DLL of the listener, if @e listener is non-NULL. */ struct Operation *prev; /** * Channel to the peer. */ struct GNUNET_CADET_Channel *channel; /** * Port this operation runs on. */ struct Listener *listener; /** * Message queue for the channel. */ struct GNUNET_MQ_Handle *mq; /** * Context message, may be NULL. */ struct GNUNET_MessageHeader *context_msg; /** * Set associated with the operation, NULL until the spec has been * associated with a set. */ struct Set *set; /** * Operation-specific operation state. Note that the exact * type depends on this being a union or intersection operation * (and thus on @e vt). */ struct OperationState *state; /** * The identity of the requesting peer. Needs to * be stored here as the op spec might not have been created yet. */ struct GNUNET_PeerIdentity peer; /** * Timeout task, if the incoming peer has not been accepted * after the timeout, it will be disconnected. */ struct GNUNET_SCHEDULER_Task *timeout_task; /** * Salt to use for the operation. */ uint32_t salt; /** * Remote peers element count */ uint32_t remote_element_count; /** * ID used to identify an operation between service and client */ uint32_t client_request_id; /** * Always use delta operation instead of sending full sets, * even it it's less efficient. */ int force_delta; /** * Always send full sets, even if delta operations would * be more efficient. */ int force_full; /** * #GNUNET_YES to fail operations where Byzantine faults * are suspected */ int byzantine; /** * Lower bound for the set size, used only when * byzantine mode is enabled. */ int byzantine_lower_bound; /** * Unique request id for the request from a remote peer, sent to the * client, which will accept or reject the request. Set to '0' iff * the request has not been suggested yet. */ uint32_t suggest_id; /** * Generation in which the operation handle * was created. */ unsigned int generation_created; }; /** * SetContent stores the actual set elements, which may be shared by * multiple generations derived from one set. */ struct SetContent { /** * Maps `struct GNUNET_HashCode *` to `struct ElementEntry *`. */ struct GNUNET_CONTAINER_MultiHashMap *elements; /** * Number of references to the content. */ unsigned int refcount; /** * FIXME: document! */ unsigned int latest_generation; /** * Number of concurrently active iterators. */ int iterator_count; }; struct GenerationRange { /** * First generation that is excluded. */ unsigned int start; /** * Generation after the last excluded generation. */ unsigned int end; }; /** * A set that supports a specific operation with other peers. */ struct Set { /** * Sets are held in a doubly linked list (in `sets_head` and `sets_tail`). */ struct Set *next; /** * Sets are held in a doubly linked list. */ struct Set *prev; /** * Client that owns the set. Only one client may own a set, * and there can only be one set per client. */ struct ClientState *cs; /** * Content, possibly shared by multiple sets, * and thus reference counted. */ struct SetContent *content; /** * Implementation-specific state. */ struct SetState *state; /** * Evaluate operations are held in a linked list. */ struct Operation *ops_head; /** * Evaluate operations are held in a linked list. */ struct Operation *ops_tail; /** * Current generation, that is, number of previously executed * operations and lazy copies on the underlying set content. */ unsigned int current_generation; }; extern struct GNUNET_STATISTICS_Handle *_GSS_statistics; /** * Destroy the given operation. Used for any operation where both * peers were known and that thus actually had a vt and channel. Must * not be used for operations where 'listener' is still set and we do * not know the other peer. * * Call the implementation-specific cancel function of the operation. * Disconnects from the remote peer. Does not disconnect the client, * as there may be multiple operations per set. * * @param op operation to destroy */ void _GSS_operation_destroy (struct Operation *op); /** * This function probably should not exist * and be replaced by inlining more specific * logic in the various places where it is called. */ void _GSS_operation_destroy2 (struct Operation *op); /** * Get the table with implementing functions for set union. * * @return the operation specific VTable */ const struct SetVT * _GSS_union_vt (void); /** * Is element @a ee part of the set used by @a op? * * @param ee element to test * @param op operation the defines the set and its generation * @return #GNUNET_YES if the element is in the set, #GNUNET_NO if not */ int _GSS_is_element_of_operation (struct ElementEntry *ee, struct Operation *op); #endif