X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fscalarproduct%2Fgnunet-scalarproduct.c;h=aa894b61d644f44f6a6d6f0af53c2acacd4400ee;hb=160ddfc67766446ba16bf9d9495d809b1e7a5c8d;hp=012ce91b8c2d043d0d92c7dbf7904ac724842925;hpb=5029a5333a53935e9c088106265698f28b1e60c1;p=oweals%2Fgnunet.git diff --git a/src/scalarproduct/gnunet-scalarproduct.c b/src/scalarproduct/gnunet-scalarproduct.c index 012ce91b8..aa894b61d 100644 --- a/src/scalarproduct/gnunet-scalarproduct.c +++ b/src/scalarproduct/gnunet-scalarproduct.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2013 Christian Grothoff (and other contributing authors) + Copyright (C) 2013, 2014 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -14,8 +14,8 @@ You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /** @@ -34,23 +34,17 @@ #include "scalarproduct.h" #define LOG(kind,...) GNUNET_log_from (kind, "gnunet-scalarproduct",__VA_ARGS__) -#define INPUTSTRINGLENGTH 1024 + /** - * A primitive closure structure holding information about our session + * the session key identifying this computation */ -struct ScalarProductCallbackClosure -{ - /** - * the session key identifying this computation - */ - struct GNUNET_HashCode key; +static struct GNUNET_HashCode session_key; - /** - * PeerID we want to compute a scalar product with - */ - struct GNUNET_PeerIdentity peer; -}; +/** + * PeerID we want to compute a scalar product with + */ +static struct GNUNET_PeerIdentity peer_id; /** * Option -p: destination peer identity for checking message-ids with @@ -60,7 +54,7 @@ static char *input_peer_id; /** * Option -p: destination peer identity for checking message-ids with */ -static char *input_key; +static char *input_session_key; /** * Option -e: vector to calculate a scalarproduct with @@ -68,14 +62,14 @@ static char *input_key; static char *input_elements; /** - * Option -m: message-ids to calculate a scalarproduct with + * Global return value */ -static char *input_mask; +static int ret = -1; /** - * Global return value + * our Scalarproduct Computation handle */ -static int ret = -1; +static struct GNUNET_SCALARPRODUCT_ComputationHandle *computation; /** @@ -88,38 +82,37 @@ static void responder_callback (void *cls, enum GNUNET_SCALARPRODUCT_ResponseStatus status) { - struct ScalarProductCallbackClosure * closure = cls; - switch (status) { - case GNUNET_SCALARPRODUCT_Status_Success: + case GNUNET_SCALARPRODUCT_STATUS_SUCCESS: ret = 0; LOG (GNUNET_ERROR_TYPE_INFO, "Session %s concluded.\n", - GNUNET_h2s (&closure->key)); + GNUNET_h2s (&session_key)); break; - case GNUNET_SCALARPRODUCT_Status_InvalidResponse: + case GNUNET_SCALARPRODUCT_STATUS_INVALID_RESPONSE: LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: invalid response\n", - GNUNET_h2s (&closure->key)); + GNUNET_h2s (&session_key)); break; - case GNUNET_SCALARPRODUCT_Status_Failure: + case GNUNET_SCALARPRODUCT_STATUS_FAILURE: LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: service failure\n", - GNUNET_h2s (&closure->key)); + GNUNET_h2s (&session_key)); break; - case GNUNET_SCALARPRODUCT_Status_ServiceDisconnected: + case GNUNET_SCALARPRODUCT_STATUS_DISCONNECTED: LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: service disconnect!\n", - GNUNET_h2s (&closure->key)); + GNUNET_h2s (&session_key)); break; default: LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s failed: return code %d\n", - GNUNET_h2s (&closure->key), + GNUNET_h2s (&session_key), status); } - GNUNET_SCHEDULER_shutdown(); + computation = NULL; + GNUNET_SCHEDULER_shutdown (); } @@ -135,49 +128,52 @@ requester_callback (void *cls, enum GNUNET_SCALARPRODUCT_ResponseStatus status, gcry_mpi_t result) { - struct ScalarProductCallbackClosure * closure = cls; - unsigned char * buf; + unsigned char *buf; gcry_error_t rc; switch (status) { - case GNUNET_SCALARPRODUCT_Status_Success: + case GNUNET_SCALARPRODUCT_STATUS_SUCCESS: if (0 == (rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, result))) { ret = 0; - printf ("%s", buf); + fprintf (stdout, + "%s\n", + buf); + fflush (stdout); } else LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_aprint", rc); break; - case GNUNET_SCALARPRODUCT_Status_InvalidResponse: + case GNUNET_SCALARPRODUCT_STATUS_INVALID_RESPONSE: LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s with peer %s failed: invalid response received\n", - GNUNET_h2s (&closure->key), - GNUNET_i2s (&closure->peer)); + GNUNET_h2s (&session_key), + GNUNET_i2s (&peer_id)); break; - case GNUNET_SCALARPRODUCT_Status_Failure: + 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)); + GNUNET_h2s (&session_key), + GNUNET_i2s (&peer_id)); break; - case GNUNET_SCALARPRODUCT_Status_ServiceDisconnected: + case GNUNET_SCALARPRODUCT_STATUS_DISCONNECTED: LOG (GNUNET_ERROR_TYPE_ERROR, "Session %s with peer %s was disconnected from service.\n", - GNUNET_h2s (&closure->key), - GNUNET_i2s (&closure->peer)); + GNUNET_h2s (&session_key), + GNUNET_i2s (&peer_id)); 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), + GNUNET_h2s (&session_key), + GNUNET_i2s (&peer_id), status); } - GNUNET_SCHEDULER_shutdown(); + computation = NULL; + GNUNET_SCHEDULER_shutdown (); } @@ -188,10 +184,13 @@ requester_callback (void *cls, * @param tc unused */ static void -shutdown_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +shutdown_task (void *cls) { - GNUNET_SCALARPRODUCT_disconnect (); + if (NULL != computation) + { + GNUNET_SCALARPRODUCT_cancel (computation); + ret = 1; /* aborted */ + } } @@ -211,173 +210,125 @@ run (void *cls, { char *begin = input_elements; char *end; - int32_t element; - int i; - int32_t *elements; - unsigned char *mask; - uint32_t mask_bytes; + unsigned int i; + struct GNUNET_SCALARPRODUCT_Element *elements; uint32_t element_count = 0; - struct ScalarProductCallbackClosure * closure; if (NULL == input_elements) { LOG (GNUNET_ERROR_TYPE_ERROR, - _ ("You must specify at least one message ID to check!\n")); + _("You must specify at least one message ID to check!\n")); return; } - - if (NULL == input_key) + if ( (NULL == input_session_key) || + (0 == strlen (input_session_key)) ) { LOG (GNUNET_ERROR_TYPE_ERROR, - _ ("This program needs a session identifier for comparing vectors.\n")); + _("This program needs a session identifier for comparing vectors.\n")); return; } - - if (1 > strnlen (input_key, sizeof (struct GNUNET_HashCode))) + GNUNET_CRYPTO_hash (input_session_key, + strlen (input_session_key), + &session_key); + if ( (NULL != input_peer_id) && + (GNUNET_OK != + GNUNET_CRYPTO_eddsa_public_key_from_string (input_peer_id, + strlen (input_peer_id), + &peer_id.public_key)) ) { LOG (GNUNET_ERROR_TYPE_ERROR, - _ ("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 *) &closure->peer))) - { - LOG (GNUNET_ERROR_TYPE_ERROR, - _ ("Tried to set initiator mode, as peer ID was given. " - "However, `%s' is not a valid peer identifier.\n"), + _("Tried to set initiator mode, as peer ID was given. " + "However, `%s' is not a valid peer identifier.\n"), input_peer_id); return; } - - /* Count input_elements_peer1, and put in elements_peer1 array */ - do + if ( ('\'' == *begin) && + ('\'' == begin[strlen(begin)-1]) ) { - // get the length of the current element and replace , with null - for (end = begin; *end && *end != ','; end++); - - if (1 == sscanf (begin, "%" SCNd32 ",", &element)) - { - //element in the middle - element_count++; - begin = end + 1; - } - else if (0 == *begin) - { - break; - } - else - { - LOG (GNUNET_ERROR_TYPE_ERROR, - _ ("Could not convert `%s' to int32_t.\n"), begin); - return; - } + begin[strlen(begin)-1] = '\0'; + if (strlen (begin) > 0) + begin++; } - while (1); + for (end = begin; 0 != *end; end++) + if (*end == ';') + element_count++; if (0 == element_count) { LOG (GNUNET_ERROR_TYPE_ERROR, - _ ("Need elements to compute the vectorproduct, got none.\n")); + _("Need elements to compute the scalarproduct, got none.\n")); return; } - begin = input_elements; - elements = GNUNET_malloc (sizeof (int32_t) * element_count); - element_count = 0; - /* Read input_elements_peer1, and put in elements_peer1 array */ - do - { - // get the length of the current element and replace , with null - for (end = begin; *end && *end != ','; end++); + elements = GNUNET_malloc (sizeof(struct GNUNET_SCALARPRODUCT_Element) * element_count); - if (1 == sscanf (begin, "%" SCNd32 ",", &elements[element_count])) + for (i = 0; i < element_count;i++) + { + struct GNUNET_SCALARPRODUCT_Element element; + char* separator = NULL; + + /* get the length of the current key,value; tupel */ + for (end = begin; *end != ';'; end++) + if (*end == ',') + separator = end; + + /* final element */ + if ( (NULL == separator) || + (begin == separator) || + (separator == end - 1) ) { - //element in the middle - element_count++; - begin = end + 1; + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Malformed input, could not parse `%s'\n"), + begin); + GNUNET_free (elements); + return; } - else if (0 == *begin) + *separator = 0; + /* read the element's key */ + GNUNET_CRYPTO_hash (begin, + strlen (begin), + &element.key); + + /* read the element's value */ + if (1 != + sscanf (separator + 1, + "%" SCNd64 ";", + &element.value) ) { - break; - } - } - while (1); - - mask_bytes = element_count / 8 + ( (element_count % 8) ? 1 : 0); - mask = GNUNET_malloc ((element_count / 8) + 1); - - /* Read input_mask_peer1 and read in mask_peer1 array */ - if ((NULL != input_peer_id) && (NULL != input_mask)) - { - begin = input_mask; - unsigned short mask_count = 0; - - do - { - // get the length of the current element and replace , with null - for (end = begin; *end && *end != ','; end++); - - if (1 == sscanf (begin, "%" SCNd32 ",", &element)) - { - //element in the middle - begin = end + 1; - } - else if (*begin == 0) - { - break; - } - else - { - LOG (GNUNET_ERROR_TYPE_ERROR, - _ ("Could not convert `%s' to integer.\n"), begin); - return; - } - - if (element) - mask[mask_count / 8] = mask[mask_count / 8] | 1 << (mask_count % 8); - mask_count++; + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Could not convert `%s' to int64_t.\n"), + begin); + GNUNET_free (elements); + return; } - while (mask_count < element_count); - } - else if (NULL != input_peer_id) - for (i = 0; i <= mask_bytes; i++) - mask[i] = UCHAR_MAX; // all 1's - - if (input_peer_id && - (NULL == GNUNET_SCALARPRODUCT_request (cfg, - &closure->key, - &closure->peer, - elements, element_count, - mask, mask_bytes, - &requester_callback, - (void *) &closure))) - { - GNUNET_free (elements); - GNUNET_free (mask); - return; + element.value = GNUNET_htonll (element.value); + elements[i] = element; + begin = end + 1; } - if ((NULL == input_peer_id) && - (NULL == GNUNET_SCALARPRODUCT_response (cfg, - &closure->key, - elements, element_count, - &responder_callback, - (void *) &closure))) + if ( ( (NULL != input_peer_id) && + (NULL == (computation + = GNUNET_SCALARPRODUCT_start_computation (cfg, + &session_key, + &peer_id, + elements, element_count, + &requester_callback, + NULL))) ) || + ( (NULL == input_peer_id) && + (NULL == (computation + = GNUNET_SCALARPRODUCT_accept_computation (cfg, + &session_key, + elements, element_count, + &responder_callback, + NULL))) ) ) { + fprintf (stderr, + _("Failed to initiate computation, were all keys unique?\n")); GNUNET_free (elements); - GNUNET_free (mask); return; } GNUNET_free (elements); - GNUNET_free (mask); - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, - &shutdown_task, - NULL); - + GNUNET_SCHEDULER_add_shutdown (&shutdown_task, + NULL); ret = 0; } @@ -393,18 +344,15 @@ int main (int argc, char *const *argv) { static const struct GNUNET_GETOPT_CommandLineOption options[] = { - {'e', "elements", "\"val1,val2,...,valn\"", + {'e', "elements", "\"key1,val1;key2,val2;...,keyn,valn;\"", gettext_noop ("A comma separated list of elements to compare as vector with our remote peer."), 1, &GNUNET_GETOPT_set_string, &input_elements}, - {'m', "mask", "\"0,1,...,maskn\"", - gettext_noop ("A comma separated mask to select which elements should actually be compared."), - 1, &GNUNET_GETOPT_set_string, &input_mask}, {'p', "peer", "PEERID", gettext_noop ("[Optional] peer to calculate our scalarproduct with. If this parameter is not given, the service will wait for a remote peer to compute the request."), 1, &GNUNET_GETOPT_set_string, &input_peer_id}, {'k', "key", "TRANSACTION_ID", gettext_noop ("Transaction ID shared with peer."), - 1, &GNUNET_GETOPT_set_string, &input_key}, + 1, &GNUNET_GETOPT_set_string, &input_session_key}, GNUNET_GETOPT_OPTION_END }; @@ -416,3 +364,4 @@ main (int argc, char *const *argv) options, &run, NULL)) ? ret : 1; } +/* end of gnunet-scalarproduct.c */