GNUnet  0.10.x
Data Structures | Macros | Enumerations | Functions
gnunet-service-set_union.c File Reference

two-peer set operations More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_statistics_service.h"
#include "gnunet-service-set.h"
#include "ibf.h"
#include "gnunet-service-set_union.h"
#include "gnunet-service-set_union_strata_estimator.h"
#include "gnunet-service-set_protocol.h"
#include <gcrypt.h>
Include dependency graph for gnunet-service-set_union.c:

Go to the source code of this file.

Data Structures

struct  OperationState
 State of an evaluate operation with another peer. 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  SetState
 Extra state required for efficient set intersection. More...
 
struct  GetElementContext
 Context for op_get_element_iterator. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "set-union",__VA_ARGS__)
 
#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
}
 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 union_op_cancel (struct Operation *op)
 Destroy the union operation. 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 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...
 
int check_union_p2p_strata_estimator (void *cls, const struct StrataEstimatorMessage *msg)
 Handle a strata estimator from a remote peer. More...
 
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...
 
int check_union_p2p_ibf (void *cls, const struct IBFMessage *msg)
 Check an IBF message from a remote peer. More...
 
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, struct GNUNET_SET_Element *element, int status)
 Send a result message to the client indicating that there is a new element. More...
 
static void send_client_done (void *cls)
 Signal to the client that the operation has finished and destroy the operation. More...
 
static void maybe_finish (struct Operation *op)
 Tests if the operation is finished, and if so notify. More...
 
int check_union_p2p_elements (void *cls, const struct GNUNET_SET_ElementMessage *emsg)
 Check an element message from a remote peer. More...
 
void handle_union_p2p_elements (void *cls, const struct GNUNET_SET_ElementMessage *emsg)
 Handle an element message from a remote peer. More...
 
int check_union_p2p_full_element (void *cls, const struct GNUNET_SET_ElementMessage *emsg)
 Check a full element message from a remote peer. More...
 
void handle_union_p2p_full_element (void *cls, const struct GNUNET_SET_ElementMessage *emsg)
 Handle an element message from a remote peer. More...
 
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...
 
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...
 
void handle_union_p2p_request_full (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a request for full set transmission. More...
 
void handle_union_p2p_full_done (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a "full done" message. More...
 
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...
 
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...
 
int check_union_p2p_offer (void *cls, const struct GNUNET_MessageHeader *mh)
 Check offer (of struct GNUNET_HashCodes). More...
 
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...
 
void handle_union_p2p_done (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a done message from a remote peer. More...
 
void handle_union_p2p_over (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a over message from a remote peer. More...
 
static struct OperationStateunion_evaluate (struct Operation *op, const struct GNUNET_MessageHeader *opaque_context)
 Initiate operation to evaluate a set union with a remote peer. More...
 
static struct OperationStateunion_accept (struct Operation *op)
 Accept an union operation request from a remote peer. More...
 
static struct SetStateunion_set_create (void)
 Create a new set supporting the union operation. More...
 
static void union_add (struct SetState *set_state, struct ElementEntry *ee)
 Add the element from the given element message to the set. More...
 
static void union_remove (struct SetState *set_state, struct ElementEntry *ee)
 Remove the element given in the element message from the set. More...
 
static void union_set_destroy (struct SetState *set_state)
 Destroy a set that supports the union operation. More...
 
static struct SetStateunion_copy_state (struct SetState *state)
 Copy union-specific set state. More...
 
static void union_channel_death (struct Operation *op)
 Handle case where channel went down for an operation. More...
 
const struct SetVT_GSS_union_vt ()
 Get the table with implementing functions for set union. More...
 

Detailed Description

two-peer set operations

Author
Florian Dold
Christian Grothoff

Definition in file gnunet-service-set_union.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "set-union",__VA_ARGS__)

◆ SE_STRATA_COUNT

#define SE_STRATA_COUNT   32

Number of IBFs in a strata estimator.

Definition at line 43 of file gnunet-service-set_union.c.

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

◆ SE_IBF_SIZE

#define SE_IBF_SIZE   80

Size of the IBFs in the strata estimator.

Definition at line 48 of file gnunet-service-set_union.c.

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

◆ SE_IBF_HASH_NUM

#define SE_IBF_HASH_NUM   4

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

Definition at line 53 of file gnunet-service-set_union.c.

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

◆ 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 58 of file gnunet-service-set_union.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 65 of file gnunet-service-set_union.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 71 of file gnunet-service-set_union.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.

Definition at line 77 of file gnunet-service-set_union.c.

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

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 290 of file gnunet-service-set_union.c.

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

Referenced by union_op_cancel().

293 {
294  struct KeyEntry *k = value;
295 
296  GNUNET_assert (NULL != k);
297  if (GNUNET_YES == k->element->remote)
298  {
299  GNUNET_free (k->element);
300  k->element = NULL;
301  }
302  GNUNET_free (k);
303  return GNUNET_YES;
304 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct ElementEntry * element
The actual element associated with the key.
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...
#define GNUNET_YES
Definition: gnunet_common.h:80
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function:

◆ union_op_cancel()

static void union_op_cancel ( struct Operation op)
static

Destroy the union operation.

Only things specific to the union operation are destroyed.

Parameters
opunion operation to destroy

Definition at line 314 of file gnunet-service-set_union.c.

References OperationState::demanded_hashes, destroy_key_to_element_iter(), GNUNET_assert, GNUNET_CONTAINER_multihashmap32_destroy(), GNUNET_CONTAINER_multihashmap32_iterate(), GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, ibf_destroy(), OperationState::key_to_element, OperationState::local_ibf, LOG, OperationState::remote_ibf, OperationState::se, Operation::state, and strata_estimator_destroy().

Referenced by _GSS_union_vt().

315 {
317  "destroying union op\n");
318  /* check if the op was canceled twice */
319  GNUNET_assert (NULL != op->state);
320  if (NULL != op->state->remote_ibf)
321  {
323  op->state->remote_ibf = NULL;
324  }
325  if (NULL != op->state->demanded_hashes)
326  {
328  op->state->demanded_hashes = NULL;
329  }
330  if (NULL != op->state->local_ibf)
331  {
332  ibf_destroy (op->state->local_ibf);
333  op->state->local_ibf = NULL;
334  }
335  if (NULL != op->state->se)
336  {
338  op->state->se = NULL;
339  }
340  if (NULL != op->state->key_to_element)
341  {
344  NULL);
346  op->state->key_to_element = NULL;
347  }
348  GNUNET_free (op->state);
349  op->state = NULL;
351  "destroying union op done\n");
352 }
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
#define LOG(kind,...)
struct InvertibleBloomFilter * remote_ibf
The IBF we currently receive.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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...
struct StrataEstimator * se
Copy of the set&#39;s strata estimator at the time of creation of this operation.
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.
void GNUNET_CONTAINER_multihashmap32_destroy(struct GNUNET_CONTAINER_MultiHashMap32 *map)
Destroy a 32-bit key hash map.
void ibf_destroy(struct InvertibleBloomFilter *ibf)
Destroy all resources associated with the invertible bloom filter.
Definition: ibf.c:388
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_HashMapIterator32 it, void *it_cls)
Iterate over all entries in the map.
struct InvertibleBloomFilter * local_ibf
The IBF with the local set&#39;s element.
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
struct OperationState * state
Operation-specific operation state.
#define GNUNET_free(ptr)
Wrapper around free.
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 362 of file gnunet-service-set_union.c.

References _GSS_operation_destroy(), Operation::client_request_id, Set::cs, GNUNET_SET_ResultMessage::element_type, GNUNET_ERROR_TYPE_WARNING, GNUNET_MESSAGE_TYPE_SET_RESULT, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_SET_STATUS_FAILURE, GNUNET_YES, LOG, ClientState::mq, msg, GNUNET_SET_ResultMessage::request_id, GNUNET_SET_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().

363 {
364  struct GNUNET_MQ_Envelope *ev;
366 
368  "union operation failed\n");
371  msg->request_id = htonl (op->client_request_id);
372  msg->element_type = htons (0);
373  GNUNET_MQ_send (op->set->cs->mq,
374  ev);
376 }
#define LOG(kind,...)
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: set.h:246
#define GNUNET_MESSAGE_TYPE_SET_RESULT
Create an empty set.
uint32_t request_id
id the result belongs to
Definition: set.h:261
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
void _GSS_operation_destroy(struct Operation *op, int gc)
Destroy the given operation.
The other peer refused to to the operation with us, or something went wrong.
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SET_Status in NBO.
Definition: set.h:267
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: set.h:272
uint32_t client_request_id
ID used to identify an operation between service and client.
#define GNUNET_YES
Definition: gnunet_common.h:80
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:353
struct ClientState * cs
Client that owns the set.
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 387 of file gnunet-service-set_union.c.

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

Referenced by op_get_element(), op_register_element(), union_add(), and union_remove().

388 {
389  struct IBF_Key key;
390  uint16_t salt = 0;
391 
393  GNUNET_CRYPTO_kdf (&key, sizeof (key),
394  src, sizeof *src,
395  &salt, sizeof (salt),
396  NULL, 0));
397  return key;
398 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
struct GNUNET_HashCode key
The key used in the DHT.
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:91
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 429 of file gnunet-service-set_union.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().

432 {
433  struct GetElementContext *ctx = cls;
434  struct KeyEntry *k = value;
435 
436  GNUNET_assert (NULL != k);
438  &ctx->hash))
439  {
440  ctx->k = k;
441  return GNUNET_NO;
442  }
443  return GNUNET_YES;
444 }
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 ElementEntry * element
The actual element associated with the key.
#define GNUNET_NO
Definition: gnunet_common.h:81
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 KeyEntry * k
FIXME.
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:278
#define GNUNET_YES
Definition: gnunet_common.h:80
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 456 of file gnunet-service-set_union.c.

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

Referenced by handle_union_p2p_elements(), and handle_union_p2p_full_element().

458 {
459  int ret;
460  struct IBF_Key ibf_key;
461  struct GetElementContext ctx = {{{ 0 }} , 0};
462 
463  ctx.hash = *element_hash;
464 
465  ibf_key = get_ibf_key (element_hash);
467  (uint32_t) ibf_key.key_val,
469  &ctx);
470 
471  /* was the iteration aborted because we found the element? */
472  if (GNUNET_SYSERR == ret)
473  {
474  GNUNET_assert (NULL != ctx.k);
475  return ctx.k;
476  }
477  return NULL;
478 }
Context for op_get_element_iterator.
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.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int ret
Final status code.
Definition: gnunet-arm.c:89
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
struct KeyEntry * k
FIXME.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
int GNUNET_CONTAINER_multihashmap32_get_multiple(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, GNUNET_CONTAINER_HashMapIterator32 it, void *it_cls)
Iterate over all entries in the map that match a particular key.
static struct IBF_Key get_ibf_key(const struct GNUNET_HashCode *src)
Derive the IBF key from a hash code and a salt.
struct OperationState * state
Operation-specific operation state.
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 496 of file gnunet-service-set_union.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, OperationState::key_to_element, IBF_Key::key_val, KeyEntry::received, and Operation::state.

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

499 {
500  struct IBF_Key ibf_key;
501  struct KeyEntry *k;
502 
504  k = GNUNET_new (struct KeyEntry);
505  k->element = ee;
506  k->ibf_key = ibf_key;
507  k->received = received;
510  (uint32_t) ibf_key.key_val,
511  k,
513 }
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
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.
struct ElementEntry * element
The actual element associated with the key.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#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.
struct IBF_Key ibf_key
IBF key for the entry, derived from the current salt.
Allow multiple values with the same key.
static struct IBF_Key get_ibf_key(const struct GNUNET_HashCode *src)
Derive the IBF key from a hash code and a salt.
struct OperationState * state
Operation-specific operation state.
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 520 of file gnunet-service-set_union.c.

References IBF_Key::key_val.

Referenced by prepare_ibf_iterator().

523 {
524  int s = salt % 64;
525  uint64_t x = k_in->key_val;
526  /* rotate ibf key */
527  x = (x >> s) | (x << (64 - s));
528  k_out->key_val = x;
529 }
uint64_t key_val
Definition: ibf.h:47
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 536 of file gnunet-service-set_union.c.

References IBF_Key::key_val.

Referenced by decode_and_send(), and handle_union_p2p_inquiry().

539 {
540  int s = salt % 64;
541  uint64_t x = k_in->key_val;
542  x = (x << s) | (x >> (64 - s));
543  k_out->key_val = x;
544 }
uint64_t key_val
Definition: ibf.h:47
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 555 of file gnunet-service-set_union.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, op, salt_key(), and value.

Referenced by prepare_ibf().

558 {
559  struct Operation *op = cls;
560  struct KeyEntry *ke = value;
561  struct IBF_Key salted_key;
562 
564  "[OP %x] inserting %lx (hash %s) into ibf\n",
565  (void *) op,
566  (unsigned long) ke->ibf_key.key_val,
568  salt_key (&ke->ibf_key,
569  op->state->salt_send,
570  &salted_key);
571  ibf_insert (op->state->local_ibf, salted_key);
572  return GNUNET_YES;
573 }
#define LOG(kind,...)
struct GNUNET_HashCode element_hash
Hash of the element.
struct ElementEntry * element
The actual element associated with the 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
static void salt_key(const struct IBF_Key *k_in, uint32_t salt, struct IBF_Key *k_out)
FIXME.
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.
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:164
#define GNUNET_YES
Definition: gnunet_common.h:80
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
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:

◆ 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 587 of file gnunet-service-set_union.c.

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

Referenced by initialize_key_to_element().

590 {
591  struct Operation *op = cls;
592  struct ElementEntry *ee = value;
593 
594  /* make sure that the element belongs to the set at the time
595  * of creating the operation */
596  if (GNUNET_NO ==
598  op))
599  return GNUNET_YES;
600  GNUNET_assert (GNUNET_NO == ee->remote);
602  ee,
603  GNUNET_NO);
604  return GNUNET_YES;
605 }
int _GSS_is_element_of_operation(struct ElementEntry *ee, struct Operation *op)
Is element ee part of the set used by op?
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:81
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...
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.
Operation context used to execute a set operation.
#define GNUNET_YES
Definition: gnunet_common.h:80
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
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 615 of file gnunet-service-set_union.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(), OperationState::key_to_element, len, Operation::set, and Operation::state.

Referenced by union_accept(), and union_evaluate().

616 {
617  unsigned int len;
618 
619  GNUNET_assert (NULL == op->state->key_to_element);
624  op);
625 }
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
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.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_HashMapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiHashMap32 * GNUNET_CONTAINER_multihashmap32_create(unsigned int len)
Create a 32-bit key multi hash map.
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 OperationState * state
Operation-specific operation state.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
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 637 of file gnunet-service-set_union.c.

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

Referenced by decode_and_send(), and send_ibf().

639 {
640  GNUNET_assert (NULL != op->state->key_to_element);
641 
642  if (NULL != op->state->local_ibf)
643  ibf_destroy (op->state->local_ibf);
645  if (NULL == op->state->local_ibf)
646  {
648  "Failed to allocate local IBF\n");
649  return GNUNET_SYSERR;
650  }
653  op);
654  return GNUNET_OK;
655 }
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
static int prepare_ibf_iterator(void *cls, uint32_t key, void *value)
Insert a key into an ibf.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
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:388
struct InvertibleBloomFilter * ibf_create(uint32_t size, uint8_t hash_num)
Create an invertible bloom filter.
Definition: ibf.c:76
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_HashMapIterator32 it, void *it_cls)
Iterate over all entries in the map.
struct InvertibleBloomFilter * local_ibf
The IBF with the local set&#39;s element.
#define SE_IBF_HASH_NUM
The hash num parameter for the difference digests and strata estimators.
#define GNUNET_log(kind,...)
struct OperationState * state
Operation-specific operation state.
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 668 of file gnunet-service-set_union.c.

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

Referenced by decode_and_send(), and handle_union_p2p_strata_estimator().

670 {
671  unsigned int buckets_sent = 0;
672  struct InvertibleBloomFilter *ibf;
673 
674  if (GNUNET_OK !=
675  prepare_ibf (op, 1<<ibf_order))
676  {
677  /* allocation failed */
678  return GNUNET_SYSERR;
679  }
680 
682  "sending ibf of size %u\n",
683  1<<ibf_order);
684 
685  {
686  char name[64] = { 0 };
687  snprintf (name, sizeof (name), "# sent IBF (order %u)", ibf_order);
689  }
690 
691  ibf = op->state->local_ibf;
692 
693  while (buckets_sent < (1 << ibf_order))
694  {
695  unsigned int buckets_in_message;
696  struct GNUNET_MQ_Envelope *ev;
697  struct IBFMessage *msg;
698 
699  buckets_in_message = (1 << ibf_order) - buckets_sent;
700  /* limit to maximum */
701  if (buckets_in_message > MAX_BUCKETS_PER_MESSAGE)
702  buckets_in_message = MAX_BUCKETS_PER_MESSAGE;
703 
704  ev = GNUNET_MQ_msg_extra (msg,
705  buckets_in_message * IBF_BUCKET_SIZE,
707  msg->reserved1 = 0;
708  msg->reserved2 = 0;
709  msg->order = ibf_order;
710  msg->offset = htonl (buckets_sent);
711  msg->salt = htonl (op->state->salt_send);
712  ibf_write_slice (ibf, buckets_sent,
713  buckets_in_message, &msg[1]);
714  buckets_sent += buckets_in_message;
716  "ibf chunk size %u, %u/%u sent\n",
717  buckets_in_message,
718  buckets_sent,
719  1<<ibf_order);
720  GNUNET_MQ_send (op->mq, ev);
721  }
722 
723  /* The other peer must decode the IBF, so
724  * we're passive. */
726  return GNUNET_OK;
727 }
uint32_t offset
Offset of the strata in the rest of the message.
The other peer is decoding the IBF we just sent.
#define LOG(kind,...)
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
uint8_t reserved1
Padding, must be 0.
#define MAX_BUCKETS_PER_MESSAGE
Number of buckets that can be transmitted in one message.
Message containing buckets of an invertible bloom filter.
static int prepare_ibf(struct Operation *op, uint32_t size)
Create an ibf with the operation&#39;s elements of the specified size.
Invertible bloom filter (IBF).
Definition: ibf.h:82
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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:284
uint32_t salt_send
Salt that we&#39;re using for sending IBFs.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
#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
uint8_t order
Order of the whole ibf, where num_buckets = 2^order.
enum IntersectionOperationPhase phase
Current state of the operation.
#define IBF_BUCKET_SIZE
Size of one ibf bucket in bytes.
Definition: ibf.h:72
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
const char * name
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF
Invertible bloom filter.
uint16_t reserved2
Padding, must be 0.
struct InvertibleBloomFilter * local_ibf
The IBF with the local set&#39;s element.
uint32_t salt
Salt used when hashing elements for this IBF.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
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:353
struct OperationState * state
Operation-specific operation state.
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 738 of file gnunet-service-set_union.c.

References IBF_ALPHA, MAX_IBF_ORDER, and SE_IBF_HASH_NUM.

Referenced by handle_union_p2p_strata_estimator().

739 {
740  unsigned int ibf_order;
741 
742  ibf_order = 2;
743  while ( ( (1<<ibf_order) < (IBF_ALPHA * diff) ||
744  ((1<<ibf_order) < SE_IBF_HASH_NUM) ) &&
745  (ibf_order < MAX_IBF_ORDER) )
746  ibf_order++;
747  // add one for correction
748  return ibf_order + 1;
749 }
#define MAX_IBF_ORDER
The maximum size of an ibf we use is 2^(MAX_IBF_ORDER).
#define IBF_ALPHA
Number of buckets used in the ibf per estimated difference.
#define SE_IBF_HASH_NUM
The hash num parameter for the difference digests and strata estimators.
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 762 of file gnunet-service-set_union.c.

References GNUNET_SET_Element::data, el, ElementEntry::element, GNUNET_SET_Element::element_type, GNUNET_SET_ElementMessage::element_type, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_YES, LOG, Operation::mq, op, GNUNET_SET_Element::size, and value.

Referenced by send_full_set().

765 {
766  struct Operation *op = cls;
767  struct GNUNET_SET_ElementMessage *emsg;
768  struct ElementEntry *ee = value;
769  struct GNUNET_SET_Element *el = &ee->element;
770  struct GNUNET_MQ_Envelope *ev;
771 
773  "Sending element %s\n",
774  GNUNET_h2s (key));
775  ev = GNUNET_MQ_msg_extra (emsg,
776  el->size,
778  emsg->element_type = htons (el->element_type);
779  GNUNET_memcpy (&emsg[1],
780  el->data,
781  el->size);
782  GNUNET_MQ_send (op->mq,
783  ev);
784  return GNUNET_YES;
785 }
#define LOG(kind,...)
static struct GNUNET_IDENTITY_EgoLookup * el
EgoLookup.
Element stored in a set.
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: set.h:293
const void * data
Actual data of the element.
#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_memcpy(dst, src, n)
static char * value
Value of the record to add/remove.
Information about an element element in the set.
Operation context used to execute a set operation.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
uint16_t size
Number of bytes in the buffer pointed to by data.
Message sent by client to the service to add or remove an element to/from the set.
Definition: set.h:282
struct GNUNET_SET_Element element
The actual element.
#define GNUNET_YES
Definition: gnunet_common.h:80
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT
Send a set element, not as response to a demand but because we&#39;re sending the full set...
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:353
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
uint16_t element_type
Application-specific element type.
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 794 of file gnunet-service-set_union.c.

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

Referenced by handle_union_p2p_request_full(), and handle_union_p2p_strata_estimator().

795 {
796  struct GNUNET_MQ_Envelope *ev;
797 
800  "Dedicing to transmit the full set\n");
801  /* FIXME: use a more memory-friendly way of doing this with an
802  iterator, just as we do in the non-full case! */
805  op);
807  GNUNET_MQ_send (op->mq,
808  ev);
809 }
static int send_full_element_iterator(void *cls, const struct GNUNET_HashCode *key, void *value)
Send a set element.
#define LOG(kind,...)
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_HashMapIterator it, void *it_cls)
Iterate over all entries in the map.
enum IntersectionOperationPhase phase
Current state of the 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
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE
Request all missing elements from the other peer, based on their sets and the elements we previously ...
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:353
struct OperationState * state
Operation-specific operation state.
After sending the full set, wait for responses with the elements that the local peer is missing...
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_union_p2p_strata_estimator()

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

Handle a strata estimator from a remote peer.

Parameters
clsthe union operation
msgthe message

Definition at line 819 of file gnunet-service-set_union.c.

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

821 {
822  struct Operation *op = cls;
823  int is_compressed;
824  size_t len;
825 
826  if (op->state->phase != PHASE_EXPECT_SE)
827  {
828  GNUNET_break (0);
829  return GNUNET_SYSERR;
830  }
831  is_compressed = (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC == htons (msg->header.type));
832  len = ntohs (msg->header.size) - sizeof (struct StrataEstimatorMessage);
833  if ( (GNUNET_NO == is_compressed) &&
835  {
836  GNUNET_break (0);
837  return GNUNET_SYSERR;
838  }
839  return GNUNET_OK;
840 }
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE(C)
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
We sent the request message, and expect a strata estimator.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC
Compressed strata estimator.
enum IntersectionOperationPhase phase
Current state of the operation.
#define IBF_BUCKET_SIZE
Size of one ibf bucket in bytes.
Definition: ibf.h:72
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
Strata estimator together with the peer&#39;s overall set size.
Operation context used to execute a set operation.
#define SE_IBF_SIZE
Size of the IBFs in the strata estimator.
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
#define SE_STRATA_COUNT
Number of IBFs in 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()

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

Handle a strata estimator from a remote peer.

Parameters
clsthe union operation
msgthe message

Definition at line 850 of file gnunet-service-set_union.c.

References _GSS_statistics, 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_SET_UNION_P2P_REQUEST_FULL, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC, GNUNET_MQ_msg_header, GNUNET_MQ_send(), GNUNET_NO, GNUNET_ntohll(), GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_YES, StrataEstimatorMessage::header, OperationState::initial_size, len, LOG, Operation::mq, op, OperationState::phase, PHASE_EXPECT_IBF, OperationState::se, SE_IBF_HASH_NUM, SE_IBF_SIZE, SE_STRATA_COUNT, send_full_set(), send_ibf(), StrataEstimatorMessage::set_size, GNUNET_MessageHeader::size, Operation::state, strata_estimator_create(), strata_estimator_destroy(), strata_estimator_difference(), strata_estimator_read(), and GNUNET_MessageHeader::type.

852 {
853  struct Operation *op = cls;
854  struct StrataEstimator *remote_se;
855  unsigned int diff;
856  uint64_t other_size;
857  size_t len;
858  int is_compressed;
859 
860  is_compressed = (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC == htons (msg->header.type));
862  "# bytes of SE received",
863  ntohs (msg->header.size),
864  GNUNET_NO);
865  len = ntohs (msg->header.size) - sizeof (struct StrataEstimatorMessage);
866  other_size = GNUNET_ntohll (msg->set_size);
868  SE_IBF_SIZE,
870  if (NULL == remote_se)
871  {
872  /* insufficient resources, fail */
874  return;
875  }
876  if (GNUNET_OK !=
877  strata_estimator_read (&msg[1],
878  len,
879  is_compressed,
880  remote_se))
881  {
882  /* decompression failed */
883  strata_estimator_destroy (remote_se);
885  return;
886  }
887  GNUNET_assert (NULL != op->state->se);
888  diff = strata_estimator_difference (remote_se,
889  op->state->se);
890 
891  if (diff > 200)
892  diff = diff * 3 / 2;
893 
894  strata_estimator_destroy (remote_se);
896  op->state->se = NULL;
898  "got se diff=%d, using ibf size %d\n",
899  diff,
900  1U << get_order_from_difference (diff));
901 
902  {
903  char *set_debug;
904 
905  set_debug = getenv ("GNUNET_SET_BENCHMARK");
906  if ( (NULL != set_debug) &&
907  (0 == strcmp (set_debug, "1")) )
908  {
909  FILE *f = fopen ("set.log", "a");
910  fprintf (f, "%llu\n", (unsigned long long) diff);
911  fclose (f);
912  }
913  }
914 
915  if ( (GNUNET_YES == op->byzantine) &&
916  (other_size < op->byzantine_lower_bound) )
917  {
918  GNUNET_break (0);
920  return;
921  }
922 
923  if ( (GNUNET_YES == op->force_full) ||
924  (diff > op->state->initial_size / 4) ||
925  (0 == other_size) )
926  {
928  "Deciding to go for full set transmission (diff=%d, own set=%u)\n",
929  diff,
930  op->state->initial_size);
932  "# of full sends",
933  1,
934  GNUNET_NO);
935  if ( (op->state->initial_size <= other_size) ||
936  (0 == other_size) )
937  {
938  send_full_set (op);
939  }
940  else
941  {
942  struct GNUNET_MQ_Envelope *ev;
943 
945  "Telling other peer that we expect its full set\n");
948  GNUNET_MQ_send (op->mq,
949  ev);
950  }
951  }
952  else
953  {
955  "# of ibf sends",
956  1,
957  GNUNET_NO);
958  if (GNUNET_OK !=
959  send_ibf (op,
961  {
962  /* Internal error, best we can do is shut the connection */
964  "Failed to send IBF, closing connection\n");
966  return;
967  }
968  }
970 }
We sent the strata estimator, and expect an IBF.
#define LOG(kind,...)
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.
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_CADET_Channel * channel
Channel to the peer.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE(C)
#define GNUNET_NO
Definition: gnunet_common.h:81
uint64_t initial_size
Initial size of our set, just before the operation started.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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.
#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.
struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
static int send_ibf(struct Operation *op, uint16_t ibf_order)
Send an ibf of appropriate size.
struct StrataEstimator * se
Copy of the set&#39;s strata estimator at the time of creation of this operation.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC
Compressed strata estimator.
void strata_estimator_destroy(struct StrataEstimator *se)
Destroy a strata estimator, free all of its resources.
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_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL
Demand the whole element from the other peer, given only the hash code.
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
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:973
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
#define SE_IBF_SIZE
Size of the IBFs in the strata estimator.
#define SE_IBF_HASH_NUM
The hash num parameter for the difference digests and strata estimators.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:80
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:353
static void send_full_set(struct Operation *op)
Switch to full set transmission for op.
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
#define SE_STRATA_COUNT
Number of IBFs in a strata estimator.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
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 981 of file gnunet-service-set_union.c.

References KeyEntry::element, ElementEntry::element_hash, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_MESSAGE_TYPE_SET_UNION_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().

984 {
985  struct SendElementClosure *sec = cls;
986  struct Operation *op = sec->op;
987  struct KeyEntry *ke = value;
988  struct GNUNET_MQ_Envelope *ev;
989  struct GNUNET_MessageHeader *mh;
990 
991  /* Detect 32-bit key collision for the 64-bit IBF keys. */
992  if (ke->ibf_key.key_val != sec->ibf_key.key_val)
993  return GNUNET_YES;
994 
996  sizeof (struct GNUNET_HashCode),
998 
999  GNUNET_assert (NULL != ev);
1000  *(struct GNUNET_HashCode *) &mh[1] = ke->element->element_hash;
1002  "[OP %x] sending element offer (%s) to peer\n",
1003  (void *) op,
1004  GNUNET_h2s (&ke->element->element_hash));
1005  GNUNET_MQ_send (op->mq, ev);
1006  return GNUNET_YES;
1007 }
#define LOG(kind,...)
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OFFER
Tell the other peer which hashes match a given IBF key.
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
struct ElementEntry * element
The actual element associated with the 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.
A 512-bit hashcode.
#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.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
struct Operation * op
Operation for which the elements should be sent.
Header for all communications.
#define GNUNET_YES
Definition: gnunet_common.h:80
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:353
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
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 1017 of file gnunet-service-set_union.c.

References GNUNET_CONTAINER_multihashmap32_get_multiple(), SendElementClosure::ibf_key, OperationState::key_to_element, IBF_Key::key_val, op, SendElementClosure::op, send_offers_iterator(), and Operation::state.

Referenced by decode_and_send(), and handle_union_p2p_inquiry().

1019 {
1020  struct SendElementClosure send_cls;
1021 
1022  send_cls.ibf_key = ibf_key;
1023  send_cls.op = op;
1025  (uint32_t) ibf_key.key_val,
1027  &send_cls);
1028 }
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
uint64_t key_val
Definition: ibf.h:47
static int send_offers_iterator(void *cls, uint32_t key, void *value)
Iterator to send elements to a remote peer.
int GNUNET_CONTAINER_multihashmap32_get_multiple(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, GNUNET_CONTAINER_HashMapIterator32 it, void *it_cls)
Iterate over all entries in the map that match a particular key.
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
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 1039 of file gnunet-service-set_union.c.

References _GSS_statistics, fail_union_operation(), GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE, GNUNET_MESSAGE_TYPE_SET_UNION_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, OperationState::local_ibf, LOG, MAX_IBF_ORDER, Operation::mq, msg, OperationState::phase, PHASE_INVENTORY_ACTIVE, prepare_ibf(), OperationState::remote_ibf, res, InquiryMessage::salt, OperationState::salt_receive, OperationState::salt_send, send_ibf(), send_offers_for_key(), size, InvertibleBloomFilter::size, Operation::state, and unsalt_key().

Referenced by handle_union_p2p_ibf().

1040 {
1041  struct IBF_Key key;
1042  struct IBF_Key last_key;
1043  int side;
1044  unsigned int num_decoded;
1045  struct InvertibleBloomFilter *diff_ibf;
1046 
1048 
1049  if (GNUNET_OK !=
1050  prepare_ibf (op,
1051  op->state->remote_ibf->size))
1052  {
1053  GNUNET_break (0);
1054  /* allocation failed */
1055  return GNUNET_SYSERR;
1056  }
1057  diff_ibf = ibf_dup (op->state->local_ibf);
1058  ibf_subtract (diff_ibf,
1059  op->state->remote_ibf);
1060 
1061  ibf_destroy (op->state->remote_ibf);
1062  op->state->remote_ibf = NULL;
1063 
1065  "decoding IBF (size=%u)\n",
1066  diff_ibf->size);
1067 
1068  num_decoded = 0;
1069  key.key_val = 0; /* just to avoid compiler thinking we use undef'ed variable */
1070 
1071  while (1)
1072  {
1073  int res;
1074  int cycle_detected = GNUNET_NO;
1075 
1076  last_key = key;
1077 
1078  res = ibf_decode (diff_ibf, &side, &key);
1079  if (res == GNUNET_OK)
1080  {
1082  "decoded ibf key %lx\n",
1083  (unsigned long) key.key_val);
1084  num_decoded += 1;
1085  if ( (num_decoded > diff_ibf->size) ||
1086  ( (num_decoded > 1) &&
1087  (last_key.key_val == key.key_val) ) )
1088  {
1090  "detected cyclic ibf (decoded %u/%u)\n",
1091  num_decoded,
1092  diff_ibf->size);
1093  cycle_detected = GNUNET_YES;
1094  }
1095  }
1096  if ( (GNUNET_SYSERR == res) ||
1097  (GNUNET_YES == cycle_detected) )
1098  {
1099  int next_order;
1100  next_order = 0;
1101  while (1<<next_order < diff_ibf->size)
1102  next_order++;
1103  next_order++;
1104  if (next_order <= MAX_IBF_ORDER)
1105  {
1107  "decoding failed, sending larger ibf (size %u)\n",
1108  1<<next_order);
1110  "# of IBF retries",
1111  1,
1112  GNUNET_NO);
1113  op->state->salt_send++;
1114  if (GNUNET_OK !=
1115  send_ibf (op, next_order))
1116  {
1117  /* Internal error, best we can do is shut the connection */
1119  "Failed to send IBF, closing connection\n");
1120  fail_union_operation (op);
1121  ibf_destroy (diff_ibf);
1122  return GNUNET_SYSERR;
1123  }
1124  }
1125  else
1126  {
1128  "# of failed union operations (too large)",
1129  1,
1130  GNUNET_NO);
1131  // XXX: Send the whole set, element-by-element
1133  "set union failed: reached ibf limit\n");
1134  fail_union_operation (op);
1135  ibf_destroy (diff_ibf);
1136  return GNUNET_SYSERR;
1137  }
1138  break;
1139  }
1140  if (GNUNET_NO == res)
1141  {
1142  struct GNUNET_MQ_Envelope *ev;
1143 
1145  "transmitted all values, sending DONE\n");
1147  GNUNET_MQ_send (op->mq, ev);
1148  /* We now wait until we get a DONE message back
1149  * and then wait for our MQ to be flushed and all our
1150  * demands be delivered. */
1151  break;
1152  }
1153  if (1 == side)
1154  {
1155  struct IBF_Key unsalted_key;
1156 
1157  unsalt_key (&key,
1158  op->state->salt_receive,
1159  &unsalted_key);
1160  send_offers_for_key (op,
1161  unsalted_key);
1162  }
1163  else if (-1 == side)
1164  {
1165  struct GNUNET_MQ_Envelope *ev;
1166  struct InquiryMessage *msg;
1167 
1168  /* It may be nice to merge multiple requests, but with CADET's corking it is not worth
1169  * the effort additional complexity. */
1170  ev = GNUNET_MQ_msg_extra (msg,
1171  sizeof (struct IBF_Key),
1173  msg->salt = htonl (op->state->salt_receive);
1174  GNUNET_memcpy (&msg[1],
1175  &key,
1176  sizeof (struct IBF_Key));
1178  "sending element inquiry for IBF key %lx\n",
1179  (unsigned long) key.key_val);
1180  GNUNET_MQ_send (op->mq, ev);
1181  }
1182  else
1183  {
1184  GNUNET_assert (0);
1185  }
1186  }
1187  ibf_destroy (diff_ibf);
1188  return GNUNET_OK;
1189 }
#define LOG(kind,...)
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct InvertibleBloomFilter * remote_ibf
The IBF we currently receive.
We are decoding an IBF.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int prepare_ibf(struct Operation *op, uint32_t size)
Create an ibf with the operation&#39;s elements of the specified size.
Invertible bloom filter (IBF).
Definition: ibf.h:82
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
uint32_t salt_send
Salt that we&#39;re using for sending IBFs.
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_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
struct InvertibleBloomFilter * ibf_dup(const struct InvertibleBloomFilter *ibf)
Create a copy of an IBF, the copy has to be destroyed properly.
Definition: ibf.c:368
static int send_ibf(struct Operation *op, uint16_t ibf_order)
Send an ibf of appropriate size.
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
uint32_t salt_receive
Salt for the IBF we&#39;ve received and that we&#39;re currently decoding.
#define GNUNET_memcpy(dst, src, n)
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:222
enum IntersectionOperationPhase phase
Current state of the operation.
#define MAX_IBF_ORDER
The maximum size of an ibf we use is 2^(MAX_IBF_ORDER).
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE
Set operation is done.
void ibf_subtract(struct InvertibleBloomFilter *ibf1, const struct InvertibleBloomFilter *ibf2)
Subtract ibf2 from ibf1, storing the result in ibf1.
Definition: ibf.c:346
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 int res
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
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:388
struct InvertibleBloomFilter * local_ibf
The IBF with the local set&#39;s element.
#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 void unsalt_key(const struct IBF_Key *k_in, uint32_t salt, struct IBF_Key *k_out)
FIXME.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:80
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:353
struct OperationState * state
Operation-specific operation state.
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.
#define GNUNET_MESSAGE_TYPE_SET_UNION_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()

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

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 1203 of file gnunet-service-set_union.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SET_OPERATION_UNION, GNUNET_SYSERR, IBFMessage::header, IBF_BUCKET_SIZE, OperationState::ibf_buckets_received, msg, IBFMessage::offset, op, Set::operation, IBFMessage::order, OperationState::phase, PHASE_EXPECT_IBF, PHASE_EXPECT_IBF_CONT, PHASE_INVENTORY_PASSIVE, OperationState::remote_ibf, IBFMessage::salt, OperationState::salt_receive, Operation::set, InvertibleBloomFilter::size, GNUNET_MessageHeader::size, and Operation::state.

1205 {
1206  struct Operation *op = cls;
1207  unsigned int buckets_in_message;
1208 
1210  {
1211  GNUNET_break_op (0);
1212  return GNUNET_SYSERR;
1213  }
1214  buckets_in_message = (ntohs (msg->header.size) - sizeof *msg) / IBF_BUCKET_SIZE;
1215  if (0 == buckets_in_message)
1216  {
1217  GNUNET_break_op (0);
1218  return GNUNET_SYSERR;
1219  }
1220  if ((ntohs (msg->header.size) - sizeof *msg) != buckets_in_message * IBF_BUCKET_SIZE)
1221  {
1222  GNUNET_break_op (0);
1223  return GNUNET_SYSERR;
1224  }
1225  if (op->state->phase == PHASE_EXPECT_IBF_CONT)
1226  {
1227  if (ntohl (msg->offset) != op->state->ibf_buckets_received)
1228  {
1229  GNUNET_break_op (0);
1230  return GNUNET_SYSERR;
1231  }
1232  if (1<<msg->order != op->state->remote_ibf->size)
1233  {
1234  GNUNET_break_op (0);
1235  return GNUNET_SYSERR;
1236  }
1237  if (ntohl (msg->salt) != op->state->salt_receive)
1238  {
1239  GNUNET_break_op (0);
1240  return GNUNET_SYSERR;
1241  }
1242  }
1243  else if ( (op->state->phase != PHASE_INVENTORY_PASSIVE) &&
1244  (op->state->phase != PHASE_EXPECT_IBF) )
1245  {
1246  GNUNET_break_op (0);
1247  return GNUNET_SYSERR;
1248  }
1249 
1250  return GNUNET_OK;
1251 }
We sent the strata estimator, and expect an IBF.
uint32_t offset
Offset of the strata in the rest of the message.
The other peer is decoding the IBF we just sent.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
struct InvertibleBloomFilter * remote_ibf
The IBF we currently receive.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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
uint32_t salt_receive
Salt for the IBF we&#39;ve received and that we&#39;re currently decoding.
#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.
enum IntersectionOperationPhase phase
Current state of the operation.
#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.
unsigned int ibf_buckets_received
Number of ibf buckets already received into the remote_ibf.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
enum GNUNET_SET_OperationType operation
Type of operation supported for this set.
Operation context used to execute a set operation.
uint32_t salt
Salt used when hashing elements for this IBF.
Continuation for multi part IBFs.
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
Set union, return all elements that are in at least one of the sets.

◆ handle_union_p2p_ibf()

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

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 1264 of file gnunet-service-set_union.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, OperationState::ibf_buckets_received, ibf_create(), ibf_read_slice(), LOG, msg, IBFMessage::offset, op, IBFMessage::order, OperationState::phase, PHASE_EXPECT_IBF, PHASE_EXPECT_IBF_CONT, PHASE_INVENTORY_ACTIVE, PHASE_INVENTORY_PASSIVE, OperationState::remote_ibf, IBFMessage::salt, OperationState::salt_receive, SE_IBF_HASH_NUM, InvertibleBloomFilter::size, GNUNET_MessageHeader::size, and Operation::state.

1266 {
1267  struct Operation *op = cls;
1268  unsigned int buckets_in_message;
1269 
1270  buckets_in_message = (ntohs (msg->header.size) - sizeof *msg) / IBF_BUCKET_SIZE;
1271  if ( (op->state->phase == PHASE_INVENTORY_PASSIVE) ||
1272  (op->state->phase == PHASE_EXPECT_IBF) )
1273  {
1275  GNUNET_assert (NULL == op->state->remote_ibf);
1277  "Creating new ibf of size %u\n",
1278  1 << msg->order);
1279  op->state->remote_ibf = ibf_create (1<<msg->order, SE_IBF_HASH_NUM);
1280  op->state->salt_receive = ntohl (msg->salt);
1282  "Receiving new IBF with salt %u\n",
1283  op->state->salt_receive);
1284  if (NULL == op->state->remote_ibf)
1285  {
1287  "Failed to parse remote IBF, closing connection\n");
1288  fail_union_operation (op);
1289  return;
1290  }
1291  op->state->ibf_buckets_received = 0;
1292  if (0 != ntohl (msg->offset))
1293  {
1294  GNUNET_break_op (0);
1295  fail_union_operation (op);
1296  return;
1297  }
1298  }
1299  else
1300  {
1303  "Received more of IBF\n");
1304  }
1305  GNUNET_assert (NULL != op->state->remote_ibf);
1306 
1307  ibf_read_slice (&msg[1],
1309  buckets_in_message,
1310  op->state->remote_ibf);
1311  op->state->ibf_buckets_received += buckets_in_message;
1312 
1313  if (op->state->ibf_buckets_received == op->state->remote_ibf->size)
1314  {
1316  "received full ibf\n");
1318  if (GNUNET_OK !=
1319  decode_and_send (op))
1320  {
1321  /* Internal error, best we can do is shut down */
1323  "Failed to decode IBF, closing connection\n");
1324  fail_union_operation (op);
1325  return;
1326  }
1327  }
1329 }
We sent the strata estimator, and expect an IBF.
uint32_t offset
Offset of the strata in the rest of the message.
The other peer is decoding the IBF we just sent.
#define LOG(kind,...)
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct InvertibleBloomFilter * remote_ibf
The IBF we currently receive.
We are decoding an IBF.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_CADET_Channel * channel
Channel to the peer.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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
uint32_t salt_receive
Salt for the IBF we&#39;ve received and that we&#39;re currently decoding.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
static int decode_and_send(struct Operation *op)
Decode which elements are missing on each side, and send the appropriate offers and inquiries...
uint8_t order
Order of the whole ibf, where num_buckets = 2^order.
enum IntersectionOperationPhase phase
Current state of the operation.
#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.
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
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:315
unsigned int ibf_buckets_received
Number of ibf buckets already received into the remote_ibf.
struct InvertibleBloomFilter * ibf_create(uint32_t size, uint8_t hash_num)
Create an invertible bloom filter.
Definition: ibf.c:76
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:973
uint32_t salt
Salt used when hashing elements for this IBF.
#define SE_IBF_HASH_NUM
The hash num parameter for the difference digests and strata estimators.
Continuation for multi part IBFs.
#define GNUNET_log(kind,...)
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
Here is the call graph for this function:

◆ send_client_element()

static void send_client_element ( struct Operation op,
struct GNUNET_SET_Element element,
int  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 1341 of file gnunet-service-set_union.c.

References Operation::client_request_id, Set::cs, GNUNET_SET_ResultMessage::current_size, GNUNET_SET_Element::data, GNUNET_SET_Element::element_type, GNUNET_SET_ResultMessage::element_type, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multihashmap32_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_htonll(), GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SET_RESULT, GNUNET_MQ_discard(), GNUNET_MQ_msg_extra, GNUNET_MQ_send(), OperationState::key_to_element, LOG, ClientState::mq, GNUNET_SET_ResultMessage::request_id, GNUNET_SET_ResultMessage::result_status, Operation::set, GNUNET_SET_Element::size, and Operation::state.

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

1344 {
1345  struct GNUNET_MQ_Envelope *ev;
1346  struct GNUNET_SET_ResultMessage *rm;
1347 
1349  "sending element (size %u) to client\n",
1350  element->size);
1351  GNUNET_assert (0 != op->client_request_id);
1353  if (NULL == ev)
1354  {
1355  GNUNET_MQ_discard (ev);
1356  GNUNET_break (0);
1357  return;
1358  }
1359  rm->result_status = htons (status);
1360  rm->request_id = htonl (op->client_request_id);
1361  rm->element_type = htons (element->element_type);
1363  GNUNET_memcpy (&rm[1],
1364  element->data,
1365  element->size);
1366  GNUNET_MQ_send (op->set->cs->mq,
1367  ev);
1368 }
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
#define LOG(kind,...)
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: set.h:246
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_MESSAGE_TYPE_SET_RESULT
Create an empty set.
uint32_t request_id
id the result belongs to
Definition: set.h:261
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
const void * data
Actual data of the element.
uint64_t current_size
Current set size.
Definition: set.h:256
#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_memcpy(dst, src, n)
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SET_Status in NBO.
Definition: set.h:267
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.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:321
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: set.h:272
uint32_t client_request_id
ID used to identify an operation between service and client.
uint16_t size
Number of bytes in the buffer pointed to by data.
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:353
struct ClientState * cs
Client that owns the set.
struct OperationState * state
Operation-specific operation state.
uint16_t element_type
Application-specific element type.
Here is the call graph for this function:
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 1378 of file gnunet-service-set_union.c.

References _GSS_statistics, OperationState::client_done_sent, Operation::client_request_id, Set::cs, GNUNET_SET_ResultMessage::current_size, GNUNET_SET_ResultMessage::element_type, GNUNET_CONTAINER_multihashmap32_size(), GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_htonll(), GNUNET_MESSAGE_TYPE_SET_RESULT, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_NO, GNUNET_SET_STATUS_DONE, GNUNET_SET_STATUS_FAILURE, GNUNET_STATISTICS_update(), GNUNET_YES, OperationState::key_to_element, LOG, ClientState::mq, op, OperationState::phase, PHASE_DONE, GNUNET_SET_ResultMessage::request_id, GNUNET_SET_ResultMessage::result_status, Operation::set, and Operation::state.

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

1379 {
1380  struct Operation *op = cls;
1381  struct GNUNET_MQ_Envelope *ev;
1382  struct GNUNET_SET_ResultMessage *rm;
1383 
1384  if (GNUNET_YES == op->state->client_done_sent)
1385  {
1386  return;
1387  }
1388 
1389  if (PHASE_DONE != op->state->phase) {
1391  "Union operation failed\n");
1393  "# Union operations failed",
1394  1,
1395  GNUNET_NO);
1398  rm->request_id = htonl (op->client_request_id);
1399  rm->element_type = htons (0);
1400  GNUNET_MQ_send (op->set->cs->mq,
1401  ev);
1402  return;
1403  }
1404 
1406 
1408  "# Union operations succeeded",
1409  1,
1410  GNUNET_NO);
1412  "Signalling client that union operation is done\n");
1413  ev = GNUNET_MQ_msg (rm,
1415  rm->request_id = htonl (op->client_request_id);
1416  rm->result_status = htons (GNUNET_SET_STATUS_DONE);
1417  rm->element_type = htons (0);
1419  GNUNET_MQ_send (op->set->cs->mq,
1420  ev);
1421 }
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
#define LOG(kind,...)
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: set.h:246
#define GNUNET_MESSAGE_TYPE_SET_RESULT
Create an empty set.
uint32_t request_id
id the result belongs to
Definition: set.h:261
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_NO
Definition: gnunet_common.h:81
int client_done_sent
Did we send the client that we are done?
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
Success, all elements have been sent (and received).
struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
uint64_t current_size
Current set size.
Definition: set.h:256
The other peer refused to to the operation with us, or something went wrong.
enum IntersectionOperationPhase phase
Current state of the operation.
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SET_Status in NBO.
Definition: set.h:267
unsigned int GNUNET_CONTAINER_multihashmap32_size(const struct GNUNET_CONTAINER_MultiHashMap32 *map)
Get the number of key-value pairs in the map.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: set.h:272
Operation context used to execute a set operation.
uint32_t client_request_id
ID used to identify an operation between service and client.
#define GNUNET_YES
Definition: gnunet_common.h:80
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:353
struct ClientState * cs
Client that owns the set.
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
In the ultimate phase, we wait until our demands are satisfied and then quit (sending another DONE me...
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 1430 of file gnunet-service-set_union.c.

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

Referenced by handle_union_p2p_done(), and handle_union_p2p_elements().

1431 {
1432  unsigned int num_demanded;
1433 
1435 
1436  if (PHASE_FINISH_WAITING == op->state->phase)
1437  {
1439  "In PHASE_FINISH_WAITING, pending %u demands\n",
1440  num_demanded);
1441  if (0 == num_demanded)
1442  {
1443  struct GNUNET_MQ_Envelope *ev;
1444 
1445  op->state->phase = PHASE_DONE;
1447  GNUNET_MQ_send (op->mq,
1448  ev);
1449  /* We now wait until the other peer sends P2P_OVER
1450  * after it got all elements from us. */
1451  }
1452  }
1453  if (PHASE_FINISH_CLOSING == op->state->phase)
1454  {
1456  "In PHASE_FINISH_CLOSING, pending %u demands\n",
1457  num_demanded);
1458  if (0 == num_demanded)
1459  {
1460  op->state->phase = PHASE_DONE;
1461  send_client_done (op);
1463  }
1464  }
1465 }
#define LOG(kind,...)
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
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.
In the penultimate phase, we wait until all our demands are satisfied.
enum IntersectionOperationPhase phase
Current state of the operation.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE
Set operation is done.
#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 GNUNET_MQ_Handle * mq
Message queue for the channel.
void _GSS_operation_destroy2(struct Operation *op)
This function probably should not exist and be replaced by inlining more specific logic in the variou...
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:353
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
struct OperationState * state
Operation-specific operation state.
In the ultimate phase, we wait until our demands are satisfied and then quit (sending another DONE me...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_union_p2p_elements()

int check_union_p2p_elements ( void *  cls,
const struct GNUNET_SET_ElementMessage emsg 
)

Check an element message from a remote peer.

Parameters
clsthe union operation
emsgthe message

Definition at line 1475 of file gnunet-service-set_union.c.

References OperationState::demanded_hashes, GNUNET_break_op, GNUNET_CONTAINER_multihashmap_size(), GNUNET_OK, GNUNET_SET_OPERATION_UNION, GNUNET_SYSERR, op, Set::operation, Operation::set, and Operation::state.

1477 {
1478  struct Operation *op = cls;
1479 
1481  {
1482  GNUNET_break_op (0);
1483  return GNUNET_SYSERR;
1484  }
1486  {
1487  GNUNET_break_op (0);
1488  return GNUNET_SYSERR;
1489  }
1490  return GNUNET_OK;
1491 }
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
enum GNUNET_SET_OperationType operation
Type of operation supported for this set.
Operation context used to execute a set operation.
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
Set union, return all elements that are in at least one of the sets.
Here is the call graph for this function:

◆ handle_union_p2p_elements()

void handle_union_p2p_elements ( void *  cls,
const struct GNUNET_SET_ElementMessage emsg 
)

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 1503 of file gnunet-service-set_union.c.

References _GSS_statistics, Operation::channel, GNUNET_SET_Element::data, OperationState::demanded_hashes, ElementEntry::element, ElementEntry::element_hash, element_size, GNUNET_SET_Element::element_type, GNUNET_SET_ElementMessage::element_type, fail_union_operation(), GNUNET_break, 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_SET_element_hash(), GNUNET_SET_RESULT_ADDED, GNUNET_SET_RESULT_SYMMETRIC, GNUNET_SET_STATUS_ADD_LOCAL, GNUNET_SET_STATUS_OK, GNUNET_STATISTICS_update(), GNUNET_YES, GNUNET_SET_ElementMessage::header, LOG, maybe_finish(), op, op_get_element(), op_register_element(), KeyEntry::received, OperationState::received_fresh, OperationState::received_total, ElementEntry::remote, Operation::result_mode, send_client_element(), GNUNET_SET_Element::size, GNUNET_MessageHeader::size, and Operation::state.

1505 {
1506  struct Operation *op = cls;
1507  struct ElementEntry *ee;
1508  struct KeyEntry *ke;
1509  uint16_t element_size;
1510 
1511  element_size = ntohs (emsg->header.size) - sizeof (struct GNUNET_SET_ElementMessage);
1512  ee = GNUNET_malloc (sizeof (struct ElementEntry) + element_size);
1513  GNUNET_memcpy (&ee[1],
1514  &emsg[1],
1515  element_size);
1516  ee->element.size = element_size;
1517  ee->element.data = &ee[1];
1518  ee->element.element_type = ntohs (emsg->element_type);
1519  ee->remote = GNUNET_YES;
1521  &ee->element_hash);
1522  if (GNUNET_NO ==
1524  &ee->element_hash,
1525  NULL))
1526  {
1527  /* We got something we didn't demand, since it's not in our map. */
1528  GNUNET_break_op (0);
1529  fail_union_operation (op);
1530  return;
1531  }
1532 
1534  "Got element (size %u, hash %s) from peer\n",
1535  (unsigned int) element_size,
1536  GNUNET_h2s (&ee->element_hash));
1537 
1539  "# received elements",
1540  1,
1541  GNUNET_NO);
1543  "# exchanged elements",
1544  1,
1545  GNUNET_NO);
1546 
1547  op->state->received_total++;
1548 
1549  ke = op_get_element (op, &ee->element_hash);
1550  if (NULL != ke)
1551  {
1552  /* Got repeated element. Should not happen since
1553  * we track demands. */
1555  "# repeated elements",
1556  1,
1557  GNUNET_NO);
1558  ke->received = GNUNET_YES;
1559  GNUNET_free (ee);
1560  }
1561  else
1562  {
1564  "Registering new element from remote peer\n");
1565  op->state->received_fresh++;
1566  op_register_element (op, ee, GNUNET_YES);
1567  /* only send results immediately if the client wants it */
1568  switch (op->result_mode)
1569  {
1572  break;
1575  break;
1576  default:
1577  /* Result mode not supported, should have been caught earlier. */
1578  GNUNET_break (0);
1579  break;
1580  }
1581  }
1582 
1583  if ( (op->state->received_total > 8) &&
1584  (op->state->received_fresh < op->state->received_total / 3) )
1585  {
1586  /* The other peer gave us lots of old elements, there's something wrong. */
1587  GNUNET_break_op (0);
1588  fail_union_operation (op);
1589  return;
1590  }
1592  maybe_finish (op);
1593 }
Client gets only elements that have been added to the set.
#define LOG(kind,...)
enum GNUNET_SET_ResultMode result_mode
When are elements sent to the client, and which elements are sent?
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...
struct GNUNET_HashCode element_hash
Hash of the element.
Element should be added to the result set of the local peer, i.e.
struct GNUNET_CADET_Channel * channel
Channel to the peer.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_ADD or GNUNET_MESSAGE_TYPE_SET_REMOVE.
Definition: set.h:288
#define GNUNET_NO
Definition: gnunet_common.h:81
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.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void GNUNET_SET_element_hash(const struct GNUNET_SET_Element *element, struct GNUNET_HashCode *ret_hash)
Hash a set element.
Definition: set_api.c:1242
uint16_t element_type
Type of the element to add or remove.
Definition: set.h:293
const void * data
Actual data of the element.
struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
The key entry is used to associate an ibf key with an element.
uint32_t received_total
Total number of elements received from the other peer.
#define GNUNET_memcpy(dst, src, n)
Information about an element element in the set.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
Everything went ok, we are transmitting an element of the result (in set, or to be removed from set...
int remote
GNUNET_YES if the element is a remote element, and does not belong to the operation&#39;s set...
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.
Client gets notified of the required changes for both the local and the remote set.
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 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 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.
Operation context used to execute a set operation.
static void send_client_element(struct Operation *op, struct GNUNET_SET_Element *element, int status)
Send a result message to the client indicating that there is a new element.
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:973
static void maybe_finish(struct Operation *op)
Tests if the operation is finished, and if so notify.
uint16_t size
Number of bytes in the buffer pointed to by data.
Message sent by client to the service to add or remove an element to/from the set.
Definition: set.h:282
struct GNUNET_SET_Element element
The actual element.
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
#define GNUNET_malloc(size)
Wrapper around malloc.
#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()

int check_union_p2p_full_element ( void *  cls,
const struct GNUNET_SET_ElementMessage emsg 
)

Check a full element message from a remote peer.

Parameters
clsthe union operation
emsgthe message

Definition at line 1603 of file gnunet-service-set_union.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SET_OPERATION_UNION, GNUNET_SYSERR, op, Set::operation, and Operation::set.

1605 {
1606  struct Operation *op = cls;
1607 
1609  {
1610  GNUNET_break_op (0);
1611  return GNUNET_SYSERR;
1612  }
1613  // FIXME: check that we expect full elements here?
1614  return GNUNET_OK;
1615 }
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
enum GNUNET_SET_OperationType operation
Type of operation supported for this set.
Operation context used to execute a set operation.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
Set union, return all elements that are in at least one of the sets.

◆ handle_union_p2p_full_element()

void handle_union_p2p_full_element ( void *  cls,
const struct GNUNET_SET_ElementMessage emsg 
)

Handle an element message from a remote peer.

Parameters
clsthe union operation
emsgthe message

Definition at line 1625 of file gnunet-service-set_union.c.

References _GSS_statistics, Operation::byzantine, Operation::channel, GNUNET_SET_Element::data, ElementEntry::element, ElementEntry::element_hash, element_size, GNUNET_SET_Element::element_type, GNUNET_SET_ElementMessage::element_type, fail_union_operation(), GNUNET_break, 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_SET_element_hash(), GNUNET_SET_RESULT_ADDED, GNUNET_SET_RESULT_SYMMETRIC, GNUNET_SET_STATUS_ADD_LOCAL, GNUNET_SET_STATUS_OK, GNUNET_STATISTICS_update(), GNUNET_YES, GNUNET_SET_ElementMessage::header, LOG, op, op_get_element(), op_register_element(), KeyEntry::received, OperationState::received_fresh, OperationState::received_total, ElementEntry::remote, Operation::result_mode, send_client_element(), GNUNET_SET_Element::size, GNUNET_MessageHeader::size, and Operation::state.

1627 {
1628  struct Operation *op = cls;
1629  struct ElementEntry *ee;
1630  struct KeyEntry *ke;
1631  uint16_t element_size;
1632 
1633  element_size = ntohs (emsg->header.size) - sizeof (struct GNUNET_SET_ElementMessage);
1634  ee = GNUNET_malloc (sizeof (struct ElementEntry) + element_size);
1635  GNUNET_memcpy (&ee[1], &emsg[1], element_size);
1636  ee->element.size = element_size;
1637  ee->element.data = &ee[1];
1638  ee->element.element_type = ntohs (emsg->element_type);
1639  ee->remote = GNUNET_YES;
1641 
1643  "Got element (full diff, size %u, hash %s) from peer\n",
1644  (unsigned int) element_size,
1645  GNUNET_h2s (&ee->element_hash));
1646 
1648  "# received elements",
1649  1,
1650  GNUNET_NO);
1652  "# exchanged elements",
1653  1,
1654  GNUNET_NO);
1655 
1656  op->state->received_total++;
1657 
1658  ke = op_get_element (op, &ee->element_hash);
1659  if (NULL != ke)
1660  {
1661  /* Got repeated element. Should not happen since
1662  * we track demands. */
1664  "# repeated elements",
1665  1,
1666  GNUNET_NO);
1667  ke->received = GNUNET_YES;
1668  GNUNET_free (ee);
1669  }
1670  else
1671  {
1673  "Registering new element from remote peer\n");
1674  op->state->received_fresh++;
1675  op_register_element (op, ee, GNUNET_YES);
1676  /* only send results immediately if the client wants it */
1677  switch (op->result_mode)
1678  {
1681  break;
1684  break;
1685  default:
1686  /* Result mode not supported, should have been caught earlier. */
1687  GNUNET_break (0);
1688  break;
1689  }
1690  }
1691 
1692  if ( (GNUNET_YES == op->byzantine) &&
1693  (op->state->received_total > 384 + op->state->received_fresh * 4) &&
1694  (op->state->received_fresh < op->state->received_total / 6) )
1695  {
1696  /* The other peer gave us lots of old elements, there's something wrong. */
1698  "Other peer sent only %llu/%llu fresh elements, failing operation\n",
1699  (unsigned long long) op->state->received_fresh,
1700  (unsigned long long) op->state->received_total);
1701  GNUNET_break_op (0);
1702  fail_union_operation (op);
1703  return;
1704  }
1706 }
Client gets only elements that have been added to the set.
#define LOG(kind,...)
enum GNUNET_SET_ResultMode result_mode
When are elements sent to the client, and which elements are sent?
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...
struct GNUNET_HashCode element_hash
Hash of the element.
Element should be added to the result set of the local peer, i.e.
struct GNUNET_CADET_Channel * channel
Channel to the peer.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_ADD or GNUNET_MESSAGE_TYPE_SET_REMOVE.
Definition: set.h:288
#define GNUNET_NO
Definition: gnunet_common.h:81
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.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void GNUNET_SET_element_hash(const struct GNUNET_SET_Element *element, struct GNUNET_HashCode *ret_hash)
Hash a set element.
Definition: set_api.c:1242
uint16_t element_type
Type of the element to add or remove.
Definition: set.h:293
const void * data
Actual data of the element.
struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
The key entry is used to associate an ibf key with an element.
uint32_t received_total
Total number of elements received from the other peer.
#define GNUNET_memcpy(dst, src, n)
Information about an element element in the set.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
Everything went ok, we are transmitting an element of the result (in set, or to be removed from set...
int remote
GNUNET_YES if the element is a remote element, and does not belong to the operation&#39;s set...
Client gets notified of the required changes for both the local and the remote set.
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 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.
int byzantine
GNUNET_YES to fail operations where Byzantine faults are suspected
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.
Operation context used to execute a set operation.
static void send_client_element(struct Operation *op, struct GNUNET_SET_Element *element, int status)
Send a result message to the client indicating that there is a new element.
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:973
uint16_t size
Number of bytes in the buffer pointed to by data.
Message sent by client to the service to add or remove an element to/from the set.
Definition: set.h:282
struct GNUNET_SET_Element element
The actual element.
#define GNUNET_YES
Definition: gnunet_common.h:80
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
#define GNUNET_malloc(size)
Wrapper around malloc.
#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()

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).

Parameters
clsthe union operation
msgthe message

Definition at line 1717 of file gnunet-service-set_union.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SET_OPERATION_UNION, GNUNET_SYSERR, InquiryMessage::header, op, Set::operation, OperationState::phase, PHASE_INVENTORY_PASSIVE, Operation::set, GNUNET_MessageHeader::size, and Operation::state.

1719 {
1720  struct Operation *op = cls;
1721  unsigned int num_keys;
1722 
1724  {
1725  GNUNET_break_op (0);
1726  return GNUNET_SYSERR;
1727  }
1728  if (op->state->phase != PHASE_INVENTORY_PASSIVE)
1729  {
1730  GNUNET_break_op (0);
1731  return GNUNET_SYSERR;
1732  }
1733  num_keys = (ntohs (msg->header.size) - sizeof (struct InquiryMessage))
1734  / sizeof (struct IBF_Key);
1735  if ((ntohs (msg->header.size) - sizeof (struct InquiryMessage))
1736  != num_keys * sizeof (struct IBF_Key))
1737  {
1738  GNUNET_break_op (0);
1739  return GNUNET_SYSERR;
1740  }
1741  return GNUNET_OK;
1742 }
The other peer is decoding the IBF we just sent.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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.
enum IntersectionOperationPhase phase
Current state of the operation.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
enum GNUNET_SET_OperationType operation
Type of operation supported for this set.
Operation context used to execute a set operation.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF.
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:45
Set union, return all elements that are in at least one of the sets.

◆ handle_union_p2p_inquiry()

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).

Parameters
clsthe union operation
msgthe message

Definition at line 1753 of file gnunet-service-set_union.c.

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

1755 {
1756  struct Operation *op = cls;
1757  const struct IBF_Key *ibf_key;
1758  unsigned int num_keys;
1759 
1761  "Received union inquiry\n");
1762  num_keys = (ntohs (msg->header.size) - sizeof (struct InquiryMessage))
1763  / sizeof (struct IBF_Key);
1764  ibf_key = (const struct IBF_Key *) &msg[1];
1765  while (0 != num_keys--)
1766  {
1767  struct IBF_Key unsalted_key;
1768 
1769  unsalt_key (ibf_key,
1770  ntohl (msg->salt),
1771  &unsalted_key);
1772  send_offers_for_key (op,
1773  unsalted_key);
1774  ibf_key++;
1775  }
1777 }
#define LOG(kind,...)
struct GNUNET_CADET_Channel * channel
Channel to the peer.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
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.
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:973
static void unsalt_key(const struct IBF_Key *k_in, uint32_t salt, struct IBF_Key *k_out)
FIXME.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
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 1791 of file gnunet-service-set_union.c.

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

Referenced by handle_union_p2p_full_done().

1794 {
1795  struct Operation *op = cls;
1796  struct KeyEntry *ke = value;
1797  struct GNUNET_MQ_Envelope *ev;
1798  struct GNUNET_SET_ElementMessage *emsg;
1799  struct ElementEntry *ee = ke->element;
1800 
1801  if (GNUNET_YES == ke->received)
1802  return GNUNET_YES;
1803  ev = GNUNET_MQ_msg_extra (emsg,
1804  ee->element.size,
1806  GNUNET_memcpy (&emsg[1],
1807  ee->element.data,
1808  ee->element.size);
1809  emsg->element_type = htons (ee->element.element_type);
1810  GNUNET_MQ_send (op->mq,
1811  ev);
1812  return GNUNET_YES;
1813 }
int received
Did we receive this element? Even if element->is_foreign is false, we might have received the element...
struct ElementEntry * element
The actual element associated with the key.
uint16_t element_type
Type of the element to add or remove.
Definition: set.h:293
const void * data
Actual data of the element.
The key entry is used to associate an ibf key with an element.
#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_memcpy(dst, src, n)
static char * value
Value of the record to add/remove.
Information about an element element in the set.
Operation context used to execute a set operation.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
uint16_t size
Number of bytes in the buffer pointed to by data.
Message sent by client to the service to add or remove an element to/from the set.
Definition: set.h:282
struct GNUNET_SET_Element element
The actual element.
#define GNUNET_YES
Definition: gnunet_common.h:80
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT
Send a set element, not as response to a demand but because we&#39;re sending the full set...
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:353
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
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()

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

Handle a request for full set transmission.

cls closure, a set union operation

Parameters
mhthe demand message

Definition at line 1823 of file gnunet-service-set_union.c.

References Operation::channel, fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_SET_OPERATION_UNION, LOG, op, Set::operation, OperationState::phase, PHASE_EXPECT_IBF, send_full_set(), Operation::set, and Operation::state.

1825 {
1826  struct Operation *op = cls;
1827 
1829  "Received request for full set transmission\n");
1831  {
1832  GNUNET_break_op (0);
1833  fail_union_operation (op);
1834  return;
1835  }
1836  if (PHASE_EXPECT_IBF != op->state->phase)
1837  {
1838  GNUNET_break_op (0);
1839  fail_union_operation (op);
1840  return;
1841  }
1842 
1843  // FIXME: we need to check that our set is larger than the
1844  // byzantine_lower_bound by some threshold
1845  send_full_set (op);
1847 }
We sent the strata estimator, and expect an IBF.
#define LOG(kind,...)
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
struct GNUNET_CADET_Channel * channel
Channel to the peer.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
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...
enum GNUNET_SET_OperationType operation
Type of operation supported for this set.
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:973
static void send_full_set(struct Operation *op)
Switch to full set transmission for op.
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
Set union, return all elements that are in at least one of the sets.
Here is the call graph for this function:

◆ handle_union_p2p_full_done()

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

Handle a "full done" message.

cls closure, a set union operation

Parameters
mhthe demand message

Definition at line 1857 of file gnunet-service-set_union.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_SET_UNION_P2P_FULL_DONE, GNUNET_MQ_msg_header, GNUNET_MQ_send(), OperationState::key_to_element, LOG, Operation::mq, op, OperationState::phase, PHASE_DONE, PHASE_EXPECT_IBF, PHASE_FULL_SENDING, send_client_done(), send_missing_full_elements_iter(), and Operation::state.

1859 {
1860  struct Operation *op = cls;
1861 
1862  switch (op->state->phase)
1863  {
1864  case PHASE_EXPECT_IBF:
1865  {
1866  struct GNUNET_MQ_Envelope *ev;
1867 
1869  "got FULL DONE, sending elements that other peer is missing\n");
1870 
1871  /* send all the elements that did not come from the remote peer */
1874  op);
1875 
1877  GNUNET_MQ_send (op->mq,
1878  ev);
1879  op->state->phase = PHASE_DONE;
1880  /* we now wait until the other peer sends us the OVER message*/
1881  }
1882  break;
1883  case PHASE_FULL_SENDING:
1884  {
1886  "got FULL DONE, finishing\n");
1887  /* We sent the full set, and got the response for that. We're done. */
1888  op->state->phase = PHASE_DONE;
1890  send_client_done (op);
1892  return;
1893  }
1894  break;
1895  default:
1897  "Handle full done phase is %u\n",
1898  (unsigned) op->state->phase);
1899  GNUNET_break_op (0);
1900  fail_union_operation (op);
1901  return;
1902  }
1904 }
We sent the strata estimator, and expect an IBF.
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
#define LOG(kind,...)
struct GNUNET_CADET_Channel * channel
Channel to the peer.
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...
static void send_client_done(void *cls)
Signal to the client that the operation has finished and destroy the operation.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
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...
Operation context used to execute a set operation.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_HashMapIterator32 it, void *it_cls)
Iterate over all entries in the map.
#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:973
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
#define GNUNET_log(kind,...)
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE
Request all missing elements from the other peer, based on their sets and the elements we previously ...
void _GSS_operation_destroy2(struct Operation *op)
This function probably should not exist and be replaced by inlining more specific logic in the variou...
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:353
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
In the ultimate phase, we wait until our demands are satisfied and then quit (sending another DONE me...
After sending the full set, wait for responses with the elements that the local peer is missing...
Here is the call graph for this function:

◆ check_union_p2p_demand()

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.

cls closure, a set union operation

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

Definition at line 1916 of file gnunet-service-set_union.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SET_OPERATION_UNION, GNUNET_SYSERR, op, Set::operation, Operation::set, and GNUNET_MessageHeader::size.

1918 {
1919  struct Operation *op = cls;
1920  unsigned int num_hashes;
1921 
1923  {
1924  GNUNET_break_op (0);
1925  return GNUNET_SYSERR;
1926  }
1927  num_hashes = (ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader))
1928  / sizeof (struct GNUNET_HashCode);
1929  if ((ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader))
1930  != num_hashes * sizeof (struct GNUNET_HashCode))
1931  {
1932  GNUNET_break_op (0);
1933  return GNUNET_SYSERR;
1934  }
1935  return GNUNET_OK;
1936 }
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
enum GNUNET_SET_OperationType operation
Type of operation supported for this set.
Operation context used to execute a set operation.
Header for all communications.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
Set union, return all elements that are in at least one of the sets.

◆ handle_union_p2p_demand()

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.

cls closure, a set union operation

Parameters
mhthe demand message

Definition at line 1947 of file gnunet-service-set_union.c.

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

1949 {
1950  struct Operation *op = cls;
1951  struct ElementEntry *ee;
1952  struct GNUNET_SET_ElementMessage *emsg;
1953  const struct GNUNET_HashCode *hash;
1954  unsigned int num_hashes;
1955  struct GNUNET_MQ_Envelope *ev;
1956 
1957  num_hashes = (ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader))
1958  / sizeof (struct GNUNET_HashCode);
1959  for (hash = (const struct GNUNET_HashCode *) &mh[1];
1960  num_hashes > 0;
1961  hash++, num_hashes--)
1962  {
1964  hash);
1965  if (NULL == ee)
1966  {
1967  /* Demand for non-existing element. */
1968  GNUNET_break_op (0);
1969  fail_union_operation (op);
1970  return;
1971  }
1972  if (GNUNET_NO == _GSS_is_element_of_operation (ee, op))
1973  {
1974  /* Probably confused lazily copied sets. */
1975  GNUNET_break_op (0);
1976  fail_union_operation (op);
1977  return;
1978  }
1980  GNUNET_memcpy (&emsg[1], ee->element.data, ee->element.size);
1981  emsg->reserved = htons (0);
1982  emsg->element_type = htons (ee->element.element_type);
1984  "[OP %x] Sending demanded element (size %u, hash %s) to peer\n",
1985  (void *) op,
1986  (unsigned int) ee->element.size,
1987  GNUNET_h2s (&ee->element_hash));
1988  GNUNET_MQ_send (op->mq, ev);
1990  "# exchanged elements",
1991  1,
1992  GNUNET_NO);
1993 
1994  switch (op->result_mode)
1995  {
1997  /* Nothing to do. */
1998  break;
2001  break;
2002  default:
2003  /* Result mode not supported, should have been caught earlier. */
2004  GNUNET_break (0);
2005  break;
2006  }
2007  }
2008  GNUNET_CADET_receive_done (op->channel);
2009 }
Client gets only elements that have been added to the set.
#define LOG(kind,...)
#define GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS
Actual set elements.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
int _GSS_is_element_of_operation(struct ElementEntry *ee, struct Operation *op)
Is element ee part of the set used by op?
Element should be added to the result set of the remote peer, i.e.
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_NO
Definition: gnunet_common.h:81
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.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
uint16_t element_type
Type of the element to add or remove.
Definition: set.h:293
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.
struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
#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_memcpy(dst, src, n)
Information about an element element in the set.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
A 512-bit hashcode.
Client gets notified of the required changes for both the local and the remote set.
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
Operation context used to execute a set operation.
static void send_client_element(struct Operation *op, struct GNUNET_SET_Element *element, int status)
Send a result message to the client indicating that there is a new element.
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:973
uint16_t reserved
For alignment, always zero.
Definition: set.h:298
uint16_t size
Number of bytes in the buffer pointed to by data.
Message sent by client to the service to add or remove an element to/from the set.
Definition: set.h:282
struct GNUNET_SET_Element element
The actual element.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
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:353
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
uint16_t element_type
Application-specific element type.
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
Here is the call graph for this function:

◆ check_union_p2p_offer()

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

Check offer (of struct GNUNET_HashCodes).

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

Definition at line 2020 of file gnunet-service-set_union.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SET_OPERATION_UNION, GNUNET_SYSERR, op, Set::operation, OperationState::phase, PHASE_INVENTORY_ACTIVE, PHASE_INVENTORY_PASSIVE, Operation::set, GNUNET_MessageHeader::size, and Operation::state.

2022 {
2023  struct Operation *op = cls;
2024  unsigned int num_hashes;
2025 
2027  {
2028  GNUNET_break_op (0);
2029  return GNUNET_SYSERR;
2030  }
2031  /* look up elements and send them */
2032  if ( (op->state->phase != PHASE_INVENTORY_PASSIVE) &&
2034  {
2035  GNUNET_break_op (0);
2036  return GNUNET_SYSERR;
2037  }
2038  num_hashes = (ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader))
2039  / sizeof (struct GNUNET_HashCode);
2040  if ((ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader)) !=
2041  num_hashes * sizeof (struct GNUNET_HashCode))
2042  {
2043  GNUNET_break_op (0);
2044  return GNUNET_SYSERR;
2045  }
2046  return GNUNET_OK;
2047 }
The other peer is decoding the IBF we just sent.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
We are decoding an IBF.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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.
enum IntersectionOperationPhase phase
Current state of the operation.
A 512-bit hashcode.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
enum GNUNET_SET_OperationType operation
Type of operation supported for this set.
Operation context used to execute a set operation.
Header for all communications.
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
Set union, return all elements that are in at least one of the sets.

◆ handle_union_p2p_offer()

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).

Parameters
clsthe union operation
mhthe message

Definition at line 2058 of file gnunet-service-set_union.c.

References _GSS_is_element_of_operation(), Operation::channel, Set::content, OperationState::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_SET_UNION_P2P_DEMAND, GNUNET_MQ_msg_header_extra, GNUNET_MQ_send(), GNUNET_OK, GNUNET_YES, LOG, op, Operation::set, GNUNET_MessageHeader::size, and Operation::state.

2060 {
2061  struct Operation *op = cls;
2062  const struct GNUNET_HashCode *hash;
2063  unsigned int num_hashes;
2064 
2065  num_hashes = (ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader))
2066  / sizeof (struct GNUNET_HashCode);
2067  for (hash = (const struct GNUNET_HashCode *) &mh[1];
2068  num_hashes > 0;
2069  hash++, num_hashes--)
2070  {
2071  struct ElementEntry *ee;
2072  struct GNUNET_MessageHeader *demands;
2073  struct GNUNET_MQ_Envelope *ev;
2074 
2076  hash);
2077  if (NULL != ee)
2078  if (GNUNET_YES == _GSS_is_element_of_operation (ee, op))
2079  continue;
2080 
2081  if (GNUNET_YES ==
2083  hash))
2084  {
2086  "Skipped sending duplicate demand\n");
2087  continue;
2088  }
2089 
2092  hash,
2093  NULL,
2095 
2097  "[OP %x] Requesting element (hash %s)\n",
2098  (void *) op, GNUNET_h2s (hash));
2099  ev = GNUNET_MQ_msg_header_extra (demands,
2100  sizeof (struct GNUNET_HashCode),
2102  GNUNET_memcpy (&demands[1],
2103  hash,
2104  sizeof (struct GNUNET_HashCode));
2105  GNUNET_MQ_send (op->mq, ev);
2106  }
2107  GNUNET_CADET_receive_done (op->channel);
2108 }
#define LOG(kind,...)
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
int _GSS_is_element_of_operation(struct ElementEntry *ee, struct Operation *op)
Is element ee part of the set used by op?
#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).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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.
#define GNUNET_memcpy(dst, src, n)
, &#39; bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_...
Information about an element element in the set.
A 512-bit hashcode.
#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:973
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
Header for all communications.
#define GNUNET_YES
Definition: gnunet_common.h:80
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:353
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND
Demand the whole element from the other peer, given only the hash code.
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
Here is the call graph for this function:

◆ handle_union_p2p_done()

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

Handle a done message from a remote peer.

Parameters
clsthe union operation
mhthe message

Definition at line 2118 of file gnunet-service-set_union.c.

References Operation::channel, fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_SET_OPERATION_UNION, LOG, maybe_finish(), op, Set::operation, OperationState::phase, PHASE_FINISH_CLOSING, PHASE_FINISH_WAITING, PHASE_INVENTORY_ACTIVE, PHASE_INVENTORY_PASSIVE, Operation::set, and Operation::state.

2120 {
2121  struct Operation *op = cls;
2122 
2124  {
2125  GNUNET_break_op (0);
2126  fail_union_operation (op);
2127  return;
2128  }
2129  switch (op->state->phase)
2130  {
2132  /* We got all requests, but still have to send our elements in response. */
2134 
2136  "got DONE (as passive partner), waiting for our demands to be satisfied\n");
2137  /* The active peer is done sending offers
2138  * and inquiries. This means that all
2139  * our responses to that (demands and offers)
2140  * must be in flight (queued or in mesh).
2141  *
2142  * We should notify the active peer once
2143  * all our demands are satisfied, so that the active
2144  * peer can quit if we gave it everything.
2145  */
2147  maybe_finish (op);
2148  return;
2151  "got DONE (as active partner), waiting to finish\n");
2152  /* All demands of the other peer are satisfied,
2153  * and we processed all offers, thus we know
2154  * exactly what our demands must be.
2155  *
2156  * We'll close the channel
2157  * to the other peer once our demands are met.
2158  */
2161  maybe_finish (op);
2162  return;
2163  default:
2164  GNUNET_break_op (0);
2165  fail_union_operation (op);
2166  return;
2167  }
2168 }
The other peer is decoding the IBF we just sent.
#define LOG(kind,...)
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
We are decoding an IBF.
struct GNUNET_CADET_Channel * channel
Channel to the peer.
The protocol is almost finished, but we still have to flush our message queue and/or expect some elem...
In the penultimate phase, we wait until all our demands are satisfied.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
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...
enum GNUNET_SET_OperationType operation
Type of operation supported for this set.
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:973
static void maybe_finish(struct Operation *op)
Tests if the operation is finished, and if so notify.
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
Set union, return all elements that are in at least one of the sets.
Here is the call graph for this function:

◆ handle_union_p2p_over()

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

Handle a over message from a remote peer.

Handle an over message from a remote peer.

Parameters
clsthe union operation
mhthe message

Definition at line 2177 of file gnunet-service-set_union.c.

References send_client_done().

2179 {
2180  send_client_done (cls);
2181 }
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:

◆ union_evaluate()

static struct OperationState* union_evaluate ( struct Operation op,
const struct GNUNET_MessageHeader opaque_context 
)
static

Initiate operation to evaluate a set union with a remote peer.

Parameters
opoperation to perform (to be initialized)
opaque_contextmessage to be transmitted to the listener to convince it to accept, may be NULL

Definition at line 2192 of file gnunet-service-set_union.c.

References _GSS_statistics, OperationState::demanded_hashes, GNUNET_break, GNUNET_CONTAINER_multihashmap32_size(), GNUNET_CONTAINER_multihashmap_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST, GNUNET_MQ_msg_nested_mh, GNUNET_MQ_send(), GNUNET_new, GNUNET_NO, GNUNET_SET_OPERATION_UNION, GNUNET_STATISTICS_update(), OperationState::initial_size, initialize_key_to_element(), OperationState::key_to_element, LOG, Operation::mq, msg, OperationRequestMessage::operation, OperationState::phase, PHASE_EXPECT_SE, OperationState::salt_receive, OperationState::salt_send, OperationState::se, SetState::se, Operation::set, state, Operation::state, Set::state, and strata_estimator_dup().

Referenced by _GSS_union_vt().

2194 {
2195  struct OperationState *state;
2196  struct GNUNET_MQ_Envelope *ev;
2197  struct OperationRequestMessage *msg;
2198 
2199  ev = GNUNET_MQ_msg_nested_mh (msg,
2201  opaque_context);
2202  if (NULL == ev)
2203  {
2204  /* the context message is too large */
2205  GNUNET_break (0);
2206  return NULL;
2207  }
2208  state = GNUNET_new (struct OperationState);
2210  GNUNET_NO);
2211  /* copy the current generation's strata estimator for this operation */
2212  state->se = strata_estimator_dup (op->set->state->se);
2213  /* we started the operation, thus we have to send the operation request */
2214  state->phase = PHASE_EXPECT_SE;
2215  state->salt_receive = state->salt_send = 42; // FIXME?????
2217  "Initiating union operation evaluation\n");
2219  "# of total union operations",
2220  1,
2221  GNUNET_NO);
2223  "# of initiated union operations",
2224  1,
2225  GNUNET_NO);
2226  msg->operation = htonl (GNUNET_SET_OPERATION_UNION);
2227  GNUNET_MQ_send (op->mq,
2228  ev);
2229 
2230  if (NULL != opaque_context)
2232  "sent op request with context message\n");
2233  else
2235  "sent op request without context message\n");
2236 
2237  op->state = state;
2240  return state;
2241 }
struct StrataEstimator * se
The strata estimator is only generated once for each set.
State of an evaluate operation with another peer.
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
#define LOG(kind,...)
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
#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 SetState * state
Implementation-specific state.
#define GNUNET_NO
Definition: gnunet_common.h:81
uint64_t initial_size
Initial size of our set, just before the operation started.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
uint32_t salt_send
Salt that we&#39;re using for sending IBFs.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
We sent the request message, and expect a strata estimator.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct StrataEstimator * strata_estimator_dup(struct StrataEstimator *se)
Make a copy of a strata estimator.
struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
uint32_t salt_receive
Salt for the IBF we&#39;ve received and that we&#39;re currently decoding.
struct StrataEstimator * se
Copy of the set&#39;s strata estimator at the time of creation of this operation.
#define GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST
Request a set operation from a remote peer.
enum State state
current state of profiling
enum IntersectionOperationPhase phase
Current state of the operation.
unsigned int GNUNET_CONTAINER_multihashmap32_size(const struct GNUNET_CONTAINER_MultiHashMap32 *map)
Get the number of key-value pairs in the map.
static void initialize_key_to_element(struct Operation *op)
Initialize the IBF key to element mapping local to this set operation.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
uint32_t operation
Operation to request, values from enum GNUNET_SET_OperationType
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
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:353
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
struct OperationState * state
Operation-specific operation state.
Set union, return all elements that are in at least one of the sets.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ union_accept()

