summaryrefslogtreecommitdiff
path: root/src/set/gnunet-service-set_intersection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/set/gnunet-service-set_intersection.c')
-rw-r--r--src/set/gnunet-service-set_intersection.c1241
1 files changed, 622 insertions, 619 deletions
diff --git a/src/set/gnunet-service-set_intersection.c b/src/set/gnunet-service-set_intersection.c
index e1bbcc152..964a26b91 100644
--- a/src/set/gnunet-service-set_intersection.c
+++ b/src/set/gnunet-service-set_intersection.c
@@ -16,7 +16,7 @@
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20/** 20/**
21 * @file set/gnunet-service-set_intersection.c 21 * @file set/gnunet-service-set_intersection.c
22 * @brief two-peer set intersection 22 * @brief two-peer set intersection
@@ -36,8 +36,7 @@
36/** 36/**
37 * Current phase we are in for a intersection operation. 37 * Current phase we are in for a intersection operation.
38 */ 38 */
39enum IntersectionOperationPhase 39enum IntersectionOperationPhase {
40{
41 /** 40 /**
42 * We are just starting. 41 * We are just starting.
43 */ 42 */
@@ -73,15 +72,13 @@ enum IntersectionOperationPhase
73 * client. 72 * client.
74 */ 73 */
75 PHASE_FINISHED 74 PHASE_FINISHED
76
77}; 75};
78 76
79 77
80/** 78/**
81 * State of an evaluate operation with another peer. 79 * State of an evaluate operation with another peer.
82 */ 80 */
83struct OperationState 81struct OperationState {
84{
85 /** 82 /**
86 * The bf we currently receive 83 * The bf we currently receive
87 */ 84 */
@@ -189,8 +186,7 @@ struct OperationState
189 * Extra state required for efficient set intersection. 186 * Extra state required for efficient set intersection.
190 * Merely tracks the total number of elements. 187 * Merely tracks the total number of elements.
191 */ 188 */
192struct SetState 189struct SetState {
193{
194 /** 190 /**
195 * Number of currently valid elements in the set which have not been 191 * Number of currently valid elements in the set which have not been
196 * removed. 192 * removed.
@@ -207,38 +203,38 @@ struct SetState
207 * @param element element to send 203 * @param element element to send
208 */ 204 */
209static void 205static void
210send_client_removed_element (struct Operation *op, 206send_client_removed_element(struct Operation *op,
211 struct GNUNET_SET_Element *element) 207 struct GNUNET_SET_Element *element)
212{ 208{
213 struct GNUNET_MQ_Envelope *ev; 209 struct GNUNET_MQ_Envelope *ev;
214 struct GNUNET_SET_ResultMessage *rm; 210 struct GNUNET_SET_ResultMessage *rm;
215 211
216 if (GNUNET_SET_RESULT_REMOVED != op->result_mode) 212 if (GNUNET_SET_RESULT_REMOVED != op->result_mode)
217 return; /* Wrong mode for transmitting removed elements */ 213 return; /* Wrong mode for transmitting removed elements */
218 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 214 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
219 "Sending removed element (size %u) to client\n", 215 "Sending removed element (size %u) to client\n",
220 element->size); 216 element->size);
221 GNUNET_STATISTICS_update (_GSS_statistics, 217 GNUNET_STATISTICS_update(_GSS_statistics,
222 "# Element removed messages sent", 218 "# Element removed messages sent",
223 1, 219 1,
224 GNUNET_NO); 220 GNUNET_NO);
225 GNUNET_assert (0 != op->client_request_id); 221 GNUNET_assert(0 != op->client_request_id);
226 ev = GNUNET_MQ_msg_extra (rm, 222 ev = GNUNET_MQ_msg_extra(rm,
227 element->size, 223 element->size,
228 GNUNET_MESSAGE_TYPE_SET_RESULT); 224 GNUNET_MESSAGE_TYPE_SET_RESULT);
229 if (NULL == ev) 225 if (NULL == ev)
230 { 226 {
231 GNUNET_break (0); 227 GNUNET_break(0);
232 return; 228 return;
233 } 229 }
234 rm->result_status = htons (GNUNET_SET_STATUS_OK); 230 rm->result_status = htons(GNUNET_SET_STATUS_OK);
235 rm->request_id = htonl (op->client_request_id); 231 rm->request_id = htonl(op->client_request_id);
236 rm->element_type = element->element_type; 232 rm->element_type = element->element_type;
237 GNUNET_memcpy (&rm[1], 233 GNUNET_memcpy(&rm[1],
238 element->data, 234 element->data,
239 element->size); 235 element->size);
240 GNUNET_MQ_send (op->set->cs->mq, 236 GNUNET_MQ_send(op->set->cs->mq,
241 ev); 237 ev);
242} 238}
243 239
244 240
@@ -251,63 +247,63 @@ send_client_removed_element (struct Operation *op,
251 * @return #GNUNET_YES (we should continue to iterate) 247 * @return #GNUNET_YES (we should continue to iterate)
252 */ 248 */
253static int 249static int
254filtered_map_initialization (void *cls, 250filtered_map_initialization(void *cls,
255 const struct GNUNET_HashCode *key, 251 const struct GNUNET_HashCode *key,
256 void *value) 252 void *value)
257{ 253{
258 struct Operation *op = cls; 254 struct Operation *op = cls;
259 struct ElementEntry *ee = value; 255 struct ElementEntry *ee = value;
260 struct GNUNET_HashCode mutated_hash; 256 struct GNUNET_HashCode mutated_hash;
261 257
262 258
263 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 259 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
264 "FIMA called for %s:%u\n", 260 "FIMA called for %s:%u\n",
265 GNUNET_h2s (&ee->element_hash), 261 GNUNET_h2s(&ee->element_hash),
266 ee->element.size); 262 ee->element.size);
267 263
268 if (GNUNET_NO == _GSS_is_element_of_operation (ee, op)) 264 if (GNUNET_NO == _GSS_is_element_of_operation(ee, op))
269 { 265 {
270 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 266 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
271 "Reduced initialization, not starting with %s:%u (wrong generation)\n", 267 "Reduced initialization, not starting with %s:%u (wrong generation)\n",
272 GNUNET_h2s (&ee->element_hash), 268 GNUNET_h2s(&ee->element_hash),
273 ee->element.size); 269 ee->element.size);
274 return GNUNET_YES; /* element not valid in our operation's generation */ 270 return GNUNET_YES; /* element not valid in our operation's generation */
275 } 271 }
276 272
277 /* Test if element is in other peer's bloomfilter */ 273 /* Test if element is in other peer's bloomfilter */
278 GNUNET_BLOCK_mingle_hash (&ee->element_hash, 274 GNUNET_BLOCK_mingle_hash(&ee->element_hash,
279 op->state->salt, 275 op->state->salt,
280 &mutated_hash); 276 &mutated_hash);
281 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 277 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
282 "Testing mingled hash %s with salt %u\n", 278 "Testing mingled hash %s with salt %u\n",
283 GNUNET_h2s (&mutated_hash), 279 GNUNET_h2s(&mutated_hash),
284 op->state->salt); 280 op->state->salt);
285 if (GNUNET_NO == 281 if (GNUNET_NO ==
286 GNUNET_CONTAINER_bloomfilter_test (op->state->remote_bf, 282 GNUNET_CONTAINER_bloomfilter_test(op->state->remote_bf,
287 &mutated_hash)) 283 &mutated_hash))
288 { 284 {
289 /* remove this element */ 285 /* remove this element */
290 send_client_removed_element (op, 286 send_client_removed_element(op,
291 &ee->element); 287 &ee->element);
292 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 288 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
293 "Reduced initialization, not starting with %s:%u\n", 289 "Reduced initialization, not starting with %s:%u\n",
294 GNUNET_h2s (&ee->element_hash), 290 GNUNET_h2s(&ee->element_hash),
295 ee->element.size); 291 ee->element.size);
296 return GNUNET_YES; 292 return GNUNET_YES;
297 } 293 }
298 op->state->my_element_count++; 294 op->state->my_element_count++;
299 GNUNET_CRYPTO_hash_xor (&op->state->my_xor, 295 GNUNET_CRYPTO_hash_xor(&op->state->my_xor,
300 &ee->element_hash, 296 &ee->element_hash,
301 &op->state->my_xor); 297 &op->state->my_xor);
302 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 298 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
303 "Filtered initialization of my_elements, adding %s:%u\n", 299 "Filtered initialization of my_elements, adding %s:%u\n",
304 GNUNET_h2s (&ee->element_hash), 300 GNUNET_h2s(&ee->element_hash),
305 ee->element.size); 301 ee->element.size);
306 GNUNET_break (GNUNET_YES == 302 GNUNET_break(GNUNET_YES ==
307 GNUNET_CONTAINER_multihashmap_put (op->state->my_elements, 303 GNUNET_CONTAINER_multihashmap_put(op->state->my_elements,
308 &ee->element_hash, 304 &ee->element_hash,
309 ee, 305 ee,
310 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 306 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
311 307
312 return GNUNET_YES; 308 return GNUNET_YES;
313} 309}
@@ -323,7 +319,7 @@ filtered_map_initialization (void *cls,
323 * @return #GNUNET_YES (we should continue to iterate) 319 * @return #GNUNET_YES (we should continue to iterate)
324 */ 320 */
325static int 321static int
326iterator_bf_reduce (void *cls, 322iterator_bf_reduce(void *cls,
327 const struct GNUNET_HashCode *key, 323 const struct GNUNET_HashCode *key,
328 void *value) 324 void *value)
329{ 325{
@@ -331,40 +327,40 @@ iterator_bf_reduce (void *cls,
331 struct ElementEntry *ee = value; 327 struct ElementEntry *ee = value;
332 struct GNUNET_HashCode mutated_hash; 328 struct GNUNET_HashCode mutated_hash;
333 329
334 GNUNET_BLOCK_mingle_hash (&ee->element_hash, 330 GNUNET_BLOCK_mingle_hash(&ee->element_hash,
335 op->state->salt, 331 op->state->salt,
336 &mutated_hash); 332 &mutated_hash);
337 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 333 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
338 "Testing mingled hash %s with salt %u\n", 334 "Testing mingled hash %s with salt %u\n",
339 GNUNET_h2s (&mutated_hash), 335 GNUNET_h2s(&mutated_hash),
340 op->state->salt); 336 op->state->salt);
341 if (GNUNET_NO == 337 if (GNUNET_NO ==
342 GNUNET_CONTAINER_bloomfilter_test (op->state->remote_bf, 338 GNUNET_CONTAINER_bloomfilter_test(op->state->remote_bf,
343 &mutated_hash)) 339 &mutated_hash))
344 { 340 {
345 GNUNET_break (0 < op->state->my_element_count); 341 GNUNET_break(0 < op->state->my_element_count);
346 op->state->my_element_count--; 342 op->state->my_element_count--;
347 GNUNET_CRYPTO_hash_xor (&op->state->my_xor, 343 GNUNET_CRYPTO_hash_xor(&op->state->my_xor,
348 &ee->element_hash, 344 &ee->element_hash,
349 &op->state->my_xor); 345 &op->state->my_xor);
350 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 346 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
351 "Bloom filter reduction of my_elements, removing %s:%u\n", 347 "Bloom filter reduction of my_elements, removing %s:%u\n",
352 GNUNET_h2s (&ee->element_hash), 348 GNUNET_h2s(&ee->element_hash),
353 ee->element.size); 349 ee->element.size);
354 GNUNET_assert (GNUNET_YES == 350 GNUNET_assert(GNUNET_YES ==
355 GNUNET_CONTAINER_multihashmap_remove (op->state->my_elements, 351 GNUNET_CONTAINER_multihashmap_remove(op->state->my_elements,
356 &ee->element_hash, 352 &ee->element_hash,
357 ee)); 353 ee));
358 send_client_removed_element (op, 354 send_client_removed_element(op,
359 &ee->element); 355 &ee->element);
360 } 356 }
361 else 357 else
362 { 358 {
363 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 359 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
364 "Bloom filter reduction of my_elements, keeping %s:%u\n", 360 "Bloom filter reduction of my_elements, keeping %s:%u\n",
365 GNUNET_h2s (&ee->element_hash), 361 GNUNET_h2s(&ee->element_hash),
366 ee->element.size); 362 ee->element.size);
367 } 363 }
368 return GNUNET_YES; 364 return GNUNET_YES;
369} 365}
370 366
@@ -378,23 +374,23 @@ iterator_bf_reduce (void *cls,
378 * @return #GNUNET_YES (we should continue to iterate) 374 * @return #GNUNET_YES (we should continue to iterate)
379 */ 375 */
380static int 376static int
381iterator_bf_create (void *cls, 377iterator_bf_create(void *cls,
382 const struct GNUNET_HashCode *key, 378 const struct GNUNET_HashCode *key,
383 void *value) 379 void *value)
384{ 380{
385 struct Operation *op = cls; 381 struct Operation *op = cls;
386 struct ElementEntry *ee = value; 382 struct ElementEntry *ee = value;
387 struct GNUNET_HashCode mutated_hash; 383 struct GNUNET_HashCode mutated_hash;
388 384
389 GNUNET_BLOCK_mingle_hash (&ee->element_hash, 385 GNUNET_BLOCK_mingle_hash(&ee->element_hash,
390 op->state->salt, 386 op->state->salt,
391 &mutated_hash); 387 &mutated_hash);
392 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 388 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
393 "Initializing BF with hash %s with salt %u\n", 389 "Initializing BF with hash %s with salt %u\n",
394 GNUNET_h2s (&mutated_hash), 390 GNUNET_h2s(&mutated_hash),
395 op->state->salt); 391 op->state->salt);
396 GNUNET_CONTAINER_bloomfilter_add (op->state->local_bf, 392 GNUNET_CONTAINER_bloomfilter_add(op->state->local_bf,
397 &mutated_hash); 393 &mutated_hash);
398 return GNUNET_YES; 394 return GNUNET_YES;
399} 395}
400 396
@@ -406,31 +402,31 @@ iterator_bf_create (void *cls,
406 * @param op the intersection operation to fail 402 * @param op the intersection operation to fail
407 */ 403 */
408static void 404static void
409fail_intersection_operation (struct Operation *op) 405fail_intersection_operation(struct Operation *op)
410{ 406{
411 struct GNUNET_MQ_Envelope *ev; 407 struct GNUNET_MQ_Envelope *ev;
412 struct GNUNET_SET_ResultMessage *msg; 408 struct GNUNET_SET_ResultMessage *msg;
413 409
414 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 410 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
415 "Intersection operation failed\n"); 411 "Intersection operation failed\n");
416 GNUNET_STATISTICS_update (_GSS_statistics, 412 GNUNET_STATISTICS_update(_GSS_statistics,
417 "# Intersection operations failed", 413 "# Intersection operations failed",
418 1, 414 1,
419 GNUNET_NO); 415 GNUNET_NO);
420 if (NULL != op->state->my_elements) 416 if (NULL != op->state->my_elements)
421 { 417 {
422 GNUNET_CONTAINER_multihashmap_destroy (op->state->my_elements); 418 GNUNET_CONTAINER_multihashmap_destroy(op->state->my_elements);
423 op->state->my_elements = NULL; 419 op->state->my_elements = NULL;
424 } 420 }
425 ev = GNUNET_MQ_msg (msg, 421 ev = GNUNET_MQ_msg(msg,
426 GNUNET_MESSAGE_TYPE_SET_RESULT); 422 GNUNET_MESSAGE_TYPE_SET_RESULT);
427 msg->result_status = htons (GNUNET_SET_STATUS_FAILURE); 423 msg->result_status = htons(GNUNET_SET_STATUS_FAILURE);
428 msg->request_id = htonl (op->client_request_id); 424 msg->request_id = htonl(op->client_request_id);
429 msg->element_type = htons (0); 425 msg->element_type = htons(0);
430 GNUNET_MQ_send (op->set->cs->mq, 426 GNUNET_MQ_send(op->set->cs->mq,
431 ev); 427 ev);
432 _GSS_operation_destroy (op, 428 _GSS_operation_destroy(op,
433 GNUNET_YES); 429 GNUNET_YES);
434} 430}
435 431
436 432
@@ -441,7 +437,7 @@ fail_intersection_operation (struct Operation *op)
441 * @param op intersection operation 437 * @param op intersection operation
442 */ 438 */
443static void 439static void
444send_bloomfilter (struct Operation *op) 440send_bloomfilter(struct Operation *op)
445{ 441{
446 struct GNUNET_MQ_Envelope *ev; 442 struct GNUNET_MQ_Envelope *ev;
447 struct BFMessage *msg; 443 struct BFMessage *msg;
@@ -455,81 +451,81 @@ send_bloomfilter (struct Operation *op)
455 the number of bits per element, as the smaller set 451 the number of bits per element, as the smaller set
456 should use more bits to maximize its set reduction 452 should use more bits to maximize its set reduction
457 potential and minimize overall bandwidth consumption. */ 453 potential and minimize overall bandwidth consumption. */
458 bf_elementbits = 2 + ceil (log2((double) 454 bf_elementbits = 2 + ceil(log2((double)
459 (op->remote_element_count / 455 (op->remote_element_count /
460 (double) op->state->my_element_count))); 456 (double)op->state->my_element_count)));
461 if (bf_elementbits < 1) 457 if (bf_elementbits < 1)
462 bf_elementbits = 1; /* make sure k is not 0 */ 458 bf_elementbits = 1; /* make sure k is not 0 */
463 /* optimize BF-size to ~50% of bits set */ 459 /* optimize BF-size to ~50% of bits set */
464 bf_size = ceil ((double) (op->state->my_element_count 460 bf_size = ceil((double)(op->state->my_element_count
465 * bf_elementbits / log(2))); 461 * bf_elementbits / log(2)));
466 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 462 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
467 "Sending Bloom filter (%u) of size %u bytes\n", 463 "Sending Bloom filter (%u) of size %u bytes\n",
468 (unsigned int) bf_elementbits, 464 (unsigned int)bf_elementbits,
469 (unsigned int) bf_size); 465 (unsigned int)bf_size);
470 op->state->local_bf = GNUNET_CONTAINER_bloomfilter_init (NULL, 466 op->state->local_bf = GNUNET_CONTAINER_bloomfilter_init(NULL,
471 bf_size, 467 bf_size,
472 bf_elementbits); 468 bf_elementbits);
473 op->state->salt = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 469 op->state->salt = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE,
474 UINT32_MAX); 470 UINT32_MAX);
475 GNUNET_CONTAINER_multihashmap_iterate (op->state->my_elements, 471 GNUNET_CONTAINER_multihashmap_iterate(op->state->my_elements,
476 &iterator_bf_create, 472 &iterator_bf_create,
477 op); 473 op);
478 474
479 /* send our Bloom filter */ 475 /* send our Bloom filter */
480 GNUNET_STATISTICS_update (_GSS_statistics, 476 GNUNET_STATISTICS_update(_GSS_statistics,
481 "# Intersection Bloom filters sent", 477 "# Intersection Bloom filters sent",
482 1, 478 1,
483 GNUNET_NO); 479 GNUNET_NO);
484 chunk_size = 60 * 1024 - sizeof (struct BFMessage); 480 chunk_size = 60 * 1024 - sizeof(struct BFMessage);
485 if (bf_size <= chunk_size) 481 if (bf_size <= chunk_size)
486 { 482 {
487 /* singlepart */ 483 /* singlepart */
488 chunk_size = bf_size; 484 chunk_size = bf_size;
489 ev = GNUNET_MQ_msg_extra (msg, 485 ev = GNUNET_MQ_msg_extra(msg,
490 chunk_size, 486 chunk_size,
491 GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF); 487 GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF);
492 GNUNET_assert (GNUNET_SYSERR != 488 GNUNET_assert(GNUNET_SYSERR !=
493 GNUNET_CONTAINER_bloomfilter_get_raw_data (op->state->local_bf, 489 GNUNET_CONTAINER_bloomfilter_get_raw_data(op->state->local_bf,
494 (char*) &msg[1], 490 (char*)&msg[1],
495 bf_size)); 491 bf_size));
496 msg->sender_element_count = htonl (op->state->my_element_count); 492 msg->sender_element_count = htonl(op->state->my_element_count);
497 msg->bloomfilter_total_length = htonl (bf_size); 493 msg->bloomfilter_total_length = htonl(bf_size);
498 msg->bits_per_element = htonl (bf_elementbits); 494 msg->bits_per_element = htonl(bf_elementbits);
499 msg->sender_mutator = htonl (op->state->salt); 495 msg->sender_mutator = htonl(op->state->salt);
500 msg->element_xor_hash = op->state->my_xor; 496 msg->element_xor_hash = op->state->my_xor;
501 GNUNET_MQ_send (op->mq, ev); 497 GNUNET_MQ_send(op->mq, ev);
502 } 498 }
503 else 499 else
504 { 500 {
505 /* multipart */ 501 /* multipart */
506 bf_data = GNUNET_malloc (bf_size); 502 bf_data = GNUNET_malloc(bf_size);
507 GNUNET_assert (GNUNET_SYSERR != 503 GNUNET_assert(GNUNET_SYSERR !=
508 GNUNET_CONTAINER_bloomfilter_get_raw_data (op->state->local_bf, 504 GNUNET_CONTAINER_bloomfilter_get_raw_data(op->state->local_bf,
509 bf_data, 505 bf_data,
510 bf_size)); 506 bf_size));
511 offset = 0; 507 offset = 0;
512 while (offset < bf_size) 508 while (offset < bf_size)
513 { 509 {
514 if (bf_size - chunk_size < offset) 510 if (bf_size - chunk_size < offset)
515 chunk_size = bf_size - offset; 511 chunk_size = bf_size - offset;
516 ev = GNUNET_MQ_msg_extra (msg, 512 ev = GNUNET_MQ_msg_extra(msg,
517 chunk_size, 513 chunk_size,
518 GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF); 514 GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF);
519 GNUNET_memcpy (&msg[1], 515 GNUNET_memcpy(&msg[1],
520 &bf_data[offset], 516 &bf_data[offset],
521 chunk_size); 517 chunk_size);
522 offset += chunk_size; 518 offset += chunk_size;
523 msg->sender_element_count = htonl (op->state->my_element_count); 519 msg->sender_element_count = htonl(op->state->my_element_count);
524 msg->bloomfilter_total_length = htonl (bf_size); 520 msg->bloomfilter_total_length = htonl(bf_size);
525 msg->bits_per_element = htonl (bf_elementbits); 521 msg->bits_per_element = htonl(bf_elementbits);
526 msg->sender_mutator = htonl (op->state->salt); 522 msg->sender_mutator = htonl(op->state->salt);
527 msg->element_xor_hash = op->state->my_xor; 523 msg->element_xor_hash = op->state->my_xor;
528 GNUNET_MQ_send (op->mq, ev); 524 GNUNET_MQ_send(op->mq, ev);
525 }
526 GNUNET_free(bf_data);
529 } 527 }
530 GNUNET_free (bf_data); 528 GNUNET_CONTAINER_bloomfilter_free(op->state->local_bf);
531 }
532 GNUNET_CONTAINER_bloomfilter_free (op->state->local_bf);
533 op->state->local_bf = NULL; 529 op->state->local_bf = NULL;
534} 530}
535 531
@@ -541,27 +537,27 @@ send_bloomfilter (struct Operation *op)
541 * @param cls operation to destroy 537 * @param cls operation to destroy
542 */ 538 */
543static void 539static void
544send_client_done_and_destroy (void *cls) 540send_client_done_and_destroy(void *cls)
545{ 541{
546 struct Operation *op = cls; 542 struct Operation *op = cls;
547 struct GNUNET_MQ_Envelope *ev; 543 struct GNUNET_MQ_Envelope *ev;
548 struct GNUNET_SET_ResultMessage *rm; 544 struct GNUNET_SET_ResultMessage *rm;
549 545
550 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 546 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
551 "Intersection succeeded, sending DONE to local client\n"); 547 "Intersection succeeded, sending DONE to local client\n");
552 GNUNET_STATISTICS_update (_GSS_statistics, 548 GNUNET_STATISTICS_update(_GSS_statistics,
553 "# Intersection operations succeeded", 549 "# Intersection operations succeeded",
554 1, 550 1,
555 GNUNET_NO); 551 GNUNET_NO);
556 ev = GNUNET_MQ_msg (rm, 552 ev = GNUNET_MQ_msg(rm,
557 GNUNET_MESSAGE_TYPE_SET_RESULT); 553 GNUNET_MESSAGE_TYPE_SET_RESULT);
558 rm->request_id = htonl (op->client_request_id); 554 rm->request_id = htonl(op->client_request_id);
559 rm->result_status = htons (GNUNET_SET_STATUS_DONE); 555 rm->result_status = htons(GNUNET_SET_STATUS_DONE);
560 rm->element_type = htons (0); 556 rm->element_type = htons(0);
561 GNUNET_MQ_send (op->set->cs->mq, 557 GNUNET_MQ_send(op->set->cs->mq,
562 ev); 558 ev);
563 _GSS_operation_destroy (op, 559 _GSS_operation_destroy(op,
564 GNUNET_YES); 560 GNUNET_YES);
565} 561}
566 562
567 563
@@ -574,12 +570,12 @@ send_client_done_and_destroy (void *cls)
574 * @param cls the `struct Operation`. 570 * @param cls the `struct Operation`.
575 */ 571 */
576static void 572static void
577finished_local_operations (void *cls) 573finished_local_operations(void *cls)
578{ 574{
579 struct Operation *op = cls; 575 struct Operation *op = cls;
580 576
581 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 577 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
582 "DONE sent to other peer, now waiting for other end to close the channel\n"); 578 "DONE sent to other peer, now waiting for other end to close the channel\n");
583 op->state->phase = PHASE_FINISHED; 579 op->state->phase = PHASE_FINISHED;
584 op->state->channel_death_expected = GNUNET_YES; 580 op->state->channel_death_expected = GNUNET_YES;
585} 581}
@@ -593,22 +589,22 @@ finished_local_operations (void *cls)
593 * @param op operation to notify for. 589 * @param op operation to notify for.
594 */ 590 */
595static void 591static void
596send_p2p_done (struct Operation *op) 592send_p2p_done(struct Operation *op)
597{ 593{
598 struct GNUNET_MQ_Envelope *ev; 594 struct GNUNET_MQ_Envelope *ev;
599 struct IntersectionDoneMessage *idm; 595 struct IntersectionDoneMessage *idm;
600 596
601 GNUNET_assert (PHASE_MUST_SEND_DONE == op->state->phase); 597 GNUNET_assert(PHASE_MUST_SEND_DONE == op->state->phase);
602 GNUNET_assert (GNUNET_NO == op->state->channel_death_expected); 598 GNUNET_assert(GNUNET_NO == op->state->channel_death_expected);
603 ev = GNUNET_MQ_msg (idm, 599 ev = GNUNET_MQ_msg(idm,
604 GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE); 600 GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE);
605 idm->final_element_count = htonl (op->state->my_element_count); 601 idm->final_element_count = htonl(op->state->my_element_count);
606 idm->element_xor_hash = op->state->my_xor; 602 idm->element_xor_hash = op->state->my_xor;
607 GNUNET_MQ_notify_sent (ev, 603 GNUNET_MQ_notify_sent(ev,
608 &finished_local_operations, 604 &finished_local_operations,
609 op); 605 op);
610 GNUNET_MQ_send (op->mq, 606 GNUNET_MQ_send(op->mq,
611 ev); 607 ev);
612} 608}
613 609
614 610
@@ -618,7 +614,7 @@ send_p2p_done (struct Operation *op)
618 * @param cls the `struct Operation *` 614 * @param cls the `struct Operation *`
619 */ 615 */
620static void 616static void
621send_remaining_elements (void *cls) 617send_remaining_elements(void *cls)
622{ 618{
623 struct Operation *op = cls; 619 struct Operation *op = cls;
624 const void *nxt; 620 const void *nxt;
@@ -628,52 +624,52 @@ send_remaining_elements (void *cls)
628 const struct GNUNET_SET_Element *element; 624 const struct GNUNET_SET_Element *element;
629 int res; 625 int res;
630 626
631 res = GNUNET_CONTAINER_multihashmap_iterator_next (op->state->full_result_iter, 627 res = GNUNET_CONTAINER_multihashmap_iterator_next(op->state->full_result_iter,
632 NULL, 628 NULL,
633 &nxt); 629 &nxt);
634 if (GNUNET_NO == res) 630 if (GNUNET_NO == res)
635 {
636 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
637 "Sending done and destroy because iterator ran out\n");
638 GNUNET_CONTAINER_multihashmap_iterator_destroy (op->state->full_result_iter);
639 op->state->full_result_iter = NULL;
640 if (PHASE_DONE_RECEIVED == op->state->phase)
641 {
642 op->state->phase = PHASE_FINISHED;
643 send_client_done_and_destroy (op);
644 }
645 else if (PHASE_MUST_SEND_DONE == op->state->phase)
646 {
647 send_p2p_done (op);
648 }
649 else
650 { 631 {
651 GNUNET_assert (0); 632 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
633 "Sending done and destroy because iterator ran out\n");
634 GNUNET_CONTAINER_multihashmap_iterator_destroy(op->state->full_result_iter);
635 op->state->full_result_iter = NULL;
636 if (PHASE_DONE_RECEIVED == op->state->phase)
637 {
638 op->state->phase = PHASE_FINISHED;
639 send_client_done_and_destroy(op);
640 }
641 else if (PHASE_MUST_SEND_DONE == op->state->phase)
642 {
643 send_p2p_done(op);
644 }
645 else
646 {
647 GNUNET_assert(0);
648 }
649 return;
652 } 650 }
653 return;
654 }
655 ee = nxt; 651 ee = nxt;
656 element = &ee->element; 652 element = &ee->element;
657 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 653 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
658 "Sending element %s:%u to client (full set)\n", 654 "Sending element %s:%u to client (full set)\n",
659 GNUNET_h2s (&ee->element_hash), 655 GNUNET_h2s(&ee->element_hash),
660 element->size); 656 element->size);
661 GNUNET_assert (0 != op->client_request_id); 657 GNUNET_assert(0 != op->client_request_id);
662 ev = GNUNET_MQ_msg_extra (rm, 658 ev = GNUNET_MQ_msg_extra(rm,
663 element->size, 659 element->size,
664 GNUNET_MESSAGE_TYPE_SET_RESULT); 660 GNUNET_MESSAGE_TYPE_SET_RESULT);
665 GNUNET_assert (NULL != ev); 661 GNUNET_assert(NULL != ev);
666 rm->result_status = htons (GNUNET_SET_STATUS_OK); 662 rm->result_status = htons(GNUNET_SET_STATUS_OK);
667 rm->request_id = htonl (op->client_request_id); 663 rm->request_id = htonl(op->client_request_id);
668 rm->element_type = element->element_type; 664 rm->element_type = element->element_type;
669 GNUNET_memcpy (&rm[1], 665 GNUNET_memcpy(&rm[1],
670 element->data, 666 element->data,
671 element->size); 667 element->size);
672 GNUNET_MQ_notify_sent (ev, 668 GNUNET_MQ_notify_sent(ev,
673 &send_remaining_elements, 669 &send_remaining_elements,
674 op); 670 op);
675 GNUNET_MQ_send (op->set->cs->mq, 671 GNUNET_MQ_send(op->set->cs->mq,
676 ev); 672 ev);
677} 673}
678 674
679 675
@@ -687,27 +683,27 @@ send_remaining_elements (void *cls)
687 * @return #GNUNET_YES (we should continue to iterate) 683 * @return #GNUNET_YES (we should continue to iterate)
688 */ 684 */
689static int 685static int
690initialize_map_unfiltered (void *cls, 686initialize_map_unfiltered(void *cls,
691 const struct GNUNET_HashCode *key, 687 const struct GNUNET_HashCode *key,
692 void *value) 688 void *value)
693{ 689{
694 struct ElementEntry *ee = value; 690 struct ElementEntry *ee = value;
695 struct Operation *op = cls; 691 struct Operation *op = cls;
696 692
697 if (GNUNET_NO == _GSS_is_element_of_operation (ee, op)) 693 if (GNUNET_NO == _GSS_is_element_of_operation(ee, op))
698 return GNUNET_YES; /* element not live in operation's generation */ 694 return GNUNET_YES; /* element not live in operation's generation */
699 GNUNET_CRYPTO_hash_xor (&op->state->my_xor, 695 GNUNET_CRYPTO_hash_xor(&op->state->my_xor,
700 &ee->element_hash, 696 &ee->element_hash,
701 &op->state->my_xor); 697 &op->state->my_xor);
702 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 698 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
703 "Initial full initialization of my_elements, adding %s:%u\n", 699 "Initial full initialization of my_elements, adding %s:%u\n",
704 GNUNET_h2s (&ee->element_hash), 700 GNUNET_h2s(&ee->element_hash),
705 ee->element.size); 701 ee->element.size);
706 GNUNET_break (GNUNET_YES == 702 GNUNET_break(GNUNET_YES ==
707 GNUNET_CONTAINER_multihashmap_put (op->state->my_elements, 703 GNUNET_CONTAINER_multihashmap_put(op->state->my_elements,
708 &ee->element_hash, 704 &ee->element_hash,
709 ee, 705 ee,
710 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 706 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
711 return GNUNET_YES; 707 return GNUNET_YES;
712} 708}
713 709
@@ -719,18 +715,18 @@ initialize_map_unfiltered (void *cls,
719 * @param op intersection operation 715 * @param op intersection operation
720 */ 716 */
721static void 717static void
722send_element_count (struct Operation *op) 718send_element_count(struct Operation *op)
723{ 719{
724 struct GNUNET_MQ_Envelope *ev; 720 struct GNUNET_MQ_Envelope *ev;
725 struct IntersectionElementInfoMessage *msg; 721 struct IntersectionElementInfoMessage *msg;
726 722
727 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 723 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
728 "Sending our element count (%u)\n", 724 "Sending our element count (%u)\n",
729 op->state->my_element_count); 725 op->state->my_element_count);
730 ev = GNUNET_MQ_msg (msg, 726 ev = GNUNET_MQ_msg(msg,
731 GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO); 727 GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO);
732 msg->sender_element_count = htonl (op->state->my_element_count); 728 msg->sender_element_count = htonl(op->state->my_element_count);
733 GNUNET_MQ_send (op->mq, ev); 729 GNUNET_MQ_send(op->mq, ev);
734} 730}
735 731
736 732
@@ -741,13 +737,13 @@ send_element_count (struct Operation *op)
741 * @param op operation to start exchange for 737 * @param op operation to start exchange for
742 */ 738 */
743static void 739static void
744begin_bf_exchange (struct Operation *op) 740begin_bf_exchange(struct Operation *op)
745{ 741{
746 op->state->phase = PHASE_BF_EXCHANGE; 742 op->state->phase = PHASE_BF_EXCHANGE;
747 GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements, 743 GNUNET_CONTAINER_multihashmap_iterate(op->set->content->elements,
748 &initialize_map_unfiltered, 744 &initialize_map_unfiltered,
749 op); 745 op);
750 send_bloomfilter (op); 746 send_bloomfilter(op);
751} 747}
752 748
753 749
@@ -759,35 +755,35 @@ begin_bf_exchange (struct Operation *op)
759 * @param mh the header of the message 755 * @param mh the header of the message
760 */ 756 */
761void 757void
762handle_intersection_p2p_element_info (void *cls, 758handle_intersection_p2p_element_info(void *cls,
763 const struct IntersectionElementInfoMessage *msg) 759 const struct IntersectionElementInfoMessage *msg)
764{ 760{
765 struct Operation *op = cls; 761 struct Operation *op = cls;
766 762
767 if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation) 763 if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation)
768 { 764 {
769 GNUNET_break_op (0); 765 GNUNET_break_op(0);
770 fail_intersection_operation(op); 766 fail_intersection_operation(op);
771 return; 767 return;
772 } 768 }
773 op->remote_element_count = ntohl (msg->sender_element_count); 769 op->remote_element_count = ntohl(msg->sender_element_count);
774 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 770 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
775 "Received remote element count (%u), I have %u\n", 771 "Received remote element count (%u), I have %u\n",
776 op->remote_element_count, 772 op->remote_element_count,
777 op->state->my_element_count); 773 op->state->my_element_count);
778 if ( ( (PHASE_INITIAL != op->state->phase) && 774 if (((PHASE_INITIAL != op->state->phase) &&
779 (PHASE_COUNT_SENT != op->state->phase) ) || 775 (PHASE_COUNT_SENT != op->state->phase)) ||
780 (op->state->my_element_count > op->remote_element_count) || 776 (op->state->my_element_count > op->remote_element_count) ||
781 (0 == op->state->my_element_count) || 777 (0 == op->state->my_element_count) ||
782 (0 == op->remote_element_count) ) 778 (0 == op->remote_element_count))
783 { 779 {
784 GNUNET_break_op (0); 780 GNUNET_break_op(0);
785 fail_intersection_operation(op); 781 fail_intersection_operation(op);
786 return; 782 return;
787 } 783 }
788 GNUNET_break (NULL == op->state->remote_bf); 784 GNUNET_break(NULL == op->state->remote_bf);
789 begin_bf_exchange (op); 785 begin_bf_exchange(op);
790 GNUNET_CADET_receive_done (op->channel); 786 GNUNET_CADET_receive_done(op->channel);
791} 787}
792 788
793 789
@@ -797,76 +793,81 @@ handle_intersection_p2p_element_info (void *cls,
797 * @param op the intersection operation 793 * @param op the intersection operation
798 */ 794 */
799static void 795static void
800process_bf (struct Operation *op) 796process_bf(struct Operation *op)
801{ 797{
802 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 798 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
803 "Received BF in phase %u, foreign count is %u, my element count is %u/%u\n", 799 "Received BF in phase %u, foreign count is %u, my element count is %u/%u\n",
804 op->state->phase, 800 op->state->phase,
805 op->remote_element_count, 801 op->remote_element_count,
806 op->state->my_element_count, 802 op->state->my_element_count,
807 GNUNET_CONTAINER_multihashmap_size (op->set->content->elements)); 803 GNUNET_CONTAINER_multihashmap_size(op->set->content->elements));
808 switch (op->state->phase) 804 switch (op->state->phase)
809 { 805 {
810 case PHASE_INITIAL: 806 case PHASE_INITIAL:
811 GNUNET_break_op (0); 807 GNUNET_break_op(0);
812 fail_intersection_operation(op); 808 fail_intersection_operation(op);
813 return; 809 return;
814 case PHASE_COUNT_SENT: 810
815 /* This is the first BF being sent, build our initial map with 811 case PHASE_COUNT_SENT:
816 filtering in place */ 812 /* This is the first BF being sent, build our initial map with
817 op->state->my_element_count = 0; 813 filtering in place */
818 GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements, 814 op->state->my_element_count = 0;
819 &filtered_map_initialization, 815 GNUNET_CONTAINER_multihashmap_iterate(op->set->content->elements,
820 op); 816 &filtered_map_initialization,
821 break; 817 op);
822 case PHASE_BF_EXCHANGE: 818 break;
823 /* Update our set by reduction */ 819
824 GNUNET_CONTAINER_multihashmap_iterate (op->state->my_elements, 820 case PHASE_BF_EXCHANGE:
825 &iterator_bf_reduce, 821 /* Update our set by reduction */
826 op); 822 GNUNET_CONTAINER_multihashmap_iterate(op->state->my_elements,
827 break; 823 &iterator_bf_reduce,
828 case PHASE_MUST_SEND_DONE: 824 op);
829 GNUNET_break_op (0); 825 break;
830 fail_intersection_operation(op); 826
831 return; 827 case PHASE_MUST_SEND_DONE:
832 case PHASE_DONE_RECEIVED: 828 GNUNET_break_op(0);
833 GNUNET_break_op (0); 829 fail_intersection_operation(op);
834 fail_intersection_operation(op); 830 return;
835 return; 831
836 case PHASE_FINISHED: 832 case PHASE_DONE_RECEIVED:
837 GNUNET_break_op (0); 833 GNUNET_break_op(0);
838 fail_intersection_operation(op); 834 fail_intersection_operation(op);
839 return; 835 return;
840 } 836
841 GNUNET_CONTAINER_bloomfilter_free (op->state->remote_bf); 837 case PHASE_FINISHED:
838 GNUNET_break_op(0);
839 fail_intersection_operation(op);
840 return;
841 }
842 GNUNET_CONTAINER_bloomfilter_free(op->state->remote_bf);
842 op->state->remote_bf = NULL; 843 op->state->remote_bf = NULL;
843 844
844 if ( (0 == op->state->my_element_count) || /* fully disjoint */ 845 if ((0 == op->state->my_element_count) || /* fully disjoint */
845 ( (op->state->my_element_count == op->remote_element_count) && 846 ((op->state->my_element_count == op->remote_element_count) &&
846 (0 == GNUNET_memcmp (&op->state->my_xor, 847 (0 == GNUNET_memcmp(&op->state->my_xor,
847 &op->state->other_xor)) ) ) 848 &op->state->other_xor))))
848 {
849 /* we are done */
850 op->state->phase = PHASE_MUST_SEND_DONE;
851 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
852 "Intersection succeeded, sending DONE to other peer\n");
853 GNUNET_CONTAINER_bloomfilter_free (op->state->local_bf);
854 op->state->local_bf = NULL;
855 if (GNUNET_SET_RESULT_FULL == op->result_mode)
856 { 849 {
857 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 850 /* we are done */
858 "Sending full result set (%u elements)\n", 851 op->state->phase = PHASE_MUST_SEND_DONE;
859 GNUNET_CONTAINER_multihashmap_size (op->state->my_elements)); 852 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
860 op->state->full_result_iter 853 "Intersection succeeded, sending DONE to other peer\n");
861 = GNUNET_CONTAINER_multihashmap_iterator_create (op->state->my_elements); 854 GNUNET_CONTAINER_bloomfilter_free(op->state->local_bf);
862 send_remaining_elements (op); 855 op->state->local_bf = NULL;
856 if (GNUNET_SET_RESULT_FULL == op->result_mode)
857 {
858 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
859 "Sending full result set (%u elements)\n",
860 GNUNET_CONTAINER_multihashmap_size(op->state->my_elements));
861 op->state->full_result_iter
862 = GNUNET_CONTAINER_multihashmap_iterator_create(op->state->my_elements);
863 send_remaining_elements(op);
864 return;
865 }
866 send_p2p_done(op);
863 return; 867 return;
864 } 868 }
865 send_p2p_done (op);
866 return;
867 }
868 op->state->phase = PHASE_BF_EXCHANGE; 869 op->state->phase = PHASE_BF_EXCHANGE;
869 send_bloomfilter (op); 870 send_bloomfilter(op);
870} 871}
871 872
872 873
@@ -878,16 +879,16 @@ process_bf (struct Operation *op)
878 * @return #GNUNET_OK if @a msg is well-formed 879 * @return #GNUNET_OK if @a msg is well-formed
879 */ 880 */
880int 881int
881check_intersection_p2p_bf (void *cls, 882check_intersection_p2p_bf(void *cls,
882 const struct BFMessage *msg) 883 const struct BFMessage *msg)
883{ 884{
884 struct Operation *op = cls; 885 struct Operation *op = cls;
885 886
886 if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation) 887 if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation)
887 { 888 {
888 GNUNET_break_op (0); 889 GNUNET_break_op(0);
889 return GNUNET_SYSERR; 890 return GNUNET_SYSERR;
890 } 891 }
891 return GNUNET_OK; 892 return GNUNET_OK;
892} 893}
893 894
@@ -899,8 +900,8 @@ check_intersection_p2p_bf (void *cls,
899 * @param msg the header of the message 900 * @param msg the header of the message
900 */ 901 */
901void 902void
902handle_intersection_p2p_bf (void *cls, 903handle_intersection_p2p_bf(void *cls,
903 const struct BFMessage *msg) 904 const struct BFMessage *msg)
904{ 905{
905 struct Operation *op = cls; 906 struct Operation *op = cls;
906 uint32_t bf_size; 907 uint32_t bf_size;
@@ -908,83 +909,85 @@ handle_intersection_p2p_bf (void *cls,
908 uint32_t bf_bits_per_element; 909 uint32_t bf_bits_per_element;
909 910
910 switch (op->state->phase) 911 switch (op->state->phase)
911 {
912 case PHASE_INITIAL:
913 GNUNET_break_op (0);
914 fail_intersection_operation (op);
915 return;
916 case PHASE_COUNT_SENT:
917 case PHASE_BF_EXCHANGE:
918 bf_size = ntohl (msg->bloomfilter_total_length);
919 bf_bits_per_element = ntohl (msg->bits_per_element);
920 chunk_size = htons (msg->header.size) - sizeof (struct BFMessage);
921 op->state->other_xor = msg->element_xor_hash;
922 if (bf_size == chunk_size)
923 { 912 {
924 if (NULL != op->state->bf_data) 913 case PHASE_INITIAL:
925 { 914 GNUNET_break_op(0);
926 GNUNET_break_op (0); 915 fail_intersection_operation(op);
927 fail_intersection_operation (op); 916 return;
928 return; 917
929 } 918 case PHASE_COUNT_SENT:
930 /* single part, done here immediately */ 919 case PHASE_BF_EXCHANGE:
931 op->state->remote_bf 920 bf_size = ntohl(msg->bloomfilter_total_length);
932 = GNUNET_CONTAINER_bloomfilter_init ((const char*) &msg[1], 921 bf_bits_per_element = ntohl(msg->bits_per_element);
933 bf_size, 922 chunk_size = htons(msg->header.size) - sizeof(struct BFMessage);
934 bf_bits_per_element); 923 op->state->other_xor = msg->element_xor_hash;
935 op->state->salt = ntohl (msg->sender_mutator); 924 if (bf_size == chunk_size)
936 op->remote_element_count = ntohl (msg->sender_element_count); 925 {
937 process_bf (op); 926 if (NULL != op->state->bf_data)
927 {
928 GNUNET_break_op(0);
929 fail_intersection_operation(op);
930 return;
931 }
932 /* single part, done here immediately */
933 op->state->remote_bf
934 = GNUNET_CONTAINER_bloomfilter_init((const char*)&msg[1],
935 bf_size,
936 bf_bits_per_element);
937 op->state->salt = ntohl(msg->sender_mutator);
938 op->remote_element_count = ntohl(msg->sender_element_count);
939 process_bf(op);
940 break;
941 }
942 /* multipart chunk */
943 if (NULL == op->state->bf_data)
944 {
945 /* first chunk, initialize */
946 op->state->bf_data = GNUNET_malloc(bf_size);
947 op->state->bf_data_size = bf_size;
948 op->state->bf_bits_per_element = bf_bits_per_element;
949 op->state->bf_data_offset = 0;
950 op->state->salt = ntohl(msg->sender_mutator);
951 op->remote_element_count = ntohl(msg->sender_element_count);
952 }
953 else
954 {
955 /* increment */
956 if ((op->state->bf_data_size != bf_size) ||
957 (op->state->bf_bits_per_element != bf_bits_per_element) ||
958 (op->state->bf_data_offset + chunk_size > bf_size) ||
959 (op->state->salt != ntohl(msg->sender_mutator)) ||
960 (op->remote_element_count != ntohl(msg->sender_element_count)))
961 {
962 GNUNET_break_op(0);
963 fail_intersection_operation(op);
964 return;
965 }
966 }
967 GNUNET_memcpy(&op->state->bf_data[op->state->bf_data_offset],
968 (const char*)&msg[1],
969 chunk_size);
970 op->state->bf_data_offset += chunk_size;
971 if (op->state->bf_data_offset == bf_size)
972 {
973 /* last chunk, run! */
974 op->state->remote_bf
975 = GNUNET_CONTAINER_bloomfilter_init(op->state->bf_data,
976 bf_size,
977 bf_bits_per_element);
978 GNUNET_free(op->state->bf_data);
979 op->state->bf_data = NULL;
980 op->state->bf_data_size = 0;
981 process_bf(op);
982 }
938 break; 983 break;
984
985 default:
986 GNUNET_break_op(0);
987 fail_intersection_operation(op);
988 return;
939 } 989 }
940 /* multipart chunk */ 990 GNUNET_CADET_receive_done(op->channel);
941 if (NULL == op->state->bf_data)
942 {
943 /* first chunk, initialize */
944 op->state->bf_data = GNUNET_malloc (bf_size);
945 op->state->bf_data_size = bf_size;
946 op->state->bf_bits_per_element = bf_bits_per_element;
947 op->state->bf_data_offset = 0;
948 op->state->salt = ntohl (msg->sender_mutator);
949 op->remote_element_count = ntohl (msg->sender_element_count);
950 }
951 else
952 {
953 /* increment */
954 if ( (op->state->bf_data_size != bf_size) ||
955 (op->state->bf_bits_per_element != bf_bits_per_element) ||
956 (op->state->bf_data_offset + chunk_size > bf_size) ||
957 (op->state->salt != ntohl (msg->sender_mutator)) ||
958 (op->remote_element_count != ntohl (msg->sender_element_count)) )
959 {
960 GNUNET_break_op (0);
961 fail_intersection_operation (op);
962 return;
963 }
964 }
965 GNUNET_memcpy (&op->state->bf_data[op->state->bf_data_offset],
966 (const char*) &msg[1],
967 chunk_size);
968 op->state->bf_data_offset += chunk_size;
969 if (op->state->bf_data_offset == bf_size)
970 {
971 /* last chunk, run! */
972 op->state->remote_bf
973 = GNUNET_CONTAINER_bloomfilter_init (op->state->bf_data,
974 bf_size,
975 bf_bits_per_element);
976 GNUNET_free (op->state->bf_data);
977 op->state->bf_data = NULL;
978 op->state->bf_data_size = 0;
979 process_bf (op);
980 }
981 break;
982 default:
983 GNUNET_break_op (0);
984 fail_intersection_operation (op);
985 return;
986 }
987 GNUNET_CADET_receive_done (op->channel);
988} 991}
989 992
990 993
@@ -997,28 +1000,28 @@ handle_intersection_p2p_bf (void *cls,
997 * @return #GNUNET_YES (we should continue to iterate) 1000 * @return #GNUNET_YES (we should continue to iterate)
998 */ 1001 */
999static int 1002static int
1000filter_all (void *cls, 1003filter_all(void *cls,
1001 const struct GNUNET_HashCode *key, 1004 const struct GNUNET_HashCode *key,
1002 void *value) 1005 void *value)
1003{ 1006{
1004 struct Operation *op = cls; 1007 struct Operation *op = cls;
1005 struct ElementEntry *ee = value; 1008 struct ElementEntry *ee = value;
1006 1009
1007 GNUNET_break (0 < op->state->my_element_count); 1010 GNUNET_break(0 < op->state->my_element_count);
1008 op->state->my_element_count--; 1011 op->state->my_element_count--;
1009 GNUNET_CRYPTO_hash_xor (&op->state->my_xor, 1012 GNUNET_CRYPTO_hash_xor(&op->state->my_xor,
1010 &ee->element_hash, 1013 &ee->element_hash,
1011 &op->state->my_xor); 1014 &op->state->my_xor);
1012 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1015 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1013 "Final reduction of my_elements, removing %s:%u\n", 1016 "Final reduction of my_elements, removing %s:%u\n",
1014 GNUNET_h2s (&ee->element_hash), 1017 GNUNET_h2s(&ee->element_hash),
1015 ee->element.size); 1018 ee->element.size);
1016 GNUNET_assert (GNUNET_YES == 1019 GNUNET_assert(GNUNET_YES ==
1017 GNUNET_CONTAINER_multihashmap_remove (op->state->my_elements, 1020 GNUNET_CONTAINER_multihashmap_remove(op->state->my_elements,
1018 &ee->element_hash, 1021 &ee->element_hash,
1019 ee)); 1022 ee));
1020 send_client_removed_element (op, 1023 send_client_removed_element(op,
1021 &ee->element); 1024 &ee->element);
1022 return GNUNET_YES; 1025 return GNUNET_YES;
1023} 1026}
1024 1027
@@ -1030,61 +1033,61 @@ filter_all (void *cls,
1030 * @param mh the message 1033 * @param mh the message
1031 */ 1034 */
1032void 1035void
1033handle_intersection_p2p_done (void *cls, 1036handle_intersection_p2p_done(void *cls,
1034 const struct IntersectionDoneMessage *idm) 1037 const struct IntersectionDoneMessage *idm)
1035{ 1038{
1036 struct Operation *op = cls; 1039 struct Operation *op = cls;
1037 1040
1038 if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation) 1041 if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation)
1039 { 1042 {
1040 GNUNET_break_op (0); 1043 GNUNET_break_op(0);
1041 fail_intersection_operation (op); 1044 fail_intersection_operation(op);
1042 return; 1045 return;
1043 } 1046 }
1044 if (PHASE_BF_EXCHANGE != op->state->phase) 1047 if (PHASE_BF_EXCHANGE != op->state->phase)
1045 { 1048 {
1046 /* wrong phase to conclude? FIXME: Or should we allow this 1049 /* wrong phase to conclude? FIXME: Or should we allow this
1047 if the other peer has _initially_ already an empty set? */ 1050 if the other peer has _initially_ already an empty set? */
1048 GNUNET_break_op (0); 1051 GNUNET_break_op(0);
1049 fail_intersection_operation (op); 1052 fail_intersection_operation(op);
1050 return; 1053 return;
1051 } 1054 }
1052 if (0 == ntohl (idm->final_element_count)) 1055 if (0 == ntohl(idm->final_element_count))
1053 { 1056 {
1054 /* other peer determined empty set is the intersection, 1057 /* other peer determined empty set is the intersection,
1055 remove all elements */ 1058 remove all elements */
1056 GNUNET_CONTAINER_multihashmap_iterate (op->state->my_elements, 1059 GNUNET_CONTAINER_multihashmap_iterate(op->state->my_elements,
1057 &filter_all, 1060 &filter_all,
1058 op); 1061 op);
1059 } 1062 }
1060 if ( (op->state->my_element_count != ntohl (idm->final_element_count)) || 1063 if ((op->state->my_element_count != ntohl(idm->final_element_count)) ||
1061 (0 != GNUNET_memcmp (&op->state->my_xor, 1064 (0 != GNUNET_memcmp(&op->state->my_xor,
1062 &idm->element_xor_hash)) ) 1065 &idm->element_xor_hash)))
1063 { 1066 {
1064 /* Other peer thinks we are done, but we disagree on the result! */ 1067 /* Other peer thinks we are done, but we disagree on the result! */
1065 GNUNET_break_op (0); 1068 GNUNET_break_op(0);
1066 fail_intersection_operation (op); 1069 fail_intersection_operation(op);
1067 return; 1070 return;
1068 } 1071 }
1069 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1072 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1070 "Got IntersectionDoneMessage, have %u elements in intersection\n", 1073 "Got IntersectionDoneMessage, have %u elements in intersection\n",
1071 op->state->my_element_count); 1074 op->state->my_element_count);
1072 op->state->phase = PHASE_DONE_RECEIVED; 1075 op->state->phase = PHASE_DONE_RECEIVED;
1073 GNUNET_CADET_receive_done (op->channel); 1076 GNUNET_CADET_receive_done(op->channel);
1074 1077
1075 GNUNET_assert (GNUNET_NO == op->state->client_done_sent); 1078 GNUNET_assert(GNUNET_NO == op->state->client_done_sent);
1076 if (GNUNET_SET_RESULT_FULL == op->result_mode) 1079 if (GNUNET_SET_RESULT_FULL == op->result_mode)
1077 { 1080 {
1078 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1081 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1079 "Sending full result set to client (%u elements)\n", 1082 "Sending full result set to client (%u elements)\n",
1080 GNUNET_CONTAINER_multihashmap_size (op->state->my_elements)); 1083 GNUNET_CONTAINER_multihashmap_size(op->state->my_elements));
1081 op->state->full_result_iter 1084 op->state->full_result_iter
1082 = GNUNET_CONTAINER_multihashmap_iterator_create (op->state->my_elements); 1085 = GNUNET_CONTAINER_multihashmap_iterator_create(op->state->my_elements);
1083 send_remaining_elements (op); 1086 send_remaining_elements(op);
1084 return; 1087 return;
1085 } 1088 }
1086 op->state->phase = PHASE_FINISHED; 1089 op->state->phase = PHASE_FINISHED;
1087 send_client_done_and_destroy (op); 1090 send_client_done_and_destroy(op);
1088} 1091}
1089 1092
1090 1093
@@ -1098,43 +1101,43 @@ handle_intersection_p2p_done (void *cls,
1098 * @return operation-specific state to keep in @a op 1101 * @return operation-specific state to keep in @a op
1099 */ 1102 */
1100static struct OperationState * 1103static struct OperationState *
1101intersection_evaluate (struct Operation *op, 1104intersection_evaluate(struct Operation *op,
1102 const struct GNUNET_MessageHeader *opaque_context) 1105 const struct GNUNET_MessageHeader *opaque_context)
1103{ 1106{
1104 struct OperationState *state; 1107 struct OperationState *state;
1105 struct GNUNET_MQ_Envelope *ev; 1108 struct GNUNET_MQ_Envelope *ev;
1106 struct OperationRequestMessage *msg; 1109 struct OperationRequestMessage *msg;
1107 1110
1108 ev = GNUNET_MQ_msg_nested_mh (msg, 1111 ev = GNUNET_MQ_msg_nested_mh(msg,
1109 GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST, 1112 GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST,
1110 opaque_context); 1113 opaque_context);
1111 if (NULL == ev) 1114 if (NULL == ev)
1112 { 1115 {
1113 /* the context message is too large!? */ 1116 /* the context message is too large!? */
1114 GNUNET_break (0); 1117 GNUNET_break(0);
1115 return NULL; 1118 return NULL;
1116 } 1119 }
1117 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1120 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1118 "Initiating intersection operation evaluation\n"); 1121 "Initiating intersection operation evaluation\n");
1119 state = GNUNET_new (struct OperationState); 1122 state = GNUNET_new(struct OperationState);
1120 /* we started the operation, thus we have to send the operation request */ 1123 /* we started the operation, thus we have to send the operation request */
1121 state->phase = PHASE_INITIAL; 1124 state->phase = PHASE_INITIAL;
1122 state->my_element_count = op->set->state->current_set_element_count; 1125 state->my_element_count = op->set->state->current_set_element_count;
1123 state->my_elements 1126 state->my_elements
1124 = GNUNET_CONTAINER_multihashmap_create (state->my_element_count, 1127 = GNUNET_CONTAINER_multihashmap_create(state->my_element_count,
1125 GNUNET_YES); 1128 GNUNET_YES);
1126 1129
1127 msg->operation = htonl (GNUNET_SET_OPERATION_INTERSECTION); 1130 msg->operation = htonl(GNUNET_SET_OPERATION_INTERSECTION);
1128 msg->element_count = htonl (state->my_element_count); 1131 msg->element_count = htonl(state->my_element_count);
1129 GNUNET_MQ_send (op->mq, 1132 GNUNET_MQ_send(op->mq,
1130 ev); 1133 ev);
1131 state->phase = PHASE_COUNT_SENT; 1134 state->phase = PHASE_COUNT_SENT;
1132 if (NULL != opaque_context) 1135 if (NULL != opaque_context)
1133 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1136 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1134 "Sent op request with context message\n"); 1137 "Sent op request with context message\n");
1135 else 1138 else
1136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1139 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1137 "Sent op request without context message\n"); 1140 "Sent op request without context message\n");
1138 return state; 1141 return state;
1139} 1142}
1140 1143
@@ -1146,31 +1149,31 @@ intersection_evaluate (struct Operation *op,
1146 * @param op operation that will be accepted as an intersection operation 1149 * @param op operation that will be accepted as an intersection operation
1147 */ 1150 */
1148static struct OperationState * 1151static struct OperationState *
1149intersection_accept (struct Operation *op) 1152intersection_accept(struct Operation *op)
1150{ 1153{
1151 struct OperationState *state; 1154 struct OperationState *state;
1152 1155
1153 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1156 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1154 "Accepting set intersection operation\n"); 1157 "Accepting set intersection operation\n");
1155 state = GNUNET_new (struct OperationState); 1158 state = GNUNET_new(struct OperationState);
1156 state->phase = PHASE_INITIAL; 1159 state->phase = PHASE_INITIAL;
1157 state->my_element_count 1160 state->my_element_count
1158 = op->set->state->current_set_element_count; 1161 = op->set->state->current_set_element_count;
1159 state->my_elements 1162 state->my_elements
1160 = GNUNET_CONTAINER_multihashmap_create (GNUNET_MIN (state->my_element_count, 1163 = GNUNET_CONTAINER_multihashmap_create(GNUNET_MIN(state->my_element_count,
1161 op->remote_element_count), 1164 op->remote_element_count),
1162 GNUNET_YES); 1165 GNUNET_YES);
1163 op->state = state; 1166 op->state = state;
1164 if (op->remote_element_count < state->my_element_count) 1167 if (op->remote_element_count < state->my_element_count)
1165 { 1168 {
1166 /* If the other peer (Alice) has fewer elements than us (Bob), 1169 /* If the other peer (Alice) has fewer elements than us (Bob),
1167 we just send the count as Alice should send the first BF */ 1170 we just send the count as Alice should send the first BF */
1168 send_element_count (op); 1171 send_element_count(op);
1169 state->phase = PHASE_COUNT_SENT; 1172 state->phase = PHASE_COUNT_SENT;
1170 return state; 1173 return state;
1171 } 1174 }
1172 /* We have fewer elements, so we start with the BF */ 1175 /* We have fewer elements, so we start with the BF */
1173 begin_bf_exchange (op); 1176 begin_bf_exchange(op);
1174 return state; 1177 return state;
1175} 1178}
1176 1179
@@ -1182,34 +1185,34 @@ intersection_accept (struct Operation *op)
1182 * @param op intersection operation to destroy 1185 * @param op intersection operation to destroy
1183 */ 1186 */
1184static void 1187static void
1185intersection_op_cancel (struct Operation *op) 1188intersection_op_cancel(struct Operation *op)
1186{ 1189{
1187 /* check if the op was canceled twice */ 1190 /* check if the op was canceled twice */
1188 GNUNET_assert (NULL != op->state); 1191 GNUNET_assert(NULL != op->state);
1189 if (NULL != op->state->remote_bf) 1192 if (NULL != op->state->remote_bf)
1190 { 1193 {
1191 GNUNET_CONTAINER_bloomfilter_free (op->state->remote_bf); 1194 GNUNET_CONTAINER_bloomfilter_free(op->state->remote_bf);
1192 op->state->remote_bf = NULL; 1195 op->state->remote_bf = NULL;
1193 } 1196 }
1194 if (NULL != op->state->local_bf) 1197 if (NULL != op->state->local_bf)
1195 { 1198 {
1196 GNUNET_CONTAINER_bloomfilter_free (op->state->local_bf); 1199 GNUNET_CONTAINER_bloomfilter_free(op->state->local_bf);
1197 op->state->local_bf = NULL; 1200 op->state->local_bf = NULL;
1198 } 1201 }
1199 if (NULL != op->state->my_elements) 1202 if (NULL != op->state->my_elements)
1200 { 1203 {
1201 GNUNET_CONTAINER_multihashmap_destroy (op->state->my_elements); 1204 GNUNET_CONTAINER_multihashmap_destroy(op->state->my_elements);
1202 op->state->my_elements = NULL; 1205 op->state->my_elements = NULL;
1203 } 1206 }
1204 if (NULL != op->state->full_result_iter) 1207 if (NULL != op->state->full_result_iter)
1205 { 1208 {
1206 GNUNET_CONTAINER_multihashmap_iterator_destroy (op->state->full_result_iter); 1209 GNUNET_CONTAINER_multihashmap_iterator_destroy(op->state->full_result_iter);
1207 op->state->full_result_iter = NULL; 1210 op->state->full_result_iter = NULL;
1208 } 1211 }
1209 GNUNET_free (op->state); 1212 GNUNET_free(op->state);
1210 op->state = NULL; 1213 op->state = NULL;
1211 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1214 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1212 "Destroying intersection op state done\n"); 1215 "Destroying intersection op state done\n");
1213} 1216}
1214 1217
1215 1218
@@ -1219,13 +1222,13 @@ intersection_op_cancel (struct Operation *op)
1219 * @return the newly created set 1222 * @return the newly created set
1220 */ 1223 */
1221static struct SetState * 1224static struct SetState *
1222intersection_set_create () 1225intersection_set_create()
1223{ 1226{
1224 struct SetState *set_state; 1227 struct SetState *set_state;
1225 1228
1226 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1229 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1227 "Intersection set created\n"); 1230 "Intersection set created\n");
1228 set_state = GNUNET_new (struct SetState); 1231 set_state = GNUNET_new(struct SetState);
1229 set_state->current_set_element_count = 0; 1232 set_state->current_set_element_count = 0;
1230 1233
1231 return set_state; 1234 return set_state;
@@ -1239,8 +1242,8 @@ intersection_set_create ()
1239 * @param ee the element to add to the set 1242 * @param ee the element to add to the set
1240 */ 1243 */
1241static void 1244static void
1242intersection_add (struct SetState *set_state, 1245intersection_add(struct SetState *set_state,
1243 struct ElementEntry *ee) 1246 struct ElementEntry *ee)
1244{ 1247{
1245 set_state->current_set_element_count++; 1248 set_state->current_set_element_count++;
1246} 1249}
@@ -1252,9 +1255,9 @@ intersection_add (struct SetState *set_state,
1252 * @param set_state the set to destroy 1255 * @param set_state the set to destroy
1253 */ 1256 */
1254static void 1257static void
1255intersection_set_destroy (struct SetState *set_state) 1258intersection_set_destroy(struct SetState *set_state)
1256{ 1259{
1257 GNUNET_free (set_state); 1260 GNUNET_free(set_state);
1258} 1261}
1259 1262
1260 1263
@@ -1265,10 +1268,10 @@ intersection_set_destroy (struct SetState *set_state)
1265 * @param element set element to remove 1268 * @param element set element to remove
1266 */ 1269 */
1267static void 1270static void
1268intersection_remove (struct SetState *set_state, 1271intersection_remove(struct SetState *set_state,
1269 struct ElementEntry *element) 1272 struct ElementEntry *element)
1270{ 1273{
1271 GNUNET_assert (0 < set_state->current_set_element_count); 1274 GNUNET_assert(0 < set_state->current_set_element_count);
1272 set_state->current_set_element_count--; 1275 set_state->current_set_element_count--;
1273} 1276}
1274 1277
@@ -1279,19 +1282,19 @@ intersection_remove (struct SetState *set_state,
1279 * @param op operation that lost the channel 1282 * @param op operation that lost the channel
1280 */ 1283 */
1281static void 1284static void
1282intersection_channel_death (struct Operation *op) 1285intersection_channel_death(struct Operation *op)
1283{ 1286{
1284 if (GNUNET_YES == op->state->channel_death_expected) 1287 if (GNUNET_YES == op->state->channel_death_expected)
1285 { 1288 {
1286 /* oh goodie, we are done! */ 1289 /* oh goodie, we are done! */
1287 send_client_done_and_destroy (op); 1290 send_client_done_and_destroy(op);
1288 } 1291 }
1289 else 1292 else
1290 { 1293 {
1291 /* sorry, channel went down early, too bad. */ 1294 /* sorry, channel went down early, too bad. */
1292 _GSS_operation_destroy (op, 1295 _GSS_operation_destroy(op,
1293 GNUNET_YES); 1296 GNUNET_YES);
1294 } 1297 }
1295} 1298}
1296 1299
1297 1300
@@ -1301,7 +1304,7 @@ intersection_channel_death (struct Operation *op)
1301 * @return the operation specific VTable 1304 * @return the operation specific VTable
1302 */ 1305 */
1303const struct SetVT * 1306const struct SetVT *
1304_GSS_intersection_vt () 1307_GSS_intersection_vt()
1305{ 1308{
1306 static const struct SetVT intersection_vt = { 1309 static const struct SetVT intersection_vt = {
1307 .create = &intersection_set_create, 1310 .create = &intersection_set_create,