From dc91365855b72f0c97c0a7abc6eac7d479704daf Mon Sep 17 00:00:00 2001 From: Christian Fuchs Date: Tue, 3 Sep 2013 12:07:52 +0000 Subject: [PATCH] re-added collective disconnect command to the scalarproduct API adapted the scalarproduct client to use the new API modified scalarproduct.h to include proper logging for gcrypt errors cancel is now quiet added proper gcry logging to the SP-API --- src/include/gnunet_scalarproduct_service.h | 12 +- src/scalarproduct/gnunet-scalarproduct.c | 394 ++++++++---------- .../gnunet-service-scalarproduct.c | 7 - src/scalarproduct/scalarproduct.h | 7 + src/scalarproduct/scalarproduct_api.c | 32 +- 5 files changed, 210 insertions(+), 242 deletions(-) diff --git a/src/include/gnunet_scalarproduct_service.h b/src/include/gnunet_scalarproduct_service.h index 4ad9f6c62..a398a3198 100644 --- a/src/include/gnunet_scalarproduct_service.h +++ b/src/include/gnunet_scalarproduct_service.h @@ -122,8 +122,16 @@ GNUNET_SCALARPRODUCT_response (const struct GNUNET_CONFIGURATION_Handle *cfg, * * @param h handel to terminate */ -void -GNUNET_SCALARPRODUCT_cancel (const struct GNUNET_SCALARPRODUCT_Handle *h); +void +GNUNET_SCALARPRODUCT_cancel (struct GNUNET_SCALARPRODUCT_ComputationHandle * h); + +/** + * Cancel ALL ongoing computation or revoke our collaboration offer. + * Closes ALL connections to the service + * + */ +void +GNUNET_SCALARPRODUCT_disconnect (); #if 0 /* keep Emacsens' auto-indent happy */ { diff --git a/src/scalarproduct/gnunet-scalarproduct.c b/src/scalarproduct/gnunet-scalarproduct.c index 78acb62ce..0bce75085 100644 --- a/src/scalarproduct/gnunet-scalarproduct.c +++ b/src/scalarproduct/gnunet-scalarproduct.c @@ -34,6 +34,20 @@ #include "scalarproduct.h" #define LOG(kind,...) GNUNET_log_from (kind, "gnunet-scalarproduct",__VA_ARGS__) + +struct ScalarProductCallbackClosure +{ + /** + * the session key identifying this computation + */ + struct GNUNET_HashCode key; + + /** + * PeerID we want to compute a scalar product with + */ + struct GNUNET_PeerIdentity peer; +}; + /** * Option -p: destination peer identity for checking message-ids with */ @@ -54,58 +68,11 @@ static char *input_elements = NULL; */ static char *input_mask = NULL; -/** - * the count of the messages sent to the service for processing - */ -static unsigned short element_count; - -/** - * the count of the mask bytes - */ -unsigned short mask_length = 0; - -/** - * the count of the number of mask bytes - */ -unsigned short mask_bytes; - -/** - * the array of converted message IDs to send to our service - */ -static int32_t * elements = NULL; - -/** - * the array of converted message IDs to send to our service - */ -static unsigned char * mask = NULL; - -/** - * information about the peer we are comparing with - */ -struct GNUNET_PeerIdentity peer; - -/** - * information about the peer we are comparing with - */ -struct GNUNET_HashCode key; - -/** - * Pointer to the GNUNET_SCALARPRODUCT_Handle - */ -struct GNUNET_SCALARPRODUCT_Handle *handle; - /** * Global return value */ static int ret; -struct GNUNET_SCALARPRODUCT_TestCls -{ - struct GNUNET_SCALARPRODUCT_Handle * h; -}; - -struct GNUNET_SCALARPRODUCT_TestCls test_cls; - /** * Callback called if we are initiating a new computation session @@ -115,33 +82,30 @@ struct GNUNET_SCALARPRODUCT_TestCls test_cls; */ static void responder_callback (void *cls, - const struct GNUNET_HashCode * key, enum GNUNET_SCALARPRODUCT_ResponseStatus status) { + struct ScalarProductCallbackClosure * closure = cls; ret = -1; switch (status) - { - case GNUNET_SCALARPRODUCT_Status_Success: - ret = 0; - LOG (GNUNET_ERROR_TYPE_INFO, "Session %s concluded.\n", GNUNET_h2s (key)); - break; - case GNUNET_SCALARPRODUCT_Status_InvalidResponse: - LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: invalid response\n", GNUNET_h2s (key)); - break; - case GNUNET_SCALARPRODUCT_Status_Timeout: - LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: timeout\n", GNUNET_h2s (key)); - break; - case GNUNET_SCALARPRODUCT_Status_Failure: - LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: service failure\n", GNUNET_h2s (key)); - case GNUNET_SCALARPRODUCT_Status_ServiceDisconnected: - LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: service disconnect!!\n", GNUNET_h2s (key)); - break; - default: - LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: return code %d\n", GNUNET_h2s (key), (int) status); - } - - GNUNET_SCALARPRODUCT_cancel (handle); + { + case GNUNET_SCALARPRODUCT_Status_Success: + ret = 0; + LOG (GNUNET_ERROR_TYPE_INFO, "Session %s concluded.\n", GNUNET_h2s (&closure->key)); + break; + case GNUNET_SCALARPRODUCT_Status_InvalidResponse: + LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: invalid response\n", GNUNET_h2s (&closure->key)); + break; + case GNUNET_SCALARPRODUCT_Status_Failure: + LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: service failure\n", GNUNET_h2s (&closure->key)); + case GNUNET_SCALARPRODUCT_Status_ServiceDisconnected: + LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: service disconnect!!\n", GNUNET_h2s (&closure->key)); + break; + default: + LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: return code %d\n", GNUNET_h2s (&closure->key), status); + } + + GNUNET_SCALARPRODUCT_disconnect (); GNUNET_SCHEDULER_shutdown (); } @@ -159,57 +123,37 @@ responder_callback (void *cls, */ static void requester_callback (void *cls, - const struct GNUNET_HashCode * key, - const struct GNUNET_PeerIdentity * peer, - enum GNUNET_SCALARPRODUCT_ResponseStatus status, - const struct GNUNET_SCALARPRODUCT_client_response *msg) + enum GNUNET_SCALARPRODUCT_ResponseStatus status, + gcry_mpi_t result) { - uint32_t product_len; + struct ScalarProductCallbackClosure * closure = cls; + unsigned char * buf; + gcry_error_t rc; ret = -1; switch (status) - { - case GNUNET_SCALARPRODUCT_Status_Success: - product_len = ntohl (msg->product_length); - - LOG (GNUNET_ERROR_TYPE_INFO, "Session %s concluded.\n", GNUNET_h2s (key)); - - if (0 < product_len && NULL != &msg[1]) - { - gcry_mpi_t result; - size_t read = 0; - - if (0 != gcry_mpi_scan (&result, GCRYMPI_FMT_USG, &msg[1], product_len, &read)) - LOG (GNUNET_ERROR_TYPE_ERROR, "Could not convert to mpi to value!\n"); - else - { - unsigned char * buf; - gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, result); - - printf ("Successfully computed result for session %s: %s\n", GNUNET_h2s (key), buf); - ret = 0; - } - } - else - { //currently not used, but if we get more info due to MESH we will need this - LOG (GNUNET_ERROR_TYPE_ERROR, "Service-side error in session %s, return code: %d\n", GNUNET_h2s (key), product_len); - } - break; - case GNUNET_SCALARPRODUCT_Status_InvalidResponse: - LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: invalid response\n", GNUNET_h2s (key)); - break; - case GNUNET_SCALARPRODUCT_Status_Timeout: - LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: timeout\n", GNUNET_h2s (key)); - break; - case GNUNET_SCALARPRODUCT_Status_Failure: - LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: service failure\n", GNUNET_h2s (key)); - case GNUNET_SCALARPRODUCT_Status_ServiceDisconnected: - LOG (GNUNET_ERROR_TYPE_ERROR, "Disconnected from service.\n", GNUNET_h2s (key)); - break; - default: - LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: return code %d\n", GNUNET_h2s (key), (int) status); + { + case GNUNET_SCALARPRODUCT_Status_Success: + + if (0 == (rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, result))) + printf ("Successfully computed result for session %s with peer %s: %s\n", GNUNET_h2s (&closure->key), GNUNET_i2s (&closure->peer), buf); + else { + printf ("Session %s with peer %s failed\n", GNUNET_h2s (&closure->key), GNUNET_i2s (&closure->peer)); + LOG_GCRY(GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_aprint", rc); } - GNUNET_SCALARPRODUCT_cancel (handle); + break; + case GNUNET_SCALARPRODUCT_Status_InvalidResponse: + LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s with peer %s failed: invalid response received\n", GNUNET_h2s (&closure->key), GNUNET_i2s (&closure->peer)); + break; + case GNUNET_SCALARPRODUCT_Status_Failure: + LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s with peer %s failed: API failure\n", GNUNET_h2s (&closure->key), GNUNET_i2s (&closure->peer)); + case GNUNET_SCALARPRODUCT_Status_ServiceDisconnected: + LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s with peer %s was disconnected from service.\n", GNUNET_h2s (&closure->key), GNUNET_i2s (&closure->peer)); + break; + default: + LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s with peer %s failed: return code %d\n", GNUNET_h2s (&closure->key), GNUNET_i2s (&closure->peer), status); + } + GNUNET_SCALARPRODUCT_disconnect (); GNUNET_SCHEDULER_shutdown (); } @@ -233,44 +177,90 @@ run (void *cls, int32_t element; int i; ret = -1; + int32_t * elements; + unsigned char * mask; + unsigned short mask_bytes; + unsigned short element_count; + struct ScalarProductCallbackClosure * closure; if (NULL == input_elements) - { - FPRINTF (stderr, "%s", _ ("You must specify at least one message ID to check!\n")); - return; - } + { + FPRINTF (stderr, "%s", _ ("You must specify at least one message ID to check!\n")); + return; + } if (NULL == input_key) - { - FPRINTF (stderr, "%s", _ ("This program needs a session identifier for comparing vectors.\n")); - return; - } + { + FPRINTF (stderr, "%s", _ ("This program needs a session identifier for comparing vectors.\n")); + return; + } if (1 > strnlen (input_key, sizeof (struct GNUNET_HashCode))) - { - FPRINTF (stderr, _ ("Please give a session key for --input_key!\n")); - return; - } - GNUNET_CRYPTO_hash (input_key, strlen (input_key), &key); + { + FPRINTF (stderr, _ ("Please give a session key for --input_key!\n")); + return; + } + closure = GNUNET_new(struct ScalarProductCallbackClosure); + GNUNET_CRYPTO_hash (input_key, strlen (input_key), &closure->key); if (input_peer_id && GNUNET_OK != GNUNET_CRYPTO_hash_from_string (input_peer_id, - (struct GNUNET_HashCode *) &peer)) - { - FPRINTF (stderr, _ ("Tried to set initiator mode, as peer ID was given. " - "However, `%s' is not a valid peer identifier.\n"), - input_peer_id); - return; - } + (struct GNUNET_HashCode *) &closure->peer)) + { + FPRINTF (stderr, _ ("Tried to set initiator mode, as peer ID was given. " + "However, `%s' is not a valid peer identifier.\n"), + input_peer_id); + return; + } int exit_loop = 0; /* Read input_elements_peer1, and put in elements_peer1 array */ do + { + unsigned int mcount = element_count; + //ignore empty rows of ,,,,,, + while (*begin == ',') + begin++; + // get the length of the current element and replace , with null + for (end = begin; *end && *end != ','; end++); + + if (*end == '\0') + exit_loop = 1; + + if (*end == ',') + *end = '\0'; + + if (1 != sscanf (begin, "%" SCNd32, &element)) + { + FPRINTF (stderr, _ ("Could not convert `%s' to int32_t.\n"), begin); + return; + } + + GNUNET_array_append (elements, mcount, element); + element_count++; + + begin = ++end; + } + while (!exit_loop); + + GNUNET_assert (elements != NULL); + GNUNET_assert (element_count > 1); + mask_bytes = element_count / 8 + (element_count % 8 ? 1 : 0); + mask = GNUNET_malloc ((element_count / 8) + 2); + + /* Read input_mask_peer1 and read in mask_peer1 array */ + if (NULL != input_mask) + { + begin = input_mask; + unsigned short mask_count = 0; + int exit_loop = 0; + + do { - unsigned int mcount = element_count; //ignore empty rows of ,,,,,, - while (*begin == ',') + while (* begin == ',') begin++; // get the length of the current element and replace , with null + // gnunet_ascii-armor uses base32, thus we can use , as separator! for (end = begin; *end && *end != ','; end++); if (*end == '\0') @@ -280,112 +270,62 @@ run (void *cls, *end = '\0'; if (1 != sscanf (begin, "%" SCNd32, &element)) - { - FPRINTF (stderr, _ ("Could not convert `%s' to int32_t.\n"), begin); - return; - } + { + FPRINTF (stderr, _ ("Could not convert `%s' to int32_t.\n"), begin); + return; + } - GNUNET_array_append (elements, mcount, element); - element_count++; + GNUNET_assert (mask_count <= element_count); - begin = ++end; - } - while (!exit_loop); + if (element) + mask[mask_count / 8] = mask[mask_count / 8] | 1 << (mask_count % 8); - GNUNET_assert (elements != NULL); - GNUNET_assert (element_count > 1); - mask_length = element_count / 8 + (element_count % 8 ? 1 : 0); - mask = GNUNET_malloc ((element_count / 8) + 2); - - /* Read input_mask_peer1 and read in mask_peer1 array */ - if (NULL != input_mask) - { - begin = input_mask; - unsigned short mask_count = 0; - int exit_loop = 0; - - do - { - //ignore empty rows of ,,,,,, - while (* begin == ',') - begin++; - // get the length of the current element and replace , with null - // gnunet_ascii-armor uses base32, thus we can use , as separator! - for (end = begin; *end && *end != ','; end++); - - if (*end == '\0') - exit_loop = 1; - - if (*end == ',') - *end = '\0'; - - if (1 != sscanf (begin, "%" SCNd32, &element)) - { - FPRINTF (stderr, _ ("Could not convert `%s' to int32_t.\n"), begin); - return; - } - - GNUNET_assert (mask_count <= element_count); - - if (element) - mask[mask_count / 8] = mask[mask_count / 8] | 1 << (mask_count % 8); - - mask_count++; - begin = ++end; - } - while (!exit_loop); - // +1 to see if we would have more data, which would indicate malformed/superficial input - GNUNET_assert (mask_count == element_count); + mask_count++; + begin = ++end; } + while (!exit_loop); + // +1 to see if we would have more data, which would indicate malformed/superficial input + GNUNET_assert (mask_count == element_count); + } else if (input_peer_id) - { - for (i = 0; i <= mask_length; i++) - mask[i] = UCHAR_MAX; // all 1's - } + { + for (i = 0; i <= mask_bytes; i++) + mask[i] = UCHAR_MAX; // all 1's + } - handle = GNUNET_SCALARPRODUCT_connect (cfg); - if (handle == NULL) - { - FPRINTF (stderr, _ ("Could not connect to the GNUNET Vector Product Service\n")); - return; - } - - test_cls.h = handle; - if (input_peer_id && !GNUNET_SCALARPRODUCT_request (handle, - &key, - &peer, - element_count, - mask_length, - elements, mask, - GNUNET_TIME_UNIT_MINUTES, + if (input_peer_id && !GNUNET_SCALARPRODUCT_request (cfg, + &closure->key, + &closure->peer, + elements, element_count, + mask, mask_bytes, &requester_callback, - (void *) &test_cls)) + (void *) &closure)) return; - if ( !input_peer_id && !GNUNET_SCALARPRODUCT_prepare_response (handle, - &key, - element_count, - elements, - GNUNET_TIME_UNIT_MINUTES, - &responder_callback, - (void *) &test_cls)) + + + if (!input_peer_id && !GNUNET_SCALARPRODUCT_response (cfg, + &closure->key, + elements, element_count, + &responder_callback, + (void *) &closure)) return; ret = 0; } -/** + /** * The main function to the scalarproduct client. * * @param argc number of arguments from the command line * @param argv command line arguments * @return 0 ok, 1 on error */ -int + int main (int argc, char *const *argv) { - static const struct GNUNET_GETOPT_CommandLineOption options[] = { + static const struct GNUNET_GETOPT_CommandLineOption options[] = { {'e', "elements", "\"val1,val2,...,valn\"", gettext_noop ("A comma separated list of elements to compare as vector with our remote peer."), 1, &GNUNET_GETOPT_set_string, &input_elements}, @@ -398,14 +338,14 @@ main (int argc, char *const *argv) {'k', "key", "TRANSACTION_ID", gettext_noop ("Transaction ID shared with peer."), 1, &GNUNET_GETOPT_set_string, &input_key}, - GNUNET_GETOPT_OPTION_END + GNUNET_GETOPT_OPTION_END }; - return (GNUNET_OK == - GNUNET_PROGRAM_run (argc, - argv, - "gnunet-scalarproduct", - gettext_noop ("Calculate the Vectorproduct with a GNUnet peer."), - options, &run, NULL)) ? ret : 1; + return (GNUNET_OK == + GNUNET_PROGRAM_run (argc, + argv, + "gnunet-scalarproduct", + gettext_noop ("Calculate the Vectorproduct with a GNUnet peer."), + options, &run, NULL)) ? ret : 1; } diff --git a/src/scalarproduct/gnunet-service-scalarproduct.c b/src/scalarproduct/gnunet-service-scalarproduct.c index be942c576..d7c8f436b 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct.c +++ b/src/scalarproduct/gnunet-service-scalarproduct.c @@ -35,13 +35,6 @@ #define LOG(kind,...) GNUNET_log_from (kind, "scalarproduct", __VA_ARGS__) -/** - * Log an error message at log-level 'level' that indicates - * a failure of the command 'cmd' with the message given - * by gcry_strerror(rc). - */ -#define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0) - /////////////////////////////////////////////////////////////////////////////// // Service Structure Definitions /////////////////////////////////////////////////////////////////////////////// diff --git a/src/scalarproduct/scalarproduct.h b/src/scalarproduct/scalarproduct.h index 43a866cf1..9304c0c7e 100644 --- a/src/scalarproduct/scalarproduct.h +++ b/src/scalarproduct/scalarproduct.h @@ -48,6 +48,13 @@ extern "C" */ #define PAILLIER_ELEMENT_LENGTH (2*KEYBITS/8 +1) +/** + * Log an error message at log-level 'level' that indicates + * a failure of the command 'cmd' with the message given + * by gcry_strerror(rc). + */ +#define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0) + /////////////////////////////////////////////////////////////////////////////// // Scalar Product Message Types /////////////////////////////////////////////////////////////////////////////// diff --git a/src/scalarproduct/scalarproduct_api.c b/src/scalarproduct/scalarproduct_api.c index 633034b31..b3390f349 100644 --- a/src/scalarproduct/scalarproduct_api.c +++ b/src/scalarproduct/scalarproduct_api.c @@ -171,6 +171,7 @@ process_result_message (void *cls, const struct GNUNET_SCALARPRODUCT_client_response *message = (const struct GNUNET_SCALARPRODUCT_client_response *) msg; gcry_mpi_t result = NULL; + gcry_error_t rc; if (GNUNET_SCALARPRODUCT_Status_Success == status && qe->cont_datum != NULL) @@ -183,9 +184,9 @@ process_result_message (void *cls, gcry_mpi_t num; size_t read = 0; - if (0 != gcry_mpi_scan (&num, GCRYMPI_FMT_USG, &msg[1], product_len, &read)) + if (0 != (rc = gcry_mpi_scan (&num, GCRYMPI_FMT_USG, &msg[1], product_len, &read))) { - LOG (GNUNET_ERROR_TYPE_ERROR, "Could not convert to mpi to value!\n"); + LOG_GCRY(GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); gcry_mpi_release (result); result = NULL; status = GNUNET_SCALARPRODUCT_Status_InvalidResponse; @@ -497,17 +498,36 @@ GNUNET_SCALARPRODUCT_cancel (struct GNUNET_SCALARPRODUCT_ComputationHandle * h) if (qe == h) { GNUNET_CONTAINER_DLL_remove (head, tail, qe); - LOG (GNUNET_ERROR_TYPE_INFO, - "Disconnecting from VectorProduct\n"); if (NULL == qe->th) GNUNET_CLIENT_notify_transmit_ready_cancel (qe->th); - GNUNET_CLIENT_disconnect (h->client); - GNUNET_STATISTICS_destroy (h->stats, GNUNET_YES); + GNUNET_CLIENT_disconnect (qe->client); + GNUNET_STATISTICS_destroy (qe->stats, GNUNET_YES); GNUNET_free (qe->msg); GNUNET_free (qe); break; } } } +/** + * Cancel ALL our ongoing scalar product computations and collaboration offers. + * Closes ALL connections to the service + */ +void +GNUNET_SCALARPRODUCT_disconnect () +{ + struct GNUNET_SCALARPRODUCT_ComputationHandle * qe; + + LOG (GNUNET_ERROR_TYPE_INFO, "Disconnecting from VectorProduct\n"); + for (qe = head; head != NULL; qe = head) + { + GNUNET_CONTAINER_DLL_remove (head, tail, qe); + if (NULL == qe->th) + GNUNET_CLIENT_notify_transmit_ready_cancel (qe->th); + GNUNET_CLIENT_disconnect (qe->client); + GNUNET_STATISTICS_destroy (qe->stats, GNUNET_YES); + GNUNET_free (qe->msg); + GNUNET_free (qe); + } +} /* end of ext_api.c */ -- 2.25.1