static struct OperationState* union_accept ( struct Operation op)
static

Accept an union operation request from a remote peer.

Only initializes the private operation state.

Parameters
opoperation that will be accepted as a union operation

Definition at line 2251 of file gnunet-service-set_union.c.

References _GSS_statistics, buf, Set::content, OperationState::demanded_hashes, SetContent::elements, GNUNET_CONTAINER_multihashmap32_size(), GNUNET_CONTAINER_multihashmap_create(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_htonll(), GNUNET_malloc, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_new, GNUNET_NO, GNUNET_STATISTICS_update(), IBF_BUCKET_SIZE, StrataEstimator::ibf_size, OperationState::initial_size, initialize_key_to_element(), OperationState::key_to_element, len, LOG, Operation::mq, OperationState::phase, PHASE_EXPECT_IBF, OperationState::salt_receive, OperationState::salt_send, OperationState::se, SetState::se, Operation::set, StrataEstimatorMessage::set_size, state, Operation::state, Set::state, StrataEstimator::strata_count, strata_estimator_dup(), strata_estimator_write(), and type.

Referenced by _GSS_union_vt().

2252 {
2253  struct OperationState *state;
2254  const struct StrataEstimator *se;
2255  struct GNUNET_MQ_Envelope *ev;
2256  struct StrataEstimatorMessage *strata_msg;
2257  char *buf;
2258  size_t len;
2259  uint16_t type;
2260 
2262  "accepting set union operation\n");
2264  "# of accepted union operations",
2265  1,
2266  GNUNET_NO);
2268  "# of total union operations",
2269  1,
2270  GNUNET_NO);
2271 
2272  state = GNUNET_new (struct OperationState);
2273  state->se = strata_estimator_dup (op->set->state->se);
2275  GNUNET_NO);
2276  state->salt_receive = state->salt_send = 42; // FIXME?????
2277  op->state = state;
2280 
2281  /* kick off the operation */
2282  se = state->se;
2283  buf = GNUNET_malloc (se->strata_count * IBF_BUCKET_SIZE * se->ibf_size);
2284  len = strata_estimator_write (se,
2285  buf);
2286  if (len < se->strata_count * IBF_BUCKET_SIZE * se->ibf_size)
2288  else
2290  ev = GNUNET_MQ_msg_extra (strata_msg,
2291  len,
2292  type);
2293  GNUNET_memcpy (&strata_msg[1],
2294  buf,
2295  len);
2296  GNUNET_free (buf);
2297  strata_msg->set_size
2299  GNUNET_MQ_send (op->mq,
2300  ev);
2301  state->phase = PHASE_EXPECT_IBF;
2302  return state;
2303 }
We sent the strata estimator, and expect an IBF.
struct StrataEstimator * se
The strata estimator is only generated once for each set.
State of an evaluate operation with another peer.
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
#define LOG(kind,...)
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
struct SetState * state
Implementation-specific state.
#define GNUNET_NO
Definition: gnunet_common.h:81
uint64_t initial_size
Initial size of our set, just before the operation started.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
uint32_t salt_send
Salt that we&#39;re using for sending IBFs.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
A handle to a strata estimator.
struct StrataEstimator * strata_estimator_dup(struct StrataEstimator *se)
Make a copy of a strata estimator.
struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
#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
uint32_t salt_receive
Salt for the IBF we&#39;ve received and that we&#39;re currently decoding.
struct StrataEstimator * se
Copy of the set&#39;s strata estimator at the time of creation of this operation.
enum State state
current state of profiling
#define GNUNET_memcpy(dst, src, n)
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC
Compressed strata estimator.
enum IntersectionOperationPhase phase
Current state of the operation.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE
Strata estimator.
#define IBF_BUCKET_SIZE
Size of one ibf bucket in bytes.
Definition: ibf.h:72
unsigned int GNUNET_CONTAINER_multihashmap32_size(const struct GNUNET_CONTAINER_MultiHashMap32 *map)
Get the number of key-value pairs in the map.
static char buf[2048]
unsigned int strata_count
Size of the IBF array in strata.
size_t strata_estimator_write(const struct StrataEstimator *se, void *buf)
Write the given strata estimator to the buffer.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
Strata estimator together with the peer&#39;s overall set size.
static void initialize_key_to_element(struct Operation *op)
Initialize the IBF key to element mapping local to this set operation.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
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:353
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
struct OperationState * state
Operation-specific operation state.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
unsigned int ibf_size
Size of each IBF stratum (in bytes)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ union_set_create()

static struct SetState* union_set_create ( void  )
static

Create a new set supporting the union operation.

We maintain one strata estimator per set and then manipulate it over the lifetime of the set, as recreating a strata estimator would be expensive.

Returns
the newly created set, NULL on error

Definition at line 2315 of file gnunet-service-set_union.c.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_new, LOG, SetState::se, SE_IBF_HASH_NUM, SE_IBF_SIZE, SE_STRATA_COUNT, and strata_estimator_create().

Referenced by _GSS_union_vt().

2316 {
2317  struct SetState *set_state;
2318 
2320  "union set created\n");
2321  set_state = GNUNET_new (struct SetState);
2324  if (NULL == set_state->se)
2325  {
2327  "Failed to allocate strata estimator\n");
2328  GNUNET_free (set_state);
2329  return NULL;
2330  }
2331  return set_state;
2332 }
struct StrataEstimator * se
The strata estimator is only generated once for each set.
#define LOG(kind,...)
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.
Extra state required for efficient set intersection.
#define SE_IBF_SIZE
Size of the IBFs in the strata estimator.
#define SE_IBF_HASH_NUM
The hash num parameter for the difference digests and strata estimators.
#define GNUNET_log(kind,...)
#define SE_STRATA_COUNT
Number of IBFs in a strata estimator.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ union_add()

static void union_add ( struct SetState set_state,
struct ElementEntry ee 
)
static

Add the element from the given element message to the set.

Parameters
set_statestate of the set want to add to
eethe element to add to the set

Definition at line 2342 of file gnunet-service-set_union.c.

References ElementEntry::element_hash, get_ibf_key(), SetState::se, and strata_estimator_insert().

Referenced by _GSS_union_vt().

2344 {
2345  strata_estimator_insert (set_state->se,
2346  get_ibf_key (&ee->element_hash));
2347 }
struct StrataEstimator * se
The strata estimator is only generated once for each set.
struct GNUNET_HashCode element_hash
Hash of the element.
void strata_estimator_insert(struct StrataEstimator *se, struct IBF_Key key)
Add a key to the strata estimator.
static struct IBF_Key get_ibf_key(const struct GNUNET_HashCode *src)
Derive the IBF key from a hash code and a salt.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ union_remove()

static void union_remove ( struct SetState set_state,
struct ElementEntry ee 
)
static

Remove the element given in the element message from the set.

Only marks the element as removed, so that older set operations can still exchange it.

Parameters
set_statestate of the set to remove from
eeset element to remove

Definition at line 2358 of file gnunet-service-set_union.c.

References ElementEntry::element_hash, get_ibf_key(), SetState::se, and strata_estimator_remove().

Referenced by _GSS_union_vt().

2360 {
2361  strata_estimator_remove (set_state->se,
2362  get_ibf_key (&ee->element_hash));
2363 }
struct StrataEstimator * se
The strata estimator is only generated once for each set.
struct GNUNET_HashCode element_hash
Hash of the element.
void strata_estimator_remove(struct StrataEstimator *se, struct IBF_Key key)
Remove a key from the strata estimator.
static struct IBF_Key get_ibf_key(const struct GNUNET_HashCode *src)
Derive the IBF key from a hash code and a salt.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ union_set_destroy()

static void union_set_destroy ( struct SetState set_state)
static

Destroy a set that supports the union operation.

Parameters
set_statethe set to destroy

Definition at line 2372 of file gnunet-service-set_union.c.

References GNUNET_free, SetState::se, and strata_estimator_destroy().

Referenced by _GSS_union_vt().

2373 {
2374  if (NULL != set_state->se)
2375  {
2376  strata_estimator_destroy (set_state->se);
2377  set_state->se = NULL;
2378  }
2379  GNUNET_free (set_state);
2380 }
struct StrataEstimator * se
The strata estimator is only generated once for each set.
void strata_estimator_destroy(struct StrataEstimator *se)
Destroy a strata estimator, free all of its resources.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ union_copy_state()

static struct SetState* union_copy_state ( struct SetState state)
static

Copy union-specific set state.

Parameters
statesource state for copying the union state
Returns
a copy of the union-specific set state

Definition at line 2390 of file gnunet-service-set_union.c.

References GNUNET_assert, GNUNET_new, SetState::se, and strata_estimator_dup().

Referenced by _GSS_union_vt().

2391 {
2392  struct SetState *new_state;
2393 
2394  GNUNET_assert ( (NULL != state) &&
2395  (NULL != state->se) );
2396  new_state = GNUNET_new (struct SetState);
2397  new_state->se = strata_estimator_dup (state->se);
2398 
2399  return new_state;
2400 }
struct StrataEstimator * se
The strata estimator is only generated once for each set.
#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.
struct StrataEstimator * strata_estimator_dup(struct StrataEstimator *se)
Make a copy of a strata estimator.
Extra state required for efficient set intersection.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ union_channel_death()

static void union_channel_death ( struct Operation op)
static

Handle case where channel went down for an operation.

Parameters
opoperation that lost the channel

Definition at line 2409 of file gnunet-service-set_union.c.

References _GSS_operation_destroy(), GNUNET_YES, and send_client_done().

Referenced by _GSS_union_vt().

2410 {
2411  send_client_done (op);
2413  GNUNET_YES);
2414 }
void _GSS_operation_destroy(struct Operation *op, int gc)
Destroy the given operation.
static void send_client_done(void *cls)
Signal to the client that the operation has finished and destroy the operation.
#define GNUNET_YES
Definition: gnunet_common.h:80
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _GSS_union_vt()

const struct SetVT* _GSS_union_vt ( void  )

Get the table with implementing functions for set union.

Returns
the operation specific VTable

Definition at line 2424 of file gnunet-service-set_union.c.

References SetVT::create, union_accept(), union_add(), union_channel_death(), union_copy_state(), union_evaluate(), union_op_cancel(), union_remove(), union_set_create(), and union_set_destroy().

Referenced by handle_client_copy_lazy_connect(), and handle_client_create_set().

2425 {
2426  static const struct SetVT union_vt = {
2428  .add = &union_add,
2429  .remove = &union_remove,
2430  .destroy_set = &union_set_destroy,
2431  .evaluate = &union_evaluate,
2432  .accept = &union_accept,
2433  .cancel = &union_op_cancel,
2434  .copy_state = &union_copy_state,
2435  .channel_death = &union_channel_death
2436  };
2437 
2438  return &union_vt;
2439 }
static struct OperationState * union_accept(struct Operation *op)
Accept an union operation request from a remote peer.
static void union_set_destroy(struct SetState *set_state)
Destroy a set that supports the union operation.
static void union_add(struct SetState *set_state, struct ElementEntry *ee)
Add the element from the given element message to the set.
static struct OperationState * union_evaluate(struct Operation *op, const struct GNUNET_MessageHeader *opaque_context)
Initiate operation to evaluate a set union with a remote peer.
static struct SetState * union_set_create(void)
Create a new set supporting the union operation.
Dispatch table for a specific set operation.
static void union_op_cancel(struct Operation *op)
Destroy the union operation.
static void union_channel_death(struct Operation *op)
Handle case where channel went down for an operation.
SetCreateImpl create
Callback for the set creation.
static struct SetState * union_copy_state(struct SetState *state)
Copy union-specific set state.
static void union_remove(struct SetState *set_state, struct ElementEntry *ee)
Remove the element given in the element message from the set.
Here is the call graph for this function:
Here is the caller graph for this function: