aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-08-19 00:06:35 +0200
committerChristian Grothoff <christian@grothoff.org>2020-08-19 00:06:35 +0200
commit9cbc1f9c76ae5de5bcfdc15f935cd04200c0e013 (patch)
tree207016a705c730d28b7ef0da4ed70bc1c6178e3d
parent3fb3bf908f4977aef6bde6a450954e2704b14bcb (diff)
downloadgnunet-9cbc1f9c76ae5de5bcfdc15f935cd04200c0e013.tar.gz
gnunet-9cbc1f9c76ae5de5bcfdc15f935cd04200c0e013.zip
-fix FTBFS for seti
-rw-r--r--src/include/gnunet_protocols.h5
-rw-r--r--src/seti/gnunet-service-seti.c1204
2 files changed, 472 insertions, 737 deletions
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index e9a2b1c0e..4526b75d9 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -1854,6 +1854,11 @@ extern "C" {
1854 */ 1854 */
1855#define GNUNET_MESSAGE_TYPE_SETI_P2P_DONE 593 1855#define GNUNET_MESSAGE_TYPE_SETI_P2P_DONE 593
1856 1856
1857/**
1858 * Request to begin set intersection operation.
1859 */
1860#define GNUNET_MESSAGE_TYPE_SETI_P2P_OPERATION_REQUEST 594
1861
1857 1862
1858/******************************************************************************* 1863/*******************************************************************************
1859 * SET message types 1864 * SET message types
diff --git a/src/seti/gnunet-service-seti.c b/src/seti/gnunet-service-seti.c
index 037181bde..7159a7ba2 100644
--- a/src/seti/gnunet-service-seti.c
+++ b/src/seti/gnunet-service-seti.c
@@ -25,6 +25,10 @@
25 */ 25 */
26#include "gnunet-service-seti_protocol.h" 26#include "gnunet-service-seti_protocol.h"
27#include "gnunet_statistics_service.h" 27#include "gnunet_statistics_service.h"
28#include "gnunet_cadet_service.h"
29#include "gnunet_seti_service.h"
30#include "gnunet_block_lib.h"
31#include "seti.h"
28 32
29/** 33/**
30 * How long do we hold on to an incoming channel if there is 34 * How long do we hold on to an incoming channel if there is
@@ -77,18 +81,6 @@ enum IntersectionOperationPhase
77 81
78 82
79/** 83/**
80 * Implementation-specific set state. Used as opaque pointer, and
81 * specified further in the respective implementation.
82 */
83struct SetState;
84
85/**
86 * Implementation-specific set operation. Used as opaque pointer, and
87 * specified further in the respective implementation.
88 */
89struct OperationState;
90
91/**
92 * A set that supports a specific operation with other peers. 84 * A set that supports a specific operation with other peers.
93 */ 85 */
94struct Set; 86struct Set;
@@ -119,7 +111,7 @@ struct ElementEntry
119 * The actual element. The data for the element 111 * The actual element. The data for the element
120 * should be allocated at the end of this struct. 112 * should be allocated at the end of this struct.
121 */ 113 */
122 struct GNUNET_SET_Element element; 114 struct GNUNET_SETI_Element element;
123 115
124 /** 116 /**
125 * Hash of the element. For set union: Will be used to derive the 117 * Hash of the element. For set union: Will be used to derive the
@@ -180,6 +172,26 @@ struct ClientState
180struct Operation 172struct Operation
181{ 173{
182 /** 174 /**
175 * The identity of the requesting peer. Needs to
176 * be stored here as the op spec might not have been created yet.
177 */
178 struct GNUNET_PeerIdentity peer;
179
180 /**
181 * XOR of the keys of all of the elements (remaining) in my set.
182 * Always updated when elements are added or removed to
183 * @e my_elements.
184 */
185 struct GNUNET_HashCode my_xor;
186
187 /**
188 * XOR of the keys of all of the elements (remaining) in
189 * the other peer's set. Updated when we receive the
190 * other peer's Bloom filter.
191 */
192 struct GNUNET_HashCode other_xor;
193
194 /**
183 * Kept in a DLL of the listener, if @e listener is non-NULL. 195 * Kept in a DLL of the listener, if @e listener is non-NULL.
184 */ 196 */
185 struct Operation *next; 197 struct Operation *next;
@@ -216,17 +228,31 @@ struct Operation
216 struct Set *set; 228 struct Set *set;
217 229
218 /** 230 /**
219 * Operation-specific operation state. Note that the exact 231 * The bf we currently receive
220 * type depends on this being a union or intersection operation
221 * (and thus on @e vt).
222 */ 232 */
223 struct OperationState *state; // FIXME: inline 233 struct GNUNET_CONTAINER_BloomFilter *remote_bf;
224 234
225 /** 235 /**
226 * The identity of the requesting peer. Needs to 236 * BF of the set's element.
227 * be stored here as the op spec might not have been created yet.
228 */ 237 */
229 struct GNUNET_PeerIdentity peer; 238 struct GNUNET_CONTAINER_BloomFilter *local_bf;
239
240 /**
241 * Remaining elements in the intersection operation.
242 * Maps element-id-hashes to 'elements in our set'.
243 */
244 struct GNUNET_CONTAINER_MultiHashMap *my_elements;
245
246 /**
247 * Iterator for sending the final set of @e my_elements to the client.
248 */
249 struct GNUNET_CONTAINER_MultiHashMapIterator *full_result_iter;
250
251 /**
252 * For multipart BF transmissions, we have to store the
253 * bloomfilter-data until we fully received it.
254 */
255 char *bf_data;
230 256
231 /** 257 /**
232 * Timeout task, if the incoming peer has not been accepted 258 * Timeout task, if the incoming peer has not been accepted
@@ -235,48 +261,68 @@ struct Operation
235 struct GNUNET_SCHEDULER_Task *timeout_task; 261 struct GNUNET_SCHEDULER_Task *timeout_task;
236 262
237 /** 263 /**
238 * Salt to use for the operation. 264 * How many bytes of @e bf_data are valid?
265 */
266 uint32_t bf_data_offset;
267
268 /**
269 * Current element count contained within @e my_elements.
270 * (May differ briefly during initialization.)
271 */
272 uint32_t my_element_count;
273
274 /**
275 * size of the bloomfilter in @e bf_data.
276 */
277 uint32_t bf_data_size;
278
279 /**
280 * size of the bloomfilter
281 */
282 uint32_t bf_bits_per_element;
283
284 /**
285 * Salt currently used for BF construction (by us or the other peer,
286 * depending on where we are in the code).
239 */ 287 */
240 uint32_t salt; 288 uint32_t salt;
241 289
242 /** 290 /**
243 * Remote peers element count 291 * Current state of the operation.
244 */ 292 */
245 uint32_t remote_element_count; 293 enum IntersectionOperationPhase phase;
246 294
247 /** 295 /**
248 * ID used to identify an operation between service and client 296 * Generation in which the operation handle was created.
249 */ 297 */
250 uint32_t client_request_id; 298 unsigned int generation_created;
251 299
252 /** 300 /**
253 * When are elements sent to the client, and which elements are sent? 301 * Did we send the client that we are done?
254 */ 302 */
255 int return_intersection; 303 int client_done_sent;
256 304
257 /** 305 /**
258 * Lower bound for the set size, used only when 306 * Set whenever we reach the state where the death of the
259 * byzantine mode is enabled. 307 * channel is perfectly find and should NOT result in the
308 * operation being cancelled.
260 */ 309 */
261 int byzantine_lower_bound; 310 int channel_death_expected;
262 311
263 /** 312 /**
264 * Always use delta operation instead of sending full sets, 313 * Remote peers element count
265 * even it it's less efficient.
266 */ 314 */
267 int force_delta; 315 uint32_t remote_element_count;
268 316
269 /** 317 /**
270 * Always send full sets, even if delta operations would 318 * ID used to identify an operation between service and client
271 * be more efficient.
272 */ 319 */
273 int force_full; 320 uint32_t client_request_id;
274 321
275 /** 322 /**
276 * #GNUNET_YES to fail operations where Byzantine faults 323 * When are elements sent to the client, and which elements are sent?
277 * are suspected
278 */ 324 */
279 int byzantine; 325 int return_intersection;
280 326
281 /** 327 /**
282 * Unique request id for the request from a remote peer, sent to the 328 * Unique request id for the request from a remote peer, sent to the
@@ -285,10 +331,6 @@ struct Operation
285 */ 331 */
286 uint32_t suggest_id; 332 uint32_t suggest_id;
287 333
288 /**
289 * Generation in which the operation handle was created.
290 */
291 unsigned int generation_created;
292}; 334};
293 335
294 336
@@ -348,9 +390,10 @@ struct Set
348 struct SetContent *content; 390 struct SetContent *content;
349 391
350 /** 392 /**
351 * Implementation-specific state. 393 * Number of currently valid elements in the set which have not been
394 * removed.
352 */ 395 */
353 struct SetState *state; 396 uint32_t current_set_element_count;
354 397
355 /** 398 /**
356 * Evaluate operations are held in a linked list. 399 * Evaluate operations are held in a linked list.
@@ -372,128 +415,6 @@ struct Set
372 415
373 416
374/** 417/**
375 * State of an evaluate operation with another peer.
376 */
377struct OperationState
378{
379 /**
380 * The bf we currently receive
381 */
382 struct GNUNET_CONTAINER_BloomFilter *remote_bf;
383
384 /**
385 * BF of the set's element.
386 */
387 struct GNUNET_CONTAINER_BloomFilter *local_bf;
388
389 /**
390 * Remaining elements in the intersection operation.
391 * Maps element-id-hashes to 'elements in our set'.
392 */
393 struct GNUNET_CONTAINER_MultiHashMap *my_elements;
394
395 /**
396 * Iterator for sending the final set of @e my_elements to the client.
397 */
398 struct GNUNET_CONTAINER_MultiHashMapIterator *full_result_iter;
399
400 /**
401 * Evaluate operations are held in a linked list.
402 */
403 struct OperationState *next;
404
405 /**
406 * Evaluate operations are held in a linked list.
407 */
408 struct OperationState *prev;
409
410 /**
411 * For multipart BF transmissions, we have to store the
412 * bloomfilter-data until we fully received it.
413 */
414 char *bf_data;
415
416 /**
417 * XOR of the keys of all of the elements (remaining) in my set.
418 * Always updated when elements are added or removed to
419 * @e my_elements.
420 */
421 struct GNUNET_HashCode my_xor;
422
423 /**
424 * XOR of the keys of all of the elements (remaining) in
425 * the other peer's set. Updated when we receive the
426 * other peer's Bloom filter.
427 */
428 struct GNUNET_HashCode other_xor;
429
430 /**
431 * How many bytes of @e bf_data are valid?
432 */
433 uint32_t bf_data_offset;
434
435 /**
436 * Current element count contained within @e my_elements.
437 * (May differ briefly during initialization.)
438 */
439 uint32_t my_element_count;
440
441 /**
442 * size of the bloomfilter in @e bf_data.
443 */
444 uint32_t bf_data_size;
445
446 /**
447 * size of the bloomfilter
448 */
449 uint32_t bf_bits_per_element;
450
451 /**
452 * Salt currently used for BF construction (by us or the other peer,
453 * depending on where we are in the code).
454 */
455 uint32_t salt;
456
457 /**
458 * Current state of the operation.
459 */
460 enum IntersectionOperationPhase phase;
461
462 /**
463 * Generation in which the operation handle
464 * was created.
465 */
466 unsigned int generation_created;
467
468 /**
469 * Did we send the client that we are done?
470 */
471 int client_done_sent;
472
473 /**
474 * Set whenever we reach the state where the death of the
475 * channel is perfectly find and should NOT result in the
476 * operation being cancelled.
477 */
478 int channel_death_expected;
479};
480
481
482/**
483 * Extra state required for efficient set intersection.
484 * Merely tracks the total number of elements.
485 */
486struct SetState
487{
488 /**
489 * Number of currently valid elements in the set which have not been
490 * removed.
491 */
492 uint32_t current_set_element_count;
493};
494
495
496/**
497 * A listener is inhabited by a client, and waits for evaluation 418 * A listener is inhabited by a client, and waits for evaluation
498 * requests from remote peers. 419 * requests from remote peers.
499 */ 420 */
@@ -540,10 +461,6 @@ struct Listener
540 */ 461 */
541 struct GNUNET_HashCode app_id; 462 struct GNUNET_HashCode app_id;
542 463
543 /**
544 * The type of the operation.
545 */
546 enum GNUNET_SET_OperationType operation;
547}; 464};
548 465
549 466
@@ -597,10 +514,10 @@ static uint32_t suggest_id;
597 */ 514 */
598static void 515static void
599send_client_removed_element (struct Operation *op, 516send_client_removed_element (struct Operation *op,
600 struct GNUNET_SET_Element *element) 517 struct GNUNET_SETI_Element *element)
601{ 518{
602 struct GNUNET_MQ_Envelope *ev; 519 struct GNUNET_MQ_Envelope *ev;
603 struct GNUNET_SET_ResultMessage *rm; 520 struct GNUNET_SETI_ResultMessage *rm;
604 521
605 if (GNUNET_NO != op->return_intersection) 522 if (GNUNET_NO != op->return_intersection)
606 return; /* Wrong mode for transmitting removed elements */ 523 return; /* Wrong mode for transmitting removed elements */
@@ -620,7 +537,7 @@ send_client_removed_element (struct Operation *op,
620 GNUNET_break (0); 537 GNUNET_break (0);
621 return; 538 return;
622 } 539 }
623 rm->result_status = htons (GNUNET_SET_STATUS_DEL_LOCAL); 540 rm->result_status = htons (GNUNET_SETI_STATUS_DEL_LOCAL);
624 rm->request_id = htonl (op->client_request_id); 541 rm->request_id = htonl (op->client_request_id);
625 rm->element_type = element->element_type; 542 rm->element_type = element->element_type;
626 GNUNET_memcpy (&rm[1], 543 GNUNET_memcpy (&rm[1],
@@ -632,6 +549,21 @@ send_client_removed_element (struct Operation *op,
632 549
633 550
634/** 551/**
552 * Is element @a ee part of the set used by @a op?
553 *
554 * @param ee element to test
555 * @param op operation the defines the set and its generation
556 * @return #GNUNET_YES if the element is in the set, #GNUNET_NO if not
557 */
558static int
559_GSS_is_element_of_operation (struct ElementEntry *ee,
560 struct Operation *op)
561{
562 return op->generation_created >= ee->generation_added;
563}
564
565
566/**
635 * Fills the "my_elements" hashmap with all relevant elements. 567 * Fills the "my_elements" hashmap with all relevant elements.
636 * 568 *
637 * @param cls the `struct Operation *` we are performing 569 * @param cls the `struct Operation *` we are performing
@@ -664,14 +596,14 @@ filtered_map_initialization (void *cls,
664 596
665 /* Test if element is in other peer's bloomfilter */ 597 /* Test if element is in other peer's bloomfilter */
666 GNUNET_BLOCK_mingle_hash (&ee->element_hash, 598 GNUNET_BLOCK_mingle_hash (&ee->element_hash,
667 op->state->salt, 599 op->salt,
668 &mutated_hash); 600 &mutated_hash);
669 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 601 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
670 "Testing mingled hash %s with salt %u\n", 602 "Testing mingled hash %s with salt %u\n",
671 GNUNET_h2s (&mutated_hash), 603 GNUNET_h2s (&mutated_hash),
672 op->state->salt); 604 op->salt);
673 if (GNUNET_NO == 605 if (GNUNET_NO ==
674 GNUNET_CONTAINER_bloomfilter_test (op->state->remote_bf, 606 GNUNET_CONTAINER_bloomfilter_test (op->remote_bf,
675 &mutated_hash)) 607 &mutated_hash))
676 { 608 {
677 /* remove this element */ 609 /* remove this element */
@@ -683,16 +615,16 @@ filtered_map_initialization (void *cls,
683 ee->element.size); 615 ee->element.size);
684 return GNUNET_YES; 616 return GNUNET_YES;
685 } 617 }
686 op->state->my_element_count++; 618 op->my_element_count++;
687 GNUNET_CRYPTO_hash_xor (&op->state->my_xor, 619 GNUNET_CRYPTO_hash_xor (&op->my_xor,
688 &ee->element_hash, 620 &ee->element_hash,
689 &op->state->my_xor); 621 &op->my_xor);
690 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 622 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
691 "Filtered initialization of my_elements, adding %s:%u\n", 623 "Filtered initialization of my_elements, adding %s:%u\n",
692 GNUNET_h2s (&ee->element_hash), 624 GNUNET_h2s (&ee->element_hash),
693 ee->element.size); 625 ee->element.size);
694 GNUNET_break (GNUNET_YES == 626 GNUNET_break (GNUNET_YES ==
695 GNUNET_CONTAINER_multihashmap_put (op->state->my_elements, 627 GNUNET_CONTAINER_multihashmap_put (op->my_elements,
696 &ee->element_hash, 628 &ee->element_hash,
697 ee, 629 ee,
698 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 630 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
@@ -720,27 +652,27 @@ iterator_bf_reduce (void *cls,
720 struct GNUNET_HashCode mutated_hash; 652 struct GNUNET_HashCode mutated_hash;
721 653
722 GNUNET_BLOCK_mingle_hash (&ee->element_hash, 654 GNUNET_BLOCK_mingle_hash (&ee->element_hash,
723 op->state->salt, 655 op->salt,
724 &mutated_hash); 656 &mutated_hash);
725 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 657 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
726 "Testing mingled hash %s with salt %u\n", 658 "Testing mingled hash %s with salt %u\n",
727 GNUNET_h2s (&mutated_hash), 659 GNUNET_h2s (&mutated_hash),
728 op->state->salt); 660 op->salt);
729 if (GNUNET_NO == 661 if (GNUNET_NO ==
730 GNUNET_CONTAINER_bloomfilter_test (op->state->remote_bf, 662 GNUNET_CONTAINER_bloomfilter_test (op->remote_bf,
731 &mutated_hash)) 663 &mutated_hash))
732 { 664 {
733 GNUNET_break (0 < op->state->my_element_count); 665 GNUNET_break (0 < op->my_element_count);
734 op->state->my_element_count--; 666 op->my_element_count--;
735 GNUNET_CRYPTO_hash_xor (&op->state->my_xor, 667 GNUNET_CRYPTO_hash_xor (&op->my_xor,
736 &ee->element_hash, 668 &ee->element_hash,
737 &op->state->my_xor); 669 &op->my_xor);
738 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 670 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
739 "Bloom filter reduction of my_elements, removing %s:%u\n", 671 "Bloom filter reduction of my_elements, removing %s:%u\n",
740 GNUNET_h2s (&ee->element_hash), 672 GNUNET_h2s (&ee->element_hash),
741 ee->element.size); 673 ee->element.size);
742 GNUNET_assert (GNUNET_YES == 674 GNUNET_assert (GNUNET_YES ==
743 GNUNET_CONTAINER_multihashmap_remove (op->state->my_elements, 675 GNUNET_CONTAINER_multihashmap_remove (op->my_elements,
744 &ee->element_hash, 676 &ee->element_hash,
745 ee)); 677 ee));
746 send_client_removed_element (op, 678 send_client_removed_element (op,
@@ -775,19 +707,197 @@ iterator_bf_create (void *cls,
775 struct GNUNET_HashCode mutated_hash; 707 struct GNUNET_HashCode mutated_hash;
776 708
777 GNUNET_BLOCK_mingle_hash (&ee->element_hash, 709 GNUNET_BLOCK_mingle_hash (&ee->element_hash,
778 op->state->salt, 710 op->salt,
779 &mutated_hash); 711 &mutated_hash);
780 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 712 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
781 "Initializing BF with hash %s with salt %u\n", 713 "Initializing BF with hash %s with salt %u\n",
782 GNUNET_h2s (&mutated_hash), 714 GNUNET_h2s (&mutated_hash),
783 op->state->salt); 715 op->salt);
784 GNUNET_CONTAINER_bloomfilter_add (op->state->local_bf, 716 GNUNET_CONTAINER_bloomfilter_add (op->local_bf,
785 &mutated_hash); 717 &mutated_hash);
786 return GNUNET_YES; 718 return GNUNET_YES;
787} 719}
788 720
789 721
790/** 722/**
723 * Destroy the given operation. Used for any operation where both
724 * peers were known and that thus actually had a vt and channel. Must
725 * not be used for operations where 'listener' is still set and we do
726 * not know the other peer.
727 *
728 * Call the implementation-specific cancel function of the operation.
729 * Disconnects from the remote peer. Does not disconnect the client,
730 * as there may be multiple operations per set.
731 *
732 * @param op operation to destroy
733 */
734static void
735_GSS_operation_destroy (struct Operation *op)
736{
737 struct Set *set = op->set;
738 struct GNUNET_CADET_Channel *channel;
739
740 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying operation %p\n", op);
741 GNUNET_assert (NULL == op->listener);
742 if (NULL != op->remote_bf)
743 {
744 GNUNET_CONTAINER_bloomfilter_free (op->remote_bf);
745 op->remote_bf = NULL;
746 }
747 if (NULL != op->local_bf)
748 {
749 GNUNET_CONTAINER_bloomfilter_free (op->local_bf);
750 op->local_bf = NULL;
751 }
752 if (NULL != op->my_elements)
753 {
754 GNUNET_CONTAINER_multihashmap_destroy (op->my_elements);
755 op->my_elements = NULL;
756 }
757 if (NULL != op->full_result_iter)
758 {
759 GNUNET_CONTAINER_multihashmap_iterator_destroy (
760 op->full_result_iter);
761 op->full_result_iter = NULL;
762 }
763 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
764 "Destroying intersection op state done\n");
765 if (NULL != set)
766 {
767 GNUNET_CONTAINER_DLL_remove (set->ops_head,
768 set->ops_tail,
769 op);
770 op->set = NULL;
771 }
772 if (NULL != op->context_msg)
773 {
774 GNUNET_free (op->context_msg);
775 op->context_msg = NULL;
776 }
777 if (NULL != (channel = op->channel))
778 {
779 /* This will free op; called conditionally as this helper function
780 is also called from within the channel disconnect handler. */
781 op->channel = NULL;
782 GNUNET_CADET_channel_destroy (channel);
783 }
784 /* We rely on the channel end handler to free 'op'. When 'op->channel' was NULL,
785 * there was a channel end handler that will free 'op' on the call stack. */
786}
787
788
789/**
790 * This function probably should not exist
791 * and be replaced by inlining more specific
792 * logic in the various places where it is called.
793 */
794static void
795_GSS_operation_destroy2 (struct Operation *op);
796
797
798/**
799 * Destroy an incoming request from a remote peer
800 *
801 * @param op remote request to destroy
802 */
803static void
804incoming_destroy (struct Operation *op)
805{
806 struct Listener *listener;
807
808 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
809 "Destroying incoming operation %p\n",
810 op);
811 if (NULL != (listener = op->listener))
812 {
813 GNUNET_CONTAINER_DLL_remove (listener->op_head,
814 listener->op_tail,
815 op);
816 op->listener = NULL;
817 }
818 if (NULL != op->timeout_task)
819 {
820 GNUNET_SCHEDULER_cancel (op->timeout_task);
821 op->timeout_task = NULL;
822 }
823 _GSS_operation_destroy2 (op);
824}
825
826
827/**
828 * Signal to the client that the operation has finished and
829 * destroy the operation.
830 *
831 * @param cls operation to destroy
832 */
833static void
834send_client_done_and_destroy (void *cls)
835{
836 struct Operation *op = cls;
837 struct GNUNET_MQ_Envelope *ev;
838 struct GNUNET_SETI_ResultMessage *rm;
839
840 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
841 "Intersection succeeded, sending DONE to local client\n");
842 GNUNET_STATISTICS_update (_GSS_statistics,
843 "# Intersection operations succeeded",
844 1,
845 GNUNET_NO);
846 ev = GNUNET_MQ_msg (rm,
847 GNUNET_MESSAGE_TYPE_SETI_RESULT);
848 rm->request_id = htonl (op->client_request_id);
849 rm->result_status = htons (GNUNET_SETI_STATUS_DONE);
850 rm->element_type = htons (0);
851 GNUNET_MQ_send (op->set->cs->mq,
852 ev);
853 _GSS_operation_destroy (op);
854}
855
856
857/**
858 * This function probably should not exist
859 * and be replaced by inlining more specific
860 * logic in the various places where it is called.
861 */
862static void
863_GSS_operation_destroy2 (struct Operation *op)
864{
865 struct GNUNET_CADET_Channel *channel;
866
867 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
868 "channel_end_cb called\n");
869 if (NULL != (channel = op->channel))
870 {
871 /* This will free op; called conditionally as this helper function
872 is also called from within the channel disconnect handler. */
873 op->channel = NULL;
874 GNUNET_CADET_channel_destroy (channel);
875 }
876 if (NULL != op->listener)
877 {
878 incoming_destroy (op);
879 return;
880 }
881 if (NULL != op->set)
882 {
883 if (GNUNET_YES == op->channel_death_expected)
884 {
885 /* oh goodie, we are done! */
886 send_client_done_and_destroy (op);
887 }
888 else
889 {
890 /* sorry, channel went down early, too bad. */
891 _GSS_operation_destroy (op);
892 }
893 }
894 else
895 _GSS_operation_destroy (op);
896 GNUNET_free (op);
897}
898
899
900/**
791 * Inform the client that the intersection operation has failed, 901 * Inform the client that the intersection operation has failed,
792 * and proceed to destroy the evaluate operation. 902 * and proceed to destroy the evaluate operation.
793 * 903 *
@@ -797,7 +907,7 @@ static void
797fail_intersection_operation (struct Operation *op) 907fail_intersection_operation (struct Operation *op)
798{ 908{
799 struct GNUNET_MQ_Envelope *ev; 909 struct GNUNET_MQ_Envelope *ev;
800 struct GNUNET_SET_ResultMessage *msg; 910 struct GNUNET_SETI_ResultMessage *msg;
801 911
802 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 912 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
803 "Intersection operation failed\n"); 913 "Intersection operation failed\n");
@@ -805,10 +915,10 @@ fail_intersection_operation (struct Operation *op)
805 "# Intersection operations failed", 915 "# Intersection operations failed",
806 1, 916 1,
807 GNUNET_NO); 917 GNUNET_NO);
808 if (NULL != op->state->my_elements) 918 if (NULL != op->my_elements)
809 { 919 {
810 GNUNET_CONTAINER_multihashmap_destroy (op->state->my_elements); 920 GNUNET_CONTAINER_multihashmap_destroy (op->my_elements);
811 op->state->my_elements = NULL; 921 op->my_elements = NULL;
812 } 922 }
813 ev = GNUNET_MQ_msg (msg, 923 ev = GNUNET_MQ_msg (msg,
814 GNUNET_MESSAGE_TYPE_SETI_RESULT); 924 GNUNET_MESSAGE_TYPE_SETI_RESULT);
@@ -817,8 +927,7 @@ fail_intersection_operation (struct Operation *op)
817 msg->element_type = htons (0); 927 msg->element_type = htons (0);
818 GNUNET_MQ_send (op->set->cs->mq, 928 GNUNET_MQ_send (op->set->cs->mq,
819 ev); 929 ev);
820 _GSS_operation_destroy (op, 930 _GSS_operation_destroy (op);
821 GNUNET_YES);
822} 931}
823 932
824 933
@@ -845,22 +954,22 @@ send_bloomfilter (struct Operation *op)
845 potential and minimize overall bandwidth consumption. */ 954 potential and minimize overall bandwidth consumption. */
846 bf_elementbits = 2 + ceil (log2 ((double) 955 bf_elementbits = 2 + ceil (log2 ((double)
847 (op->remote_element_count 956 (op->remote_element_count
848 / (double) op->state->my_element_count))); 957 / (double) op->my_element_count)));
849 if (bf_elementbits < 1) 958 if (bf_elementbits < 1)
850 bf_elementbits = 1; /* make sure k is not 0 */ 959 bf_elementbits = 1; /* make sure k is not 0 */
851 /* optimize BF-size to ~50% of bits set */ 960 /* optimize BF-size to ~50% of bits set */
852 bf_size = ceil ((double) (op->state->my_element_count 961 bf_size = ceil ((double) (op->my_element_count
853 * bf_elementbits / log (2))); 962 * bf_elementbits / log (2)));
854 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 963 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
855 "Sending Bloom filter (%u) of size %u bytes\n", 964 "Sending Bloom filter (%u) of size %u bytes\n",
856 (unsigned int) bf_elementbits, 965 (unsigned int) bf_elementbits,
857 (unsigned int) bf_size); 966 (unsigned int) bf_size);
858 op->state->local_bf = GNUNET_CONTAINER_bloomfilter_init (NULL, 967 op->local_bf = GNUNET_CONTAINER_bloomfilter_init (NULL,
859 bf_size, 968 bf_size,
860 bf_elementbits); 969 bf_elementbits);
861 op->state->salt = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 970 op->salt = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
862 UINT32_MAX); 971 UINT32_MAX);
863 GNUNET_CONTAINER_multihashmap_iterate (op->state->my_elements, 972 GNUNET_CONTAINER_multihashmap_iterate (op->my_elements,
864 &iterator_bf_create, 973 &iterator_bf_create,
865 op); 974 op);
866 975
@@ -876,17 +985,17 @@ send_bloomfilter (struct Operation *op)
876 chunk_size = bf_size; 985 chunk_size = bf_size;
877 ev = GNUNET_MQ_msg_extra (msg, 986 ev = GNUNET_MQ_msg_extra (msg,
878 chunk_size, 987 chunk_size,
879 GNUNET_MESSAGE_TYPE_SETI_INTERSECTION_P2P_BF); 988 GNUNET_MESSAGE_TYPE_SETI_P2P_BF);
880 GNUNET_assert (GNUNET_SYSERR != 989 GNUNET_assert (GNUNET_SYSERR !=
881 GNUNET_CONTAINER_bloomfilter_get_raw_data ( 990 GNUNET_CONTAINER_bloomfilter_get_raw_data (
882 op->state->local_bf, 991 op->local_bf,
883 (char *) &msg[1], 992 (char *) &msg[1],
884 bf_size)); 993 bf_size));
885 msg->sender_element_count = htonl (op->state->my_element_count); 994 msg->sender_element_count = htonl (op->my_element_count);
886 msg->bloomfilter_total_length = htonl (bf_size); 995 msg->bloomfilter_total_length = htonl (bf_size);
887 msg->bits_per_element = htonl (bf_elementbits); 996 msg->bits_per_element = htonl (bf_elementbits);
888 msg->sender_mutator = htonl (op->state->salt); 997 msg->sender_mutator = htonl (op->salt);
889 msg->element_xor_hash = op->state->my_xor; 998 msg->element_xor_hash = op->my_xor;
890 GNUNET_MQ_send (op->mq, ev); 999 GNUNET_MQ_send (op->mq, ev);
891 } 1000 }
892 else 1001 else
@@ -895,7 +1004,7 @@ send_bloomfilter (struct Operation *op)
895 bf_data = GNUNET_malloc (bf_size); 1004 bf_data = GNUNET_malloc (bf_size);
896 GNUNET_assert (GNUNET_SYSERR != 1005 GNUNET_assert (GNUNET_SYSERR !=
897 GNUNET_CONTAINER_bloomfilter_get_raw_data ( 1006 GNUNET_CONTAINER_bloomfilter_get_raw_data (
898 op->state->local_bf, 1007 op->local_bf,
899 bf_data, 1008 bf_data,
900 bf_size)); 1009 bf_size));
901 offset = 0; 1010 offset = 0;
@@ -905,53 +1014,22 @@ send_bloomfilter (struct Operation *op)
905 chunk_size = bf_size - offset; 1014 chunk_size = bf_size - offset;
906 ev = GNUNET_MQ_msg_extra (msg, 1015 ev = GNUNET_MQ_msg_extra (msg,
907 chunk_size, 1016 chunk_size,
908 GNUNET_MESSAGE_TYPE_SETI_INTERSECTION_P2P_BF); 1017 GNUNET_MESSAGE_TYPE_SETI_P2P_BF);
909 GNUNET_memcpy (&msg[1], 1018 GNUNET_memcpy (&msg[1],
910 &bf_data[offset], 1019 &bf_data[offset],
911 chunk_size); 1020 chunk_size);
912 offset += chunk_size; 1021 offset += chunk_size;
913 msg->sender_element_count = htonl (op->state->my_element_count); 1022 msg->sender_element_count = htonl (op->my_element_count);
914 msg->bloomfilter_total_length = htonl (bf_size); 1023 msg->bloomfilter_total_length = htonl (bf_size);
915 msg->bits_per_element = htonl (bf_elementbits); 1024 msg->bits_per_element = htonl (bf_elementbits);
916 msg->sender_mutator = htonl (op->state->salt); 1025 msg->sender_mutator = htonl (op->salt);
917 msg->element_xor_hash = op->state->my_xor; 1026 msg->element_xor_hash = op->my_xor;
918 GNUNET_MQ_send (op->mq, ev); 1027 GNUNET_MQ_send (op->mq, ev);
919 } 1028 }
920 GNUNET_free (bf_data); 1029 GNUNET_free (bf_data);
921 } 1030 }
922 GNUNET_CONTAINER_bloomfilter_free (op->state->local_bf); 1031 GNUNET_CONTAINER_bloomfilter_free (op->local_bf);
923 op->state->local_bf = NULL; 1032 op->local_bf = NULL;
924}
925
926
927/**
928 * Signal to the client that the operation has finished and
929 * destroy the operation.
930 *
931 * @param cls operation to destroy
932 */
933static void
934send_client_done_and_destroy (void *cls)
935{
936 struct Operation *op = cls;
937 struct GNUNET_MQ_Envelope *ev;
938 struct GNUNET_SET_ResultMessage *rm;
939
940 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
941 "Intersection succeeded, sending DONE to local client\n");
942 GNUNET_STATISTICS_update (_GSS_statistics,
943 "# Intersection operations succeeded",
944 1,
945 GNUNET_NO);
946 ev = GNUNET_MQ_msg (rm,
947 GNUNET_MESSAGE_TYPE_SETI_RESULT);
948 rm->request_id = htonl (op->client_request_id);
949 rm->result_status = htons (GNUNET_SET_STATUS_DONE);
950 rm->element_type = htons (0);
951 GNUNET_MQ_send (op->set->cs->mq,
952 ev);
953 _GSS_operation_destroy (op,
954 GNUNET_YES);
955} 1033}
956 1034
957 1035
@@ -970,8 +1048,8 @@ finished_local_operations (void *cls)
970 1048
971 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1049 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
972 "DONE sent to other peer, now waiting for other end to close the channel\n"); 1050 "DONE sent to other peer, now waiting for other end to close the channel\n");
973 op->state->phase = PHASE_FINISHED; 1051 op->phase = PHASE_FINISHED;
974 op->state->channel_death_expected = GNUNET_YES; 1052 op->channel_death_expected = GNUNET_YES;
975} 1053}
976 1054
977 1055
@@ -988,12 +1066,12 @@ send_p2p_done (struct Operation *op)
988 struct GNUNET_MQ_Envelope *ev; 1066 struct GNUNET_MQ_Envelope *ev;
989 struct IntersectionDoneMessage *idm; 1067 struct IntersectionDoneMessage *idm;
990 1068
991 GNUNET_assert (PHASE_MUST_SEND_DONE == op->state->phase); 1069 GNUNET_assert (PHASE_MUST_SEND_DONE == op->phase);
992 GNUNET_assert (GNUNET_NO == op->state->channel_death_expected); 1070 GNUNET_assert (GNUNET_NO == op->channel_death_expected);
993 ev = GNUNET_MQ_msg (idm, 1071 ev = GNUNET_MQ_msg (idm,
994 GNUNET_MESSAGE_TYPE_SETI_INTERSECTION_P2P_DONE); 1072 GNUNET_MESSAGE_TYPE_SETI_P2P_DONE);
995 idm->final_element_count = htonl (op->state->my_element_count); 1073 idm->final_element_count = htonl (op->my_element_count);
996 idm->element_xor_hash = op->state->my_xor; 1074 idm->element_xor_hash = op->my_xor;
997 GNUNET_MQ_notify_sent (ev, 1075 GNUNET_MQ_notify_sent (ev,
998 &finished_local_operations, 1076 &finished_local_operations,
999 op); 1077 op);
@@ -1014,12 +1092,12 @@ send_remaining_elements (void *cls)
1014 const void *nxt; 1092 const void *nxt;
1015 const struct ElementEntry *ee; 1093 const struct ElementEntry *ee;
1016 struct GNUNET_MQ_Envelope *ev; 1094 struct GNUNET_MQ_Envelope *ev;
1017 struct GNUNET_SET_ResultMessage *rm; 1095 struct GNUNET_SETI_ResultMessage *rm;
1018 const struct GNUNET_SET_Element *element; 1096 const struct GNUNET_SETI_Element *element;
1019 int res; 1097 int res;
1020 1098
1021 res = GNUNET_CONTAINER_multihashmap_iterator_next ( 1099 res = GNUNET_CONTAINER_multihashmap_iterator_next (
1022 op->state->full_result_iter, 1100 op->full_result_iter,
1023 NULL, 1101 NULL,
1024 &nxt); 1102 &nxt);
1025 if (GNUNET_NO == res) 1103 if (GNUNET_NO == res)
@@ -1027,14 +1105,14 @@ send_remaining_elements (void *cls)
1027 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1105 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1028 "Sending done and destroy because iterator ran out\n"); 1106 "Sending done and destroy because iterator ran out\n");
1029 GNUNET_CONTAINER_multihashmap_iterator_destroy ( 1107 GNUNET_CONTAINER_multihashmap_iterator_destroy (
1030 op->state->full_result_iter); 1108 op->full_result_iter);
1031 op->state->full_result_iter = NULL; 1109 op->full_result_iter = NULL;
1032 if (PHASE_DONE_RECEIVED == op->state->phase) 1110 if (PHASE_DONE_RECEIVED == op->phase)
1033 { 1111 {
1034 op->state->phase = PHASE_FINISHED; 1112 op->phase = PHASE_FINISHED;
1035 send_client_done_and_destroy (op); 1113 send_client_done_and_destroy (op);
1036 } 1114 }
1037 else if (PHASE_MUST_SEND_DONE == op->state->phase) 1115 else if (PHASE_MUST_SEND_DONE == op->phase)
1038 { 1116 {
1039 send_p2p_done (op); 1117 send_p2p_done (op);
1040 } 1118 }
@@ -1055,7 +1133,7 @@ send_remaining_elements (void *cls)
1055 element->size, 1133 element->size,
1056 GNUNET_MESSAGE_TYPE_SETI_RESULT); 1134 GNUNET_MESSAGE_TYPE_SETI_RESULT);
1057 GNUNET_assert (NULL != ev); 1135 GNUNET_assert (NULL != ev);
1058 rm->result_status = htons (GNUNET_SET_STATUS_OK); 1136 rm->result_status = htons (GNUNET_SETI_STATUS_ADD_LOCAL);
1059 rm->request_id = htonl (op->client_request_id); 1137 rm->request_id = htonl (op->client_request_id);
1060 rm->element_type = element->element_type; 1138 rm->element_type = element->element_type;
1061 GNUNET_memcpy (&rm[1], 1139 GNUNET_memcpy (&rm[1],
@@ -1088,15 +1166,15 @@ initialize_map_unfiltered (void *cls,
1088 1166
1089 if (GNUNET_NO == _GSS_is_element_of_operation (ee, op)) 1167 if (GNUNET_NO == _GSS_is_element_of_operation (ee, op))
1090 return GNUNET_YES; /* element not live in operation's generation */ 1168 return GNUNET_YES; /* element not live in operation's generation */
1091 GNUNET_CRYPTO_hash_xor (&op->state->my_xor, 1169 GNUNET_CRYPTO_hash_xor (&op->my_xor,
1092 &ee->element_hash, 1170 &ee->element_hash,
1093 &op->state->my_xor); 1171 &op->my_xor);
1094 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1172 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1095 "Initial full initialization of my_elements, adding %s:%u\n", 1173 "Initial full initialization of my_elements, adding %s:%u\n",
1096 GNUNET_h2s (&ee->element_hash), 1174 GNUNET_h2s (&ee->element_hash),
1097 ee->element.size); 1175 ee->element.size);
1098 GNUNET_break (GNUNET_YES == 1176 GNUNET_break (GNUNET_YES ==
1099 GNUNET_CONTAINER_multihashmap_put (op->state->my_elements, 1177 GNUNET_CONTAINER_multihashmap_put (op->my_elements,
1100 &ee->element_hash, 1178 &ee->element_hash,
1101 ee, 1179 ee,
1102 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 1180 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
@@ -1118,10 +1196,10 @@ send_element_count (struct Operation *op)
1118 1196
1119 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1197 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1120 "Sending our element count (%u)\n", 1198 "Sending our element count (%u)\n",
1121 op->state->my_element_count); 1199 op->my_element_count);
1122 ev = GNUNET_MQ_msg (msg, 1200 ev = GNUNET_MQ_msg (msg,
1123 GNUNET_MESSAGE_TYPE_SETI_INTERSECTION_P2P_ELEMENT_INFO); 1201 GNUNET_MESSAGE_TYPE_SETI_P2P_ELEMENT_INFO);
1124 msg->sender_element_count = htonl (op->state->my_element_count); 1202 msg->sender_element_count = htonl (op->my_element_count);
1125 GNUNET_MQ_send (op->mq, ev); 1203 GNUNET_MQ_send (op->mq, ev);
1126} 1204}
1127 1205
@@ -1135,7 +1213,7 @@ send_element_count (struct Operation *op)
1135static void 1213static void
1136begin_bf_exchange (struct Operation *op) 1214begin_bf_exchange (struct Operation *op)
1137{ 1215{
1138 op->state->phase = PHASE_BF_EXCHANGE; 1216 op->phase = PHASE_BF_EXCHANGE;
1139 GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements, 1217 GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements,
1140 &initialize_map_unfiltered, 1218 &initialize_map_unfiltered,
1141 op); 1219 op);
@@ -1157,28 +1235,22 @@ handle_intersection_p2p_element_info (void *cls,
1157{ 1235{
1158 struct Operation *op = cls; 1236 struct Operation *op = cls;
1159 1237
1160 if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation)
1161 {
1162 GNUNET_break_op (0);
1163 fail_intersection_operation (op);
1164 return;
1165 }
1166 op->remote_element_count = ntohl (msg->sender_element_count); 1238 op->remote_element_count = ntohl (msg->sender_element_count);
1167 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1239 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1168 "Received remote element count (%u), I have %u\n", 1240 "Received remote element count (%u), I have %u\n",
1169 op->remote_element_count, 1241 op->remote_element_count,
1170 op->state->my_element_count); 1242 op->my_element_count);
1171 if (((PHASE_INITIAL != op->state->phase) && 1243 if (((PHASE_INITIAL != op->phase) &&
1172 (PHASE_COUNT_SENT != op->state->phase)) || 1244 (PHASE_COUNT_SENT != op->phase)) ||
1173 (op->state->my_element_count > op->remote_element_count) || 1245 (op->my_element_count > op->remote_element_count) ||
1174 (0 == op->state->my_element_count) || 1246 (0 == op->my_element_count) ||
1175 (0 == op->remote_element_count)) 1247 (0 == op->remote_element_count))
1176 { 1248 {
1177 GNUNET_break_op (0); 1249 GNUNET_break_op (0);
1178 fail_intersection_operation (op); 1250 fail_intersection_operation (op);
1179 return; 1251 return;
1180 } 1252 }
1181 GNUNET_break (NULL == op->state->remote_bf); 1253 GNUNET_break (NULL == op->remote_bf);
1182 begin_bf_exchange (op); 1254 begin_bf_exchange (op);
1183 GNUNET_CADET_receive_done (op->channel); 1255 GNUNET_CADET_receive_done (op->channel);
1184} 1256}
@@ -1194,11 +1266,11 @@ process_bf (struct Operation *op)
1194{ 1266{
1195 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1267 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1196 "Received BF in phase %u, foreign count is %u, my element count is %u/%u\n", 1268 "Received BF in phase %u, foreign count is %u, my element count is %u/%u\n",
1197 op->state->phase, 1269 op->phase,
1198 op->remote_element_count, 1270 op->remote_element_count,
1199 op->state->my_element_count, 1271 op->my_element_count,
1200 GNUNET_CONTAINER_multihashmap_size (op->set->content->elements)); 1272 GNUNET_CONTAINER_multihashmap_size (op->set->content->elements));
1201 switch (op->state->phase) 1273 switch (op->phase)
1202 { 1274 {
1203 case PHASE_INITIAL: 1275 case PHASE_INITIAL:
1204 GNUNET_break_op (0); 1276 GNUNET_break_op (0);
@@ -1207,14 +1279,14 @@ process_bf (struct Operation *op)
1207 case PHASE_COUNT_SENT: 1279 case PHASE_COUNT_SENT:
1208 /* This is the first BF being sent, build our initial map with 1280 /* This is the first BF being sent, build our initial map with
1209 filtering in place */ 1281 filtering in place */
1210 op->state->my_element_count = 0; 1282 op->my_element_count = 0;
1211 GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements, 1283 GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements,
1212 &filtered_map_initialization, 1284 &filtered_map_initialization,
1213 op); 1285 op);
1214 break; 1286 break;
1215 case PHASE_BF_EXCHANGE: 1287 case PHASE_BF_EXCHANGE:
1216 /* Update our set by reduction */ 1288 /* Update our set by reduction */
1217 GNUNET_CONTAINER_multihashmap_iterate (op->state->my_elements, 1289 GNUNET_CONTAINER_multihashmap_iterate (op->my_elements,
1218 &iterator_bf_reduce, 1290 &iterator_bf_reduce,
1219 op); 1291 op);
1220 break; 1292 break;
@@ -1231,35 +1303,35 @@ process_bf (struct Operation *op)
1231 fail_intersection_operation (op); 1303 fail_intersection_operation (op);
1232 return; 1304 return;
1233 } 1305 }
1234 GNUNET_CONTAINER_bloomfilter_free (op->state->remote_bf); 1306 GNUNET_CONTAINER_bloomfilter_free (op->remote_bf);
1235 op->state->remote_bf = NULL; 1307 op->remote_bf = NULL;
1236 1308
1237 if ((0 == op->state->my_element_count) || /* fully disjoint */ 1309 if ((0 == op->my_element_count) || /* fully disjoint */
1238 ((op->state->my_element_count == op->remote_element_count) && 1310 ((op->my_element_count == op->remote_element_count) &&
1239 (0 == GNUNET_memcmp (&op->state->my_xor, 1311 (0 == GNUNET_memcmp (&op->my_xor,
1240 &op->state->other_xor)))) 1312 &op->other_xor))))
1241 { 1313 {
1242 /* we are done */ 1314 /* we are done */
1243 op->state->phase = PHASE_MUST_SEND_DONE; 1315 op->phase = PHASE_MUST_SEND_DONE;
1244 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1316 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1245 "Intersection succeeded, sending DONE to other peer\n"); 1317 "Intersection succeeded, sending DONE to other peer\n");
1246 GNUNET_CONTAINER_bloomfilter_free (op->state->local_bf); 1318 GNUNET_CONTAINER_bloomfilter_free (op->local_bf);
1247 op->state->local_bf = NULL; 1319 op->local_bf = NULL;
1248 if (GNUNET_SET_RESULT_FULL == op->result_mode) 1320 if (GNUNET_YES == op->return_intersection)
1249 { 1321 {
1250 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1322 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1251 "Sending full result set (%u elements)\n", 1323 "Sending full result set (%u elements)\n",
1252 GNUNET_CONTAINER_multihashmap_size (op->state->my_elements)); 1324 GNUNET_CONTAINER_multihashmap_size (op->my_elements));
1253 op->state->full_result_iter 1325 op->full_result_iter
1254 = GNUNET_CONTAINER_multihashmap_iterator_create ( 1326 = GNUNET_CONTAINER_multihashmap_iterator_create (
1255 op->state->my_elements); 1327 op->my_elements);
1256 send_remaining_elements (op); 1328 send_remaining_elements (op);
1257 return; 1329 return;
1258 } 1330 }
1259 send_p2p_done (op); 1331 send_p2p_done (op);
1260 return; 1332 return;
1261 } 1333 }
1262 op->state->phase = PHASE_BF_EXCHANGE; 1334 op->phase = PHASE_BF_EXCHANGE;
1263 send_bloomfilter (op); 1335 send_bloomfilter (op);
1264} 1336}
1265 1337
@@ -1277,11 +1349,7 @@ check_intersection_p2p_bf (void *cls,
1277{ 1349{
1278 struct Operation *op = cls; 1350 struct Operation *op = cls;
1279 1351
1280 if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation) 1352 (void) op;
1281 {
1282 GNUNET_break_op (0);
1283 return GNUNET_SYSERR;
1284 }
1285 return GNUNET_OK; 1353 return GNUNET_OK;
1286} 1354}
1287 1355
@@ -1301,7 +1369,7 @@ handle_intersection_p2p_bf (void *cls,
1301 uint32_t chunk_size; 1369 uint32_t chunk_size;
1302 uint32_t bf_bits_per_element; 1370 uint32_t bf_bits_per_element;
1303 1371
1304 switch (op->state->phase) 1372 switch (op->phase)
1305 { 1373 {
1306 case PHASE_INITIAL: 1374 case PHASE_INITIAL:
1307 GNUNET_break_op (0); 1375 GNUNET_break_op (0);
@@ -1313,43 +1381,43 @@ handle_intersection_p2p_bf (void *cls,
1313 bf_size = ntohl (msg->bloomfilter_total_length); 1381 bf_size = ntohl (msg->bloomfilter_total_length);
1314 bf_bits_per_element = ntohl (msg->bits_per_element); 1382 bf_bits_per_element = ntohl (msg->bits_per_element);
1315 chunk_size = htons (msg->header.size) - sizeof(struct BFMessage); 1383 chunk_size = htons (msg->header.size) - sizeof(struct BFMessage);
1316 op->state->other_xor = msg->element_xor_hash; 1384 op->other_xor = msg->element_xor_hash;
1317 if (bf_size == chunk_size) 1385 if (bf_size == chunk_size)
1318 { 1386 {
1319 if (NULL != op->state->bf_data) 1387 if (NULL != op->bf_data)
1320 { 1388 {
1321 GNUNET_break_op (0); 1389 GNUNET_break_op (0);
1322 fail_intersection_operation (op); 1390 fail_intersection_operation (op);
1323 return; 1391 return;
1324 } 1392 }
1325 /* single part, done here immediately */ 1393 /* single part, done here immediately */
1326 op->state->remote_bf 1394 op->remote_bf
1327 = GNUNET_CONTAINER_bloomfilter_init ((const char *) &msg[1], 1395 = GNUNET_CONTAINER_bloomfilter_init ((const char *) &msg[1],
1328 bf_size, 1396 bf_size,
1329 bf_bits_per_element); 1397 bf_bits_per_element);
1330 op->state->salt = ntohl (msg->sender_mutator); 1398 op->salt = ntohl (msg->sender_mutator);
1331 op->remote_element_count = ntohl (msg->sender_element_count); 1399 op->remote_element_count = ntohl (msg->sender_element_count);
1332 process_bf (op); 1400 process_bf (op);
1333 break; 1401 break;
1334 } 1402 }
1335 /* multipart chunk */ 1403 /* multipart chunk */
1336 if (NULL == op->state->bf_data) 1404 if (NULL == op->bf_data)
1337 { 1405 {
1338 /* first chunk, initialize */ 1406 /* first chunk, initialize */
1339 op->state->bf_data = GNUNET_malloc (bf_size); 1407 op->bf_data = GNUNET_malloc (bf_size);
1340 op->state->bf_data_size = bf_size; 1408 op->bf_data_size = bf_size;
1341 op->state->bf_bits_per_element = bf_bits_per_element; 1409 op->bf_bits_per_element = bf_bits_per_element;
1342 op->state->bf_data_offset = 0; 1410 op->bf_data_offset = 0;
1343 op->state->salt = ntohl (msg->sender_mutator); 1411 op->salt = ntohl (msg->sender_mutator);
1344 op->remote_element_count = ntohl (msg->sender_element_count); 1412 op->remote_element_count = ntohl (msg->sender_element_count);
1345 } 1413 }
1346 else 1414 else
1347 { 1415 {
1348 /* increment */ 1416 /* increment */
1349 if ((op->state->bf_data_size != bf_size) || 1417 if ((op->bf_data_size != bf_size) ||
1350 (op->state->bf_bits_per_element != bf_bits_per_element) || 1418 (op->bf_bits_per_element != bf_bits_per_element) ||
1351 (op->state->bf_data_offset + chunk_size > bf_size) || 1419 (op->bf_data_offset + chunk_size > bf_size) ||
1352 (op->state->salt != ntohl (msg->sender_mutator)) || 1420 (op->salt != ntohl (msg->sender_mutator)) ||
1353 (op->remote_element_count != ntohl (msg->sender_element_count))) 1421 (op->remote_element_count != ntohl (msg->sender_element_count)))
1354 { 1422 {
1355 GNUNET_break_op (0); 1423 GNUNET_break_op (0);
@@ -1357,20 +1425,20 @@ handle_intersection_p2p_bf (void *cls,
1357 return; 1425 return;
1358 } 1426 }
1359 } 1427 }
1360 GNUNET_memcpy (&op->state->bf_data[op->state->bf_data_offset], 1428 GNUNET_memcpy (&op->bf_data[op->bf_data_offset],
1361 (const char *) &msg[1], 1429 (const char *) &msg[1],
1362 chunk_size); 1430 chunk_size);
1363 op->state->bf_data_offset += chunk_size; 1431 op->bf_data_offset += chunk_size;
1364 if (op->state->bf_data_offset == bf_size) 1432 if (op->bf_data_offset == bf_size)
1365 { 1433 {
1366 /* last chunk, run! */ 1434 /* last chunk, run! */
1367 op->state->remote_bf 1435 op->remote_bf
1368 = GNUNET_CONTAINER_bloomfilter_init (op->state->bf_data, 1436 = GNUNET_CONTAINER_bloomfilter_init (op->bf_data,
1369 bf_size, 1437 bf_size,
1370 bf_bits_per_element); 1438 bf_bits_per_element);
1371 GNUNET_free (op->state->bf_data); 1439 GNUNET_free (op->bf_data);
1372 op->state->bf_data = NULL; 1440 op->bf_data = NULL;
1373 op->state->bf_data_size = 0; 1441 op->bf_data_size = 0;
1374 process_bf (op); 1442 process_bf (op);
1375 } 1443 }
1376 break; 1444 break;
@@ -1400,17 +1468,17 @@ filter_all (void *cls,
1400 struct Operation *op = cls; 1468 struct Operation *op = cls;
1401 struct ElementEntry *ee = value; 1469 struct ElementEntry *ee = value;
1402 1470
1403 GNUNET_break (0 < op->state->my_element_count); 1471 GNUNET_break (0 < op->my_element_count);
1404 op->state->my_element_count--; 1472 op->my_element_count--;
1405 GNUNET_CRYPTO_hash_xor (&op->state->my_xor, 1473 GNUNET_CRYPTO_hash_xor (&op->my_xor,
1406 &ee->element_hash, 1474 &ee->element_hash,
1407 &op->state->my_xor); 1475 &op->my_xor);
1408 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1476 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1409 "Final reduction of my_elements, removing %s:%u\n", 1477 "Final reduction of my_elements, removing %s:%u\n",
1410 GNUNET_h2s (&ee->element_hash), 1478 GNUNET_h2s (&ee->element_hash),
1411 ee->element.size); 1479 ee->element.size);
1412 GNUNET_assert (GNUNET_YES == 1480 GNUNET_assert (GNUNET_YES ==
1413 GNUNET_CONTAINER_multihashmap_remove (op->state->my_elements, 1481 GNUNET_CONTAINER_multihashmap_remove (op->my_elements,
1414 &ee->element_hash, 1482 &ee->element_hash,
1415 ee)); 1483 ee));
1416 send_client_removed_element (op, 1484 send_client_removed_element (op,
@@ -1431,13 +1499,7 @@ handle_intersection_p2p_done (void *cls,
1431{ 1499{
1432 struct Operation *op = cls; 1500 struct Operation *op = cls;
1433 1501
1434 if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation) 1502 if (PHASE_BF_EXCHANGE != op->phase)
1435 {
1436 GNUNET_break_op (0);
1437 fail_intersection_operation (op);
1438 return;
1439 }
1440 if (PHASE_BF_EXCHANGE != op->state->phase)
1441 { 1503 {
1442 /* wrong phase to conclude? FIXME: Or should we allow this 1504 /* wrong phase to conclude? FIXME: Or should we allow this
1443 if the other peer has _initially_ already an empty set? */ 1505 if the other peer has _initially_ already an empty set? */
@@ -1449,12 +1511,12 @@ handle_intersection_p2p_done (void *cls,
1449 { 1511 {
1450 /* other peer determined empty set is the intersection, 1512 /* other peer determined empty set is the intersection,
1451 remove all elements */ 1513 remove all elements */
1452 GNUNET_CONTAINER_multihashmap_iterate (op->state->my_elements, 1514 GNUNET_CONTAINER_multihashmap_iterate (op->my_elements,
1453 &filter_all, 1515 &filter_all,
1454 op); 1516 op);
1455 } 1517 }
1456 if ((op->state->my_element_count != ntohl (idm->final_element_count)) || 1518 if ((op->my_element_count != ntohl (idm->final_element_count)) ||
1457 (0 != GNUNET_memcmp (&op->state->my_xor, 1519 (0 != GNUNET_memcmp (&op->my_xor,
1458 &idm->element_xor_hash))) 1520 &idm->element_xor_hash)))
1459 { 1521 {
1460 /* Other peer thinks we are done, but we disagree on the result! */ 1522 /* Other peer thinks we are done, but we disagree on the result! */
@@ -1464,22 +1526,22 @@ handle_intersection_p2p_done (void *cls,
1464 } 1526 }
1465 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1527 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1466 "Got IntersectionDoneMessage, have %u elements in intersection\n", 1528 "Got IntersectionDoneMessage, have %u elements in intersection\n",
1467 op->state->my_element_count); 1529 op->my_element_count);
1468 op->state->phase = PHASE_DONE_RECEIVED; 1530 op->phase = PHASE_DONE_RECEIVED;
1469 GNUNET_CADET_receive_done (op->channel); 1531 GNUNET_CADET_receive_done (op->channel);
1470 1532
1471 GNUNET_assert (GNUNET_NO == op->state->client_done_sent); 1533 GNUNET_assert (GNUNET_NO == op->client_done_sent);
1472 if (GNUNET_SET_RESULT_FULL == op->result_mode) 1534 if (GNUNET_YES == op->return_intersection)
1473 { 1535 {
1474 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1536 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1475 "Sending full result set to client (%u elements)\n", 1537 "Sending full result set to client (%u elements)\n",
1476 GNUNET_CONTAINER_multihashmap_size (op->state->my_elements)); 1538 GNUNET_CONTAINER_multihashmap_size (op->my_elements));
1477 op->state->full_result_iter 1539 op->full_result_iter
1478 = GNUNET_CONTAINER_multihashmap_iterator_create (op->state->my_elements); 1540 = GNUNET_CONTAINER_multihashmap_iterator_create (op->my_elements);
1479 send_remaining_elements (op); 1541 send_remaining_elements (op);
1480 return; 1542 return;
1481 } 1543 }
1482 op->state->phase = PHASE_FINISHED; 1544 op->phase = PHASE_FINISHED;
1483 send_client_done_and_destroy (op); 1545 send_client_done_and_destroy (op);
1484} 1546}
1485 1547
@@ -1507,122 +1569,6 @@ get_incoming (uint32_t id)
1507 1569
1508 1570
1509/** 1571/**
1510 * Destroy an incoming request from a remote peer
1511 *
1512 * @param op remote request to destroy
1513 */
1514static void
1515incoming_destroy (struct Operation *op)
1516{
1517 struct Listener *listener;
1518
1519 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1520 "Destroying incoming operation %p\n",
1521 op);
1522 if (NULL != (listener = op->listener))
1523 {
1524 GNUNET_CONTAINER_DLL_remove (listener->op_head, listener->op_tail, op);
1525 op->listener = NULL;
1526 }
1527 if (NULL != op->timeout_task)
1528 {
1529 GNUNET_SCHEDULER_cancel (op->timeout_task);
1530 op->timeout_task = NULL;
1531 }
1532 _GSS_operation_destroy2 (op);
1533}
1534
1535
1536/**
1537 * Is element @a ee part of the set used by @a op?
1538 *
1539 * @param ee element to test
1540 * @param op operation the defines the set and its generation
1541 * @return #GNUNET_YES if the element is in the set, #GNUNET_NO if not
1542 */
1543static int
1544_GSS_is_element_of_operation (struct ElementEntry *ee,
1545 struct Operation *op)
1546{
1547 return op->generation_created >= ee->generation_added;
1548}
1549
1550
1551/**
1552 * Destroy the given operation. Used for any operation where both
1553 * peers were known and that thus actually had a vt and channel. Must
1554 * not be used for operations where 'listener' is still set and we do
1555 * not know the other peer.
1556 *
1557 * Call the implementation-specific cancel function of the operation.
1558 * Disconnects from the remote peer. Does not disconnect the client,
1559 * as there may be multiple operations per set.
1560 *
1561 * @param op operation to destroy
1562 */
1563static void
1564_GSS_operation_destroy (struct Operation *op)
1565{
1566 struct Set *set = op->set;
1567 struct GNUNET_CADET_Channel *channel;
1568
1569 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying operation %p\n", op);
1570 GNUNET_assert (NULL == op->listener);
1571 if (NULL != op->state)
1572 {
1573 /* check if the op was canceled twice */
1574 GNUNET_assert (NULL != op->state);
1575 if (NULL != op->state->remote_bf)
1576 {
1577 GNUNET_CONTAINER_bloomfilter_free (op->state->remote_bf);
1578 op->state->remote_bf = NULL;
1579 }
1580 if (NULL != op->state->local_bf)
1581 {
1582 GNUNET_CONTAINER_bloomfilter_free (op->state->local_bf);
1583 op->state->local_bf = NULL;
1584 }
1585 if (NULL != op->state->my_elements)
1586 {
1587 GNUNET_CONTAINER_multihashmap_destroy (op->state->my_elements);
1588 op->state->my_elements = NULL;
1589 }
1590 if (NULL != op->state->full_result_iter)
1591 {
1592 GNUNET_CONTAINER_multihashmap_iterator_destroy (
1593 op->state->full_result_iter);
1594 op->state->full_result_iter = NULL;
1595 }
1596 GNUNET_free (op->state);
1597 op->state = NULL;
1598 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1599 "Destroying intersection op state done\n");
1600 }
1601 if (NULL != set)
1602 {
1603 GNUNET_CONTAINER_DLL_remove (set->ops_head,
1604 set->ops_tail,
1605 op);
1606 op->set = NULL;
1607 }
1608 if (NULL != op->context_msg)
1609 {
1610 GNUNET_free (op->context_msg);
1611 op->context_msg = NULL;
1612 }
1613 if (NULL != (channel = op->channel))
1614 {
1615 /* This will free op; called conditionally as this helper function
1616 is also called from within the channel disconnect handler. */
1617 op->channel = NULL;
1618 GNUNET_CADET_channel_destroy (channel);
1619 }
1620 /* We rely on the channel end handler to free 'op'. When 'op->channel' was NULL,
1621 * there was a channel end handler that will free 'op' on the call stack. */
1622}
1623
1624
1625/**
1626 * Callback called when a client connects to the service. 1572 * Callback called when a client connects to the service.
1627 * 1573 *
1628 * @param cls closure for the service 1574 * @param cls closure for the service
@@ -1660,7 +1606,6 @@ destroy_elements_iterator (void *cls,
1660{ 1606{
1661 struct ElementEntry *ee = value; 1607 struct ElementEntry *ee = value;
1662 1608
1663 GNUNET_free (ee->mutations);
1664 GNUNET_free (ee); 1609 GNUNET_free (ee);
1665 return GNUNET_YES; 1610 return GNUNET_YES;
1666} 1611}
@@ -1691,19 +1636,7 @@ client_disconnect_cb (void *cls,
1691 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying client's set\n"); 1636 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying client's set\n");
1692 /* Destroy pending set operations */ 1637 /* Destroy pending set operations */
1693 while (NULL != set->ops_head) 1638 while (NULL != set->ops_head)
1694 _GSS_operation_destroy (set->ops_head, GNUNET_NO); 1639 _GSS_operation_destroy (set->ops_head);
1695
1696 /* Destroy operation-specific state */
1697 GNUNET_assert (NULL != set->state);
1698 GNUNET_free (set->state);
1699
1700 /* Clean up ongoing iterations */
1701 if (NULL != set->iter)
1702 {
1703 GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter);
1704 set->iter = NULL;
1705 set->iteration_id++;
1706 }
1707 1640
1708 /* free set content (or at least decrement RC) */ 1641 /* free set content (or at least decrement RC) */
1709 set->content = NULL; 1642 set->content = NULL;
@@ -1719,9 +1652,6 @@ client_disconnect_cb (void *cls,
1719 content->elements = NULL; 1652 content->elements = NULL;
1720 GNUNET_free (content); 1653 GNUNET_free (content);
1721 } 1654 }
1722 GNUNET_free (set->excluded_generations);
1723 set->excluded_generations = NULL;
1724
1725 GNUNET_free (set); 1655 GNUNET_free (set);
1726 } 1656 }
1727 1657
@@ -1777,20 +1707,14 @@ check_incoming_msg (void *cls,
1777 return GNUNET_SYSERR; 1707 return GNUNET_SYSERR;
1778 } 1708 }
1779 /* This should be equivalent to the previous condition, but can't hurt to check twice */ 1709 /* This should be equivalent to the previous condition, but can't hurt to check twice */
1780 if (NULL == op->listener) 1710 if (NULL == listener)
1781 { 1711 {
1782 GNUNET_break (0); 1712 GNUNET_break (0);
1783 return GNUNET_SYSERR; 1713 return GNUNET_SYSERR;
1784 } 1714 }
1785 if (listener->operation !=
1786 (enum GNUNET_SET_OperationType) ntohl (msg->operation))
1787 {
1788 GNUNET_break_op (0);
1789 return GNUNET_SYSERR;
1790 }
1791 nested_context = GNUNET_MQ_extract_nested_mh (msg); 1715 nested_context = GNUNET_MQ_extract_nested_mh (msg);
1792 if ((NULL != nested_context) && 1716 if ((NULL != nested_context) &&
1793 (ntohs (nested_context->size) > GNUNET_SET_CONTEXT_MESSAGE_MAX_SIZE)) 1717 (ntohs (nested_context->size) > GNUNET_SETI_CONTEXT_MESSAGE_MAX_SIZE))
1794 { 1718 {
1795 GNUNET_break_op (0); 1719 GNUNET_break_op (0);
1796 return GNUNET_SYSERR; 1720 return GNUNET_SYSERR;
@@ -1824,7 +1748,7 @@ handle_incoming_msg (void *cls,
1824 struct Listener *listener = op->listener; 1748 struct Listener *listener = op->listener;
1825 const struct GNUNET_MessageHeader *nested_context; 1749 const struct GNUNET_MessageHeader *nested_context;
1826 struct GNUNET_MQ_Envelope *env; 1750 struct GNUNET_MQ_Envelope *env;
1827 struct GNUNET_SET_RequestMessage *cmsg; 1751 struct GNUNET_SETI_RequestMessage *cmsg;
1828 1752
1829 nested_context = GNUNET_MQ_extract_nested_mh (msg); 1753 nested_context = GNUNET_MQ_extract_nested_mh (msg);
1830 /* Make a copy of the nested_context (application-specific context 1754 /* Make a copy of the nested_context (application-specific context
@@ -1835,8 +1759,7 @@ handle_incoming_msg (void *cls,
1835 op->remote_element_count = ntohl (msg->element_count); 1759 op->remote_element_count = ntohl (msg->element_count);
1836 GNUNET_log ( 1760 GNUNET_log (
1837 GNUNET_ERROR_TYPE_DEBUG, 1761 GNUNET_ERROR_TYPE_DEBUG,
1838 "Received P2P operation request (op %u, port %s) for active listener\n", 1762 "Received P2P operation request (port %s) for active listener\n",
1839 (uint32_t) ntohl (msg->operation),
1840 GNUNET_h2s (&op->listener->app_id)); 1763 GNUNET_h2s (&op->listener->app_id));
1841 GNUNET_assert (0 == op->suggest_id); 1764 GNUNET_assert (0 == op->suggest_id);
1842 if (0 == suggest_id) 1765 if (0 == suggest_id)
@@ -1863,110 +1786,6 @@ handle_incoming_msg (void *cls,
1863 1786
1864 1787
1865/** 1788/**
1866 * Send the next element of a set to the set's client. The next element is given by
1867 * the set's current hashmap iterator. The set's iterator will be set to NULL if there
1868 * are no more elements in the set. The caller must ensure that the set's iterator is
1869 * valid.
1870 *
1871 * The client will acknowledge each received element with a
1872 * #GNUNET_MESSAGE_TYPE_SETI_ITER_ACK message. Our
1873 * #handle_client_iter_ack() will then trigger the next transmission.
1874 * Note that the #GNUNET_MESSAGE_TYPE_SETI_ITER_DONE is not acknowledged.
1875 *
1876 * @param set set that should send its next element to its client
1877 */
1878static void
1879send_client_element (struct Set *set)
1880{
1881 int ret;
1882 struct ElementEntry *ee;
1883 struct GNUNET_MQ_Envelope *ev;
1884 struct GNUNET_SET_IterResponseMessage *msg;
1885
1886 GNUNET_assert (NULL != set->iter);
1887 do
1888 {
1889 ret = GNUNET_CONTAINER_multihashmap_iterator_next (set->iter,
1890 NULL,
1891 (const void **) &ee);
1892 if (GNUNET_NO == ret)
1893 {
1894 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration on %p done.\n", set);
1895 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SETI_ITER_DONE);
1896 GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter);
1897 set->iter = NULL;
1898 set->iteration_id++;
1899 GNUNET_assert (set->content->iterator_count > 0);
1900 set->content->iterator_count--;
1901 execute_delayed_mutations (set);
1902 GNUNET_MQ_send (set->cs->mq, ev);
1903 return;
1904 }
1905 GNUNET_assert (NULL != ee);
1906 }
1907 while (GNUNET_NO ==
1908 is_element_of_generation (ee,
1909 set->iter_generation,
1910 set->excluded_generations,
1911 set->excluded_generations_size));
1912 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1913 "Sending iteration element on %p.\n",
1914 set);
1915 ev = GNUNET_MQ_msg_extra (msg,
1916 ee->element.size,
1917 GNUNET_MESSAGE_TYPE_SETI_ITER_ELEMENT);
1918 GNUNET_memcpy (&msg[1], ee->element.data, ee->element.size);
1919 msg->element_type = htons (ee->element.element_type);
1920 msg->iteration_id = htons (set->iteration_id);
1921 GNUNET_MQ_send (set->cs->mq, ev);
1922}
1923
1924
1925/**
1926 * Called when a client wants to iterate the elements of a set.
1927 * Checks if we have a set associated with the client and if we
1928 * can right now start an iteration. If all checks out, starts
1929 * sending the elements of the set to the client.
1930 *
1931 * @param cls client that sent the message
1932 * @param m message sent by the client
1933 */
1934static void
1935handle_client_iterate (void *cls,
1936 const struct GNUNET_MessageHeader *m)
1937{
1938 struct ClientState *cs = cls;
1939 struct Set *set;
1940
1941 if (NULL == (set = cs->set))
1942 {
1943 /* attempt to iterate over a non existing set */
1944 GNUNET_break (0);
1945 GNUNET_SERVICE_client_drop (cs->client);
1946 return;
1947 }
1948 if (NULL != set->iter)
1949 {
1950 /* Only one concurrent iterate-action allowed per set */
1951 GNUNET_break (0);
1952 GNUNET_SERVICE_client_drop (cs->client);
1953 return;
1954 }
1955 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1956 "Iterating set %p in gen %u with %u content elements\n",
1957 (void *) set,
1958 set->current_generation,
1959 GNUNET_CONTAINER_multihashmap_size (set->content->elements));
1960 GNUNET_SERVICE_client_continue (cs->client);
1961 set->content->iterator_count++;
1962 set->iter =
1963 GNUNET_CONTAINER_multihashmap_iterator_create (set->content->elements);
1964 set->iter_generation = set->current_generation;
1965 send_client_element (set);
1966}
1967
1968
1969/**
1970 * Called when a client wants to create a new set. This is typically 1789 * Called when a client wants to create a new set. This is typically
1971 * the first request from a client, and includes the type of set 1790 * the first request from a client, and includes the type of set
1972 * operation to be performed. 1791 * operation to be performed.
@@ -1976,14 +1795,13 @@ handle_client_iterate (void *cls,
1976 */ 1795 */
1977static void 1796static void
1978handle_client_create_set (void *cls, 1797handle_client_create_set (void *cls,
1979 const struct GNUNET_SET_CreateMessage *msg) 1798 const struct GNUNET_SETI_CreateMessage *msg)
1980{ 1799{
1981 struct ClientState *cs = cls; 1800 struct ClientState *cs = cls;
1982 struct Set *set; 1801 struct Set *set;
1983 1802
1984 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1803 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1985 "Client created new set (operation %u)\n", 1804 "Client created new intersection set\n");
1986 (uint32_t) ntohl (msg->operation));
1987 if (NULL != cs->set) 1805 if (NULL != cs->set)
1988 { 1806 {
1989 /* There can only be one set per client */ 1807 /* There can only be one set per client */
@@ -1992,25 +1810,6 @@ handle_client_create_set (void *cls,
1992 return; 1810 return;
1993 } 1811 }
1994 set = GNUNET_new (struct Set); 1812 set = GNUNET_new (struct Set);
1995 {
1996 struct SetState *set_state;
1997
1998 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1999 "Intersection set created\n");
2000 set_state = GNUNET_new (struct SetState);
2001 set_state->current_set_element_count = 0;
2002
2003 set->state = set_state;
2004 }
2005
2006
2007 if (NULL == set->state)
2008 {
2009 /* initialization failed (i.e. out of memory) */
2010 GNUNET_free (set);
2011 GNUNET_SERVICE_client_drop (cs->client);
2012 return;
2013 }
2014 set->content = GNUNET_new (struct SetContent); 1813 set->content = GNUNET_new (struct SetContent);
2015 set->content->refcount = 1; 1814 set->content->refcount = 1;
2016 set->content->elements = GNUNET_CONTAINER_multihashmap_create (1, 1815 set->content->elements = GNUNET_CONTAINER_multihashmap_create (1,
@@ -2113,51 +1912,6 @@ channel_end_cb (void *channel_ctx,
2113 1912
2114 1913
2115/** 1914/**
2116 * This function probably should not exist
2117 * and be replaced by inlining more specific
2118 * logic in the various places where it is called.
2119 */
2120static void
2121_GSS_operation_destroy2 (struct Operation *op)
2122{
2123 struct GNUNET_CADET_Channel *channel;
2124
2125 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2126 "channel_end_cb called\n");
2127 if (NULL != (channel = op->channel))
2128 {
2129 /* This will free op; called conditionally as this helper function
2130 is also called from within the channel disconnect handler. */
2131 op->channel = NULL;
2132 GNUNET_CADET_channel_destroy (channel);
2133 }
2134 if (NULL != op->listener)
2135 {
2136 incoming_destroy (op);
2137 return;
2138 }
2139 if (NULL != op->set)
2140 {
2141 if (GNUNET_YES == op->state->channel_death_expected)
2142 {
2143 /* oh goodie, we are done! */
2144 send_client_done_and_destroy (op);
2145 }
2146 else
2147 {
2148 /* sorry, channel went down early, too bad. */
2149 _GSS_operation_destroy (op,
2150 GNUNET_YES);
2151 }
2152 }
2153 else
2154 _GSS_operation_destroy (op,
2155 GNUNET_YES);
2156 GNUNET_free (op);
2157}
2158
2159
2160/**
2161 * Function called whenever an MQ-channel's transmission window size changes. 1915 * Function called whenever an MQ-channel's transmission window size changes.
2162 * 1916 *
2163 * The first callback in an outgoing channel will be with a non-zero value 1917 * The first callback in an outgoing channel will be with a non-zero value
@@ -2188,11 +1942,11 @@ channel_window_cb (void *cls,
2188 */ 1942 */
2189static void 1943static void
2190handle_client_listen (void *cls, 1944handle_client_listen (void *cls,
2191 const struct GNUNET_SET_ListenMessage *msg) 1945 const struct GNUNET_SETI_ListenMessage *msg)
2192{ 1946{
2193 struct ClientState *cs = cls; 1947 struct ClientState *cs = cls;
2194 struct GNUNET_MQ_MessageHandler cadet_handlers[] = 1948 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
2195 { GNUNET_MQ_hd_var_size (incoming_msg, 1949 GNUNET_MQ_hd_var_size (incoming_msg,
2196 GNUNET_MESSAGE_TYPE_SETI_P2P_OPERATION_REQUEST, 1950 GNUNET_MESSAGE_TYPE_SETI_P2P_OPERATION_REQUEST,
2197 struct OperationRequestMessage, 1951 struct OperationRequestMessage,
2198 NULL), 1952 NULL),
@@ -2208,7 +1962,8 @@ handle_client_listen (void *cls,
2208 GNUNET_MESSAGE_TYPE_SETI_P2P_DONE, 1962 GNUNET_MESSAGE_TYPE_SETI_P2P_DONE,
2209 struct IntersectionDoneMessage, 1963 struct IntersectionDoneMessage,
2210 NULL), 1964 NULL),
2211 GNUNET_MQ_handler_end () }; 1965 GNUNET_MQ_handler_end ()
1966 };
2212 struct Listener *listener; 1967 struct Listener *listener;
2213 1968
2214 if (NULL != cs->listener) 1969 if (NULL != cs->listener)
@@ -2222,13 +1977,11 @@ handle_client_listen (void *cls,
2222 listener->cs = cs; 1977 listener->cs = cs;
2223 cs->listener = listener; 1978 cs->listener = listener;
2224 listener->app_id = msg->app_id; 1979 listener->app_id = msg->app_id;
2225 listener->operation = (enum GNUNET_SET_OperationType) ntohl (msg->operation);
2226 GNUNET_CONTAINER_DLL_insert (listener_head, 1980 GNUNET_CONTAINER_DLL_insert (listener_head,
2227 listener_tail, 1981 listener_tail,
2228 listener); 1982 listener);
2229 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1983 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2230 "New listener created (op %u, port %s)\n", 1984 "New listener for set intersection created (port %s)\n",
2231 listener->operation,
2232 GNUNET_h2s (&listener->app_id)); 1985 GNUNET_h2s (&listener->app_id));
2233 listener->open_port = GNUNET_CADET_open_port (cadet, 1986 listener->open_port = GNUNET_CADET_open_port (cadet,
2234 &msg->app_id, 1987 &msg->app_id,
@@ -2250,7 +2003,7 @@ handle_client_listen (void *cls,
2250 */ 2003 */
2251static void 2004static void
2252handle_client_reject (void *cls, 2005handle_client_reject (void *cls,
2253 const struct GNUNET_SET_RejectMessage *msg) 2006 const struct GNUNET_SETI_RejectMessage *msg)
2254{ 2007{
2255 struct ClientState *cs = cls; 2008 struct ClientState *cs = cls;
2256 struct Operation *op; 2009 struct Operation *op;
@@ -2267,8 +2020,7 @@ handle_client_reject (void *cls,
2267 return; 2020 return;
2268 } 2021 }
2269 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2022 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2270 "Peer request (op %u, app %s) rejected by client\n", 2023 "Peer request (app %s) rejected by client\n",
2271 op->listener->operation,
2272 GNUNET_h2s (&cs->listener->app_id)); 2024 GNUNET_h2s (&cs->listener->app_id));
2273 _GSS_operation_destroy2 (op); 2025 _GSS_operation_destroy2 (op);
2274 GNUNET_SERVICE_client_continue (cs->client); 2026 GNUNET_SERVICE_client_continue (cs->client);
@@ -2282,8 +2034,8 @@ handle_client_reject (void *cls,
2282 * @param msg message sent by the client 2034 * @param msg message sent by the client
2283 */ 2035 */
2284static int 2036static int
2285check_client_mutation (void *cls, 2037check_client_set_add (void *cls,
2286 const struct GNUNET_SET_ElementMessage *msg) 2038 const struct GNUNET_SETI_ElementMessage *msg)
2287{ 2039{
2288 /* NOTE: Technically, we should probably check with the 2040 /* NOTE: Technically, we should probably check with the
2289 block library whether the element we are given is well-formed */ 2041 block library whether the element we are given is well-formed */
@@ -2299,11 +2051,11 @@ check_client_mutation (void *cls,
2299 */ 2051 */
2300static void 2052static void
2301handle_client_set_add (void *cls, 2053handle_client_set_add (void *cls,
2302 const struct GNUNET_SET_ElementMessage *msg) 2054 const struct GNUNET_SETI_ElementMessage *msg)
2303{ 2055{
2304 struct ClientState *cs = cls; 2056 struct ClientState *cs = cls;
2305 struct Set *set; 2057 struct Set *set;
2306 struct GNUNET_SET_Element el; 2058 struct GNUNET_SETI_Element el;
2307 struct ElementEntry *ee; 2059 struct ElementEntry *ee;
2308 struct GNUNET_HashCode hash; 2060 struct GNUNET_HashCode hash;
2309 2061
@@ -2318,7 +2070,7 @@ handle_client_set_add (void *cls,
2318 el.size = ntohs (msg->header.size) - sizeof(*msg); 2070 el.size = ntohs (msg->header.size) - sizeof(*msg);
2319 el.data = &msg[1]; 2071 el.data = &msg[1];
2320 el.element_type = ntohs (msg->element_type); 2072 el.element_type = ntohs (msg->element_type);
2321 GNUNET_ISET_element_hash (&el, 2073 GNUNET_SETI_element_hash (&el,
2322 &hash); 2074 &hash);
2323 ee = GNUNET_CONTAINER_multihashmap_get (set->content->elements, 2075 ee = GNUNET_CONTAINER_multihashmap_get (set->content->elements,
2324 &hash); 2076 &hash);
@@ -2334,8 +2086,6 @@ handle_client_set_add (void *cls,
2334 ee->element.data = &ee[1]; 2086 ee->element.data = &ee[1];
2335 ee->element.element_type = el.element_type; 2087 ee->element.element_type = el.element_type;
2336 ee->remote = GNUNET_NO; 2088 ee->remote = GNUNET_NO;
2337 ee->mutations = NULL;
2338 ee->mutations_size = 0;
2339 ee->element_hash = hash; 2089 ee->element_hash = hash;
2340 GNUNET_break (GNUNET_YES == 2090 GNUNET_break (GNUNET_YES ==
2341 GNUNET_CONTAINER_multihashmap_put ( 2091 GNUNET_CONTAINER_multihashmap_put (
@@ -2353,7 +2103,7 @@ handle_client_set_add (void *cls,
2353 /* same element inserted twice */ 2103 /* same element inserted twice */
2354 return; 2104 return;
2355 } 2105 }
2356 set->state->current_set_element_count++; 2106 set->current_set_element_count++;
2357} 2107}
2358 2108
2359 2109
@@ -2387,7 +2137,7 @@ advance_generation (struct Set *set)
2387 */ 2137 */
2388static int 2138static int
2389check_client_evaluate (void *cls, 2139check_client_evaluate (void *cls,
2390 const struct GNUNET_SET_EvaluateMessage *msg) 2140 const struct GNUNET_SETI_EvaluateMessage *msg)
2391{ 2141{
2392 /* FIXME: suboptimal, even if the context below could be NULL, 2142 /* FIXME: suboptimal, even if the context below could be NULL,
2393 there are malformed messages this does not check for... */ 2143 there are malformed messages this does not check for... */
@@ -2405,7 +2155,7 @@ check_client_evaluate (void *cls,
2405 */ 2155 */
2406static void 2156static void
2407handle_client_evaluate (void *cls, 2157handle_client_evaluate (void *cls,
2408 const struct GNUNET_SET_EvaluateMessage *msg) 2158 const struct GNUNET_SETI_EvaluateMessage *msg)
2409{ 2159{
2410 struct ClientState *cs = cls; 2160 struct ClientState *cs = cls;
2411 struct Operation *op = GNUNET_new (struct Operation); 2161 struct Operation *op = GNUNET_new (struct Operation);
@@ -2441,12 +2191,7 @@ handle_client_evaluate (void *cls,
2441 op->salt = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 2191 op->salt = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
2442 UINT32_MAX); 2192 UINT32_MAX);
2443 op->peer = msg->target_peer; 2193 op->peer = msg->target_peer;
2444 op->result_mode = ntohl (msg->result_mode);
2445 op->client_request_id = ntohl (msg->request_id); 2194 op->client_request_id = ntohl (msg->request_id);
2446 op->byzantine = msg->byzantine;
2447 op->byzantine_lower_bound = msg->byzantine_lower_bound;
2448 op->force_full = msg->force_full;
2449 op->force_delta = msg->force_delta;
2450 context = GNUNET_MQ_extract_nested_mh (msg); 2195 context = GNUNET_MQ_extract_nested_mh (msg);
2451 2196
2452 /* Advance generation values, so that 2197 /* Advance generation values, so that
@@ -2458,9 +2203,8 @@ handle_client_evaluate (void *cls,
2458 set->ops_tail, 2203 set->ops_tail,
2459 op); 2204 op);
2460 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2205 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2461 "Creating new CADET channel to port %s for set operation type %u\n", 2206 "Creating new CADET channel to port %s for set intersection\n",
2462 GNUNET_h2s (&msg->app_id), 2207 GNUNET_h2s (&msg->app_id));
2463 set->operation);
2464 op->channel = GNUNET_CADET_channel_create (cadet, 2208 op->channel = GNUNET_CADET_channel_create (cadet,
2465 op, 2209 op,
2466 &msg->target_peer, 2210 &msg->target_peer,
@@ -2470,7 +2214,6 @@ handle_client_evaluate (void *cls,
2470 cadet_handlers); 2214 cadet_handlers);
2471 op->mq = GNUNET_CADET_get_mq (op->channel); 2215 op->mq = GNUNET_CADET_get_mq (op->channel);
2472 { 2216 {
2473 struct OperationState *state;
2474 struct GNUNET_MQ_Envelope *ev; 2217 struct GNUNET_MQ_Envelope *ev;
2475 struct OperationRequestMessage *msg; 2218 struct OperationRequestMessage *msg;
2476 2219
@@ -2486,25 +2229,23 @@ handle_client_evaluate (void *cls,
2486 } 2229 }
2487 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2230 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2488 "Initiating intersection operation evaluation\n"); 2231 "Initiating intersection operation evaluation\n");
2489 state = GNUNET_new (struct OperationState);
2490 /* we started the operation, thus we have to send the operation request */ 2232 /* we started the operation, thus we have to send the operation request */
2491 state->phase = PHASE_INITIAL; 2233 op->phase = PHASE_INITIAL;
2492 state->my_element_count = op->set->state->current_set_element_count; 2234 op->my_element_count = op->set->current_set_element_count;
2493 state->my_elements 2235 op->my_elements
2494 = GNUNET_CONTAINER_multihashmap_create (state->my_element_count, 2236 = GNUNET_CONTAINER_multihashmap_create (op->my_element_count,
2495 GNUNET_YES); 2237 GNUNET_YES);
2496 2238
2497 msg->element_count = htonl (state->my_element_count); 2239 msg->element_count = htonl (op->my_element_count);
2498 GNUNET_MQ_send (op->mq, 2240 GNUNET_MQ_send (op->mq,
2499 ev); 2241 ev);
2500 state->phase = PHASE_COUNT_SENT; 2242 op->phase = PHASE_COUNT_SENT;
2501 if (NULL != opaque_context) 2243 if (NULL != context)
2502 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2244 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2503 "Sent op request with context message\n"); 2245 "Sent op request with context message\n");
2504 else 2246 else
2505 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2247 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2506 "Sent op request without context message\n"); 2248 "Sent op request without context message\n");
2507 op->state = state;
2508 } 2249 }
2509 GNUNET_SERVICE_client_continue (cs->client); 2250 GNUNET_SERVICE_client_continue (cs->client);
2510} 2251}
@@ -2518,7 +2259,7 @@ handle_client_evaluate (void *cls,
2518 */ 2259 */
2519static void 2260static void
2520handle_client_cancel (void *cls, 2261handle_client_cancel (void *cls,
2521 const struct GNUNET_SET_CancelMessage *msg) 2262 const struct GNUNET_SETI_CancelMessage *msg)
2522{ 2263{
2523 struct ClientState *cs = cls; 2264 struct ClientState *cs = cls;
2524 struct Set *set; 2265 struct Set *set;
@@ -2557,7 +2298,7 @@ handle_client_cancel (void *cls,
2557 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2298 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2558 "Client requested cancel for op %u\n", 2299 "Client requested cancel for op %u\n",
2559 (uint32_t) ntohl (msg->request_id)); 2300 (uint32_t) ntohl (msg->request_id));
2560 _GSS_operation_destroy (op, GNUNET_YES); 2301 _GSS_operation_destroy (op);
2561 } 2302 }
2562 GNUNET_SERVICE_client_continue (cs->client); 2303 GNUNET_SERVICE_client_continue (cs->client);
2563} 2304}
@@ -2573,12 +2314,12 @@ handle_client_cancel (void *cls,
2573 */ 2314 */
2574static void 2315static void
2575handle_client_accept (void *cls, 2316handle_client_accept (void *cls,
2576 const struct GNUNET_SET_AcceptMessage *msg) 2317 const struct GNUNET_SETI_AcceptMessage *msg)
2577{ 2318{
2578 struct ClientState *cs = cls; 2319 struct ClientState *cs = cls;
2579 struct Set *set; 2320 struct Set *set;
2580 struct Operation *op; 2321 struct Operation *op;
2581 struct GNUNET_SET_ResultMessage *result_message; 2322 struct GNUNET_SETI_ResultMessage *result_message;
2582 struct GNUNET_MQ_Envelope *ev; 2323 struct GNUNET_MQ_Envelope *ev;
2583 struct Listener *listener; 2324 struct Listener *listener;
2584 2325
@@ -2603,7 +2344,7 @@ handle_client_accept (void *cls,
2603 ev = GNUNET_MQ_msg (result_message, 2344 ev = GNUNET_MQ_msg (result_message,
2604 GNUNET_MESSAGE_TYPE_SETI_RESULT); 2345 GNUNET_MESSAGE_TYPE_SETI_RESULT);
2605 result_message->request_id = msg->request_id; 2346 result_message->request_id = msg->request_id;
2606 result_message->result_status = htons (GNUNET_SET_STATUS_FAILURE); 2347 result_message->result_status = htons (GNUNET_SETI_STATUS_FAILURE);
2607 GNUNET_MQ_send (set->cs->mq, ev); 2348 GNUNET_MQ_send (set->cs->mq, ev);
2608 GNUNET_SERVICE_client_continue (cs->client); 2349 GNUNET_SERVICE_client_continue (cs->client);
2609 return; 2350 return;
@@ -2617,45 +2358,34 @@ handle_client_accept (void *cls,
2617 op->set = set; 2358 op->set = set;
2618 GNUNET_CONTAINER_DLL_insert (set->ops_head, set->ops_tail, op); 2359 GNUNET_CONTAINER_DLL_insert (set->ops_head, set->ops_tail, op);
2619 op->client_request_id = ntohl (msg->request_id); 2360 op->client_request_id = ntohl (msg->request_id);
2620 op->result_mode = ntohl (msg->result_mode);
2621 op->byzantine = msg->byzantine;
2622 op->byzantine_lower_bound = msg->byzantine_lower_bound;
2623 op->force_full = msg->force_full;
2624 op->force_delta = msg->force_delta;
2625 2361
2626 /* Advance generation values, so that future mutations do not 2362 /* Advance generation values, so that future mutations do not
2627 interfer with the running operation. */ 2363 interfer with the running operation. */
2628 op->generation_created = set->current_generation; 2364 op->generation_created = set->current_generation;
2629 advance_generation (set); 2365 advance_generation (set);
2630 GNUNET_assert (NULL == op->state);
2631 { 2366 {
2632 struct OperationState *state;
2633
2634 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2635 "Accepting set intersection operation\n"); 2368 "Accepting set intersection operation\n");
2636 state = GNUNET_new (struct OperationState); 2369 op->phase = PHASE_INITIAL;
2637 state->phase = PHASE_INITIAL; 2370 op->my_element_count
2638 state->my_element_count 2371 = op->set->current_set_element_count;
2639 = op->set->state->current_set_element_count; 2372 op->my_elements
2640 state->my_elements
2641 = GNUNET_CONTAINER_multihashmap_create ( 2373 = GNUNET_CONTAINER_multihashmap_create (
2642 GNUNET_MIN (state->my_element_count, 2374 GNUNET_MIN (op->my_element_count,
2643 op->remote_element_count), 2375 op->remote_element_count),
2644 GNUNET_YES); 2376 GNUNET_YES);
2645 op->state = state; 2377 if (op->remote_element_count < op->my_element_count)
2646 if (op->remote_element_count < state->my_element_count)
2647 { 2378 {
2648 /* If the other peer (Alice) has fewer elements than us (Bob), 2379 /* If the other peer (Alice) has fewer elements than us (Bob),
2649 we just send the count as Alice should send the first BF */ 2380 we just send the count as Alice should send the first BF */
2650 send_element_count (op); 2381 send_element_count (op);
2651 state->phase = PHASE_COUNT_SENT; 2382 op->phase = PHASE_COUNT_SENT;
2652 } 2383 }
2653 else 2384 else
2654 { 2385 {
2655 /* We have fewer elements, so we start with the BF */ 2386 /* We have fewer elements, so we start with the BF */
2656 begin_bf_exchange (op); 2387 begin_bf_exchange (op);
2657 } 2388 }
2658 op->state = state;
2659 } 2389 }
2660 /* Now allow CADET to continue, as we did not do this in 2390 /* Now allow CADET to continue, as we did not do this in
2661 #handle_incoming_msg (as we wanted to first see if the 2391 #handle_incoming_msg (as we wanted to first see if the
@@ -2733,31 +2463,31 @@ GNUNET_SERVICE_MAIN (
2733 NULL, 2463 NULL,
2734 GNUNET_MQ_hd_fixed_size (client_accept, 2464 GNUNET_MQ_hd_fixed_size (client_accept,
2735 GNUNET_MESSAGE_TYPE_SETI_ACCEPT, 2465 GNUNET_MESSAGE_TYPE_SETI_ACCEPT,
2736 struct GNUNET_SET_AcceptMessage, 2466 struct GNUNET_SETI_AcceptMessage,
2737 NULL), 2467 NULL),
2738 GNUNET_MQ_hd_var_size (client_set_add, 2468 GNUNET_MQ_hd_var_size (client_set_add,
2739 GNUNET_MESSAGE_TYPE_SETI_ADD, 2469 GNUNET_MESSAGE_TYPE_SETI_ADD,
2740 struct GNUNET_SET_ElementMessage, 2470 struct GNUNET_SETI_ElementMessage,
2741 NULL), 2471 NULL),
2742 GNUNET_MQ_hd_fixed_size (client_create_set, 2472 GNUNET_MQ_hd_fixed_size (client_create_set,
2743 GNUNET_MESSAGE_TYPE_SETI_CREATE, 2473 GNUNET_MESSAGE_TYPE_SETI_CREATE,
2744 struct GNUNET_SET_CreateMessage, 2474 struct GNUNET_SETI_CreateMessage,
2745 NULL), 2475 NULL),
2746 GNUNET_MQ_hd_var_size (client_evaluate, 2476 GNUNET_MQ_hd_var_size (client_evaluate,
2747 GNUNET_MESSAGE_TYPE_SETI_EVALUATE, 2477 GNUNET_MESSAGE_TYPE_SETI_EVALUATE,
2748 struct GNUNET_SET_EvaluateMessage, 2478 struct GNUNET_SETI_EvaluateMessage,
2749 NULL), 2479 NULL),
2750 GNUNET_MQ_hd_fixed_size (client_listen, 2480 GNUNET_MQ_hd_fixed_size (client_listen,
2751 GNUNET_MESSAGE_TYPE_SETI_LISTEN, 2481 GNUNET_MESSAGE_TYPE_SETI_LISTEN,
2752 struct GNUNET_SET_ListenMessage, 2482 struct GNUNET_SETI_ListenMessage,
2753 NULL), 2483 NULL),
2754 GNUNET_MQ_hd_fixed_size (client_reject, 2484 GNUNET_MQ_hd_fixed_size (client_reject,
2755 GNUNET_MESSAGE_TYPE_SETI_REJECT, 2485 GNUNET_MESSAGE_TYPE_SETI_REJECT,
2756 struct GNUNET_SET_RejectMessage, 2486 struct GNUNET_SETI_RejectMessage,
2757 NULL), 2487 NULL),
2758 GNUNET_MQ_hd_fixed_size (client_cancel, 2488 GNUNET_MQ_hd_fixed_size (client_cancel,
2759 GNUNET_MESSAGE_TYPE_SETI_CANCEL, 2489 GNUNET_MESSAGE_TYPE_SETI_CANCEL,
2760 struct GNUNET_SET_CancelMessage, 2490 struct GNUNET_SETI_CancelMessage,
2761 NULL), 2491 NULL),
2762 GNUNET_MQ_handler_end ()); 2492 GNUNET_MQ_handler_end ());
2763 2493