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

two-peer set intersection More...

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

Go to the source code of this file.

Data Structures

struct  OperationState
 State of an evaluate operation with another peer. More...
 
struct  SetState
 Extra state required for efficient set intersection. More...
 

Enumerations

enum  IntersectionOperationPhase {
  PHASE_INITIAL, PHASE_COUNT_SENT, PHASE_BF_EXCHANGE, PHASE_MUST_SEND_DONE,
  PHASE_DONE_RECEIVED, PHASE_FINISHED
}
 Current phase we are in for a intersection operation. More...
 

Functions

static void send_client_removed_element (struct Operation *op, struct GNUNET_SET_Element *element)
 If applicable in the current operation mode, send a result message to the client indicating we removed an element. More...
 
static int filtered_map_initialization (void *cls, const struct GNUNET_HashCode *key, void *value)
 Fills the "my_elements" hashmap with all relevant elements. More...
 
static int iterator_bf_reduce (void *cls, const struct GNUNET_HashCode *key, void *value)
 Removes elements from our hashmap if they are not contained within the provided remote bloomfilter. More...
 
static int iterator_bf_create (void *cls, const struct GNUNET_HashCode *key, void *value)
 Create initial bloomfilter based on all the elements given. More...
 
static void fail_intersection_operation (struct Operation *op)
 Inform the client that the intersection operation has failed, and proceed to destroy the evaluate operation. More...
 
static void send_bloomfilter (struct Operation *op)
 Send a bloomfilter to our peer. More...
 
static void send_client_done_and_destroy (void *cls)
 Signal to the client that the operation has finished and destroy the operation. More...
 
static void finished_local_operations (void *cls)
 Remember that we are done dealing with the local client AND have sent the other peer our message that we are done, so we are not just waiting for the channel to die before telling the local client that we are done as our last act. More...
 
static void send_p2p_done (struct Operation *op)
 Notify the other peer that we are done. More...
 
static void send_remaining_elements (void *cls)
 Send all elements in the full result iterator. More...
 
static int initialize_map_unfiltered (void *cls, const struct GNUNET_HashCode *key, void *value)
 Fills the "my_elements" hashmap with the initial set of (non-deleted) elements from the set of the specification. More...
 
static void send_element_count (struct Operation *op)
 Send our element count to the peer, in case our element count is lower than theirs. More...
 
static void begin_bf_exchange (struct Operation *op)
 We go first, initialize our map with all elements and send the first Bloom filter. More...
 
void handle_intersection_p2p_element_info (void *cls, const struct IntersectionElementInfoMessage *msg)
 Handle the initial struct IntersectionElementInfoMessage from a remote peer. More...
 
static void process_bf (struct Operation *op)
 Process a Bloomfilter once we got all the chunks. More...
 
int check_intersection_p2p_bf (void *cls, const struct BFMessage *msg)
 Check an BF message from a remote peer. More...
 
void handle_intersection_p2p_bf (void *cls, const struct BFMessage *msg)
 Handle an BF message from a remote peer. More...
 
static int filter_all (void *cls, const struct GNUNET_HashCode *key, void *value)
 Remove all elements from our hashmap. More...
 
void handle_intersection_p2p_done (void *cls, const struct IntersectionDoneMessage *idm)
 Handle a done message from a remote peer. More...
 
static struct OperationStateintersection_evaluate (struct Operation *op, const struct GNUNET_MessageHeader *opaque_context)
 Initiate a set intersection operation with a remote peer. More...
 
static struct OperationStateintersection_accept (struct Operation *op)
 Accept an intersection operation request from a remote peer. More...
 
static void intersection_op_cancel (struct Operation *op)
 Destroy the intersection operation. More...
 
static struct SetStateintersection_set_create ()
 Create a new set supporting the intersection operation. More...
 
static void intersection_add (struct SetState *set_state, struct ElementEntry *ee)
 Add the element from the given element message to the set. More...
 
static void intersection_set_destroy (struct SetState *set_state)
 Destroy a set that supports the intersection operation. More...
 
static void intersection_remove (struct SetState *set_state, struct ElementEntry *element)
 Remove the element given in the element message from the set. More...
 
static void intersection_channel_death (struct Operation *op)
 Callback for channel death for the intersection operation. More...
 
const struct SetVT_GSS_intersection_vt ()
 Get the table with implementing functions for set intersection. More...
 

Detailed Description

two-peer set intersection

Author
Christian Fuchs
Christian Grothoff

Definition in file gnunet-service-set_intersection.c.

Enumeration Type Documentation

◆ IntersectionOperationPhase

Current phase we are in for a intersection operation.

Enumerator
PHASE_INITIAL 

We are just starting.

PHASE_COUNT_SENT 

We have send the number of our elements to the other peer, but did not setup our element set yet.

PHASE_BF_EXCHANGE 

We have initialized our set and are now reducing it by exchanging Bloom filters until one party notices the their element hashes are equal.

PHASE_MUST_SEND_DONE 

We must next send the P2P DONE message (after finishing mostly with the local client).

Then we will wait for the channel to close.

PHASE_DONE_RECEIVED 

We have received the P2P DONE message, and must finish with the local client before terminating the channel.

PHASE_FINISHED 

The protocol is over.

Results may still have to be sent to the client.

Definition at line 39 of file gnunet-service-set_intersection.c.

40 {
45 
51 
58 
64 
70 
76 
77 };
We are just starting.
We have initialized our set and are now reducing it by exchanging Bloom filters until one party notic...
The protocol is over.
We must next send the P2P DONE message (after finishing mostly with the local client).
We have received the P2P DONE message, and must finish with the local client before terminating the c...
We have send the number of our elements to the other peer, but did not setup our element set yet...

Function Documentation

◆ send_client_removed_element()

static void send_client_removed_element ( struct Operation op,
struct GNUNET_SET_Element element 
)
static

If applicable in the current operation mode, send a result message to the client indicating we removed an element.

Parameters
opintersection operation
elementelement to send

Definition at line 210 of file gnunet-service-set_intersection.c.

References _GSS_statistics, Operation::client_request_id, Set::cs, GNUNET_SET_Element::data, GNUNET_SET_Element::element_type, GNUNET_SET_ResultMessage::element_type, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SET_RESULT, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_SET_RESULT_REMOVED, GNUNET_SET_STATUS_OK, GNUNET_STATISTICS_update(), ClientState::mq, GNUNET_SET_ResultMessage::request_id, Operation::result_mode, GNUNET_SET_ResultMessage::result_status, Operation::set, and GNUNET_SET_Element::size.

Referenced by filter_all(), filtered_map_initialization(), and iterator_bf_reduce().

212 {
213  struct GNUNET_MQ_Envelope *ev;
214  struct GNUNET_SET_ResultMessage *rm;
215 
217  return; /* Wrong mode for transmitting removed elements */
219  "Sending removed element (size %u) to client\n",
220  element->size);
222  "# Element removed messages sent",
223  1,
224  GNUNET_NO);
225  GNUNET_assert (0 != op->client_request_id);
226  ev = GNUNET_MQ_msg_extra (rm,
227  element->size,
229  if (NULL == ev)
230  {
231  GNUNET_break (0);
232  return;
233  }
234  rm->result_status = htons (GNUNET_SET_STATUS_OK);
235  rm->request_id = htonl (op->client_request_id);
236  rm->element_type = element->element_type;
237  GNUNET_memcpy (&rm[1],
238  element->data,
239  element->size);
240  GNUNET_MQ_send (op->set->cs->mq,
241  ev);
242 }
enum GNUNET_SET_ResultMode result_mode
When are elements sent to the client, and which elements are sent?
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: set.h:246
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_MESSAGE_TYPE_SET_RESULT
Create an empty set.
uint32_t request_id
id the result belongs to
Definition: set.h:261
#define GNUNET_NO
Definition: gnunet_common.h:81
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...
const void * data
Actual data of the element.
struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
#define GNUNET_memcpy(dst, src, n)
Everything went ok, we are transmitting an element of the result (in set, or to be removed from set...
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SET_Status in NBO.
Definition: set.h:267
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: set.h:272
uint32_t client_request_id
ID used to identify an operation between service and client.
uint16_t size
Number of bytes in the buffer pointed to by data.
#define GNUNET_log(kind,...)
Client gets only elements that have been removed from the set.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
struct ClientState * cs
Client that owns the set.
uint16_t element_type
Application-specific element type.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ filtered_map_initialization()

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

Fills the "my_elements" hashmap with all relevant elements.

Parameters
clsthe struct Operation * we are performing
keycurrent key code
valuethe struct ElementEntry * from the hash map
Returns
GNUNET_YES (we should continue to iterate)

Definition at line 254 of file gnunet-service-set_intersection.c.

References _GSS_is_element_of_operation(), ElementEntry::element, ElementEntry::element_hash, GNUNET_BLOCK_mingle_hash(), GNUNET_break, GNUNET_CONTAINER_bloomfilter_test(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CRYPTO_hash_xor(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_NO, GNUNET_YES, OperationState::my_element_count, OperationState::my_elements, OperationState::my_xor, op, OperationState::remote_bf, OperationState::salt, send_client_removed_element(), GNUNET_SET_Element::size, Operation::state, and value.

Referenced by process_bf().

257 {
258  struct Operation *op = cls;
259  struct ElementEntry *ee = value;
260  struct GNUNET_HashCode mutated_hash;
261 
262 
264  "FIMA called for %s:%u\n",
265  GNUNET_h2s (&ee->element_hash),
266  ee->element.size);
267 
268  if (GNUNET_NO == _GSS_is_element_of_operation (ee, op))
269  {
271  "Reduced initialization, not starting with %s:%u (wrong generation)\n",
272  GNUNET_h2s (&ee->element_hash),
273  ee->element.size);
274  return GNUNET_YES; /* element not valid in our operation's generation */
275  }
276 
277  /* Test if element is in other peer's bloomfilter */
279  op->state->salt,
280  &mutated_hash);
282  "Testing mingled hash %s with salt %u\n",
283  GNUNET_h2s (&mutated_hash),
284  op->state->salt);
285  if (GNUNET_NO ==
287  &mutated_hash))
288  {
289  /* remove this element */
291  &ee->element);
293  "Reduced initialization, not starting with %s:%u\n",
294  GNUNET_h2s (&ee->element_hash),
295  ee->element.size);
296  return GNUNET_YES;
297  }
298  op->state->my_element_count++;
300  &ee->element_hash,
301  &op->state->my_xor);
303  "Filtered initialization of my_elements, adding %s:%u\n",
304  GNUNET_h2s (&ee->element_hash),
305  ee->element.size);
308  &ee->element_hash,
309  ee,
311 
312  return GNUNET_YES;
313 }
int _GSS_is_element_of_operation(struct ElementEntry *ee, struct Operation *op)
Is element ee part of the set used by op?
uint32_t salt
Salt currently used for BF construction (by us or the other peer, depending on where we are in the co...
struct GNUNET_HashCode element_hash
Hash of the element.
uint32_t my_element_count
Current element count contained within my_elements.
#define GNUNET_NO
Definition: gnunet_common.h:81
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static void send_client_removed_element(struct Operation *op, struct GNUNET_SET_Element *element)
If applicable in the current operation mode, send a result message to the client indicating we remove...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static char * value
Value of the record to add/remove.
Information about an element element in the set.
int GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
A 512-bit hashcode.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
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.
struct GNUNET_CONTAINER_BloomFilter * remote_bf
The bf we currently receive.
uint16_t size
Number of bytes in the buffer pointed to by data.
#define GNUNET_log(kind,...)
struct GNUNET_SET_Element element
The actual element.
#define GNUNET_YES
Definition: gnunet_common.h:80
void GNUNET_CRYPTO_hash_xor(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result)
compute result = a ^ b
Definition: crypto_hash.c:193
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
struct GNUNET_HashCode my_xor
XOR of the keys of all of the elements (remaining) in my set.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
void GNUNET_BLOCK_mingle_hash(const struct GNUNET_HashCode *in, uint32_t mingle_number, struct GNUNET_HashCode *hc)
Mingle hash with the mingle_number to produce different bits.
Definition: block.c:81
Here is the call graph for this function:
Here is the caller graph for this function:

◆ iterator_bf_reduce()

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

Removes elements from our hashmap if they are not contained within the provided remote bloomfilter.

Parameters
clsclosure with the struct Operation *
keycurrent key code
valuevalue in the hash map
Returns
GNUNET_YES (we should continue to iterate)

Definition at line 326 of file gnunet-service-set_intersection.c.

References ElementEntry::element, ElementEntry::element_hash, GNUNET_assert, GNUNET_BLOCK_mingle_hash(), GNUNET_break, GNUNET_CONTAINER_bloomfilter_test(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CRYPTO_hash_xor(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_NO, GNUNET_YES, OperationState::my_element_count, OperationState::my_elements, OperationState::my_xor, op, OperationState::remote_bf, OperationState::salt, send_client_removed_element(), GNUNET_SET_Element::size, Operation::state, and value.

Referenced by process_bf().

329 {
330  struct Operation *op = cls;
331  struct ElementEntry *ee = value;
332  struct GNUNET_HashCode mutated_hash;
333 
335  op->state->salt,
336  &mutated_hash);
338  "Testing mingled hash %s with salt %u\n",
339  GNUNET_h2s (&mutated_hash),
340  op->state->salt);
341  if (GNUNET_NO ==
343  &mutated_hash))
344  {
346  op->state->my_element_count--;
348  &ee->element_hash,
349  &op->state->my_xor);
351  "Bloom filter reduction of my_elements, removing %s:%u\n",
352  GNUNET_h2s (&ee->element_hash),
353  ee->element.size);
356  &ee->element_hash,
357  ee));
359  &ee->element);
360  }
361  else
362  {
364  "Bloom filter reduction of my_elements, keeping %s:%u\n",
365  GNUNET_h2s (&ee->element_hash),
366  ee->element.size);
367  }
368  return GNUNET_YES;
369 }
uint32_t salt
Salt currently used for BF construction (by us or the other peer, depending on where we are in the co...
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
uint32_t my_element_count
Current element count contained within my_elements.
#define GNUNET_NO
Definition: gnunet_common.h:81
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static void send_client_removed_element(struct Operation *op, struct GNUNET_SET_Element *element)
If applicable in the current operation mode, send a result message to the client indicating we remove...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static char * value
Value of the record to add/remove.
Information about an element element in the set.
int GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
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.
A 512-bit hashcode.
Operation context used to execute a set operation.
struct GNUNET_CONTAINER_BloomFilter * remote_bf
The bf we currently receive.
uint16_t size
Number of bytes in the buffer pointed to by data.
#define GNUNET_log(kind,...)
struct GNUNET_SET_Element element
The actual element.
#define GNUNET_YES
Definition: gnunet_common.h:80
void GNUNET_CRYPTO_hash_xor(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result)
compute result = a ^ b
Definition: crypto_hash.c:193
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
struct GNUNET_HashCode my_xor
XOR of the keys of all of the elements (remaining) in my set.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
void GNUNET_BLOCK_mingle_hash(const struct GNUNET_HashCode *in, uint32_t mingle_number, struct GNUNET_HashCode *hc)
Mingle hash with the mingle_number to produce different bits.
Definition: block.c:81
Here is the call graph for this function:
Here is the caller graph for this function:

◆ iterator_bf_create()

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

Create initial bloomfilter based on all the elements given.

Parameters
clsthe struct Operation *
keycurrent key code
valuethe struct ElementEntry to process
Returns
GNUNET_YES (we should continue to iterate)

Definition at line 381 of file gnunet-service-set_intersection.c.

References ElementEntry::element_hash, GNUNET_BLOCK_mingle_hash(), GNUNET_CONTAINER_bloomfilter_add(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_YES, OperationState::local_bf, op, OperationState::salt, Operation::state, and value.

Referenced by send_bloomfilter().

384 {
385  struct Operation *op = cls;
386  struct ElementEntry *ee = value;
387  struct GNUNET_HashCode mutated_hash;
388 
390  op->state->salt,
391  &mutated_hash);
393  "Initializing BF with hash %s with salt %u\n",
394  GNUNET_h2s (&mutated_hash),
395  op->state->salt);
397  &mutated_hash);
398  return GNUNET_YES;
399 }
void GNUNET_CONTAINER_bloomfilter_add(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Add an element to the filter.
uint32_t salt
Salt currently used for BF construction (by us or the other peer, depending on where we are in the co...
struct GNUNET_HashCode element_hash
Hash of the element.
struct GNUNET_CONTAINER_BloomFilter * local_bf
BF of the set&#39;s element.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static char * value
Value of the record to add/remove.
Information about an element element in the set.
A 512-bit hashcode.
Operation context used to execute a set operation.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:80
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
void GNUNET_BLOCK_mingle_hash(const struct GNUNET_HashCode *in, uint32_t mingle_number, struct GNUNET_HashCode *hc)
Mingle hash with the mingle_number to produce different bits.
Definition: block.c:81
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fail_intersection_operation()

static void fail_intersection_operation ( struct Operation op)
static

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

Parameters
opthe intersection operation to fail

Definition at line 409 of file gnunet-service-set_intersection.c.

References _GSS_operation_destroy(), _GSS_statistics, Operation::client_request_id, Set::cs, GNUNET_SET_ResultMessage::element_type, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_MESSAGE_TYPE_SET_RESULT, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_NO, GNUNET_SET_STATUS_FAILURE, GNUNET_STATISTICS_update(), GNUNET_YES, ClientState::mq, msg, OperationState::my_elements, GNUNET_SET_ResultMessage::request_id, GNUNET_SET_ResultMessage::result_status, Operation::set, and Operation::state.

Referenced by handle_intersection_p2p_bf(), handle_intersection_p2p_done(), handle_intersection_p2p_element_info(), and process_bf().

410 {
411  struct GNUNET_MQ_Envelope *ev;
413 
415  "Intersection operation failed\n");
417  "# Intersection operations failed",
418  1,
419  GNUNET_NO);
420  if (NULL != op->state->my_elements)
421  {
423  op->state->my_elements = NULL;
424  }
425  ev = GNUNET_MQ_msg (msg,
428  msg->request_id = htonl (op->client_request_id);
429  msg->element_type = htons (0);
430  GNUNET_MQ_send (op->set->cs->mq,
431  ev);
433  GNUNET_YES);
434 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: set.h:246
#define GNUNET_MESSAGE_TYPE_SET_RESULT
Create an empty set.
uint32_t request_id
id the result belongs to
Definition: set.h:261
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_NO
Definition: gnunet_common.h:81
void _GSS_operation_destroy(struct Operation *op, int gc)
Destroy the given operation.
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.
The other peer refused to to the operation with us, or something went wrong.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SET_Status in NBO.
Definition: set.h:267
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: set.h:272
uint32_t client_request_id
ID used to identify an operation between service and client.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:80
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
struct ClientState * cs
Client that owns the set.
struct OperationState * state
Operation-specific operation state.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_bloomfilter()

static void send_bloomfilter ( struct Operation op)
static

Send a bloomfilter to our peer.

After the result done message has been sent to the client, destroy the evaluate operation.

Parameters
opintersection operation

Definition at line 444 of file gnunet-service-set_intersection.c.

References _GSS_statistics, OperationState::bf_data, BFMessage::bits_per_element, BFMessage::bloomfilter_total_length, BFMessage::element_xor_hash, GNUNET_assert, GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_bloomfilter_get_raw_data(), GNUNET_CONTAINER_bloomfilter_init(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CRYPTO_QUALITY_NONCE, GNUNET_CRYPTO_random_u32(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_malloc, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_SYSERR, iterator_bf_create(), OperationState::local_bf, Operation::mq, msg, OperationState::my_element_count, OperationState::my_elements, OperationState::my_xor, Operation::remote_element_count, OperationState::salt, BFMessage::sender_element_count, BFMessage::sender_mutator, and Operation::state.

Referenced by begin_bf_exchange(), and process_bf().

445 {
446  struct GNUNET_MQ_Envelope *ev;
447  struct BFMessage *msg;
448  uint32_t bf_size;
449  uint32_t bf_elementbits;
450  uint32_t chunk_size;
451  char *bf_data;
452  uint32_t offset;
453 
454  /* We consider the ratio of the set sizes to determine
455  the number of bits per element, as the smaller set
456  should use more bits to maximize its set reduction
457  potential and minimize overall bandwidth consumption. */
458  bf_elementbits = 2 + ceil (log2((double)
459  (op->remote_element_count /
460  (double) op->state->my_element_count)));
461  if (bf_elementbits < 1)
462  bf_elementbits = 1; /* make sure k is not 0 */
463  /* optimize BF-size to ~50% of bits set */
464  bf_size = ceil ((double) (op->state->my_element_count
465  * bf_elementbits / log(2)));
467  "Sending Bloom filter (%u) of size %u bytes\n",
468  (unsigned int) bf_elementbits,
469  (unsigned int) bf_size);
471  bf_size,
472  bf_elementbits);
474  UINT32_MAX);
477  op);
478 
479  /* send our Bloom filter */
481  "# Intersection Bloom filters sent",
482  1,
483  GNUNET_NO);
484  chunk_size = 60 * 1024 - sizeof (struct BFMessage);
485  if (bf_size <= chunk_size)
486  {
487  /* singlepart */
488  chunk_size = bf_size;
489  ev = GNUNET_MQ_msg_extra (msg,
490  chunk_size,
494  (char*) &msg[1],
495  bf_size));
496  msg->sender_element_count = htonl (op->state->my_element_count);
497  msg->bloomfilter_total_length = htonl (bf_size);
498  msg->bits_per_element = htonl (bf_elementbits);
499  msg->sender_mutator = htonl (op->state->salt);
500  msg->element_xor_hash = op->state->my_xor;
501  GNUNET_MQ_send (op->mq, ev);
502  }
503  else
504  {
505  /* multipart */
506  bf_data = GNUNET_malloc (bf_size);
509  bf_data,
510  bf_size));
511  offset = 0;
512  while (offset < bf_size)
513  {
514  if (bf_size - chunk_size < offset)
515  chunk_size = bf_size - offset;
516  ev = GNUNET_MQ_msg_extra (msg,
517  chunk_size,
519  GNUNET_memcpy (&msg[1],
520  &bf_data[offset],
521  chunk_size);
522  offset += chunk_size;
523  msg->sender_element_count = htonl (op->state->my_element_count);
524  msg->bloomfilter_total_length = htonl (bf_size);
525  msg->bits_per_element = htonl (bf_elementbits);
526  msg->sender_mutator = htonl (op->state->salt);
527  msg->element_xor_hash = op->state->my_xor;
528  GNUNET_MQ_send (op->mq, ev);
529  }
530  GNUNET_free (bf_data);
531  }
533  op->state->local_bf = NULL;
534 }
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF
Bloom filter message for intersection exchange started by Bob.
uint32_t salt
Salt currently used for BF construction (by us or the other peer, depending on where we are in the co...
uint32_t sender_element_count
Number of elements the sender still has in the set.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_CONTAINER_BloomFilter * local_bf
BF of the set&#39;s element.
uint32_t my_element_count
Current element count contained within my_elements.
#define GNUNET_NO
Definition: gnunet_common.h:81
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
uint32_t bloomfilter_total_length
Total length of the bloomfilter data.
struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
#define GNUNET_memcpy(dst, src, n)
Randomness for IVs etc.
Bloom filter messages exchanged for set intersection calculation.
struct GNUNET_HashCode element_xor_hash
XOR of all hashes over all elements remaining in the set.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
int GNUNET_CONTAINER_bloomfilter_get_raw_data(const struct GNUNET_CONTAINER_BloomFilter *bf, char *data, size_t size)
Copy the raw data of this Bloom filter into the given data array.
uint32_t bits_per_element
Number of bits (k-value) used in encoding the bloomfilter.
static int iterator_bf_create(void *cls, const struct GNUNET_HashCode *key, void *value)
Create initial bloomfilter based on all the elements given.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
#define GNUNET_log(kind,...)
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
uint32_t remote_element_count
Remote peers element count.
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.
struct GNUNET_HashCode my_xor
XOR of the keys of all of the elements (remaining) in my set.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associcated with a filter in memory, flush to drive if needed (do not free the space o...
uint32_t sender_mutator
Mutator used with this bloomfilter.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_client_done_and_destroy()

static void send_client_done_and_destroy ( void *  cls)
static

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

Parameters
clsoperation to destroy

Definition at line 544 of file gnunet-service-set_intersection.c.

References _GSS_operation_destroy(), _GSS_statistics, Operation::client_request_id, Set::cs, GNUNET_SET_ResultMessage::element_type, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_SET_RESULT, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_NO, GNUNET_SET_STATUS_DONE, GNUNET_STATISTICS_update(), GNUNET_YES, ClientState::mq, op, GNUNET_SET_ResultMessage::request_id, GNUNET_SET_ResultMessage::result_status, and Operation::set.

Referenced by handle_intersection_p2p_done(), intersection_channel_death(), and send_remaining_elements().

545 {
546  struct Operation *op = cls;
547  struct GNUNET_MQ_Envelope *ev;
548  struct GNUNET_SET_ResultMessage *rm;
549 
551  "Intersection succeeded, sending DONE to local client\n");
553  "# Intersection operations succeeded",
554  1,
555  GNUNET_NO);
556  ev = GNUNET_MQ_msg (rm,
558  rm->request_id = htonl (op->client_request_id);
560  rm->element_type = htons (0);
561  GNUNET_MQ_send (op->set->cs->mq,
562  ev);
564  GNUNET_YES);
565 }
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: set.h:246
#define GNUNET_MESSAGE_TYPE_SET_RESULT
Create an empty set.
uint32_t request_id
id the result belongs to
Definition: set.h:261
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_NO
Definition: gnunet_common.h:81
void _GSS_operation_destroy(struct Operation *op, int gc)
Destroy the given operation.
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.
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SET_Status in NBO.
Definition: set.h:267
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: set.h:272
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_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:80
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
struct ClientState * cs
Client that owns the set.
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:

◆ finished_local_operations()

static void finished_local_operations ( void *  cls)
static

Remember that we are done dealing with the local client AND have sent the other peer our message that we are done, so we are not just waiting for the channel to die before telling the local client that we are done as our last act.

Parameters
clsthe struct Operation.

Definition at line 577 of file gnunet-service-set_intersection.c.

References OperationState::channel_death_expected, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_YES, op, OperationState::phase, PHASE_FINISHED, and Operation::state.

Referenced by send_p2p_done().

578 {
579  struct Operation *op = cls;
580 
582  "DONE sent to other peer, now waiting for other end to close the channel\n");
583  op->state->phase = PHASE_FINISHED;
585 }
The protocol is over.
enum IntersectionOperationPhase phase
Current state of the operation.
Operation context used to execute a set operation.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:80
int channel_death_expected
Set whenever we reach the state where the death of the channel is perfectly find and should NOT resul...
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
Here is the caller graph for this function:

◆ send_p2p_done()

static void send_p2p_done ( struct Operation op)
static

Notify the other peer that we are done.

Once this message is out, we still need to notify the local client that we are done.

Parameters
opoperation to notify for.

Definition at line 596 of file gnunet-service-set_intersection.c.

References OperationState::channel_death_expected, IntersectionDoneMessage::element_xor_hash, IntersectionDoneMessage::final_element_count, finished_local_operations(), GNUNET_assert, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE, GNUNET_MQ_msg, GNUNET_MQ_notify_sent(), GNUNET_MQ_send(), GNUNET_NO, Operation::mq, OperationState::my_element_count, OperationState::my_xor, OperationState::phase, PHASE_MUST_SEND_DONE, and Operation::state.

Referenced by process_bf(), and send_remaining_elements().

597 {
598  struct GNUNET_MQ_Envelope *ev;
599  struct IntersectionDoneMessage *idm;
600 
603  ev = GNUNET_MQ_msg (idm,
605  idm->final_element_count = htonl (op->state->my_element_count);
606  idm->element_xor_hash = op->state->my_xor;
609  op);
610  GNUNET_MQ_send (op->mq,
611  ev);
612 }
uint32_t final_element_count
Final number of elements in intersection.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
uint32_t my_element_count
Current element count contained within my_elements.
#define GNUNET_NO
Definition: gnunet_common.h:81
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore...
Definition: mq.c:774
static void finished_local_operations(void *cls)
Remember that we are done dealing with the local client AND have sent the other peer our message that...
enum IntersectionOperationPhase phase
Current state of the operation.
We must next send the P2P DONE message (after finishing mostly with the local client).
struct GNUNET_HashCode element_xor_hash
XOR of all hashes over all elements remaining in the set.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE
Intersection operation is done.
Last message, send to confirm the final set.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
int channel_death_expected
Set whenever we reach the state where the death of the channel is perfectly find and should NOT resul...
struct OperationState * state
Operation-specific operation state.
struct GNUNET_HashCode my_xor
XOR of the keys of all of the elements (remaining) in my set.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_remaining_elements()

static void send_remaining_elements ( void *  cls)
static

Send all elements in the full result iterator.

Parameters
clsthe struct Operation *

Definition at line 621 of file gnunet-service-set_intersection.c.

References Operation::client_request_id, Set::cs, GNUNET_SET_Element::data, ElementEntry::element, ElementEntry::element_hash, GNUNET_SET_Element::element_type, GNUNET_SET_ResultMessage::element_type, OperationState::full_result_iter, GNUNET_assert, GNUNET_CONTAINER_multihashmap_iterator_destroy(), GNUNET_CONTAINER_multihashmap_iterator_next(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SET_RESULT, GNUNET_MQ_msg_extra, GNUNET_MQ_notify_sent(), GNUNET_MQ_send(), GNUNET_NO, GNUNET_SET_STATUS_OK, ClientState::mq, op, OperationState::phase, PHASE_DONE_RECEIVED, PHASE_FINISHED, PHASE_MUST_SEND_DONE, GNUNET_SET_ResultMessage::request_id, res, GNUNET_SET_ResultMessage::result_status, send_client_done_and_destroy(), send_p2p_done(), Operation::set, GNUNET_SET_Element::size, and Operation::state.

Referenced by handle_intersection_p2p_done(), and process_bf().

622 {
623  struct Operation *op = cls;
624  const void *nxt;
625  const struct ElementEntry *ee;
626  struct GNUNET_MQ_Envelope *ev;
627  struct GNUNET_SET_ResultMessage *rm;
628  const struct GNUNET_SET_Element *element;
629  int res;
630 
632  NULL,
633  &nxt);
634  if (GNUNET_NO == res)
635  {
637  "Sending done and destroy because iterator ran out\n");
639  op->state->full_result_iter = NULL;
640  if (PHASE_DONE_RECEIVED == op->state->phase)
641  {
642  op->state->phase = PHASE_FINISHED;
644  }
645  else if (PHASE_MUST_SEND_DONE == op->state->phase)
646  {
647  send_p2p_done (op);
648  }
649  else
650  {
651  GNUNET_assert (0);
652  }
653  return;
654  }
655  ee = nxt;
656  element = &ee->element;
658  "Sending element %s:%u to client (full set)\n",
659  GNUNET_h2s (&ee->element_hash),
660  element->size);
661  GNUNET_assert (0 != op->client_request_id);
662  ev = GNUNET_MQ_msg_extra (rm,
663  element->size,
665  GNUNET_assert (NULL != ev);
666  rm->result_status = htons (GNUNET_SET_STATUS_OK);
667  rm->request_id = htonl (op->client_request_id);
668  rm->element_type = element->element_type;
669  GNUNET_memcpy (&rm[1],
670  element->data,
671  element->size);
674  op);
675  GNUNET_MQ_send (op->set->cs->mq,
676  ev);
677 }
void GNUNET_CONTAINER_multihashmap_iterator_destroy(struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
Destroy a multihashmap iterator.
int GNUNET_CONTAINER_multihashmap_iterator_next(struct GNUNET_CONTAINER_MultiHashMapIterator *iter, struct GNUNET_HashCode *key, const void **value)
Retrieve the next element from the hash map at the iterator&#39;s position.
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.
static void send_remaining_elements(void *cls)
Send all elements in the full result iterator.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: set.h:246
Element stored in a set.
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_MESSAGE_TYPE_SET_RESULT
Create an empty set.
static void send_client_done_and_destroy(void *cls)
Signal to the client that the operation has finished and destroy the operation.
uint32_t request_id
id the result belongs to
Definition: set.h:261
#define GNUNET_NO
Definition: gnunet_common.h:81
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
const void * data
Actual data of the element.
static void send_p2p_done(struct Operation *op)
Notify the other peer that we are done.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
#define GNUNET_memcpy(dst, src, n)
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore...
Definition: mq.c:774
Information about an element element in the set.
Everything went ok, we are transmitting an element of the result (in set, or to be removed from set...
The protocol is over.
enum IntersectionOperationPhase phase
Current state of the operation.
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SET_Status in NBO.
Definition: set.h:267
We must next send the P2P DONE message (after finishing mostly with the local client).
static int res
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: set.h:272
Operation context used to execute a set operation.
We have received the P2P DONE message, and must finish with the local client before terminating the c...
struct GNUNET_CONTAINER_MultiHashMapIterator * full_result_iter
Iterator for sending the final set of my_elements to the client.
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.
#define GNUNET_log(kind,...)
struct GNUNET_SET_Element element
The actual element.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
struct ClientState * cs
Client that owns the set.
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
uint16_t element_type
Application-specific element type.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ initialize_map_unfiltered()

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

Fills the "my_elements" hashmap with the initial set of (non-deleted) elements from the set of the specification.

Parameters
clsclosure with the struct Operation *
keycurrent key code for the element
valuevalue in the hash map with the struct ElementEntry *
Returns
GNUNET_YES (we should continue to iterate)

Definition at line 690 of file gnunet-service-set_intersection.c.

References _GSS_is_element_of_operation(), ElementEntry::element, ElementEntry::element_hash, GNUNET_break, GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CRYPTO_hash_xor(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_NO, GNUNET_YES, OperationState::my_elements, OperationState::my_xor, op, GNUNET_SET_Element::size, Operation::state, and value.

Referenced by begin_bf_exchange().

693 {
694  struct ElementEntry *ee = value;
695  struct Operation *op = cls;
696 
697  if (GNUNET_NO == _GSS_is_element_of_operation (ee, op))
698  return GNUNET_YES; /* element not live in operation's generation */
700  &ee->element_hash,
701  &op->state->my_xor);
703  "Initial full initialization of my_elements, adding %s:%u\n",
704  GNUNET_h2s (&ee->element_hash),
705  ee->element.size);
708  &ee->element_hash,
709  ee,
711  return GNUNET_YES;
712 }
int _GSS_is_element_of_operation(struct ElementEntry *ee, struct Operation *op)
Is element ee part of the set used by op?
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_NO
Definition: gnunet_common.h:81
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static char * value
Value of the record to add/remove.
Information about an element element in the set.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
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.
uint16_t size
Number of bytes in the buffer pointed to by data.
#define GNUNET_log(kind,...)
struct GNUNET_SET_Element element
The actual element.
#define GNUNET_YES
Definition: gnunet_common.h:80
void GNUNET_CRYPTO_hash_xor(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result)
compute result = a ^ b
Definition: crypto_hash.c:193
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
struct GNUNET_HashCode my_xor
XOR of the keys of all of the elements (remaining) in my set.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_element_count()

static void send_element_count ( struct Operation op)
static

Send our element count to the peer, in case our element count is lower than theirs.

Parameters
opintersection operation

Definition at line 722 of file gnunet-service-set_intersection.c.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO, GNUNET_MQ_msg, GNUNET_MQ_send(), Operation::mq, msg, OperationState::my_element_count, IntersectionElementInfoMessage::sender_element_count, and Operation::state.

Referenced by intersection_accept().

723 {
724  struct GNUNET_MQ_Envelope *ev;
726 
728  "Sending our element count (%u)\n",
729  op->state->my_element_count);
730  ev = GNUNET_MQ_msg (msg,
732  msg->sender_element_count = htonl (op->state->my_element_count);
733  GNUNET_MQ_send (op->mq, ev);
734 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
uint32_t my_element_count
Current element count contained within my_elements.
uint32_t sender_element_count
mutator used with this bloomfilter.
#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO
Information about the element count for intersection.
During intersection, the first (and possibly second) message send it the number of elements in the se...
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
#define GNUNET_log(kind,...)
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
struct OperationState * state
Operation-specific operation state.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ begin_bf_exchange()

static void begin_bf_exchange ( struct Operation op)
static

We go first, initialize our map with all elements and send the first Bloom filter.

Parameters
opoperation to start exchange for

Definition at line 744 of file gnunet-service-set_intersection.c.

References Set::content, SetContent::elements, GNUNET_CONTAINER_multihashmap_iterate(), initialize_map_unfiltered(), OperationState::phase, PHASE_BF_EXCHANGE, send_bloomfilter(), Operation::set, and Operation::state.

Referenced by handle_intersection_p2p_element_info(), and intersection_accept().

745 {
749  op);
750  send_bloomfilter (op);
751 }
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
static int initialize_map_unfiltered(void *cls, const struct GNUNET_HashCode *key, void *value)
Fills the "my_elements" hashmap with the initial set of (non-deleted) elements from the set of the sp...
We have initialized our set and are now reducing it by exchanging Bloom filters until one party notic...
enum IntersectionOperationPhase phase
Current state of the operation.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
static void send_bloomfilter(struct Operation *op)
Send a bloomfilter to our peer.
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.
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:

◆ handle_intersection_p2p_element_info()

void handle_intersection_p2p_element_info ( void *  cls,
const struct IntersectionElementInfoMessage msg 
)

Handle the initial struct IntersectionElementInfoMessage from a remote peer.

Parameters
clsthe intersection operation
mhthe header of the message

Definition at line 762 of file gnunet-service-set_intersection.c.

References begin_bf_exchange(), Operation::channel, fail_intersection_operation(), GNUNET_break, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_SET_OPERATION_INTERSECTION, OperationState::my_element_count, op, Set::operation, OperationState::phase, PHASE_COUNT_SENT, PHASE_INITIAL, OperationState::remote_bf, Operation::remote_element_count, IntersectionElementInfoMessage::sender_element_count, Operation::set, and Operation::state.

764 {
765  struct Operation *op = cls;
766 
768  {
769  GNUNET_break_op (0);
771  return;
772  }
773  op->remote_element_count = ntohl (msg->sender_element_count);
775  "Received remote element count (%u), I have %u\n",
777  op->state->my_element_count);
778  if ( ( (PHASE_INITIAL != op->state->phase) &&
779  (PHASE_COUNT_SENT != op->state->phase) ) ||
781  (0 == op->state->my_element_count) ||
782  (0 == op->remote_element_count) )
783  {
784  GNUNET_break_op (0);
786  return;
787  }
788  GNUNET_break (NULL == op->state->remote_bf);
789  begin_bf_exchange (op);
791 }
We are just starting.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
static void fail_intersection_operation(struct Operation *op)
Inform the client that the intersection operation has failed, and proceed to destroy the evaluate ope...
static void begin_bf_exchange(struct Operation *op)
We go first, initialize our map with all elements and send the first Bloom filter.
struct GNUNET_CADET_Channel * channel
Channel to the peer.
uint32_t my_element_count
Current element count contained within my_elements.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
enum IntersectionOperationPhase phase
Current state of the operation.
uint32_t sender_element_count
mutator used with this bloomfilter.
enum GNUNET_SET_OperationType operation
Type of operation supported for this set.
Operation context used to execute a set operation.
We have send the number of our elements to the other peer, but did not setup our element set yet...
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:955
struct GNUNET_CONTAINER_BloomFilter * remote_bf
The bf we currently receive.
#define GNUNET_log(kind,...)
Set intersection, only return elements that are in both sets.
uint32_t remote_element_count
Remote peers element count.
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:

◆ process_bf()

static void process_bf ( struct Operation op)
static

Process a Bloomfilter once we got all the chunks.

Parameters
opthe intersection operation

Definition at line 800 of file gnunet-service-set_intersection.c.

References Set::content, SetContent::elements, fail_intersection_operation(), filtered_map_initialization(), OperationState::full_result_iter, GNUNET_break_op, GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CONTAINER_multihashmap_iterator_create(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcmp, GNUNET_SET_RESULT_FULL, iterator_bf_reduce(), OperationState::local_bf, OperationState::my_element_count, OperationState::my_elements, OperationState::my_xor, OperationState::other_xor, OperationState::phase, PHASE_BF_EXCHANGE, PHASE_COUNT_SENT, PHASE_DONE_RECEIVED, PHASE_FINISHED, PHASE_INITIAL, PHASE_MUST_SEND_DONE, OperationState::remote_bf, Operation::remote_element_count, Operation::result_mode, send_bloomfilter(), send_p2p_done(), send_remaining_elements(), Operation::set, and Operation::state.

Referenced by handle_intersection_p2p_bf().

801 {
803  "Received BF in phase %u, foreign count is %u, my element count is %u/%u\n",
804  op->state->phase,
806  op->state->my_element_count,
808  switch (op->state->phase)
809  {
810  case PHASE_INITIAL:
811  GNUNET_break_op (0);
813  return;
814  case PHASE_COUNT_SENT:
815  /* This is the first BF being sent, build our initial map with
816  filtering in place */
817  op->state->my_element_count = 0;
820  op);
821  break;
822  case PHASE_BF_EXCHANGE:
823  /* Update our set by reduction */
826  op);
827  break;
829  GNUNET_break_op (0);
831  return;
832  case PHASE_DONE_RECEIVED:
833  GNUNET_break_op (0);
835  return;
836  case PHASE_FINISHED:
837  GNUNET_break_op (0);
839  return;
840  }
842  op->state->remote_bf = NULL;
843 
844  if ( (0 == op->state->my_element_count) || /* fully disjoint */
845  ( (op->state->my_element_count == op->remote_element_count) &&
846  (0 == GNUNET_memcmp (&op->state->my_xor,
847  &op->state->other_xor)) ) )
848  {
849  /* we are done */
852  "Intersection succeeded, sending DONE to other peer\n");
854  op->state->local_bf = NULL;
856  {
858  "Sending full result set (%u elements)\n",
863  return;
864  }
865  send_p2p_done (op);
866  return;
867  }
869  send_bloomfilter (op);
870 }
enum GNUNET_SET_ResultMode result_mode
When are elements sent to the client, and which elements are sent?
We are just starting.
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.
static void fail_intersection_operation(struct Operation *op)
Inform the client that the intersection operation has failed, and proceed to destroy the evaluate ope...
struct GNUNET_CONTAINER_MultiHashMapIterator * GNUNET_CONTAINER_multihashmap_iterator_create(const struct GNUNET_CONTAINER_MultiHashMap *map)
Create an iterator for a multihashmap.
static void send_remaining_elements(void *cls)
Send all elements in the full result iterator.
static int filtered_map_initialization(void *cls, const struct GNUNET_HashCode *key, void *value)
Fills the "my_elements" hashmap with all relevant elements.
We have initialized our set and are now reducing it by exchanging Bloom filters until one party notic...
struct GNUNET_CONTAINER_BloomFilter * local_bf
BF of the set&#39;s element.
uint32_t my_element_count
Current element count contained within my_elements.
Client gets every element in the resulting set.
static void send_p2p_done(struct Operation *op)
Notify the other peer that we are done.
static int iterator_bf_reduce(void *cls, const struct GNUNET_HashCode *key, void *value)
Removes elements from our hashmap if they are not contained within the provided remote bloomfilter...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
The protocol is over.
enum IntersectionOperationPhase phase
Current state of the operation.
We must next send the P2P DONE message (after finishing mostly with the local client).
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
We have received the P2P DONE message, and must finish with the local client before terminating the c...
We have send the number of our elements to the other peer, but did not setup our element set yet...
struct GNUNET_CONTAINER_MultiHashMapIterator * full_result_iter
Iterator for sending the final set of my_elements to the client.
struct GNUNET_HashCode other_xor
XOR of the keys of all of the elements (remaining) in the other peer&#39;s set.
struct GNUNET_CONTAINER_BloomFilter * remote_bf
The bf we currently receive.
#define GNUNET_log(kind,...)
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
static void send_bloomfilter(struct Operation *op)
Send a bloomfilter to our peer.
uint32_t remote_element_count
Remote peers element count.
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.
struct GNUNET_HashCode my_xor
XOR of the keys of all of the elements (remaining) in my set.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associcated with a filter in memory, flush to drive if needed (do not free the space o...
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_intersection_p2p_bf()

int check_intersection_p2p_bf ( void *  cls,
const struct BFMessage msg 
)

Check an BF message from a remote peer.

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

Definition at line 881 of file gnunet-service-set_intersection.c.

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

883 {
884  struct Operation *op = cls;
885 
887  {
888  GNUNET_break_op (0);
889  return GNUNET_SYSERR;
890  }
891  return GNUNET_OK;
892 }
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
enum GNUNET_SET_OperationType operation
Type of operation supported for this set.
Operation context used to execute a set operation.
Set intersection, only return elements that are in both sets.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139

◆ handle_intersection_p2p_bf()

void handle_intersection_p2p_bf ( void *  cls,
const struct BFMessage msg 
)

Handle an BF message from a remote peer.

Parameters
clsthe intersection operation
msgthe header of the message

Definition at line 902 of file gnunet-service-set_intersection.c.

References OperationState::bf_bits_per_element, OperationState::bf_data, OperationState::bf_data_offset, OperationState::bf_data_size, BFMessage::bits_per_element, BFMessage::bloomfilter_total_length, Operation::channel, BFMessage::element_xor_hash, fail_intersection_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_bloomfilter_init(), GNUNET_free, GNUNET_malloc, GNUNET_memcpy, BFMessage::header, op, OperationState::other_xor, OperationState::phase, PHASE_BF_EXCHANGE, PHASE_COUNT_SENT, PHASE_INITIAL, process_bf(), OperationState::remote_bf, Operation::remote_element_count, OperationState::salt, BFMessage::sender_element_count, BFMessage::sender_mutator, GNUNET_MessageHeader::size, and Operation::state.

904 {
905  struct Operation *op = cls;
906  uint32_t bf_size;
907  uint32_t chunk_size;
908  uint32_t bf_bits_per_element;
909 
910  switch (op->state->phase)
911  {
912  case PHASE_INITIAL:
913  GNUNET_break_op (0);
915  return;
916  case PHASE_COUNT_SENT:
917  case PHASE_BF_EXCHANGE:
918  bf_size = ntohl (msg->bloomfilter_total_length);
919  bf_bits_per_element = ntohl (msg->bits_per_element);
920  chunk_size = htons (msg->header.size) - sizeof (struct BFMessage);
921  op->state->other_xor = msg->element_xor_hash;
922  if (bf_size == chunk_size)
923  {
924  if (NULL != op->state->bf_data)
925  {
926  GNUNET_break_op (0);
928  return;
929  }
930  /* single part, done here immediately */
931  op->state->remote_bf
932  = GNUNET_CONTAINER_bloomfilter_init ((const char*) &msg[1],
933  bf_size,
934  bf_bits_per_element);
935  op->state->salt = ntohl (msg->sender_mutator);
936  op->remote_element_count = ntohl (msg->sender_element_count);
937  process_bf (op);
938  break;
939  }
940  /* multipart chunk */
941  if (NULL == op->state->bf_data)
942  {
943  /* first chunk, initialize */
944  op->state->bf_data = GNUNET_malloc (bf_size);
945  op->state->bf_data_size = bf_size;
946  op->state->bf_bits_per_element = bf_bits_per_element;
947  op->state->bf_data_offset = 0;
948  op->state->salt = ntohl (msg->sender_mutator);
949  op->remote_element_count = ntohl (msg->sender_element_count);
950  }
951  else
952  {
953  /* increment */
954  if ( (op->state->bf_data_size != bf_size) ||
955  (op->state->bf_bits_per_element != bf_bits_per_element) ||
956  (op->state->bf_data_offset + chunk_size > bf_size) ||
957  (op->state->salt != ntohl (msg->sender_mutator)) ||
958  (op->remote_element_count != ntohl (msg->sender_element_count)) )
959  {
960  GNUNET_break_op (0);
962  return;
963  }
964  }
966  (const char*) &msg[1],
967  chunk_size);
968  op->state->bf_data_offset += chunk_size;
969  if (op->state->bf_data_offset == bf_size)
970  {
971  /* last chunk, run! */
972  op->state->remote_bf
974  bf_size,
975  bf_bits_per_element);
976  GNUNET_free (op->state->bf_data);
977  op->state->bf_data = NULL;
978  op->state->bf_data_size = 0;
979  process_bf (op);
980  }
981  break;
982  default:
983  GNUNET_break_op (0);
985  return;
986  }
988 }
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
We are just starting.
static void fail_intersection_operation(struct Operation *op)
Inform the client that the intersection operation has failed, and proceed to destroy the evaluate ope...
uint32_t bf_data_size
size of the bloomfilter in bf_data.
uint32_t salt
Salt currently used for BF construction (by us or the other peer, depending on where we are in the co...
uint32_t sender_element_count
Number of elements the sender still has in the set.
struct GNUNET_CADET_Channel * channel
Channel to the peer.
uint32_t bf_bits_per_element
size of the bloomfilter
static void process_bf(struct Operation *op)
Process a Bloomfilter once we got all the chunks.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF.
We have initialized our set and are now reducing it by exchanging Bloom filters until one party notic...
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
uint32_t bloomfilter_total_length
Total length of the bloomfilter data.
#define GNUNET_memcpy(dst, src, n)
uint32_t bf_data_offset
How many bytes of bf_data are valid?
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
enum IntersectionOperationPhase phase
Current state of the operation.
Bloom filter messages exchanged for set intersection calculation.
struct GNUNET_HashCode element_xor_hash
XOR of all hashes over all elements remaining in the set.
char * bf_data
For multipart BF transmissions, we have to store the bloomfilter-data until we fully received it...
Operation context used to execute a set operation.
uint32_t bits_per_element
Number of bits (k-value) used in encoding the bloomfilter.
We have send the number of our elements to the other peer, but did not setup our element set yet...
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:955
struct GNUNET_HashCode other_xor
XOR of the keys of all of the elements (remaining) in the other peer&#39;s set.
struct GNUNET_CONTAINER_BloomFilter * remote_bf
The bf we currently receive.
uint32_t remote_element_count
Remote peers element count.
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
uint32_t sender_mutator
Mutator used with this bloomfilter.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:

◆ filter_all()

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

Remove all elements from our hashmap.

Parameters
clsclosure with the struct Operation *
keycurrent key code
valuevalue in the hash map
Returns
GNUNET_YES (we should continue to iterate)

Definition at line 1000 of file gnunet-service-set_intersection.c.

References ElementEntry::element, ElementEntry::element_hash, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CRYPTO_hash_xor(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_YES, OperationState::my_element_count, OperationState::my_elements, OperationState::my_xor, op, send_client_removed_element(), GNUNET_SET_Element::size, Operation::state, and value.

Referenced by handle_intersection_p2p_done().

1003 {
1004  struct Operation *op = cls;
1005  struct ElementEntry *ee = value;
1006 
1007  GNUNET_break (0 < op->state->my_element_count);
1008  op->state->my_element_count--;
1010  &ee->element_hash,
1011  &op->state->my_xor);
1013  "Final reduction of my_elements, removing %s:%u\n",
1014  GNUNET_h2s (&ee->element_hash),
1015  ee->element.size);
1018  &ee->element_hash,
1019  ee));
1021  &ee->element);
1022  return GNUNET_YES;
1023 }
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
uint32_t my_element_count
Current element count contained within my_elements.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static void send_client_removed_element(struct Operation *op, struct GNUNET_SET_Element *element)
If applicable in the current operation mode, send a result message to the client indicating we remove...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static char * value
Value of the record to add/remove.
Information about an element element in the 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.
Operation context used to execute a set operation.
uint16_t size
Number of bytes in the buffer pointed to by data.
#define GNUNET_log(kind,...)
struct GNUNET_SET_Element element
The actual element.
#define GNUNET_YES
Definition: gnunet_common.h:80
void GNUNET_CRYPTO_hash_xor(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result)
compute result = a ^ b
Definition: crypto_hash.c:193
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
struct GNUNET_HashCode my_xor
XOR of the keys of all of the elements (remaining) in my set.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_intersection_p2p_done()

void handle_intersection_p2p_done ( void *  cls,
const struct IntersectionDoneMessage idm 
)

Handle a done message from a remote peer.

Parameters
clsthe intersection operation
mhthe message

Definition at line 1033 of file gnunet-service-set_intersection.c.

References Operation::channel, OperationState::client_done_sent, IntersectionDoneMessage::element_xor_hash, fail_intersection_operation(), filter_all(), IntersectionDoneMessage::final_element_count, OperationState::full_result_iter, GNUNET_assert, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CONTAINER_multihashmap_iterator_create(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcmp, GNUNET_NO, GNUNET_SET_OPERATION_INTERSECTION, GNUNET_SET_RESULT_FULL, OperationState::my_element_count, OperationState::my_elements, OperationState::my_xor, op, Set::operation, OperationState::phase, PHASE_BF_EXCHANGE, PHASE_DONE_RECEIVED, PHASE_FINISHED, Operation::result_mode, send_client_done_and_destroy(), send_remaining_elements(), Operation::set, and Operation::state.

1035 {
1036  struct Operation *op = cls;
1037 
1039  {
1040  GNUNET_break_op (0);
1042  return;
1043  }
1044  if (PHASE_BF_EXCHANGE != op->state->phase)
1045  {
1046  /* wrong phase to conclude? FIXME: Or should we allow this
1047  if the other peer has _initially_ already an empty set? */
1048  GNUNET_break_op (0);
1050  return;
1051  }
1052  if (0 == ntohl (idm->final_element_count))
1053  {
1054  /* other peer determined empty set is the intersection,
1055  remove all elements */
1057  &filter_all,
1058  op);
1059  }
1060  if ( (op->state->my_element_count != ntohl (idm->final_element_count)) ||
1061  (0 != GNUNET_memcmp (&op->state->my_xor,
1062  &idm->element_xor_hash)) )
1063  {
1064  /* Other peer thinks we are done, but we disagree on the result! */
1065  GNUNET_break_op (0);
1067  return;
1068  }
1070  "Got IntersectionDoneMessage, have %u elements in intersection\n",
1071  op->state->my_element_count);
1074 
1077  {
1079  "Sending full result set to client (%u elements)\n",
1081  op->state->full_result_iter
1084  return;
1085  }
1086  op->state->phase = PHASE_FINISHED;
1088 }
enum GNUNET_SET_ResultMode result_mode
When are elements sent to the client, and which elements are sent?
uint32_t final_element_count
Final number of elements in intersection.
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.
static void fail_intersection_operation(struct Operation *op)
Inform the client that the intersection operation has failed, and proceed to destroy the evaluate ope...
struct GNUNET_CONTAINER_MultiHashMapIterator * GNUNET_CONTAINER_multihashmap_iterator_create(const struct GNUNET_CONTAINER_MultiHashMap *map)
Create an iterator for a multihashmap.
static void send_remaining_elements(void *cls)
Send all elements in the full result iterator.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_CADET_Channel * channel
Channel to the peer.
static void send_client_done_and_destroy(void *cls)
Signal to the client that the operation has finished and destroy the operation.
We have initialized our set and are now reducing it by exchanging Bloom filters until one party notic...
uint32_t my_element_count
Current element count contained within my_elements.
#define GNUNET_NO
Definition: gnunet_common.h:81
static int filter_all(void *cls, const struct GNUNET_HashCode *key, void *value)
Remove all elements from our hashmap.
int client_done_sent
Did we send the client that we are done?
Client gets every element in the resulting set.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
The protocol is over.
enum IntersectionOperationPhase phase
Current state of the operation.
struct GNUNET_HashCode element_xor_hash
XOR of all hashes over all elements remaining in the set.
enum GNUNET_SET_OperationType operation
Type of operation supported for this set.
Operation context used to execute a set operation.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
We have received the P2P DONE message, and must finish with the local client before terminating the c...
struct GNUNET_CONTAINER_MultiHashMapIterator * full_result_iter
Iterator for sending the final set of my_elements to the client.
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:955
#define GNUNET_log(kind,...)
Set intersection, only return elements that are in both sets.
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_HashCode my_xor
XOR of the keys of all of the elements (remaining) in my set.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
Here is the call graph for this function:

◆ intersection_evaluate()

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

Initiate a set intersection operation with a remote peer.

Parameters
opoperation that is created, should be initialized to begin the evaluation
opaque_contextmessage to be transmitted to the listener to convince it to accept, may be NULL
Returns
operation-specific state to keep in op

Definition at line 1101 of file gnunet-service-set_intersection.c.

References SetState::current_set_element_count, OperationRequestMessage::element_count, GNUNET_break, GNUNET_CONTAINER_multihashmap_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST, GNUNET_MQ_msg_nested_mh, GNUNET_MQ_send(), GNUNET_new, GNUNET_SET_OPERATION_INTERSECTION, GNUNET_YES, Operation::mq, msg, OperationState::my_element_count, OperationState::my_elements, OperationRequestMessage::operation, OperationState::phase, PHASE_COUNT_SENT, PHASE_INITIAL, Operation::set, state, and Set::state.

Referenced by _GSS_intersection_vt().

1103 {
1104  struct OperationState *state;
1105  struct GNUNET_MQ_Envelope *ev;
1106  struct OperationRequestMessage *msg;
1107 
1108  ev = GNUNET_MQ_msg_nested_mh (msg,
1110  opaque_context);
1111  if (NULL == ev)
1112  {
1113  /* the context message is too large!? */
1114  GNUNET_break (0);
1115  return NULL;
1116  }
1118  "Initiating intersection operation evaluation\n");
1119  state = GNUNET_new (struct OperationState);
1120  /* we started the operation, thus we have to send the operation request */
1121  state->phase = PHASE_INITIAL;
1123  state->my_elements
1125  GNUNET_YES);
1126 
1128  msg->element_count = htonl (state->my_element_count);
1129  GNUNET_MQ_send (op->mq,
1130  ev);
1131  state->phase = PHASE_COUNT_SENT;
1132  if (NULL != opaque_context)
1134  "Sent op request with context message\n");
1135  else
1137  "Sent op request without context message\n");
1138  return state;
1139 }
State of an evaluate operation with another peer.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
We are just starting.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
uint32_t element_count
For Intersection: my element count.
#define GNUNET_MQ_msg_nested_mh(mvar, type, mh)
Allocate a GNUNET_MQ_Envelope, and append a payload message after the given message struct...
struct SetState * state
Implementation-specific state.
uint32_t my_element_count
Current element count contained within my_elements.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_MESSAGE_TYPE_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.
uint32_t current_set_element_count
Number of currently valid elements in the set which have not been removed.
We have send the number of our elements to the other peer, but did not setup our element set yet...
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
#define GNUNET_log(kind,...)
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.
#define GNUNET_YES
Definition: gnunet_common.h:80
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
Set intersection, only return elements that are in both sets.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ intersection_accept()

static struct OperationState* intersection_accept ( struct Operation op)
static

Accept an intersection operation request from a remote peer.

Only initializes the private operation state.

Parameters
opoperation that will be accepted as an intersection operation

Definition at line 1149 of file gnunet-service-set_intersection.c.

References begin_bf_exchange(), SetState::current_set_element_count, GNUNET_CONTAINER_multihashmap_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MIN, GNUNET_new, GNUNET_YES, OperationState::my_element_count, OperationState::my_elements, OperationState::phase, PHASE_COUNT_SENT, PHASE_INITIAL, Operation::remote_element_count, send_element_count(), Operation::set, state, Operation::state, and Set::state.

Referenced by _GSS_intersection_vt().

1150 {
1151  struct OperationState *state;
1152 
1154  "Accepting set intersection operation\n");
1155  state = GNUNET_new (struct OperationState);
1156  state->phase = PHASE_INITIAL;
1157  state->my_element_count
1159  state->my_elements
1161  op->remote_element_count),
1162  GNUNET_YES);
1163  op->state = state;
1164  if (op->remote_element_count < state->my_element_count)
1165  {
1166  /* If the other peer (Alice) has fewer elements than us (Bob),
1167  we just send the count as Alice should send the first BF */
1168  send_element_count (op);
1169  state->phase = PHASE_COUNT_SENT;
1170  return state;
1171  }
1172  /* We have fewer elements, so we start with the BF */
1173  begin_bf_exchange (op);
1174  return state;
1175 }
State of an evaluate operation with another peer.
We are just starting.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
struct SetState * state
Implementation-specific state.
static void begin_bf_exchange(struct Operation *op)
We go first, initialize our map with all elements and send the first Bloom filter.
uint32_t my_element_count
Current element count contained within my_elements.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
enum State state
current state of profiling
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:83
enum IntersectionOperationPhase phase
Current state of the operation.
uint32_t current_set_element_count
Number of currently valid elements in the set which have not been removed.
static void send_element_count(struct Operation *op)
Send our element count to the peer, in case our element count is lower than theirs.
We have send the number of our elements to the other peer, but did not setup our element set yet...
#define GNUNET_log(kind,...)
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
#define GNUNET_YES
Definition: gnunet_common.h:80
uint32_t remote_element_count
Remote peers element count.
struct OperationState * state
Operation-specific operation state.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ intersection_op_cancel()

static void intersection_op_cancel ( struct Operation op)
static

Destroy the intersection operation.

Only things specific to the intersection operation are destroyed.

Parameters
opintersection operation to destroy

Definition at line 1185 of file gnunet-service-set_intersection.c.

References OperationState::full_result_iter, GNUNET_assert, GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterator_destroy(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, OperationState::local_bf, OperationState::my_elements, OperationState::remote_bf, and Operation::state.

Referenced by _GSS_intersection_vt().

1186 {
1187  /* check if the op was canceled twice */
1188  GNUNET_assert (NULL != op->state);
1189  if (NULL != op->state->remote_bf)
1190  {
1192  op->state->remote_bf = NULL;
1193  }
1194  if (NULL != op->state->local_bf)
1195  {
1197  op->state->local_bf = NULL;
1198  }
1199  if (NULL != op->state->my_elements)
1200  {
1202  op->state->my_elements = NULL;
1203  }
1204  if (NULL != op->state->full_result_iter)
1205  {
1207  op->state->full_result_iter = NULL;
1208  }
1209  GNUNET_free (op->state);
1210  op->state = NULL;
1212  "Destroying intersection op state done\n");
1213 }
void GNUNET_CONTAINER_multihashmap_iterator_destroy(struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
Destroy a multihashmap iterator.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_CONTAINER_BloomFilter * local_bf
BF of the set&#39;s element.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMapIterator * full_result_iter
Iterator for sending the final set of my_elements to the client.
struct GNUNET_CONTAINER_BloomFilter * remote_bf
The bf we currently receive.
#define GNUNET_log(kind,...)
struct OperationState * state
Operation-specific operation state.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associcated with a filter in memory, flush to drive if needed (do not free the space o...
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ intersection_set_create()

static struct SetState* intersection_set_create ( )
static

Create a new set supporting the intersection operation.

Returns
the newly created set

Definition at line 1222 of file gnunet-service-set_intersection.c.

References SetState::current_set_element_count, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, and GNUNET_new.

Referenced by _GSS_intersection_vt().

1223 {
1224  struct SetState *set_state;
1225 
1227  "Intersection set created\n");
1228  set_state = GNUNET_new (struct SetState);
1229  set_state->current_set_element_count = 0;
1230 
1231  return set_state;
1232 }
#define GNUNET_new(type)
Allocate a struct or union of the given type.
uint32_t current_set_element_count
Number of currently valid elements in the set which have not been removed.
Extra state required for efficient set intersection.
#define GNUNET_log(kind,...)
Here is the caller graph for this function:

◆ intersection_add()

static void intersection_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 1242 of file gnunet-service-set_intersection.c.

References SetState::current_set_element_count.

Referenced by _GSS_intersection_vt().

1244 {
1245  set_state->current_set_element_count++;
1246 }
uint32_t current_set_element_count
Number of currently valid elements in the set which have not been removed.
Here is the caller graph for this function:

◆ intersection_set_destroy()

static void intersection_set_destroy ( struct SetState set_state)
static

Destroy a set that supports the intersection operation.

Parameters
set_statethe set to destroy

Definition at line 1255 of file gnunet-service-set_intersection.c.

References GNUNET_free.

Referenced by _GSS_intersection_vt().

1256 {
1257  GNUNET_free (set_state);
1258 }
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function:

◆ intersection_remove()

static void intersection_remove ( struct SetState set_state,
struct ElementEntry element 
)
static

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

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

Definition at line 1268 of file gnunet-service-set_intersection.c.

References SetState::current_set_element_count, and GNUNET_assert.

Referenced by _GSS_intersection_vt().

1270 {
1271  GNUNET_assert (0 < set_state->current_set_element_count);
1272  set_state->current_set_element_count--;
1273 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
uint32_t current_set_element_count
Number of currently valid elements in the set which have not been removed.
Here is the caller graph for this function:

◆ intersection_channel_death()

static void intersection_channel_death ( struct Operation op)
static

Callback for channel death for the intersection operation.

Parameters
opoperation that lost the channel

Definition at line 1282 of file gnunet-service-set_intersection.c.

References _GSS_operation_destroy(), OperationState::channel_death_expected, GNUNET_YES, send_client_done_and_destroy(), and Operation::state.

Referenced by _GSS_intersection_vt().

1283 {
1285  {
1286  /* oh goodie, we are done! */
1288  }
1289  else
1290  {
1291  /* sorry, channel went down early, too bad. */
1293  GNUNET_YES);
1294  }
1295 }
static void send_client_done_and_destroy(void *cls)
Signal to the client that the operation has finished and destroy the operation.
void _GSS_operation_destroy(struct Operation *op, int gc)
Destroy the given operation.
#define GNUNET_YES
Definition: gnunet_common.h:80
int channel_death_expected
Set whenever we reach the state where the death of the channel is perfectly find and should NOT resul...
struct OperationState * state
Operation-specific operation state.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _GSS_intersection_vt()

const struct SetVT* _GSS_intersection_vt ( void  )

Get the table with implementing functions for set intersection.

Returns
the operation specific VTable

Definition at line 1304 of file gnunet-service-set_intersection.c.

References SetVT::create, intersection_accept(), intersection_add(), intersection_channel_death(), intersection_evaluate(), intersection_op_cancel(), intersection_remove(), intersection_set_create(), and intersection_set_destroy().

Referenced by handle_client_copy_lazy_connect(), and handle_client_create_set().

1305 {
1306  static const struct SetVT intersection_vt = {
1308  .add = &intersection_add,
1309  .remove = &intersection_remove,
1310  .destroy_set = &intersection_set_destroy,
1311  .evaluate = &intersection_evaluate,
1312  .accept = &intersection_accept,
1313  .cancel = &intersection_op_cancel,
1314  .channel_death = &intersection_channel_death,
1315  };
1316 
1317  return &intersection_vt;
1318 }
static void intersection_add(struct SetState *set_state, struct ElementEntry *ee)
Add the element from the given element message to the set.
static struct OperationState * intersection_evaluate(struct Operation *op, const struct GNUNET_MessageHeader *opaque_context)
Initiate a set intersection operation with a remote peer.
Dispatch table for a specific set operation.
static struct SetState * intersection_set_create()
Create a new set supporting the intersection operation.
static void intersection_remove(struct SetState *set_state, struct ElementEntry *element)
Remove the element given in the element message from the set.
static void intersection_channel_death(struct Operation *op)
Callback for channel death for the intersection operation.
static void intersection_set_destroy(struct SetState *set_state)
Destroy a set that supports the intersection operation.
SetCreateImpl create
Callback for the set creation.
static struct OperationState * intersection_accept(struct Operation *op)
Accept an intersection operation request from a remote peer.
static void intersection_op_cancel(struct Operation *op)
Destroy the intersection operation.
Here is the call graph for this function:
Here is the caller graph for this function: