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.

77  {
82 
93 
98 
103 
108 
114 
122 
128  PHASE_DONE,
129 
135 };
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 285 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().

288 {
289  struct KeyEntry *k = value;
290 
291  GNUNET_assert(NULL != k);
292  if (GNUNET_YES == k->element->remote)
293  {
294  GNUNET_free(k->element);
295  k->element = NULL;
296  }
297  GNUNET_free(k);
298  return GNUNET_YES;
299 }
#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:77
#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 309 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().

310 {
312  "destroying union op\n");
313  /* check if the op was canceled twice */
314  GNUNET_assert(NULL != op->state);
315  if (NULL != op->state->remote_ibf)
316  {
318  op->state->remote_ibf = NULL;
319  }
320  if (NULL != op->state->demanded_hashes)
321  {
323  op->state->demanded_hashes = NULL;
324  }
325  if (NULL != op->state->local_ibf)
326  {
328  op->state->local_ibf = NULL;
329  }
330  if (NULL != op->state->se)
331  {
333  op->state->se = NULL;
334  }
335  if (NULL != op->state->key_to_element)
336  {
339  NULL);
341  op->state->key_to_element = NULL;
342  }
343  GNUNET_free(op->state);
344  op->state = NULL;
346  "destroying union op done\n");
347 }
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.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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:392
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 357 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().

358 {
359  struct GNUNET_MQ_Envelope *ev;
361 
363  "union operation failed\n");
366  msg->request_id = htonl(op->client_request_id);
367  msg->element_type = htons(0);
368  GNUNET_MQ_send(op->set->cs->mq,
369  ev);
371 }
#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:238
#define GNUNET_MESSAGE_TYPE_SET_RESULT
Create an empty set.
uint32_t request_id
id the result belongs to
Definition: set.h:252
#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:258
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: set.h:263
uint32_t client_request_id
ID used to identify an operation between service and client.
#define GNUNET_YES
Definition: gnunet_common.h:77
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:351
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 382 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().

383 {
384  struct IBF_Key key;
385  uint16_t salt = 0;
386 
388  GNUNET_CRYPTO_kdf(&key, sizeof(key),
389  src, sizeof *src,
390  &salt, sizeof(salt),
391  NULL, 0));
392  return key;
393 }
#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:75
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 423 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().

426 {
427  struct GetElementContext *ctx = cls;
428  struct KeyEntry *k = value;
429 
430  GNUNET_assert(NULL != k);
432  &ctx->hash))
433  {
434  ctx->k = k;
435  return GNUNET_NO;
436  }
437  return GNUNET_YES;
438 }
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:78
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:77
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 450 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().

452 {
453  int ret;
454  struct IBF_Key ibf_key;
455  struct GetElementContext ctx = { { { 0 } }, 0 };
456 
457  ctx.hash = *element_hash;
458 
459  ibf_key = get_ibf_key(element_hash);
461  (uint32_t)ibf_key.key_val,
463  &ctx);
464 
465  /* was the iteration aborted because we found the element? */
466  if (GNUNET_SYSERR == ret)
467  {
468  GNUNET_assert(NULL != ctx.k);
469  return ctx.k;
470  }
471  return NULL;
472 }
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.
int GNUNET_CONTAINER_multihashmap32_get_multiple(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
static 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:76
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 490 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().

493 {
494  struct IBF_Key ibf_key;
495  struct KeyEntry *k;
496 
498  k = GNUNET_new(struct KeyEntry);
499  k->element = ee;
500  k->ibf_key = ibf_key;
501  k->received = received;
504  (uint32_t)ibf_key.key_val,
505  k,
507 }
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:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
uint64_t key_val
Definition: ibf.h:46
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 514 of file gnunet-service-set_union.c.

References IBF_Key::key_val.

Referenced by prepare_ibf_iterator().

517 {
518  int s = salt % 64;
519  uint64_t x = k_in->key_val;
520 
521  /* rotate ibf key */
522  x = (x >> s) | (x << (64 - s));
523  k_out->key_val = x;
524 }
uint64_t key_val
Definition: ibf.h:46
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 531 of file gnunet-service-set_union.c.

References IBF_Key::key_val.

Referenced by decode_and_send(), and handle_union_p2p_inquiry().

534 {
535  int s = salt % 64;
536  uint64_t x = k_in->key_val;
537 
538  x = (x << s) | (x >> (64 - s));
539  k_out->key_val = x;
540 }
uint64_t key_val
Definition: ibf.h:46
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 551 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().

554 {
555  struct Operation *op = cls;
556  struct KeyEntry *ke = value;
557  struct IBF_Key salted_key;
558 
560  "[OP %x] inserting %lx (hash %s) into ibf\n",
561  (void *)op,
562  (unsigned long)ke->ibf_key.key_val,
564  salt_key(&ke->ibf_key,
565  op->state->salt_send,
566  &salted_key);
567  ibf_insert(op->state->local_ibf, salted_key);
568  return GNUNET_YES;
569 }
#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:46
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:77
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 583 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().

586 {
587  struct Operation *op = cls;
588  struct ElementEntry *ee = value;
589 
590  /* make sure that the element belongs to the set at the time
591  * of creating the operation */
592  if (GNUNET_NO ==
594  op))
595  return GNUNET_YES;
598  ee,
599  GNUNET_NO);
600  return GNUNET_YES;
601 }
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:78
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:77
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 611 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().

612 {
613  unsigned int len;
614 
615  GNUNET_assert(NULL == op->state->key_to_element);
620  op);
621 }
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.
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.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
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 633 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().

635 {
636  GNUNET_assert(NULL != op->state->key_to_element);
637 
638  if (NULL != op->state->local_ibf)
641  if (NULL == op->state->local_ibf)
642  {
644  "Failed to allocate local IBF\n");
645  return GNUNET_SYSERR;
646  }
649  op);
650  return GNUNET_OK;
651 }
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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:76
static unsigned int size
Size of the "table".
Definition: peer.c:66
void ibf_destroy(struct InvertibleBloomFilter *ibf)
Destroy all resources associated with the invertible bloom filter.
Definition: ibf.c:392
struct InvertibleBloomFilter * ibf_create(uint32_t size, uint8_t hash_num)
Create an invertible bloom filter.
Definition: ibf.c:76
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 664 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().

666 {
667  unsigned int buckets_sent = 0;
668  struct InvertibleBloomFilter *ibf;
669 
670  if (GNUNET_OK !=
671  prepare_ibf(op, 1 << ibf_order))
672  {
673  /* allocation failed */
674  return GNUNET_SYSERR;
675  }
676 
678  "sending ibf of size %u\n",
679  1 << ibf_order);
680 
681  {
682  char name[64] = { 0 };
683  snprintf(name, sizeof(name), "# sent IBF (order %u)", ibf_order);
685  }
686 
687  ibf = op->state->local_ibf;
688 
689  while (buckets_sent < (1 << ibf_order))
690  {
691  unsigned int buckets_in_message;
692  struct GNUNET_MQ_Envelope *ev;
693  struct IBFMessage *msg;
694 
695  buckets_in_message = (1 << ibf_order) - buckets_sent;
696  /* limit to maximum */
697  if (buckets_in_message > MAX_BUCKETS_PER_MESSAGE)
698  buckets_in_message = MAX_BUCKETS_PER_MESSAGE;
699 
700  ev = GNUNET_MQ_msg_extra(msg,
701  buckets_in_message * IBF_BUCKET_SIZE,
703  msg->reserved1 = 0;
704  msg->reserved2 = 0;
705  msg->order = ibf_order;
706  msg->offset = htonl(buckets_sent);
707  msg->salt = htonl(op->state->salt_send);
708  ibf_write_slice(ibf, buckets_sent,
709  buckets_in_message, &msg[1]);
710  buckets_sent += buckets_in_message;
712  "ibf chunk size %u, %u/%u sent\n",
713  buckets_in_message,
714  buckets_sent,
715  1 << ibf_order);
716  GNUNET_MQ_send(op->mq, ev);
717  }
718 
719  /* The other peer must decode the IBF, so
720  * we're passive. */
722  return GNUNET_OK;
723 }
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:79
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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:287
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:69
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
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:351
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 734 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().

735 {
736  unsigned int ibf_order;
737 
738  ibf_order = 2;
739  while (((1 << ibf_order) < (IBF_ALPHA * diff) ||
740  ((1 << ibf_order) < SE_IBF_HASH_NUM)) &&
741  (ibf_order < MAX_IBF_ORDER))
742  ibf_order++;
743  // add one for correction
744  return ibf_order + 1;
745 }
#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 758 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().

761 {
762  struct Operation *op = cls;
763  struct GNUNET_SET_ElementMessage *emsg;
764  struct ElementEntry *ee = value;
765  struct GNUNET_SET_Element *el = &ee->element;
766  struct GNUNET_MQ_Envelope *ev;
767 
769  "Sending element %s\n",
770  GNUNET_h2s(key));
771  ev = GNUNET_MQ_msg_extra(emsg,
772  el->size,
774  emsg->element_type = htons(el->element_type);
775  GNUNET_memcpy(&emsg[1],
776  el->data,
777  el->size);
778  GNUNET_MQ_send(op->mq,
779  ev);
780  return GNUNET_YES;
781 }
#define LOG(kind,...)
static struct GNUNET_IDENTITY_EgoLookup * el
EgoLookup.
Element stored in a set.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint16_t element_type
Type of the element to add or remove.
Definition: set.h:283
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
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:273
struct GNUNET_SET_Element element
The actual element.
#define GNUNET_YES
Definition: gnunet_common.h:77
#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:351
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 790 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().

791 {
792  struct GNUNET_MQ_Envelope *ev;
793 
796  "Dedicing to transmit the full set\n");
797  /* FIXME: use a more memory-friendly way of doing this with an
798  iterator, just as we do in the non-full case! */
801  op);
803  GNUNET_MQ_send(op->mq,
804  ev);
805 }
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...
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:351
struct OperationState * state
Operation-specific operation state.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
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 815 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.

817 {
818  struct Operation *op = cls;
819  int is_compressed;
820  size_t len;
821 
822  if (op->state->phase != PHASE_EXPECT_SE)
823  {
824  GNUNET_break(0);
825  return GNUNET_SYSERR;
826  }
827  is_compressed = (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC == htons(msg->header.type));
828  len = ntohs(msg->header.size) - sizeof(struct StrataEstimatorMessage);
829  if ((GNUNET_NO == is_compressed) &&
831  {
832  GNUNET_break(0);
833  return GNUNET_SYSERR;
834  }
835  return GNUNET_OK;
836 }
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE(C)
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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:69
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
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 846 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.

848 {
849  struct Operation *op = cls;
850  struct StrataEstimator *remote_se;
851  unsigned int diff;
852  uint64_t other_size;
853  size_t len;
854  int is_compressed;
855 
856  is_compressed = (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC == htons(msg->header.type));
858  "# bytes of SE received",
859  ntohs(msg->header.size),
860  GNUNET_NO);
861  len = ntohs(msg->header.size) - sizeof(struct StrataEstimatorMessage);
862  other_size = GNUNET_ntohll(msg->set_size);
864  SE_IBF_SIZE,
866  if (NULL == remote_se)
867  {
868  /* insufficient resources, fail */
870  return;
871  }
872  if (GNUNET_OK !=
873  strata_estimator_read(&msg[1],
874  len,
875  is_compressed,
876  remote_se))
877  {
878  /* decompression failed */
879  strata_estimator_destroy(remote_se);
881  return;
882  }
883  GNUNET_assert(NULL != op->state->se);
884  diff = strata_estimator_difference(remote_se,
885  op->state->se);
886 
887  if (diff > 200)
888  diff = diff * 3 / 2;
889 
890  strata_estimator_destroy(remote_se);
892  op->state->se = NULL;
894  "got se diff=%d, using ibf size %d\n",
895  diff,
896  1U << get_order_from_difference(diff));
897 
898  {
899  char *set_debug;
900 
901  set_debug = getenv("GNUNET_SET_BENCHMARK");
902  if ((NULL != set_debug) &&
903  (0 == strcmp(set_debug, "1")))
904  {
905  FILE *f = fopen("set.log", "a");
906  fprintf(f, "%llu\n", (unsigned long long)diff);
907  fclose(f);
908  }
909  }
910 
911  if ((GNUNET_YES == op->byzantine) &&
912  (other_size < op->byzantine_lower_bound))
913  {
914  GNUNET_break(0);
916  return;
917  }
918 
919  if ((GNUNET_YES == op->force_full) ||
920  (diff > op->state->initial_size / 4) ||
921  (0 == other_size))
922  {
924  "Deciding to go for full set transmission (diff=%d, own set=%u)\n",
925  diff,
926  op->state->initial_size);
928  "# of full sends",
929  1,
930  GNUNET_NO);
931  if ((op->state->initial_size <= other_size) ||
932  (0 == other_size))
933  {
934  send_full_set(op);
935  }
936  else
937  {
938  struct GNUNET_MQ_Envelope *ev;
939 
941  "Telling other peer that we expect its full set\n");
944  GNUNET_MQ_send(op->mq,
945  ev);
946  }
947  }
948  else
949  {
951  "# of ibf sends",
952  1,
953  GNUNET_NO);
954  if (GNUNET_OK !=
955  send_ibf(op,
957  {
958  /* Internal error, best we can do is shut the connection */
960  "Failed to send IBF, closing connection\n");
962  return;
963  }
964  }
966 }
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:78
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:75
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:951
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:77
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:351
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 977 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().

