diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-03-11 18:15:38 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-03-11 18:15:38 +0100 |
commit | abdec5e11ff11bb10d32c013e11344a54786f80f (patch) | |
tree | c2b8eb6705efa8ac8278a6024d8ab19222471f0e /src/set/gnunet-service-set_intersection.c | |
parent | 4e981fb2bd74f21c33adf05d7999b05704d6909b (diff) | |
download | gnunet-abdec5e11ff11bb10d32c013e11344a54786f80f.tar.gz gnunet-abdec5e11ff11bb10d32c013e11344a54786f80f.zip |
cleaning up set handlers, eliminating 2nd level demultiplexing and improving use of types
Diffstat (limited to 'src/set/gnunet-service-set_intersection.c')
-rw-r--r-- | src/set/gnunet-service-set_intersection.c | 139 |
1 files changed, 59 insertions, 80 deletions
diff --git a/src/set/gnunet-service-set_intersection.c b/src/set/gnunet-service-set_intersection.c index 9fe1eabe6..b298f7b41 100644 --- a/src/set/gnunet-service-set_intersection.c +++ b/src/set/gnunet-service-set_intersection.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2013, 2014 GNUnet e.V. | 3 | Copyright (C) 2013-2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -28,6 +28,7 @@ | |||
28 | #include "gnunet-service-set.h" | 28 | #include "gnunet-service-set.h" |
29 | #include "gnunet_block_lib.h" | 29 | #include "gnunet_block_lib.h" |
30 | #include "gnunet-service-set_protocol.h" | 30 | #include "gnunet-service-set_protocol.h" |
31 | #include "gnunet-service-set_intersection.h" | ||
31 | #include <gcrypt.h> | 32 | #include <gcrypt.h> |
32 | 33 | ||
33 | 34 | ||
@@ -550,6 +551,8 @@ send_remaining_elements (void *cls) | |||
550 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 551 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
551 | "Sending done and destroy because iterator ran out\n"); | 552 | "Sending done and destroy because iterator ran out\n"); |
552 | op->keep--; | 553 | op->keep--; |
554 | GNUNET_CONTAINER_multihashmap_iterator_destroy (op->state->full_result_iter); | ||
555 | op->state->full_result_iter = NULL; | ||
553 | send_client_done_and_destroy (op); | 556 | send_client_done_and_destroy (op); |
554 | return; | 557 | return; |
555 | } | 558 | } |
@@ -627,9 +630,6 @@ process_bf (struct Operation *op) | |||
627 | case PHASE_COUNT_SENT: | 630 | case PHASE_COUNT_SENT: |
628 | /* This is the first BF being sent, build our initial map with | 631 | /* This is the first BF being sent, build our initial map with |
629 | filtering in place */ | 632 | filtering in place */ |
630 | op->state->my_elements | ||
631 | = GNUNET_CONTAINER_multihashmap_create (op->spec->remote_element_count, | ||
632 | GNUNET_YES); | ||
633 | op->state->my_element_count = 0; | 633 | op->state->my_element_count = 0; |
634 | GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements, | 634 | GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements, |
635 | &filtered_map_initialization, | 635 | &filtered_map_initialization, |
@@ -665,41 +665,53 @@ process_bf (struct Operation *op) | |||
665 | 665 | ||
666 | 666 | ||
667 | /** | 667 | /** |
668 | * Check an BF message from a remote peer. | ||
669 | * | ||
670 | * @param cls the intersection operation | ||
671 | * @param msg the header of the message | ||
672 | * @return #GNUNET_OK if @a msg is well-formed | ||
673 | */ | ||
674 | int | ||
675 | check_intersection_p2p_bf (void *cls, | ||
676 | const struct BFMessage *msg) | ||
677 | { | ||
678 | struct Operation *op = cls; | ||
679 | |||
680 | if (OT_INTERSECTION != op->type) | ||
681 | { | ||
682 | GNUNET_break_op (0); | ||
683 | return GNUNET_SYSERR; | ||
684 | } | ||
685 | return GNUNET_OK; | ||
686 | } | ||
687 | |||
688 | |||
689 | /** | ||
668 | * Handle an BF message from a remote peer. | 690 | * Handle an BF message from a remote peer. |
669 | * | 691 | * |
670 | * @param cls the intersection operation | 692 | * @param cls the intersection operation |
671 | * @param mh the header of the message | 693 | * @param msg the header of the message |
672 | */ | 694 | */ |
673 | static void | 695 | void |
674 | handle_p2p_bf (void *cls, | 696 | handle_intersection_p2p_bf (void *cls, |
675 | const struct GNUNET_MessageHeader *mh) | 697 | const struct BFMessage *msg) |
676 | { | 698 | { |
677 | struct Operation *op = cls; | 699 | struct Operation *op = cls; |
678 | const struct BFMessage *msg; | ||
679 | uint32_t bf_size; | 700 | uint32_t bf_size; |
680 | uint32_t chunk_size; | 701 | uint32_t chunk_size; |
681 | uint32_t bf_bits_per_element; | 702 | uint32_t bf_bits_per_element; |
682 | uint16_t msize; | ||
683 | 703 | ||
684 | msize = htons (mh->size); | ||
685 | if (msize < sizeof (struct BFMessage)) | ||
686 | { | ||
687 | GNUNET_break_op (0); | ||
688 | fail_intersection_operation (op); | ||
689 | return; | ||
690 | } | ||
691 | msg = (const struct BFMessage *) mh; | ||
692 | switch (op->state->phase) | 704 | switch (op->state->phase) |
693 | { | 705 | { |
694 | case PHASE_INITIAL: | 706 | case PHASE_INITIAL: |
695 | GNUNET_break_op (0); | 707 | GNUNET_break_op (0); |
696 | fail_intersection_operation (op); | 708 | fail_intersection_operation (op); |
697 | break; | 709 | return; |
698 | case PHASE_COUNT_SENT: | 710 | case PHASE_COUNT_SENT: |
699 | case PHASE_BF_EXCHANGE: | 711 | case PHASE_BF_EXCHANGE: |
700 | bf_size = ntohl (msg->bloomfilter_total_length); | 712 | bf_size = ntohl (msg->bloomfilter_total_length); |
701 | bf_bits_per_element = ntohl (msg->bits_per_element); | 713 | bf_bits_per_element = ntohl (msg->bits_per_element); |
702 | chunk_size = msize - sizeof (struct BFMessage); | 714 | chunk_size = htons (msg->header.size) - sizeof (struct BFMessage); |
703 | op->state->other_xor = msg->element_xor_hash; | 715 | op->state->other_xor = msg->element_xor_hash; |
704 | if (bf_size == chunk_size) | 716 | if (bf_size == chunk_size) |
705 | { | 717 | { |
@@ -717,7 +729,7 @@ handle_p2p_bf (void *cls, | |||
717 | op->state->salt = ntohl (msg->sender_mutator); | 729 | op->state->salt = ntohl (msg->sender_mutator); |
718 | op->spec->remote_element_count = ntohl (msg->sender_element_count); | 730 | op->spec->remote_element_count = ntohl (msg->sender_element_count); |
719 | process_bf (op); | 731 | process_bf (op); |
720 | return; | 732 | break; |
721 | } | 733 | } |
722 | /* multipart chunk */ | 734 | /* multipart chunk */ |
723 | if (NULL == op->state->bf_data) | 735 | if (NULL == op->state->bf_data) |
@@ -764,8 +776,9 @@ handle_p2p_bf (void *cls, | |||
764 | default: | 776 | default: |
765 | GNUNET_break_op (0); | 777 | GNUNET_break_op (0); |
766 | fail_intersection_operation (op); | 778 | fail_intersection_operation (op); |
767 | break; | 779 | return; |
768 | } | 780 | } |
781 | GNUNET_CADET_receive_done (op->channel); | ||
769 | } | 782 | } |
770 | 783 | ||
771 | 784 | ||
@@ -836,6 +849,7 @@ static void | |||
836 | begin_bf_exchange (struct Operation *op) | 849 | begin_bf_exchange (struct Operation *op) |
837 | { | 850 | { |
838 | op->state->phase = PHASE_BF_EXCHANGE; | 851 | op->state->phase = PHASE_BF_EXCHANGE; |
852 | GNUNET_assert (NULL == op->state->my_elements); | ||
839 | op->state->my_elements | 853 | op->state->my_elements |
840 | = GNUNET_CONTAINER_multihashmap_create (op->state->my_element_count, | 854 | = GNUNET_CONTAINER_multihashmap_create (op->state->my_element_count, |
841 | GNUNET_YES); | 855 | GNUNET_YES); |
@@ -853,20 +867,18 @@ begin_bf_exchange (struct Operation *op) | |||
853 | * @param cls the intersection operation | 867 | * @param cls the intersection operation |
854 | * @param mh the header of the message | 868 | * @param mh the header of the message |
855 | */ | 869 | */ |
856 | static void | 870 | void |
857 | handle_p2p_element_info (void *cls, | 871 | handle_intersection_p2p_element_info (void *cls, |
858 | const struct GNUNET_MessageHeader *mh) | 872 | const struct IntersectionElementInfoMessage *msg) |
859 | { | 873 | { |
860 | struct Operation *op = cls; | 874 | struct Operation *op = cls; |
861 | const struct IntersectionElementInfoMessage *msg; | ||
862 | 875 | ||
863 | if (ntohs (mh->size) != sizeof (struct IntersectionElementInfoMessage)) | 876 | if (OT_INTERSECTION != op->type) |
864 | { | 877 | { |
865 | GNUNET_break_op (0); | 878 | GNUNET_break_op (0); |
866 | fail_intersection_operation(op); | 879 | fail_intersection_operation(op); |
867 | return; | 880 | return; |
868 | } | 881 | } |
869 | msg = (const struct IntersectionElementInfoMessage *) mh; | ||
870 | op->spec->remote_element_count = ntohl (msg->sender_element_count); | 882 | op->spec->remote_element_count = ntohl (msg->sender_element_count); |
871 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 883 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
872 | "Received remote element count (%u), I have %u\n", | 884 | "Received remote element count (%u), I have %u\n", |
@@ -884,6 +896,7 @@ handle_p2p_element_info (void *cls, | |||
884 | } | 896 | } |
885 | GNUNET_break (NULL == op->state->remote_bf); | 897 | GNUNET_break (NULL == op->state->remote_bf); |
886 | begin_bf_exchange (op); | 898 | begin_bf_exchange (op); |
899 | GNUNET_CADET_receive_done (op->channel); | ||
887 | } | 900 | } |
888 | 901 | ||
889 | 902 | ||
@@ -955,28 +968,26 @@ filter_all (void *cls, | |||
955 | * @param cls the intersection operation | 968 | * @param cls the intersection operation |
956 | * @param mh the message | 969 | * @param mh the message |
957 | */ | 970 | */ |
958 | static void | 971 | void |
959 | handle_p2p_done (void *cls, | 972 | handle_intersection_p2p_done (void *cls, |
960 | const struct GNUNET_MessageHeader *mh) | 973 | const struct IntersectionDoneMessage *idm) |
961 | { | 974 | { |
962 | struct Operation *op = cls; | 975 | struct Operation *op = cls; |
963 | const struct IntersectionDoneMessage *idm; | ||
964 | 976 | ||
965 | if (PHASE_BF_EXCHANGE != op->state->phase) | 977 | if (OT_INTERSECTION != op->type) |
966 | { | 978 | { |
967 | /* wrong phase to conclude? FIXME: Or should we allow this | ||
968 | if the other peer has _initially_ already an empty set? */ | ||
969 | GNUNET_break_op (0); | 979 | GNUNET_break_op (0); |
970 | fail_intersection_operation (op); | 980 | fail_intersection_operation(op); |
971 | return; | 981 | return; |
972 | } | 982 | } |
973 | if (ntohs (mh->size) != sizeof (struct IntersectionDoneMessage)) | 983 | if (PHASE_BF_EXCHANGE != op->state->phase) |
974 | { | 984 | { |
985 | /* wrong phase to conclude? FIXME: Or should we allow this | ||
986 | if the other peer has _initially_ already an empty set? */ | ||
975 | GNUNET_break_op (0); | 987 | GNUNET_break_op (0); |
976 | fail_intersection_operation (op); | 988 | fail_intersection_operation (op); |
977 | return; | 989 | return; |
978 | } | 990 | } |
979 | idm = (const struct IntersectionDoneMessage *) mh; | ||
980 | if (0 == ntohl (idm->final_element_count)) | 991 | if (0 == ntohl (idm->final_element_count)) |
981 | { | 992 | { |
982 | /* other peer determined empty set is the intersection, | 993 | /* other peer determined empty set is the intersection, |
@@ -1000,6 +1011,7 @@ handle_p2p_done (void *cls, | |||
1000 | op->state->my_element_count); | 1011 | op->state->my_element_count); |
1001 | op->state->phase = PHASE_FINISHED; | 1012 | op->state->phase = PHASE_FINISHED; |
1002 | finish_and_destroy (op); | 1013 | finish_and_destroy (op); |
1014 | GNUNET_CADET_receive_done (op->channel); | ||
1003 | } | 1015 | } |
1004 | 1016 | ||
1005 | 1017 | ||
@@ -1064,11 +1076,11 @@ intersection_accept (struct Operation *op) | |||
1064 | op->state->phase = PHASE_INITIAL; | 1076 | op->state->phase = PHASE_INITIAL; |
1065 | op->state->my_element_count | 1077 | op->state->my_element_count |
1066 | = op->spec->set->state->current_set_element_count; | 1078 | = op->spec->set->state->current_set_element_count; |
1079 | GNUNET_assert (NULL == op->state->my_elements); | ||
1067 | op->state->my_elements | 1080 | op->state->my_elements |
1068 | = GNUNET_CONTAINER_multihashmap_create | 1081 | = GNUNET_CONTAINER_multihashmap_create (GNUNET_MIN (op->state->my_element_count, |
1069 | (GNUNET_MIN (op->state->my_element_count, | 1082 | op->spec->remote_element_count), |
1070 | op->spec->remote_element_count), | 1083 | GNUNET_YES); |
1071 | GNUNET_YES); | ||
1072 | if (op->spec->remote_element_count < op->state->my_element_count) | 1084 | if (op->spec->remote_element_count < op->state->my_element_count) |
1073 | { | 1085 | { |
1074 | /* If the other peer (Alice) has fewer elements than us (Bob), | 1086 | /* If the other peer (Alice) has fewer elements than us (Bob), |
@@ -1083,43 +1095,6 @@ intersection_accept (struct Operation *op) | |||
1083 | 1095 | ||
1084 | 1096 | ||
1085 | /** | 1097 | /** |
1086 | * Dispatch messages for a intersection operation. | ||
1087 | * | ||
1088 | * @param op the state of the intersection evaluate operation | ||
1089 | * @param mh the received message | ||
1090 | * @return #GNUNET_SYSERR if the tunnel should be disconnected, | ||
1091 | * #GNUNET_OK otherwise | ||
1092 | */ | ||
1093 | static int | ||
1094 | intersection_handle_p2p_message (struct Operation *op, | ||
1095 | const struct GNUNET_MessageHeader *mh) | ||
1096 | { | ||
1097 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1098 | "Received p2p message (t: %u, s: %u)\n", | ||
1099 | ntohs (mh->type), ntohs (mh->size)); | ||
1100 | switch (ntohs (mh->type)) | ||
1101 | { | ||
1102 | /* this message handler is not active until after we received an | ||
1103 | * operation request message, thus the ops request is not handled here | ||
1104 | */ | ||
1105 | case GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO: | ||
1106 | handle_p2p_element_info (op, mh); | ||
1107 | break; | ||
1108 | case GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF: | ||
1109 | handle_p2p_bf (op, mh); | ||
1110 | break; | ||
1111 | case GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE: | ||
1112 | handle_p2p_done (op, mh); | ||
1113 | break; | ||
1114 | default: | ||
1115 | /* something wrong with cadet's message handlers? */ | ||
1116 | GNUNET_assert (0); | ||
1117 | } | ||
1118 | return GNUNET_OK; | ||
1119 | } | ||
1120 | |||
1121 | |||
1122 | /** | ||
1123 | * Handler for peer-disconnects, notifies the client about the aborted | 1098 | * Handler for peer-disconnects, notifies the client about the aborted |
1124 | * operation. If we did not expect anything from the other peer, we | 1099 | * operation. If we did not expect anything from the other peer, we |
1125 | * gracefully terminate the operation. | 1100 | * gracefully terminate the operation. |
@@ -1168,6 +1143,11 @@ intersection_op_cancel (struct Operation *op) | |||
1168 | GNUNET_CONTAINER_multihashmap_destroy (op->state->my_elements); | 1143 | GNUNET_CONTAINER_multihashmap_destroy (op->state->my_elements); |
1169 | op->state->my_elements = NULL; | 1144 | op->state->my_elements = NULL; |
1170 | } | 1145 | } |
1146 | if (NULL != op->state->full_result_iter) | ||
1147 | { | ||
1148 | GNUNET_CONTAINER_multihashmap_iterator_destroy (op->state->full_result_iter); | ||
1149 | op->state->full_result_iter = NULL; | ||
1150 | } | ||
1171 | GNUNET_free (op->state); | 1151 | GNUNET_free (op->state); |
1172 | op->state = NULL; | 1152 | op->state = NULL; |
1173 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1153 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1245,7 +1225,6 @@ _GSS_intersection_vt () | |||
1245 | { | 1225 | { |
1246 | static const struct SetVT intersection_vt = { | 1226 | static const struct SetVT intersection_vt = { |
1247 | .create = &intersection_set_create, | 1227 | .create = &intersection_set_create, |
1248 | .msg_handler = &intersection_handle_p2p_message, | ||
1249 | .add = &intersection_add, | 1228 | .add = &intersection_add, |
1250 | .remove = &intersection_remove, | 1229 | .remove = &intersection_remove, |
1251 | .destroy_set = &intersection_set_destroy, | 1230 | .destroy_set = &intersection_set_destroy, |