123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- /*
- This file is part of GNUnet.
- 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 Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- or (at your option) any later version.
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- SPDX-License-Identifier: AGPL3.0-or-later
- */
- /**
- * @file scalarproduct/gnunet-scalarproduct.c
- * @brief scalarproduct client
- * @author Christian M. Fuchs
- */
- #define GCRYPT_NO_DEPRECATED
- #include <gcrypt.h>
- #include <inttypes.h>
- #include "platform.h"
- #include "gnunet_util_lib.h"
- #include "gnunet_scalarproduct_service.h"
- #include "gnunet_protocols.h"
- #include "scalarproduct.h"
- #define LOG(kind,...) GNUNET_log_from (kind, "gnunet-scalarproduct",__VA_ARGS__)
- /**
- * the session key identifying this computation
- */
- static struct GNUNET_HashCode session_key;
- /**
- * 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
- */
- static char *input_peer_id;
- /**
- * Option -p: destination peer identity for checking message-ids with
- */
- static char *input_session_key;
- /**
- * Option -e: vector to calculate a scalarproduct with
- */
- static char *input_elements;
- /**
- * Global return value
- */
- static int ret = -1;
- /**
- * our Scalarproduct Computation handle
- */
- static struct GNUNET_SCALARPRODUCT_ComputationHandle *computation;
- /**
- * Callback called if we are initiating a new computation session
- *
- * @param cls unused
- * @param status if our job was successfully processed
- */
- static void
- responder_callback (void *cls,
- enum GNUNET_SCALARPRODUCT_ResponseStatus status)
- {
- switch (status)
- {
- case GNUNET_SCALARPRODUCT_STATUS_SUCCESS:
- ret = 0;
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Session %s concluded.\n",
- GNUNET_h2s (&session_key));
- break;
- case GNUNET_SCALARPRODUCT_STATUS_INVALID_RESPONSE:
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "Session %s failed: invalid response\n",
- GNUNET_h2s (&session_key));
- break;
- case GNUNET_SCALARPRODUCT_STATUS_FAILURE:
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "Session %s failed: service failure\n",
- GNUNET_h2s (&session_key));
- break;
- case GNUNET_SCALARPRODUCT_STATUS_DISCONNECTED:
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "Session %s failed: service disconnect!\n",
- GNUNET_h2s (&session_key));
- break;
- default:
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "Session %s failed: return code %d\n",
- GNUNET_h2s (&session_key),
- status);
- }
- computation = NULL;
- GNUNET_SCHEDULER_shutdown ();
- }
- /**
- * Callback called if we are initiating a new computation session
- *
- * @param cls unused
- * @param status if our job was successfully processed
- * @param result the result in gnu/gcry MPI format
- */
- static void
- requester_callback (void *cls,
- enum GNUNET_SCALARPRODUCT_ResponseStatus status,
- gcry_mpi_t result)
- {
- unsigned char *buf;
- gcry_error_t rc;
- switch (status)
- {
- case GNUNET_SCALARPRODUCT_STATUS_SUCCESS:
- if (0 == (rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, result)))
- {
- ret = 0;
- fprintf (stdout,
- "%s\n",
- buf);
- fflush (stdout);
- }
- else
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
- "gcry_mpi_aprint",
- rc);
- break;
- case GNUNET_SCALARPRODUCT_STATUS_INVALID_RESPONSE:
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "Session %s with peer %s failed: invalid response received\n",
- GNUNET_h2s (&session_key),
- GNUNET_i2s (&peer_id));
- break;
- case GNUNET_SCALARPRODUCT_STATUS_FAILURE:
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "Session %s with peer %s failed: API failure\n",
- GNUNET_h2s (&session_key),
- GNUNET_i2s (&peer_id));
- break;
- case GNUNET_SCALARPRODUCT_STATUS_DISCONNECTED:
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "Session %s with peer %s was disconnected from service.\n",
- 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 (&session_key),
- GNUNET_i2s (&peer_id),
- status);
- }
- computation = NULL;
- GNUNET_SCHEDULER_shutdown ();
- }
- /**
- * Task run during shutdown.
- *
- * @param cls unused
- * @param tc unused
- */
- static void
- shutdown_task (void *cls)
- {
- if (NULL != computation)
- {
- GNUNET_SCALARPRODUCT_cancel (computation);
- ret = 1; /* aborted */
- }
- }
- /**
- * Main function that will be run by the scheduler.
- *
- * @param cls closure
- * @param args remaining command-line arguments
- * @param cfgfile name of the configuration file used (for saving, can be NULL!)
- * @param cfg configuration
- */
- static void
- run (void *cls,
- char *const *args,
- const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
- {
- char *begin = input_elements;
- char *end;
- unsigned int i;
- struct GNUNET_SCALARPRODUCT_Element *elements;
- uint32_t element_count = 0;
- if (NULL == input_elements)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- _("You must specify at least one message ID to check!\n"));
- return;
- }
- 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"));
- return;
- }
- 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,
- _("Tried to set initiator mode, as peer ID was given. "
- "However, `%s' is not a valid peer identifier.\n"),
- input_peer_id);
- return;
- }
- if ( ('\'' == *begin) &&
- ('\'' == begin[strlen(begin)-1]) )
- {
- begin[strlen(begin)-1] = '\0';
- if (strlen (begin) > 0)
- begin++;
- }
- for (end = begin; 0 != *end; end++)
- if (*end == ';')
- element_count++;
- if (0 == element_count)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- _("Need elements to compute the scalarproduct, got none.\n"));
- return;
- }
- elements = GNUNET_malloc (sizeof(struct GNUNET_SCALARPRODUCT_Element) * 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) )
- {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- _("Malformed input, could not parse `%s'\n"),
- begin);
- GNUNET_free (elements);
- return;
- }
- *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) )
- {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- _("Could not convert `%s' to int64_t.\n"),
- begin);
- GNUNET_free (elements);
- return;
- }
- element.value = GNUNET_htonll (element.value);
- elements[i] = element;
- begin = end + 1;
- }
- 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);
- return;
- }
- GNUNET_free (elements);
- GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
- NULL);
- 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
- main (int argc, char *const *argv)
- {
- struct GNUNET_GETOPT_CommandLineOption options[] = {
- GNUNET_GETOPT_option_string ('e',
- "elements",
- "\"key1,val1;key2,val2;...,keyn,valn;\"",
- gettext_noop ("A comma separated list of elements to compare as vector with our remote peer."),
- &input_elements),
- GNUNET_GETOPT_option_string ('e',
- "elements",
- "\"key1,val1;key2,val2;...,keyn,valn;\"",
- gettext_noop ("A comma separated list of elements to compare as vector with our remote peer."),
- &input_elements),
- GNUNET_GETOPT_option_string ('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."),
- &input_peer_id),
- GNUNET_GETOPT_option_string ('k',
- "key",
- "TRANSACTION_ID",
- gettext_noop ("Transaction ID shared with peer."),
- &input_session_key),
- 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;
- }
- /* end of gnunet-scalarproduct.c */
|