From aa6bebab28149dc9440749afadc279f134ea3f5c Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 7 Nov 2014 18:13:30 +0000 Subject: [PATCH] make set testcase fail to highlight issue #3490 --- src/set/gnunet-service-set_intersection.c | 123 +++++++++++++------- src/set/test_set_intersection_result_full.c | 119 +++++++++---------- 2 files changed, 140 insertions(+), 102 deletions(-) diff --git a/src/set/gnunet-service-set_intersection.c b/src/set/gnunet-service-set_intersection.c index 6b2473e26..27110077e 100644 --- a/src/set/gnunet-service-set_intersection.c +++ b/src/set/gnunet-service-set_intersection.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet - (C) 2013 Christian Grothoff (and other contributing authors) + (C) 2013, 2014 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -171,7 +171,9 @@ send_client_element (struct Operation *op, struct GNUNET_MQ_Envelope *ev; struct GNUNET_SET_ResultMessage *rm; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sending removed element (size %u) to client\n", element->size); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "sending removed element (size %u) to client\n", + element->size); GNUNET_assert (0 != op->spec->client_request_id); ev = GNUNET_MQ_msg_extra (rm, element->size, GNUNET_MESSAGE_TYPE_SET_RESULT); if (NULL == ev) @@ -305,8 +307,9 @@ iterator_bf_reduce (void *cls, return GNUNET_YES; } + /** - * create a bloomfilter based on the elements given + * Create a bloomfilter based on the elements given * * @param cls closure * @param key current key code @@ -317,20 +320,22 @@ iterator_bf_reduce (void *cls, */ static int iterator_bf_create (void *cls, - const struct GNUNET_HashCode *key, - void *value) + const struct GNUNET_HashCode *key, + void *value) { struct ElementEntry *ee = value; struct Operation *op = cls; struct GNUNET_HashCode mutated_hash; - GNUNET_BLOCK_mingle_hash(&ee->element_hash, op->spec->salt, &mutated_hash); - + GNUNET_BLOCK_mingle_hash (&ee->element_hash, + op->spec->salt, + &mutated_hash); GNUNET_CONTAINER_bloomfilter_add (op->state->local_bf, &mutated_hash); return GNUNET_YES; } + /** * Inform the client that the union operation has failed, * and proceed to destroy the evaluate operation. @@ -343,11 +348,13 @@ fail_intersection_operation (struct Operation *op) struct GNUNET_MQ_Envelope *ev; struct GNUNET_SET_ResultMessage *msg; - if (op->state->my_elements){ + if (op->state->my_elements) + { GNUNET_CONTAINER_multihashmap_destroy(op->state->my_elements); op->state->my_elements = NULL; } - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "intersection operation failed\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "intersection operation failed\n"); ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_RESULT); msg->result_status = htons (GNUNET_SET_STATUS_FAILURE); @@ -387,9 +394,11 @@ send_operation_request (struct Operation *op) GNUNET_MQ_send (op->mq, ev); if (NULL != op->spec->context_msg) - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sent op request with context message\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "sent op request with context message\n"); else - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sent op request without context message\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "sent op request without context message\n"); if (NULL != op->spec->context_msg) { @@ -398,8 +407,10 @@ send_operation_request (struct Operation *op) } } + static void -send_bloomfilter_multipart (struct Operation *op, uint32_t offset) +send_bloomfilter_multipart (struct Operation *op, + uint32_t offset) { struct GNUNET_MQ_Envelope *ev; struct BFPart *msg; @@ -409,7 +420,9 @@ send_bloomfilter_multipart (struct Operation *op, uint32_t offset) if (todo_size < chunk_size) chunk_size = todo_size; - ev = GNUNET_MQ_msg_extra (msg, chunk_size, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF_PART); + ev = GNUNET_MQ_msg_extra (msg, + chunk_size, + GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF_PART); msg->chunk_length = htonl (chunk_size); msg->chunk_offset = htonl (offset); @@ -424,10 +437,10 @@ send_bloomfilter_multipart (struct Operation *op, uint32_t offset) op->state->bf_data = NULL; return; } - send_bloomfilter_multipart (op, offset + chunk_size); } + /** * Send a bloomfilter to our peer. * that the operation is over. @@ -446,7 +459,8 @@ send_bloomfilter (struct Operation *op) uint32_t chunk_size; struct GNUNET_CONTAINER_BloomFilter * local_bf; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sending bf of size %u\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "sending bf of size %u\n"); CALCULATE_BF_SIZE(op->state->my_element_count, op->spec->remote_element_count, @@ -463,7 +477,8 @@ send_bloomfilter (struct Operation *op) op); // send our bloomfilter - if (GNUNET_SERVER_MAX_MESSAGE_SIZE > bf_size + sizeof (struct BFMessage)) { + if (GNUNET_SERVER_MAX_MESSAGE_SIZE > bf_size + sizeof (struct BFMessage)) + { // singlepart chunk_size = bf_size; ev = GNUNET_MQ_msg_extra (msg, chunk_size, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF); @@ -472,7 +487,8 @@ send_bloomfilter (struct Operation *op) (char*)&msg[1], bf_size)); } - else { + else + { //multipart chunk_size = GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct BFMessage); ev = GNUNET_MQ_msg_extra (msg, chunk_size, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF); @@ -535,15 +551,21 @@ send_remaining_elements (void *cls) struct GNUNET_SET_Element *element; int res; - res = GNUNET_CONTAINER_multihashmap_iterator_next (op->state->full_result_iter, NULL, (const void **) &remaining); - if (GNUNET_NO == res) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sending done and destroy because iterator ran out\n"); + res = GNUNET_CONTAINER_multihashmap_iterator_next (op->state->full_result_iter, + NULL, + (const void **) &remaining); + if (GNUNET_NO == res) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "sending done and destroy because iterator ran out\n"); send_client_done_and_destroy (op); return; } element = &remaining->element; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sending element (size %u) to client (full set)\n", element->size); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "sending element (size %u) to client (full set)\n", + element->size); GNUNET_assert (0 != op->spec->client_request_id); ev = GNUNET_MQ_msg_extra (rm, element->size, GNUNET_MESSAGE_TYPE_SET_RESULT); @@ -570,7 +592,8 @@ send_peer_done (struct Operation *op) struct GNUNET_MQ_Envelope *ev; op->state->phase = PHASE_FINISHED; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Intersection succeeded, sending DONE\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Intersection succeeded, sending DONE\n"); GNUNET_CONTAINER_bloomfilter_free (op->state->local_bf); op->state->local_bf = NULL; @@ -585,7 +608,8 @@ send_peer_done (struct Operation *op) * @param op the intersection operation */ static void -process_bf (struct Operation *op){ +process_bf (struct Operation *op) +{ uint32_t old_elements; uint32_t peer_elements; @@ -623,7 +647,8 @@ process_bf (struct Operation *op){ if ((0 == op->state->my_element_count) // fully disjoint || ((op->state->phase == PHASE_MAYBE_FINISHED) // we agree on a shared set of elements && (old_elements == op->state->my_element_count) - && (op->state->my_element_count == peer_elements))) { + && (op->state->my_element_count == peer_elements))) + { // In the last round we though we were finished, we now know this is correct send_peer_done (op); return; @@ -657,7 +682,8 @@ handle_p2p_bf_part (void *cls, const struct GNUNET_MessageHeader *mh) chunk_offset = ntohl(msg->chunk_offset); if ((NULL == op->state->bf_data) - || (op->state->bf_data_size < chunk_size + chunk_offset)){ + || (op->state->bf_data_size < chunk_size + chunk_offset)) + { // unexpected multipart chunk GNUNET_break_op (0); fail_intersection_operation(op); @@ -688,7 +714,8 @@ handle_p2p_bf_part (void *cls, const struct GNUNET_MessageHeader *mh) * @param mh the header of the message */ static void -handle_p2p_bf (void *cls, const struct GNUNET_MessageHeader *mh) +handle_p2p_bf (void *cls, + const struct GNUNET_MessageHeader *mh) { struct Operation *op = cls; const struct BFMessage *msg = (const struct BFMessage *) mh; @@ -701,14 +728,16 @@ handle_p2p_bf (void *cls, const struct GNUNET_MessageHeader *mh) case PHASE_INITIAL: case PHASE_BF_EXCHANGE: case PHASE_MAYBE_FINISHED: - if (NULL == op->state->bf_data) { + if (NULL == op->state->bf_data) + { // no colliding multipart transaction going on currently op->spec->salt = ntohl (msg->sender_mutator); bf_size = ntohl (msg->bloomfilter_total_length); bf_bits_per_element = ntohl (msg->bits_per_element); chunk_size = ntohl (msg->bloomfilter_length); op->spec->remote_element_count = ntohl(msg->sender_element_count); - if (bf_size == chunk_size) { + if (bf_size == chunk_size) + { // single part, done here op->state->remote_bf = GNUNET_CONTAINER_bloomfilter_init ((const char*) &msg[1], bf_size, @@ -738,16 +767,18 @@ handle_p2p_bf (void *cls, const struct GNUNET_MessageHeader *mh) * @param mh the header of the message */ static void -handle_p2p_element_info (void *cls, const struct GNUNET_MessageHeader *mh) +handle_p2p_element_info (void *cls, + const struct GNUNET_MessageHeader *mh) { struct Operation *op = cls; - struct BFMessage *msg = (struct BFMessage *) mh; + const struct BFMessage *msg = (const struct BFMessage *) mh; op->spec->remote_element_count = ntohl(msg->sender_element_count); if ((op->state->phase != PHASE_INITIAL) || (op->state->my_element_count > op->spec->remote_element_count) || (0 == op->state->my_element_count) - || (0 == op->spec->remote_element_count)){ + || (0 == op->spec->remote_element_count)) + { GNUNET_break_op (0); fail_intersection_operation(op); return; @@ -762,7 +793,7 @@ handle_p2p_element_info (void *cls, const struct GNUNET_MessageHeader *mh) GNUNET_CONTAINER_bloomfilter_free (op->state->remote_bf); op->state->remote_bf = NULL; - + if (op->state->my_element_count == ntohl (msg->sender_element_count)) op->state->phase = PHASE_MAYBE_FINISHED; @@ -781,7 +812,8 @@ send_element_count (struct Operation *op) struct GNUNET_MQ_Envelope *ev; struct BFMessage *msg; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sending element count (bf_msg)\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "sending element count (bf_msg)\n"); // just send our element count, as the other peer must start ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO); @@ -808,7 +840,8 @@ finish_and_destroy (struct Operation *op) if (GNUNET_SET_RESULT_FULL == op->spec->result_mode) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sending full result set\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "sending full result set\n"); op->state->full_result_iter = GNUNET_CONTAINER_multihashmap_iterator_create (op->state->my_elements); send_remaining_elements (op); @@ -830,8 +863,11 @@ handle_p2p_done (void *cls, { struct Operation *op = cls; - if ((op->state->phase = PHASE_FINISHED) || (op->state->phase = PHASE_MAYBE_FINISHED)){ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got final DONE\n"); + if ( (op->state->phase = PHASE_FINISHED) || + (op->state->phase = PHASE_MAYBE_FINISHED) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "got final DONE\n"); finish_and_destroy (op); return; @@ -872,7 +908,8 @@ intersection_evaluate (struct Operation *op) static void intersection_accept (struct Operation *op) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "accepting set union operation\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "accepting set union operation\n"); op->state = GNUNET_new (struct OperationState); op->state->my_elements = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_YES); op->state->my_element_count = op->spec->set->state->current_set_element_count; @@ -967,7 +1004,8 @@ static int intersection_handle_p2p_message (struct Operation *op, const struct GNUNET_MessageHeader *mh) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "received p2p message (t: %u, s: %u)\n", + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "received p2p message (t: %u, s: %u)\n", ntohs (mh->type), ntohs (mh->size)); switch (ntohs (mh->type)) { @@ -1012,12 +1050,14 @@ intersection_peer_disconnect (struct Operation *op) msg->result_status = htons (GNUNET_SET_STATUS_FAILURE); msg->element_type = htons (0); GNUNET_MQ_send (op->spec->set->client_mq, ev); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "other peer disconnected prematurely\n"); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "other peer disconnected prematurely\n"); _GSS_operation_destroy (op); return; } // else: the session has already been concluded - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "other peer disconnected (finished)\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "other peer disconnected (finished)\n"); if (GNUNET_NO == op->state->client_done_sent) finish_and_destroy (op); } @@ -1031,7 +1071,8 @@ intersection_peer_disconnect (struct Operation *op) static void intersection_op_cancel (struct Operation *op) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying intersection op\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "destroying intersection op\n"); /* check if the op was canceled twice */ GNUNET_assert (NULL != op->state); if (NULL != op->state->remote_bf) diff --git a/src/set/test_set_intersection_result_full.c b/src/set/test_set_intersection_result_full.c index b5140b101..c59624459 100644 --- a/src/set/test_set_intersection_result_full.c +++ b/src/set/test_set_intersection_result_full.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2012 Christian Grothoff (and other contributing authors) + (C) 2012-2014 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -21,6 +21,8 @@ /** * @file set/test_set_intersection_result_full.c * @brief testcase for full result mode of the intersection set operation + * @author Christian Fuchs + * @author Christian Grothoff */ #include "platform.h" #include "gnunet_util_lib.h" @@ -33,56 +35,63 @@ static int ret; static struct GNUNET_PeerIdentity local_id; static struct GNUNET_HashCode app_id; + static struct GNUNET_SET_Handle *set1; + static struct GNUNET_SET_Handle *set2; + static struct GNUNET_SET_ListenHandle *listen_handle; -const static struct GNUNET_CONFIGURATION_Handle *config; + +static const struct GNUNET_CONFIGURATION_Handle *config; static int iter_count; static void -result_cb_set1 (void *cls, const struct GNUNET_SET_Element *element, +result_cb_set1 (void *cls, + const struct GNUNET_SET_Element *element, enum GNUNET_SET_Status status) { + static int count; switch (status) { - case GNUNET_SET_STATUS_OK: - printf ("set 1: got element\n"); - break; - case GNUNET_SET_STATUS_FAILURE: - printf ("set 1: failure\n"); - ret = 1; - break; - case GNUNET_SET_STATUS_DONE: - printf ("set 1: done\n"); - GNUNET_SET_destroy (set1); - break; - default: - GNUNET_assert (0); + case GNUNET_SET_STATUS_OK: + count++; + break; + case GNUNET_SET_STATUS_FAILURE: + ret = 1; + break; + case GNUNET_SET_STATUS_DONE: + GNUNET_assert (1 == count); + GNUNET_SET_destroy (set1); + break; + default: + GNUNET_assert (0); } } static void -result_cb_set2 (void *cls, const struct GNUNET_SET_Element *element, - enum GNUNET_SET_Status status) +result_cb_set2 (void *cls, + const struct GNUNET_SET_Element *element, + enum GNUNET_SET_Status status) { + static int count; + switch (status) { - case GNUNET_SET_STATUS_OK: - printf ("set 2: got element\n"); - break; - case GNUNET_SET_STATUS_FAILURE: - printf ("set 2: failure\n"); - ret = 1; - break; - case GNUNET_SET_STATUS_DONE: - printf ("set 2: done\n"); - GNUNET_SET_destroy (set2); - break; - default: - GNUNET_assert (0); + case GNUNET_SET_STATUS_OK: + count++; + break; + case GNUNET_SET_STATUS_FAILURE: + ret = 1; + break; + case GNUNET_SET_STATUS_DONE: + GNUNET_assert (1 == count); + GNUNET_SET_destroy (set2); + break; + default: + GNUNET_assert (0); } } @@ -96,13 +105,11 @@ listen_cb (void *cls, struct GNUNET_SET_OperationHandle *oh; GNUNET_assert (NULL != context_msg); - GNUNET_assert (ntohs (context_msg->type) == GNUNET_MESSAGE_TYPE_TEST); - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "listen cb called\n"); GNUNET_SET_listen_cancel (listen_handle); - - oh = GNUNET_SET_accept (request, GNUNET_SET_RESULT_FULL, result_cb_set2, NULL); + oh = GNUNET_SET_accept (request, + GNUNET_SET_RESULT_FULL, + &result_cb_set2, NULL); GNUNET_SET_commit (oh, set2); } @@ -120,12 +127,15 @@ start (void *cls) context_msg.size = htons (sizeof context_msg); context_msg.type = htons (GNUNET_MESSAGE_TYPE_TEST); - - listen_handle = GNUNET_SET_listen (config, GNUNET_SET_OPERATION_INTERSECTION, - &app_id, listen_cb, NULL); - oh = GNUNET_SET_prepare (&local_id, &app_id, &context_msg, 42, + listen_handle = GNUNET_SET_listen (config, + GNUNET_SET_OPERATION_INTERSECTION, + &app_id, + &listen_cb, NULL); + oh = GNUNET_SET_prepare (&local_id, + &app_id, + &context_msg, 42, GNUNET_SET_RESULT_FULL, - result_cb_set1, NULL); + &result_cb_set1, NULL); GNUNET_SET_commit (oh, set1); } @@ -140,10 +150,9 @@ init_set2 (void *cls) { struct GNUNET_SET_Element element; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initializing set 2\n"); - + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "initializing set 2\n"); element.type = 0; - element.data = "hello"; element.size = strlen(element.data); GNUNET_SET_add_element (set2, &element, NULL, NULL); @@ -152,7 +161,7 @@ init_set2 (void *cls) GNUNET_SET_add_element (set2, &element, NULL, NULL); element.data = "baz"; element.size = strlen(element.data); - GNUNET_SET_add_element (set2, &element, start, NULL); + GNUNET_SET_add_element (set2, &element, &start, NULL); } @@ -165,15 +174,12 @@ init_set1 (void) struct GNUNET_SET_Element element; element.type = 0; - element.data = "hello"; element.size = strlen(element.data); GNUNET_SET_add_element (set1, &element, NULL, NULL); element.data = "bar"; element.size = strlen(element.data); - GNUNET_SET_add_element (set1, &element, init_set2, NULL); - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initialized set 1\n"); + GNUNET_SET_add_element (set1, &element, &init_set2, NULL); } @@ -187,7 +193,6 @@ iter_cb (void *cls, GNUNET_SET_destroy (cls); return GNUNET_YES; } - printf ("iter: got element\n"); iter_count++; return GNUNET_YES; } @@ -200,9 +205,7 @@ test_iter () struct GNUNET_SET_Handle *iter_set; iter_set = GNUNET_SET_create (config, GNUNET_SET_OPERATION_INTERSECTION); - element.type = 0; - element.data = "hello"; element.size = strlen(element.data); GNUNET_SET_add_element (iter_set, &element, NULL, NULL); @@ -212,8 +215,7 @@ test_iter () element.data = "quux"; element.size = strlen(element.data); GNUNET_SET_add_element (iter_set, &element, NULL, NULL); - - GNUNET_SET_iterate (iter_set, iter_cb, iter_set); + GNUNET_SET_iterate (iter_set, &iter_cb, iter_set); } @@ -231,11 +233,7 @@ run (void *cls, struct GNUNET_TESTING_Peer *peer) { config = cfg; - GNUNET_CRYPTO_get_peer_identity (cfg, &local_id); - printf ("my id (from CRYPTO): %s\n", GNUNET_i2s (&local_id)); GNUNET_TESTING_peer_get_identity (peer, &local_id); - printf ("my id (from TESTING): %s\n", GNUNET_i2s (&local_id)); - test_iter (); set1 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_INTERSECTION); @@ -246,15 +244,14 @@ run (void *cls, init_set1 (); } + int main (int argc, char **argv) { if (0 != GNUNET_TESTING_peer_run ("test_set_api", "test_set.conf", &run, NULL)) - { - return 0; - } + return 1; return ret; } -- 2.25.1