diff options
-rw-r--r-- | src/setu/gnunet-service-setu.c | 264 |
1 files changed, 109 insertions, 155 deletions
diff --git a/src/setu/gnunet-service-setu.c b/src/setu/gnunet-service-setu.c index c59d375cf..e61e1ab0c 100644 --- a/src/setu/gnunet-service-setu.c +++ b/src/setu/gnunet-service-setu.c | |||
@@ -122,16 +122,13 @@ enum UnionOperationPhase | |||
122 | PHASE_FINISH_CLOSING, | 122 | PHASE_FINISH_CLOSING, |
123 | 123 | ||
124 | /** | 124 | /** |
125 | * In the penultimate phase, | 125 | * In the penultimate phase, we wait until all our demands are satisfied. |
126 | * we wait until all our demands | 126 | * Then we send a done message, and wait for another done message. |
127 | * are satisfied. Then we send a done | ||
128 | * message, and wait for another done message. | ||
129 | */ | 127 | */ |
130 | PHASE_FINISH_WAITING, | 128 | PHASE_FINISH_WAITING, |
131 | 129 | ||
132 | /** | 130 | /** |
133 | * In the ultimate phase, we wait until | 131 | * In the ultimate phase, we wait until our demands are satisfied and then |
134 | * our demands are satisfied and then | ||
135 | * quit (sending another DONE message). | 132 | * quit (sending another DONE message). |
136 | */ | 133 | */ |
137 | PHASE_DONE, | 134 | PHASE_DONE, |
@@ -222,6 +219,18 @@ struct ClientState | |||
222 | */ | 219 | */ |
223 | struct Operation | 220 | struct Operation |
224 | { | 221 | { |
222 | |||
223 | /** | ||
224 | * The identity of the requesting peer. Needs to | ||
225 | * be stored here as the op spec might not have been created yet. | ||
226 | */ | ||
227 | struct GNUNET_PeerIdentity peer; | ||
228 | |||
229 | /** | ||
230 | * Initial size of our set, just before the operation started. | ||
231 | */ | ||
232 | uint64_t initial_size; | ||
233 | |||
225 | /** | 234 | /** |
226 | * Kept in a DLL of the listener, if @e listener is non-NULL. | 235 | * Kept in a DLL of the listener, if @e listener is non-NULL. |
227 | */ | 236 | */ |
@@ -282,6 +291,17 @@ struct Operation | |||
282 | struct GNUNET_CONTAINER_MultiHashMap32 *key_to_element; | 291 | struct GNUNET_CONTAINER_MultiHashMap32 *key_to_element; |
283 | 292 | ||
284 | /** | 293 | /** |
294 | * Timeout task, if the incoming peer has not been accepted | ||
295 | * after the timeout, it will be disconnected. | ||
296 | */ | ||
297 | struct GNUNET_SCHEDULER_Task *timeout_task; | ||
298 | |||
299 | /** | ||
300 | * Hashes for elements that we have demanded from the other peer. | ||
301 | */ | ||
302 | struct GNUNET_CONTAINER_MultiHashMap *demanded_hashes; | ||
303 | |||
304 | /** | ||
285 | * Current state of the operation. | 305 | * Current state of the operation. |
286 | */ | 306 | */ |
287 | enum UnionOperationPhase phase; | 307 | enum UnionOperationPhase phase; |
@@ -297,11 +317,6 @@ struct Operation | |||
297 | unsigned int ibf_buckets_received; | 317 | unsigned int ibf_buckets_received; |
298 | 318 | ||
299 | /** | 319 | /** |
300 | * Hashes for elements that we have demanded from the other peer. | ||
301 | */ | ||
302 | struct GNUNET_CONTAINER_MultiHashMap *demanded_hashes; | ||
303 | |||
304 | /** | ||
305 | * Salt that we're using for sending IBFs | 320 | * Salt that we're using for sending IBFs |
306 | */ | 321 | */ |
307 | uint32_t salt_send; | 322 | uint32_t salt_send; |
@@ -323,24 +338,6 @@ struct Operation | |||
323 | uint32_t received_total; | 338 | uint32_t received_total; |
324 | 339 | ||
325 | /** | 340 | /** |
326 | * Initial size of our set, just before | ||
327 | * the operation started. | ||
328 | */ | ||
329 | uint64_t initial_size; | ||
330 | |||
331 | /** | ||
332 | * The identity of the requesting peer. Needs to | ||
333 | * be stored here as the op spec might not have been created yet. | ||
334 | */ | ||
335 | struct GNUNET_PeerIdentity peer; | ||
336 | |||
337 | /** | ||
338 | * Timeout task, if the incoming peer has not been accepted | ||
339 | * after the timeout, it will be disconnected. | ||
340 | */ | ||
341 | struct GNUNET_SCHEDULER_Task *timeout_task; | ||
342 | |||
343 | /** | ||
344 | * Salt to use for the operation. | 341 | * Salt to use for the operation. |
345 | */ | 342 | */ |
346 | uint32_t salt; | 343 | uint32_t salt; |
@@ -450,10 +447,8 @@ struct Set | |||
450 | struct SetContent *content; | 447 | struct SetContent *content; |
451 | 448 | ||
452 | /** | 449 | /** |
453 | * The strata estimator is only generated once for | 450 | * The strata estimator is only generated once for each set. The IBF keys |
454 | * each set. | 451 | * are derived from the element hashes with salt=0. |
455 | * The IBF keys are derived from the element hashes with | ||
456 | * salt=0. | ||
457 | */ | 452 | */ |
458 | struct StrataEstimator *se; | 453 | struct StrataEstimator *se; |
459 | 454 | ||
@@ -495,10 +490,9 @@ struct KeyEntry | |||
495 | struct ElementEntry *element; | 490 | struct ElementEntry *element; |
496 | 491 | ||
497 | /** | 492 | /** |
498 | * Did we receive this element? | 493 | * Did we receive this element? Even if element->is_foreign is false, we |
499 | * Even if element->is_foreign is false, we might | 494 | * might have received the element, so this indicates that the other peer |
500 | * have received the element, so this indicates that | 495 | * has it. |
501 | * the other peer has it. | ||
502 | */ | 496 | */ |
503 | int received; | 497 | int received; |
504 | }; | 498 | }; |
@@ -607,10 +601,9 @@ static unsigned int num_clients; | |||
607 | static int in_shutdown; | 601 | static int in_shutdown; |
608 | 602 | ||
609 | /** | 603 | /** |
610 | * Counter for allocating unique IDs for clients, used to identify | 604 | * Counter for allocating unique IDs for clients, used to identify incoming |
611 | * incoming operation requests from remote peers, that the client can | 605 | * operation requests from remote peers, that the client can choose to accept |
612 | * choose to accept or refuse. 0 must not be used (reserved for | 606 | * or refuse. 0 must not be used (reserved for uninitialized). |
613 | * uninitialized). | ||
614 | */ | 607 | */ |
615 | static uint32_t suggest_id; | 608 | static uint32_t suggest_id; |
616 | 609 | ||
@@ -644,51 +637,6 @@ destroy_key_to_element_iter (void *cls, | |||
644 | 637 | ||
645 | 638 | ||
646 | /** | 639 | /** |
647 | * Destroy the union operation. Only things specific to the union | ||
648 | * operation are destroyed. | ||
649 | * | ||
650 | * @param op union operation to destroy | ||
651 | */ | ||
652 | static void | ||
653 | union_op_cancel (struct Operation *op) | ||
654 | { | ||
655 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
656 | "destroying union op\n"); | ||
657 | /* check if the op was canceled twice */ | ||
658 | if (NULL != op->remote_ibf) | ||
659 | { | ||
660 | ibf_destroy (op->remote_ibf); | ||
661 | op->remote_ibf = NULL; | ||
662 | } | ||
663 | if (NULL != op->demanded_hashes) | ||
664 | { | ||
665 | GNUNET_CONTAINER_multihashmap_destroy (op->demanded_hashes); | ||
666 | op->demanded_hashes = NULL; | ||
667 | } | ||
668 | if (NULL != op->local_ibf) | ||
669 | { | ||
670 | ibf_destroy (op->local_ibf); | ||
671 | op->local_ibf = NULL; | ||
672 | } | ||
673 | if (NULL != op->se) | ||
674 | { | ||
675 | strata_estimator_destroy (op->se); | ||
676 | op->se = NULL; | ||
677 | } | ||
678 | if (NULL != op->key_to_element) | ||
679 | { | ||
680 | GNUNET_CONTAINER_multihashmap32_iterate (op->key_to_element, | ||
681 | &destroy_key_to_element_iter, | ||
682 | NULL); | ||
683 | GNUNET_CONTAINER_multihashmap32_destroy (op->key_to_element); | ||
684 | op->key_to_element = NULL; | ||
685 | } | ||
686 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
687 | "destroying union op done\n"); | ||
688 | } | ||
689 | |||
690 | |||
691 | /** | ||
692 | * Signal to the client that the operation has finished and | 640 | * Signal to the client that the operation has finished and |
693 | * destroy the operation. | 641 | * destroy the operation. |
694 | * | 642 | * |
@@ -761,11 +709,38 @@ _GSS_operation_destroy (struct Operation *op) | |||
761 | struct GNUNET_CADET_Channel *channel; | 709 | struct GNUNET_CADET_Channel *channel; |
762 | 710 | ||
763 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 711 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
764 | "Destroying operation %p\n", | 712 | "Destroying union operation %p\n", |
765 | op); | 713 | op); |
766 | GNUNET_assert (NULL == op->listener); | 714 | GNUNET_assert (NULL == op->listener); |
767 | // FIXME: inline? | 715 | /* check if the op was canceled twice */ |
768 | union_op_cancel (op); | 716 | if (NULL != op->remote_ibf) |
717 | { | ||
718 | ibf_destroy (op->remote_ibf); | ||
719 | op->remote_ibf = NULL; | ||
720 | } | ||
721 | if (NULL != op->demanded_hashes) | ||
722 | { | ||
723 | GNUNET_CONTAINER_multihashmap_destroy (op->demanded_hashes); | ||
724 | op->demanded_hashes = NULL; | ||
725 | } | ||
726 | if (NULL != op->local_ibf) | ||
727 | { | ||
728 | ibf_destroy (op->local_ibf); | ||
729 | op->local_ibf = NULL; | ||
730 | } | ||
731 | if (NULL != op->se) | ||
732 | { | ||
733 | strata_estimator_destroy (op->se); | ||
734 | op->se = NULL; | ||
735 | } | ||
736 | if (NULL != op->key_to_element) | ||
737 | { | ||
738 | GNUNET_CONTAINER_multihashmap32_iterate (op->key_to_element, | ||
739 | &destroy_key_to_element_iter, | ||
740 | NULL); | ||
741 | GNUNET_CONTAINER_multihashmap32_destroy (op->key_to_element); | ||
742 | op->key_to_element = NULL; | ||
743 | } | ||
769 | if (NULL != set) | 744 | if (NULL != set) |
770 | { | 745 | { |
771 | GNUNET_CONTAINER_DLL_remove (set->ops_head, | 746 | GNUNET_CONTAINER_DLL_remove (set->ops_head, |
@@ -1128,8 +1103,7 @@ init_key_to_element_iterator (void *cls, | |||
1128 | 1103 | ||
1129 | 1104 | ||
1130 | /** | 1105 | /** |
1131 | * Initialize the IBF key to element mapping local to this set | 1106 | * Initialize the IBF key to element mapping local to this set operation. |
1132 | * operation. | ||
1133 | * | 1107 | * |
1134 | * @param op the set union operation | 1108 | * @param op the set union operation |
1135 | */ | 1109 | */ |
@@ -2594,62 +2568,6 @@ handle_union_p2p_over (void *cls, | |||
2594 | 2568 | ||
2595 | 2569 | ||
2596 | /** | 2570 | /** |
2597 | * Initiate operation to evaluate a set union with a remote peer. | ||
2598 | * | ||
2599 | * @param[in,out] op operation to perform (to be initialized) | ||
2600 | * @param opaque_context message to be transmitted to the listener | ||
2601 | * to convince it to accept, may be NULL | ||
2602 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure | ||
2603 | */ | ||
2604 | static int | ||
2605 | union_evaluate (struct Operation *op, | ||
2606 | const struct GNUNET_MessageHeader *opaque_context) | ||
2607 | { | ||
2608 | struct GNUNET_MQ_Envelope *ev; | ||
2609 | struct OperationRequestMessage *msg; | ||
2610 | |||
2611 | ev = GNUNET_MQ_msg_nested_mh (msg, | ||
2612 | GNUNET_MESSAGE_TYPE_SETU_P2P_OPERATION_REQUEST, | ||
2613 | opaque_context); | ||
2614 | if (NULL == ev) | ||
2615 | { | ||
2616 | /* the context message is too large */ | ||
2617 | GNUNET_break (0); | ||
2618 | return GNUNET_SYSERR; | ||
2619 | } | ||
2620 | op->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32, | ||
2621 | GNUNET_NO); | ||
2622 | /* copy the current generation's strata estimator for this operation */ | ||
2623 | op->se = strata_estimator_dup (op->set->se); | ||
2624 | /* we started the operation, thus we have to send the operation request */ | ||
2625 | op->phase = PHASE_EXPECT_SE; | ||
2626 | op->salt_receive = op->salt_send = 42; // FIXME????? | ||
2627 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2628 | "Initiating union operation evaluation\n"); | ||
2629 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
2630 | "# of total union operations", | ||
2631 | 1, | ||
2632 | GNUNET_NO); | ||
2633 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
2634 | "# of initiated union operations", | ||
2635 | 1, | ||
2636 | GNUNET_NO); | ||
2637 | GNUNET_MQ_send (op->mq, | ||
2638 | ev); | ||
2639 | |||
2640 | if (NULL != opaque_context) | ||
2641 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2642 | "sent op request with context message\n"); | ||
2643 | else | ||
2644 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2645 | "sent op request without context message\n"); | ||
2646 | initialize_key_to_element (op); | ||
2647 | op->initial_size = GNUNET_CONTAINER_multihashmap32_size (op->key_to_element); | ||
2648 | return GNUNET_OK; | ||
2649 | } | ||
2650 | |||
2651 | |||
2652 | /** | ||
2653 | * Get the incoming socket associated with the given id. | 2571 | * Get the incoming socket associated with the given id. |
2654 | * | 2572 | * |
2655 | * @param listener the listener to look in | 2573 | * @param listener the listener to look in |
@@ -3422,14 +3340,49 @@ handle_client_evaluate (void *cls, | |||
3422 | &channel_end_cb, | 3340 | &channel_end_cb, |
3423 | cadet_handlers); | 3341 | cadet_handlers); |
3424 | op->mq = GNUNET_CADET_get_mq (op->channel); | 3342 | op->mq = GNUNET_CADET_get_mq (op->channel); |
3425 | // FIXME: inline! | ||
3426 | if (GNUNET_OK != | ||
3427 | union_evaluate (op, | ||
3428 | context)) | ||
3429 | { | 3343 | { |
3430 | GNUNET_break (0); | 3344 | struct GNUNET_MQ_Envelope *ev; |
3431 | GNUNET_SERVICE_client_drop (cs->client); | 3345 | struct OperationRequestMessage *msg; |
3432 | return; | 3346 | |
3347 | ev = GNUNET_MQ_msg_nested_mh (msg, | ||
3348 | GNUNET_MESSAGE_TYPE_SETU_P2P_OPERATION_REQUEST, | ||
3349 | context); | ||
3350 | if (NULL == ev) | ||
3351 | { | ||
3352 | /* the context message is too large */ | ||
3353 | GNUNET_break (0); | ||
3354 | GNUNET_SERVICE_client_drop (cs->client); | ||
3355 | return; | ||
3356 | } | ||
3357 | op->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32, | ||
3358 | GNUNET_NO); | ||
3359 | /* copy the current generation's strata estimator for this operation */ | ||
3360 | op->se = strata_estimator_dup (op->set->se); | ||
3361 | /* we started the operation, thus we have to send the operation request */ | ||
3362 | op->phase = PHASE_EXPECT_SE; | ||
3363 | op->salt_receive = op->salt_send = 42; // FIXME????? | ||
3364 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3365 | "Initiating union operation evaluation\n"); | ||
3366 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
3367 | "# of total union operations", | ||
3368 | 1, | ||
3369 | GNUNET_NO); | ||
3370 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
3371 | "# of initiated union operations", | ||
3372 | 1, | ||
3373 | GNUNET_NO); | ||
3374 | GNUNET_MQ_send (op->mq, | ||
3375 | ev); | ||
3376 | if (NULL != context) | ||
3377 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3378 | "sent op request with context message\n"); | ||
3379 | else | ||
3380 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3381 | "sent op request without context message\n"); | ||
3382 | initialize_key_to_element (op); | ||
3383 | op->initial_size = GNUNET_CONTAINER_multihashmap32_size ( | ||
3384 | op->key_to_element); | ||
3385 | |||
3433 | } | 3386 | } |
3434 | GNUNET_SERVICE_client_continue (cs->client); | 3387 | GNUNET_SERVICE_client_continue (cs->client); |
3435 | } | 3388 | } |
@@ -3657,7 +3610,8 @@ run (void *cls, | |||
3657 | forcefully disconnected! */ | 3610 | forcefully disconnected! */ |
3658 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, | 3611 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, |
3659 | NULL); | 3612 | NULL); |
3660 | _GSS_statistics = GNUNET_STATISTICS_create ("setu", cfg); | 3613 | _GSS_statistics = GNUNET_STATISTICS_create ("setu", |
3614 | cfg); | ||
3661 | cadet = GNUNET_CADET_connect (cfg); | 3615 | cadet = GNUNET_CADET_connect (cfg); |
3662 | if (NULL == cadet) | 3616 | if (NULL == cadet) |
3663 | { | 3617 | { |