980 {
981  struct SendElementClosure *sec = cls;
982  struct Operation *op = sec->op;
983  struct KeyEntry *ke = value;
984  struct GNUNET_MQ_Envelope *ev;
985  struct GNUNET_MessageHeader *mh;
986 
987  /* Detect 32-bit key collision for the 64-bit IBF keys. */
988  if (ke->ibf_key.key_val != sec->ibf_key.key_val)
989  return GNUNET_YES;
990 
992  sizeof(struct GNUNET_HashCode),
994 
995  GNUNET_assert(NULL != ev);
996  *(struct GNUNET_HashCode *)&mh[1] = ke->element->element_hash;
998  "[OP %x] sending element offer (%s) to peer\n",
999  (void *)op,
1001  GNUNET_MQ_send(op->mq, ev);
1002  return GNUNET_YES;
1003 }
#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:46
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:77
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:351
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 1013 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().

1015 {
1016  struct SendElementClosure send_cls;
1017 
1018  send_cls.ibf_key = ibf_key;
1019  send_cls.op = op;
1021  (uint32_t)ibf_key.key_val,
1023  &send_cls);
1024 }
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
uint64_t key_val
Definition: ibf.h:46
int GNUNET_CONTAINER_multihashmap32_get_multiple(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
static int send_offers_iterator(void *cls, uint32_t key, void *value)
Iterator to send elements to a remote peer.
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 1035 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().

1036 {
1037  struct IBF_Key key;
1038  struct IBF_Key last_key;
1039  int side;
1040  unsigned int num_decoded;
1041  struct InvertibleBloomFilter *diff_ibf;
1042 
1044 
1045  if (GNUNET_OK !=
1046  prepare_ibf(op,
1047  op->state->remote_ibf->size))
1048  {
1049  GNUNET_break(0);
1050  /* allocation failed */
1051  return GNUNET_SYSERR;
1052  }
1053  diff_ibf = ibf_dup(op->state->local_ibf);
1054  ibf_subtract(diff_ibf,
1055  op->state->remote_ibf);
1056 
1058  op->state->remote_ibf = NULL;
1059 
1061  "decoding IBF (size=%u)\n",
1062  diff_ibf->size);
1063 
1064  num_decoded = 0;
1065  key.key_val = 0; /* just to avoid compiler thinking we use undef'ed variable */
1066 
1067  while (1)
1068  {
1069  int res;
1070  int cycle_detected = GNUNET_NO;
1071 
1072  last_key = key;
1073 
1074  res = ibf_decode(diff_ibf, &side, &key);
1075  if (res == GNUNET_OK)
1076  {
1078  "decoded ibf key %lx\n",
1079  (unsigned long)key.key_val);
1080  num_decoded += 1;
1081  if ((num_decoded > diff_ibf->size) ||
1082  ((num_decoded > 1) &&
1083  (last_key.key_val == key.key_val)))
1084  {
1086  "detected cyclic ibf (decoded %u/%u)\n",
1087  num_decoded,
1088  diff_ibf->size);
1089  cycle_detected = GNUNET_YES;
1090  }
1091  }
1092  if ((GNUNET_SYSERR == res) ||
1093  (GNUNET_YES == cycle_detected))
1094  {
1095  int next_order;
1096  next_order = 0;
1097  while (1 << next_order < diff_ibf->size)
1098  next_order++;
1099  next_order++;
1100  if (next_order <= MAX_IBF_ORDER)
1101  {
1103  "decoding failed, sending larger ibf (size %u)\n",
1104  1 << next_order);
1106  "# of IBF retries",
1107  1,
1108  GNUNET_NO);
1109  op->state->salt_send++;
1110  if (GNUNET_OK !=
1111  send_ibf(op, next_order))
1112  {
1113  /* Internal error, best we can do is shut the connection */
1115  "Failed to send IBF, closing connection\n");
1117  ibf_destroy(diff_ibf);
1118  return GNUNET_SYSERR;
1119  }
1120  }
1121  else
1122  {
1124  "# of failed union operations (too large)",
1125  1,
1126  GNUNET_NO);
1127  // XXX: Send the whole set, element-by-element
1129  "set union failed: reached ibf limit\n");
1131  ibf_destroy(diff_ibf);
1132  return GNUNET_SYSERR;
1133  }
1134  break;
1135  }
1136  if (GNUNET_NO == res)
1137  {
1138  struct GNUNET_MQ_Envelope *ev;
1139 
1141  "transmitted all values, sending DONE\n");
1143  GNUNET_MQ_send(op->mq, ev);
1144  /* We now wait until we get a DONE message back
1145  * and then wait for our MQ to be flushed and all our
1146  * demands be delivered. */
1147  break;
1148  }
1149  if (1 == side)
1150  {
1151  struct IBF_Key unsalted_key;
1152 
1153  unsalt_key(&key,
1154  op->state->salt_receive,
1155  &unsalted_key);
1157  unsalted_key);
1158  }
1159  else if (-1 == side)
1160  {
1161  struct GNUNET_MQ_Envelope *ev;
1162  struct InquiryMessage *msg;
1163 
1164  /* It may be nice to merge multiple requests, but with CADET's corking it is not worth
1165  * the effort additional complexity. */
1166  ev = GNUNET_MQ_msg_extra(msg,
1167  sizeof(struct IBF_Key),
1169  msg->salt = htonl(op->state->salt_receive);
1170  GNUNET_memcpy(&msg[1],
1171  &key,
1172  sizeof(struct IBF_Key));
1174  "sending element inquiry for IBF key %lx\n",
1175  (unsigned long)key.key_val);
1176  GNUNET_MQ_send(op->mq, ev);
1177  }
1178  else
1179  {
1180  GNUNET_assert(0);
1181  }
1182  }
1183  ibf_destroy(diff_ibf);
1184  return GNUNET_OK;
1185 }
#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:79
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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:371
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:83
#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.
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:225
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:349
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:76
static unsigned int size
Size of the "table".
Definition: peer.c:66
void ibf_destroy(struct InvertibleBloomFilter *ibf)
Destroy all resources associated with the invertible bloom filter.
Definition: ibf.c:392
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:77
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:351
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 1199 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.

1201 {
1202  struct Operation *op = cls;
1203  unsigned int buckets_in_message;
1204 
1206  {
1207  GNUNET_break_op(0);
1208  return GNUNET_SYSERR;
1209  }
1210  buckets_in_message = (ntohs(msg->header.size) - sizeof *msg) / IBF_BUCKET_SIZE;
1211  if (0 == buckets_in_message)
1212  {
1213  GNUNET_break_op(0);
1214  return GNUNET_SYSERR;
1215  }
1216  if ((ntohs(msg->header.size) - sizeof *msg) != buckets_in_message * IBF_BUCKET_SIZE)
1217  {
1218  GNUNET_break_op(0);
1219  return GNUNET_SYSERR;
1220  }
1221  if (op->state->phase == PHASE_EXPECT_IBF_CONT)
1222  {
1223  if (ntohl(msg->offset) != op->state->ibf_buckets_received)
1224  {
1225  GNUNET_break_op(0);
1226  return GNUNET_SYSERR;
1227  }
1228  if (1 << msg->order != op->state->remote_ibf->size)
1229  {
1230  GNUNET_break_op(0);
1231  return GNUNET_SYSERR;
1232  }
1233  if (ntohl(msg->salt) != op->state->salt_receive)
1234  {
1235  GNUNET_break_op(0);
1236  return GNUNET_SYSERR;
1237  }
1238  }
1239  else if ((op->state->phase != PHASE_INVENTORY_PASSIVE) &&
1240  (op->state->phase != PHASE_EXPECT_IBF))
1241  {
1242  GNUNET_break_op(0);
1243  return GNUNET_SYSERR;
1244  }
1245 
1246  return GNUNET_OK;
1247 }
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:75
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:83
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:69
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:76
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 1260 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.

1262 {
1263  struct Operation *op = cls;
1264  unsigned int buckets_in_message;
1265 
1266  buckets_in_message = (ntohs(msg->header.size) - sizeof *msg) / IBF_BUCKET_SIZE;
1267  if ((op->state->phase == PHASE_INVENTORY_PASSIVE) ||
1268  (op->state->phase == PHASE_EXPECT_IBF))
1269  {
1271  GNUNET_assert(NULL == op->state->remote_ibf);
1273  "Creating new ibf of size %u\n",
1274  1 << msg->order);
1275  op->state->remote_ibf = ibf_create(1 << msg->order, SE_IBF_HASH_NUM);
1276  op->state->salt_receive = ntohl(msg->salt);
1278  "Receiving new IBF with salt %u\n",
1279  op->state->salt_receive);
1280  if (NULL == op->state->remote_ibf)
1281  {
1283  "Failed to parse remote IBF, closing connection\n");
1285  return;
1286  }
1287  op->state->ibf_buckets_received = 0;
1288  if (0 != ntohl(msg->offset))
1289  {
1290  GNUNET_break_op(0);
1292  return;
1293  }
1294  }
1295  else
1296  {
1299  "Received more of IBF\n");
1300  }
1301  GNUNET_assert(NULL != op->state->remote_ibf);
1302 
1303  ibf_read_slice(&msg[1],
1305  buckets_in_message,
1306  op->state->remote_ibf);
1307  op->state->ibf_buckets_received += buckets_in_message;
1308 
1309  if (op->state->ibf_buckets_received == op->state->remote_ibf->size)
1310  {
1312  "received full ibf\n");
1314  if (GNUNET_OK !=
1315  decode_and_send(op))
1316  {
1317  /* Internal error, best we can do is shut down */
1319  "Failed to decode IBF, closing connection\n");
1321  return;
1322  }
1323  }
1325 }
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:75
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:83
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:69
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:318
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:951
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 1337 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().

1340 {
1341  struct GNUNET_MQ_Envelope *ev;
1342  struct GNUNET_SET_ResultMessage *rm;
1343 
1345  "sending element (size %u) to client\n",
1346  element->size);
1347  GNUNET_assert(0 != op->client_request_id);
1349  if (NULL == ev)
1350  {
1351  GNUNET_MQ_discard(ev);
1352  GNUNET_break(0);
1353  return;
1354  }
1355  rm->result_status = htons(status);
1356  rm->request_id = htonl(op->client_request_id);
1357  rm->element_type = htons(element->element_type);
1359  GNUNET_memcpy(&rm[1],
1360  element->data,
1361  element->size);
1362  GNUNET_MQ_send(op->set->cs->mq,
1363  ev);
1364 }
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:238
#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:252
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#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:247
#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
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SET_Status in NBO.
Definition: set.h:258
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:319
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:263
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:351
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 1374 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().

1375 {
1376  struct Operation *op = cls;
1377  struct GNUNET_MQ_Envelope *ev;
1378  struct GNUNET_SET_ResultMessage *rm;
1379 
1380  if (GNUNET_YES == op->state->client_done_sent)
1381  {
1382  return;
1383  }
1384 
1385  if (PHASE_DONE != op->state->phase)
1386  {
1388  "Union operation failed\n");
1390  "# Union operations failed",
1391  1,
1392  GNUNET_NO);
1395  rm->request_id = htonl(op->client_request_id);
1396  rm->element_type = htons(0);
1397  GNUNET_MQ_send(op->set->cs->mq,
1398  ev);
1399  return;
1400  }
1401 
1403 
1405  "# Union operations succeeded",
1406  1,
1407  GNUNET_NO);
1409  "Signalling client that union operation is done\n");
1410  ev = GNUNET_MQ_msg(rm,
1412  rm->request_id = htonl(op->client_request_id);
1414  rm->element_type = htons(0);
1416  GNUNET_MQ_send(op->set->cs->mq,
1417  ev);
1418 }
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:238
#define GNUNET_MESSAGE_TYPE_SET_RESULT
Create an empty set.
uint32_t request_id
id the result belongs to
Definition: set.h:252
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_NO
Definition: gnunet_common.h:78
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:247
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:258
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:263
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:77
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:351
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 1427 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().

1428 {
1429  unsigned int num_demanded;
1430 
1432 
1433  if (PHASE_FINISH_WAITING == op->state->phase)
1434  {
1436  "In PHASE_FINISH_WAITING, pending %u demands\n",
1437  num_demanded);
1438  if (0 == num_demanded)
1439  {
1440  struct GNUNET_MQ_Envelope *ev;
1441 
1442  op->state->phase = PHASE_DONE;
1444  GNUNET_MQ_send(op->mq,
1445  ev);
1446  /* We now wait until the other peer sends P2P_OVER
1447  * after it got all elements from us. */
1448  }
1449  }
1450  if (PHASE_FINISH_CLOSING == op->state->phase)
1451  {
1453  "In PHASE_FINISH_CLOSING, pending %u demands\n",
1454  num_demanded);
1455  if (0 == num_demanded)
1456  {
1457  op->state->phase = PHASE_DONE;
1458  send_client_done(op);
1460  }
1461  }
1462 }
#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:351
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 1472 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.

1474 {
1475  struct Operation *op = cls;
1476 
1478  {
1479  GNUNET_break_op(0);
1480  return GNUNET_SYSERR;
1481  }
1483  {
1484  GNUNET_break_op(0);
1485  return GNUNET_SYSERR;
1486  }
1487  return GNUNET_OK;
1488 }
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:75
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
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 1500 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.

1502 {
1503  struct Operation *op = cls;
1504  struct ElementEntry *ee;
1505  struct KeyEntry *ke;
1506  uint16_t element_size;
1507 
1508  element_size = ntohs(emsg->header.size) - sizeof(struct GNUNET_SET_ElementMessage);
1509  ee = GNUNET_malloc(sizeof(struct ElementEntry) + element_size);
1510  GNUNET_memcpy(&ee[1],
1511  &emsg[1],
1512  element_size);
1513  ee->element.size = element_size;
1514  ee->element.data = &ee[1];
1515  ee->element.element_type = ntohs(emsg->element_type);
1516  ee->remote = GNUNET_YES;
1518  &ee->element_hash);
1519  if (GNUNET_NO ==
1521  &ee->element_hash,
1522  NULL))
1523  {
1524  /* We got something we didn't demand, since it's not in our map. */
1525  GNUNET_break_op(0);
1527  return;
1528  }
1529 
1531  "Got element (size %u, hash %s) from peer\n",
1532  (unsigned int)element_size,
1533  GNUNET_h2s(&ee->element_hash));
1534 
1536  "# received elements",
1537  1,
1538  GNUNET_NO);
1540  "# exchanged elements",
1541  1,
1542  GNUNET_NO);
1543 
1544  op->state->received_total++;
1545 
1546  ke = op_get_element(op, &ee->element_hash);
1547  if (NULL != ke)
1548  {
1549  /* Got repeated element. Should not happen since
1550  * we track demands. */
1552  "# repeated elements",
1553  1,
1554  GNUNET_NO);
1555  ke->received = GNUNET_YES;
1556  GNUNET_free(ee);
1557  }
1558  else
1559  {
1561  "Registering new element from remote peer\n");
1562  op->state->received_fresh++;
1564  /* only send results immediately if the client wants it */
1565  switch (op->result_mode)
1566  {
1569  break;
1570 
1573  break;
1574 
1575  default:
1576  /* Result mode not supported, should have been caught earlier. */
1577  GNUNET_break(0);
1578  break;
1579  }
1580  }
1581 
1582  if ((op->state->received_total > 8) &&
1583  (op->state->received_fresh < op->state->received_total / 3))
1584  {
1585  /* The other peer gave us lots of old elements, there's something wrong. */
1586  GNUNET_break_op(0);
1588  return;
1589  }
1591  maybe_finish(op);
1592 }
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:278
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
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:1241
uint16_t element_type
Type of the element to add or remove.
Definition: set.h:283
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.
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:951
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:273
struct GNUNET_SET_Element element
The actual element.
#define GNUNET_YES
Definition: gnunet_common.h:77
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 1602 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.

1604 {
1605  struct Operation *op = cls;
1606 
1608  {
1609  GNUNET_break_op(0);
1610  return GNUNET_SYSERR;
1611  }
1612  // FIXME: check that we expect full elements here?
1613  return GNUNET_OK;
1614 }
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:75
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
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 1624 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.

1626 {
1627  struct Operation *op = cls;
1628  struct ElementEntry *ee;
1629  struct KeyEntry *ke;
1630  uint16_t element_size;
1631 
1632  element_size = ntohs(emsg->header.size) - sizeof(struct GNUNET_SET_ElementMessage);
1633  ee = GNUNET_malloc(sizeof(struct ElementEntry) + element_size);
1634  GNUNET_memcpy(&ee[1], &emsg[1], element_size);
1635  ee->element.size = element_size;
1636  ee->element.data = &ee[1];
1637  ee->element.element_type = ntohs(emsg->element_type);
1638  ee->remote = GNUNET_YES;
1640 
1642  "Got element (full diff, size %u, hash %s) from peer\n",
1643  (unsigned int)element_size,
1644  GNUNET_h2s(&ee->element_hash));
1645 
1647  "# received elements",
1648  1,
1649  GNUNET_NO);
1651  "# exchanged elements",
1652  1,
1653  GNUNET_NO);
1654 
1655  op->state->received_total++;
1656 
1657  ke = op_get_element(op, &ee->element_hash);
1658  if (NULL != ke)
1659  {
1660  /* Got repeated element. Should not happen since
1661  * we track demands. */
1663  "# repeated elements",
1664  1,
1665  GNUNET_NO);
1666  ke->received = GNUNET_YES;
1667  GNUNET_free(ee);
1668  }
1669  else
1670  {
1672  "Registering new element from remote peer\n");
1673  op->state->received_fresh++;
1675  /* only send results immediately if the client wants it */
1676  switch (op->result_mode)
1677  {
1680  break;
1681 
1684  break;
1685 
1686  default:
1687  /* Result mode not supported, should have been caught earlier. */
1688  GNUNET_break(0);
1689  break;
1690  }
1691  }
1692 
1693  if ((GNUNET_YES == op->byzantine) &&
1694  (op->state->received_total > 384 + op->state->received_fresh * 4) &&
1695  (op->state->received_fresh < op->state->received_total / 6))
1696  {
1697  /* The other peer gave us lots of old elements, there's something wrong. */
1699  "Other peer sent only %llu/%llu fresh elements, failing operation\n",
1700  (unsigned long long)op->state->received_fresh,
1701  (unsigned long long)op->state->received_total);
1702  GNUNET_break_op(0);
1704  return;
1705  }
1707 }
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:278
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
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:1241
uint16_t element_type
Type of the element to add or remove.
Definition: set.h:283
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.
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:951
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:273
struct GNUNET_SET_Element element
The actual element.
#define GNUNET_YES
Definition: gnunet_common.h:77
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 1718 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.

1720 {
1721  struct Operation *op = cls;
1722  unsigned int num_keys;
1723 
1725  {
1726  GNUNET_break_op(0);
1727  return GNUNET_SYSERR;
1728  }
1729  if (op->state->phase != PHASE_INVENTORY_PASSIVE)
1730  {
1731  GNUNET_break_op(0);
1732  return GNUNET_SYSERR;
1733  }
1734  num_keys = (ntohs(msg->header.size) - sizeof(struct InquiryMessage))
1735  / sizeof(struct IBF_Key);
1736  if ((ntohs(msg->header.size) - sizeof(struct InquiryMessage))
1737  != num_keys * sizeof(struct IBF_Key))
1738  {
1739  GNUNET_break_op(0);
1740  return GNUNET_SYSERR;
1741  }
1742  return GNUNET_OK;
1743 }
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:75
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:76
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 1754 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().

1756 {
1757  struct Operation *op = cls;
1758  const struct IBF_Key *ibf_key;
1759  unsigned int num_keys;
1760 
1762  "Received union inquiry\n");
1763  num_keys = (ntohs(msg->header.size) - sizeof(struct InquiryMessage))
1764  / sizeof(struct IBF_Key);
1765  ibf_key = (const struct IBF_Key *)&msg[1];
1766  while (0 != num_keys--)
1767  {
1768  struct IBF_Key unsalted_key;
1769 
1770  unsalt_key(ibf_key,
1771  ntohl(msg->salt),
1772  &unsalted_key);
1774  unsalted_key);
1775  ibf_key++;
1776  }
1778 }
#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:951
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 1792 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().

1795 {
1796  struct Operation *op = cls;
1797  struct KeyEntry *ke = value;
1798  struct GNUNET_MQ_Envelope *ev;
1799  struct GNUNET_SET_ElementMessage *emsg;
1800  struct ElementEntry *ee = ke->element;
1801 
1802  if (GNUNET_YES == ke->received)
1803  return GNUNET_YES;
1804  ev = GNUNET_MQ_msg_extra(emsg,
1805  ee->element.size,
1807  GNUNET_memcpy(&emsg[1],
1808  ee->element.data,
1809  ee->element.size);
1810  emsg->element_type = htons(ee->element.element_type);
1811  GNUNET_MQ_send(op->mq,
1812  ev);
1813  return GNUNET_YES;
1814 }
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.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint16_t element_type
Type of the element to add or remove.
Definition: set.h:283
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
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:273
struct GNUNET_SET_Element element
The actual element.
#define GNUNET_YES
Definition: gnunet_common.h:77
#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:351
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 1824 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.

1826 {
1827  struct Operation *op = cls;
1828 
1830  "Received request for full set transmission\n");
1832  {
1833  GNUNET_break_op(0);
1835  return;
1836  }
1837  if (PHASE_EXPECT_IBF != op->state->phase)
1838  {
1839  GNUNET_break_op(0);
1841  return;
1842  }
1843 
1844  // FIXME: we need to check that our set is larger than the
1845  // byzantine_lower_bound by some threshold
1846  send_full_set(op);
1848 }
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:951
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 1858 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.

1860 {
1861  struct Operation *op = cls;
1862 
1863  switch (op->state->phase)
1864  {
1865  case PHASE_EXPECT_IBF:
1866  {
1867  struct GNUNET_MQ_Envelope *ev;
1868 
1870  "got FULL DONE, sending elements that other peer is missing\n");
1871 
1872  /* send all the elements that did not come from the remote peer */
1875  op);
1876 
1878  GNUNET_MQ_send(op->mq,
1879  ev);
1880  op->state->phase = PHASE_DONE;
1881  /* we now wait until the other peer sends us the OVER message*/
1882  }
1883  break;
1884 
1885  case PHASE_FULL_SENDING:
1886  {
1888  "got FULL DONE, finishing\n");
1889  /* We sent the full set, and got the response for that. We're done. */
1890  op->state->phase = PHASE_DONE;
1892  send_client_done(op);
1894  return;
1895  }
1896  break;
1897 
1898  default:
1900  "Handle full done phase is %u\n",
1901  (unsigned)op->state->phase);
1902  GNUNET_break_op(0);
1904  return;
1905  }
1907 }
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,...)
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
struct 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.
#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:951
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:351
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 1919 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.

1921 {
1922  struct Operation *op = cls;
1923  unsigned int num_hashes;
1924 
1926  {
1927  GNUNET_break_op(0);
1928  return GNUNET_SYSERR;
1929  }
1930  num_hashes = (ntohs(mh->size) - sizeof(struct GNUNET_MessageHeader))
1931  / sizeof(struct GNUNET_HashCode);
1932  if ((ntohs(mh->size) - sizeof(struct GNUNET_MessageHeader))
1933  != num_hashes * sizeof(struct GNUNET_HashCode))
1934  {
1935  GNUNET_break_op(0);
1936  return GNUNET_SYSERR;
1937  }
1938  return GNUNET_OK;
1939 }
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:75
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:76
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 1950 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.

1952 {
1953  struct Operation *op = cls;
1954  struct ElementEntry *ee;
1955  struct GNUNET_SET_ElementMessage *emsg;
1956  const struct GNUNET_HashCode *hash;
1957  unsigned int num_hashes;
1958  struct GNUNET_MQ_Envelope *ev;
1959 
1960  num_hashes = (ntohs(mh->size) - sizeof(struct GNUNET_MessageHeader))
1961  / sizeof(struct GNUNET_HashCode);
1962  for (hash = (const struct GNUNET_HashCode *)&mh[1];
1963  num_hashes > 0;
1964  hash++, num_hashes--)
1965  {
1967  hash);
1968  if (NULL == ee)
1969  {
1970  /* Demand for non-existing element. */
1971  GNUNET_break_op(0);
1973  return;
1974  }
1975  if (GNUNET_NO == _GSS_is_element_of_operation(ee, op))
1976  {
1977  /* Probably confused lazily copied sets. */
1978  GNUNET_break_op(0);
1980  return;
1981  }
1983  GNUNET_memcpy(&emsg[1], ee->element.data, ee->element.size);
1984  emsg->reserved = htons(0);
1985  emsg->element_type = htons(ee->element.element_type);
1987  "[OP %x] Sending demanded element (size %u, hash %s) to peer\n",
1988  (void *)op,
1989  (unsigned int)ee->element.size,
1990  GNUNET_h2s(&ee->element_hash));
1991  GNUNET_MQ_send(op->mq, ev);
1993  "# exchanged elements",
1994  1,
1995  GNUNET_NO);
1996 
1997  switch (op->result_mode)
1998  {
2000  /* Nothing to do. */
2001  break;
2002 
2005  break;
2006 
2007  default:
2008  /* Result mode not supported, should have been caught earlier. */
2009  GNUNET_break(0);
2010  break;
2011  }
2012  }
2013  GNUNET_CADET_receive_done(op->channel);
2014 }
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_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
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:283
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
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:951
uint16_t reserved
For alignment, always zero.
Definition: set.h:288
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:273
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:351
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 2025 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.

2027 {
2028  struct Operation *op = cls;
2029  unsigned int num_hashes;
2030 
2032  {
2033  GNUNET_break_op(0);
2034  return GNUNET_SYSERR;
2035  }
2036  /* look up elements and send them */
2037  if ((op->state->phase != PHASE_INVENTORY_PASSIVE) &&
2039  {
2040  GNUNET_break_op(0);
2041  return GNUNET_SYSERR;
2042  }
2043  num_hashes = (ntohs(mh->size) - sizeof(struct GNUNET_MessageHeader))
2044  / sizeof(struct GNUNET_HashCode);
2045  if ((ntohs(mh->size) - sizeof(struct GNUNET_MessageHeader)) !=
2046  num_hashes * sizeof(struct GNUNET_HashCode))
2047  {
2048  GNUNET_break_op(0);
2049  return GNUNET_SYSERR;
2050  }
2051  return GNUNET_OK;
2052 }
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:75
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:76
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 2063 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.

2065 {
2066  struct Operation *op = cls;
2067  const struct GNUNET_HashCode *hash;
2068  unsigned int num_hashes;
2069 
2070  num_hashes = (ntohs(mh->size) - sizeof(struct GNUNET_MessageHeader))
2071  / sizeof(struct GNUNET_HashCode);
2072  for (hash = (const struct GNUNET_HashCode *)&mh[1];
2073  num_hashes > 0;
2074  hash++, num_hashes--)
2075  {
2076  struct ElementEntry *ee;
2077  struct GNUNET_MessageHeader *demands;
2078  struct GNUNET_MQ_Envelope *ev;
2079 
2081  hash);
2082  if (NULL != ee)
2084  continue;
2085 
2086  if (GNUNET_YES ==
2088  hash))
2089  {
2091  "Skipped sending duplicate demand\n");
2092  continue;
2093  }
2094 
2097  hash,
2098  NULL,
2100 
2102  "[OP %x] Requesting element (hash %s)\n",
2103  (void *)op, GNUNET_h2s(hash));
2104  ev = GNUNET_MQ_msg_header_extra(demands,
2105  sizeof(struct GNUNET_HashCode),
2107  GNUNET_memcpy(&demands[1],
2108  hash,
2109  sizeof(struct GNUNET_HashCode));
2110  GNUNET_MQ_send(op->mq, ev);
2111  }
2112  GNUNET_CADET_receive_done(op->channel);
2113 }
#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.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
, &#39; bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_...
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:951
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
Header for all communications.
#define GNUNET_YES
Definition: gnunet_common.h:77
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:351
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 2123 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.

2125 {
2126  struct Operation *op = cls;
2127 
2129  {
2130  GNUNET_break_op(0);
2132  return;
2133  }
2134  switch (op->state->phase)
2135  {
2137  /* We got all requests, but still have to send our elements in response. */
2139 
2141  "got DONE (as passive partner), waiting for our demands to be satisfied\n");
2142  /* The active peer is done sending offers
2143  * and inquiries. This means that all
2144  * our responses to that (demands and offers)
2145  * must be in flight (queued or in mesh).
2146  *
2147  * We should notify the active peer once
2148  * all our demands are satisfied, so that the active
2149  * peer can quit if we gave it everything.
2150  */
2152  maybe_finish(op);
2153  return;
2154 
2157  "got DONE (as active partner), waiting to finish\n");
2158  /* All demands of the other peer are satisfied,
2159  * and we processed all offers, thus we know
2160  * exactly what our demands must be.
2161  *
2162  * We'll close the channel
2163  * to the other peer once our demands are met.
2164  */
2167  maybe_finish(op);
2168  return;
2169 
2170  default:
2171  GNUNET_break_op(0);
2173  return;
2174  }
2175 }
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:951
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 2184 of file gnunet-service-set_union.c.

References send_client_done().

2186 {
2187  send_client_done(cls);
2188 }
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 2199 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().

2201 {
2202  struct OperationState *state;
2203  struct GNUNET_MQ_Envelope *ev;
2204  struct OperationRequestMessage *msg;
2205 
2206  ev = GNUNET_MQ_msg_nested_mh(msg,
2208  opaque_context);
2209  if (NULL == ev)
2210  {
2211  /* the context message is too large */
2212  GNUNET_break(0);
2213  return NULL;
2214  }
2215  state = GNUNET_new(struct OperationState);
2217  GNUNET_NO);
2218  /* copy the current generation's strata estimator for this operation */
2219  state->se = strata_estimator_dup(op->set->state->se);
2220  /* we started the operation, thus we have to send the operation request */
2221  state->phase = PHASE_EXPECT_SE;
2222  state->salt_receive = state->salt_send = 42; // FIXME?????
2224  "Initiating union operation evaluation\n");
2226  "# of total union operations",
2227  1,
2228  GNUNET_NO);
2230  "# of initiated union operations",
2231  1,
2232  GNUNET_NO);
2233  msg->operation = htonl(GNUNET_SET_OPERATION_UNION);
2234  GNUNET_MQ_send(op->mq,
2235  ev);
2236 
2237  if (NULL != opaque_context)
2239  "sent op request with context message\n");
2240  else
2242  "sent op request without context message\n");
2243 
2244  op->state = state;
2247  return state;
2248 }
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:78
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:351
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 2258 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().

2259 {
2260  struct OperationState *state;
2261  const struct StrataEstimator *se;
2262  struct GNUNET_MQ_Envelope *ev;
2263  struct StrataEstimatorMessage *strata_msg;
2264  char *buf;
2265  size_t len;
2266  uint16_t type;
2267 
2269  "accepting set union operation\n");
2271  "# of accepted union operations",
2272  1,
2273  GNUNET_NO);
2275  "# of total union operations",
2276  1,
2277  GNUNET_NO);
2278 
2279  state = GNUNET_new(struct OperationState);
2280  state->se = strata_estimator_dup(op->set->state->se);
2282  GNUNET_NO);
2283  state->salt_receive = state->salt_send = 42; // FIXME?????
2284  op->state = state;
2287 
2288  /* kick off the operation */
2289  se = state->se;
2291  len = strata_estimator_write(se,
2292  buf);
2293  if (len < se->strata_count * IBF_BUCKET_SIZE * se->ibf_size)
2295  else
2297  ev = GNUNET_MQ_msg_extra(strata_msg,
2298  len,
2299  type);
2300  GNUNET_memcpy(&strata_msg[1],
2301  buf,
2302  len);
2303  GNUNET_free(buf);
2304  strata_msg->set_size
2306  GNUNET_MQ_send(op->mq,
2307  ev);
2308  state->phase = PHASE_EXPECT_IBF;
2309  return state;
2310 }
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_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
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_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:69
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:351
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 2322 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().

2323 {
2324  struct SetState *set_state;
2325 
2327  "union set created\n");
2328  set_state = GNUNET_new(struct SetState);
2331  if (NULL == set_state->se)
2332  {
2334  "Failed to allocate strata estimator\n");
2335  GNUNET_free(set_state);
2336  return NULL;
2337  }
2338  return set_state;
2339 }
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 2349 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().

2351 {
2352  strata_estimator_insert(set_state->se,
2353  get_ibf_key(&ee->element_hash));
2354 }
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 2365 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().

2367 {
2368  strata_estimator_remove(set_state->se,
2369  get_ibf_key(&ee->element_hash));
2370 }
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 2379 of file gnunet-service-set_union.c.

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

Referenced by _GSS_union_vt().

2380 {
2381  if (NULL != set_state->se)
2382  {
2383  strata_estimator_destroy(set_state->se);
2384  set_state->se = NULL;
2385  }
2386  GNUNET_free(set_state);
2387 }
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 2397 of file gnunet-service-set_union.c.

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

Referenced by _GSS_union_vt().

2398 {
2399  struct SetState *new_state;
2400 
2401  GNUNET_assert((NULL != state) &&
2402  (NULL != state->se));
2403  new_state = GNUNET_new(struct SetState);
2404  new_state->se = strata_estimator_dup(state->se);
2405 
2406  return new_state;
2407 }
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 2416 of file gnunet-service-set_union.c.

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

Referenced by _GSS_union_vt().

2417 {
2418  send_client_done(op);
2420  GNUNET_YES);
2421 }
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:77
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 2431 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().

2432 {
2433  static const struct SetVT union_vt = {
2435  .add = &union_add,
2436  .remove = &union_remove,
2437  .destroy_set = &union_set_destroy,
2438  .evaluate = &union_evaluate,
2439  .accept = &union_accept,
2440  .cancel = &union_op_cancel,
2441  .copy_state = &union_copy_state,
2442  .channel_death = &union_channel_death
2443  };
2444 
2445  return &union_vt;
2446 }
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.