GNUnet 0.28.0-dev.3-20-gf1136b0b8
 
Loading...
Searching...
No Matches
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.
 
void handle_intersection_p2p_bf (void *cls, const struct BFMessage *msg)
 Handle an BF message from a remote peer.
 
void handle_intersection_p2p_element_info (void *cls, const struct IntersectionElementInfoMessage *msg)
 Handle the initial struct IntersectionElementInfoMessage from a remote peer.
 
void handle_intersection_p2p_done (void *cls, const struct IntersectionDoneMessage *idm)
 Handle a done message from a remote peer.
 

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

885{
886 struct Operation *op = cls;
887
888 if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation)
889 {
890 GNUNET_break_op (0);
891 return GNUNET_SYSERR;
892 }
893 return GNUNET_OK;
894}
static struct GNUNET_ARM_Operation * op
Current operation.
Definition gnunet-arm.c:143
@ 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 904 of file gnunet-service-set_intersection.c.

906{
907 struct Operation *op = cls;
908 uint32_t bf_size;
909 uint32_t chunk_size;
910 uint32_t bf_bits_per_element;
911
912 switch (op->state->phase)
913 {
914 case PHASE_INITIAL:
915 GNUNET_break_op (0);
917 return;
918
919 case PHASE_COUNT_SENT:
921 bf_size = ntohl (msg->bloomfilter_total_length);
922 bf_bits_per_element = ntohl (msg->bits_per_element);
923 chunk_size = htons (msg->header.size) - sizeof(struct BFMessage);
924 op->state->other_xor = msg->element_xor_hash;
925 if (bf_size == chunk_size)
926 {
927 if (NULL != op->state->bf_data)
928 {
929 GNUNET_break_op (0);
931 return;
932 }
933 /* single part, done here immediately */
934 op->state->remote_bf
935 = GNUNET_CONTAINER_bloomfilter_init ((const char *) &msg[1],
936 bf_size,
937 bf_bits_per_element);
938 op->state->salt = ntohl (msg->sender_mutator);
939 op->remote_element_count = ntohl (msg->sender_element_count);
940 process_bf (op);
941 break;
942 }
943 /* multipart chunk */
944 if (NULL == op->state->bf_data)
945 {
946 /* first chunk, initialize */
947 op->state->bf_data = GNUNET_malloc (bf_size);
948 op->state->bf_data_size = bf_size;
949 op->state->bf_bits_per_element = bf_bits_per_element;
950 op->state->bf_data_offset = 0;
951 op->state->salt = ntohl (msg->sender_mutator);
952 op->remote_element_count = ntohl (msg->sender_element_count);
953 }
954 else
955 {
956 /* increment */
957 if ((op->state->bf_data_size != bf_size) ||
958 (op->state->bf_bits_per_element != bf_bits_per_element) ||
959 (op->state->bf_data_offset + chunk_size > bf_size) ||
960 (op->state->salt != ntohl (msg->sender_mutator)) ||
961 (op->remote_element_count != ntohl (msg->sender_element_count)))
962 {
963 GNUNET_break_op (0);
965 return;
966 }
967 }
968 GNUNET_memcpy (&op->state->bf_data[op->state->bf_data_offset],
969 (const char *) &msg[1],
970 chunk_size);
971 op->state->bf_data_offset += chunk_size;
972 if (op->state->bf_data_offset == bf_size)
973 {
974 /* last chunk, run! */
975 op->state->remote_bf
976 = GNUNET_CONTAINER_bloomfilter_init (op->state->bf_data,
977 bf_size,
978 bf_bits_per_element);
979 GNUNET_free (op->state->bf_data);
980 op->state->bf_data = NULL;
981 op->state->bf_data_size = 0;
982 process_bf (op);
983 }
984 break;
985
986 default:
987 GNUNET_break_op (0);
989 return;
990 }
991 GNUNET_CADET_receive_done (op->channel);
992}
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:875
#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 757 of file gnunet-service-set_intersection.c.

760{
761 struct Operation *op = cls;
762
763 if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation)
764 {
765 GNUNET_break_op (0);
767 return;
768 }
769 op->remote_element_count = ntohl (msg->sender_element_count);
771 "Received remote element count (%u), I have %u\n",
772 op->remote_element_count,
773 op->state->my_element_count);
774 if (((PHASE_INITIAL != op->state->phase) &&
775 (PHASE_COUNT_SENT != op->state->phase)) ||
776 (op->state->my_element_count > op->remote_element_count) ||
777 (0 == op->state->my_element_count) ||
778 (0 == op->remote_element_count))
779 {
780 GNUNET_break_op (0);
782 return;
783 }
784 GNUNET_break (NULL == op->state->remote_bf);
786 GNUNET_CADET_receive_done (op->channel);
787}
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 1037 of file gnunet-service-set_intersection.c.

1039{
1040 struct Operation *op = cls;
1041
1042 if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation)
1043 {
1044 GNUNET_break_op (0);
1046 return;
1047 }
1048 if (PHASE_BF_EXCHANGE != op->state->phase)
1049 {
1050 /* wrong phase to conclude? FIXME: Or should we allow this
1051 if the other peer has _initially_ already an empty set? */
1052 GNUNET_break_op (0);
1054 return;
1055 }
1056 if (0 == ntohl (idm->final_element_count))
1057 {
1058 /* other peer determined empty set is the intersection,
1059 remove all elements */
1060 GNUNET_CONTAINER_multihashmap_iterate (op->state->my_elements,
1061 &filter_all,
1062 op);
1063 }
1064 if ((op->state->my_element_count != ntohl (idm->final_element_count)) ||
1065 (0 != GNUNET_memcmp (&op->state->my_xor,
1066 &idm->element_xor_hash)))
1067 {
1068 /* Other peer thinks we are done, but we disagree on the result! */
1069 GNUNET_break_op (0);
1071 return;
1072 }
1074 "Got IntersectionDoneMessage, have %u elements in intersection\n",
1075 op->state->my_element_count);
1076 op->state->phase = PHASE_DONE_RECEIVED;
1077 GNUNET_CADET_receive_done (op->channel);
1078
1079 GNUNET_assert (GNUNET_NO == op->state->client_done_sent);
1080 if (GNUNET_SET_RESULT_FULL == op->result_mode)
1081 {
1083 "Sending full result set to client (%u elements)\n",
1084 GNUNET_CONTAINER_multihashmap_size (op->state->my_elements));
1085 op->state->full_result_iter
1086 = GNUNET_CONTAINER_multihashmap_iterator_create (op->state->my_elements);
1088 return;
1089 }
1090 op->state->phase = PHASE_FINISHED;
1092}
@ 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: