GNUnet  0.11.x
Data Structures | Macros | Enumerations | Functions | Variables
gnunet-service-setu.c File Reference

set union operation More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_statistics_service.h"
#include "ibf.h"
#include "gnunet_protocols.h"
#include "gnunet_applications.h"
#include "gnunet_cadet_service.h"
#include "gnunet-service-setu_strata_estimator.h"
#include "gnunet-service-setu_protocol.h"
#include <gcrypt.h>
#include "gnunet_setu_service.h"
#include "setu.h"
Include dependency graph for gnunet-service-setu.c:

Go to the source code of this file.

Data Structures

struct  ElementEntry
 Information about an element element in the set. More...
 
struct  ClientState
 State we keep per client. More...
 
struct  Operation
 Operation context used to execute a set operation. More...
 
struct  SetContent
 SetContent stores the actual set elements, which may be shared by multiple generations derived from one set. More...
 
struct  Set
 A set that supports a specific operation with other peers. More...
 
struct  KeyEntry
 The key entry is used to associate an ibf key with an element. More...
 
struct  SendElementClosure
 Used as a closure for sending elements with a specific IBF key. More...
 
struct  Listener
 A listener is inhabited by a client, and waits for evaluation requests from remote peers. More...
 
struct  GetElementContext
 Context for op_get_element_iterator. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "setu", __VA_ARGS__)
 
#define INCOMING_CHANNEL_TIMEOUT   GNUNET_TIME_UNIT_MINUTES
 How long do we hold on to an incoming channel if there is no local listener before giving up? More...
 
#define SE_STRATA_COUNT   32
 Number of IBFs in a strata estimator. More...
 
#define SE_IBF_SIZE   80
 Size of the IBFs in the strata estimator. More...
 
#define SE_IBF_HASH_NUM   4
 The hash num parameter for the difference digests and strata estimators. More...
 
#define MAX_BUCKETS_PER_MESSAGE   ((1 << 15) / IBF_BUCKET_SIZE)
 Number of buckets that can be transmitted in one message. More...
 
#define MAX_IBF_ORDER   (20)
 The maximum size of an ibf we use is 2^(MAX_IBF_ORDER). More...
 
#define IBF_ALPHA   4
 Number of buckets used in the ibf per estimated difference. More...
 

Enumerations

enum  UnionOperationPhase {
  PHASE_EXPECT_SE, PHASE_EXPECT_IBF, PHASE_EXPECT_IBF_CONT, PHASE_INVENTORY_ACTIVE,
  PHASE_INVENTORY_PASSIVE, PHASE_FINISH_CLOSING, PHASE_FINISH_WAITING, PHASE_DONE,
  PHASE_FULL_SENDING, PHASE_EXPECT_SE, PHASE_EXPECT_IBF, PHASE_EXPECT_IBF_CONT,
  PHASE_INVENTORY_ACTIVE, PHASE_INVENTORY_PASSIVE, PHASE_FINISH_CLOSING, PHASE_FINISH_WAITING,
  PHASE_DONE, PHASE_FULL_SENDING
}
 Current phase we are in for a union operation. More...
 

Functions

static int destroy_key_to_element_iter (void *cls, uint32_t key, void *value)
 Iterator over hash map entries, called to destroy the linked list of colliding ibf key entries. More...
 
static void send_client_done (void *cls)
 Signal to the client that the operation has finished and destroy the operation. More...
 
static void _GSS_operation_destroy (struct Operation *op)
 Destroy the given operation. More...
 
static void _GSS_operation_destroy2 (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. More...
 
static void incoming_destroy (struct Operation *op)
 Destroy an incoming request from a remote peer. More...
 
static void fail_union_operation (struct Operation *op)
 Inform the client that the union operation has failed, and proceed to destroy the evaluate operation. More...
 
static struct IBF_Key get_ibf_key (const struct GNUNET_HashCode *src)
 Derive the IBF key from a hash code and a salt. More...
 
static int op_get_element_iterator (void *cls, uint32_t key, void *value)
 Iterator over the mapping from IBF keys to element entries. More...
 
static struct KeyEntryop_get_element (struct Operation *op, const struct GNUNET_HashCode *element_hash)
 Determine whether the given element is already in the operation's element set. More...
 
static void op_register_element (struct Operation *op, struct ElementEntry *ee, int received)
 Insert an element into the union operation's key-to-element mapping. More...
 
static void salt_key (const struct IBF_Key *k_in, uint32_t salt, struct IBF_Key *k_out)
 FIXME. More...
 
static void unsalt_key (const struct IBF_Key *k_in, uint32_t salt, struct IBF_Key *k_out)
 FIXME. More...
 
static int prepare_ibf_iterator (void *cls, uint32_t key, void *value)
 Insert a key into an ibf. More...
 
static int _GSS_is_element_of_operation (struct ElementEntry *ee, struct Operation *op)
 Is element ee part of the set used by op? More...
 
static int init_key_to_element_iterator (void *cls, const struct GNUNET_HashCode *key, void *value)
 Iterator for initializing the key-to-element mapping of a union operation. More...
 
static void initialize_key_to_element (struct Operation *op)
 Initialize the IBF key to element mapping local to this set operation. More...
 
static int prepare_ibf (struct Operation *op, uint32_t size)
 Create an ibf with the operation's elements of the specified size. More...
 
static int send_ibf (struct Operation *op, uint16_t ibf_order)
 Send an ibf of appropriate size. More...
 
static unsigned int get_order_from_difference (unsigned int diff)
 Compute the necessary order of an ibf from the size of the symmetric set difference. More...
 
static int send_full_element_iterator (void *cls, const struct GNUNET_HashCode *key, void *value)
 Send a set element. More...
 
static void send_full_set (struct Operation *op)
 Switch to full set transmission for op. More...
 
static int check_union_p2p_strata_estimator (void *cls, const struct StrataEstimatorMessage *msg)
 Handle a strata estimator from a remote peer. More...
 
static void handle_union_p2p_strata_estimator (void *cls, const struct StrataEstimatorMessage *msg)
 Handle a strata estimator from a remote peer. More...
 
static int send_offers_iterator (void *cls, uint32_t key, void *value)
 Iterator to send elements to a remote peer. More...
 
static void send_offers_for_key (struct Operation *op, struct IBF_Key ibf_key)
 Send offers (in the form of GNUNET_Hash-es) to the remote peer for the given IBF key. More...
 
static int decode_and_send (struct Operation *op)
 Decode which elements are missing on each side, and send the appropriate offers and inquiries. More...
 
static int check_union_p2p_ibf (void *cls, const struct IBFMessage *msg)
 Check an IBF message from a remote peer. More...
 
static void handle_union_p2p_ibf (void *cls, const struct IBFMessage *msg)
 Handle an IBF message from a remote peer. More...
 
static void send_client_element (struct Operation *op, const struct GNUNET_SETU_Element *element, enum GNUNET_SETU_Status status)
 Send a result message to the client indicating that there is a new element. More...
 
static void maybe_finish (struct Operation *op)
 Tests if the operation is finished, and if so notify. More...
 
static int check_union_p2p_elements (void *cls, const struct GNUNET_SETU_ElementMessage *emsg)
 Check an element message from a remote peer. More...
 
static void handle_union_p2p_elements (void *cls, const struct GNUNET_SETU_ElementMessage *emsg)
 Handle an element message from a remote peer. More...
 
static int check_union_p2p_full_element (void *cls, const struct GNUNET_SETU_ElementMessage *emsg)
 Check a full element message from a remote peer. More...
 
static void handle_union_p2p_full_element (void *cls, const struct GNUNET_SETU_ElementMessage *emsg)
 Handle an element message from a remote peer. More...
 
static int check_union_p2p_inquiry (void *cls, const struct InquiryMessage *msg)
 Send offers (for GNUNET_Hash-es) in response to inquiries (for IBF_Key-s). More...
 
static void handle_union_p2p_inquiry (void *cls, const struct InquiryMessage *msg)
 Send offers (for GNUNET_Hash-es) in response to inquiries (for IBF_Key-s). More...
 
static int send_missing_full_elements_iter (void *cls, uint32_t key, void *value)
 Iterator over hash map entries, called to destroy the linked list of colliding ibf key entries. More...
 
static void handle_union_p2p_request_full (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a request for full set transmission. More...
 
static void handle_union_p2p_full_done (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a "full done" message. More...
 
static int check_union_p2p_demand (void *cls, const struct GNUNET_MessageHeader *mh)
 Check a demand by the other peer for elements based on a list of struct GNUNET_HashCodes. More...
 
static void handle_union_p2p_demand (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a demand by the other peer for elements based on a list of struct GNUNET_HashCodes. More...
 
static int check_union_p2p_offer (void *cls, const struct GNUNET_MessageHeader *mh)
 Check offer (of struct GNUNET_HashCodes). More...
 
static void handle_union_p2p_offer (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle offers (of struct GNUNET_HashCodes) and respond with demands (of struct GNUNET_HashCodes). More...
 
static void handle_union_p2p_done (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a done message from a remote peer. More...
 
static void handle_union_p2p_over (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a over message from a remote peer. More...
 
static struct Operationget_incoming (uint32_t id)
 Get the incoming socket associated with the given id. More...
 
static void * client_connect_cb (void *cls, struct GNUNET_SERVICE_Client *c, struct GNUNET_MQ_Handle *mq)
 Callback called when a client connects to the service. More...
 
static int destroy_elements_iterator (void *cls, const struct GNUNET_HashCode *key, void *value)
 Iterator over hash map entries to free element entries. More...
 
static void client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client, void *internal_cls)
 Clean up after a client has disconnected. More...
 
static int check_incoming_msg (void *cls, const struct OperationRequestMessage *msg)
 Check a request for a set operation from another peer. More...
 
static void handle_incoming_msg (void *cls, const struct OperationRequestMessage *msg)
 Handle a request for a set operation from another peer. More...
 
static void handle_client_create_set (void *cls, const struct GNUNET_SETU_CreateMessage *msg)
 Called when a client wants to create a new set. More...
 
static void incoming_timeout_cb (void *cls)
 Timeout happens iff: More...
 
static void * channel_new_cb (void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *source)
 Method called whenever another peer has added us to a channel the other peer initiated. More...
 
static void channel_end_cb (void *channel_ctx, const struct GNUNET_CADET_Channel *channel)
 Function called whenever a channel is destroyed. More...
 
static void channel_window_cb (void *cls, const struct GNUNET_CADET_Channel *channel, int window_size)
 Function called whenever an MQ-channel's transmission window size changes. More...
 
static void handle_client_listen (void *cls, const struct GNUNET_SETU_ListenMessage *msg)
 Called when a client wants to create a new listener. More...
 
static void handle_client_reject (void *cls, const struct GNUNET_SETU_RejectMessage *msg)
 Called when the listening client rejects an operation request by another peer. More...
 
static int check_client_set_add (void *cls, const struct GNUNET_SETU_ElementMessage *msg)
 Called when a client wants to add or remove an element to a set it inhabits. More...
 
static void handle_client_set_add (void *cls, const struct GNUNET_SETU_ElementMessage *msg)
 Called when a client wants to add or remove an element to a set it inhabits. More...
 
static void advance_generation (struct Set *set)
 Advance the current generation of a set, adding exclusion ranges if necessary. More...
 
static int check_client_evaluate (void *cls, const struct GNUNET_SETU_EvaluateMessage *msg)
 Called when a client wants to initiate a set operation with another peer. More...
 
static void handle_client_evaluate (void *cls, const struct GNUNET_SETU_EvaluateMessage *msg)
 Called when a client wants to initiate a set operation with another peer. More...
 
static void handle_client_cancel (void *cls, const struct GNUNET_SETU_CancelMessage *msg)
 Handle a request from the client to cancel a running set operation. More...
 
static void handle_client_accept (void *cls, const struct GNUNET_SETU_AcceptMessage *msg)
 Handle a request from the client to accept a set operation that came from a remote peer. More...
 
static void shutdown_task (void *cls)
 Called to clean up, after a shutdown has been requested. More...
 
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
 Function called by the service's run method to run service-specific setup code. More...
 
 GNUNET_SERVICE_MAIN ("set", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_fixed_size(client_accept, GNUNET_MESSAGE_TYPE_SETU_ACCEPT, struct GNUNET_SETU_AcceptMessage, NULL), GNUNET_MQ_hd_var_size(client_set_add, GNUNET_MESSAGE_TYPE_SETU_ADD, struct GNUNET_SETU_ElementMessage, NULL), GNUNET_MQ_hd_fixed_size(client_create_set, GNUNET_MESSAGE_TYPE_SETU_CREATE, struct GNUNET_SETU_CreateMessage, NULL), GNUNET_MQ_hd_var_size(client_evaluate, GNUNET_MESSAGE_TYPE_SETU_EVALUATE, struct GNUNET_SETU_EvaluateMessage, NULL), GNUNET_MQ_hd_fixed_size(client_listen, GNUNET_MESSAGE_TYPE_SETU_LISTEN, struct GNUNET_SETU_ListenMessage, NULL), GNUNET_MQ_hd_fixed_size(client_reject, GNUNET_MESSAGE_TYPE_SETU_REJECT, struct GNUNET_SETU_RejectMessage, NULL), GNUNET_MQ_hd_fixed_size(client_cancel, GNUNET_MESSAGE_TYPE_SETU_CANCEL, struct GNUNET_SETU_CancelMessage, NULL), GNUNET_MQ_handler_end())
 Define "main" method using service macro. More...
 

Variables

static struct GNUNET_CADET_Handlecadet
 Handle to the cadet service, used to listen for and connect to remote peers. More...
 
static struct GNUNET_STATISTICS_Handle_GSS_statistics
 Statistics handle. More...
 
static struct Listenerlistener_head
 Listeners are held in a doubly linked list. More...
 
static struct Listenerlistener_tail
 Listeners are held in a doubly linked list. More...
 
static unsigned int num_clients
 Number of active clients. More...
 
static int in_shutdown
 Are we in shutdown? if GNUNET_YES and the number of clients drops to zero, disconnect from CADET. More...
 
static uint32_t suggest_id
 Counter for allocating unique IDs for clients, used to identify incoming operation requests from remote peers, that the client can choose to accept or refuse. More...
 

Detailed Description

set union operation

Author
Florian Dold
Christian Grothoff

Definition in file gnunet-service-setu.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "setu", __VA_ARGS__)

◆ INCOMING_CHANNEL_TIMEOUT

#define INCOMING_CHANNEL_TIMEOUT   GNUNET_TIME_UNIT_MINUTES

How long do we hold on to an incoming channel if there is no local listener before giving up?

Definition at line 46 of file gnunet-service-setu.c.

Referenced by channel_new_cb().

◆ SE_STRATA_COUNT

#define SE_STRATA_COUNT   32

Number of IBFs in a strata estimator.

Definition at line 51 of file gnunet-service-setu.c.

Referenced by check_union_p2p_strata_estimator(), handle_client_create_set(), and handle_union_p2p_strata_estimator().

◆ SE_IBF_SIZE

#define SE_IBF_SIZE   80

Size of the IBFs in the strata estimator.

Definition at line 56 of file gnunet-service-setu.c.

Referenced by check_union_p2p_strata_estimator(), handle_client_create_set(), and handle_union_p2p_strata_estimator().

◆ SE_IBF_HASH_NUM

#define SE_IBF_HASH_NUM   4

The hash num parameter for the difference digests and strata estimators.

Definition at line 61 of file gnunet-service-setu.c.

Referenced by get_order_from_difference(), handle_client_create_set(), handle_union_p2p_ibf(), handle_union_p2p_strata_estimator(), and prepare_ibf().

◆ MAX_BUCKETS_PER_MESSAGE

#define MAX_BUCKETS_PER_MESSAGE   ((1 << 15) / IBF_BUCKET_SIZE)

Number of buckets that can be transmitted in one message.

Definition at line 66 of file gnunet-service-setu.c.

Referenced by send_ibf().

◆ MAX_IBF_ORDER

#define MAX_IBF_ORDER   (20)

The maximum size of an ibf we use is 2^(MAX_IBF_ORDER).

Choose this value so that computing the IBF is still cheaper than transmitting all values.

Definition at line 73 of file gnunet-service-setu.c.

Referenced by decode_and_send(), and get_order_from_difference().

◆ IBF_ALPHA

#define IBF_ALPHA   4

Number of buckets used in the ibf per estimated difference.

Definition at line 79 of file gnunet-service-setu.c.

Referenced by get_order_from_difference().

Enumeration Type Documentation

◆ UnionOperationPhase

Current phase we are in for a union operation.

Enumerator
PHASE_EXPECT_SE 

We sent the request message, and expect a strata estimator.

PHASE_EXPECT_IBF 

We sent the strata estimator, and expect an IBF.

This phase is entered once upon initialization and later via #PHASE_EXPECT_ELEMENTS_AND_REQUESTS.

XXX: could use better wording. XXX: repurposed to also expect a "request full set" message, should be renamed

After receiving the complete IBF, we enter #PHASE_EXPECT_ELEMENTS

PHASE_EXPECT_IBF_CONT 

Continuation for multi part IBFs.

PHASE_INVENTORY_ACTIVE 

We are decoding an IBF.

PHASE_INVENTORY_PASSIVE 

The other peer is decoding the IBF we just sent.

PHASE_FINISH_CLOSING 

The protocol is almost finished, but we still have to flush our message queue and/or expect some elements.

PHASE_FINISH_WAITING 

In the penultimate phase, we wait until all our demands are satisfied.

Then we send a done message, and wait for another done message.

PHASE_DONE 

In the ultimate phase, we wait until our demands are satisfied and then quit (sending another DONE message).

PHASE_FULL_SENDING 

After sending the full set, wait for responses with the elements that the local peer is missing.

PHASE_EXPECT_SE 

We sent the request message, and expect a strata estimator.

PHASE_EXPECT_IBF 

We sent the strata estimator, and expect an IBF.

This phase is entered once upon initialization and later via #PHASE_EXPECT_ELEMENTS_AND_REQUESTS.

XXX: could use better wording. XXX: repurposed to also expect a "request full set" message, should be renamed

After receiving the complete IBF, we enter #PHASE_EXPECT_ELEMENTS

PHASE_EXPECT_IBF_CONT 

Continuation for multi part IBFs.

PHASE_INVENTORY_ACTIVE 

We are decoding an IBF.

PHASE_INVENTORY_PASSIVE 

The other peer is decoding the IBF we just sent.

PHASE_FINISH_CLOSING 

The protocol is almost finished, but we still have to flush our message queue and/or expect some elements.

PHASE_FINISH_WAITING 

In the penultimate phase, we wait until all our demands are satisfied.

Then we send a done message, and wait for another done message.

PHASE_DONE 

In the ultimate phase, we wait until our demands are satisfied and then quit (sending another DONE message).

PHASE_FULL_SENDING 

After sending the full set, wait for responses with the elements that the local peer is missing.

Definition at line 85 of file gnunet-service-setu.c.

86 {
91 
102 
107 
112 
117 
123 
129 
134  PHASE_DONE,
135 
141 };
After sending the full set, wait for responses with the elements that the local peer is missing...
The protocol is almost finished, but we still have to flush our message queue and/or expect some elem...
The other peer is decoding the IBF we just sent.
We are decoding an IBF.
We sent the strata estimator, and expect an IBF.
In the penultimate phase, we wait until all our demands are satisfied.
In the ultimate phase, we wait until our demands are satisfied and then quit (sending another DONE me...
Continuation for multi part IBFs.
We sent the request message, and expect a strata estimator.

Function Documentation

◆ destroy_key_to_element_iter()

static int destroy_key_to_element_iter ( void *  cls,
uint32_t  key,
void *  value 
)
static

Iterator over hash map entries, called to destroy the linked list of colliding ibf key entries.

Parameters
clsclosure
keycurrent key code
valuevalue in the hash map
Returns
GNUNET_YES if we should continue to iterate, GNUNET_NO if not.

Definition at line 628 of file gnunet-service-setu.c.

References KeyEntry::element, GNUNET_assert, GNUNET_free, GNUNET_YES, ElementEntry::remote, and value.

Referenced by _GSS_operation_destroy().

631 {
632  struct KeyEntry *k = value;
633 
634  GNUNET_assert (NULL != k);
635  if (GNUNET_YES == k->element->remote)
636  {
637  GNUNET_free (k->element);
638  k->element = NULL;
639  }
640  GNUNET_free (k);
641  return GNUNET_YES;
642 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
The key entry is used to associate an ibf key with an element.
static char * value
Value of the record to add/remove.
int remote
GNUNET_YES if the element is a remote element, and does not belong to the operation&#39;s set...
struct ElementEntry * element
The actual element associated with the key.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function:

◆ send_client_done()

static void send_client_done ( void *  cls)
static

Signal to the client that the operation has finished and destroy the operation.

Parameters
clsoperation to destroy

Definition at line 652 of file gnunet-service-setu.c.

References Operation::client_done_sent, Operation::client_request_id, Set::cs, GNUNET_SETU_ResultMessage::current_size, GNUNET_SETU_ResultMessage::element_type, GNUNET_CONTAINER_multihashmap32_size(), GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_htonll(), GNUNET_MESSAGE_TYPE_SETU_RESULT, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_NO, GNUNET_SETU_STATUS_DONE, GNUNET_SETU_STATUS_FAILURE, GNUNET_STATISTICS_update(), GNUNET_YES, Operation::key_to_element, LOG, ClientState::mq, op, Operation::phase, PHASE_DONE, GNUNET_SETU_ResultMessage::request_id, GNUNET_SETU_ResultMessage::result_status, and Operation::set.

Referenced by _GSS_operation_destroy2(), handle_union_p2p_full_done(), handle_union_p2p_over(), and maybe_finish().

653 {
654  struct Operation *op = cls;
655  struct GNUNET_MQ_Envelope *ev;
656  struct GNUNET_SETU_ResultMessage *rm;
657 
658  if (GNUNET_YES == op->client_done_sent)
659  return;
660  if (PHASE_DONE != op->phase)
661  {
663  "Union operation failed\n");
665  "# Union operations failed",
666  1,
667  GNUNET_NO);
670  rm->request_id = htonl (op->client_request_id);
671  rm->element_type = htons (0);
672  GNUNET_MQ_send (op->set->cs->mq,
673  ev);
674  return;
675  }
676 
678 
680  "# Union operations succeeded",
681  1,
682  GNUNET_NO);
684  "Signalling client that union operation is done\n");
685  ev = GNUNET_MQ_msg (rm,
687  rm->request_id = htonl (op->client_request_id);
689  rm->element_type = htons (0);
691  op->key_to_element));
692  GNUNET_MQ_send (op->set->cs->mq,
693  ev);
694 }
enum IntersectionOperationPhase phase
Current state of the operation.
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
uint32_t request_id
id the result belongs to
Definition: setu.h:254
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: setu.h:265
The other peer refused to do the operation with us, or something went wrong.
#define GNUNET_MESSAGE_TYPE_SETU_RESULT
Handle result message from operation.
Success, all elements have been sent (and received).
unsigned int GNUNET_CONTAINER_multihashmap32_size(const struct GNUNET_CONTAINER_MultiHashMap32 *map)
Get the number of key-value pairs in the map.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SETU_Status in NBO.
Definition: setu.h:260
#define LOG(kind,...)
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:36
uint64_t current_size
Current set size.
Definition: setu.h:249
struct ClientState * cs
Client that owns the set.
int client_done_sent
Did we send the client that we are done?
Operation context used to execute a set operation.
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: setu.h:239
uint32_t client_request_id
ID used to identify an operation between service and client.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
In the ultimate phase, we wait until our demands are satisfied and then quit (sending another DONE me...
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _GSS_operation_destroy()

static void _GSS_operation_destroy ( struct Operation op)
static

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.

Parameters
opoperation to destroy

Definition at line 712 of file gnunet-service-setu.c.

References _GSS_operation_destroy2(), Operation::channel, Operation::context_msg, Operation::demanded_hashes, destroy_key_to_element_iter(), GNUNET_assert, GNUNET_CADET_channel_destroy(), GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multihashmap32_destroy(), GNUNET_CONTAINER_multihashmap32_iterate(), GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, ibf_destroy(), Operation::key_to_element, Operation::listener, Operation::local_ibf, op, Operation::remote_ibf, Operation::se, Operation::set, and strata_estimator_destroy().

Referenced by _GSS_operation_destroy2(), client_disconnect_cb(), fail_union_operation(), and handle_client_cancel().

713 {
714  struct Set *set = op->set;
715  struct GNUNET_CADET_Channel *channel;
716 
718  "Destroying union operation %p\n",
719  op);
720  GNUNET_assert (NULL == op->listener);
721  /* check if the op was canceled twice */
722  if (NULL != op->remote_ibf)
723  {
724  ibf_destroy (op->remote_ibf);
725  op->remote_ibf = NULL;
726  }
727  if (NULL != op->demanded_hashes)
728  {
730  op->demanded_hashes = NULL;
731  }
732  if (NULL != op->local_ibf)
733  {
734  ibf_destroy (op->local_ibf);
735  op->local_ibf = NULL;
736  }
737  if (NULL != op->se)
738  {
740  op->se = NULL;
741  }
742  if (NULL != op->key_to_element)
743  {
746  NULL);
748  op->key_to_element = NULL;
749  }
750  if (NULL != set)
751  {
752  GNUNET_CONTAINER_DLL_remove (set->ops_head,
753  set->ops_tail,
754  op);
755  op->set = NULL;
756  }
757  if (NULL != op->context_msg)
758  {
759  GNUNET_free (op->context_msg);
760  op->context_msg = NULL;
761  }
762  if (NULL != (channel = op->channel))
763  {
764  /* This will free op; called conditionally as this helper function
765  is also called from within the channel disconnect handler. */
766  op->channel = NULL;
768  }
769  /* We rely on the channel end handler to free 'op'. When 'op->channel' was NULL,
770  * there was a channel end handler that will free 'op' on the call stack. */
771 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct StrataEstimator * se
Copy of the set&#39;s strata estimator at the time of creation of this operation.
struct GNUNET_MessageHeader * context_msg
Context message, may be NULL.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
struct InvertibleBloomFilter * remote_ibf
The IBF we currently receive.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Opaque handle to a channel.
Definition: cadet.h:116
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
void strata_estimator_destroy(struct StrataEstimator *se)
Destroy a strata estimator, free all of its resources.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
A set that supports a specific operation with other peers.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
static int destroy_key_to_element_iter(void *cls, uint32_t key, void *value)
Iterator over hash map entries, called to destroy the linked list of colliding ibf key entries...
void GNUNET_CONTAINER_multihashmap32_destroy(struct GNUNET_CONTAINER_MultiHashMap32 *map)
Destroy a 32-bit key hash map.
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
void ibf_destroy(struct InvertibleBloomFilter *ibf)
Destroy all resources associated with the invertible bloom filter.
Definition: ibf.c:403
struct GNUNET_CADET_Channel * channel
Channel to the peer.
struct InvertibleBloomFilter * local_ibf
The IBF with the local set&#39;s element.
#define GNUNET_log(kind,...)
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:837
struct Listener * listener
Port this operation runs on.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _GSS_operation_destroy2()

static void _GSS_operation_destroy2 ( struct Operation op)
static

This function probably should not exist and be replaced by inlining more specific logic in the various places where it is called.

Definition at line 818 of file gnunet-service-setu.c.

References _GSS_operation_destroy(), Operation::channel, GNUNET_CADET_channel_destroy(), GNUNET_free, incoming_destroy(), Operation::listener, send_client_done(), and Operation::set.

Referenced by _GSS_operation_destroy(), channel_end_cb(), handle_client_reject(), handle_union_p2p_full_done(), incoming_destroy(), and maybe_finish().

819 {
820  struct GNUNET_CADET_Channel *channel;
821 
822  if (NULL != (channel = op->channel))
823  {
824  /* This will free op; called conditionally as this helper function
825  is also called from within the channel disconnect handler. */
826  op->channel = NULL;
828  }
829  if (NULL != op->listener)
830  {
831  incoming_destroy (op);
832  return;
833  }
834  if (NULL != op->set)
835  send_client_done (op);
837  GNUNET_free (op);
838 }
Opaque handle to a channel.
Definition: cadet.h:116
static void _GSS_operation_destroy(struct Operation *op)
Destroy the given operation.
static void send_client_done(void *cls)
Signal to the client that the operation has finished and destroy the operation.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
static void incoming_destroy(struct Operation *op)
Destroy an incoming request from a remote peer.
struct GNUNET_CADET_Channel * channel
Channel to the peer.
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:837
struct Listener * listener
Port this operation runs on.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ incoming_destroy()

static void incoming_destroy ( struct Operation op)
static

Destroy an incoming request from a remote peer.

Parameters
opremote request to destroy

Definition at line 789 of file gnunet-service-setu.c.

References _GSS_operation_destroy2(), GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_SCHEDULER_cancel(), Operation::listener, Listener::op_head, Listener::op_tail, and Operation::timeout_task.

Referenced by _GSS_operation_destroy2(), client_disconnect_cb(), and incoming_timeout_cb().

790 {
791  struct Listener *listener;
792 
794  "Destroying incoming operation %p\n",
795  op);
796  if (NULL != (listener = op->listener))
797  {
799  listener->op_tail,
800  op);
801  op->listener = NULL;
802  }
803  if (NULL != op->timeout_task)
804  {
806  op->timeout_task = NULL;
807  }
809 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct Operation * op_head
Head of DLL of operations this listener is responsible for.
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
static void _GSS_operation_destroy2(struct Operation *op)
This function probably should not exist and be replaced by inlining more specific logic in the variou...
struct GNUNET_SCHEDULER_Task * timeout_task
Timeout task, if the incoming peer has not been accepted after the timeout, it will be disconnected...
#define GNUNET_log(kind,...)
struct Operation * op_tail
Tail of DLL of operations this listener is responsible for.
struct Listener * listener
Port this operation runs on.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fail_union_operation()

static void fail_union_operation ( struct Operation op)
static

Inform the client that the union operation has failed, and proceed to destroy the evaluate operation.

Parameters
opthe union operation to fail

Definition at line 848 of file gnunet-service-setu.c.

References _GSS_operation_destroy(), Operation::client_request_id, Set::cs, GNUNET_SETU_ResultMessage::element_type, GNUNET_ERROR_TYPE_WARNING, GNUNET_MESSAGE_TYPE_SETU_RESULT, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_SETU_STATUS_FAILURE, LOG, ClientState::mq, msg, GNUNET_SETU_ResultMessage::request_id, GNUNET_SETU_ResultMessage::result_status, and Operation::set.

Referenced by decode_and_send(), handle_union_p2p_demand(), handle_union_p2p_done(), handle_union_p2p_elements(), handle_union_p2p_full_done(), handle_union_p2p_full_element(), handle_union_p2p_ibf(), handle_union_p2p_request_full(), and handle_union_p2p_strata_estimator().

849 {
850  struct GNUNET_MQ_Envelope *ev;
852 
854  "union operation failed\n");
857  msg->request_id = htonl (op->client_request_id);
858  msg->element_type = htons (0);
859  GNUNET_MQ_send (op->set->cs->mq,
860  ev);
862 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
uint32_t request_id
id the result belongs to
Definition: setu.h:254
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: setu.h:265
static void _GSS_operation_destroy(struct Operation *op)
Destroy the given operation.
The other peer refused to do the operation with us, or something went wrong.
#define GNUNET_MESSAGE_TYPE_SETU_RESULT
Handle result message from operation.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SETU_Status in NBO.
Definition: setu.h:260
#define LOG(kind,...)
struct ClientState * cs
Client that owns the set.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: setu.h:239
uint32_t client_request_id
ID used to identify an operation between service and client.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_ibf_key()

static struct IBF_Key get_ibf_key ( const struct GNUNET_HashCode src)
static

Derive the IBF key from a hash code and a salt.

Parameters
srcthe hash code
Returns
the derived IBF key

Definition at line 873 of file gnunet-service-setu.c.

References GNUNET_assert, GNUNET_CRYPTO_kdf(), GNUNET_OK, key, and salt.

Referenced by handle_client_set_add(), op_get_element(), and op_register_element().

874 {
875  struct IBF_Key key;
876  uint16_t salt = 0;
877 
879  GNUNET_CRYPTO_kdf (&key, sizeof(key),
880  src, sizeof *src,
881  &salt, sizeof(salt),
882  NULL, 0));
883  return key;
884 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calcualations.
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:45
int GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_kdf.c:90
Here is the call graph for this function:
Here is the caller graph for this function:

◆ op_get_element_iterator()

static int op_get_element_iterator ( void *  cls,
uint32_t  key,
void *  value 
)
static

Iterator over the mapping from IBF keys to element entries.

Checks if we have an element with a given GNUNET_HashCode.

Parameters
clsclosure
keycurrent key code
valuevalue in the hash map
Returns
GNUNET_YES if we should search further, GNUNET_NO if we've found the element.

Definition at line 915 of file gnunet-service-setu.c.

References ctx, KeyEntry::element, ElementEntry::element_hash, GNUNET_assert, GNUNET_CRYPTO_hash_cmp(), GNUNET_NO, GNUNET_YES, GetElementContext::hash, GetElementContext::k, and value.

Referenced by op_get_element().

918 {
919  struct GetElementContext *ctx = cls;
920  struct KeyEntry *k = value;
921 
922  GNUNET_assert (NULL != k);
924  &ctx->hash))
925  {
926  ctx->k = k;
927  return GNUNET_NO;
928  }
929  return GNUNET_YES;
930 }
Context for op_get_element_iterator.
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct KeyEntry * k
FIXME.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
The key entry is used to associate an ibf key with an element.
static char * value
Value of the record to add/remove.
struct ElementEntry * element
The actual element associated with the key.
int GNUNET_CRYPTO_hash_cmp(const struct GNUNET_HashCode *h1, const struct GNUNET_HashCode *h2)
Compare function for HashCodes, producing a total ordering of all hashcodes.
Definition: crypto_hash.c:311
struct GNUNET_HashCode hash
FIXME.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ op_get_element()

static struct KeyEntry* op_get_element ( struct Operation op,
const struct GNUNET_HashCode element_hash 
)
static

Determine whether the given element is already in the operation's element set.

Parameters
opoperation that should be tested for 'element_hash'
element_hashhash of the element to look for
Returns
GNUNET_YES if the element has been found, GNUNET_NO otherwise

Definition at line 942 of file gnunet-service-setu.c.

References ElementEntry::element_hash, get_ibf_key(), GNUNET_assert, GNUNET_CONTAINER_multihashmap32_get_multiple(), GNUNET_SYSERR, GetElementContext::hash, GetElementContext::k, Operation::key_to_element, IBF_Key::key_val, op_get_element_iterator(), and ret.

Referenced by handle_union_p2p_elements(), and handle_union_p2p_full_element().

944 {
945  int ret;
946  struct IBF_Key ibf_key;
947  struct GetElementContext ctx = { { { 0 } }, 0 };
948 
949  ctx.hash = *element_hash;
950 
951  ibf_key = get_ibf_key (element_hash);
953  (uint32_t) ibf_key.key_val,
955  &ctx);
956 
957  /* was the iteration aborted because we found the element? */
958  if (GNUNET_SYSERR == ret)
959  {
960  GNUNET_assert (NULL != ctx.k);
961  return ctx.k;
962  }
963  return NULL;
964 }
Context for op_get_element_iterator.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
struct KeyEntry * k
FIXME.
int GNUNET_CONTAINER_multihashmap32_get_multiple(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
static struct IBF_Key get_ibf_key(const struct GNUNET_HashCode *src)
Derive the IBF key from a hash code and a salt.
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
static int op_get_element_iterator(void *cls, uint32_t key, void *value)
Iterator over the mapping from IBF keys to element entries.
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:45
struct GNUNET_HashCode hash
FIXME.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ op_register_element()

static void op_register_element ( struct Operation op,
struct ElementEntry ee,
int  received 
)
static

Insert an element into the union operation's key-to-element mapping.

Takes ownership of 'ee'. Note that this does not insert the element in the set, only in the operation's key-element mapping. This is done to speed up re-tried operations, if some elements were transmitted, and then the IBF fails to decode.

XXX: clarify ownership, doesn't sound right.

Parameters
opthe union operation
eethe element entry received was this element received from the remote peer?

Definition at line 982 of file gnunet-service-setu.c.

References KeyEntry::element, ElementEntry::element_hash, get_ibf_key(), GNUNET_assert, GNUNET_CONTAINER_multihashmap32_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_new, GNUNET_OK, KeyEntry::ibf_key, Operation::key_to_element, IBF_Key::key_val, and KeyEntry::received.

Referenced by handle_union_p2p_elements(), handle_union_p2p_full_element(), and init_key_to_element_iterator().

985 {
986  struct IBF_Key ibf_key;
987  struct KeyEntry *k;
988 
990  k = GNUNET_new (struct KeyEntry);
991  k->element = ee;
992  k->ibf_key = ibf_key;
993  k->received = received;
996  (uint32_t) ibf_key.key_val,
997  k,
999 }
int received
Did we receive this element? Even if element->is_foreign is false, we might have received the element...
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
uint64_t key_val
Definition: ibf.h:47
int GNUNET_CONTAINER_multihashmap32_put(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
The key entry is used to associate an ibf key with an element.
static struct IBF_Key get_ibf_key(const struct GNUNET_HashCode *src)
Derive the IBF key from a hash code and a salt.
struct IBF_Key ibf_key
IBF key for the entry, derived from the current salt.
struct ElementEntry * element
The actual element associated with the key.
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
Allow multiple values with the same key.
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:45
Here is the call graph for this function:
Here is the caller graph for this function:

◆ salt_key()

static void salt_key ( const struct IBF_Key k_in,
uint32_t  salt,
struct IBF_Key k_out 
)
static

FIXME.

Definition at line 1006 of file gnunet-service-setu.c.

References IBF_Key::key_val.

Referenced by prepare_ibf_iterator().

1009 {
1010  int s = salt % 64;
1011  uint64_t x = k_in->key_val;
1012 
1013  /* rotate ibf key */
1014  x = (x >> s) | (x << (64 - s));
1015  k_out->key_val = x;
1016 }
uint64_t key_val
Definition: ibf.h:47
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calcualations.
Here is the caller graph for this function:

◆ unsalt_key()

static void unsalt_key ( const struct IBF_Key k_in,
uint32_t  salt,
struct IBF_Key k_out 
)
static

FIXME.

Definition at line 1023 of file gnunet-service-setu.c.

References IBF_Key::key_val.

Referenced by decode_and_send(), and handle_union_p2p_inquiry().

1026 {
1027  int s = salt % 64;
1028  uint64_t x = k_in->key_val;
1029 
1030  x = (x << s) | (x >> (64 - s));
1031  k_out->key_val = x;
1032 }
uint64_t key_val
Definition: ibf.h:47
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calcualations.
Here is the caller graph for this function:

◆ prepare_ibf_iterator()

static int prepare_ibf_iterator ( void *  cls,
uint32_t  key,
void *  value 
)
static

Insert a key into an ibf.

Parameters
clsthe ibf
keyunused
valuethe key entry to get the key from

Definition at line 1043 of file gnunet-service-setu.c.

References KeyEntry::element, ElementEntry::element_hash, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_YES, ibf_insert(), KeyEntry::ibf_key, IBF_Key::key_val, LOG, salt_key(), and value.

Referenced by prepare_ibf().

1046 {
1047  struct Operation *op = cls;
1048  struct KeyEntry *ke = value;
1049  struct IBF_Key salted_key;
1050 
1052  "[OP %x] inserting %lx (hash %s) into ibf\n",
1053  (void *) op,
1054  (unsigned long) ke->ibf_key.key_val,
1055  GNUNET_h2s (&ke->element->element_hash));
1056  salt_key (&ke->ibf_key,
1057  op->salt_send,
1058  &salted_key);
1059  ibf_insert (op->local_ibf, salted_key);
1060  return GNUNET_YES;
1061 }
struct GNUNET_HashCode element_hash
Hash of the element.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint64_t key_val
Definition: ibf.h:47
The key entry is used to associate an ibf key with an element.
static char * value
Value of the record to add/remove.
struct IBF_Key ibf_key
IBF key for the entry, derived from the current salt.
struct ElementEntry * element
The actual element associated with the key.
static void salt_key(const struct IBF_Key *k_in, uint32_t salt, struct IBF_Key *k_out)
FIXME.
#define LOG(kind,...)
Operation context used to execute a set operation.
void ibf_insert(struct InvertibleBloomFilter *ibf, struct IBF_Key key)
Insert a key into an IBF.
Definition: ibf.c:167
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:45
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _GSS_is_element_of_operation()

static int _GSS_is_element_of_operation ( struct ElementEntry ee,
struct Operation op 
)
static

Is element ee part of the set used by op?

Parameters
eeelement to test
opoperation the defines the set and its generation
Returns
GNUNET_YES if the element is in the set, GNUNET_NO if not

Definition at line 1072 of file gnunet-service-setu.c.

References ElementEntry::generation, and Operation::generation_created.

Referenced by handle_union_p2p_demand(), handle_union_p2p_offer(), and init_key_to_element_iterator().

1074 {
1075  return ee->generation >= op->generation_created;
1076 }
unsigned int generation_created
Generation in which the operation handle was created.
unsigned int generation
First generation that includes this element.
Here is the caller graph for this function:

◆ init_key_to_element_iterator()

static int init_key_to_element_iterator ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Iterator for initializing the key-to-element mapping of a union operation.

Parameters
clsthe union operation struct Operation *
keyunused
valuethe struct ElementEntry * to insert into the key-to-element mapping
Returns
GNUNET_YES (to continue iterating)

Definition at line 1090 of file gnunet-service-setu.c.

References _GSS_is_element_of_operation(), GNUNET_assert, GNUNET_NO, GNUNET_YES, op_register_element(), ElementEntry::remote, and value.

Referenced by initialize_key_to_element().

1093 {
1094  struct Operation *op = cls;
1095  struct ElementEntry *ee = value;
1096 
1097  /* make sure that the element belongs to the set at the time
1098  * of creating the operation */
1099  if (GNUNET_NO ==
1101  op))
1102  return GNUNET_YES;
1103  GNUNET_assert (GNUNET_NO == ee->remote);
1104  op_register_element (op,
1105  ee,
1106  GNUNET_NO);
1107  return GNUNET_YES;
1108 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static char * value
Value of the record to add/remove.
Information about an element element in the set.
int remote
GNUNET_YES if the element is a remote element, and does not belong to the operation&#39;s set...
Operation context used to execute a set operation.
static void op_register_element(struct Operation *op, struct ElementEntry *ee, int received)
Insert an element into the union operation&#39;s key-to-element mapping.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static int _GSS_is_element_of_operation(struct ElementEntry *ee, struct Operation *op)
Is element ee part of the set used by op?
Here is the call graph for this function:
Here is the caller graph for this function:

◆ initialize_key_to_element()

static void initialize_key_to_element ( struct Operation op)
static

Initialize the IBF key to element mapping local to this set operation.

Parameters
opthe set union operation

Definition at line 1117 of file gnunet-service-setu.c.

References Set::content, SetContent::elements, GNUNET_assert, GNUNET_CONTAINER_multihashmap32_create(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CONTAINER_multihashmap_size(), init_key_to_element_iterator(), Operation::key_to_element, len, and Operation::set.

Referenced by handle_client_accept(), and handle_client_evaluate().

1118 {
1119  unsigned int len;
1120 
1121  GNUNET_assert (NULL == op->key_to_element);
1126  op);
1127 }
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int init_key_to_element_iterator(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator for initializing the key-to-element mapping of a union operation.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
struct GNUNET_CONTAINER_MultiHashMap32 * GNUNET_CONTAINER_multihashmap32_create(unsigned int len)
Create a 32-bit key multi hash map.
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ prepare_ibf()

static int prepare_ibf ( struct Operation op,
uint32_t  size 
)
static

Create an ibf with the operation's elements of the specified size.

Parameters
opthe union operation
sizesize of the ibf to create
Returns
GNUNET_OK on success, GNUNET_SYSERR on failure

Definition at line 1139 of file gnunet-service-setu.c.

References GNUNET_assert, GNUNET_CONTAINER_multihashmap32_iterate(), GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_OK, GNUNET_SYSERR, ibf_create(), ibf_destroy(), Operation::key_to_element, Operation::local_ibf, prepare_ibf_iterator(), and SE_IBF_HASH_NUM.

Referenced by decode_and_send(), and send_ibf().

1141 {
1142  GNUNET_assert (NULL != op->key_to_element);
1143 
1144  if (NULL != op->local_ibf)
1145  ibf_destroy (op->local_ibf);
1147  if (NULL == op->local_ibf)
1148  {
1150  "Failed to allocate local IBF\n");
1151  return GNUNET_SYSERR;
1152  }
1155  op);
1156  return GNUNET_OK;
1157 }
static int prepare_ibf_iterator(void *cls, uint32_t key, void *value)
Insert a key into an ibf.
#define SE_IBF_HASH_NUM
The hash num parameter for the difference digests and strata estimators.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
static unsigned int size
Size of the "table".
Definition: peer.c:67
void ibf_destroy(struct InvertibleBloomFilter *ibf)
Destroy all resources associated with the invertible bloom filter.
Definition: ibf.c:403
struct InvertibleBloomFilter * ibf_create(uint32_t size, uint8_t hash_num)
Create an invertible bloom filter.
Definition: ibf.c:79
struct InvertibleBloomFilter * local_ibf
The IBF with the local set&#39;s element.
#define GNUNET_log(kind,...)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_ibf()

static int send_ibf ( struct Operation op,
uint16_t  ibf_order 
)
static

Send an ibf of appropriate size.

Fragments the IBF into multiple messages if necessary.

Parameters
opthe union operation
ibf_orderorder of the ibf to send, size=2^order
Returns
GNUNET_OK on success, GNUNET_SYSERR on failure

Definition at line 1170 of file gnunet-service-setu.c.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_SETU_P2P_IBF, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_SYSERR, IBF_BUCKET_SIZE, ibf_write_slice(), Operation::local_ibf, LOG, MAX_BUCKETS_PER_MESSAGE, Operation::mq, msg, name, IBFMessage::offset, IBFMessage::order, Operation::phase, PHASE_INVENTORY_PASSIVE, prepare_ibf(), IBFMessage::reserved1, IBFMessage::reserved2, IBFMessage::salt, and Operation::salt_send.

Referenced by decode_and_send(), and handle_union_p2p_strata_estimator().

1172 {
1173  unsigned int buckets_sent = 0;
1174  struct InvertibleBloomFilter *ibf;
1175 
1176  if (GNUNET_OK !=
1177  prepare_ibf (op, 1 << ibf_order))
1178  {
1179  /* allocation failed */
1180  return GNUNET_SYSERR;
1181  }
1182 
1184  "sending ibf of size %u\n",
1185  1 << ibf_order);
1186 
1187  {
1188  char name[64] = { 0 };
1189  snprintf (name, sizeof(name), "# sent IBF (order %u)", ibf_order);
1191  }
1192 
1193  ibf = op->local_ibf;
1194 
1195  while (buckets_sent < (1 << ibf_order))
1196  {
1197  unsigned int buckets_in_message;
1198  struct GNUNET_MQ_Envelope *ev;
1199  struct IBFMessage *msg;
1200 
1201  buckets_in_message = (1 << ibf_order) - buckets_sent;
1202  /* limit to maximum */
1203  if (buckets_in_message > MAX_BUCKETS_PER_MESSAGE)
1204  buckets_in_message = MAX_BUCKETS_PER_MESSAGE;
1205 
1206  ev = GNUNET_MQ_msg_extra (msg,
1207  buckets_in_message * IBF_BUCKET_SIZE,
1209  msg->reserved1 = 0;
1210  msg->reserved2 = 0;
1211  msg->order = ibf_order;
1212  msg->offset = htonl (buckets_sent);
1213  msg->salt = htonl (op->salt_send);
1214  ibf_write_slice (ibf, buckets_sent,
1215  buckets_in_message, &msg[1]);
1216  buckets_sent += buckets_in_message;
1218  "ibf chunk size %u, %u/%u sent\n",
1219  buckets_in_message,
1220  buckets_sent,
1221  1 << ibf_order);
1222  GNUNET_MQ_send (op->mq, ev);
1223  }
1224 
1225  /* The other peer must decode the IBF, so
1226  * we're passive. */
1228  return GNUNET_OK;
1229 }
uint32_t offset
Offset of the strata in the rest of the message.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
enum IntersectionOperationPhase phase
Current state of the operation.
uint8_t reserved1
Padding, must be 0.
Message containing buckets of an invertible bloom filter.
Invertible bloom filter (IBF).
Definition: ibf.h:82
void ibf_write_slice(const struct InvertibleBloomFilter *ibf, uint32_t start, uint32_t count, void *buf)
Write buckets from an ibf to a buffer.
Definition: ibf.c:290
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
The other peer is decoding the IBF we just sent.
#define MAX_BUCKETS_PER_MESSAGE
Number of buckets that can be transmitted in one message.
uint8_t order
Order of the whole ibf, where num_buckets = 2^order.
#define IBF_BUCKET_SIZE
Size of one ibf bucket in bytes.
Definition: ibf.h:72
#define LOG(kind,...)
uint16_t reserved2
Padding, must be 0.
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
uint32_t salt
Salt used when hashing elements for this IBF.
const char * name
struct InvertibleBloomFilter * local_ibf
The IBF with the local set&#39;s element.
#define GNUNET_MESSAGE_TYPE_SETU_P2P_IBF
Invertible bloom filter.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
static int prepare_ibf(struct Operation *op, uint32_t size)
Create an ibf with the operation&#39;s elements of the specified size.
uint32_t salt_send
Salt that we&#39;re using for sending IBFs.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_order_from_difference()

static unsigned int get_order_from_difference ( unsigned int  diff)
static

Compute the necessary order of an ibf from the size of the symmetric set difference.

Parameters
diffthe difference
Returns
the required size of the ibf

Definition at line 1240 of file gnunet-service-setu.c.

References IBF_ALPHA, MAX_IBF_ORDER, and SE_IBF_HASH_NUM.

Referenced by handle_union_p2p_strata_estimator().

1241 {
1242  unsigned int ibf_order;
1243 
1244  ibf_order = 2;
1245  while (((1 << ibf_order) < (IBF_ALPHA * diff) ||
1246  ((1 << ibf_order) < SE_IBF_HASH_NUM)) &&
1247  (ibf_order < MAX_IBF_ORDER))
1248  ibf_order++;
1249  // add one for correction
1250  return ibf_order + 1;
1251 }
#define SE_IBF_HASH_NUM
The hash num parameter for the difference digests and strata estimators.
#define IBF_ALPHA
Number of buckets used in the ibf per estimated difference.
#define MAX_IBF_ORDER
The maximum size of an ibf we use is 2^(MAX_IBF_ORDER).
Here is the caller graph for this function:

◆ send_full_element_iterator()

static int send_full_element_iterator ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Send a set element.

Parameters
clsthe union operation struct Operation *
keyunused
valuethe struct ElementEntry * to insert into the key-to-element mapping
Returns
GNUNET_YES (to continue iterating)

Definition at line 1264 of file gnunet-service-setu.c.

References GNUNET_SETU_Element::data, el, ElementEntry::element, GNUNET_SETU_Element::element_type, GNUNET_SETU_ElementMessage::element_type, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_YES, LOG, Operation::mq, GNUNET_SETU_Element::size, and value.

Referenced by send_full_set().

1267 {
1268  struct Operation *op = cls;
1269  struct GNUNET_SETU_ElementMessage *emsg;
1270  struct ElementEntry *ee = value;
1271  struct GNUNET_SETU_Element *el = &ee->element;
1272  struct GNUNET_MQ_Envelope *ev;
1273 
1275  "Sending element %s\n",
1276  GNUNET_h2s (key));
1277  ev = GNUNET_MQ_msg_extra (emsg,
1278  el->size,
1280  emsg->element_type = htons (el->element_type);
1281  GNUNET_memcpy (&emsg[1],
1282  el->data,
1283  el->size);
1284  GNUNET_MQ_send (op->mq,
1285  ev);
1286  return GNUNET_YES;
1287 }
const void * data
Actual data of the element.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint16_t element_type
Type of the element to add or remove.
Definition: setu.h:285
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
static char * value
Value of the record to add/remove.
Information about an element element in the set.
uint16_t element_type
Application-specific element type.
#define LOG(kind,...)
#define GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT
Send a set element, not as response to a demand but because we&#39;re sending the full set...
Message sent by client to the service to add an element to the set.
Definition: setu.h:275
Operation context used to execute a set operation.
struct GNUNET_SET_Element element
The actual element.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static struct GNUNET_IDENTITY_EgoLookup * el
EgoLookup.
Definition: gnunet-abd.c:51
uint16_t size
Number of bytes in the buffer pointed to by data.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
Element stored in a set.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_full_set()

static void send_full_set ( struct Operation op)
static

Switch to full set transmission for op.

Parameters
opoperation to switch to full set transmission.

Definition at line 1296 of file gnunet-service-setu.c.

References Set::content, SetContent::elements, GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE, GNUNET_MQ_msg_header, GNUNET_MQ_send(), LOG, Operation::mq, Operation::phase, PHASE_FULL_SENDING, send_full_element_iterator(), and Operation::set.

Referenced by handle_union_p2p_request_full(), and handle_union_p2p_strata_estimator().

1297 {
1298  struct GNUNET_MQ_Envelope *ev;
1299 
1300  op->phase = PHASE_FULL_SENDING;
1302  "Dedicing to transmit the full set\n");
1303  /* FIXME: use a more memory-friendly way of doing this with an
1304  iterator, just as we do in the non-full case! */
1307  op);
1309  GNUNET_MQ_send (op->mq,
1310  ev);
1311 }
After sending the full set, wait for responses with the elements that the local peer is missing...
enum IntersectionOperationPhase phase
Current state of the operation.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
static int send_full_element_iterator(void *cls, const struct GNUNET_HashCode *key, void *value)
Send a set element.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
#define GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE
Request all missing elements from the other peer, based on their sets and the elements we previously ...
#define LOG(kind,...)
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
Definition: gnunet_mq_lib.h:76
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_union_p2p_strata_estimator()

static int check_union_p2p_strata_estimator ( void *  cls,
const struct StrataEstimatorMessage msg 
)
static

Handle a strata estimator from a remote peer.

Parameters
clsthe union operation
msgthe message

Definition at line 1321 of file gnunet-service-setu.c.

References GNUNET_break, GNUNET_MESSAGE_TYPE_SETU_P2P_SEC, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, StrataEstimatorMessage::header, IBF_BUCKET_SIZE, len, Operation::phase, PHASE_EXPECT_SE, SE_IBF_SIZE, SE_STRATA_COUNT, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

1323 {
1324  struct Operation *op = cls;
1325  int is_compressed;
1326  size_t len;
1327 
1328  if (op->phase != PHASE_EXPECT_SE)
1329  {
1330  GNUNET_break (0);
1331  return GNUNET_SYSERR;
1332  }
1333  is_compressed = (GNUNET_MESSAGE_TYPE_SETU_P2P_SEC == htons (
1334  msg->header.type));
1335  len = ntohs (msg->header.size) - sizeof(struct StrataEstimatorMessage);
1336  if ((GNUNET_NO == is_compressed) &&
1338  {
1339  GNUNET_break (0);
1340  return GNUNET_SYSERR;
1341  }
1342  return GNUNET_OK;
1343 }
enum IntersectionOperationPhase phase
Current state of the operation.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE(C)
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define SE_IBF_SIZE
Size of the IBFs in the strata estimator.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_MESSAGE_TYPE_SETU_P2P_SEC
Compressed strata estimator.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define IBF_BUCKET_SIZE
Size of one ibf bucket in bytes.
Definition: ibf.h:72
Strata estimator together with the peer&#39;s overall set size.
Operation context used to execute a set operation.
#define SE_STRATA_COUNT
Number of IBFs in a strata estimator.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
We sent the request message, and expect a strata estimator.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...

◆ handle_union_p2p_strata_estimator()

static void handle_union_p2p_strata_estimator ( void *  cls,
const struct StrataEstimatorMessage msg 
)
static

Handle a strata estimator from a remote peer.

Parameters
clsthe union operation
msgthe message

Definition at line 1353 of file gnunet-service-setu.c.

References Operation::byzantine, Operation::channel, removetrailingwhitespace::f, fail_union_operation(), Operation::force_full, get_order_from_difference(), getenv(), GNUNET_assert, GNUNET_break, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_MESSAGE_TYPE_SETU_P2P_REQUEST_FULL, GNUNET_MESSAGE_TYPE_SETU_P2P_SEC, GNUNET_MQ_msg_header, GNUNET_MQ_send(), GNUNET_NO, GNUNET_ntohll(), GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_YES, StrataEstimatorMessage::header, Operation::initial_size, len, LOG, Operation::mq, Operation::phase, PHASE_EXPECT_IBF, Operation::se, SE_IBF_HASH_NUM, SE_IBF_SIZE, SE_STRATA_COUNT, send_full_set(), send_ibf(), StrataEstimatorMessage::set_size, GNUNET_MessageHeader::size, strata_estimator_create(), strata_estimator_destroy(), strata_estimator_difference(), strata_estimator_read(), and GNUNET_MessageHeader::type.

1355 {
1356  struct Operation *op = cls;
1357  struct StrataEstimator *remote_se;
1358  unsigned int diff;
1359  uint64_t other_size;
1360  size_t len;
1361  int is_compressed;
1362 
1363  is_compressed = (GNUNET_MESSAGE_TYPE_SETU_P2P_SEC == htons (
1364  msg->header.type));
1366  "# bytes of SE received",
1367  ntohs (msg->header.size),
1368  GNUNET_NO);
1369  len = ntohs (msg->header.size) - sizeof(struct StrataEstimatorMessage);
1370  other_size = GNUNET_ntohll (msg->set_size);
1372  SE_IBF_SIZE,
1373  SE_IBF_HASH_NUM);
1374  if (NULL == remote_se)
1375  {
1376  /* insufficient resources, fail */
1377  fail_union_operation (op);
1378  return;
1379  }
1380  if (GNUNET_OK !=
1381  strata_estimator_read (&msg[1],
1382  len,
1383  is_compressed,
1384  remote_se))
1385  {
1386  /* decompression failed */
1387  strata_estimator_destroy (remote_se);
1388  fail_union_operation (op);
1389  return;
1390  }
1391  GNUNET_assert (NULL != op->se);
1392  diff = strata_estimator_difference (remote_se,
1393  op->se);
1394 
1395  if (diff > 200)
1396  diff = diff * 3 / 2;
1397 
1398  strata_estimator_destroy (remote_se);
1400  op->se = NULL;
1402  "got se diff=%d, using ibf size %d\n",
1403  diff,
1404  1U << get_order_from_difference (diff));
1405 
1406  {
1407  char *set_debug;
1408 
1409  set_debug = getenv ("GNUNET_SETU_BENCHMARK");
1410  if ((NULL != set_debug) &&
1411  (0 == strcmp (set_debug, "1")))
1412  {
1413  FILE *f = fopen ("set.log", "a");
1414  fprintf (f, "%llu\n", (unsigned long long) diff);
1415  fclose (f);
1416  }
1417  }
1418 
1419  if ((GNUNET_YES == op->byzantine) &&
1420  (other_size < op->byzantine_lower_bound))
1421  {
1422  GNUNET_break (0);
1423  fail_union_operation (op);
1424  return;
1425  }
1426 
1427  if ((GNUNET_YES == op->force_full) ||
1428  (diff > op->initial_size / 4) ||
1429  (0 == other_size))
1430  {
1432  "Deciding to go for full set transmission (diff=%d, own set=%u)\n",
1433  diff,
1434  op->initial_size);
1436  "# of full sends",
1437  1,
1438  GNUNET_NO);
1439  if ((op->initial_size <= other_size) ||
1440  (0 == other_size))
1441  {
1442  send_full_set (op);
1443  }
1444  else
1445  {
1446  struct GNUNET_MQ_Envelope *ev;
1447 
1449  "Telling other peer that we expect its full set\n");
1450  op->phase = PHASE_EXPECT_IBF;
1451  ev = GNUNET_MQ_msg_header (
1453  GNUNET_MQ_send (op->mq,
1454  ev);
1455  }
1456  }
1457  else
1458  {
1460  "# of ibf sends",
1461  1,
1462  GNUNET_NO);
1463  if (GNUNET_OK !=
1464  send_ibf (op,
1465  get_order_from_difference (diff)))
1466  {
1467  /* Internal error, best we can do is shut the connection */
1469  "Failed to send IBF, closing connection\n");
1470  fail_union_operation (op);
1471  return;
1472  }
1473  }
1475 }
struct StrataEstimator * se
Copy of the set&#39;s strata estimator at the time of creation of this operation.
static void send_full_set(struct Operation *op)
Switch to full set transmission for op.
#define SE_IBF_HASH_NUM
The hash num parameter for the difference digests and strata estimators.
enum IntersectionOperationPhase phase
Current state of the operation.
struct StrataEstimator * strata_estimator_create(unsigned int strata_count, uint32_t ibf_size, uint8_t ibf_hashnum)
Create a new strata estimator with the given parameters.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE(C)
uint64_t initial_size
Initial size of our set, just before the operation started.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static int send_ibf(struct Operation *op, uint16_t ibf_order)
Send an ibf of appropriate size.
#define SE_IBF_SIZE
Size of the IBFs in the strata estimator.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
A handle to a strata estimator.
#define GNUNET_MESSAGE_TYPE_SETU_P2P_SEC
Compressed strata estimator.
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_MESSAGE_TYPE_SETU_P2P_REQUEST_FULL
Demand the whole element from the other peer, given only the hash code.
void strata_estimator_destroy(struct StrataEstimator *se)
Destroy a strata estimator, free all of its resources.
We sent the strata estimator, and expect an IBF.
#define LOG(kind,...)
int strata_estimator_read(const void *buf, size_t buf_len, int is_compressed, struct StrataEstimator *se)
Read strata from the buffer into the given strata estimator.
int byzantine
GNUNET_YES to fail operations where Byzantine faults are suspected
char * getenv()
Strata estimator together with the peer&#39;s overall set size.
unsigned int strata_estimator_difference(const struct StrataEstimator *se1, const struct StrataEstimator *se2)
Estimate set difference with two strata estimators, i.e.
Operation context used to execute a set operation.
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
Definition: gnunet_mq_lib.h:76
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888
struct GNUNET_CADET_Channel * channel
Channel to the peer.
#define GNUNET_log(kind,...)
#define SE_STRATA_COUNT
Number of IBFs in a strata estimator.
static unsigned int get_order_from_difference(unsigned int diff)
Compute the necessary order of an ibf from the size of the symmetric set difference.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:53
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
int force_full
Always send full sets, even if delta operations would be more efficient.
Here is the call graph for this function:

◆ send_offers_iterator()

static int send_offers_iterator ( void *  cls,
uint32_t  key,
void *  value 
)
static

Iterator to send elements to a remote peer.

Parameters
clsclosure with the element key and the union operation
keyignored
valuethe key entry

Definition at line 1486 of file gnunet-service-setu.c.

References KeyEntry::element, ElementEntry::element_hash, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_MESSAGE_TYPE_SETU_P2P_OFFER, GNUNET_MQ_msg_header_extra, GNUNET_MQ_send(), GNUNET_YES, KeyEntry::ibf_key, SendElementClosure::ibf_key, IBF_Key::key_val, LOG, mh, Operation::mq, op, SendElementClosure::op, and value.

Referenced by send_offers_for_key().

1489 {
1490  struct SendElementClosure *sec = cls;
1491  struct Operation *op = sec->op;
1492  struct KeyEntry *ke = value;
1493  struct GNUNET_MQ_Envelope *ev;
1494  struct GNUNET_MessageHeader *mh;
1495 
1496  /* Detect 32-bit key collision for the 64-bit IBF keys. */
1497  if (ke->ibf_key.key_val != sec->ibf_key.key_val)
1498  return GNUNET_YES;
1499 
1500  ev = GNUNET_MQ_msg_header_extra (mh,
1501  sizeof(struct GNUNET_HashCode),
1503 
1504  GNUNET_assert (NULL != ev);
1505  *(struct GNUNET_HashCode *) &mh[1] = ke->element->element_hash;
1507  "[OP %x] sending element offer (%s) to peer\n",
1508  (void *) op,
1509  GNUNET_h2s (&ke->element->element_hash));
1510  GNUNET_MQ_send (op->mq, ev);
1511  return GNUNET_YES;
1512 }
struct Operation * op
Operation for which the elements should be sent.
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_CADET_Handle * mh
Cadet handle.
Definition: gnunet-cadet.c:92
#define GNUNET_MESSAGE_TYPE_SETU_P2P_OFFER
Tell the other peer which hashes match a given IBF key.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint64_t key_val
Definition: ibf.h:47
The key entry is used to associate an ibf key with an element.
static char * value
Value of the record to add/remove.
struct IBF_Key ibf_key
IBF key for the entry, derived from the current salt.
struct ElementEntry * element
The actual element associated with the key.
A 512-bit hashcode.
#define LOG(kind,...)
#define GNUNET_MQ_msg_header_extra(mh, esize, type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header and extra space...
Definition: gnunet_mq_lib.h:88
Operation context used to execute a set operation.
Header for all communications.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
Used as a closure for sending elements with a specific IBF key.
struct IBF_Key ibf_key
The IBF key whose matching elements should be sent.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_offers_for_key()

static void send_offers_for_key ( struct Operation op,
struct IBF_Key  ibf_key 
)
static

Send offers (in the form of GNUNET_Hash-es) to the remote peer for the given IBF key.

Parameters
opunion operation
ibf_keyIBF key of interest

Definition at line 1522 of file gnunet-service-setu.c.

References GNUNET_CONTAINER_multihashmap32_get_multiple(), SendElementClosure::ibf_key, Operation::key_to_element, op, SendElementClosure::op, and send_offers_iterator().

Referenced by decode_and_send(), and handle_union_p2p_inquiry().

1524 {
1525  struct SendElementClosure send_cls;
1526 
1527  send_cls.ibf_key = ibf_key;
1528  send_cls.op = op;
1530  op->key_to_element,
1531  (uint32_t) ibf_key.
1532  key_val,
1534  &send_cls);
1535 }
int GNUNET_CONTAINER_multihashmap32_get_multiple(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
static int send_offers_iterator(void *cls, uint32_t key, void *value)
Iterator to send elements to a remote peer.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Used as a closure for sending elements with a specific IBF key.
struct IBF_Key ibf_key
The IBF key whose matching elements should be sent.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ decode_and_send()

static int decode_and_send ( struct Operation op)
static

Decode which elements are missing on each side, and send the appropriate offers and inquiries.

Parameters
opunion operation
Returns
GNUNET_OK on success, GNUNET_SYSERR on failure

Definition at line 1546 of file gnunet-service-setu.c.

References fail_union_operation(), GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SETU_P2P_DONE, GNUNET_MESSAGE_TYPE_SETU_P2P_INQUIRY, GNUNET_MQ_msg_extra, GNUNET_MQ_msg_header, GNUNET_MQ_send(), GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_YES, ibf_decode(), ibf_destroy(), ibf_dup(), ibf_subtract(), key, IBF_Key::key_val, Operation::local_ibf, LOG, MAX_IBF_ORDER, Operation::mq, msg, Operation::phase, PHASE_INVENTORY_ACTIVE, prepare_ibf(), Operation::remote_ibf, res, InquiryMessage::salt, Operation::salt_receive, Operation::salt_send, send_ibf(), send_offers_for_key(), size, InvertibleBloomFilter::size, and unsalt_key().

Referenced by handle_union_p2p_ibf().

1547 {
1548  struct IBF_Key key;
1549  struct IBF_Key last_key;
1550  int side;
1551  unsigned int num_decoded;
1552  struct InvertibleBloomFilter *diff_ibf;
1553 
1555 
1556  if (GNUNET_OK !=
1557  prepare_ibf (op,
1558  op->remote_ibf->size))
1559  {
1560  GNUNET_break (0);
1561  /* allocation failed */
1562  return GNUNET_SYSERR;
1563  }
1564  diff_ibf = ibf_dup (op->local_ibf);
1565  ibf_subtract (diff_ibf,
1566  op->remote_ibf);
1567 
1568  ibf_destroy (op->remote_ibf);
1569  op->remote_ibf = NULL;
1570 
1572  "decoding IBF (size=%u)\n",
1573  diff_ibf->size);
1574 
1575  num_decoded = 0;
1576  key.key_val = 0; /* just to avoid compiler thinking we use undef'ed variable */
1577 
1578  while (1)
1579  {
1580  int res;
1581  int cycle_detected = GNUNET_NO;
1582 
1583  last_key = key;
1584 
1585  res = ibf_decode (diff_ibf,
1586  &side,
1587  &key);
1588  if (res == GNUNET_OK)
1589  {
1591  "decoded ibf key %lx\n",
1592  (unsigned long) key.key_val);
1593  num_decoded += 1;
1594  if ((num_decoded > diff_ibf->size) ||
1595  ((num_decoded > 1) &&
1596  (last_key.key_val == key.key_val)))
1597  {
1599  "detected cyclic ibf (decoded %u/%u)\n",
1600  num_decoded,
1601  diff_ibf->size);
1602  cycle_detected = GNUNET_YES;
1603  }
1604  }
1605  if ((GNUNET_SYSERR == res) ||
1606  (GNUNET_YES == cycle_detected))
1607  {
1608  int next_order;
1609  next_order = 0;
1610  while (1 << next_order < diff_ibf->size)
1611  next_order++;
1612  next_order++;
1613  if (next_order <= MAX_IBF_ORDER)
1614  {
1616  "decoding failed, sending larger ibf (size %u)\n",
1617  1 << next_order);
1619  "# of IBF retries",
1620  1,
1621  GNUNET_NO);
1622  op->salt_send++;
1623  if (GNUNET_OK !=
1624  send_ibf (op, next_order))
1625  {
1626  /* Internal error, best we can do is shut the connection */
1628  "Failed to send IBF, closing connection\n");
1629  fail_union_operation (op);
1630  ibf_destroy (diff_ibf);
1631  return GNUNET_SYSERR;
1632  }
1633  }
1634  else
1635  {
1637  "# of failed union operations (too large)",
1638  1,
1639  GNUNET_NO);
1640  // XXX: Send the whole set, element-by-element
1642  "set union failed: reached ibf limit\n");
1643  fail_union_operation (op);
1644  ibf_destroy (diff_ibf);
1645  return GNUNET_SYSERR;
1646  }
1647  break;
1648  }
1649  if (GNUNET_NO == res)
1650  {
1651  struct GNUNET_MQ_Envelope *ev;
1652 
1654  "transmitted all values, sending DONE\n");
1656  GNUNET_MQ_send (op->mq, ev);
1657  /* We now wait until we get a DONE message back
1658  * and then wait for our MQ to be flushed and all our
1659  * demands be delivered. */
1660  break;
1661  }
1662  if (1 == side)
1663  {
1664  struct IBF_Key unsalted_key;
1665 
1666  unsalt_key (&key,
1667  op->salt_receive,
1668  &unsalted_key);
1669  send_offers_for_key (op,
1670  unsalted_key);
1671  }
1672  else if (-1 == side)
1673  {
1674  struct GNUNET_MQ_Envelope *ev;
1675  struct InquiryMessage *msg;
1676 
1677  /* It may be nice to merge multiple requests, but with CADET's corking it is not worth
1678  * the effort additional complexity. */
1679  ev = GNUNET_MQ_msg_extra (msg,
1680  sizeof(struct IBF_Key),
1682  msg->salt = htonl (op->salt_receive);
1683  GNUNET_memcpy (&msg[1],
1684  &key,
1685  sizeof(struct IBF_Key));
1687  "sending element inquiry for IBF key %lx\n",
1688  (unsigned long) key.key_val);
1689  GNUNET_MQ_send (op->mq, ev);
1690  }
1691  else
1692  {
1693  GNUNET_assert (0);
1694  }
1695  }
1696  ibf_destroy (diff_ibf);
1697  return GNUNET_OK;
1698 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
enum IntersectionOperationPhase phase
Current state of the operation.
struct InvertibleBloomFilter * remote_ibf
The IBF we currently receive.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Invertible bloom filter (IBF).
Definition: ibf.h:82
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static void send_offers_for_key(struct Operation *op, struct IBF_Key ibf_key)
Send offers (in the form of GNUNET_Hash-es) to the remote peer for the given IBF key.
static void unsalt_key(const struct IBF_Key *k_in, uint32_t salt, struct IBF_Key *k_out)
FIXME.
#define GNUNET_MESSAGE_TYPE_SETU_P2P_DONE
Set operation is done.
uint32_t salt_receive
Salt for the IBF we&#39;ve received and that we&#39;re currently decoding.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static int send_ibf(struct Operation *op, uint16_t ibf_order)
Send an ibf of appropriate size.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct InvertibleBloomFilter * ibf_dup(const struct InvertibleBloomFilter *ibf)
Create a copy of an IBF, the copy has to be destroyed properly.
Definition: ibf.c:379
uint32_t size
How many cells does this IBF have?
Definition: ibf.h:87
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
We are decoding an IBF.
int ibf_decode(struct InvertibleBloomFilter *ibf, int *ret_side, struct IBF_Key *ret_id)
Decode and remove an element from the IBF, if possible.
Definition: ibf.c:228
void ibf_subtract(struct InvertibleBloomFilter *ibf1, const struct InvertibleBloomFilter *ibf2)
Subtract ibf2 from ibf1, storing the result in ibf1.
Definition: ibf.c:356
static int res
#define LOG(kind,...)
struct GNUNET_HashCode key
The key used in the DHT.
static unsigned int size
Size of the "table".
Definition: peer.c:67
void ibf_destroy(struct InvertibleBloomFilter *ibf)
Destroy all resources associated with the invertible bloom filter.
Definition: ibf.c:403
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
Definition: gnunet_mq_lib.h:76
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
struct InvertibleBloomFilter * local_ibf
The IBF with the local set&#39;s element.
#define GNUNET_log(kind,...)
#define MAX_IBF_ORDER
The maximum size of an ibf we use is 2^(MAX_IBF_ORDER).
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
static int prepare_ibf(struct Operation *op, uint32_t size)
Create an ibf with the operation&#39;s elements of the specified size.
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:45
uint32_t salt
Salt used when hashing elements for this inquiry.
uint32_t salt_send
Salt that we&#39;re using for sending IBFs.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
#define GNUNET_MESSAGE_TYPE_SETU_P2P_INQUIRY
Tell the other peer to send us a list of hashes that match an IBF key.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_union_p2p_ibf()

static int check_union_p2p_ibf ( void *  cls,
const struct IBFMessage msg 
)
static

Check an IBF message from a remote peer.

Reassemble the IBF from multiple pieces, and process the whole IBF once possible.

Parameters
clsthe union operation
msgthe header of the message
Returns
GNUNET_OK if msg is well-formed

Definition at line 1712 of file gnunet-service-setu.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, IBFMessage::header, IBF_BUCKET_SIZE, Operation::ibf_buckets_received, msg, IBFMessage::offset, IBFMessage::order, Operation::phase, PHASE_EXPECT_IBF, PHASE_EXPECT_IBF_CONT, PHASE_INVENTORY_PASSIVE, Operation::remote_ibf, IBFMessage::salt, Operation::salt_receive, InvertibleBloomFilter::size, and GNUNET_MessageHeader::size.

1714 {
1715  struct Operation *op = cls;
1716  unsigned int buckets_in_message;
1717 
1718  buckets_in_message = (ntohs (msg->header.size) - sizeof *msg)
1719  / IBF_BUCKET_SIZE;
1720  if (0 == buckets_in_message)
1721  {
1722  GNUNET_break_op (0);
1723  return GNUNET_SYSERR;
1724  }
1725  if ((ntohs (msg->header.size) - sizeof *msg) != buckets_in_message
1726  * IBF_BUCKET_SIZE)
1727  {
1728  GNUNET_break_op (0);
1729  return GNUNET_SYSERR;
1730  }
1731  if (op->phase == PHASE_EXPECT_IBF_CONT)
1732  {
1733  if (ntohl (msg->offset) != op->ibf_buckets_received)
1734  {
1735  GNUNET_break_op (0);
1736  return GNUNET_SYSERR;
1737  }
1738  if (1 << msg->order != op->remote_ibf->size)
1739  {
1740  GNUNET_break_op (0);
1741  return GNUNET_SYSERR;
1742  }
1743  if (ntohl (msg->salt) != op->salt_receive)
1744  {
1745  GNUNET_break_op (0);
1746  return GNUNET_SYSERR;
1747  }
1748  }
1749  else if ((op->phase != PHASE_INVENTORY_PASSIVE) &&
1750  (op->phase != PHASE_EXPECT_IBF))
1751  {
1752  GNUNET_break_op (0);
1753  return GNUNET_SYSERR;
1754  }
1755 
1756  return GNUNET_OK;
1757 }
uint32_t offset
Offset of the strata in the rest of the message.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
enum IntersectionOperationPhase phase
Current state of the operation.
struct InvertibleBloomFilter * remote_ibf
The IBF we currently receive.
unsigned int ibf_buckets_received
Number of ibf buckets already received into the remote_ibf.
uint32_t salt_receive
Salt for the IBF we&#39;ve received and that we&#39;re currently decoding.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
uint32_t size
How many cells does this IBF have?
Definition: ibf.h:87
The other peer is decoding the IBF we just sent.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
uint8_t order
Order of the whole ibf, where num_buckets = 2^order.
We sent the strata estimator, and expect an IBF.
#define IBF_BUCKET_SIZE
Size of one ibf bucket in bytes.
Definition: ibf.h:72
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF.
Operation context used to execute a set operation.
uint32_t salt
Salt used when hashing elements for this IBF.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Continuation for multi part IBFs.

◆ handle_union_p2p_ibf()

static void handle_union_p2p_ibf ( void *  cls,
const struct IBFMessage msg 
)
static

Handle an IBF message from a remote peer.

Reassemble the IBF from multiple pieces, and process the whole IBF once possible.

Parameters
clsthe union operation
msgthe header of the message

Definition at line 1770 of file gnunet-service-setu.c.

References Operation::channel, decode_and_send(), fail_union_operation(), GNUNET_assert, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_OK, IBFMessage::header, IBF_BUCKET_SIZE, Operation::ibf_buckets_received, ibf_create(), ibf_read_slice(), LOG, msg, IBFMessage::offset, IBFMessage::order, Operation::phase, PHASE_EXPECT_IBF, PHASE_EXPECT_IBF_CONT, PHASE_INVENTORY_ACTIVE, PHASE_INVENTORY_PASSIVE, Operation::remote_ibf, IBFMessage::salt, Operation::salt_receive, SE_IBF_HASH_NUM, InvertibleBloomFilter::size, and GNUNET_MessageHeader::size.

1772 {
1773  struct Operation *op = cls;
1774  unsigned int buckets_in_message;
1775 
1776  buckets_in_message = (ntohs (msg->header.size) - sizeof *msg)
1777  / IBF_BUCKET_SIZE;
1778  if ((op->phase == PHASE_INVENTORY_PASSIVE) ||
1779  (op->phase == PHASE_EXPECT_IBF))
1780  {
1782  GNUNET_assert (NULL == op->remote_ibf);
1784  "Creating new ibf of size %u\n",
1785  1 << msg->order);
1786  op->remote_ibf = ibf_create (1 << msg->order, SE_IBF_HASH_NUM);
1787  op->salt_receive = ntohl (msg->salt);
1789  "Receiving new IBF with salt %u\n",
1790  op->salt_receive);
1791  if (NULL == op->remote_ibf)
1792  {
1794  "Failed to parse remote IBF, closing connection\n");
1795  fail_union_operation (op);
1796  return;
1797  }
1798  op->ibf_buckets_received = 0;
1799  if (0 != ntohl (msg->offset))
1800  {
1801  GNUNET_break_op (0);
1802  fail_union_operation (op);
1803  return;
1804  }
1805  }
1806  else
1807  {
1810  "Received more of IBF\n");
1811  }
1812  GNUNET_assert (NULL != op->remote_ibf);
1813 
1814  ibf_read_slice (&msg[1],
1816  buckets_in_message,
1817  op->remote_ibf);
1818  op->ibf_buckets_received += buckets_in_message;
1819 
1820  if (op->ibf_buckets_received == op->remote_ibf->size)
1821  {
1823  "received full ibf\n");
1825  if (GNUNET_OK !=
1826  decode_and_send (op))
1827  {
1828  /* Internal error, best we can do is shut down */
1830  "Failed to decode IBF, closing connection\n");
1831  fail_union_operation (op);
1832  return;
1833  }
1834  }
1836 }
uint32_t offset
Offset of the strata in the rest of the message.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define SE_IBF_HASH_NUM
The hash num parameter for the difference digests and strata estimators.
enum IntersectionOperationPhase phase
Current state of the operation.
struct InvertibleBloomFilter * remote_ibf
The IBF we currently receive.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
unsigned int ibf_buckets_received
Number of ibf buckets already received into the remote_ibf.
uint32_t salt_receive
Salt for the IBF we&#39;ve received and that we&#39;re currently decoding.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
uint32_t size
How many cells does this IBF have?
Definition: ibf.h:87
The other peer is decoding the IBF we just sent.
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
We are decoding an IBF.
uint8_t order
Order of the whole ibf, where num_buckets = 2^order.
We sent the strata estimator, and expect an IBF.
#define IBF_BUCKET_SIZE
Size of one ibf bucket in bytes.
Definition: ibf.h:72
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF.
#define LOG(kind,...)
void ibf_read_slice(const void *buf, uint32_t start, uint32_t count, struct InvertibleBloomFilter *ibf)
Read buckets from a buffer into an ibf.
Definition: ibf.c:323
static int decode_and_send(struct Operation *op)
Decode which elements are missing on each side, and send the appropriate offers and inquiries...
struct InvertibleBloomFilter * ibf_create(uint32_t size, uint8_t hash_num)
Create an invertible bloom filter.
Definition: ibf.c:79
Operation context used to execute a set operation.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888
struct GNUNET_CADET_Channel * channel
Channel to the peer.
uint32_t salt
Salt used when hashing elements for this IBF.
#define GNUNET_log(kind,...)
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Continuation for multi part IBFs.
Here is the call graph for this function:

◆ send_client_element()

static void send_client_element ( struct Operation op,
const struct GNUNET_SETU_Element element,
enum GNUNET_SETU_Status  status 
)
static

Send a result message to the client indicating that there is a new element.

Parameters
opunion operation
elementelement to send
statusstatus to send with the new element

Definition at line 1848 of file gnunet-service-setu.c.

References Operation::client_request_id, Set::cs, GNUNET_SETU_ResultMessage::current_size, GNUNET_SETU_Element::data, GNUNET_SETU_Element::element_type, GNUNET_SETU_ResultMessage::element_type, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multihashmap32_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_htonll(), GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SETU_RESULT, GNUNET_MQ_discard(), GNUNET_MQ_msg_extra, GNUNET_MQ_send(), Operation::key_to_element, LOG, ClientState::mq, GNUNET_SETU_ResultMessage::request_id, GNUNET_SETU_ResultMessage::result_status, Operation::set, and GNUNET_SETU_Element::size.

Referenced by handle_union_p2p_demand(), handle_union_p2p_elements(), and handle_union_p2p_full_element().

1851 {
1852  struct GNUNET_MQ_Envelope *ev;
1853  struct GNUNET_SETU_ResultMessage *rm;
1854 
1856  "sending element (size %u) to client\n",
1857  element->size);
1858  GNUNET_assert (0 != op->client_request_id);
1859  ev = GNUNET_MQ_msg_extra (rm,
1860  element->size,
1862  if (NULL == ev)
1863  {
1864  GNUNET_MQ_discard (ev);
1865  GNUNET_break (0);
1866  return;
1867  }
1868  rm->result_status = htons (status);
1869  rm->request_id = htonl (op->client_request_id);
1870  rm->element_type = htons (element->element_type);
1872  op->key_to_element));
1873  GNUNET_memcpy (&rm[1],
1874  element->data,
1875  element->size);
1876  GNUNET_MQ_send (op->set->cs->mq,
1877  ev);
1878 }
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
const void * data
Actual data of the element.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint32_t request_id
id the result belongs to
Definition: setu.h:254
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: setu.h:265
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
#define GNUNET_MESSAGE_TYPE_SETU_RESULT
Handle result message from operation.
uint16_t element_type
Application-specific element type.
unsigned int GNUNET_CONTAINER_multihashmap32_size(const struct GNUNET_CONTAINER_MultiHashMap32 *map)
Get the number of key-value pairs in the map.
uint16_t status
See PRISM_STATUS_*-constants.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SETU_Status in NBO.
Definition: setu.h:260
#define LOG(kind,...)
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:323
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:36
uint64_t current_size
Current set size.
Definition: setu.h:249
struct ClientState * cs
Client that owns the set.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: setu.h:239
uint32_t client_request_id
ID used to identify an operation between service and client.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
uint16_t size
Number of bytes in the buffer pointed to by data.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ maybe_finish()

static void maybe_finish ( struct Operation op)
static

Tests if the operation is finished, and if so notify.

Parameters
opoperation to check

Definition at line 1887 of file gnunet-service-setu.c.

References _GSS_operation_destroy2(), Operation::demanded_hashes, GNUNET_CONTAINER_multihashmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_SETU_P2P_DONE, GNUNET_MQ_msg_header, GNUNET_MQ_send(), LOG, Operation::mq, Operation::phase, PHASE_DONE, PHASE_FINISH_CLOSING, PHASE_FINISH_WAITING, and send_client_done().

Referenced by handle_union_p2p_done(), and handle_union_p2p_elements().

1888 {
1889  unsigned int num_demanded;
1890 
1891  num_demanded = GNUNET_CONTAINER_multihashmap_size (
1892  op->demanded_hashes);
1893 
1894  if (PHASE_FINISH_WAITING == op->phase)
1895  {
1897  "In PHASE_FINISH_WAITING, pending %u demands\n",
1898  num_demanded);
1899  if (0 == num_demanded)
1900  {
1901  struct GNUNET_MQ_Envelope *ev;
1902 
1903  op->phase = PHASE_DONE;
1905  GNUNET_MQ_send (op->mq,
1906  ev);
1907  /* We now wait until the other peer sends P2P_OVER
1908  * after it got all elements from us. */
1909  }
1910  }
1911  if (PHASE_FINISH_CLOSING == op->phase)
1912  {
1914  "In PHASE_FINISH_CLOSING, pending %u demands\n",
1915  num_demanded);
1916  if (0 == num_demanded)
1917  {
1918  op->phase = PHASE_DONE;
1919  send_client_done (op);
1921  }
1922  }
1923 }
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
enum IntersectionOperationPhase phase
Current state of the operation.
#define GNUNET_MESSAGE_TYPE_SETU_P2P_DONE
Set operation is done.
static void _GSS_operation_destroy2(struct Operation *op)
This function probably should not exist and be replaced by inlining more specific logic in the variou...
The protocol is almost finished, but we still have to flush our message queue and/or expect some elem...
static void send_client_done(void *cls)
Signal to the client that the operation has finished and destroy the operation.
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
In the penultimate phase, we wait until all our demands are satisfied.
#define LOG(kind,...)
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
Definition: gnunet_mq_lib.h:76
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
In the ultimate phase, we wait until our demands are satisfied and then quit (sending another DONE me...
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_union_p2p_elements()

static int check_union_p2p_elements ( void *  cls,
const struct GNUNET_SETU_ElementMessage emsg 
)
static

Check an element message from a remote peer.

Parameters
clsthe union operation
emsgthe message

Definition at line 1933 of file gnunet-service-setu.c.

References Operation::demanded_hashes, GNUNET_break_op, GNUNET_CONTAINER_multihashmap_size(), GNUNET_OK, and GNUNET_SYSERR.

1935 {
1936  struct Operation *op = cls;
1937 
1939  {
1940  GNUNET_break_op (0);
1941  return GNUNET_SYSERR;
1942  }
1943  return GNUNET_OK;
1944 }
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
Operation context used to execute a set operation.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Here is the call graph for this function:

◆ handle_union_p2p_elements()

static void handle_union_p2p_elements ( void *  cls,
const struct GNUNET_SETU_ElementMessage emsg 
)
static

Handle an element message from a remote peer.

Sent by the other peer either because we decoded an IBF and placed a demand, or because the other peer switched to full set transmission.

Parameters
clsthe union operation
emsgthe message

Definition at line 1956 of file gnunet-service-setu.c.

References Operation::channel, GNUNET_SET_Element::data, Operation::demanded_hashes, ElementEntry::element, ElementEntry::element_hash, element_size, GNUNET_SET_Element::element_type, GNUNET_SETU_ElementMessage::element_type, fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_h2s(), GNUNET_malloc, GNUNET_memcpy, GNUNET_NO, GNUNET_SETU_element_hash(), GNUNET_SETU_STATUS_ADD_LOCAL, GNUNET_STATISTICS_update(), GNUNET_YES, GNUNET_SETU_ElementMessage::header, LOG, maybe_finish(), op_get_element(), op_register_element(), KeyEntry::received, Operation::received_fresh, Operation::received_total, ElementEntry::remote, send_client_element(), GNUNET_SET_Element::size, and GNUNET_MessageHeader::size.

1958 {
1959  struct Operation *op = cls;
1960  struct ElementEntry *ee;
1961  struct KeyEntry *ke;
1962  uint16_t element_size;
1963 
1964  element_size = ntohs (emsg->header.size) - sizeof(struct
1966  ee = GNUNET_malloc (sizeof(struct ElementEntry) + element_size);
1967  GNUNET_memcpy (&ee[1],
1968  &emsg[1],
1969  element_size);
1970  ee->element.size = element_size;
1971  ee->element.data = &ee[1];
1972  ee->element.element_type = ntohs (emsg->element_type);
1973  ee->remote = GNUNET_YES;
1975  &ee->element_hash);
1976  if (GNUNET_NO ==
1978  &ee->element_hash,
1979  NULL))
1980  {
1981  /* We got something we didn't demand, since it's not in our map. */
1982  GNUNET_break_op (0);
1983  fail_union_operation (op);
1984  return;
1985  }
1986 
1988  "Got element (size %u, hash %s) from peer\n",
1989  (unsigned int) element_size,
1990  GNUNET_h2s (&ee->element_hash));
1991 
1993  "# received elements",
1994  1,
1995  GNUNET_NO);
1997  "# exchanged elements",
1998  1,
1999  GNUNET_NO);
2000 
2001  op->received_total++;
2002 
2003  ke = op_get_element (op,
2004  &ee->element_hash);
2005  if (NULL != ke)
2006  {
2007  /* Got repeated element. Should not happen since
2008  * we track demands. */
2010  "# repeated elements",
2011  1,
2012  GNUNET_NO);
2013  ke->received = GNUNET_YES;
2014  GNUNET_free (ee);
2015  }
2016  else
2017  {
2019  "Registering new element from remote peer\n");
2020  op->received_fresh++;
2021  op_register_element (op, ee, GNUNET_YES);
2022  /* only send results immediately if the client wants it */
2023  send_client_element (op,
2024  &ee->element,
2026  }
2027 
2028  if ((op->received_total > 8) &&
2029  (op->received_fresh < op->received_total / 3))
2030  {
2031  /* The other peer gave us lots of old elements, there's something wrong. */
2032  GNUNET_break_op (0);
2033  fail_union_operation (op);
2034  return;
2035  }
2037  maybe_finish (op);
2038 }
uint32_t received_fresh
Number of elements we received from the other peer that were not in the local set yet...
static void maybe_finish(struct Operation *op)
Tests if the operation is finished, and if so notify.
static unsigned int element_size
int received
Did we receive this element? Even if element->is_foreign is false, we might have received the element...
static void send_client_element(struct Operation *op, const struct GNUNET_SETU_Element *element, enum GNUNET_SETU_Status status)
Send a result message to the client indicating that there is a new element.
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
const void * data
Actual data of the element.
The key entry is used to associate an ibf key with an element.
uint16_t element_type
Type of the element to add or remove.
Definition: setu.h:285
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
static struct KeyEntry * op_get_element(struct Operation *op, const struct GNUNET_HashCode *element_hash)
Determine whether the given element is already in the operation&#39;s element set.
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
Information about an element element in the set.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
int remote
GNUNET_YES if the element is a remote element, and does not belong to the operation&#39;s set...
Element should be added to the result set of the local peer, i.e.
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
void GNUNET_SETU_element_hash(const struct GNUNET_SETU_Element *element, struct GNUNET_HashCode *ret_hash)
Hash a set element.
Definition: setu_api.c:876
#define LOG(kind,...)
Message sent by client to the service to add an element to the set.
Definition: setu.h:275
Operation context used to execute a set operation.
static void op_register_element(struct Operation *op, struct ElementEntry *ee, int received)
Insert an element into the union operation&#39;s key-to-element mapping.
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888
struct GNUNET_CADET_Channel * channel
Channel to the peer.
uint16_t size
Number of bytes in the buffer pointed to by data.
struct GNUNET_SET_Element element
The actual element.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SETU_ADD.
Definition: setu.h:280
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
#define GNUNET_malloc(size)
Wrapper around malloc.
uint32_t received_total
Total number of elements received from the other peer.
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t element_type
Application-specific element type.
Here is the call graph for this function:

◆ check_union_p2p_full_element()

static int check_union_p2p_full_element ( void *  cls,
const struct GNUNET_SETU_ElementMessage emsg 
)
static

Check a full element message from a remote peer.

Parameters
clsthe union operation
emsgthe message

Definition at line 2048 of file gnunet-service-setu.c.

References GNUNET_OK.

2050 {
2051  struct Operation *op = cls;
2052 
2053  (void) op;
2054  // FIXME: check that we expect full elements here?
2055  return GNUNET_OK;
2056 }
Operation context used to execute a set operation.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144

◆ handle_union_p2p_full_element()

static void handle_union_p2p_full_element ( void *  cls,
const struct GNUNET_SETU_ElementMessage emsg 
)
static

Handle an element message from a remote peer.

Parameters
clsthe union operation
emsgthe message

Definition at line 2066 of file gnunet-service-setu.c.

References Operation::byzantine, Operation::channel, GNUNET_SET_Element::data, ElementEntry::element, ElementEntry::element_hash, element_size, GNUNET_SET_Element::element_type, GNUNET_SETU_ElementMessage::element_type, fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_h2s(), GNUNET_malloc, GNUNET_memcpy, GNUNET_NO, GNUNET_SETU_element_hash(), GNUNET_SETU_STATUS_ADD_LOCAL, GNUNET_STATISTICS_update(), GNUNET_YES, GNUNET_SETU_ElementMessage::header, LOG, op_get_element(), op_register_element(), KeyEntry::received, Operation::received_fresh, Operation::received_total, ElementEntry::remote, send_client_element(), GNUNET_SET_Element::size, and GNUNET_MessageHeader::size.

2068 {
2069  struct Operation *op = cls;
2070  struct ElementEntry *ee;
2071  struct KeyEntry *ke;
2072  uint16_t element_size;
2073 
2074  element_size = ntohs (emsg->header.size)
2075  - sizeof(struct GNUNET_SETU_ElementMessage);
2076  ee = GNUNET_malloc (sizeof(struct ElementEntry) + element_size);
2077  GNUNET_memcpy (&ee[1], &emsg[1], element_size);
2078  ee->element.size = element_size;
2079  ee->element.data = &ee[1];
2080  ee->element.element_type = ntohs (emsg->element_type);
2081  ee->remote = GNUNET_YES;
2083  &ee->element_hash);
2085  "Got element (full diff, size %u, hash %s) from peer\n",
2086  (unsigned int) element_size,
2087  GNUNET_h2s (&ee->element_hash));
2088 
2090  "# received elements",
2091  1,
2092  GNUNET_NO);
2094  "# exchanged elements",
2095  1,
2096  GNUNET_NO);
2097 
2098  op->received_total++;
2099 
2100  ke = op_get_element (op,
2101  &ee->element_hash);
2102  if (NULL != ke)
2103  {
2104  /* Got repeated element. Should not happen since
2105  * we track demands. */
2107  "# repeated elements",
2108  1,
2109  GNUNET_NO);
2110  ke->received = GNUNET_YES;
2111  GNUNET_free (ee);
2112  }
2113  else
2114  {
2116  "Registering new element from remote peer\n");
2117  op->received_fresh++;
2118  op_register_element (op, ee, GNUNET_YES);
2119  /* only send results immediately if the client wants it */
2120  send_client_element (op,
2121  &ee->element,
2123  }
2124 
2125  if ((GNUNET_YES == op->byzantine) &&
2126  (op->received_total > 384 + op->received_fresh * 4) &&
2127  (op->received_fresh < op->received_total / 6))
2128  {
2129  /* The other peer gave us lots of old elements, there's something wrong. */
2131  "Other peer sent only %llu/%llu fresh elements, failing operation\n",
2132  (unsigned long long) op->received_fresh,
2133  (unsigned long long) op->received_total);
2134  GNUNET_break_op (0);
2135  fail_union_operation (op);
2136  return;
2137  }
2139 }
uint32_t received_fresh
Number of elements we received from the other peer that were not in the local set yet...
static unsigned int element_size
int received
Did we receive this element? Even if element->is_foreign is false, we might have received the element...
static void send_client_element(struct Operation *op, const struct GNUNET_SETU_Element *element, enum GNUNET_SETU_Status status)
Send a result message to the client indicating that there is a new element.
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
const void * data
Actual data of the element.
The key entry is used to associate an ibf key with an element.
uint16_t element_type
Type of the element to add or remove.
Definition: setu.h:285
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
static struct KeyEntry * op_get_element(struct Operation *op, const struct GNUNET_HashCode *element_hash)
Determine whether the given element is already in the operation&#39;s element set.
Information about an element element in the set.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
int remote
GNUNET_YES if the element is a remote element, and does not belong to the operation&#39;s set...
Element should be added to the result set of the local peer, i.e.
void GNUNET_SETU_element_hash(const struct GNUNET_SETU_Element *element, struct GNUNET_HashCode *ret_hash)
Hash a set element.
Definition: setu_api.c:876
#define LOG(kind,...)
int byzantine
GNUNET_YES to fail operations where Byzantine faults are suspected
Message sent by client to the service to add an element to the set.
Definition: setu.h:275
Operation context used to execute a set operation.
static void op_register_element(struct Operation *op, struct ElementEntry *ee, int received)
Insert an element into the union operation&#39;s key-to-element mapping.
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888
struct GNUNET_CADET_Channel * channel
Channel to the peer.
uint16_t size
Number of bytes in the buffer pointed to by data.
struct GNUNET_SET_Element element
The actual element.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SETU_ADD.
Definition: setu.h:280
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
#define GNUNET_malloc(size)
Wrapper around malloc.
uint32_t received_total
Total number of elements received from the other peer.
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t element_type
Application-specific element type.
Here is the call graph for this function:

◆ check_union_p2p_inquiry()

static int check_union_p2p_inquiry ( void *  cls,
const struct InquiryMessage msg 
)
static

Send offers (for GNUNET_Hash-es) in response to inquiries (for IBF_Key-s).

Parameters
clsthe union operation
msgthe message

Definition at line 2150 of file gnunet-service-setu.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, InquiryMessage::header, Operation::phase, PHASE_INVENTORY_PASSIVE, and GNUNET_MessageHeader::size.

2152 {
2153  struct Operation *op = cls;
2154  unsigned int num_keys;
2155 
2156  if (op->phase != PHASE_INVENTORY_PASSIVE)
2157  {
2158  GNUNET_break_op (0);
2159  return GNUNET_SYSERR;
2160  }
2161  num_keys = (ntohs (msg->header.size) - sizeof(struct InquiryMessage))
2162  / sizeof(struct IBF_Key);
2163  if ((ntohs (msg->header.size) - sizeof(struct InquiryMessage))
2164  != num_keys * sizeof(struct IBF_Key))
2165  {
2166  GNUNET_break_op (0);
2167  return GNUNET_SYSERR;
2168  }
2169  return GNUNET_OK;
2170 }
enum IntersectionOperationPhase phase
Current state of the operation.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
The other peer is decoding the IBF we just sent.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
Operation context used to execute a set operation.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:45

◆ handle_union_p2p_inquiry()

static void handle_union_p2p_inquiry ( void *  cls,
const struct InquiryMessage msg 
)
static

Send offers (for GNUNET_Hash-es) in response to inquiries (for IBF_Key-s).

Parameters
clsthe union operation
msgthe message

Definition at line 2180 of file gnunet-service-setu.c.

References Operation::channel, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, InquiryMessage::header, LOG, InquiryMessage::salt, send_offers_for_key(), GNUNET_MessageHeader::size, and unsalt_key().

2182 {
2183  struct Operation *op = cls;
2184  const struct IBF_Key *ibf_key;
2185  unsigned int num_keys;
2186 
2188  "Received union inquiry\n");
2189  num_keys = (ntohs (msg->header.size) - sizeof(struct InquiryMessage))
2190  / sizeof(struct IBF_Key);
2191  ibf_key = (const struct IBF_Key *) &msg[1];
2192  while (0 != num_keys--)
2193  {
2194  struct IBF_Key unsalted_key;
2195 
2196  unsalt_key (ibf_key,
2197  ntohl (msg->salt),
2198  &unsalted_key);
2199  send_offers_for_key (op,
2200  unsalted_key);
2201  ibf_key++;
2202  }
2204 }
static void send_offers_for_key(struct Operation *op, struct IBF_Key ibf_key)
Send offers (in the form of GNUNET_Hash-es) to the remote peer for the given IBF key.
static void unsalt_key(const struct IBF_Key *k_in, uint32_t salt, struct IBF_Key *k_out)
FIXME.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define LOG(kind,...)
Operation context used to execute a set operation.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888
struct GNUNET_CADET_Channel * channel
Channel to the peer.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:45
uint32_t salt
Salt used when hashing elements for this inquiry.
Here is the call graph for this function:

◆ send_missing_full_elements_iter()

static int send_missing_full_elements_iter ( void *  cls,
uint32_t  key,
void *  value 
)
static

Iterator over hash map entries, called to destroy the linked list of colliding ibf key entries.

Parameters
clsclosure
keycurrent key code
valuevalue in the hash map
Returns
GNUNET_YES if we should continue to iterate, GNUNET_NO if not.

Definition at line 2218 of file gnunet-service-setu.c.

References GNUNET_SET_Element::data, ElementEntry::element, KeyEntry::element, GNUNET_SET_Element::element_type, GNUNET_SETU_ElementMessage::element_type, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_YES, Operation::mq, KeyEntry::received, GNUNET_SET_Element::size, and value.

Referenced by handle_union_p2p_full_done().

2221 {
2222  struct Operation *op = cls;
2223  struct KeyEntry *ke = value;
2224  struct GNUNET_MQ_Envelope *ev;
2225  struct GNUNET_SETU_ElementMessage *emsg;
2226  struct ElementEntry *ee = ke->element;
2227 
2228  if (GNUNET_YES == ke->received)
2229  return GNUNET_YES;
2230  ev = GNUNET_MQ_msg_extra (emsg,
2231  ee->element.size,
2233  GNUNET_memcpy (&emsg[1],
2234  ee->element.data,
2235  ee->element.size);
2236  emsg->element_type = htons (ee->element.element_type);
2237  GNUNET_MQ_send (op->mq,
2238  ev);
2239  return GNUNET_YES;
2240 }
int received
Did we receive this element? Even if element->is_foreign is false, we might have received the element...
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
const void * data
Actual data of the element.
The key entry is used to associate an ibf key with an element.
uint16_t element_type
Type of the element to add or remove.
Definition: setu.h:285
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
static char * value
Value of the record to add/remove.
Information about an element element in the set.
struct ElementEntry * element
The actual element associated with the key.
#define GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT
Send a set element, not as response to a demand but because we&#39;re sending the full set...
Message sent by client to the service to add an element to the set.
Definition: setu.h:275
Operation context used to execute a set operation.
uint16_t size
Number of bytes in the buffer pointed to by data.
struct GNUNET_SET_Element element
The actual element.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
uint16_t element_type
Application-specific element type.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_union_p2p_request_full()

static void handle_union_p2p_request_full ( void *  cls,
const struct GNUNET_MessageHeader mh 
)
static

Handle a request for full set transmission.

cls closure, a set union operation

Parameters
mhthe demand message

Definition at line 2250 of file gnunet-service-setu.c.

References Operation::channel, fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, LOG, Operation::phase, PHASE_EXPECT_IBF, and send_full_set().

2252 {
2253  struct Operation *op = cls;
2254 
2256  "Received request for full set transmission\n");
2257  if (PHASE_EXPECT_IBF != op->phase)
2258  {
2259  GNUNET_break_op (0);
2260  fail_union_operation (op);
2261  return;
2262  }
2263 
2264  // FIXME: we need to check that our set is larger than the
2265  // byzantine_lower_bound by some threshold
2266  send_full_set (op);
2268 }
static void send_full_set(struct Operation *op)
Switch to full set transmission for op.
enum IntersectionOperationPhase phase
Current state of the operation.
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
We sent the strata estimator, and expect an IBF.
#define LOG(kind,...)
Operation context used to execute a set operation.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888
struct GNUNET_CADET_Channel * channel
Channel to the peer.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Here is the call graph for this function:

◆ handle_union_p2p_full_done()

static void handle_union_p2p_full_done ( void *  cls,
const struct GNUNET_MessageHeader mh 
)
static

Handle a "full done" message.

cls closure, a set union operation

Parameters
mhthe demand message

Definition at line 2278 of file gnunet-service-setu.c.

References _GSS_operation_destroy2(), Operation::channel, fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_multihashmap32_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE, GNUNET_MQ_msg_header, GNUNET_MQ_send(), Operation::key_to_element, LOG, Operation::mq, Operation::phase, PHASE_DONE, PHASE_EXPECT_IBF, PHASE_FULL_SENDING, send_client_done(), and send_missing_full_elements_iter().

2280 {
2281  struct Operation *op = cls;
2282 
2283  switch (op->phase)
2284  {
2285  case PHASE_EXPECT_IBF:
2286  {
2287  struct GNUNET_MQ_Envelope *ev;
2288 
2290  "got FULL DONE, sending elements that other peer is missing\n");
2291 
2292  /* send all the elements that did not come from the remote peer */
2295  op);
2297  GNUNET_MQ_send (op->mq,
2298  ev);
2299  op->phase = PHASE_DONE;
2300  /* we now wait until the other peer sends us the OVER message*/
2301  }
2302  break;
2303 
2304  case PHASE_FULL_SENDING:
2305  {
2307  "got FULL DONE, finishing\n");
2308  /* We sent the full set, and got the response for that. We're done. */
2309  op->phase = PHASE_DONE;
2311  send_client_done (op);
2313  return;
2314  }
2315  break;
2316 
2317  default:
2319  "Handle full done phase is %u\n",
2320  (unsigned) op->phase);
2321  GNUNET_break_op (0);
2322  fail_union_operation (op);
2323  return;
2324  }
2326 }
After sending the full set, wait for responses with the elements that the local peer is missing...
enum IntersectionOperationPhase phase
Current state of the operation.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
static void _GSS_operation_destroy2(struct Operation *op)
This function probably should not exist and be replaced by inlining more specific logic in the variou...
static void send_client_done(void *cls)
Signal to the client that the operation has finished and destroy the operation.
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
We sent the strata estimator, and expect an IBF.
#define GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE
Request all missing elements from the other peer, based on their sets and the elements we previously ...
#define LOG(kind,...)
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
Operation context used to execute a set operation.
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
Definition: gnunet_mq_lib.h:76
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888
static int send_missing_full_elements_iter(void *cls, uint32_t key, void *value)
Iterator over hash map entries, called to destroy the linked list of colliding ibf key entries...
struct GNUNET_CADET_Channel * channel
Channel to the peer.
#define GNUNET_log(kind,...)
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
In the ultimate phase, we wait until our demands are satisfied and then quit (sending another DONE me...
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
Here is the call graph for this function:

◆ check_union_p2p_demand()

static int check_union_p2p_demand ( void *  cls,
const struct GNUNET_MessageHeader mh 
)
static

Check a demand by the other peer for elements based on a list of struct GNUNET_HashCodes.

cls closure, a set union operation

Parameters
mhthe demand message
Returns
GNUNET_OK if mh is well-formed

Definition at line 2338 of file gnunet-service-setu.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, and GNUNET_MessageHeader::size.

2340 {
2341  struct Operation *op = cls;
2342  unsigned int num_hashes;
2343 
2344  (void) op;
2345  num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
2346  / sizeof(struct GNUNET_HashCode);
2347  if ((ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
2348  != num_hashes * sizeof(struct GNUNET_HashCode))
2349  {
2350  GNUNET_break_op (0);
2351  return GNUNET_SYSERR;
2352  }
2353  return GNUNET_OK;
2354 }
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
A 512-bit hashcode.
Operation context used to execute a set operation.
Header for all communications.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144

◆ handle_union_p2p_demand()

static void handle_union_p2p_demand ( void *  cls,
const struct GNUNET_MessageHeader mh 
)
static

Handle a demand by the other peer for elements based on a list of struct GNUNET_HashCodes.

cls closure, a set union operation

Parameters
mhthe demand message

Definition at line 2365 of file gnunet-service-setu.c.

References _GSS_is_element_of_operation(), Operation::channel, Set::content, GNUNET_SET_Element::data, ElementEntry::element, ElementEntry::element_hash, GNUNET_SET_Element::element_type, GNUNET_SETU_ElementMessage::element_type, SetContent::elements, fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SETU_P2P_ELEMENTS, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_SET_STATUS_ADD_REMOTE, GNUNET_STATISTICS_update(), LOG, GNUNET_SETU_ElementMessage::reserved, send_client_element(), Operation::set, GNUNET_SET_Element::size, and GNUNET_MessageHeader::size.

2367 {
2368  struct Operation *op = cls;
2369  struct ElementEntry *ee;
2370  struct GNUNET_SETU_ElementMessage *emsg;
2371  const struct GNUNET_HashCode *hash;
2372  unsigned int num_hashes;
2373  struct GNUNET_MQ_Envelope *ev;
2374 
2375  num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
2376  / sizeof(struct GNUNET_HashCode);
2377  for (hash = (const struct GNUNET_HashCode *) &mh[1];
2378  num_hashes > 0;
2379  hash++, num_hashes--)
2380  {
2382  hash);
2383  if (NULL == ee)
2384  {
2385  /* Demand for non-existing element. */
2386  GNUNET_break_op (0);
2387  fail_union_operation (op);
2388  return;
2389  }
2390  if (GNUNET_NO == _GSS_is_element_of_operation (ee, op))
2391  {
2392  /* Probably confused lazily copied sets. */
2393  GNUNET_break_op (0);
2394  fail_union_operation (op);
2395  return;
2396  }
2397  ev = GNUNET_MQ_msg_extra (emsg,
2398  ee->element.size,
2400  GNUNET_memcpy (&emsg[1],
2401  ee->element.data,
2402  ee->element.size);
2403  emsg->reserved = htons (0);
2404  emsg->element_type = htons (ee->element.element_type);
2406  "[OP %x] Sending demanded element (size %u, hash %s) to peer\n",
2407  (void *) op,
2408  (unsigned int) ee->element.size,
2409  GNUNET_h2s (&ee->element_hash));
2410  GNUNET_MQ_send (op->mq, ev);
2412  "# exchanged elements",
2413  1,
2414  GNUNET_NO);
2415  if (op->symmetric)
2416  send_client_element (op,
2417  &ee->element,
2419  }
2420  GNUNET_CADET_receive_done (op->channel);
2421 }
Element should be added to the result set of the remote peer, i.e.
uint16_t reserved
For alignment, always zero.
Definition: setu.h:290
static void send_client_element(struct Operation *op, const struct GNUNET_SETU_Element *element, enum GNUNET_SETU_Status status)
Send a result message to the client indicating that there is a new element.
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
const void * data
Actual data of the element.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
uint16_t element_type
Type of the element to add or remove.
Definition: setu.h:285
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
Information about an element element in the set.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
A 512-bit hashcode.
#define LOG(kind,...)
Message sent by client to the service to add an element to the set.
Definition: setu.h:275
Operation context used to execute a set operation.
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
uint16_t size
Number of bytes in the buffer pointed to by data.
struct GNUNET_SET_Element element
The actual element.
Header for all communications.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static int _GSS_is_element_of_operation(struct ElementEntry *ee, struct Operation *op)
Is element ee part of the set used by op?
#define GNUNET_MESSAGE_TYPE_SETU_P2P_ELEMENTS
Actual set elements.
uint16_t element_type
Application-specific element type.
Here is the call graph for this function:

◆ check_union_p2p_offer()

static int check_union_p2p_offer ( void *  cls,
const struct GNUNET_MessageHeader mh 
)
static

Check offer (of struct GNUNET_HashCodes).

Parameters
clsthe union operation
mhthe message
Returns
GNUNET_OK if mh is well-formed

Definition at line 2432 of file gnunet-service-setu.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, Operation::phase, PHASE_INVENTORY_ACTIVE, PHASE_INVENTORY_PASSIVE, and GNUNET_MessageHeader::size.

2434 {
2435  struct Operation *op = cls;
2436  unsigned int num_hashes;
2437 
2438  /* look up elements and send them */
2439  if ((op->phase != PHASE_INVENTORY_PASSIVE) &&
2440  (op->phase != PHASE_INVENTORY_ACTIVE))
2441  {
2442  GNUNET_break_op (0);
2443  return GNUNET_SYSERR;
2444  }
2445  num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
2446  / sizeof(struct GNUNET_HashCode);
2447  if ((ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader)) !=
2448  num_hashes * sizeof(struct GNUNET_HashCode))
2449  {
2450  GNUNET_break_op (0);
2451  return GNUNET_SYSERR;
2452  }
2453  return GNUNET_OK;
2454 }
enum IntersectionOperationPhase phase
Current state of the operation.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
The other peer is decoding the IBF we just sent.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
We are decoding an IBF.
A 512-bit hashcode.
Operation context used to execute a set operation.
Header for all communications.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144

◆ handle_union_p2p_offer()

static void handle_union_p2p_offer ( void *  cls,
const struct GNUNET_MessageHeader mh 
)
static

Handle offers (of struct GNUNET_HashCodes) and respond with demands (of struct GNUNET_HashCodes).

Parameters
clsthe union operation
mhthe message

Definition at line 2465 of file gnunet-service-setu.c.

References _GSS_is_element_of_operation(), Operation::channel, Set::content, Operation::demanded_hashes, SetContent::elements, GNUNET_assert, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SETU_P2P_DEMAND, GNUNET_MQ_msg_header_extra, GNUNET_MQ_send(), GNUNET_OK, GNUNET_YES, LOG, Operation::set, and GNUNET_MessageHeader::size.

2467 {
2468  struct Operation *op = cls;
2469  const struct GNUNET_HashCode *hash;
2470  unsigned int num_hashes;
2471 
2472  num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
2473  / sizeof(struct GNUNET_HashCode);
2474  for (hash = (const struct GNUNET_HashCode *) &mh[1];
2475  num_hashes > 0;
2476  hash++, num_hashes--)
2477  {
2478  struct ElementEntry *ee;
2479  struct GNUNET_MessageHeader *demands;
2480  struct GNUNET_MQ_Envelope *ev;
2481 
2483  hash);
2484  if (NULL != ee)
2485  if (GNUNET_YES == _GSS_is_element_of_operation (ee, op))
2486  continue;
2487 
2488  if (GNUNET_YES ==
2490  hash))
2491  {
2493  "Skipped sending duplicate demand\n");
2494  continue;
2495  }
2496 
2499  op->demanded_hashes,
2500  hash,
2501  NULL,
2503 
2505  "[OP %x] Requesting element (hash %s)\n",
2506  (void *) op, GNUNET_h2s (hash));
2507  ev = GNUNET_MQ_msg_header_extra (demands,
2508  sizeof(struct GNUNET_HashCode),
2510  GNUNET_memcpy (&demands[1],
2511  hash,
2512  sizeof(struct GNUNET_HashCode));
2513  GNUNET_MQ_send (op->mq, ev);
2514  }
2515  GNUNET_CADET_receive_done (op->channel);
2516 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
, &#39; bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_...
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
Information about an element element in the set.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
A 512-bit hashcode.
#define LOG(kind,...)
#define GNUNET_MQ_msg_header_extra(mh, esize, type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header and extra space...
Definition: gnunet_mq_lib.h:88
Operation context used to execute a set operation.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
Header for all communications.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
#define GNUNET_MESSAGE_TYPE_SETU_P2P_DEMAND
Demand the whole element from the other peer, given only the hash code.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static int _GSS_is_element_of_operation(struct ElementEntry *ee, struct Operation *op)
Is element ee part of the set used by op?
Here is the call graph for this function:

◆ handle_union_p2p_done()

static void handle_union_p2p_done ( void *  cls,
const struct GNUNET_MessageHeader mh 
)
static

Handle a done message from a remote peer.

Parameters
clsthe union operation
mhthe message

Definition at line 2526 of file gnunet-service-setu.c.

References Operation::channel, fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, LOG, maybe_finish(), Operation::phase, PHASE_FINISH_CLOSING, PHASE_FINISH_WAITING, PHASE_INVENTORY_ACTIVE, and PHASE_INVENTORY_PASSIVE.

2528 {
2529  struct Operation *op = cls;
2530 
2531  switch (op->phase)
2532  {
2534  /* We got all requests, but still have to send our elements in response. */
2537  "got DONE (as passive partner), waiting for our demands to be satisfied\n");
2538  /* The active peer is done sending offers
2539  * and inquiries. This means that all
2540  * our responses to that (demands and offers)
2541  * must be in flight (queued or in mesh).
2542  *
2543  * We should notify the active peer once
2544  * all our demands are satisfied, so that the active
2545  * peer can quit if we gave it everything.
2547  maybe_finish (op);
2548  return;
2551  "got DONE (as active partner), waiting to finish\n");
2552  /* All demands of the other peer are satisfied,
2553  * and we processed all offers, thus we know
2554  * exactly what our demands must be.
2555  *
2556  * We'll close the channel
2557  * to the other peer once our demands are met.
2558  */op->phase = PHASE_FINISH_CLOSING;
2560  maybe_finish (op);
2561  return;
2562  default:
2563  GNUNET_break_op (0);
2564  fail_union_operation (op);
2565  return;
2566  }
2567 }
static void maybe_finish(struct Operation *op)
Tests if the operation is finished, and if so notify.
enum IntersectionOperationPhase phase
Current state of the operation.
The protocol is almost finished, but we still have to flush our message queue and/or expect some elem...
The other peer is decoding the IBF we just sent.
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
We are decoding an IBF.
In the penultimate phase, we wait until all our demands are satisfied.
#define LOG(kind,...)
Operation context used to execute a set operation.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888
struct GNUNET_CADET_Channel * channel
Channel to the peer.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Here is the call graph for this function:

◆ handle_union_p2p_over()

static void handle_union_p2p_over ( void *  cls,
const struct GNUNET_MessageHeader mh 
)
static

Handle a over message from a remote peer.

Parameters
clsthe union operation
mhthe message

Definition at line 2577 of file gnunet-service-setu.c.

References send_client_done().

2579 {
2580  send_client_done (cls);
2581 }
static void send_client_done(void *cls)
Signal to the client that the operation has finished and destroy the operation.
Here is the call graph for this function:

◆ get_incoming()

static struct Operation* get_incoming ( uint32_t  id)
static

Get the incoming socket associated with the given id.

Parameters
listenerthe listener to look in
idid to look for
Returns
the incoming socket associated with the id, or NULL if there is none

Definition at line 2593 of file gnunet-service-setu.c.

References Operation::listener, Listener::next, Operation::next, op, Listener::op_head, and Operation::suggest_id.

Referenced by handle_client_accept(), and handle_client_reject().

2594 {
2595  for (struct Listener *listener = listener_head;
2596  NULL != listener;
2597  listener = listener->next)
2598  {
2599  for (struct Operation *op = listener->op_head;
2600  NULL != op;
2601  op = op->next)
2602  if (op->suggest_id == id)
2603  return op;
2604  }
2605  return NULL;
2606 }
struct GNUNET_ARM_Operation * next
This is a doubly-linked list.
Definition: arm_api.c:45
struct Listener * next
Listeners are held in a doubly linked list.
struct Operation * op_head
Head of DLL of operations this listener is responsible for.
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
Operation context used to execute a set operation.
static struct Listener * listener_head
Listeners are held in a doubly linked list.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct Listener * listener
Port this operation runs on.
Here is the caller graph for this function:

◆ client_connect_cb()

static void* client_connect_cb ( void *  cls,
struct GNUNET_SERVICE_Client c,
struct GNUNET_MQ_Handle mq 
)
static

Callback called when a client connects to the service.

Parameters
clsclosure for the service
cthe new client that connected to the service
mqthe message queue used to send messages to the client
Returns
struct ClientState

Definition at line 2618 of file gnunet-service-setu.c.

References ClientState::client, GNUNET_new, mq, ClientState::mq, and num_clients.

Referenced by run().

2621 {
2622  struct ClientState *cs;
2623 
2624  num_clients++;
2625  cs = GNUNET_new (struct ClientState);
2626  cs->client = c;
2627  cs->mq = mq;
2628  return cs;
2629 }
State we keep per client.
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static unsigned int num_clients
Number of active clients.
struct GNUNET_SERVICE_Client * client
Client this is about.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
Here is the caller graph for this function:

◆ destroy_elements_iterator()

static int destroy_elements_iterator ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Iterator over hash map entries to free element entries.

Parameters
clsclosure
keycurrent key code
valuea struct ElementEntry * to be free'd
Returns
GNUNET_YES (continue to iterate)

Definition at line 2641 of file gnunet-service-setu.c.

References GNUNET_free, GNUNET_YES, and value.

Referenced by client_disconnect_cb().

2644 {
2645  struct ElementEntry *ee = value;
2646 
2647  GNUNET_free (ee);
2648  return GNUNET_YES;
2649 }
static char * value
Value of the record to add/remove.
Information about an element element in the set.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function:

◆ client_disconnect_cb()

static void client_disconnect_cb ( void *  cls,
struct GNUNET_SERVICE_Client client,
void *  internal_cls 
)
static

Clean up after a client has disconnected.

Parameters
clsclosure, unused
clientthe client to clean up after
internal_clsthe struct ClientState

Definition at line 2660 of file gnunet-service-setu.c.

References _GSS_operation_destroy(), Operation::client_request_id, destroy_elements_iterator(), SetContent::elements, GNUNET_assert, GNUNET_CADET_close_port(), GNUNET_CADET_disconnect(), GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_YES, in_shutdown, incoming_destroy(), ClientState::listener, num_clients, op, Listener::op_head, Listener::open_port, Operation::peer, SetContent::refcount, ClientState::set, and strata_estimator_destroy().

Referenced by run().

2663 {
2664  struct ClientState *cs = internal_cls;
2665  struct Operation *op;
2666  struct Listener *listener;
2667  struct Set *set;
2668 
2670  "Client disconnected, cleaning up\n");
2671  if (NULL != (set = cs->set))
2672  {
2673  struct SetContent *content = set->content;
2674 
2676  "Destroying client's set\n");
2677  /* Destroy pending set operations */
2678  while (NULL != set->ops_head)
2679  _GSS_operation_destroy (set->ops_head);
2680 
2681  /* Destroy operation-specific state */
2682  if (NULL != set->se)
2683  {
2684  strata_estimator_destroy (set->se);
2685  set->se = NULL;
2686  }
2687  /* free set content (or at least decrement RC) */
2688  set->content = NULL;
2689  GNUNET_assert (0 != content->refcount);
2690  content->refcount--;
2691  if (0 == content->refcount)
2692  {
2693  GNUNET_assert (NULL != content->elements);
2696  NULL);
2698  content->elements = NULL;
2699  GNUNET_free (content);
2700  }
2701  GNUNET_free (set);
2702  }
2703 
2704  if (NULL != (listener = cs->listener))
2705  {
2707  "Destroying client's listener\n");
2708  GNUNET_CADET_close_port (listener->open_port);
2709  listener->open_port = NULL;
2710  while (NULL != (op = listener->op_head))
2711  {
2713  "Destroying incoming operation `%u' from peer `%s'\n",
2714  (unsigned int) op->client_request_id,
2715  GNUNET_i2s (&op->peer));
2716  incoming_destroy (op);
2717  }
2719  listener_tail,
2720  listener);
2721  GNUNET_free (listener);
2722  }
2723  GNUNET_free (cs);
2724  num_clients--;
2725  if ( (GNUNET_YES == in_shutdown) &&
2726  (0 == num_clients) )
2727  {
2728  if (NULL != cadet)
2729  {
2731  cadet = NULL;
2732  }
2733  }
2734 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:775
struct Set * set
Set, if associated with the client, otherwise NULL.
State we keep per client.
unsigned int refcount
Number of references to the content.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct Listener * listener_tail
Listeners are held in a doubly linked list.
struct Operation * op_head
Head of DLL of operations this listener is responsible for.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
static struct GNUNET_CADET_Handle * cadet
Handle to the cadet service, used to listen for and connect to remote peers.
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
static unsigned int num_clients
Number of active clients.
static void _GSS_operation_destroy(struct Operation *op)
Destroy the given operation.
struct GNUNET_PeerIdentity peer
The identity of the requesting peer.
static int destroy_elements_iterator(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over hash map entries to free element entries.
void strata_estimator_destroy(struct StrataEstimator *se)
Destroy a strata estimator, free all of its resources.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
A set that supports a specific operation with other peers.
struct GNUNET_CADET_Port * open_port
The port we are listening on with CADET.
Operation context used to execute a set operation.
SetContent stores the actual set elements, which may be shared by multiple generations derived from o...
static void incoming_destroy(struct Operation *op)
Destroy an incoming request from a remote peer.
uint32_t client_request_id
ID used to identify an operation between service and client.
static int in_shutdown
Are we in shutdown? if GNUNET_YES and the number of clients drops to zero, disconnect from CADET...
#define GNUNET_log(kind,...)
static struct Listener * listener_head
Listeners are held in a doubly linked list.
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port().
Definition: cadet_api.c:808
struct Listener * listener
Listener, if associated with the client, otherwise NULL.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_incoming_msg()

static int check_incoming_msg ( void *  cls,
const struct OperationRequestMessage msg 
)
static

Check a request for a set operation from another peer.

Parameters
clsthe operation state
msgthe received message
Returns
GNUNET_OK if the channel should be kept alive, GNUNET_SYSERR to destroy the channel

Definition at line 2746 of file gnunet-service-setu.c.

References GNUNET_break, GNUNET_break_op, GNUNET_MQ_extract_nested_mh, GNUNET_OK, GNUNET_SETU_CONTEXT_MESSAGE_MAX_SIZE, GNUNET_SYSERR, Operation::listener, GNUNET_MessageHeader::size, and Operation::suggest_id.

2748 {
2749  struct Operation *op = cls;
2750  struct Listener *listener = op->listener;
2751  const struct GNUNET_MessageHeader *nested_context;
2752 
2753  /* double operation request */
2754  if (0 != op->suggest_id)
2755  {
2756  GNUNET_break_op (0);
2757  return GNUNET_SYSERR;
2758  }
2759  /* This should be equivalent to the previous condition, but can't hurt to check twice */
2760  if (NULL == listener)
2761  {
2762  GNUNET_break (0);
2763  return GNUNET_SYSERR;
2764  }
2765  nested_context = GNUNET_MQ_extract_nested_mh (msg);
2766  if ((NULL != nested_context) &&
2767  (ntohs (nested_context->size) > GNUNET_SETU_CONTEXT_MESSAGE_MAX_SIZE))
2768  {
2769  GNUNET_break_op (0);
2770  return GNUNET_SYSERR;
2771  }
2772  return GNUNET_OK;
2773 }
uint32_t suggest_id
Unique request id for the request from a remote peer, sent to the client, which will accept or reject...
#define GNUNET_MQ_extract_nested_mh(var)
Return a pointer to the message at the end of the given message.
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SETU_CONTEXT_MESSAGE_MAX_SIZE
Maximum size of a context message for set operation requests.
Operation context used to execute a set operation.
Header for all communications.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct Listener * listener
Port this operation runs on.

◆ handle_incoming_msg()

static void handle_incoming_msg ( void *  cls,
const struct OperationRequestMessage msg 
)
static

Handle a request for a set operation from another peer.

Checks if we have a listener waiting for such a request (and in that case initiates asking the listener about accepting the connection). If no listener is waiting, we queue the operation request in hope that a listener shows up soon (before timeout).

This msg is expected as the first and only msg handled through the non-operation bound virtual table, acceptance of this operation replaces our virtual table and subsequent msgs would be routed differently (as we then know what type of operation this is).

Parameters
clsthe operation state
msgthe received message
Returns
GNUNET_OK if the channel should be kept alive, GNUNET_SYSERR to destroy the channel

Definition at line 2794 of file gnunet-service-setu.c.

References GNUNET_SETU_RequestMessage::accept_id, Listener::app_id, Operation::context_msg, Listener::cs, OperationRequestMessage::element_count, env, GNUNET_assert, GNUNET_copy_message(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_SETU_REQUEST, GNUNET_MQ_extract_nested_mh, GNUNET_MQ_msg_nested_mh, GNUNET_MQ_send(), GNUNET_SCHEDULER_cancel(), Operation::listener, ClientState::mq, Operation::peer, GNUNET_SETU_RequestMessage::peer_id, Operation::remote_element_count, Operation::suggest_id, suggest_id, and Operation::timeout_task.

2796 {
2797  struct Operation *op = cls;
2798  struct Listener *listener = op->listener;
2799  const struct GNUNET_MessageHeader *nested_context;
2800  struct GNUNET_MQ_Envelope *env;
2801  struct GNUNET_SETU_RequestMessage *cmsg;
2802 
2803  nested_context = GNUNET_MQ_extract_nested_mh (msg);
2804  /* Make a copy of the nested_context (application-specific context
2805  information that is opaque to set) so we can pass it to the
2806  listener later on */
2807  if (NULL != nested_context)
2808  op->context_msg = GNUNET_copy_message (nested_context);
2809  op->remote_element_count = ntohl (msg->element_count);
2810  GNUNET_log (
2812  "Received P2P operation request (port %s) for active listener\n",
2813  GNUNET_h2s (&op->listener->app_id));
2814  GNUNET_assert (0 == op->suggest_id);
2815  if (0 == suggest_id)
2816  suggest_id++;
2817  op->suggest_id = suggest_id++;
2818  GNUNET_assert (NULL != op->timeout_task);
2820  op->timeout_task = NULL;
2821  env = GNUNET_MQ_msg_nested_mh (cmsg,
2823  op->context_msg);
2824  GNUNET_log (
2826  "Suggesting incoming request with accept id %u to listener %p of client %p\n",
2827  op->suggest_id,
2828  listener,
2829  listener->cs);
2830  cmsg->accept_id = htonl (op->suggest_id);
2831  cmsg->peer_id = op->peer;
2832  GNUNET_MQ_send (listener->cs->mq,
2833  env);
2834  /* NOTE: GNUNET_CADET_receive_done() will be called in
2835  #handle_client_accept() */
2836 }
#define GNUNET_MESSAGE_TYPE_SETU_REQUEST
Notify the client of an incoming request from a remote peer.
struct GNUNET_MessageHeader * context_msg
Context message, may be NULL.
uint32_t suggest_id
Unique request id for the request from a remote peer, sent to the client, which will accept or reject...
uint32_t element_count
For Intersection: my element count.
#define GNUNET_MQ_msg_nested_mh(mvar, type, mh)
Allocate a GNUNET_MQ_Envelope, and append a payload message after the given message struct...
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
#define GNUNET_MQ_extract_nested_mh(var)
Return a pointer to the message at the end of the given message.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
struct GNUNET_SCHEDULER_Task * timeout_task
Timeout task, if the incoming peer has not been accepted after the timeout, it will be disconnected...
struct GNUNET_PeerIdentity peer
The identity of the requesting peer.
uint32_t accept_id
ID of the to identify the request when accepting or rejecting it.
Definition: setu.h:159
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
Operation context used to execute a set operation.
A request for an operation with another client.
Definition: setu.h:148
static uint32_t suggest_id
Counter for allocating unique IDs for clients, used to identify incoming operation requests from remo...
struct GNUNET_PeerIdentity peer_id
Identity of the requesting peer.
Definition: setu.h:164
#define GNUNET_log(kind,...)
struct GNUNET_HashCode app_id
Application ID for the operation, used to distinguish multiple operations of the same type with the s...
Header for all communications.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
struct ClientState * cs
Client that owns the listener.
uint32_t remote_element_count
Remote peers element count.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct Listener * listener
Port this operation runs on.
struct GNUNET_MessageHeader * GNUNET_copy_message(const struct GNUNET_MessageHeader *msg)
Create a copy of the given message.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
Here is the call graph for this function:

◆ handle_client_create_set()

static void handle_client_create_set ( void *  cls,
const struct GNUNET_SETU_CreateMessage msg 
)
static

Called when a client wants to create a new set.

This is typically the first request from a client, and includes the type of set operation to be performed.

Parameters
clsclient that sent the message
mmessage sent by the client

Definition at line 2848 of file gnunet-service-setu.c.

References ClientState::client, GNUNET_break, GNUNET_CONTAINER_multihashmap_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_new, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_YES, SE_IBF_HASH_NUM, SE_IBF_SIZE, SE_STRATA_COUNT, ClientState::set, and strata_estimator_create().

2850 {
2851  struct ClientState *cs = cls;
2852  struct Set *set;
2853 
2855  "Client created new set for union operation\n");
2856  if (NULL != cs->set)
2857  {
2858  /* There can only be one set per client */
2859  GNUNET_break (0);
2861  return;
2862  }
2863  set = GNUNET_new (struct Set);
2864  {
2865  struct StrataEstimator *se;
2866 
2868  SE_IBF_SIZE,
2869  SE_IBF_HASH_NUM);
2870  if (NULL == se)
2871  {
2873  "Failed to allocate strata estimator\n");
2874  GNUNET_free (set);
2876  return;
2877  }
2878  set->se = se;
2879  }
2880  set->content = GNUNET_new (struct SetContent);
2881  set->content->refcount = 1;
2882  set->content->elements = GNUNET_CONTAINER_multihashmap_create (1,
2883  GNUNET_YES);
2884  set->cs = cs;
2885  cs->set = set;
2887 }
struct Set * set
Set, if associated with the client, otherwise NULL.
State we keep per client.
#define SE_IBF_HASH_NUM
The hash num parameter for the difference digests and strata estimators.
struct StrataEstimator * strata_estimator_create(unsigned int strata_count, uint32_t ibf_size, uint8_t ibf_hashnum)
Create a new strata estimator with the given parameters.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define SE_IBF_SIZE
Size of the IBFs in the strata estimator.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
A handle to a strata estimator.
A set that supports a specific operation with other peers.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2323
SetContent stores the actual set elements, which may be shared by multiple generations derived from o...
struct GNUNET_SERVICE_Client * client
Client this is about.
#define GNUNET_log(kind,...)
#define SE_STRATA_COUNT
Number of IBFs in a strata estimator.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2242
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:

◆ incoming_timeout_cb()

static void incoming_timeout_cb ( void *  cls)
static

Timeout happens iff:

Parameters
clschannel context
tccontext information (why was this task triggered now)

Definition at line 2900 of file gnunet-service-setu.c.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, incoming_destroy(), and Operation::timeout_task.

Referenced by channel_new_cb().

2901 {
2902  struct Operation *op = cls;
2903 
2904  op->timeout_task = NULL;
2906  "Remote peer's incoming request timed out\n");
2907  incoming_destroy (op);
2908 }
struct GNUNET_SCHEDULER_Task * timeout_task
Timeout task, if the incoming peer has not been accepted after the timeout, it will be disconnected...
Definition: gnunet-se