GNUnet  0.19.5
gnunet-service-set_intersection.h File Reference

two-peer set operations More...

Include dependency graph for gnunet-service-set_intersection.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

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...
 
void handle_intersection_p2p_element_info (void *cls, const struct IntersectionElementInfoMessage *msg)
 Handle the initial struct IntersectionElementInfoMessage from a remote peer. More...
 
void handle_intersection_p2p_done (void *cls, const struct IntersectionDoneMessage *idm)
 Handle a done message from a remote peer. More...
 

Detailed Description

two-peer set operations

Author
Florian Dold
Christian Grothoff

Definition in file gnunet-service-set_intersection.h.

Function Documentation

◆ 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 884 of file gnunet-service-set_intersection.c.

886 {
887  struct Operation *op = cls;
888 
889  if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation)
890  {
891  GNUNET_break_op (0);
892  return GNUNET_SYSERR;
893  }
894  return GNUNET_OK;
895 }
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
@ GNUNET_OK
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
@ GNUNET_SET_OPERATION_INTERSECTION
Set intersection, only return elements that are in both sets.
Operation context used to execute a set operation.

References GNUNET_break_op, GNUNET_OK, GNUNET_SET_OPERATION_INTERSECTION, GNUNET_SYSERR, and op.

◆ 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 905 of file gnunet-service-set_intersection.c.

907 {
908  struct Operation *op = cls;
909  uint32_t bf_size;
910  uint32_t chunk_size;
911  uint32_t bf_bits_per_element;
912 
913  switch (op->state->phase)
914  {
915  case PHASE_INITIAL:
916  GNUNET_break_op (0);
918  return;
919 
920  case PHASE_COUNT_SENT:
921  case PHASE_BF_EXCHANGE:
922  bf_size = ntohl (msg->bloomfilter_total_length);
923  bf_bits_per_element = ntohl (msg->bits_per_element);
924  chunk_size = htons (msg->header.size) - sizeof(struct BFMessage);
925  op->state->other_xor = msg->element_xor_hash;
926  if (bf_size == chunk_size)
927  {
928  if (NULL != op->state->bf_data)
929  {
930  GNUNET_break_op (0);
932  return;
933  }
934  /* single part, done here immediately */
935  op->state->remote_bf
936  = GNUNET_CONTAINER_bloomfilter_init ((const char *) &msg[1],
937  bf_size,
938  bf_bits_per_element);
939  op->state->salt = ntohl (msg->sender_mutator);
940  op->remote_element_count = ntohl (msg->sender_element_count);
941  process_bf (op);
942  break;
943  }
944  /* multipart chunk */
945  if (NULL == op->state->bf_data)
946  {
947  /* first chunk, initialize */
948  op->state->bf_data = GNUNET_malloc (bf_size);
949  op->state->bf_data_size = bf_size;
950  op->state->bf_bits_per_element = bf_bits_per_element;
951  op->state->bf_data_offset = 0;
952  op->state->salt = ntohl (msg->sender_mutator);
953  op->remote_element_count = ntohl (msg->sender_element_count);
954  }
955  else
956  {
957  /* increment */
958  if ((op->state->bf_data_size != bf_size) ||
959  (op->state->bf_bits_per_element != bf_bits_per_element) ||
960  (op->state->bf_data_offset + chunk_size > bf_size) ||
961  (op->state->salt != ntohl (msg->sender_mutator)) ||
962  (op->remote_element_count != ntohl (msg->sender_element_count)))
963  {
964  GNUNET_break_op (0);
966  return;
967  }
968  }
969  GNUNET_memcpy (&op->state->bf_data[op->state->bf_data_offset],
970  (const char *) &msg[1],
971  chunk_size);
972  op->state->bf_data_offset += chunk_size;
973  if (op->state->bf_data_offset == bf_size)
974  {
975  /* last chunk, run! */
976  op->state->remote_bf
977  = GNUNET_CONTAINER_bloomfilter_init (op->state->bf_data,
978  bf_size,
979  bf_bits_per_element);
980  GNUNET_free (op->state->bf_data);
981  op->state->bf_data = NULL;
982  op->state->bf_data_size = 0;
983  process_bf (op);
984  }
985  break;
986 
987  default:
988  GNUNET_break_op (0);
990  return;
991  }
992  GNUNET_CADET_receive_done (op->channel);
993 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
@ PHASE_INITIAL
We are just starting.
@ PHASE_BF_EXCHANGE
We have initialized our set and are now reducing it by exchanging Bloom filters until one party notic...
@ PHASE_COUNT_SENT
We have send the number of our elements to the other peer, but did not setup our element set yet.
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 process_bf(struct Operation *op)
Process a Bloomfilter once we got all the chunks.
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
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:872
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
Bloom filter messages exchanged for set intersection calculation.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
uint32_t bf_bits_per_element
size of the bloomfilter

References Operation::bf_bits_per_element, fail_intersection_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_bloomfilter_init(), GNUNET_free, GNUNET_malloc, GNUNET_memcpy, msg, op, PHASE_BF_EXCHANGE, PHASE_COUNT_SENT, PHASE_INITIAL, process_bf(), and GNUNET_MessageHeader::size.

Here is the call 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
msgthe header of the message

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

761 {
762  struct Operation *op = cls;
763 
764  if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation)
765  {
766  GNUNET_break_op (0);
768  return;
769  }
770  op->remote_element_count = ntohl (msg->sender_element_count);
772  "Received remote element count (%u), I have %u\n",
773  op->remote_element_count,
774  op->state->my_element_count);
775  if (((PHASE_INITIAL != op->state->phase) &&
776  (PHASE_COUNT_SENT != op->state->phase)) ||
777  (op->state->my_element_count > op->remote_element_count) ||
778  (0 == op->state->my_element_count) ||
779  (0 == op->remote_element_count))
780  {
781  GNUNET_break_op (0);
783  return;
784  }
785  GNUNET_break (NULL == op->state->remote_bf);
787  GNUNET_CADET_receive_done (op->channel);
788 }
static void begin_bf_exchange(struct Operation *op)
We go first, initialize our map with all elements and send the first Bloom filter.
#define GNUNET_log(kind,...)
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_DEBUG

References begin_bf_exchange(), fail_intersection_operation(), GNUNET_break, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_SET_OPERATION_INTERSECTION, msg, op, PHASE_COUNT_SENT, and PHASE_INITIAL.

Here is the call 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
clsthe intersection operation
idmthe message

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

1040 {
1041  struct Operation *op = cls;
1042 
1043  if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation)
1044  {
1045  GNUNET_break_op (0);
1047  return;
1048  }
1049  if (PHASE_BF_EXCHANGE != op->state->phase)
1050  {
1051  /* wrong phase to conclude? FIXME: Or should we allow this
1052  if the other peer has _initially_ already an empty set? */
1053  GNUNET_break_op (0);
1055  return;
1056  }
1057  if (0 == ntohl (idm->final_element_count))
1058  {
1059  /* other peer determined empty set is the intersection,
1060  remove all elements */
1061  GNUNET_CONTAINER_multihashmap_iterate (op->state->my_elements,
1062  &filter_all,
1063  op);
1064  }
1065  if ((op->state->my_element_count != ntohl (idm->final_element_count)) ||
1066  (0 != GNUNET_memcmp (&op->state->my_xor,
1067  &idm->element_xor_hash)))
1068  {
1069  /* Other peer thinks we are done, but we disagree on the result! */
1070  GNUNET_break_op (0);
1072  return;
1073  }
1075  "Got IntersectionDoneMessage, have %u elements in intersection\n",
1076  op->state->my_element_count);
1077  op->state->phase = PHASE_DONE_RECEIVED;
1078  GNUNET_CADET_receive_done (op->channel);
1079 
1080  GNUNET_assert (GNUNET_NO == op->state->client_done_sent);
1081  if (GNUNET_SET_RESULT_FULL == op->result_mode)
1082  {
1084  "Sending full result set to client (%u elements)\n",
1085  GNUNET_CONTAINER_multihashmap_size (op->state->my_elements));
1086  op->state->full_result_iter
1087  = GNUNET_CONTAINER_multihashmap_iterator_create (op->state->my_elements);
1089  return;
1090  }
1091  op->state->phase = PHASE_FINISHED;
1093 }
@ PHASE_DONE_RECEIVED
We have received the P2P DONE message, and must finish with the local client before terminating the c...
@ PHASE_FINISHED
The protocol is over.
static int filter_all(void *cls, const struct GNUNET_HashCode *key, void *value)
Remove all elements from our hashmap.
static void send_remaining_elements(void *cls)
Send all elements in the full result iterator.
static void send_client_done_and_destroy(void *cls)
Signal to the client that the operation has finished and destroy the operation.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
struct GNUNET_CONTAINER_MultiHashMapIterator * GNUNET_CONTAINER_multihashmap_iterator_create(const struct GNUNET_CONTAINER_MultiHashMap *map)
Create an iterator for a multihashmap.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
@ GNUNET_NO
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_SET_RESULT_FULL
Client gets every element in the resulting set.
uint32_t final_element_count
Final number of elements in intersection.
struct GNUNET_HashCode element_xor_hash
XOR of all hashes over all elements remaining in the set.

References IntersectionDoneMessage::element_xor_hash, fail_intersection_operation(), filter_all(), IntersectionDoneMessage::final_element_count, 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, op, PHASE_BF_EXCHANGE, PHASE_DONE_RECEIVED, PHASE_FINISHED, send_client_done_and_destroy(), and send_remaining_elements().

Here is the call graph for this function: