aboutsummaryrefslogtreecommitdiff
path: root/src/set/gnunet-service-set_intersection.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-03-11 18:15:38 +0100
committerChristian Grothoff <christian@grothoff.org>2017-03-11 18:15:38 +0100
commitabdec5e11ff11bb10d32c013e11344a54786f80f (patch)
treec2b8eb6705efa8ac8278a6024d8ab19222471f0e /src/set/gnunet-service-set_intersection.c
parent4e981fb2bd74f21c33adf05d7999b05704d6909b (diff)
downloadgnunet-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.c139
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 */
674int
675check_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 */
673static void 695void
674handle_p2p_bf (void *cls, 696handle_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
836begin_bf_exchange (struct Operation *op) 849begin_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 */
856static void 870void
857handle_p2p_element_info (void *cls, 871handle_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 */
958static void 971void
959handle_p2p_done (void *cls, 972handle_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 */
1093static int
1094intersection_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,