aboutsummaryrefslogtreecommitdiff
path: root/src/set
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2014-11-27 20:17:24 +0000
committerChristian Grothoff <christian@grothoff.org>2014-11-27 20:17:24 +0000
commitf23525cfc0c0a8931db0b20b35c1aabbfbc5ac4e (patch)
tree3ef89bce9f65613c8f697c04b4280e14091d1ace /src/set
parent1dc3a88ad71d1ca99bed5d38977d69f88de3d253 (diff)
downloadgnunet-f23525cfc0c0a8931db0b20b35c1aabbfbc5ac4e.tar.gz
gnunet-f23525cfc0c0a8931db0b20b35c1aabbfbc5ac4e.zip
use separate struct for just sending #elements in set, and check message size before casting
Diffstat (limited to 'src/set')
-rw-r--r--src/set/gnunet-service-set_intersection.c576
-rw-r--r--src/set/gnunet-service-set_protocol.h23
-rw-r--r--src/set/set.h9
3 files changed, 337 insertions, 271 deletions
diff --git a/src/set/gnunet-service-set_intersection.c b/src/set/gnunet-service-set_intersection.c
index 749f2e98d..19d6498f5 100644
--- a/src/set/gnunet-service-set_intersection.c
+++ b/src/set/gnunet-service-set_intersection.c
@@ -31,6 +31,15 @@
31 31
32#define BLOOMFILTER_SIZE GNUNET_CRYPTO_HASH_LENGTH 32#define BLOOMFILTER_SIZE GNUNET_CRYPTO_HASH_LENGTH
33 33
34/**
35 * Calculate the size of the bloom filter.
36 *
37 * @param A
38 * @param B
39 * @param s
40 * @param k
41 * @return
42 */
34#define CALCULATE_BF_SIZE(A, B, s, k) \ 43#define CALCULATE_BF_SIZE(A, B, s, k) \
35 do { \ 44 do { \
36 k = ceil(1 + log2((double) (2*B / (double) A)));\ 45 k = ceil(1 + log2((double) (2*B / (double) A)));\
@@ -38,6 +47,7 @@
38 s = ceil((double) (A * k / log(2))); \ 47 s = ceil((double) (A * k / log(2))); \
39 } while (0) 48 } while (0)
40 49
50
41/** 51/**
42 * Current phase we are in for a intersection operation. 52 * Current phase we are in for a intersection operation.
43 */ 53 */
@@ -48,11 +58,13 @@ enum IntersectionOperationPhase
48 * and is waiting for a bf or session end. 58 * and is waiting for a bf or session end.
49 */ 59 */
50 PHASE_INITIAL, 60 PHASE_INITIAL,
61
51 /** 62 /**
52 * Bob has accepted the operation, Bob and Alice are now exchanging bfs 63 * Bob has accepted the operation, Bob and Alice are now exchanging bfs
53 * until one notices the their element count is equal 64 * until one notices the their element count is equal
54 */ 65 */
55 PHASE_BF_EXCHANGE, 66 PHASE_BF_EXCHANGE,
67
56 /** 68 /**
57 * if both peers have an equal peercount, they enter this state for 69 * if both peers have an equal peercount, they enter this state for
58 * one more turn, to see if they actually have agreed on a correct set. 70 * one more turn, to see if they actually have agreed on a correct set.
@@ -60,6 +72,7 @@ enum IntersectionOperationPhase
60 * it ends the the session 72 * it ends the the session
61 */ 73 */
62 PHASE_MAYBE_FINISHED, 74 PHASE_MAYBE_FINISHED,
75
63 /** 76 /**
64 * The protocol is over. 77 * The protocol is over.
65 * Results may still have to be sent to the client. 78 * Results may still have to be sent to the client.
@@ -84,7 +97,13 @@ struct OperationState
84 struct GNUNET_CONTAINER_BloomFilter *local_bf; 97 struct GNUNET_CONTAINER_BloomFilter *local_bf;
85 98
86 /** 99 /**
87 * Iterator for sending elements on the key to element mapping to the client. 100 * Remaining elements in the intersection operation.
101 * Maps element-id-hashes to 'elements in our set'.
102 */
103 struct GNUNET_CONTAINER_MultiHashMap *my_elements;
104
105 /**
106 * Iterator for sending the final set of @e my_elements to the client.
88 */ 107 */
89 struct GNUNET_CONTAINER_MultiHashMapIterator *full_result_iter; 108 struct GNUNET_CONTAINER_MultiHashMapIterator *full_result_iter;
90 109
@@ -104,11 +123,6 @@ struct OperationState
104 char *bf_data; 123 char *bf_data;
105 124
106 /** 125 /**
107 * Maps element-id-hashes to 'elements in our set'.
108 */
109 struct GNUNET_CONTAINER_MultiHashMap *my_elements;
110
111 /**
112 * Current element count contained within @e my_elements 126 * Current element count contained within @e my_elements
113 */ 127 */
114 uint32_t my_element_count; 128 uint32_t my_element_count;
@@ -143,6 +157,7 @@ struct OperationState
143 157
144/** 158/**
145 * Extra state required for efficient set intersection. 159 * Extra state required for efficient set intersection.
160 * Merely tracks the total number of elements.
146 */ 161 */
147struct SetState 162struct SetState
148{ 163{
@@ -154,140 +169,113 @@ struct SetState
154 169
155 170
156/** 171/**
157 * Send a result message to the client indicating 172 * If applicable in the current operation mode, send a result message
158 * we removed an element 173 * to the client indicating we removed an element.
159 * 174 *
160 * @param op union operation 175 * @param op intersection operation
161 * @param element element to send 176 * @param element element to send
162 */ 177 */
163static void 178static void
164send_client_element (struct Operation *op, 179send_client_removed_element (struct Operation *op,
165 struct GNUNET_SET_Element *element) 180 struct GNUNET_SET_Element *element)
166{ 181{
167 struct GNUNET_MQ_Envelope *ev; 182 struct GNUNET_MQ_Envelope *ev;
168 struct GNUNET_SET_ResultMessage *rm; 183 struct GNUNET_SET_ResultMessage *rm;
169 184
185 if (GNUNET_SET_RESULT_REMOVED != op->spec->result_mode)
186 return; /* Wrong mode for transmitting removed elements */
170 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
171 "sending removed element (size %u) to client\n", 188 "Sending removed element (size %u) to client\n",
172 element->size); 189 element->size);
173 GNUNET_assert (0 != op->spec->client_request_id); 190 GNUNET_assert (0 != op->spec->client_request_id);
174 ev = GNUNET_MQ_msg_extra (rm, element->size, GNUNET_MESSAGE_TYPE_SET_RESULT); 191 ev = GNUNET_MQ_msg_extra (rm,
192 element->size,
193 GNUNET_MESSAGE_TYPE_SET_RESULT);
175 if (NULL == ev) 194 if (NULL == ev)
176 { 195 {
177 GNUNET_MQ_discard (ev);
178 GNUNET_break (0); 196 GNUNET_break (0);
179 return; 197 return;
180 } 198 }
181 rm->result_status = htons (GNUNET_SET_STATUS_OK); 199 rm->result_status = htons (GNUNET_SET_STATUS_OK);
182 rm->request_id = htonl (op->spec->client_request_id); 200 rm->request_id = htonl (op->spec->client_request_id);
183 rm->element_type = element->element_type; 201 rm->element_type = element->element_type;
184 memcpy (&rm[1], element->data, element->size); 202 memcpy (&rm[1],
185 GNUNET_MQ_send (op->spec->set->client_mq, ev); 203 element->data,
204 element->size);
205 GNUNET_MQ_send (op->spec->set->client_mq,
206 ev);
186} 207}
187 208
188 209
189/** 210/**
190 * Alice's version: 211 * Fills the "my_elements" hashmap with all relevant elements and
212 * adds their mutated hashes to our local bloomfilter with mutator+1.
191 * 213 *
192 * fills the contained-elements hashmap with all relevant 214 * @param cls the `struct Operation *` we are performing
193 * elements and adds their mutated hashes to our local bloomfilter with mutator+1
194 *
195 * @param cls closure
196 * @param key current key code 215 * @param key current key code
197 * @param value value in the hash map 216 * @param value the `struct ElementEntry *` from the hash map
198 * @return #GNUNET_YES if we should continue to 217 * @return #GNUNET_YES (we should continue to iterate)
199 * iterate,
200 * #GNUNET_NO if not.
201 */ 218 */
202static int 219static int
203iterator_initialization_by_alice (void *cls, 220filtered_map_and_bf_initialization (void *cls,
204 const struct GNUNET_HashCode *key, 221 const struct GNUNET_HashCode *key,
205 void *value) 222 void *value)
206{ 223{
207 struct ElementEntry *ee = value;
208 struct Operation *op = cls; 224 struct Operation *op = cls;
225 struct ElementEntry *ee = value;
209 struct GNUNET_HashCode mutated_hash; 226 struct GNUNET_HashCode mutated_hash;
210 227
211 //only consider this element, if it is valid for us 228 if ( (op->generation_created < ee->generation_removed) &&
212 if ((op->generation_created < ee->generation_removed) 229 (op->generation_created >= ee->generation_added) )
213 && (op->generation_created >= ee->generation_added)) 230 return GNUNET_YES; /* element not valid in our operation's generation */
214 return GNUNET_YES;
215 231
216 // not contained according to bob's bloomfilter 232 /* Test if element is in Bob's bloomfilter */
217 GNUNET_BLOCK_mingle_hash(&ee->element_hash, 233 // FIXME: where does this salt come from!?
218 op->spec->salt, 234 GNUNET_BLOCK_mingle_hash (&ee->element_hash,
219 &mutated_hash); 235 op->spec->salt,
220 if (GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (op->state->remote_bf, 236 &mutated_hash);
221 &mutated_hash)){ 237 if (GNUNET_NO ==
222 if (GNUNET_SET_RESULT_REMOVED == op->spec->result_mode) 238 GNUNET_CONTAINER_bloomfilter_test (op->state->remote_bf,
223 send_client_element (op, &ee->element); 239 &mutated_hash))
240 {
241 /* remove this element */
242 send_client_removed_element (op,
243 &ee->element);
224 return GNUNET_YES; 244 return GNUNET_YES;
225 } 245 }
226
227 op->state->my_element_count++; 246 op->state->my_element_count++;
228 GNUNET_assert (GNUNET_YES == 247 GNUNET_break (GNUNET_YES ==
229 GNUNET_CONTAINER_multihashmap_put (op->state->my_elements, 248 GNUNET_CONTAINER_multihashmap_put (op->state->my_elements,
230 &ee->element_hash, ee, 249 &ee->element_hash,
231 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 250 ee,
232 251 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
233 return GNUNET_YES;
234}
235
236
237/**
238 * fills the contained-elements hashmap with all relevant
239 * elements and adds their mutated hashes to our local bloomfilter
240 *
241 * @param cls closure
242 * @param key current key code
243 * @param value value in the hash map
244 * @return #GNUNET_YES if we should continue to
245 * iterate,
246 * #GNUNET_NO if not.
247 */
248static int
249iterator_initialization (void *cls,
250 const struct GNUNET_HashCode *key,
251 void *value)
252{
253 struct ElementEntry *ee = value;
254 struct Operation *op = cls;
255 252
256 //only consider this element, if it is valid for us
257 if ((op->generation_created < ee->generation_removed)
258 && (op->generation_created >= ee->generation_added))
259 return GNUNET_YES;
260
261 GNUNET_assert (GNUNET_YES ==
262 GNUNET_CONTAINER_multihashmap_put (op->state->my_elements,
263 &ee->element_hash, ee,
264 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
265 return GNUNET_YES; 253 return GNUNET_YES;
266} 254}
267 255
268 256
269/** 257/**
270 * removes element from a hashmap if it is not contained within the 258 * Removes elements from our hashmap if they are not contained within the
271 * provided remote bloomfilter. Then, fill our new bloomfilter. 259 * provided remote bloomfilter.
272 * 260 *
273 * @param cls closure 261 * @param cls closure with the `struct Operation *`
274 * @param key current key code 262 * @param key current key code
275 * @param value value in the hash map 263 * @param value value in the hash map
276 * @return #GNUNET_YES if we should continue to 264 * @return #GNUNET_YES (we should continue to iterate)
277 * iterate,
278 * #GNUNET_NO if not.
279 */ 265 */
280static int 266static int
281iterator_bf_reduce (void *cls, 267iterator_bf_reduce (void *cls,
282 const struct GNUNET_HashCode *key, 268 const struct GNUNET_HashCode *key,
283 void *value) 269 void *value)
284{ 270{
285 struct ElementEntry *ee = value;
286 struct Operation *op = cls; 271 struct Operation *op = cls;
272 struct ElementEntry *ee = value;
287 struct GNUNET_HashCode mutated_hash; 273 struct GNUNET_HashCode mutated_hash;
288 274
289 GNUNET_BLOCK_mingle_hash(&ee->element_hash, op->spec->salt, &mutated_hash); 275 // FIXME: where does this salt come from!?
290 276 GNUNET_BLOCK_mingle_hash (&ee->element_hash,
277 op->spec->salt,
278 &mutated_hash);
291 if (GNUNET_NO == 279 if (GNUNET_NO ==
292 GNUNET_CONTAINER_bloomfilter_test (op->state->remote_bf, 280 GNUNET_CONTAINER_bloomfilter_test (op->state->remote_bf,
293 &mutated_hash)) 281 &mutated_hash))
@@ -297,33 +285,31 @@ iterator_bf_reduce (void *cls,
297 GNUNET_CONTAINER_multihashmap_remove (op->state->my_elements, 285 GNUNET_CONTAINER_multihashmap_remove (op->state->my_elements,
298 &ee->element_hash, 286 &ee->element_hash,
299 ee)); 287 ee));
300 if (GNUNET_SET_RESULT_REMOVED == op->spec->result_mode) 288 send_client_removed_element (op,
301 send_client_element (op, &ee->element); 289 &ee->element);
302 } 290 }
303
304 return GNUNET_YES; 291 return GNUNET_YES;
305} 292}
306 293
307 294
308/** 295/**
309 * Create a bloomfilter based on the elements given 296 * Create initial bloomfilter based on all the elements given.
310 * 297 *
311 * @param cls closure 298 * @param cls the `struct Operation *`
312 * @param key current key code 299 * @param key current key code
313 * @param value value in the hash map 300 * @param value the `struct ElementEntry` to process
314 * @return #GNUNET_YES if we should continue to 301 * @return #GNUNET_YES (we should continue to iterate)
315 * iterate,
316 * #GNUNET_NO if not.
317 */ 302 */
318static int 303static int
319iterator_bf_create (void *cls, 304iterator_bf_create (void *cls,
320 const struct GNUNET_HashCode *key, 305 const struct GNUNET_HashCode *key,
321 void *value) 306 void *value)
322{ 307{
323 struct ElementEntry *ee = value;
324 struct Operation *op = cls; 308 struct Operation *op = cls;
309 struct ElementEntry *ee = value;
325 struct GNUNET_HashCode mutated_hash; 310 struct GNUNET_HashCode mutated_hash;
326 311
312 // FIXME: where does this salt come from!?
327 GNUNET_BLOCK_mingle_hash (&ee->element_hash, 313 GNUNET_BLOCK_mingle_hash (&ee->element_hash,
328 op->spec->salt, 314 op->spec->salt,
329 &mutated_hash); 315 &mutated_hash);
@@ -334,7 +320,7 @@ iterator_bf_create (void *cls,
334 320
335 321
336/** 322/**
337 * Inform the client that the union operation has failed, 323 * Inform the client that the intersection operation has failed,
338 * and proceed to destroy the evaluate operation. 324 * and proceed to destroy the evaluate operation.
339 * 325 *
340 * @param op the intersection operation to fail 326 * @param op the intersection operation to fail
@@ -345,23 +331,35 @@ fail_intersection_operation (struct Operation *op)
345 struct GNUNET_MQ_Envelope *ev; 331 struct GNUNET_MQ_Envelope *ev;
346 struct GNUNET_SET_ResultMessage *msg; 332 struct GNUNET_SET_ResultMessage *msg;
347 333
348 if (op->state->my_elements) 334 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
335 "Intersection operation failed\n");
336 if (NULL != op->state->my_elements)
349 { 337 {
350 GNUNET_CONTAINER_multihashmap_destroy(op->state->my_elements); 338 GNUNET_CONTAINER_multihashmap_destroy (op->state->my_elements);
351 op->state->my_elements = NULL; 339 op->state->my_elements = NULL;
352 } 340 }
353 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 341 ev = GNUNET_MQ_msg (msg,
354 "intersection operation failed\n"); 342 GNUNET_MESSAGE_TYPE_SET_RESULT);
355
356 ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_RESULT);
357 msg->result_status = htons (GNUNET_SET_STATUS_FAILURE); 343 msg->result_status = htons (GNUNET_SET_STATUS_FAILURE);
358 msg->request_id = htonl (op->spec->client_request_id); 344 msg->request_id = htonl (op->spec->client_request_id);
359 msg->element_type = htons (0); 345 msg->element_type = htons (0);
360 GNUNET_MQ_send (op->spec->set->client_mq, ev); 346 GNUNET_MQ_send (op->spec->set->client_mq,
361 _GSS_operation_destroy (op, GNUNET_YES); 347 ev);
348 _GSS_operation_destroy (op,
349 GNUNET_YES);
362} 350}
363 351
364 352
353
354
355
356
357
358/**
359 *
360 * @param op
361 * @param offset
362 */
365static void 363static void
366send_bloomfilter_multipart (struct Operation *op, 364send_bloomfilter_multipart (struct Operation *op,
367 uint32_t offset) 365 uint32_t offset)
@@ -396,10 +394,8 @@ send_bloomfilter_multipart (struct Operation *op,
396 394
397 395
398/** 396/**
399 * Send a bloomfilter to our peer. 397 * Send a bloomfilter to our peer. After the result done message has
400 * that the operation is over. 398 * been sent to the client, destroy the evaluate operation.
401 * After the result done message has been sent to the client,
402 * destroy the evaluate operation.
403 * 399 *
404 * @param op intersection operation 400 * @param op intersection operation
405 */ 401 */
@@ -411,7 +407,7 @@ send_bloomfilter (struct Operation *op)
411 uint32_t bf_size; 407 uint32_t bf_size;
412 uint32_t bf_elementbits; 408 uint32_t bf_elementbits;
413 uint32_t chunk_size; 409 uint32_t chunk_size;
414 struct GNUNET_CONTAINER_BloomFilter * local_bf; 410 struct GNUNET_CONTAINER_BloomFilter *local_bf;
415 411
416 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 412 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
417 "sending bf of size %u\n"); 413 "sending bf of size %u\n");
@@ -435,7 +431,9 @@ send_bloomfilter (struct Operation *op)
435 { 431 {
436 // singlepart 432 // singlepart
437 chunk_size = bf_size; 433 chunk_size = bf_size;
438 ev = GNUNET_MQ_msg_extra (msg, chunk_size, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF); 434 ev = GNUNET_MQ_msg_extra (msg,
435 chunk_size,
436 GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF);
439 GNUNET_assert (GNUNET_SYSERR != 437 GNUNET_assert (GNUNET_SYSERR !=
440 GNUNET_CONTAINER_bloomfilter_get_raw_data (local_bf, 438 GNUNET_CONTAINER_bloomfilter_get_raw_data (local_bf,
441 (char*)&msg[1], 439 (char*)&msg[1],
@@ -445,7 +443,9 @@ send_bloomfilter (struct Operation *op)
445 { 443 {
446 //multipart 444 //multipart
447 chunk_size = GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct BFMessage); 445 chunk_size = GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct BFMessage);
448 ev = GNUNET_MQ_msg_extra (msg, chunk_size, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF); 446 ev = GNUNET_MQ_msg_extra (msg,
447 chunk_size,
448 GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF);
449 op->state->bf_data = (char *) GNUNET_malloc (bf_size); 449 op->state->bf_data = (char *) GNUNET_malloc (bf_size);
450 GNUNET_assert (GNUNET_SYSERR != 450 GNUNET_assert (GNUNET_SYSERR !=
451 GNUNET_CONTAINER_bloomfilter_get_raw_data (local_bf, 451 GNUNET_CONTAINER_bloomfilter_get_raw_data (local_bf,
@@ -482,57 +482,65 @@ send_client_done_and_destroy (void *cls)
482 struct GNUNET_MQ_Envelope *ev; 482 struct GNUNET_MQ_Envelope *ev;
483 struct GNUNET_SET_ResultMessage *rm; 483 struct GNUNET_SET_ResultMessage *rm;
484 484
485 ev = GNUNET_MQ_msg (rm, GNUNET_MESSAGE_TYPE_SET_RESULT); 485 ev = GNUNET_MQ_msg (rm,
486 GNUNET_MESSAGE_TYPE_SET_RESULT);
486 rm->request_id = htonl (op->spec->client_request_id); 487 rm->request_id = htonl (op->spec->client_request_id);
487 rm->result_status = htons (GNUNET_SET_STATUS_DONE); 488 rm->result_status = htons (GNUNET_SET_STATUS_DONE);
488 rm->element_type = htons (0); 489 rm->element_type = htons (0);
489 GNUNET_MQ_send (op->spec->set->client_mq, ev); 490 GNUNET_MQ_send (op->spec->set->client_mq,
490 _GSS_operation_destroy (op, GNUNET_YES); 491 ev);
492 _GSS_operation_destroy (op,
493 GNUNET_YES);
491} 494}
492 495
493 496
494/** 497/**
495 * Send all elements in the full result iterator. 498 * Send all elements in the full result iterator.
496 * 499 *
497 * @param cls operation 500 * @param cls the `struct Operation *`
498 */ 501 */
499static void 502static void
500send_remaining_elements (void *cls) 503send_remaining_elements (void *cls)
501{ 504{
502 struct Operation *op = cls; 505 struct Operation *op = cls;
503 struct ElementEntry *remaining; //TODO rework this, key entry does not exist here 506 const void *nxt;
507 const struct ElementEntry *ee;
504 struct GNUNET_MQ_Envelope *ev; 508 struct GNUNET_MQ_Envelope *ev;
505 struct GNUNET_SET_ResultMessage *rm; 509 struct GNUNET_SET_ResultMessage *rm;
506 struct GNUNET_SET_Element *element; 510 const struct GNUNET_SET_Element *element;
507 int res; 511 int res;
508 512
509 res = GNUNET_CONTAINER_multihashmap_iterator_next (op->state->full_result_iter, 513 res = GNUNET_CONTAINER_multihashmap_iterator_next (op->state->full_result_iter,
510 NULL, 514 NULL,
511 (const void **) &remaining); 515 &nxt);
512 if (GNUNET_NO == res) 516 if (GNUNET_NO == res)
513 { 517 {
514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 518 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
515 "sending done and destroy because iterator ran out\n"); 519 "Sending done and destroy because iterator ran out\n");
516 send_client_done_and_destroy (op); 520 send_client_done_and_destroy (op);
517 return; 521 return;
518 } 522 }
519 523 ee = nxt;
520 element = &remaining->element; 524 element = &ee->element;
521 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 525 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
522 "sending element (size %u) to client (full set)\n", 526 "Sending element (size %u) to client (full set)\n",
523 element->size); 527 element->size);
524 GNUNET_assert (0 != op->spec->client_request_id); 528 GNUNET_assert (0 != op->spec->client_request_id);
525 529 ev = GNUNET_MQ_msg_extra (rm,
526 ev = GNUNET_MQ_msg_extra (rm, element->size, GNUNET_MESSAGE_TYPE_SET_RESULT); 530 element->size,
531 GNUNET_MESSAGE_TYPE_SET_RESULT);
527 GNUNET_assert (NULL != ev); 532 GNUNET_assert (NULL != ev);
528
529 rm->result_status = htons (GNUNET_SET_STATUS_OK); 533 rm->result_status = htons (GNUNET_SET_STATUS_OK);
530 rm->request_id = htonl (op->spec->client_request_id); 534 rm->request_id = htonl (op->spec->client_request_id);
531 rm->element_type = element->element_type; 535 rm->element_type = element->element_type;
532 memcpy (&rm[1], element->data, element->size); 536 memcpy (&rm[1],
533 537 element->data,
534 GNUNET_MQ_notify_sent (ev, send_remaining_elements, op); 538 element->size);
535 GNUNET_MQ_send (op->spec->set->client_mq, ev); 539 GNUNET_MQ_notify_sent (ev,
540 &send_remaining_elements,
541 op);
542 GNUNET_MQ_send (op->spec->set->client_mq,
543 ev);
536} 544}
537 545
538 546
@@ -558,7 +566,7 @@ send_peer_done (struct Operation *op)
558 566
559 567
560/** 568/**
561 * Process a Bloomfilter once we got all the chunks 569 * Process a Bloomfilter once we got all the chunks.
562 * 570 *
563 * @param op the intersection operation 571 * @param op the intersection operation
564 */ 572 */
@@ -573,16 +581,18 @@ process_bf (struct Operation *op)
573 switch (op->state->phase) 581 switch (op->state->phase)
574 { 582 {
575 case PHASE_INITIAL: 583 case PHASE_INITIAL:
576 // If we are ot our first msg 584 /* This is the first BF being sent, build our
577 op->state->my_elements = GNUNET_CONTAINER_multihashmap_create (op->state->my_element_count, GNUNET_YES); 585 initial map with filtering in place */
578 586 op->state->my_elements
587 = GNUNET_CONTAINER_multihashmap_create (op->spec->remote_element_count,
588 GNUNET_YES);
579 GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->elements, 589 GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->elements,
580 &iterator_initialization_by_alice, 590 &filtered_map_and_bf_initialization,
581 op); 591 op);
582 break; 592 break;
583 case PHASE_BF_EXCHANGE: 593 case PHASE_BF_EXCHANGE:
584 case PHASE_MAYBE_FINISHED: 594 case PHASE_MAYBE_FINISHED:
585 // if we are bob or alice and are continuing operation 595 /* Update our set by reduction */
586 GNUNET_CONTAINER_multihashmap_iterate (op->state->my_elements, 596 GNUNET_CONTAINER_multihashmap_iterate (op->state->my_elements,
587 &iterator_bf_reduce, 597 &iterator_bf_reduce,
588 op); 598 op);
@@ -626,7 +636,8 @@ process_bf (struct Operation *op)
626 * @param mh the header of the message 636 * @param mh the header of the message
627 */ 637 */
628static void 638static void
629handle_p2p_bf_part (void *cls, const struct GNUNET_MessageHeader *mh) 639handle_p2p_bf_part (void *cls,
640 const struct GNUNET_MessageHeader *mh)
630{ 641{
631 struct Operation *op = cls; 642 struct Operation *op = cls;
632 const struct BFPart *msg = (const struct BFPart *) mh; 643 const struct BFPart *msg = (const struct BFPart *) mh;
@@ -716,7 +727,37 @@ handle_p2p_bf (void *cls,
716 727
717 728
718/** 729/**
719 * Handle an BF message from a remote peer. 730 * Fills the "my_elements" hashmap with the initial set of
731 * (non-deleted) elements from the set of the specification.
732 *
733 * @param cls closure with the `struct Operation *`
734 * @param key current key code for the element
735 * @param value value in the hash map with the `struct ElementEntry *`
736 * @return #GNUNET_YES (we should continue to iterate)
737 */
738static int
739initialize_map (void *cls,
740 const struct GNUNET_HashCode *key,
741 void *value)
742{
743 struct ElementEntry *ee = value;
744 struct Operation *op = cls;
745
746 if ( (op->generation_created < ee->generation_removed) &&
747 (op->generation_created >= ee->generation_added) )
748 return GNUNET_YES; /* element not live in operation's generation */
749 GNUNET_break (GNUNET_YES ==
750 GNUNET_CONTAINER_multihashmap_put (op->state->my_elements,
751 &ee->element_hash,
752 ee,
753 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
754 return GNUNET_YES;
755}
756
757
758/**
759 * Handle the initial `struct IntersectionElementInfoMessage` from a
760 * remote peer.
720 * 761 *
721 * @param cls the intersection operation 762 * @param cls the intersection operation
722 * @param mh the header of the message 763 * @param mh the header of the message
@@ -726,13 +767,20 @@ handle_p2p_element_info (void *cls,
726 const struct GNUNET_MessageHeader *mh) 767 const struct GNUNET_MessageHeader *mh)
727{ 768{
728 struct Operation *op = cls; 769 struct Operation *op = cls;
729 const struct BFMessage *msg = (const struct BFMessage *) mh; 770 const struct IntersectionElementInfoMessage *msg;
730 771
731 op->spec->remote_element_count = ntohl(msg->sender_element_count); 772 if (ntohs (mh->size) != sizeof (struct IntersectionElementInfoMessage))
732 if ((op->state->phase != PHASE_INITIAL) 773 {
733 || (op->state->my_element_count > op->spec->remote_element_count) 774 GNUNET_break_op (0);
734 || (0 == op->state->my_element_count) 775 fail_intersection_operation(op);
735 || (0 == op->spec->remote_element_count)) 776 return;
777 }
778 msg = (const struct IntersectionElementInfoMessage *) mh;
779 op->spec->remote_element_count = ntohl (msg->sender_element_count);
780 if ( (PHASE_INITIAL != op->state->phase) ||
781 (op->state->my_element_count > op->spec->remote_element_count) ||
782 (0 == op->state->my_element_count) ||
783 (0 == op->spec->remote_element_count) )
736 { 784 {
737 GNUNET_break_op (0); 785 GNUNET_break_op (0);
738 fail_intersection_operation(op); 786 fail_intersection_operation(op);
@@ -740,12 +788,12 @@ handle_p2p_element_info (void *cls,
740 } 788 }
741 789
742 op->state->phase = PHASE_BF_EXCHANGE; 790 op->state->phase = PHASE_BF_EXCHANGE;
743 op->state->my_elements = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); 791 // FIXME... -- why a new map here!?
744 792 op->state->my_elements = GNUNET_CONTAINER_multihashmap_create (1,
793 GNUNET_YES);
745 GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->elements, 794 GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->elements,
746 &iterator_initialization, 795 &initialize_map, // FIXME: filtering!?
747 op); 796 op);
748
749 GNUNET_CONTAINER_bloomfilter_free (op->state->remote_bf); 797 GNUNET_CONTAINER_bloomfilter_free (op->state->remote_bf);
750 op->state->remote_bf = NULL; 798 op->state->remote_bf = NULL;
751 799
@@ -765,26 +813,21 @@ static void
765send_element_count (struct Operation *op) 813send_element_count (struct Operation *op)
766{ 814{
767 struct GNUNET_MQ_Envelope *ev; 815 struct GNUNET_MQ_Envelope *ev;
768 struct BFMessage *msg; 816 struct IntersectionElementInfoMessage *msg;
769 817
770 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 818 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
771 "sending element count (bf_msg)\n"); 819 "Sending our element count (bf_msg)\n");
772 820 ev = GNUNET_MQ_msg (msg,
773 // just send our element count, as the other peer must start 821 GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO);
774 ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO);
775 msg->sender_element_count = htonl (op->state->my_element_count); 822 msg->sender_element_count = htonl (op->state->my_element_count);
776 msg->bloomfilter_length = htonl (0);
777 msg->sender_mutator = htonl (0);
778
779 GNUNET_MQ_send (op->mq, ev); 823 GNUNET_MQ_send (op->mq, ev);
780} 824}
781 825
782 826
783/** 827/**
784 * Send a result message to the client indicating 828 * Send a result message to the client indicating that the operation
785 * that the operation is over. 829 * is over. After the result done message has been sent to the
786 * After the result done message has been sent to the client, 830 * client, destroy the evaluate operation.
787 * destroy the evaluate operation.
788 * 831 *
789 * @param op intersection operation 832 * @param op intersection operation
790 */ 833 */
@@ -796,9 +839,9 @@ finish_and_destroy (struct Operation *op)
796 if (GNUNET_SET_RESULT_FULL == op->spec->result_mode) 839 if (GNUNET_SET_RESULT_FULL == op->spec->result_mode)
797 { 840 {
798 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 841 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
799 "sending full result set\n"); 842 "Sending full result set\n");
800 op->state->full_result_iter = 843 op->state->full_result_iter
801 GNUNET_CONTAINER_multihashmap_iterator_create (op->state->my_elements); 844 = GNUNET_CONTAINER_multihashmap_iterator_create (op->state->my_elements);
802 send_remaining_elements (op); 845 send_remaining_elements (op);
803 return; 846 return;
804 } 847 }
@@ -809,7 +852,7 @@ finish_and_destroy (struct Operation *op)
809/** 852/**
810 * Handle a done message from a remote peer 853 * Handle a done message from a remote peer
811 * 854 *
812 * @param cls the union operation 855 * @param cls the intersection operation
813 * @param mh the message 856 * @param mh the message
814 */ 857 */
815static void 858static void
@@ -822,19 +865,17 @@ handle_p2p_done (void *cls,
822 (op->state->phase = PHASE_MAYBE_FINISHED) ) 865 (op->state->phase = PHASE_MAYBE_FINISHED) )
823 { 866 {
824 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 867 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
825 "got final DONE\n"); 868 "Got final DONE\n");
826
827 finish_and_destroy (op); 869 finish_and_destroy (op);
828 return; 870 return;
829 } 871 }
830
831 GNUNET_break_op (0); 872 GNUNET_break_op (0);
832 fail_intersection_operation (op); 873 fail_intersection_operation (op);
833} 874}
834 875
835 876
836/** 877/**
837 * Initiate a set union operation with a remote peer. 878 * Initiate a set intersection operation with a remote peer.
838 * 879 *
839 * @param op operation that is created, should be initialized to 880 * @param op operation that is created, should be initialized to
840 * begin the evaluation 881 * begin the evaluation
@@ -861,119 +902,66 @@ intersection_evaluate (struct Operation *op,
861 opaque_context); 902 opaque_context);
862 if (NULL == ev) 903 if (NULL == ev)
863 { 904 {
864 /* the context message is too large */ 905 /* the context message is too large!? */
865 GNUNET_break (0); 906 GNUNET_break (0);
866 GNUNET_SERVER_client_disconnect (op->spec->set->client); 907 GNUNET_SERVER_client_disconnect (op->spec->set->client);
867 return; 908 return;
868 } 909 }
869 msg->operation = htonl (GNUNET_SET_OPERATION_INTERSECTION); 910 msg->operation = htonl (GNUNET_SET_OPERATION_INTERSECTION);
870 msg->app_id = op->spec->app_id; 911 msg->app_id = op->spec->app_id;
912 // FIXME: where does this 'salt' come from?
871 msg->salt = htonl (op->spec->salt); 913 msg->salt = htonl (op->spec->salt);
872 msg->element_count = htonl(op->state->my_element_count); 914 msg->element_count = htonl (op->state->my_element_count);
873 GNUNET_MQ_send (op->mq, ev); 915 GNUNET_MQ_send (op->mq,
916 ev);
874 if (NULL != opaque_context) 917 if (NULL != opaque_context)
875 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 918 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
876 "sent op request with context message\n"); 919 "Sent op request with context message\n");
877 else 920 else
878 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 921 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
879 "sent op request without context message\n"); 922 "Sent op request without context message\n");
880} 923}
881 924
882 925
883/** 926/**
884 * Accept an union operation request from a remote peer. 927 * Accept an intersection operation request from a remote peer. Only
885 * Only initializes the private operation state. 928 * initializes the private operation state.
886 * 929 *
887 * @param op operation that will be accepted as a union operation 930 * @param op operation that will be accepted as an intersection operation
888 */ 931 */
889static void 932static void
890intersection_accept (struct Operation *op) 933intersection_accept (struct Operation *op)
891{ 934{
892 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 935 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
893 "accepting set union operation\n"); 936 "Accepting set intersection operation\n");
894 op->state = GNUNET_new (struct OperationState); 937 op->state = GNUNET_new (struct OperationState);
895 op->state->my_elements = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_YES); 938 op->state->my_element_count
896 op->state->my_element_count = op->spec->set->state->current_set_element_count; 939 = op->spec->set->state->current_set_element_count;
897 940 op->state->my_elements
898 // if Alice (the peer) has more elements than Bob (us), she should start 941 = GNUNET_CONTAINER_multihashmap_create (GNUNET_MIN (op->state->my_element_count,
899 if (op->spec->remote_element_count < op->state->my_element_count){ 942 op->spec->remote_element_count),
943 GNUNET_YES);
944 if (op->spec->remote_element_count < op->state->my_element_count)
945 {
946 /* If the other peer (Alice) has fewer elements than us (Bob),
947 we just send the count as Alice should send the first BF */
900 op->state->phase = PHASE_INITIAL; 948 op->state->phase = PHASE_INITIAL;
901 send_element_count(op); 949 send_element_count (op);
902 return; 950 return;
903 } 951 }
904 // create a new bloomfilter in case we have fewer elements 952 /* We have fewer elements, so we start with the BF */
905 op->state->phase = PHASE_BF_EXCHANGE; 953 op->state->phase = PHASE_BF_EXCHANGE;
906 op->state->local_bf = GNUNET_CONTAINER_bloomfilter_init (NULL, 954 op->state->local_bf = GNUNET_CONTAINER_bloomfilter_init (NULL,
907 BLOOMFILTER_SIZE, 955 BLOOMFILTER_SIZE,
908 GNUNET_CONSTANTS_BLOOMFILTER_K); 956 GNUNET_CONSTANTS_BLOOMFILTER_K);
909 GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->elements, 957 GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->elements,
910 &iterator_initialization, 958 &initialize_map,
911 op); 959 op);
912 send_bloomfilter (op); 960 send_bloomfilter (op);
913} 961}
914 962
915 963
916/** 964/**
917 * Create a new set supporting the intersection operation
918 *
919 * @return the newly created set
920 */
921static struct SetState *
922intersection_set_create ()
923{
924 struct SetState *set_state;
925
926 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
927 "intersection set created\n");
928 set_state = GNUNET_new (struct SetState);
929 set_state->current_set_element_count = 0;
930
931 return set_state;
932}
933
934
935/**
936 * Add the element from the given element message to the set.
937 *
938 * @param set_state state of the set want to add to
939 * @param ee the element to add to the set
940 */
941static void
942intersection_add (struct SetState *set_state,
943 struct ElementEntry *ee)
944{
945 set_state->current_set_element_count++;
946}
947
948
949/**
950 * Destroy a set that supports the intersection operation
951 *
952 * @param set_state the set to destroy
953 */
954static void
955intersection_set_destroy (struct SetState *set_state)
956{
957 GNUNET_free (set_state);
958}
959
960
961/**
962 * Remove the element given in the element message from the set.
963 *
964 * @param set_state state of the set to remove from
965 * @param element set element to remove
966 */
967static void
968intersection_remove (struct SetState *set_state,
969 struct ElementEntry *element)
970{
971 GNUNET_assert(0 < set_state->current_set_element_count);
972 set_state->current_set_element_count--;
973}
974
975
976/**
977 * Dispatch messages for a intersection operation. 965 * Dispatch messages for a intersection operation.
978 * 966 *
979 * @param op the state of the intersection evaluate operation 967 * @param op the state of the intersection evaluate operation
@@ -986,7 +974,7 @@ intersection_handle_p2p_message (struct Operation *op,
986 const struct GNUNET_MessageHeader *mh) 974 const struct GNUNET_MessageHeader *mh)
987{ 975{
988 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 976 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
989 "received p2p message (t: %u, s: %u)\n", 977 "Received p2p message (t: %u, s: %u)\n",
990 ntohs (mh->type), ntohs (mh->size)); 978 ntohs (mh->type), ntohs (mh->size));
991 switch (ntohs (mh->type)) 979 switch (ntohs (mh->type))
992 { 980 {
@@ -1014,7 +1002,9 @@ intersection_handle_p2p_message (struct Operation *op,
1014 1002
1015 1003
1016/** 1004/**
1017 * handler for peer-disconnects, notifies the client about the aborted operation 1005 * Handler for peer-disconnects, notifies the client about the aborted
1006 * operation. If we did not expect anything from the other peer, we
1007 * gracefully terminate the operation.
1018 * 1008 *
1019 * @param op the destroyed operation 1009 * @param op the destroyed operation
1020 */ 1010 */
@@ -1023,37 +1013,26 @@ intersection_peer_disconnect (struct Operation *op)
1023{ 1013{
1024 if (PHASE_FINISHED != op->state->phase) 1014 if (PHASE_FINISHED != op->state->phase)
1025 { 1015 {
1026 struct GNUNET_MQ_Envelope *ev; 1016 fail_intersection_operation (op);
1027 struct GNUNET_SET_ResultMessage *msg;
1028
1029 ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_RESULT);
1030 msg->request_id = htonl (op->spec->client_request_id);
1031 msg->result_status = htons (GNUNET_SET_STATUS_FAILURE);
1032 msg->element_type = htons (0);
1033 GNUNET_MQ_send (op->spec->set->client_mq, ev);
1034 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1035 "other peer disconnected prematurely\n");
1036 _GSS_operation_destroy (op, GNUNET_YES);
1037 return; 1017 return;
1038 } 1018 }
1039 // else: the session has already been concluded 1019 /* the session has already been concluded */
1040 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1020 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1041 "other peer disconnected (finished)\n"); 1021 "Other peer disconnected (finished)\n");
1042 if (GNUNET_NO == op->state->client_done_sent) 1022 if (GNUNET_NO == op->state->client_done_sent)
1043 finish_and_destroy (op); 1023 finish_and_destroy (op);
1044} 1024}
1045 1025
1046 1026
1047/** 1027/**
1048 * Destroy the union operation. Only things specific to the union operation are destroyed. 1028 * Destroy the intersection operation. Only things specific to the
1029 * intersection operation are destroyed.
1049 * 1030 *
1050 * @param op union operation to destroy 1031 * @param op intersection operation to destroy
1051 */ 1032 */
1052static void 1033static void
1053intersection_op_cancel (struct Operation *op) 1034intersection_op_cancel (struct Operation *op)
1054{ 1035{
1055 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1056 "destroying intersection op\n");
1057 /* check if the op was canceled twice */ 1036 /* check if the op was canceled twice */
1058 GNUNET_assert (NULL != op->state); 1037 GNUNET_assert (NULL != op->state);
1059 if (NULL != op->state->remote_bf) 1038 if (NULL != op->state->remote_bf)
@@ -1066,16 +1045,75 @@ intersection_op_cancel (struct Operation *op)
1066 GNUNET_CONTAINER_bloomfilter_free (op->state->local_bf); 1045 GNUNET_CONTAINER_bloomfilter_free (op->state->local_bf);
1067 op->state->local_bf = NULL; 1046 op->state->local_bf = NULL;
1068 } 1047 }
1069/* if (NULL != op->state->my_elements) 1048 if (NULL != op->state->my_elements)
1070 { 1049 {
1071 // no need to free the elements, they are still part of the set
1072 GNUNET_CONTAINER_multihashmap_destroy (op->state->my_elements); 1050 GNUNET_CONTAINER_multihashmap_destroy (op->state->my_elements);
1073 op->state->my_elements = NULL; 1051 op->state->my_elements = NULL;
1074 }*/ 1052 }
1075 GNUNET_free (op->state); 1053 GNUNET_free (op->state);
1076 op->state = NULL; 1054 op->state = NULL;
1077 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1055 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1078 "destroying intersection op done\n"); 1056 "Destroying intersection op state done\n");
1057}
1058
1059
1060/**
1061 * Create a new set supporting the intersection operation.
1062 *
1063 * @return the newly created set
1064 */
1065static struct SetState *
1066intersection_set_create ()
1067{
1068 struct SetState *set_state;
1069
1070 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1071 "Intersection set created\n");
1072 set_state = GNUNET_new (struct SetState);
1073 set_state->current_set_element_count = 0;
1074
1075 return set_state;
1076}
1077
1078
1079/**
1080 * Add the element from the given element message to the set.
1081 *
1082 * @param set_state state of the set want to add to
1083 * @param ee the element to add to the set
1084 */
1085static void
1086intersection_add (struct SetState *set_state,
1087 struct ElementEntry *ee)
1088{
1089 set_state->current_set_element_count++;
1090}
1091
1092
1093/**
1094 * Destroy a set that supports the intersection operation
1095 *
1096 * @param set_state the set to destroy
1097 */
1098static void
1099intersection_set_destroy (struct SetState *set_state)
1100{
1101 GNUNET_free (set_state);
1102}
1103
1104
1105/**
1106 * Remove the element given in the element message from the set.
1107 *
1108 * @param set_state state of the set to remove from
1109 * @param element set element to remove
1110 */
1111static void
1112intersection_remove (struct SetState *set_state,
1113 struct ElementEntry *element)
1114{
1115 GNUNET_assert (0 < set_state->current_set_element_count);
1116 set_state->current_set_element_count--;
1079} 1117}
1080 1118
1081 1119
diff --git a/src/set/gnunet-service-set_protocol.h b/src/set/gnunet-service-set_protocol.h
index 73332b4c3..f02c61718 100644
--- a/src/set/gnunet-service-set_protocol.h
+++ b/src/set/gnunet-service-set_protocol.h
@@ -95,6 +95,29 @@ struct IBFMessage
95}; 95};
96 96
97 97
98/**
99 * During intersection, the first (and possibly second) message
100 * send it the number of elements in the set, to allow the peers
101 * to decide who should start with the Bloom filter.
102 */
103struct IntersectionElementInfoMessage
104{
105 /**
106 * Type: #GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO
107 */
108 struct GNUNET_MessageHeader header;
109
110 /**
111 * mutator used with this bloomfilter.
112 */
113 uint32_t sender_element_count GNUNET_PACKED;
114
115};
116
117
118/**
119 * Bloom filter messages exchanged for set intersection calculation.
120 */
98struct BFMessage 121struct BFMessage
99{ 122{
100 /** 123 /**
diff --git a/src/set/set.h b/src/set/set.h
index 944881b63..f688ccf72 100644
--- a/src/set/set.h
+++ b/src/set/set.h
@@ -188,6 +188,12 @@ struct GNUNET_SET_EvaluateMessage
188}; 188};
189 189
190 190
191/**
192 * Message sent by the service to the client to indicate an
193 * element that is removed (set intersection) or added
194 * (set union) or part of the final result, depending on
195 * options specified for the operation.
196 */
191struct GNUNET_SET_ResultMessage 197struct GNUNET_SET_ResultMessage
192{ 198{
193 /** 199 /**
@@ -207,8 +213,7 @@ struct GNUNET_SET_ResultMessage
207 uint16_t result_status GNUNET_PACKED; 213 uint16_t result_status GNUNET_PACKED;
208 214
209 /** 215 /**
210 * Type of the element attachted to the message, 216 * Type of the element attachted to the message, if any.
211 * if any.
212 */ 217 */
213 uint16_t element_type GNUNET_PACKED; 218 uint16_t element_type GNUNET_PACKED;
214 219