GNUnet 0.21.1
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:
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)
Indicate readiness to receive the next message on a channel.
Definition: cadet_api.c:872
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
Bloom filter messages exchanged for set intersection calculation.
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.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
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.
#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: