diff options
Diffstat (limited to 'src/set')
-rw-r--r-- | src/set/Makefile.am | 16 | ||||
-rw-r--r-- | src/set/gnunet-service-set.c | 128 | ||||
-rw-r--r-- | src/set/gnunet-service-set.h | 24 | ||||
-rw-r--r-- | src/set/gnunet-service-set_protocol.h | 14 | ||||
-rw-r--r-- | src/set/gnunet-service-set_union.c | 482 | ||||
-rw-r--r-- | src/set/gnunet-set-profiler.c | 105 | ||||
-rw-r--r-- | src/set/plugin_block_set_test.c | 123 | ||||
-rw-r--r-- | src/set/set.h | 53 | ||||
-rw-r--r-- | src/set/set_api.c | 27 | ||||
-rw-r--r-- | src/set/test_set.conf | 1 | ||||
-rw-r--r-- | src/set/test_set_api.c | 5 | ||||
-rw-r--r-- | src/set/test_set_intersection_result_full.c | 4 | ||||
-rw-r--r-- | src/set/test_set_union_result_symmetric.c | 4 |
13 files changed, 881 insertions, 105 deletions
diff --git a/src/set/Makefile.am b/src/set/Makefile.am index 10f7ddc5d..cfe95bc1a 100644 --- a/src/set/Makefile.am +++ b/src/set/Makefile.am | |||
@@ -5,6 +5,8 @@ pkgcfgdir= $(pkgdatadir)/config.d/ | |||
5 | 5 | ||
6 | libexecdir= $(pkglibdir)/libexec/ | 6 | libexecdir= $(pkglibdir)/libexec/ |
7 | 7 | ||
8 | plugindir = $(libdir)/gnunet | ||
9 | |||
8 | pkgcfg_DATA = \ | 10 | pkgcfg_DATA = \ |
9 | set.conf | 11 | set.conf |
10 | 12 | ||
@@ -112,5 +114,19 @@ test_set_union_copy_LDADD = \ | |||
112 | $(top_builddir)/src/testing/libgnunettesting.la \ | 114 | $(top_builddir)/src/testing/libgnunettesting.la \ |
113 | libgnunetset.la | 115 | libgnunetset.la |
114 | 116 | ||
117 | plugin_LTLIBRARIES = \ | ||
118 | libgnunet_plugin_block_set_test.la | ||
119 | |||
120 | libgnunet_plugin_block_set_test_la_SOURCES = \ | ||
121 | plugin_block_set_test.c | ||
122 | libgnunet_plugin_block_set_test_la_LIBADD = \ | ||
123 | $(top_builddir)/src/block/libgnunetblock.la \ | ||
124 | $(top_builddir)/src/block/libgnunetblockgroup.la \ | ||
125 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
126 | $(LTLIBINTL) | ||
127 | libgnunet_plugin_block_set_test_la_LDFLAGS = \ | ||
128 | $(GN_PLUGIN_LDFLAGS) | ||
129 | |||
130 | |||
115 | EXTRA_DIST = \ | 131 | EXTRA_DIST = \ |
116 | test_set.conf | 132 | test_set.conf |
diff --git a/src/set/gnunet-service-set.c b/src/set/gnunet-service-set.c index a545e8a06..b0f8b2091 100644 --- a/src/set/gnunet-service-set.c +++ b/src/set/gnunet-service-set.c | |||
@@ -223,6 +223,9 @@ listener_destroy (struct Listener *listener) | |||
223 | { | 223 | { |
224 | struct GNUNET_SERVICE_Client *client = listener->client; | 224 | struct GNUNET_SERVICE_Client *client = listener->client; |
225 | 225 | ||
226 | GNUNET_MQ_destroy (listener->client_mq); | ||
227 | listener->client_mq = NULL; | ||
228 | |||
226 | listener->client = NULL; | 229 | listener->client = NULL; |
227 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 230 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
228 | "Disconnecting listener client\n"); | 231 | "Disconnecting listener client\n"); |
@@ -611,42 +614,6 @@ client_connect_cb (void *cls, | |||
611 | 614 | ||
612 | 615 | ||
613 | /** | 616 | /** |
614 | * Clean up after a client has disconnected | ||
615 | * | ||
616 | * @param cls closure, unused | ||
617 | * @param client the client to clean up after | ||
618 | * @param internal_cls our client-specific internal data structure | ||
619 | */ | ||
620 | static void | ||
621 | client_disconnect_cb (void *cls, | ||
622 | struct GNUNET_SERVICE_Client *client, | ||
623 | void *internal_cls) | ||
624 | { | ||
625 | struct Listener *listener; | ||
626 | struct Set *set; | ||
627 | |||
628 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
629 | "client disconnected, cleaning up\n"); | ||
630 | set = set_get (client); | ||
631 | if (NULL != set) | ||
632 | { | ||
633 | set->client = NULL; | ||
634 | set_destroy (set); | ||
635 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
636 | "Client's set destroyed\n"); | ||
637 | } | ||
638 | listener = listener_get (client); | ||
639 | if (NULL != listener) | ||
640 | { | ||
641 | listener->client = NULL; | ||
642 | listener_destroy (listener); | ||
643 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
644 | "Client's listener destroyed\n"); | ||
645 | } | ||
646 | } | ||
647 | |||
648 | |||
649 | /** | ||
650 | * Destroy an incoming request from a remote peer | 617 | * Destroy an incoming request from a remote peer |
651 | * | 618 | * |
652 | * @param incoming remote request to destroy | 619 | * @param incoming remote request to destroy |
@@ -681,6 +648,52 @@ incoming_destroy (struct Operation *incoming) | |||
681 | 648 | ||
682 | 649 | ||
683 | /** | 650 | /** |
651 | * Clean up after a client has disconnected | ||
652 | * | ||
653 | * @param cls closure, unused | ||
654 | * @param client the client to clean up after | ||
655 | * @param internal_cls our client-specific internal data structure | ||
656 | */ | ||
657 | static void | ||
658 | client_disconnect_cb (void *cls, | ||
659 | struct GNUNET_SERVICE_Client *client, | ||
660 | void *internal_cls) | ||
661 | { | ||
662 | struct Set *set; | ||
663 | |||
664 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
665 | "client disconnected, cleaning up\n"); | ||
666 | set = set_get (client); | ||
667 | if (NULL != set) | ||
668 | { | ||
669 | set->client = NULL; | ||
670 | set_destroy (set); | ||
671 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
672 | "Client's set destroyed\n"); | ||
673 | } | ||
674 | struct Listener *listener = listener_get (client); | ||
675 | struct Operation *op = incoming_head; | ||
676 | if (NULL != listener) | ||
677 | { | ||
678 | /* destroy all incoming operations whose client just | ||
679 | * got destroyed */ | ||
680 | while (NULL != op) | ||
681 | { | ||
682 | struct Operation *curr = op; | ||
683 | op = op->next; | ||
684 | if ( (GNUNET_YES == curr->is_incoming) && | ||
685 | (curr->listener == listener) ) | ||
686 | incoming_destroy (curr); | ||
687 | } | ||
688 | listener->client = NULL; | ||
689 | listener_destroy (listener); | ||
690 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
691 | "Client's listener destroyed\n"); | ||
692 | } | ||
693 | } | ||
694 | |||
695 | |||
696 | /** | ||
684 | * Suggest the given request to the listener. The listening client can | 697 | * Suggest the given request to the listener. The listening client can |
685 | * then accept or reject the remote request. | 698 | * then accept or reject the remote request. |
686 | * | 699 | * |
@@ -781,7 +794,7 @@ handle_incoming_msg (struct Operation *op, | |||
781 | listener = op->listener; | 794 | listener = op->listener; |
782 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 795 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
783 | "Received P2P operation request (op %u, port %s) for active listener\n", | 796 | "Received P2P operation request (op %u, port %s) for active listener\n", |
784 | ntohl (msg->operation), | 797 | (uint32_t) ntohl (msg->operation), |
785 | GNUNET_h2s (&listener->app_id)); | 798 | GNUNET_h2s (&listener->app_id)); |
786 | incoming_suggest (op, | 799 | incoming_suggest (op, |
787 | listener); | 800 | listener); |
@@ -1075,7 +1088,7 @@ handle_client_create_set (void *cls, | |||
1075 | 1088 | ||
1076 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1089 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1077 | "Client created new set (operation %u)\n", | 1090 | "Client created new set (operation %u)\n", |
1078 | ntohl (msg->operation)); | 1091 | (uint32_t) ntohl (msg->operation)); |
1079 | if (NULL != set_get (client)) | 1092 | if (NULL != set_get (client)) |
1080 | { | 1093 | { |
1081 | /* There can only be one set per client */ | 1094 | /* There can only be one set per client */ |
@@ -1371,6 +1384,14 @@ handle_client_listen (void *cls, | |||
1371 | struct GNUNET_MessageHeader, | 1384 | struct GNUNET_MessageHeader, |
1372 | NULL), | 1385 | NULL), |
1373 | GNUNET_MQ_hd_var_size (p2p_message, | 1386 | GNUNET_MQ_hd_var_size (p2p_message, |
1387 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE, | ||
1388 | struct GNUNET_MessageHeader, | ||
1389 | NULL), | ||
1390 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1391 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL, | ||
1392 | struct GNUNET_MessageHeader, | ||
1393 | NULL), | ||
1394 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1374 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE, | 1395 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE, |
1375 | struct GNUNET_MessageHeader, | 1396 | struct GNUNET_MessageHeader, |
1376 | NULL), | 1397 | NULL), |
@@ -1379,6 +1400,10 @@ handle_client_listen (void *cls, | |||
1379 | struct GNUNET_MessageHeader, | 1400 | struct GNUNET_MessageHeader, |
1380 | NULL), | 1401 | NULL), |
1381 | GNUNET_MQ_hd_var_size (p2p_message, | 1402 | GNUNET_MQ_hd_var_size (p2p_message, |
1403 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT, | ||
1404 | struct GNUNET_MessageHeader, | ||
1405 | NULL), | ||
1406 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1382 | GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO, | 1407 | GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO, |
1383 | struct GNUNET_MessageHeader, | 1408 | struct GNUNET_MessageHeader, |
1384 | NULL), | 1409 | NULL), |
@@ -1393,7 +1418,6 @@ handle_client_listen (void *cls, | |||
1393 | GNUNET_MQ_handler_end () | 1418 | GNUNET_MQ_handler_end () |
1394 | }; | 1419 | }; |
1395 | struct Listener *listener; | 1420 | struct Listener *listener; |
1396 | struct Operation *op; | ||
1397 | 1421 | ||
1398 | if (NULL != listener_get (client)) | 1422 | if (NULL != listener_get (client)) |
1399 | { | 1423 | { |
@@ -1422,7 +1446,7 @@ handle_client_listen (void *cls, | |||
1422 | &channel_end_cb, | 1446 | &channel_end_cb, |
1423 | cadet_handlers); | 1447 | cadet_handlers); |
1424 | /* check for existing incoming requests the listener might be interested in */ | 1448 | /* check for existing incoming requests the listener might be interested in */ |
1425 | for (op = incoming_head; NULL != op; op = op->next) | 1449 | for (struct Operation *op = incoming_head; NULL != op; op = op->next) |
1426 | { | 1450 | { |
1427 | if (NULL == op->spec) | 1451 | if (NULL == op->spec) |
1428 | continue; /* no details available yet */ | 1452 | continue; /* no details available yet */ |
@@ -1634,6 +1658,18 @@ handle_client_evaluate (void *cls, | |||
1634 | struct GNUNET_MessageHeader, | 1658 | struct GNUNET_MessageHeader, |
1635 | op), | 1659 | op), |
1636 | GNUNET_MQ_hd_var_size (p2p_message, | 1660 | GNUNET_MQ_hd_var_size (p2p_message, |
1661 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE, | ||
1662 | struct GNUNET_MessageHeader, | ||
1663 | op), | ||
1664 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1665 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL, | ||
1666 | struct GNUNET_MessageHeader, | ||
1667 | op), | ||
1668 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1669 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT, | ||
1670 | struct GNUNET_MessageHeader, | ||
1671 | op), | ||
1672 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1637 | GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO, | 1673 | GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO, |
1638 | struct GNUNET_MessageHeader, | 1674 | struct GNUNET_MessageHeader, |
1639 | op), | 1675 | op), |
@@ -1668,6 +1704,10 @@ handle_client_evaluate (void *cls, | |||
1668 | spec->set = set; | 1704 | spec->set = set; |
1669 | spec->result_mode = ntohl (msg->result_mode); | 1705 | spec->result_mode = ntohl (msg->result_mode); |
1670 | spec->client_request_id = ntohl (msg->request_id); | 1706 | spec->client_request_id = ntohl (msg->request_id); |
1707 | spec->byzantine = msg->byzantine; | ||
1708 | spec->byzantine_lower_bound = msg->byzantine_lower_bound; | ||
1709 | spec->force_full = msg->force_full; | ||
1710 | spec->force_delta = msg->force_delta; | ||
1671 | context = GNUNET_MQ_extract_nested_mh (msg); | 1711 | context = GNUNET_MQ_extract_nested_mh (msg); |
1672 | op->spec = spec; | 1712 | op->spec = spec; |
1673 | 1713 | ||
@@ -1918,7 +1958,7 @@ handle_client_cancel (void *cls, | |||
1918 | } | 1958 | } |
1919 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1959 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1920 | "Client requested cancel for op %u\n", | 1960 | "Client requested cancel for op %u\n", |
1921 | ntohl (msg->request_id)); | 1961 | (uint32_t) ntohl (msg->request_id)); |
1922 | found = GNUNET_NO; | 1962 | found = GNUNET_NO; |
1923 | for (op = set->ops_head; NULL != op; op = op->next) | 1963 | for (op = set->ops_head; NULL != op; op = op->next) |
1924 | { | 1964 | { |
@@ -1992,7 +2032,7 @@ handle_client_accept (void *cls, | |||
1992 | 2032 | ||
1993 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2033 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1994 | "Client accepting request %u\n", | 2034 | "Client accepting request %u\n", |
1995 | ntohl (msg->accept_reject_id)); | 2035 | (uint32_t) ntohl (msg->accept_reject_id)); |
1996 | GNUNET_assert (GNUNET_YES == op->is_incoming); | 2036 | GNUNET_assert (GNUNET_YES == op->is_incoming); |
1997 | op->is_incoming = GNUNET_NO; | 2037 | op->is_incoming = GNUNET_NO; |
1998 | GNUNET_CONTAINER_DLL_remove (incoming_head, | 2038 | GNUNET_CONTAINER_DLL_remove (incoming_head, |
@@ -2004,6 +2044,10 @@ handle_client_accept (void *cls, | |||
2004 | op); | 2044 | op); |
2005 | op->spec->client_request_id = ntohl (msg->request_id); | 2045 | op->spec->client_request_id = ntohl (msg->request_id); |
2006 | op->spec->result_mode = ntohl (msg->result_mode); | 2046 | op->spec->result_mode = ntohl (msg->result_mode); |
2047 | op->spec->byzantine = msg->byzantine; | ||
2048 | op->spec->byzantine_lower_bound = msg->byzantine_lower_bound; | ||
2049 | op->spec->force_full = msg->force_full; | ||
2050 | op->spec->force_delta = msg->force_delta; | ||
2007 | 2051 | ||
2008 | // Advance generation values, so that | 2052 | // Advance generation values, so that |
2009 | // mutations won't interfer with the running operation. | 2053 | // mutations won't interfer with the running operation. |
diff --git a/src/set/gnunet-service-set.h b/src/set/gnunet-service-set.h index 1460707fa..68d8fe81f 100644 --- a/src/set/gnunet-service-set.h +++ b/src/set/gnunet-service-set.h | |||
@@ -119,6 +119,30 @@ struct OperationSpecification | |||
119 | * When are elements sent to the client, and which elements are sent? | 119 | * When are elements sent to the client, and which elements are sent? |
120 | */ | 120 | */ |
121 | enum GNUNET_SET_ResultMode result_mode; | 121 | enum GNUNET_SET_ResultMode result_mode; |
122 | |||
123 | /** | ||
124 | * Always use delta operation instead of sending full sets, | ||
125 | * even it it's less efficient. | ||
126 | */ | ||
127 | int force_delta; | ||
128 | |||
129 | /** | ||
130 | * Always send full sets, even if delta operations would | ||
131 | * be more efficient. | ||
132 | */ | ||
133 | int force_full; | ||
134 | |||
135 | /** | ||
136 | * #GNUNET_YES to fail operations where Byzantine faults | ||
137 | * are suspected | ||
138 | */ | ||
139 | int byzantine; | ||
140 | |||
141 | /** | ||
142 | * Lower bound for the set size, used only when | ||
143 | * byzantine mode is enabled. | ||
144 | */ | ||
145 | int byzantine_lower_bound; | ||
122 | }; | 146 | }; |
123 | 147 | ||
124 | 148 | ||
diff --git a/src/set/gnunet-service-set_protocol.h b/src/set/gnunet-service-set_protocol.h index 748da15fc..0138b21c7 100644 --- a/src/set/gnunet-service-set_protocol.h +++ b/src/set/gnunet-service-set_protocol.h | |||
@@ -208,6 +208,20 @@ struct IntersectionDoneMessage | |||
208 | struct GNUNET_HashCode element_xor_hash; | 208 | struct GNUNET_HashCode element_xor_hash; |
209 | }; | 209 | }; |
210 | 210 | ||
211 | |||
212 | /** | ||
213 | * Strata estimator together with the peer's overall set size. | ||
214 | */ | ||
215 | struct StrataEstimatorMessage | ||
216 | { | ||
217 | /** | ||
218 | * Type: #GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE(C) | ||
219 | */ | ||
220 | struct GNUNET_MessageHeader header; | ||
221 | |||
222 | uint64_t set_size; | ||
223 | }; | ||
224 | |||
211 | GNUNET_NETWORK_STRUCT_END | 225 | GNUNET_NETWORK_STRUCT_END |
212 | 226 | ||
213 | #endif | 227 | #endif |
diff --git a/src/set/gnunet-service-set_union.c b/src/set/gnunet-service-set_union.c index acaabd94a..f46713c31 100644 --- a/src/set/gnunet-service-set_union.c +++ b/src/set/gnunet-service-set_union.c | |||
@@ -85,6 +85,7 @@ enum UnionOperationPhase | |||
85 | * upon initialization and later via #PHASE_EXPECT_ELEMENTS_AND_REQUESTS. | 85 | * upon initialization and later via #PHASE_EXPECT_ELEMENTS_AND_REQUESTS. |
86 | * | 86 | * |
87 | * XXX: could use better wording. | 87 | * XXX: could use better wording. |
88 | * XXX: repurposed to also expect a "request full set" message, should be renamed | ||
88 | * | 89 | * |
89 | * After receiving the complete IBF, we enter #PHASE_EXPECT_ELEMENTS | 90 | * After receiving the complete IBF, we enter #PHASE_EXPECT_ELEMENTS |
90 | */ | 91 | */ |
@@ -115,14 +116,22 @@ enum UnionOperationPhase | |||
115 | * In the penultimate phase, | 116 | * In the penultimate phase, |
116 | * we wait until all our demands | 117 | * we wait until all our demands |
117 | * are satisfied. Then we send a done | 118 | * are satisfied. Then we send a done |
118 | * message, and wait for another done message.*/ | 119 | * message, and wait for another done message. |
120 | */ | ||
119 | PHASE_FINISH_WAITING, | 121 | PHASE_FINISH_WAITING, |
120 | 122 | ||
121 | /** | 123 | /** |
122 | * In the ultimate phase, we wait until | 124 | * In the ultimate phase, we wait until |
123 | * our demands are satisfied and then | 125 | * our demands are satisfied and then |
124 | * quit (sending another DONE message). */ | 126 | * quit (sending another DONE message). |
125 | PHASE_DONE | 127 | */ |
128 | PHASE_DONE, | ||
129 | |||
130 | /** | ||
131 | * After sending the full set, wait for responses with the elements | ||
132 | * that the local peer is missing. | ||
133 | */ | ||
134 | PHASE_FULL_SENDING, | ||
126 | }; | 135 | }; |
127 | 136 | ||
128 | 137 | ||
@@ -148,7 +157,7 @@ struct OperationState | |||
148 | struct InvertibleBloomFilter *local_ibf; | 157 | struct InvertibleBloomFilter *local_ibf; |
149 | 158 | ||
150 | /** | 159 | /** |
151 | * Maps IBF-Keys (specific to the current salt) to elements. | 160 | * Maps unsalted IBF-Keys to elements. |
152 | * Used as a multihashmap, the keys being the lower 32bit of the IBF-Key. | 161 | * Used as a multihashmap, the keys being the lower 32bit of the IBF-Key. |
153 | * Colliding IBF-Keys are linked. | 162 | * Colliding IBF-Keys are linked. |
154 | */ | 163 | */ |
@@ -183,6 +192,23 @@ struct OperationState | |||
183 | * Salt for the IBF we've received and that we're currently decoding. | 192 | * Salt for the IBF we've received and that we're currently decoding. |
184 | */ | 193 | */ |
185 | uint32_t salt_receive; | 194 | uint32_t salt_receive; |
195 | |||
196 | /** | ||
197 | * Number of elements we received from the other peer | ||
198 | * that were not in the local set yet. | ||
199 | */ | ||
200 | uint32_t received_fresh; | ||
201 | |||
202 | /** | ||
203 | * Total number of elements received from the other peer. | ||
204 | */ | ||
205 | uint32_t received_total; | ||
206 | |||
207 | /** | ||
208 | * Initial size of our set, just before | ||
209 | * the operation started. | ||
210 | */ | ||
211 | uint64_t initial_size; | ||
186 | }; | 212 | }; |
187 | 213 | ||
188 | 214 | ||
@@ -203,6 +229,14 @@ struct KeyEntry | |||
203 | * is #GNUNET_YES. | 229 | * is #GNUNET_YES. |
204 | */ | 230 | */ |
205 | struct ElementEntry *element; | 231 | struct ElementEntry *element; |
232 | |||
233 | /** | ||
234 | * Did we receive this element? | ||
235 | * Even if element->is_foreign is false, we might | ||
236 | * have received the element, so this indicates that | ||
237 | * the other peer has it. | ||
238 | */ | ||
239 | int received; | ||
206 | }; | 240 | }; |
207 | 241 | ||
208 | 242 | ||
@@ -362,6 +396,16 @@ get_ibf_key (const struct GNUNET_HashCode *src) | |||
362 | 396 | ||
363 | 397 | ||
364 | /** | 398 | /** |
399 | * Context for #op_get_element_iterator | ||
400 | */ | ||
401 | struct GetElementContext | ||
402 | { | ||
403 | struct GNUNET_HashCode hash; | ||
404 | struct KeyEntry *k; | ||
405 | }; | ||
406 | |||
407 | |||
408 | /** | ||
365 | * Iterator over the mapping from IBF keys to element entries. Checks if we | 409 | * Iterator over the mapping from IBF keys to element entries. Checks if we |
366 | * have an element with a given GNUNET_HashCode. | 410 | * have an element with a given GNUNET_HashCode. |
367 | * | 411 | * |
@@ -372,17 +416,20 @@ get_ibf_key (const struct GNUNET_HashCode *src) | |||
372 | * #GNUNET_NO if we've found the element. | 416 | * #GNUNET_NO if we've found the element. |
373 | */ | 417 | */ |
374 | static int | 418 | static int |
375 | op_has_element_iterator (void *cls, | 419 | op_get_element_iterator (void *cls, |
376 | uint32_t key, | 420 | uint32_t key, |
377 | void *value) | 421 | void *value) |
378 | { | 422 | { |
379 | struct GNUNET_HashCode *element_hash = cls; | 423 | struct GetElementContext *ctx = cls; |
380 | struct KeyEntry *k = value; | 424 | struct KeyEntry *k = value; |
381 | 425 | ||
382 | GNUNET_assert (NULL != k); | 426 | GNUNET_assert (NULL != k); |
383 | if (0 == GNUNET_CRYPTO_hash_cmp (&k->element->element_hash, | 427 | if (0 == GNUNET_CRYPTO_hash_cmp (&k->element->element_hash, |
384 | element_hash)) | 428 | &ctx->hash)) |
429 | { | ||
430 | ctx->k = k; | ||
385 | return GNUNET_NO; | 431 | return GNUNET_NO; |
432 | } | ||
386 | return GNUNET_YES; | 433 | return GNUNET_YES; |
387 | } | 434 | } |
388 | 435 | ||
@@ -395,23 +442,29 @@ op_has_element_iterator (void *cls, | |||
395 | * @param element_hash hash of the element to look for | 442 | * @param element_hash hash of the element to look for |
396 | * @return #GNUNET_YES if the element has been found, #GNUNET_NO otherwise | 443 | * @return #GNUNET_YES if the element has been found, #GNUNET_NO otherwise |
397 | */ | 444 | */ |
398 | static int | 445 | static struct KeyEntry * |
399 | op_has_element (struct Operation *op, | 446 | op_get_element (struct Operation *op, |
400 | const struct GNUNET_HashCode *element_hash) | 447 | const struct GNUNET_HashCode *element_hash) |
401 | { | 448 | { |
402 | int ret; | 449 | int ret; |
403 | struct IBF_Key ibf_key; | 450 | struct IBF_Key ibf_key; |
451 | struct GetElementContext ctx = {{{ 0 }} , 0}; | ||
452 | |||
453 | ctx.hash = *element_hash; | ||
404 | 454 | ||
405 | ibf_key = get_ibf_key (element_hash); | 455 | ibf_key = get_ibf_key (element_hash); |
406 | ret = GNUNET_CONTAINER_multihashmap32_get_multiple (op->state->key_to_element, | 456 | ret = GNUNET_CONTAINER_multihashmap32_get_multiple (op->state->key_to_element, |
407 | (uint32_t) ibf_key.key_val, | 457 | (uint32_t) ibf_key.key_val, |
408 | op_has_element_iterator, | 458 | op_get_element_iterator, |
409 | (void *) element_hash); | 459 | &ctx); |
410 | 460 | ||
411 | /* was the iteration aborted because we found the element? */ | 461 | /* was the iteration aborted because we found the element? */ |
412 | if (GNUNET_SYSERR == ret) | 462 | if (GNUNET_SYSERR == ret) |
413 | return GNUNET_YES; | 463 | { |
414 | return GNUNET_NO; | 464 | GNUNET_assert (NULL != ctx.k); |
465 | return ctx.k; | ||
466 | } | ||
467 | return NULL; | ||
415 | } | 468 | } |
416 | 469 | ||
417 | 470 | ||
@@ -427,10 +480,12 @@ op_has_element (struct Operation *op, | |||
427 | * | 480 | * |
428 | * @param op the union operation | 481 | * @param op the union operation |
429 | * @param ee the element entry | 482 | * @param ee the element entry |
483 | * @parem received was this element received from the remote peer? | ||
430 | */ | 484 | */ |
431 | static void | 485 | static void |
432 | op_register_element (struct Operation *op, | 486 | op_register_element (struct Operation *op, |
433 | struct ElementEntry *ee) | 487 | struct ElementEntry *ee, |
488 | int received) | ||
434 | { | 489 | { |
435 | struct IBF_Key ibf_key; | 490 | struct IBF_Key ibf_key; |
436 | struct KeyEntry *k; | 491 | struct KeyEntry *k; |
@@ -439,6 +494,7 @@ op_register_element (struct Operation *op, | |||
439 | k = GNUNET_new (struct KeyEntry); | 494 | k = GNUNET_new (struct KeyEntry); |
440 | k->element = ee; | 495 | k->element = ee; |
441 | k->ibf_key = ibf_key; | 496 | k->ibf_key = ibf_key; |
497 | k->received = received; | ||
442 | GNUNET_assert (GNUNET_OK == | 498 | GNUNET_assert (GNUNET_OK == |
443 | GNUNET_CONTAINER_multihashmap32_put (op->state->key_to_element, | 499 | GNUNET_CONTAINER_multihashmap32_put (op->state->key_to_element, |
444 | (uint32_t) ibf_key.key_val, | 500 | (uint32_t) ibf_key.key_val, |
@@ -524,12 +580,30 @@ init_key_to_element_iterator (void *cls, | |||
524 | 580 | ||
525 | GNUNET_assert (GNUNET_NO == ee->remote); | 581 | GNUNET_assert (GNUNET_NO == ee->remote); |
526 | 582 | ||
527 | op_register_element (op, ee); | 583 | op_register_element (op, ee, GNUNET_NO); |
528 | return GNUNET_YES; | 584 | return GNUNET_YES; |
529 | } | 585 | } |
530 | 586 | ||
531 | 587 | ||
532 | /** | 588 | /** |
589 | * Initialize the IBF key to element mapping local to this set | ||
590 | * operation. | ||
591 | * | ||
592 | * @param op the set union operation | ||
593 | */ | ||
594 | static void | ||
595 | initialize_key_to_element (struct Operation *op) | ||
596 | { | ||
597 | unsigned int len; | ||
598 | |||
599 | GNUNET_assert (NULL == op->state->key_to_element); | ||
600 | len = GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements); | ||
601 | op->state->key_to_element = GNUNET_CONTAINER_multihashmap32_create (len + 1); | ||
602 | GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements, init_key_to_element_iterator, op); | ||
603 | } | ||
604 | |||
605 | |||
606 | /** | ||
533 | * Create an ibf with the operation's elements | 607 | * Create an ibf with the operation's elements |
534 | * of the specified size | 608 | * of the specified size |
535 | * | 609 | * |
@@ -541,15 +615,8 @@ static int | |||
541 | prepare_ibf (struct Operation *op, | 615 | prepare_ibf (struct Operation *op, |
542 | uint32_t size) | 616 | uint32_t size) |
543 | { | 617 | { |
544 | if (NULL == op->state->key_to_element) | 618 | GNUNET_assert (NULL != op->state->key_to_element); |
545 | { | ||
546 | unsigned int len; | ||
547 | 619 | ||
548 | len = GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements); | ||
549 | op->state->key_to_element = GNUNET_CONTAINER_multihashmap32_create (len + 1); | ||
550 | GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements, | ||
551 | init_key_to_element_iterator, op); | ||
552 | } | ||
553 | if (NULL != op->state->local_ibf) | 620 | if (NULL != op->state->local_ibf) |
554 | ibf_destroy (op->state->local_ibf); | 621 | ibf_destroy (op->state->local_ibf); |
555 | op->state->local_ibf = ibf_create (size, SE_IBF_HASH_NUM); | 622 | op->state->local_ibf = ibf_create (size, SE_IBF_HASH_NUM); |
@@ -648,7 +715,7 @@ send_strata_estimator (struct Operation *op) | |||
648 | { | 715 | { |
649 | const struct StrataEstimator *se = op->state->se; | 716 | const struct StrataEstimator *se = op->state->se; |
650 | struct GNUNET_MQ_Envelope *ev; | 717 | struct GNUNET_MQ_Envelope *ev; |
651 | struct GNUNET_MessageHeader *strata_msg; | 718 | struct StrataEstimatorMessage *strata_msg; |
652 | char *buf; | 719 | char *buf; |
653 | size_t len; | 720 | size_t len; |
654 | uint16_t type; | 721 | uint16_t type; |
@@ -660,13 +727,14 @@ send_strata_estimator (struct Operation *op) | |||
660 | type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC; | 727 | type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC; |
661 | else | 728 | else |
662 | type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE; | 729 | type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE; |
663 | ev = GNUNET_MQ_msg_header_extra (strata_msg, | 730 | ev = GNUNET_MQ_msg_extra (strata_msg, |
664 | len, | 731 | len, |
665 | type); | 732 | type); |
666 | GNUNET_memcpy (&strata_msg[1], | 733 | GNUNET_memcpy (&strata_msg[1], |
667 | buf, | 734 | buf, |
668 | len); | 735 | len); |
669 | GNUNET_free (buf); | 736 | GNUNET_free (buf); |
737 | strata_msg->set_size = GNUNET_htonll (GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements)); | ||
670 | GNUNET_MQ_send (op->mq, | 738 | GNUNET_MQ_send (op->mq, |
671 | ev); | 739 | ev); |
672 | op->state->phase = PHASE_EXPECT_IBF; | 740 | op->state->phase = PHASE_EXPECT_IBF; |
@@ -693,7 +761,51 @@ get_order_from_difference (unsigned int diff) | |||
693 | ibf_order++; | 761 | ibf_order++; |
694 | if (ibf_order > MAX_IBF_ORDER) | 762 | if (ibf_order > MAX_IBF_ORDER) |
695 | ibf_order = MAX_IBF_ORDER; | 763 | ibf_order = MAX_IBF_ORDER; |
696 | return ibf_order; | 764 | // add one for correction |
765 | return ibf_order + 1; | ||
766 | } | ||
767 | |||
768 | |||
769 | /** | ||
770 | * Send a set element. | ||
771 | * | ||
772 | * @param cls the union operation `struct Operation *` | ||
773 | * @param key unused | ||
774 | * @param value the `struct ElementEntry *` to insert | ||
775 | * into the key-to-element mapping | ||
776 | * @return #GNUNET_YES (to continue iterating) | ||
777 | */ | ||
778 | static int | ||
779 | send_element_iterator (void *cls, | ||
780 | const struct GNUNET_HashCode *key, | ||
781 | void *value) | ||
782 | { | ||
783 | struct Operation *op = cls; | ||
784 | struct GNUNET_SET_ElementMessage *emsg; | ||
785 | struct ElementEntry *ee = value; | ||
786 | struct GNUNET_SET_Element *el = &ee->element; | ||
787 | struct GNUNET_MQ_Envelope *ev; | ||
788 | |||
789 | |||
790 | ev = GNUNET_MQ_msg_extra (emsg, el->size, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT); | ||
791 | emsg->element_type = htons (el->element_type); | ||
792 | GNUNET_memcpy (&emsg[1], el->data, el->size); | ||
793 | GNUNET_MQ_send (op->mq, ev); | ||
794 | return GNUNET_YES; | ||
795 | } | ||
796 | |||
797 | |||
798 | static void | ||
799 | send_full_set (struct Operation *op) | ||
800 | { | ||
801 | struct GNUNET_MQ_Envelope *ev; | ||
802 | |||
803 | op->state->phase = PHASE_FULL_SENDING; | ||
804 | |||
805 | (void) GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements, | ||
806 | &send_element_iterator, op); | ||
807 | ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE); | ||
808 | GNUNET_MQ_send (op->mq, ev); | ||
697 | } | 809 | } |
698 | 810 | ||
699 | 811 | ||
@@ -713,7 +825,9 @@ handle_p2p_strata_estimator (void *cls, | |||
713 | { | 825 | { |
714 | struct Operation *op = cls; | 826 | struct Operation *op = cls; |
715 | struct StrataEstimator *remote_se; | 827 | struct StrataEstimator *remote_se; |
716 | int diff; | 828 | struct StrataEstimatorMessage *msg = (void *) mh; |
829 | unsigned int diff; | ||
830 | uint64_t other_size; | ||
717 | size_t len; | 831 | size_t len; |
718 | 832 | ||
719 | GNUNET_STATISTICS_update (_GSS_statistics, | 833 | GNUNET_STATISTICS_update (_GSS_statistics, |
@@ -723,11 +837,11 @@ handle_p2p_strata_estimator (void *cls, | |||
723 | 837 | ||
724 | if (op->state->phase != PHASE_EXPECT_SE) | 838 | if (op->state->phase != PHASE_EXPECT_SE) |
725 | { | 839 | { |
726 | fail_union_operation (op); | ||
727 | GNUNET_break (0); | 840 | GNUNET_break (0); |
841 | fail_union_operation (op); | ||
728 | return GNUNET_SYSERR; | 842 | return GNUNET_SYSERR; |
729 | } | 843 | } |
730 | len = ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader); | 844 | len = ntohs (mh->size) - sizeof (struct StrataEstimatorMessage); |
731 | if ( (GNUNET_NO == is_compressed) && | 845 | if ( (GNUNET_NO == is_compressed) && |
732 | (len != SE_STRATA_COUNT * SE_IBF_SIZE * IBF_BUCKET_SIZE) ) | 846 | (len != SE_STRATA_COUNT * SE_IBF_SIZE * IBF_BUCKET_SIZE) ) |
733 | { | 847 | { |
@@ -735,6 +849,7 @@ handle_p2p_strata_estimator (void *cls, | |||
735 | GNUNET_break (0); | 849 | GNUNET_break (0); |
736 | return GNUNET_SYSERR; | 850 | return GNUNET_SYSERR; |
737 | } | 851 | } |
852 | other_size = GNUNET_ntohll (msg->set_size); | ||
738 | remote_se = strata_estimator_create (SE_STRATA_COUNT, | 853 | remote_se = strata_estimator_create (SE_STRATA_COUNT, |
739 | SE_IBF_SIZE, | 854 | SE_IBF_SIZE, |
740 | SE_IBF_HASH_NUM); | 855 | SE_IBF_HASH_NUM); |
@@ -745,7 +860,7 @@ handle_p2p_strata_estimator (void *cls, | |||
745 | return GNUNET_SYSERR; | 860 | return GNUNET_SYSERR; |
746 | } | 861 | } |
747 | if (GNUNET_OK != | 862 | if (GNUNET_OK != |
748 | strata_estimator_read (&mh[1], | 863 | strata_estimator_read (&msg[1], |
749 | len, | 864 | len, |
750 | is_compressed, | 865 | is_compressed, |
751 | remote_se)) | 866 | remote_se)) |
@@ -758,6 +873,10 @@ handle_p2p_strata_estimator (void *cls, | |||
758 | GNUNET_assert (NULL != op->state->se); | 873 | GNUNET_assert (NULL != op->state->se); |
759 | diff = strata_estimator_difference (remote_se, | 874 | diff = strata_estimator_difference (remote_se, |
760 | op->state->se); | 875 | op->state->se); |
876 | |||
877 | if (diff > 200) | ||
878 | diff = diff * 3 / 2; | ||
879 | |||
761 | strata_estimator_destroy (remote_se); | 880 | strata_estimator_destroy (remote_se); |
762 | strata_estimator_destroy (op->state->se); | 881 | strata_estimator_destroy (op->state->se); |
763 | op->state->se = NULL; | 882 | op->state->se = NULL; |
@@ -765,16 +884,55 @@ handle_p2p_strata_estimator (void *cls, | |||
765 | "got se diff=%d, using ibf size %d\n", | 884 | "got se diff=%d, using ibf size %d\n", |
766 | diff, | 885 | diff, |
767 | 1<<get_order_from_difference (diff)); | 886 | 1<<get_order_from_difference (diff)); |
768 | if (GNUNET_OK != | 887 | |
769 | send_ibf (op, | 888 | if ((GNUNET_YES == op->spec->byzantine) && (other_size < op->spec->byzantine_lower_bound)) |
770 | get_order_from_difference (diff))) | ||
771 | { | 889 | { |
772 | /* Internal error, best we can do is shut the connection */ | 890 | GNUNET_break (0); |
773 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
774 | "Failed to send IBF, closing connection\n"); | ||
775 | fail_union_operation (op); | 891 | fail_union_operation (op); |
776 | return GNUNET_SYSERR; | 892 | return GNUNET_SYSERR; |
777 | } | 893 | } |
894 | |||
895 | |||
896 | if ( (GNUNET_YES == op->spec->force_full) || (diff > op->state->initial_size / 4)) | ||
897 | { | ||
898 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
899 | "Sending full set (diff=%d, own set=%u)\n", | ||
900 | diff, | ||
901 | op->state->initial_size); | ||
902 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
903 | "# of full sends", | ||
904 | 1, | ||
905 | GNUNET_NO); | ||
906 | if (op->state->initial_size <= other_size) | ||
907 | { | ||
908 | send_full_set (op); | ||
909 | } | ||
910 | else | ||
911 | { | ||
912 | struct GNUNET_MQ_Envelope *ev; | ||
913 | op->state->phase = PHASE_EXPECT_IBF; | ||
914 | ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL); | ||
915 | GNUNET_MQ_send (op->mq, ev); | ||
916 | } | ||
917 | } | ||
918 | else | ||
919 | { | ||
920 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
921 | "# of ibf sends", | ||
922 | 1, | ||
923 | GNUNET_NO); | ||
924 | if (GNUNET_OK != | ||
925 | send_ibf (op, | ||
926 | get_order_from_difference (diff))) | ||
927 | { | ||
928 | /* Internal error, best we can do is shut the connection */ | ||
929 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
930 | "Failed to send IBF, closing connection\n"); | ||
931 | fail_union_operation (op); | ||
932 | return GNUNET_SYSERR; | ||
933 | } | ||
934 | } | ||
935 | |||
778 | return GNUNET_OK; | 936 | return GNUNET_OK; |
779 | } | 937 | } |
780 | 938 | ||
@@ -1141,7 +1299,8 @@ send_client_element (struct Operation *op, | |||
1141 | } | 1299 | } |
1142 | rm->result_status = htons (status); | 1300 | rm->result_status = htons (status); |
1143 | rm->request_id = htonl (op->spec->client_request_id); | 1301 | rm->request_id = htonl (op->spec->client_request_id); |
1144 | rm->element_type = element->element_type; | 1302 | rm->element_type = htons (element->element_type); |
1303 | rm->current_size = GNUNET_htonll (GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element)); | ||
1145 | GNUNET_memcpy (&rm[1], element->data, element->size); | 1304 | GNUNET_memcpy (&rm[1], element->data, element->size); |
1146 | GNUNET_MQ_send (op->spec->set->client_mq, ev); | 1305 | GNUNET_MQ_send (op->spec->set->client_mq, ev); |
1147 | } | 1306 | } |
@@ -1164,6 +1323,7 @@ send_done_and_destroy (void *cls) | |||
1164 | rm->request_id = htonl (op->spec->client_request_id); | 1323 | rm->request_id = htonl (op->spec->client_request_id); |
1165 | rm->result_status = htons (GNUNET_SET_STATUS_DONE); | 1324 | rm->result_status = htons (GNUNET_SET_STATUS_DONE); |
1166 | rm->element_type = htons (0); | 1325 | rm->element_type = htons (0); |
1326 | rm->current_size = GNUNET_htonll (GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element)); | ||
1167 | GNUNET_MQ_send (op->spec->set->client_mq, ev); | 1327 | GNUNET_MQ_send (op->spec->set->client_mq, ev); |
1168 | /* Will also call the union-specific cancel function. */ | 1328 | /* Will also call the union-specific cancel function. */ |
1169 | _GSS_operation_destroy (op, GNUNET_YES); | 1329 | _GSS_operation_destroy (op, GNUNET_YES); |
@@ -1210,6 +1370,8 @@ maybe_finish (struct Operation *op) | |||
1210 | 1370 | ||
1211 | /** | 1371 | /** |
1212 | * Handle an element message from a remote peer. | 1372 | * Handle an element message from a remote peer. |
1373 | * Sent by the other peer either because we decoded an IBF and placed a demand, | ||
1374 | * or because the other peer switched to full set transmission. | ||
1213 | * | 1375 | * |
1214 | * @param cls the union operation | 1376 | * @param cls the union operation |
1215 | * @param mh the message | 1377 | * @param mh the message |
@@ -1273,7 +1435,11 @@ handle_p2p_elements (void *cls, | |||
1273 | 1, | 1435 | 1, |
1274 | GNUNET_NO); | 1436 | GNUNET_NO); |
1275 | 1437 | ||
1276 | if (GNUNET_YES == op_has_element (op, &ee->element_hash)) | 1438 | op->state->received_total += 1; |
1439 | |||
1440 | struct KeyEntry *ke = op_get_element (op, &ee->element_hash); | ||
1441 | |||
1442 | if (NULL != ke) | ||
1277 | { | 1443 | { |
1278 | /* Got repeated element. Should not happen since | 1444 | /* Got repeated element. Should not happen since |
1279 | * we track demands. */ | 1445 | * we track demands. */ |
@@ -1281,13 +1447,15 @@ handle_p2p_elements (void *cls, | |||
1281 | "# repeated elements", | 1447 | "# repeated elements", |
1282 | 1, | 1448 | 1, |
1283 | GNUNET_NO); | 1449 | GNUNET_NO); |
1450 | ke->received = GNUNET_YES; | ||
1284 | GNUNET_free (ee); | 1451 | GNUNET_free (ee); |
1285 | } | 1452 | } |
1286 | else | 1453 | else |
1287 | { | 1454 | { |
1288 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1455 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1289 | "Registering new element from remote peer\n"); | 1456 | "Registering new element from remote peer\n"); |
1290 | op_register_element (op, ee); | 1457 | op->state->received_fresh += 1; |
1458 | op_register_element (op, ee, GNUNET_YES); | ||
1291 | /* only send results immediately if the client wants it */ | 1459 | /* only send results immediately if the client wants it */ |
1292 | switch (op->spec->result_mode) | 1460 | switch (op->spec->result_mode) |
1293 | { | 1461 | { |
@@ -1304,11 +1472,118 @@ handle_p2p_elements (void *cls, | |||
1304 | } | 1472 | } |
1305 | } | 1473 | } |
1306 | 1474 | ||
1475 | if (op->state->received_total > 8 && op->state->received_fresh < op->state->received_total / 3) | ||
1476 | { | ||
1477 | /* The other peer gave us lots of old elements, there's something wrong. */ | ||
1478 | GNUNET_break_op (0); | ||
1479 | fail_union_operation (op); | ||
1480 | return; | ||
1481 | } | ||
1482 | |||
1307 | maybe_finish (op); | 1483 | maybe_finish (op); |
1308 | } | 1484 | } |
1309 | 1485 | ||
1310 | 1486 | ||
1311 | /** | 1487 | /** |
1488 | * Handle an element message from a remote peer. | ||
1489 | * | ||
1490 | * @param cls the union operation | ||
1491 | * @param mh the message | ||
1492 | */ | ||
1493 | static void | ||
1494 | handle_p2p_full_element (void *cls, | ||
1495 | const struct GNUNET_MessageHeader *mh) | ||
1496 | { | ||
1497 | struct Operation *op = cls; | ||
1498 | struct ElementEntry *ee; | ||
1499 | const struct GNUNET_SET_ElementMessage *emsg; | ||
1500 | uint16_t element_size; | ||
1501 | |||
1502 | if (ntohs (mh->size) < sizeof (struct GNUNET_SET_ElementMessage)) | ||
1503 | { | ||
1504 | GNUNET_break_op (0); | ||
1505 | fail_union_operation (op); | ||
1506 | return; | ||
1507 | } | ||
1508 | |||
1509 | emsg = (const struct GNUNET_SET_ElementMessage *) mh; | ||
1510 | |||
1511 | element_size = ntohs (mh->size) - sizeof (struct GNUNET_SET_ElementMessage); | ||
1512 | ee = GNUNET_malloc (sizeof (struct ElementEntry) + element_size); | ||
1513 | GNUNET_memcpy (&ee[1], &emsg[1], element_size); | ||
1514 | ee->element.size = element_size; | ||
1515 | ee->element.data = &ee[1]; | ||
1516 | ee->element.element_type = ntohs (emsg->element_type); | ||
1517 | ee->remote = GNUNET_YES; | ||
1518 | GNUNET_SET_element_hash (&ee->element, &ee->element_hash); | ||
1519 | |||
1520 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1521 | "Got element (full diff, size %u, hash %s) from peer\n", | ||
1522 | (unsigned int) element_size, | ||
1523 | GNUNET_h2s (&ee->element_hash)); | ||
1524 | |||
1525 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
1526 | "# received elements", | ||
1527 | 1, | ||
1528 | GNUNET_NO); | ||
1529 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
1530 | "# exchanged elements", | ||
1531 | 1, | ||
1532 | GNUNET_NO); | ||
1533 | |||
1534 | op->state->received_total += 1; | ||
1535 | |||
1536 | struct KeyEntry *ke = op_get_element (op, &ee->element_hash); | ||
1537 | |||
1538 | if (NULL != ke) | ||
1539 | { | ||
1540 | /* Got repeated element. Should not happen since | ||
1541 | * we track demands. */ | ||
1542 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
1543 | "# repeated elements", | ||
1544 | 1, | ||
1545 | GNUNET_NO); | ||
1546 | ke->received = GNUNET_YES; | ||
1547 | GNUNET_free (ee); | ||
1548 | } | ||
1549 | else | ||
1550 | { | ||
1551 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1552 | "Registering new element from remote peer\n"); | ||
1553 | op->state->received_fresh += 1; | ||
1554 | op_register_element (op, ee, GNUNET_YES); | ||
1555 | /* only send results immediately if the client wants it */ | ||
1556 | switch (op->spec->result_mode) | ||
1557 | { | ||
1558 | case GNUNET_SET_RESULT_ADDED: | ||
1559 | send_client_element (op, &ee->element, GNUNET_SET_STATUS_OK); | ||
1560 | break; | ||
1561 | case GNUNET_SET_RESULT_SYMMETRIC: | ||
1562 | send_client_element (op, &ee->element, GNUNET_SET_STATUS_ADD_LOCAL); | ||
1563 | break; | ||
1564 | default: | ||
1565 | /* Result mode not supported, should have been caught earlier. */ | ||
1566 | GNUNET_break (0); | ||
1567 | break; | ||
1568 | } | ||
1569 | } | ||
1570 | |||
1571 | if ( (GNUNET_YES == op->spec->byzantine) && | ||
1572 | (op->state->received_total > 384 + op->state->received_fresh * 4) && | ||
1573 | (op->state->received_fresh < op->state->received_total / 6) ) | ||
1574 | { | ||
1575 | /* The other peer gave us lots of old elements, there's something wrong. */ | ||
1576 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
1577 | "Other peer sent only %llu/%llu fresh elements, failing operation\n", | ||
1578 | (unsigned long long) op->state->received_fresh, | ||
1579 | (unsigned long long) op->state->received_total); | ||
1580 | GNUNET_break_op (0); | ||
1581 | fail_union_operation (op); | ||
1582 | return; | ||
1583 | } | ||
1584 | } | ||
1585 | |||
1586 | /** | ||
1312 | * Send offers (for GNUNET_Hash-es) in response | 1587 | * Send offers (for GNUNET_Hash-es) in response |
1313 | * to inquiries (for IBF_Key-s). | 1588 | * to inquiries (for IBF_Key-s). |
1314 | * | 1589 | * |
@@ -1355,7 +1630,116 @@ handle_p2p_inquiry (void *cls, | |||
1355 | 1630 | ||
1356 | 1631 | ||
1357 | /** | 1632 | /** |
1358 | * FIXME | 1633 | * Iterator over hash map entries, called to |
1634 | * destroy the linked list of colliding ibf key entries. | ||
1635 | * | ||
1636 | * @param cls closure | ||
1637 | * @param key current key code | ||
1638 | * @param value value in the hash map | ||
1639 | * @return #GNUNET_YES if we should continue to iterate, | ||
1640 | * #GNUNET_NO if not. | ||
1641 | */ | ||
1642 | static int | ||
1643 | send_missing_elements_iter (void *cls, | ||
1644 | uint32_t key, | ||
1645 | void *value) | ||
1646 | { | ||
1647 | struct Operation *op = cls; | ||
1648 | struct KeyEntry *ke = value; | ||
1649 | struct GNUNET_MQ_Envelope *ev; | ||
1650 | struct GNUNET_SET_ElementMessage *emsg; | ||
1651 | struct ElementEntry *ee = ke->element; | ||
1652 | |||
1653 | if (GNUNET_YES == ke->received) | ||
1654 | return GNUNET_YES; | ||
1655 | |||
1656 | ev = GNUNET_MQ_msg_extra (emsg, ee->element.size, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT); | ||
1657 | GNUNET_memcpy (&emsg[1], ee->element.data, ee->element.size); | ||
1658 | emsg->reserved = htons (0); | ||
1659 | emsg->element_type = htons (ee->element.element_type); | ||
1660 | GNUNET_MQ_send (op->mq, ev); | ||
1661 | |||
1662 | return GNUNET_YES; | ||
1663 | } | ||
1664 | |||
1665 | |||
1666 | /** | ||
1667 | * Handle a | ||
1668 | * | ||
1669 | * @parem cls closure, a set union operation | ||
1670 | * @param mh the demand message | ||
1671 | */ | ||
1672 | static void | ||
1673 | handle_p2p_request_full (void *cls, | ||
1674 | const struct GNUNET_MessageHeader *mh) | ||
1675 | { | ||
1676 | struct Operation *op = cls; | ||
1677 | |||
1678 | if (PHASE_EXPECT_IBF != op->state->phase) | ||
1679 | { | ||
1680 | fail_union_operation (op); | ||
1681 | GNUNET_break_op (0); | ||
1682 | return; | ||
1683 | } | ||
1684 | |||
1685 | // FIXME: we need to check that our set is larger than the | ||
1686 | // byzantine_lower_bound by some threshold | ||
1687 | send_full_set (op); | ||
1688 | } | ||
1689 | |||
1690 | |||
1691 | /** | ||
1692 | * Handle a "full done" message. | ||
1693 | * | ||
1694 | * @parem cls closure, a set union operation | ||
1695 | * @param mh the demand message | ||
1696 | */ | ||
1697 | static void | ||
1698 | handle_p2p_full_done (void *cls, | ||
1699 | const struct GNUNET_MessageHeader *mh) | ||
1700 | { | ||
1701 | struct Operation *op = cls; | ||
1702 | |||
1703 | if (PHASE_EXPECT_IBF == op->state->phase) | ||
1704 | { | ||
1705 | struct GNUNET_MQ_Envelope *ev; | ||
1706 | |||
1707 | LOG (GNUNET_ERROR_TYPE_DEBUG, "got FULL DONE, sending elements that other peer is missing\n"); | ||
1708 | |||
1709 | /* send all the elements that did not come from the remote peer */ | ||
1710 | GNUNET_CONTAINER_multihashmap32_iterate (op->state->key_to_element, | ||
1711 | &send_missing_elements_iter, | ||
1712 | op); | ||
1713 | |||
1714 | ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE); | ||
1715 | GNUNET_MQ_send (op->mq, ev); | ||
1716 | op->state->phase = PHASE_DONE; | ||
1717 | |||
1718 | /* we now wait until the other peer shuts the tunnel down*/ | ||
1719 | } | ||
1720 | else if (PHASE_FULL_SENDING == op->state->phase) | ||
1721 | { | ||
1722 | LOG (GNUNET_ERROR_TYPE_DEBUG, "got FULL DONE, finishing\n"); | ||
1723 | /* We sent the full set, and got the response for that. We're done. */ | ||
1724 | op->state->phase = PHASE_DONE; | ||
1725 | send_done_and_destroy (op); | ||
1726 | } | ||
1727 | else | ||
1728 | { | ||
1729 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "handle full done phase is %u\n", (unsigned) op->state->phase); | ||
1730 | GNUNET_break_op (0); | ||
1731 | fail_union_operation (op); | ||
1732 | return; | ||
1733 | } | ||
1734 | } | ||
1735 | |||
1736 | |||
1737 | /** | ||
1738 | * Handle a demand by the other peer for elements based on a list | ||
1739 | * of GNUNET_HashCode-s. | ||
1740 | * | ||
1741 | * @parem cls closure, a set union operation | ||
1742 | * @param mh the demand message | ||
1359 | */ | 1743 | */ |
1360 | static void | 1744 | static void |
1361 | handle_p2p_demand (void *cls, | 1745 | handle_p2p_demand (void *cls, |
@@ -1607,6 +1991,9 @@ union_evaluate (struct Operation *op, | |||
1607 | else | 1991 | else |
1608 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1992 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1609 | "sent op request without context message\n"); | 1993 | "sent op request without context message\n"); |
1994 | |||
1995 | initialize_key_to_element (op); | ||
1996 | op->state->initial_size = GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element); | ||
1610 | } | 1997 | } |
1611 | 1998 | ||
1612 | 1999 | ||
@@ -1636,6 +2023,8 @@ union_accept (struct Operation *op) | |||
1636 | op->state->se = strata_estimator_dup (op->spec->set->state->se); | 2023 | op->state->se = strata_estimator_dup (op->spec->set->state->se); |
1637 | op->state->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); | 2024 | op->state->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); |
1638 | op->state->salt_receive = op->state->salt_send = 42; | 2025 | op->state->salt_receive = op->state->salt_send = 42; |
2026 | initialize_key_to_element (op); | ||
2027 | op->state->initial_size = GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element); | ||
1639 | /* kick off the operation */ | 2028 | /* kick off the operation */ |
1640 | send_strata_estimator (op); | 2029 | send_strata_estimator (op); |
1641 | } | 2030 | } |
@@ -1743,6 +2132,9 @@ union_handle_p2p_message (struct Operation *op, | |||
1743 | case GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS: | 2132 | case GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS: |
1744 | handle_p2p_elements (op, mh); | 2133 | handle_p2p_elements (op, mh); |
1745 | break; | 2134 | break; |
2135 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT: | ||
2136 | handle_p2p_full_element (op, mh); | ||
2137 | break; | ||
1746 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_INQUIRY: | 2138 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_INQUIRY: |
1747 | handle_p2p_inquiry (op, mh); | 2139 | handle_p2p_inquiry (op, mh); |
1748 | break; | 2140 | break; |
@@ -1755,6 +2147,12 @@ union_handle_p2p_message (struct Operation *op, | |||
1755 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND: | 2147 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND: |
1756 | handle_p2p_demand (op, mh); | 2148 | handle_p2p_demand (op, mh); |
1757 | break; | 2149 | break; |
2150 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE: | ||
2151 | handle_p2p_full_done (op, mh); | ||
2152 | break; | ||
2153 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL: | ||
2154 | handle_p2p_request_full (op, mh); | ||
2155 | break; | ||
1758 | default: | 2156 | default: |
1759 | /* Something wrong with cadet's message handlers? */ | 2157 | /* Something wrong with cadet's message handlers? */ |
1760 | GNUNET_assert (0); | 2158 | GNUNET_assert (0); |
diff --git a/src/set/gnunet-set-profiler.c b/src/set/gnunet-set-profiler.c index f89817ff5..8404b191c 100644 --- a/src/set/gnunet-set-profiler.c +++ b/src/set/gnunet-set-profiler.c | |||
@@ -58,6 +58,11 @@ static struct GNUNET_PeerIdentity local_peer; | |||
58 | 58 | ||
59 | static struct GNUNET_SET_ListenHandle *set_listener; | 59 | static struct GNUNET_SET_ListenHandle *set_listener; |
60 | 60 | ||
61 | static int byzantine; | ||
62 | static int force_delta; | ||
63 | static int force_full; | ||
64 | static unsigned int element_size = 32; | ||
65 | |||
61 | /** | 66 | /** |
62 | * Handle to the statistics service. | 67 | * Handle to the statistics service. |
63 | */ | 68 | */ |
@@ -86,7 +91,7 @@ map_remove_iterator (void *cls, | |||
86 | 91 | ||
87 | GNUNET_assert (NULL != key); | 92 | GNUNET_assert (NULL != key); |
88 | 93 | ||
89 | ret = GNUNET_CONTAINER_multihashmap_remove (m, key, NULL); | 94 | ret = GNUNET_CONTAINER_multihashmap_remove_all (m, key); |
90 | if (GNUNET_OK != ret) | 95 | if (GNUNET_OK != ret) |
91 | printf ("spurious element\n"); | 96 | printf ("spurious element\n"); |
92 | return GNUNET_YES; | 97 | return GNUNET_YES; |
@@ -158,6 +163,7 @@ check_all_done (void) | |||
158 | static void | 163 | static void |
159 | set_result_cb (void *cls, | 164 | set_result_cb (void *cls, |
160 | const struct GNUNET_SET_Element *element, | 165 | const struct GNUNET_SET_Element *element, |
166 | uint64_t current_size, | ||
161 | enum GNUNET_SET_Status status) | 167 | enum GNUNET_SET_Status status) |
162 | { | 168 | { |
163 | struct SetInfo *info = cls; | 169 | struct SetInfo *info = cls; |
@@ -191,7 +197,7 @@ set_result_cb (void *cls, | |||
191 | GNUNET_assert (0); | 197 | GNUNET_assert (0); |
192 | } | 198 | } |
193 | 199 | ||
194 | if (element->size != sizeof (struct GNUNET_HashCode)) | 200 | if (element->size != element_size) |
195 | { | 201 | { |
196 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 202 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
197 | "wrong element size: %u, expected %u\n", | 203 | "wrong element size: %u, expected %u\n", |
@@ -203,8 +209,10 @@ set_result_cb (void *cls, | |||
203 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "set %s: got element (%s)\n", | 209 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "set %s: got element (%s)\n", |
204 | info->id, GNUNET_h2s (element->data)); | 210 | info->id, GNUNET_h2s (element->data)); |
205 | GNUNET_assert (NULL != element->data); | 211 | GNUNET_assert (NULL != element->data); |
212 | struct GNUNET_HashCode data_hash; | ||
213 | GNUNET_CRYPTO_hash (element->data, element_size, &data_hash); | ||
206 | GNUNET_CONTAINER_multihashmap_put (info->received, | 214 | GNUNET_CONTAINER_multihashmap_put (info->received, |
207 | element->data, NULL, | 215 | &data_hash, NULL, |
208 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | 216 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); |
209 | } | 217 | } |
210 | 218 | ||
@@ -215,6 +223,10 @@ set_listen_cb (void *cls, | |||
215 | const struct GNUNET_MessageHeader *context_msg, | 223 | const struct GNUNET_MessageHeader *context_msg, |
216 | struct GNUNET_SET_Request *request) | 224 | struct GNUNET_SET_Request *request) |
217 | { | 225 | { |
226 | /* max. 2 options plus terminator */ | ||
227 | struct GNUNET_SET_Option opts[3] = {{0}}; | ||
228 | unsigned int n_opts = 0; | ||
229 | |||
218 | if (NULL == request) | 230 | if (NULL == request) |
219 | { | 231 | { |
220 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 232 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
@@ -224,8 +236,24 @@ set_listen_cb (void *cls, | |||
224 | GNUNET_assert (NULL == info2.oh); | 236 | GNUNET_assert (NULL == info2.oh); |
225 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 237 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
226 | "set listen cb called\n"); | 238 | "set listen cb called\n"); |
239 | if (byzantine) | ||
240 | { | ||
241 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_BYZANTINE }; | ||
242 | } | ||
243 | GNUNET_assert (!(force_full && force_delta)); | ||
244 | if (force_full) | ||
245 | { | ||
246 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_FORCE_FULL }; | ||
247 | } | ||
248 | if (force_delta) | ||
249 | { | ||
250 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_FORCE_DELTA }; | ||
251 | } | ||
252 | |||
253 | opts[n_opts].type = 0; | ||
227 | info2.oh = GNUNET_SET_accept (request, GNUNET_SET_RESULT_SYMMETRIC, | 254 | info2.oh = GNUNET_SET_accept (request, GNUNET_SET_RESULT_SYMMETRIC, |
228 | set_result_cb, &info2); | 255 | opts, |
256 | set_result_cb, &info2); | ||
229 | GNUNET_SET_commit (info2.oh, info2.set); | 257 | GNUNET_SET_commit (info2.oh, info2.set); |
230 | } | 258 | } |
231 | 259 | ||
@@ -236,16 +264,12 @@ set_insert_iterator (void *cls, | |||
236 | void *value) | 264 | void *value) |
237 | { | 265 | { |
238 | struct GNUNET_SET_Handle *set = cls; | 266 | struct GNUNET_SET_Handle *set = cls; |
239 | struct GNUNET_SET_Element *el; | 267 | struct GNUNET_SET_Element el; |
240 | 268 | ||
241 | el = GNUNET_malloc (sizeof (struct GNUNET_SET_Element) + | 269 | el.element_type = 0; |
242 | sizeof (struct GNUNET_HashCode)); | 270 | el.data = value; |
243 | el->element_type = 0; | 271 | el.size = element_size; |
244 | GNUNET_memcpy (&el[1], key, sizeof *key); | 272 | GNUNET_SET_add_element (set, &el, NULL, NULL); |
245 | el->data = &el[1]; | ||
246 | el->size = sizeof *key; | ||
247 | GNUNET_SET_add_element (set, el, NULL, NULL); | ||
248 | GNUNET_free (el); | ||
249 | return GNUNET_YES; | 273 | return GNUNET_YES; |
250 | } | 274 | } |
251 | 275 | ||
@@ -291,9 +315,14 @@ run (void *cls, | |||
291 | { | 315 | { |
292 | unsigned int i; | 316 | unsigned int i; |
293 | struct GNUNET_HashCode hash; | 317 | struct GNUNET_HashCode hash; |
318 | /* max. 2 options plus terminator */ | ||
319 | struct GNUNET_SET_Option opts[3] = {{0}}; | ||
320 | unsigned int n_opts = 0; | ||
294 | 321 | ||
295 | config = cfg; | 322 | config = cfg; |
296 | 323 | ||
324 | GNUNET_assert (element_size > 0); | ||
325 | |||
297 | if (GNUNET_OK != GNUNET_CRYPTO_get_peer_identity (cfg, &local_peer)) | 326 | if (GNUNET_OK != GNUNET_CRYPTO_get_peer_identity (cfg, &local_peer)) |
298 | { | 327 | { |
299 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not retrieve host identity\n"); | 328 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not retrieve host identity\n"); |
@@ -317,22 +346,28 @@ run (void *cls, | |||
317 | 346 | ||
318 | for (i = 0; i < num_a; i++) | 347 | for (i = 0; i < num_a; i++) |
319 | { | 348 | { |
320 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, &hash); | 349 | char *data = GNUNET_malloc (element_size); |
321 | GNUNET_CONTAINER_multihashmap_put (info1.sent, &hash, NULL, | 350 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, data, element_size); |
351 | GNUNET_CRYPTO_hash (data, element_size, &hash); | ||
352 | GNUNET_CONTAINER_multihashmap_put (info1.sent, &hash, data, | ||
322 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | 353 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); |
323 | } | 354 | } |
324 | 355 | ||
325 | for (i = 0; i < num_b; i++) | 356 | for (i = 0; i < num_b; i++) |
326 | { | 357 | { |
327 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, &hash); | 358 | char *data = GNUNET_malloc (element_size); |
328 | GNUNET_CONTAINER_multihashmap_put (info2.sent, &hash, NULL, | 359 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, data, element_size); |
360 | GNUNET_CRYPTO_hash (data, element_size, &hash); | ||
361 | GNUNET_CONTAINER_multihashmap_put (info2.sent, &hash, data, | ||
329 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | 362 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); |
330 | } | 363 | } |
331 | 364 | ||
332 | for (i = 0; i < num_c; i++) | 365 | for (i = 0; i < num_c; i++) |
333 | { | 366 | { |
334 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, &hash); | 367 | char *data = GNUNET_malloc (element_size); |
335 | GNUNET_CONTAINER_multihashmap_put (common_sent, &hash, NULL, | 368 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, data, element_size); |
369 | GNUNET_CRYPTO_hash (data, element_size, &hash); | ||
370 | GNUNET_CONTAINER_multihashmap_put (common_sent, &hash, data, | ||
336 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | 371 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); |
337 | } | 372 | } |
338 | 373 | ||
@@ -350,8 +385,26 @@ run (void *cls, | |||
350 | set_listener = GNUNET_SET_listen (config, GNUNET_SET_OPERATION_UNION, | 385 | set_listener = GNUNET_SET_listen (config, GNUNET_SET_OPERATION_UNION, |
351 | &app_id, set_listen_cb, NULL); | 386 | &app_id, set_listen_cb, NULL); |
352 | 387 | ||
388 | |||
389 | if (byzantine) | ||
390 | { | ||
391 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_BYZANTINE }; | ||
392 | } | ||
393 | GNUNET_assert (!(force_full && force_delta)); | ||
394 | if (force_full) | ||
395 | { | ||
396 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_FORCE_FULL }; | ||
397 | } | ||
398 | if (force_delta) | ||
399 | { | ||
400 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_FORCE_DELTA }; | ||
401 | } | ||
402 | |||
403 | opts[n_opts].type = 0; | ||
404 | |||
353 | info1.oh = GNUNET_SET_prepare (&local_peer, &app_id, NULL, | 405 | info1.oh = GNUNET_SET_prepare (&local_peer, &app_id, NULL, |
354 | GNUNET_SET_RESULT_SYMMETRIC, | 406 | GNUNET_SET_RESULT_SYMMETRIC, |
407 | opts, | ||
355 | set_result_cb, &info1); | 408 | set_result_cb, &info1); |
356 | GNUNET_SET_commit (info1.oh, info1.set); | 409 | GNUNET_SET_commit (info1.oh, info1.set); |
357 | GNUNET_SET_destroy (info1.set); | 410 | GNUNET_SET_destroy (info1.set); |
@@ -380,12 +433,24 @@ main (int argc, char **argv) | |||
380 | { 'B', "num-second", NULL, | 433 | { 'B', "num-second", NULL, |
381 | gettext_noop ("number of values"), | 434 | gettext_noop ("number of values"), |
382 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_b }, | 435 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_b }, |
436 | { 'b', "byzantine", NULL, | ||
437 | gettext_noop ("use byzantine mode"), | ||
438 | GNUNET_NO, &GNUNET_GETOPT_set_one, &byzantine }, | ||
439 | { 'f', "force-full", NULL, | ||
440 | gettext_noop ("force sending full set"), | ||
441 | GNUNET_NO, &GNUNET_GETOPT_set_uint, &force_full }, | ||
442 | { 'd', "force-delta", NULL, | ||
443 | gettext_noop ("number delta operation"), | ||
444 | GNUNET_NO, &GNUNET_GETOPT_set_uint, &force_delta }, | ||
383 | { 'C', "num-common", NULL, | 445 | { 'C', "num-common", NULL, |
384 | gettext_noop ("number of values"), | 446 | gettext_noop ("number of values"), |
385 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_c }, | 447 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_c }, |
386 | { 'x', "operation", NULL, | 448 | { 'x', "operation", NULL, |
387 | gettext_noop ("operation to execute"), | 449 | gettext_noop ("operation to execute"), |
388 | GNUNET_YES, &GNUNET_GETOPT_set_string, &op_str }, | 450 | GNUNET_YES, &GNUNET_GETOPT_set_string, &op_str }, |
451 | { 'w', "element-size", NULL, | ||
452 | gettext_noop ("element size"), | ||
453 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &element_size }, | ||
389 | { 's', "statistics", NULL, | 454 | { 's', "statistics", NULL, |
390 | gettext_noop ("write statistics to file"), | 455 | gettext_noop ("write statistics to file"), |
391 | GNUNET_YES, &GNUNET_GETOPT_set_filename, &statistics_filename }, | 456 | GNUNET_YES, &GNUNET_GETOPT_set_filename, &statistics_filename }, |
diff --git a/src/set/plugin_block_set_test.c b/src/set/plugin_block_set_test.c new file mode 100644 index 000000000..01b0c8602 --- /dev/null +++ b/src/set/plugin_block_set_test.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2017 GNUnet e.V. | ||
4 | |||
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 | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file set/plugin_block_set_test.c | ||
23 | * @brief set test block, recognizes elements with non-zero first byte as invalid | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_block_plugin.h" | ||
29 | #include "gnunet_block_group_lib.h" | ||
30 | |||
31 | |||
32 | /** | ||
33 | * Function called to validate a reply or a request. For | ||
34 | * request evaluation, simply pass "NULL" for the reply_block. | ||
35 | * | ||
36 | * @param cls closure | ||
37 | * @param ctx block context | ||
38 | * @param type block type | ||
39 | * @param group block group to use | ||
40 | * @param eo control flags | ||
41 | * @param query original query (hash) | ||
42 | * @param xquery extrended query data (can be NULL, depending on type) | ||
43 | * @param xquery_size number of bytes in xquery | ||
44 | * @param reply_block response to validate | ||
45 | * @param reply_block_size number of bytes in reply block | ||
46 | * @return characterization of result | ||
47 | */ | ||
48 | static enum GNUNET_BLOCK_EvaluationResult | ||
49 | block_plugin_set_test_evaluate (void *cls, | ||
50 | struct GNUNET_BLOCK_Context *ctx, | ||
51 | enum GNUNET_BLOCK_Type type, | ||
52 | struct GNUNET_BLOCK_Group *group, | ||
53 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
54 | const struct GNUNET_HashCode *query, | ||
55 | const void *xquery, | ||
56 | size_t xquery_size, | ||
57 | const void *reply_block, | ||
58 | size_t reply_block_size) | ||
59 | { | ||
60 | if ( (NULL == reply_block) || | ||
61 | (reply_block_size == 0) || | ||
62 | (0 != ((char *) reply_block)[0]) ) | ||
63 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
64 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
65 | } | ||
66 | |||
67 | |||
68 | /** | ||
69 | * Function called to obtain the key for a block. | ||
70 | * | ||
71 | * @param cls closure | ||
72 | * @param type block type | ||
73 | * @param block block to get the key for | ||
74 | * @param block_size number of bytes in block | ||
75 | * @param key set to the key (query) for the given block | ||
76 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | ||
77 | * (or if extracting a key from a block of this type does not work) | ||
78 | */ | ||
79 | static int | ||
80 | block_plugin_set_test_get_key (void *cls, | ||
81 | enum GNUNET_BLOCK_Type type, | ||
82 | const void *block, | ||
83 | size_t block_size, | ||
84 | struct GNUNET_HashCode *key) | ||
85 | { | ||
86 | return GNUNET_SYSERR; | ||
87 | } | ||
88 | |||
89 | |||
90 | /** | ||
91 | * Entry point for the plugin. | ||
92 | */ | ||
93 | void * | ||
94 | libgnunet_plugin_block_set_test_init (void *cls) | ||
95 | { | ||
96 | static enum GNUNET_BLOCK_Type types[] = | ||
97 | { | ||
98 | GNUNET_BLOCK_TYPE_SET_TEST, | ||
99 | GNUNET_BLOCK_TYPE_ANY /* end of list */ | ||
100 | }; | ||
101 | struct GNUNET_BLOCK_PluginFunctions *api; | ||
102 | |||
103 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | ||
104 | api->evaluate = &block_plugin_set_test_evaluate; | ||
105 | api->get_key = &block_plugin_set_test_get_key; | ||
106 | api->types = types; | ||
107 | return api; | ||
108 | } | ||
109 | |||
110 | |||
111 | /** | ||
112 | * Exit point from the plugin. | ||
113 | */ | ||
114 | void * | ||
115 | libgnunet_plugin_block_set_test_done (void *cls) | ||
116 | { | ||
117 | struct GNUNET_BLOCK_PluginFunctions *api = cls; | ||
118 | |||
119 | GNUNET_free (api); | ||
120 | return NULL; | ||
121 | } | ||
122 | |||
123 | /* end of plugin_block_set_test.c */ | ||
diff --git a/src/set/set.h b/src/set/set.h index f31216cb8..258e2bff9 100644 --- a/src/set/set.h +++ b/src/set/set.h | |||
@@ -102,6 +102,30 @@ struct GNUNET_SET_AcceptMessage | |||
102 | * See `enum GNUNET_SET_ResultMode`. | 102 | * See `enum GNUNET_SET_ResultMode`. |
103 | */ | 103 | */ |
104 | uint32_t result_mode GNUNET_PACKED; | 104 | uint32_t result_mode GNUNET_PACKED; |
105 | |||
106 | /** | ||
107 | * Always use delta operation instead of sending full sets, | ||
108 | * even it it's less efficient. | ||
109 | */ | ||
110 | uint8_t force_delta; | ||
111 | |||
112 | /** | ||
113 | * Always send full sets, even if delta operations would | ||
114 | * be more efficient. | ||
115 | */ | ||
116 | uint8_t force_full; | ||
117 | |||
118 | /** | ||
119 | * #GNUNET_YES to fail operations where Byzantine faults | ||
120 | * are suspected | ||
121 | */ | ||
122 | uint8_t byzantine; | ||
123 | |||
124 | /** | ||
125 | * Lower bound for the set size, used only when | ||
126 | * byzantine mode is enabled. | ||
127 | */ | ||
128 | uint8_t byzantine_lower_bound; | ||
105 | }; | 129 | }; |
106 | 130 | ||
107 | 131 | ||
@@ -184,6 +208,30 @@ struct GNUNET_SET_EvaluateMessage | |||
184 | */ | 208 | */ |
185 | uint32_t request_id GNUNET_PACKED; | 209 | uint32_t request_id GNUNET_PACKED; |
186 | 210 | ||
211 | /** | ||
212 | * Always use delta operation instead of sending full sets, | ||
213 | * even it it's less efficient. | ||
214 | */ | ||
215 | uint8_t force_delta; | ||
216 | |||
217 | /** | ||
218 | * Always send full sets, even if delta operations would | ||
219 | * be more efficient. | ||
220 | */ | ||
221 | uint8_t force_full; | ||
222 | |||
223 | /** | ||
224 | * #GNUNET_YES to fail operations where Byzantine faults | ||
225 | * are suspected | ||
226 | */ | ||
227 | uint8_t byzantine; | ||
228 | |||
229 | /** | ||
230 | * Lower bound for the set size, used only when | ||
231 | * byzantine mode is enabled. | ||
232 | */ | ||
233 | uint8_t byzantine_lower_bound; | ||
234 | |||
187 | /* rest: context message, that is, application-specific | 235 | /* rest: context message, that is, application-specific |
188 | message to convince listener to pick up */ | 236 | message to convince listener to pick up */ |
189 | }; | 237 | }; |
@@ -203,6 +251,11 @@ struct GNUNET_SET_ResultMessage | |||
203 | struct GNUNET_MessageHeader header; | 251 | struct GNUNET_MessageHeader header; |
204 | 252 | ||
205 | /** | 253 | /** |
254 | * Current set size. | ||
255 | */ | ||
256 | uint64_t current_size; | ||
257 | |||
258 | /** | ||
206 | * id the result belongs to | 259 | * id the result belongs to |
207 | */ | 260 | */ |
208 | uint32_t request_id GNUNET_PACKED; | 261 | uint32_t request_id GNUNET_PACKED; |
diff --git a/src/set/set_api.c b/src/set/set_api.c index baeee6da0..5b5b1b8ee 100644 --- a/src/set/set_api.c +++ b/src/set/set_api.c | |||
@@ -432,6 +432,7 @@ do_final: | |||
432 | { | 432 | { |
433 | oh->result_cb (oh->result_cls, | 433 | oh->result_cb (oh->result_cls, |
434 | NULL, | 434 | NULL, |
435 | GNUNET_ntohll (msg->current_size), | ||
435 | result_status); | 436 | result_status); |
436 | } | 437 | } |
437 | else | 438 | else |
@@ -453,6 +454,7 @@ do_element: | |||
453 | if (NULL != oh->result_cb) | 454 | if (NULL != oh->result_cb) |
454 | oh->result_cb (oh->result_cls, | 455 | oh->result_cb (oh->result_cls, |
455 | &e, | 456 | &e, |
457 | GNUNET_ntohll (msg->current_size), | ||
456 | result_status); | 458 | result_status); |
457 | } | 459 | } |
458 | 460 | ||
@@ -538,6 +540,7 @@ handle_client_set_error (void *cls, | |||
538 | if (NULL != set->ops_head->result_cb) | 540 | if (NULL != set->ops_head->result_cb) |
539 | set->ops_head->result_cb (set->ops_head->result_cls, | 541 | set->ops_head->result_cb (set->ops_head->result_cls, |
540 | NULL, | 542 | NULL, |
543 | 0, | ||
541 | GNUNET_SET_STATUS_FAILURE); | 544 | GNUNET_SET_STATUS_FAILURE); |
542 | set_operation_destroy (set->ops_head); | 545 | set_operation_destroy (set->ops_head); |
543 | } | 546 | } |
@@ -654,6 +657,8 @@ GNUNET_SET_add_element (struct GNUNET_SET_Handle *set, | |||
654 | struct GNUNET_MQ_Envelope *mqm; | 657 | struct GNUNET_MQ_Envelope *mqm; |
655 | struct GNUNET_SET_ElementMessage *msg; | 658 | struct GNUNET_SET_ElementMessage *msg; |
656 | 659 | ||
660 | LOG (GNUNET_ERROR_TYPE_INFO, "adding element of type %u\n", (unsigned) element->element_type); | ||
661 | |||
657 | if (GNUNET_YES == set->invalid) | 662 | if (GNUNET_YES == set->invalid) |
658 | { | 663 | { |
659 | if (NULL != cont) | 664 | if (NULL != cont) |
@@ -766,12 +771,14 @@ GNUNET_SET_prepare (const struct GNUNET_PeerIdentity *other_peer, | |||
766 | const struct GNUNET_HashCode *app_id, | 771 | const struct GNUNET_HashCode *app_id, |
767 | const struct GNUNET_MessageHeader *context_msg, | 772 | const struct GNUNET_MessageHeader *context_msg, |
768 | enum GNUNET_SET_ResultMode result_mode, | 773 | enum GNUNET_SET_ResultMode result_mode, |
774 | struct GNUNET_SET_Option options[], | ||
769 | GNUNET_SET_ResultIterator result_cb, | 775 | GNUNET_SET_ResultIterator result_cb, |
770 | void *result_cls) | 776 | void *result_cls) |
771 | { | 777 | { |
772 | struct GNUNET_MQ_Envelope *mqm; | 778 | struct GNUNET_MQ_Envelope *mqm; |
773 | struct GNUNET_SET_OperationHandle *oh; | 779 | struct GNUNET_SET_OperationHandle *oh; |
774 | struct GNUNET_SET_EvaluateMessage *msg; | 780 | struct GNUNET_SET_EvaluateMessage *msg; |
781 | struct GNUNET_SET_Option *opt; | ||
775 | 782 | ||
776 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 783 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
777 | "Client prepares set operation (%d)\n", | 784 | "Client prepares set operation (%d)\n", |
@@ -785,6 +792,25 @@ GNUNET_SET_prepare (const struct GNUNET_PeerIdentity *other_peer, | |||
785 | msg->app_id = *app_id; | 792 | msg->app_id = *app_id; |
786 | msg->result_mode = htonl (result_mode); | 793 | msg->result_mode = htonl (result_mode); |
787 | msg->target_peer = *other_peer; | 794 | msg->target_peer = *other_peer; |
795 | for (opt = options; opt->type != 0; opt++) | ||
796 | { | ||
797 | switch (opt->type) | ||
798 | { | ||
799 | case GNUNET_SET_OPTION_BYZANTINE: | ||
800 | msg->byzantine = GNUNET_YES; | ||
801 | msg->byzantine_lower_bound = opt->v.num; | ||
802 | break; | ||
803 | case GNUNET_SET_OPTION_FORCE_FULL: | ||
804 | msg->force_full = GNUNET_YES; | ||
805 | break; | ||
806 | case GNUNET_SET_OPTION_FORCE_DELTA: | ||
807 | msg->force_delta = GNUNET_YES; | ||
808 | break; | ||
809 | default: | ||
810 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
811 | "Option with type %d not recognized\n", (int) opt->type); | ||
812 | } | ||
813 | } | ||
788 | oh->conclude_mqm = mqm; | 814 | oh->conclude_mqm = mqm; |
789 | oh->request_id_addr = &msg->request_id; | 815 | oh->request_id_addr = &msg->request_id; |
790 | 816 | ||
@@ -1006,6 +1032,7 @@ GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh) | |||
1006 | struct GNUNET_SET_OperationHandle * | 1032 | struct GNUNET_SET_OperationHandle * |
1007 | GNUNET_SET_accept (struct GNUNET_SET_Request *request, | 1033 | GNUNET_SET_accept (struct GNUNET_SET_Request *request, |
1008 | enum GNUNET_SET_ResultMode result_mode, | 1034 | enum GNUNET_SET_ResultMode result_mode, |
1035 | struct GNUNET_SET_Option options[], | ||
1009 | GNUNET_SET_ResultIterator result_cb, | 1036 | GNUNET_SET_ResultIterator result_cb, |
1010 | void *result_cls) | 1037 | void *result_cls) |
1011 | { | 1038 | { |
diff --git a/src/set/test_set.conf b/src/set/test_set.conf index 69e7f5c52..e28dfc6e9 100644 --- a/src/set/test_set.conf +++ b/src/set/test_set.conf | |||
@@ -5,7 +5,6 @@ GNUNET_TEST_HOME = /tmp/test-gnunet-set/ | |||
5 | 5 | ||
6 | [set] | 6 | [set] |
7 | AUTOSTART = YES | 7 | AUTOSTART = YES |
8 | # PREFIX = valgrind | ||
9 | #PREFIX = valgrind --leak-check=full | 8 | #PREFIX = valgrind --leak-check=full |
10 | #PREFIX = gdbserver :1234 | 9 | #PREFIX = gdbserver :1234 |
11 | OPTIONS = -L INFO | 10 | OPTIONS = -L INFO |
diff --git a/src/set/test_set_api.c b/src/set/test_set_api.c index 21af45f8a..dd3f004f2 100644 --- a/src/set/test_set_api.c +++ b/src/set/test_set_api.c | |||
@@ -55,6 +55,7 @@ static struct GNUNET_SCHEDULER_Task *tt; | |||
55 | static void | 55 | static void |
56 | result_cb_set1 (void *cls, | 56 | result_cb_set1 (void *cls, |
57 | const struct GNUNET_SET_Element *element, | 57 | const struct GNUNET_SET_Element *element, |
58 | uint64_t size, | ||
58 | enum GNUNET_SET_Status status) | 59 | enum GNUNET_SET_Status status) |
59 | { | 60 | { |
60 | switch (status) | 61 | switch (status) |
@@ -101,6 +102,7 @@ result_cb_set1 (void *cls, | |||
101 | static void | 102 | static void |
102 | result_cb_set2 (void *cls, | 103 | result_cb_set2 (void *cls, |
103 | const struct GNUNET_SET_Element *element, | 104 | const struct GNUNET_SET_Element *element, |
105 | uint64_t size, | ||
104 | enum GNUNET_SET_Status status) | 106 | enum GNUNET_SET_Status status) |
105 | { | 107 | { |
106 | switch (status) | 108 | switch (status) |
@@ -149,6 +151,7 @@ listen_cb (void *cls, | |||
149 | listen_handle = NULL; | 151 | listen_handle = NULL; |
150 | oh2 = GNUNET_SET_accept (request, | 152 | oh2 = GNUNET_SET_accept (request, |
151 | GNUNET_SET_RESULT_ADDED, | 153 | GNUNET_SET_RESULT_ADDED, |
154 | (struct GNUNET_SET_Option[]) { 0 }, | ||
152 | &result_cb_set2, | 155 | &result_cb_set2, |
153 | NULL); | 156 | NULL); |
154 | GNUNET_SET_commit (oh2, | 157 | GNUNET_SET_commit (oh2, |
@@ -179,6 +182,7 @@ start (void *cls) | |||
179 | &app_id, | 182 | &app_id, |
180 | &context_msg, | 183 | &context_msg, |
181 | GNUNET_SET_RESULT_ADDED, | 184 | GNUNET_SET_RESULT_ADDED, |
185 | (struct GNUNET_SET_Option[]) { 0 }, | ||
182 | &result_cb_set1, | 186 | &result_cb_set1, |
183 | NULL); | 187 | NULL); |
184 | GNUNET_SET_commit (oh1, | 188 | GNUNET_SET_commit (oh1, |
@@ -378,6 +382,7 @@ run (void *cls, | |||
378 | &app_id, | 382 | &app_id, |
379 | NULL, | 383 | NULL, |
380 | GNUNET_SET_RESULT_ADDED, | 384 | GNUNET_SET_RESULT_ADDED, |
385 | (struct GNUNET_SET_Option[]) { 0 }, | ||
381 | NULL, | 386 | NULL, |
382 | NULL); | 387 | NULL); |
383 | 388 | ||
diff --git a/src/set/test_set_intersection_result_full.c b/src/set/test_set_intersection_result_full.c index b2d6ce8a9..a36aae4d5 100644 --- a/src/set/test_set_intersection_result_full.c +++ b/src/set/test_set_intersection_result_full.c | |||
@@ -56,6 +56,7 @@ static struct GNUNET_SET_OperationHandle *oh2; | |||
56 | static void | 56 | static void |
57 | result_cb_set1 (void *cls, | 57 | result_cb_set1 (void *cls, |
58 | const struct GNUNET_SET_Element *element, | 58 | const struct GNUNET_SET_Element *element, |
59 | uint64_t current_size, | ||
59 | enum GNUNET_SET_Status status) | 60 | enum GNUNET_SET_Status status) |
60 | { | 61 | { |
61 | static int count; | 62 | static int count; |
@@ -89,6 +90,7 @@ result_cb_set1 (void *cls, | |||
89 | static void | 90 | static void |
90 | result_cb_set2 (void *cls, | 91 | result_cb_set2 (void *cls, |
91 | const struct GNUNET_SET_Element *element, | 92 | const struct GNUNET_SET_Element *element, |
93 | uint64_t current_size, | ||
92 | enum GNUNET_SET_Status status) | 94 | enum GNUNET_SET_Status status) |
93 | { | 95 | { |
94 | static int count; | 96 | static int count; |
@@ -133,6 +135,7 @@ listen_cb (void *cls, | |||
133 | listen_handle = NULL; | 135 | listen_handle = NULL; |
134 | oh2 = GNUNET_SET_accept (request, | 136 | oh2 = GNUNET_SET_accept (request, |
135 | GNUNET_SET_RESULT_FULL, | 137 | GNUNET_SET_RESULT_FULL, |
138 | (struct GNUNET_SET_Option[]) { 0 }, | ||
136 | &result_cb_set2, | 139 | &result_cb_set2, |
137 | NULL); | 140 | NULL); |
138 | GNUNET_SET_commit (oh2, | 141 | GNUNET_SET_commit (oh2, |
@@ -163,6 +166,7 @@ start (void *cls) | |||
163 | &app_id, | 166 | &app_id, |
164 | &context_msg, | 167 | &context_msg, |
165 | GNUNET_SET_RESULT_FULL, | 168 | GNUNET_SET_RESULT_FULL, |
169 | (struct GNUNET_SET_Option[]) { 0 }, | ||
166 | &result_cb_set1, | 170 | &result_cb_set1, |
167 | NULL); | 171 | NULL); |
168 | GNUNET_SET_commit (oh1, | 172 | GNUNET_SET_commit (oh1, |
diff --git a/src/set/test_set_union_result_symmetric.c b/src/set/test_set_union_result_symmetric.c index ab191a34a..f81c7b8f7 100644 --- a/src/set/test_set_union_result_symmetric.c +++ b/src/set/test_set_union_result_symmetric.c | |||
@@ -77,6 +77,7 @@ static struct GNUNET_SCHEDULER_Task *timeout_task; | |||
77 | static void | 77 | static void |
78 | result_cb_set1 (void *cls, | 78 | result_cb_set1 (void *cls, |
79 | const struct GNUNET_SET_Element *element, | 79 | const struct GNUNET_SET_Element *element, |
80 | uint64_t current_size, | ||
80 | enum GNUNET_SET_Status status) | 81 | enum GNUNET_SET_Status status) |
81 | { | 82 | { |
82 | switch (status) | 83 | switch (status) |
@@ -125,6 +126,7 @@ result_cb_set1 (void *cls, | |||
125 | static void | 126 | static void |
126 | result_cb_set2 (void *cls, | 127 | result_cb_set2 (void *cls, |
127 | const struct GNUNET_SET_Element *element, | 128 | const struct GNUNET_SET_Element *element, |
129 | uint64_t current_size, | ||
128 | enum GNUNET_SET_Status status) | 130 | enum GNUNET_SET_Status status) |
129 | { | 131 | { |
130 | switch (status) | 132 | switch (status) |
@@ -184,6 +186,7 @@ listen_cb (void *cls, | |||
184 | listen_handle = NULL; | 186 | listen_handle = NULL; |
185 | oh2 = GNUNET_SET_accept (request, | 187 | oh2 = GNUNET_SET_accept (request, |
186 | GNUNET_SET_RESULT_SYMMETRIC, | 188 | GNUNET_SET_RESULT_SYMMETRIC, |
189 | (struct GNUNET_SET_Option[]) { 0 }, | ||
187 | &result_cb_set2, | 190 | &result_cb_set2, |
188 | NULL); | 191 | NULL); |
189 | GNUNET_SET_commit (oh2, | 192 | GNUNET_SET_commit (oh2, |
@@ -212,6 +215,7 @@ start (void *cls) | |||
212 | &app_id, | 215 | &app_id, |
213 | &context_msg, | 216 | &context_msg, |
214 | GNUNET_SET_RESULT_SYMMETRIC, | 217 | GNUNET_SET_RESULT_SYMMETRIC, |
218 | (struct GNUNET_SET_Option[]) { 0 }, | ||
215 | &result_cb_set1, NULL); | 219 | &result_cb_set1, NULL); |
216 | GNUNET_SET_commit (oh1, set1); | 220 | GNUNET_SET_commit (oh1, set1); |
217 | } | 221 | } |