aboutsummaryrefslogtreecommitdiff
path: root/src/set
diff options
context:
space:
mode:
authorChristian Fuchs <christian.fuchs@cfuchs.net>2013-11-14 16:48:49 +0000
committerChristian Fuchs <christian.fuchs@cfuchs.net>2013-11-14 16:48:49 +0000
commit0d6e1036ad64d341651d113e3427323a157353d3 (patch)
treeccd6286eddbdb4ce055209d9c1557bc3802fb45c /src/set
parentd67a1f6613ec4feadc99026f027483aff03f8381 (diff)
downloadgnunet-0d6e1036ad64d341651d113e3427323a157353d3.tar.gz
gnunet-0d6e1036ad64d341651d113e3427323a157353d3.zip
added new msg type
more work on intersection
Diffstat (limited to 'src/set')
-rw-r--r--src/set/gnunet-service-set.c2
-rw-r--r--src/set/gnunet-service-set.h5
-rw-r--r--src/set/gnunet-service-set_intersection.c541
-rw-r--r--src/set/set_protocol.h17
4 files changed, 365 insertions, 200 deletions
diff --git a/src/set/gnunet-service-set.c b/src/set/gnunet-service-set.c
index d4c347d48..490a3e5ce 100644
--- a/src/set/gnunet-service-set.c
+++ b/src/set/gnunet-service-set.c
@@ -567,6 +567,7 @@ handle_incoming_msg (struct Operation *op,
567 spec->app_id = msg->app_id; 567 spec->app_id = msg->app_id;
568 spec->salt = ntohl (msg->salt); 568 spec->salt = ntohl (msg->salt);
569 spec->peer = op->state->peer; 569 spec->peer = op->state->peer;
570 spec->element_count = ntohl (msg->element_count);
570 571
571 op->spec = spec; 572 op->spec = spec;
572 573
@@ -1325,6 +1326,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1325 {dispatch_p2p_message, GNUNET_MESSAGE_TYPE_SET_P2P_DONE, 0}, 1326 {dispatch_p2p_message, GNUNET_MESSAGE_TYPE_SET_P2P_DONE, 0},
1326 {dispatch_p2p_message, GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENT_REQUESTS, 0}, 1327 {dispatch_p2p_message, GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENT_REQUESTS, 0},
1327 {dispatch_p2p_message, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE, 0}, 1328 {dispatch_p2p_message, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE, 0},
1329 {dispatch_p2p_message, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO, 0},
1328 {dispatch_p2p_message, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF, 0}, 1330 {dispatch_p2p_message, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF, 0},
1329 {NULL, 0, 0} 1331 {NULL, 0, 0}
1330 }; 1332 };
diff --git a/src/set/gnunet-service-set.h b/src/set/gnunet-service-set.h
index 62e8cbc87..af3aa7287 100644
--- a/src/set/gnunet-service-set.h
+++ b/src/set/gnunet-service-set.h
@@ -89,6 +89,11 @@ struct OperationSpecification
89 * Salt to use for the operation. 89 * Salt to use for the operation.
90 */ 90 */
91 uint32_t salt; 91 uint32_t salt;
92
93 /**
94 * Remote peers element count
95 */
96 uint32_t element_count;
92 97
93 /** 98 /**
94 * ID used to identify an operation between service and client 99 * ID used to identify an operation between service and client
diff --git a/src/set/gnunet-service-set_intersection.c b/src/set/gnunet-service-set_intersection.c
index de5198b9c..042d9fa33 100644
--- a/src/set/gnunet-service-set_intersection.c
+++ b/src/set/gnunet-service-set_intersection.c
@@ -36,14 +36,23 @@
36enum IntersectionOperationPhase 36enum IntersectionOperationPhase
37{ 37{
38 /** 38 /**
39 * We get our tunnel but received no message as of now 39 * Alices has suggested an operation to bob,
40 * and is waiting for a bf or session end.
40 */ 41 */
41 PHASE_EXPECT_INITIAL, 42 PHASE_INITIAL,
42 /** 43 /**
43 * We expect a BF + the number of the other peers elements 44 * Bob has accepted the operation, Bob and Alice are now exchanging bfs
45 * until one notices the their element count is equal
44 */ 46 */
45 PHASE_BF_EXCHANGE, 47 PHASE_BF_EXCHANGE,
46 /** 48 /**
49 * if both peers have an equal peercount, they enter this state for
50 * one more turn, to see if they actually have agreed on a correct set.
51 * if a peer finds the same element count after the next iteration,
52 * it ends the the session
53 */
54 PHASE_MAYBE_FINISHED,
55 /**
47 * The protocol is over. 56 * The protocol is over.
48 * Results may still have to be sent to the client. 57 * Results may still have to be sent to the client.
49 */ 58 */
@@ -81,12 +90,12 @@ struct OperationState
81 /** 90 /**
82 * Maps element-id-hashes to 'elements in our set'. 91 * Maps element-id-hashes to 'elements in our set'.
83 */ 92 */
84 struct GNUNET_CONTAINER_MultiHashMap *contained_elements; 93 struct GNUNET_CONTAINER_MultiHashMap *my_elements;
85 94
86 /** 95 /**
87 * Current element count contained within contained_elements 96 * Current element count contained within contained_elements
88 */ 97 */
89 uint32_t contained_elements_count; 98 uint32_t my_elements_count;
90 99
91 /** 100 /**
92 * Iterator for sending elements on the key to element mapping to the client. 101 * Iterator for sending elements on the key to element mapping to the client.
@@ -112,6 +121,175 @@ struct OperationState
112}; 121};
113 122
114 123
124/**
125 * Alice's version:
126 *
127 * fills the contained-elements hashmap with all relevant
128 * elements and adds their mutated hashes to our local bloomfilter with mutator+1
129 *
130 * @param cls closure
131 * @param key current key code
132 * @param value value in the hash map
133 * @return #GNUNET_YES if we should continue to
134 * iterate,
135 * #GNUNET_NO if not.
136 */
137static int
138iterator_initialization_alice (void *cls,
139 const struct GNUNET_HashCode *key,
140 void *value){
141 struct ElementEntry *ee = value;
142 struct Operation *op = cls;
143 struct GNUNET_HashCode mutated_hash;
144
145 //only consider this element, if it is valid for us
146 if ((op->generation_created >= ee->generation_removed)
147 || (op->generation_created < ee->generation_added))
148 return GNUNET_YES;
149
150 // not contained according to bob's bloomfilter
151 GNUNET_BLOCK_mingle_hash(&ee->element_hash, op->spec->salt, &mutated_hash);
152 if (GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (op->state->remote_bf,
153 &mutated_hash))
154 return GNUNET_YES;
155
156 op->state->my_elements_count++;
157 GNUNET_CONTAINER_multihashmap_put (op->state->my_elements,
158 &ee->element_hash, ee,
159 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
160
161 // create our own bloomfilter with salt+1
162 GNUNET_BLOCK_mingle_hash(&ee->element_hash, op->spec->salt+1, &mutated_hash);
163 GNUNET_CONTAINER_bloomfilter_add (op->state->local_bf,
164 &mutated_hash);
165
166 return GNUNET_YES;
167}
168
169/**
170 * Bob's version:
171 *
172 * fills the contained-elements hashmap with all relevant
173 * elements and adds their mutated hashes to our local bloomfilter
174 *
175 * @param cls closure
176 * @param key current key code
177 * @param value value in the hash map
178 * @return #GNUNET_YES if we should continue to
179 * iterate,
180 * #GNUNET_NO if not.
181 */
182static int
183iterator_initialization (void *cls,
184 const struct GNUNET_HashCode *key,
185 void *value){
186 struct ElementEntry *ee = value;
187 struct Operation *op = cls;
188 struct GNUNET_HashCode mutated_hash;
189
190 //only consider this element, if it is valid for us
191 if ((op->generation_created >= ee->generation_removed)
192 || (op->generation_created < ee->generation_added))
193 return GNUNET_YES;
194
195 GNUNET_CONTAINER_multihashmap_put (op->state->my_elements,
196 &ee->element_hash, ee,
197 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
198
199 GNUNET_BLOCK_mingle_hash(&ee->element_hash, op->spec->salt, &mutated_hash);
200
201 GNUNET_CONTAINER_bloomfilter_add (op->state->local_bf,
202 &mutated_hash);
203
204 return GNUNET_YES;
205}
206
207/**
208 * Counts all valid elements in the hashmap
209 * (the ones that are valid in our generation)
210 *
211 * @param cls closure
212 * @param key current key code
213 * @param value value in the hash map
214 * @return #GNUNET_YES if we should continue to
215 * iterate,
216 * #GNUNET_NO if not.
217 */
218static int
219iterator_element_count (void *cls,
220 const struct GNUNET_HashCode *key,
221 void *value){
222 struct ElementEntry *ee = value;
223 struct Operation *op = cls;
224
225 //only consider this element, if it is valid for us
226 if ((op->generation_created >= ee->generation_removed)
227 || (op->generation_created < ee->generation_added))
228 return GNUNET_YES;
229
230 op->state->my_elements_count++;
231
232 return GNUNET_YES;
233}
234
235/**
236 * removes element from a hashmap if it is not contained within the
237 * provided remote bloomfilter.
238 *
239 * @param cls closure
240 * @param key current key code
241 * @param value value in the hash map
242 * @return #GNUNET_YES if we should continue to
243 * iterate,
244 * #GNUNET_NO if not.
245 */
246static int
247iterator_element_removal (void *cls,
248 const struct GNUNET_HashCode *key,
249 void *value){
250 struct ElementEntry *ee = value;
251 struct Operation *op = cls;
252 struct GNUNET_HashCode mutated_hash;
253
254 GNUNET_BLOCK_mingle_hash(&ee->element_hash, op->spec->salt, &mutated_hash);
255
256 if (GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (op->state->remote_bf,
257 &mutated_hash)){
258 op->state->my_elements_count--;
259 GNUNET_CONTAINER_multihashmap_remove (op->state->my_elements,
260 &ee->element_hash,
261 ee);
262 }
263
264 return GNUNET_YES;
265}
266
267/**
268 * removes element from a hashmap if it is not contained within the
269 * provided remote bloomfilter.
270 *
271 * @param cls closure
272 * @param key current key code
273 * @param value value in the hash map
274 * @return #GNUNET_YES if we should continue to
275 * iterate,
276 * #GNUNET_NO if not.
277 */
278static int
279iterator_create_bf (void *cls,
280 const struct GNUNET_HashCode *key,
281 void *value){
282 struct ElementEntry *ee = value;
283 struct Operation *op = cls;
284 struct GNUNET_HashCode mutated_hash;
285
286 GNUNET_BLOCK_mingle_hash(&ee->element_hash, op->spec->salt, &mutated_hash);
287
288 GNUNET_CONTAINER_bloomfilter_add (op->state->local_bf,
289 &mutated_hash);
290
291 return GNUNET_YES;
292}
115 293
116/** 294/**
117 * Destroy a intersection operation, and free all resources 295 * Destroy a intersection operation, and free all resources
@@ -201,6 +379,8 @@ send_operation_request (struct Operation *op)
201 msg->operation = htonl (GNUNET_SET_OPERATION_INTERSECTION); 379 msg->operation = htonl (GNUNET_SET_OPERATION_INTERSECTION);
202 msg->app_id = op->spec->app_id; 380 msg->app_id = op->spec->app_id;
203 msg->salt = htonl (op->spec->salt); 381 msg->salt = htonl (op->spec->salt);
382 msg->element_count = htonl(op->state->my_elements);
383
204 GNUNET_MQ_send (op->mq, ev); 384 GNUNET_MQ_send (op->mq, ev);
205 385
206 if (NULL != op->spec->context_msg) 386 if (NULL != op->spec->context_msg)
@@ -226,19 +406,40 @@ send_operation_request (struct Operation *op)
226static void 406static void
227handle_p2p_bf (void *cls, const struct GNUNET_MessageHeader *mh) 407handle_p2p_bf (void *cls, const struct GNUNET_MessageHeader *mh)
228{ 408{
229 struct OperationState *eo = cls; 409 struct Operation *op = cls;
230 struct BFMessage *msg = (struct BFMessage *) mh; 410 struct BFMessage *msg = (struct BFMessage *) mh;
231 unsigned int buckets_in_message;
232 411
233 if (eo->phase == PHASE_EXPECT_INITIAL ) 412 switch (op->state->phase){
234 { 413 case PHASE_INITIAL:
235 eo->phase = PHASE_BF_EXCHANGE; 414 op->state->phase = PHASE_BF_EXCHANGE;
415 op->state->my_elements = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
416
417 op->spec->salt = ntohl(msg->sender_mutator);
418 op->state->remote_bf = GNUNET_CONTAINER_bloomfilter_init (&msg[1],
419 GNUNET_CRYPTO_HASH_LENGTH,
420 ntohl(msg->bloomfilter_length));
421 op->state->local_bf = GNUNET_CONTAINER_bloomfilter_init (NULL,
422 GNUNET_CRYPTO_HASH_LENGTH,
423 GNUNET_CONSTANTS_BLOOMFILTER_K);
424 GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->elements,
425 &iterator_initialization_alice,
426 op);
427 // iterator_initialization_alice created a new BF with salt+1
428 // bob needs this information for decoding the next BF
429 // this behavior can be modified at will later on.
430 op->spec->salt++;
431
432 GNUNET_CONTAINER_bloomfilter_free(op->state->remote_bf);
433 op->state->remote_bf = NULL;
434
435 if (op->state->my_elements_count == ntohl(msg->sender_element_count))
436 op->state->phase = PHASE_MAYBE_FINISHED;
437
438 send_bloomfilter (op);
236 439
237 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "creating new bf of size %u\n", 1<<msg->order);
238
239 // if (the remote peer has less elements than us) 440 // if (the remote peer has less elements than us)
240 // run our elements through his bloomfilter 441 // run our elements through his bloomfilter
241 // else if (we have the same elements) 442 // if (we have the same elements)
242 // done; 443 // done;
243 // 444 //
244 // evict elements we can exclude through the bloomfilter 445 // evict elements we can exclude through the bloomfilter
@@ -246,12 +447,59 @@ handle_p2p_bf (void *cls, const struct GNUNET_MessageHeader *mh)
246 // create a new bloomfilter over our remaining elements 447 // create a new bloomfilter over our remaining elements
247 // 448 //
248 // send our new count and the bloomfilter back 449 // send our new count and the bloomfilter back
450 case PHASE_BF_EXCHANGE:
451 break;
452 default:
453 GNUNET_break_op(0);
249 } 454 }
250 else if (eo->phase == PHASE_BF_EXCHANGE) 455}
251 { 456
252 457
458/**
459 * Handle an BF message from a remote peer.
460 *
461 * @param cls the intersection operation
462 * @param mh the header of the message
463 */
464static void
465handle_p2p_element_info (void *cls, const struct GNUNET_MessageHeader *mh)
466{
467 struct Operation *op = cls;
468 struct BFMessage *msg = (struct BFMessage *) mh;
469 uint32_t remote_element_count;
470
471 remote_element_count = ntohl(msg->sender_element_count);
472 if (op->state->phase == PHASE_INITIAL
473 || op->state->my_elements_count > remote_element_count){
474 GNUNET_break_op (0);
475 fail_intersection_operation(op);
253 } 476 }
254 477
478 op->state->phase = PHASE_BF_EXCHANGE;
479 op->state->my_elements = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
480
481 op->spec->salt = ntohl (msg->sender_mutator);
482 op->state->remote_bf = GNUNET_CONTAINER_bloomfilter_init (&msg[1],
483 GNUNET_CRYPTO_HASH_LENGTH,
484 ntohl (msg->bloomfilter_length));
485 op->state->local_bf = GNUNET_CONTAINER_bloomfilter_init (NULL,
486 GNUNET_CRYPTO_HASH_LENGTH,
487 GNUNET_CONSTANTS_BLOOMFILTER_K);
488 GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->elements,
489 &iterator_initialization_alice,
490 op);
491 // iterator_initialization_alice created a new BF with salt+1
492 // bob needs this information for decoding the next BF
493 // this behavior can be modified at will later on.
494 op->spec->salt++;
495
496 GNUNET_CONTAINER_bloomfilter_free (op->state->remote_bf);
497 op->state->remote_bf = NULL;
498
499 if (op->state->my_elements_count == ntohl (msg->sender_element_count))
500 op->state->phase = PHASE_MAYBE_FINISHED;
501
502 send_bloomfilter (op);
255} 503}
256 504
257 505
@@ -313,7 +561,6 @@ send_client_done_and_destroy (struct OperationState *eo)
313 intersection_operation_destroy (eo); 561 intersection_operation_destroy (eo);
314} 562}
315 563
316
317/** 564/**
318 * Send a bloomfilter to our peer. 565 * Send a bloomfilter to our peer.
319 * that the operation is over. 566 * that the operation is over.
@@ -328,24 +575,49 @@ send_bloomfilter (struct Operation *op)
328 struct BloomFilter *bf; 575 struct BloomFilter *bf;
329 struct GNUNET_MQ_Envelope *ev; 576 struct GNUNET_MQ_Envelope *ev;
330 struct BFMessage *msg; 577 struct BFMessage *msg;
331 578 uint32_t bf_size;
332 579
333 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sending bf of size %u\n", ); 580 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sending bf of size %u\n",);
334 581
335 ev = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF); 582 // send our bloomfilter
583 bf_size = GNUNET_CONTAINER_bloomfilter_get_size (op->state->local_bf);
584
585 ev = GNUNET_MQ_msg_extra (msg, bf_size, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF);
336 msg->reserved = 0; 586 msg->reserved = 0;
587 msg->sender_element_count = htonl (op->state->my_elements_count);
588 msg->bloomfilter_length = htonl (bf_size);
337 msg->sender_mutator = htonl (op->spec->salt); 589 msg->sender_mutator = htonl (op->spec->salt);
338 msg->sender_element_count = htonl (op->state->contained_elements_count); 590 GNUNET_assert (GNUNET_SYSERR !=
339 GNUNET_assert(GNUNET_SYSERR != GNUNET_CONTAINER_bloomfilter_get_raw_data( 591 GNUNET_CONTAINER_bloomfilter_get_raw_data (op->state->local_bf,
340 op->state->local_bf, 592 &msg->sender_bf_data,
341 &msg->bf_data, 593 GNUNET_CRYPTO_HASH_LENGTH));
342 GNUNET_CRYPTO_HASH_LENGTH));
343
344 GNUNET_MQ_send (op->mq, ev); 594 GNUNET_MQ_send (op->mq, ev);
595}
345 596
346 op->state->phase = PHASE_BF_EXCHANGE; 597/**
598 * Send our element to the peer, in case our element count is lower than his
599 *
600 * @param eo intersection operation
601 */
602static void
603send_element_count (struct Operation *op)
604{
605 struct GNUNET_MQ_Envelope *ev;
606 struct BFMessage *msg;
607
608 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sending element count (bf_msg)\n");
609
610 // just send our element count, as the other peer must start
611 ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO);
612 msg->reserved = 0;
613 msg->sender_element_count = htonl (op->state->my_elements_count);
614 msg->bloomfilter_length = htonl (0);
615 msg->sender_mutator = htonl (0);
616
617 GNUNET_MQ_send (op->mq, ev);
347} 618}
348 619
620
349/** 621/**
350 * Handle a done message from a remote peer 622 * Handle a done message from a remote peer
351 * 623 *
@@ -391,157 +663,16 @@ intersection_evaluate (struct Operation *op)
391{ 663{
392 op->state = GNUNET_new (struct OperationState); 664 op->state = GNUNET_new (struct OperationState);
393 /* we started the operation, thus we have to send the operation request */ 665 /* we started the operation, thus we have to send the operation request */
394 op->state->phase = PHASE_BF_EXCHANGE; 666 op->state->phase = PHASE_INITIAL;
667 op->state->my_elements = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_YES);
668 GNUNET_CONTAINER_multihashmap_iterate(op->spec->set->elements,
669 &iterator_element_count,
670 op);
671
395 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "evaluating intersection operation"); 672 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "evaluating intersection operation");
396 send_operation_request (op); 673 send_operation_request (op);
397} 674}
398 675
399
400/**
401 * Alice's version:
402 *
403 * fills the contained-elements hashmap with all relevant
404 * elements and adds their mutated hashes to our local bloomfilter with mutator+1
405 *
406 * @param cls closure
407 * @param key current key code
408 * @param value value in the hash map
409 * @return #GNUNET_YES if we should continue to
410 * iterate,
411 * #GNUNET_NO if not.
412 */
413static int
414intersection_iterator_set_to_contained_alice (void *cls,
415 const struct GNUNET_HashCode *key,
416 void *value){
417 struct ElementEntry *ee = value;
418 struct Operation *op = cls;
419 struct GNUNET_HashCode mutated_hash;
420
421 //only consider this element, if it is valid for us
422 if ((op->generation_created >= ee->generation_removed)
423 || (op->generation_created < ee->generation_added))
424 return GNUNET_YES;
425
426 // not contained according to bob's bloomfilter
427 GNUNET_BLOCK_mingle_hash(&ee->element_hash, op->spec->salt, &mutated_hash);
428 if (GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (op->state->remote_bf,
429 &mutated_hash))
430 return GNUNET_YES;
431
432 op->state->contained_elements_count++;
433 GNUNET_CONTAINER_multihashmap_put (op->state->contained_elements,
434 &ee->element_hash, ee,
435 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
436
437 // create our own bloomfilter with salt+1
438 GNUNET_BLOCK_mingle_hash(&ee->element_hash, op->spec->salt+1, &mutated_hash);
439 GNUNET_CONTAINER_bloomfilter_add (op->state->local_bf,
440 &mutated_hash);
441
442 return GNUNET_YES;
443}
444
445/**
446 * Bob's version:
447 *
448 * fills the contained-elements hashmap with all relevant
449 * elements and adds their mutated hashes to our local bloomfilter
450 *
451 * @param cls closure
452 * @param key current key code
453 * @param value value in the hash map
454 * @return #GNUNET_YES if we should continue to
455 * iterate,
456 * #GNUNET_NO if not.
457 */
458static int
459intersection_iterator_set_to_contained_bob (void *cls,
460 const struct GNUNET_HashCode *key,
461 void *value){
462 struct ElementEntry *ee = value;
463 struct Operation *op = cls;
464 struct GNUNET_HashCode mutated_hash;
465
466 //only consider this element, if it is valid for us
467 if ((op->generation_created >= ee->generation_removed)
468 || (op->generation_created < ee->generation_added))
469 return GNUNET_YES;
470
471 GNUNET_CONTAINER_multihashmap_put (op->state->contained_elements,
472 &ee->element_hash, ee,
473 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
474
475 op->state->contained_elements_count++;
476
477 GNUNET_BLOCK_mingle_hash(&ee->element_hash, op->spec->salt, &mutated_hash);
478
479 GNUNET_CONTAINER_bloomfilter_add (op->state->local_bf,
480 &mutated_hash);
481
482 return GNUNET_YES;
483}
484
485/**
486 * removes element from a hashmap if it is not contained within the
487 * provided remote bloomfilter.
488 *
489 * @param cls closure
490 * @param key current key code
491 * @param value value in the hash map
492 * @return #GNUNET_YES if we should continue to
493 * iterate,
494 * #GNUNET_NO if not.
495 */
496static int
497intersection_iterator_element_removal (void *cls,
498 const struct GNUNET_HashCode *key,
499 void *value){
500 struct ElementEntry *ee = value;
501 struct Operation *op = cls;
502 struct GNUNET_HashCode mutated_hash;
503
504 GNUNET_BLOCK_mingle_hash(&ee->element_hash, op->spec->salt, &mutated_hash);
505
506 if (GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (op->state->remote_bf,
507 &mutated_hash)){
508 op->state->contained_elements_count--;
509 GNUNET_CONTAINER_multihashmap_remove (op->state->contained_elements,
510 &ee->element_hash,
511 ee);
512 }
513
514 return GNUNET_YES;
515}
516
517/**
518 * removes element from a hashmap if it is not contained within the
519 * provided remote bloomfilter.
520 *
521 * @param cls closure
522 * @param key current key code
523 * @param value value in the hash map
524 * @return #GNUNET_YES if we should continue to
525 * iterate,
526 * #GNUNET_NO if not.
527 */
528static int
529intersection_iterator_create_bf (void *cls,
530 const struct GNUNET_HashCode *key,
531 void *value){
532 struct ElementEntry *ee = value;
533 struct Operation *op = cls;
534 struct GNUNET_HashCode mutated_hash;
535
536 GNUNET_BLOCK_mingle_hash(&ee->element_hash, op->spec->salt, &mutated_hash);
537
538 GNUNET_CONTAINER_bloomfilter_add (op->state->local_bf,
539 &mutated_hash);
540
541 return GNUNET_YES;
542}
543
544
545/** 676/**
546 * Accept an union operation request from a remote peer. 677 * Accept an union operation request from a remote peer.
547 * Only initializes the private operation state. 678 * Only initializes the private operation state.
@@ -551,18 +682,33 @@ intersection_iterator_create_bf (void *cls,
551static void 682static void
552intersection_accept (struct Operation *op) 683intersection_accept (struct Operation *op)
553{ 684{
685 struct OperationRequestMessage * context = 1;
554 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "accepting set union operation\n"); 686 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "accepting set union operation\n");
555 op->state = GNUNET_new (struct OperationState);
556 687
557 op->state->contained_elements = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_YES); 688 op->state = GNUNET_new (struct OperationState);
558 op->state-> = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_YES); 689 op->state->my_elements = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_YES);
559
560 op->state->local_bf = GNUNET_CONTAINER_bloomfilter_init(NULL, , GNUNET_CONSTANTS_BLOOMFILTER_K);
561 690
562 GNUNET_CONTAINER_multihashmap_iterate(op->spec->set->elements, 691 GNUNET_CONTAINER_multihashmap_iterate(op->spec->set->elements,
563 &intersection_iterator_set_to_contained_bob, 692 &iterator_element_count,
564 op); 693 op);
565 /* kick off the operation */ 694
695 // if we have more elements than our peer, he should start
696 if (op->spec->element_count < op->state->my_elements_count){
697 op->state->phase = PHASE_INITIAL;
698 send_element_count(op);
699 return;
700 }
701
702 // create a new bloomfilter in case we have fewer elements
703 op->state->phase = PHASE_BF_EXCHANGE;
704 op->state->local_bf = GNUNET_CONTAINER_bloomfilter_init (NULL,
705 GNUNET_CRYPTO_HASH_LENGTH,
706 GNUNET_CONSTANTS_BLOOMFILTER_K);
707
708 GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->elements,
709 &iterator_initialization,
710 op);
711
566 send_bloomfilter (op); 712 send_bloomfilter (op);
567} 713}
568 714
@@ -632,8 +778,8 @@ intersection_remove (struct SetState *set_state, struct ElementEntry *element)
632 * GNUNET_OK otherwise 778 * GNUNET_OK otherwise
633 */ 779 */
634int 780int
635intersection_handle_p2p_message (struct OperationState *eo, 781intersection_handle_p2p_message (struct Operation *op,
636 const struct GNUNET_MessageHeader *mh) 782 const struct GNUNET_MessageHeader *mh)
637{ 783{
638 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "received p2p message (t: %u, s: %u)\n", 784 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "received p2p message (t: %u, s: %u)\n",
639 ntohs (mh->type), ntohs (mh->size)); 785 ntohs (mh->type), ntohs (mh->size));
@@ -642,15 +788,18 @@ intersection_handle_p2p_message (struct OperationState *eo,
642 /* this message handler is not active until after we received an 788 /* this message handler is not active until after we received an
643 * operation request message, thus the ops request is not handled here 789 * operation request message, thus the ops request is not handled here
644 */ 790 */
645 case GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF: 791 case GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO:
646 handle_p2p_bf (eo, mh); 792 handle_p2p_element_info (op, mh);
647 break; 793 break;
648 case GNUNET_MESSAGE_TYPE_SET_P2P_DONE: 794 case GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF:
649 handle_p2p_done (eo, mh); 795 handle_p2p_bf (op, mh);
650 break; 796 break;
651 default: 797 case GNUNET_MESSAGE_TYPE_SET_P2P_DONE:
652 /* something wrong with mesh's message handlers? */ 798 handle_p2p_done (op, mh);
653 GNUNET_assert (0); 799 break;
800 default:
801 /* something wrong with mesh's message handlers? */
802 GNUNET_assert (0);
654 } 803 }
655 return GNUNET_OK; 804 return GNUNET_OK;
656} 805}
@@ -693,7 +842,7 @@ finish_and_destroy (struct Operation *op)
693 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sending full result set\n"); 842 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sending full result set\n");
694 GNUNET_assert (NULL == op->state->full_result_iter); 843 GNUNET_assert (NULL == op->state->full_result_iter);
695 op->state->full_result_iter = 844 op->state->full_result_iter =
696 GNUNET_CONTAINER_multihashmap32_iterator_create (op->state->contained_elements); 845 GNUNET_CONTAINER_multihashmap32_iterator_create (op->state->my_elements);
697 return; 846 return;
698 } 847 }
699 send_done_and_destroy (op); 848 send_done_and_destroy (op);
@@ -748,11 +897,11 @@ intersection_op_cancel (struct Operation *op)
748 GNUNET_CONTAINER_bloomfilter_free (op->state->local_bf); 897 GNUNET_CONTAINER_bloomfilter_free (op->state->local_bf);
749 op->state->local_bf = NULL; 898 op->state->local_bf = NULL;
750 } 899 }
751 if (NULL != op->state->contained_elements) 900 if (NULL != op->state->my_elements)
752 { 901 {
753 // no need to free the elements, they are still part of the set 902 // no need to free the elements, they are still part of the set
754 GNUNET_CONTAINER_multihashmap_destroy (op->state->contained_elements); 903 GNUNET_CONTAINER_multihashmap_destroy (op->state->my_elements);
755 op->state->contained_elements = NULL; 904 op->state->my_elements = NULL;
756 } 905 }
757 GNUNET_free (op->state); 906 GNUNET_free (op->state);
758 op->state = NULL; 907 op->state = NULL;
diff --git a/src/set/set_protocol.h b/src/set/set_protocol.h
index 4741eb5c2..d37551d2e 100644
--- a/src/set/set_protocol.h
+++ b/src/set/set_protocol.h
@@ -50,6 +50,11 @@ struct OperationRequestMessage
50 uint32_t salt; 50 uint32_t salt;
51 51
52 /** 52 /**
53 * For Intersection: my element count
54 */
55 uint32_t element_count;
56
57 /**
53 * Application-specific identifier of the request. 58 * Application-specific identifier of the request.
54 */ 59 */
55 struct GNUNET_HashCode app_id; 60 struct GNUNET_HashCode app_id;
@@ -103,17 +108,21 @@ struct BFMessage
103 /** 108 /**
104 * mutator used with this bloomfilter. 109 * mutator used with this bloomfilter.
105 */ 110 */
106 uint64_t sender_element_count; 111 uint32_t sender_element_count GNUNET_PACKED;
107 112
108 /** 113 /**
109 * mutator used with this bloomfilter. 114 * mutator used with this bloomfilter.
110 */ 115 */
111 uint32_t sender_mutator; 116 uint32_t sender_mutator GNUNET_PACKED;
112 117
113 /** 118 /**
114 * the sender's bloomfilter 119 * Length of the bloomfilter data block
120 */
121 uint32_t bloomfilter_length GNUNET_PACKED;
122
123 /**
124 * rest: the sender's bloomfilter
115 */ 125 */
116 char sender_bf_data[GNUNET_CRYPTO_HASH_LENGTH];
117}; 126};
118 127
119GNUNET_NETWORK_STRUCT_END 128GNUNET_NETWORK_STRUCT_END