GNUnet  0.10.x
gnunet-scalarproduct.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2013, 2014 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
26 #define GCRYPT_NO_DEPRECATED
27 #include <gcrypt.h>
28 #include <inttypes.h>
29 
30 #include "platform.h"
31 #include "gnunet_util_lib.h"
33 #include "gnunet_protocols.h"
34 #include "scalarproduct.h"
35 
36 #define LOG(kind,...) GNUNET_log_from (kind, "gnunet-scalarproduct",__VA_ARGS__)
37 
38 
43 
48 
52 static char *input_peer_id;
53 
57 static char *input_session_key;
58 
62 static char *input_elements;
63 
67 static int ret = -1;
68 
73 
74 
81 static void
82 responder_callback (void *cls,
84 {
85  switch (status)
86  {
88  ret = 0;
90  "Session %s concluded.\n",
92  break;
95  "Session %s failed: invalid response\n",
97  break;
100  "Session %s failed: service failure\n",
102  break;
105  "Session %s failed: service disconnect!\n",
107  break;
108  default:
110  "Session %s failed: return code %d\n",
112  status);
113  }
114  computation = NULL;
116 }
117 
118 
126 static void
129  gcry_mpi_t result)
130 {
131  unsigned char *buf;
132  gcry_error_t rc;
133 
134  switch (status)
135  {
137  if (0 == (rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, result)))
138  {
139  ret = 0;
140  fprintf (stdout,
141  "%s\n",
142  buf);
143  fflush (stdout);
144  }
145  else
147  "gcry_mpi_aprint",
148  rc);
149  break;
152  "Session %s with peer %s failed: invalid response received\n",
154  GNUNET_i2s (&peer_id));
155  break;
158  "Session %s with peer %s failed: API failure\n",
160  GNUNET_i2s (&peer_id));
161  break;
164  "Session %s with peer %s was disconnected from service.\n",
166  GNUNET_i2s (&peer_id));
167  break;
168  default:
170  "Session %s with peer %s failed: return code %d\n",
172  GNUNET_i2s (&peer_id),
173  status);
174  }
175  computation = NULL;
177 }
178 
179 
186 static void
187 shutdown_task (void *cls)
188 {
189  if (NULL != computation)
190  {
191  GNUNET_SCALARPRODUCT_cancel (computation);
192  ret = 1; /* aborted */
193  }
194 }
195 
196 
205 static void
206 run (void *cls,
207  char *const *args,
208  const char *cfgfile,
209  const struct GNUNET_CONFIGURATION_Handle *cfg)
210 {
211  char *begin = input_elements;
212  char *end;
213  unsigned int i;
214  struct GNUNET_SCALARPRODUCT_Element *elements;
215  uint32_t element_count = 0;
216 
217  if (NULL == input_elements)
218  {
220  _("You must specify at least one message ID to check!\n"));
221  return;
222  }
223  if ( (NULL == input_session_key) ||
224  (0 == strlen (input_session_key)) )
225  {
227  _("This program needs a session identifier for comparing vectors.\n"));
228  return;
229  }
231  strlen (input_session_key),
232  &session_key);
233  if ( (NULL != input_peer_id) &&
234  (GNUNET_OK !=
236  strlen (input_peer_id),
237  &peer_id.public_key)) )
238  {
240  _("Tried to set initiator mode, as peer ID was given. "
241  "However, `%s' is not a valid peer identifier.\n"),
242  input_peer_id);
243  return;
244  }
245  if ( ('\'' == *begin) &&
246  ('\'' == begin[strlen(begin)-1]) )
247  {
248  begin[strlen(begin)-1] = '\0';
249  if (strlen (begin) > 0)
250  begin++;
251  }
252  for (end = begin; 0 != *end; end++)
253  if (*end == ';')
254  element_count++;
255  if (0 == element_count)
256  {
258  _("Need elements to compute the scalarproduct, got none.\n"));
259  return;
260  }
261 
262  elements = GNUNET_malloc (sizeof(struct GNUNET_SCALARPRODUCT_Element) * element_count);
263 
264  for (i = 0; i < element_count;i++)
265  {
266  struct GNUNET_SCALARPRODUCT_Element element;
267  char* separator = NULL;
268 
269  /* get the length of the current key,value; tupel */
270  for (end = begin; *end != ';'; end++)
271  if (*end == ',')
272  separator = end;
273 
274  /* final element */
275  if ( (NULL == separator) ||
276  (begin == separator) ||
277  (separator == end - 1) )
278  {
280  _("Malformed input, could not parse `%s'\n"),
281  begin);
282  GNUNET_free (elements);
283  return;
284  }
285  *separator = 0;
286  /* read the element's key */
287  GNUNET_CRYPTO_hash (begin,
288  strlen (begin),
289  &element.key);
290 
291  /* read the element's value */
292  if (1 !=
293  sscanf (separator + 1,
294  "%" SCNd64 ";",
295  &element.value) )
296  {
298  _("Could not convert `%s' to int64_t.\n"),
299  begin);
300  GNUNET_free (elements);
301  return;
302  }
303  element.value = GNUNET_htonll (element.value);
304  elements[i] = element;
305  begin = end + 1;
306  }
307 
308  if ( ( (NULL != input_peer_id) &&
309  (NULL == (computation
311  &session_key,
312  &peer_id,
313  elements, element_count,
315  NULL))) ) ||
316  ( (NULL == input_peer_id) &&
317  (NULL == (computation
319  &session_key,
320  elements, element_count,
322  NULL))) ) )
323  {
324  fprintf (stderr,
325  _("Failed to initiate computation, were all keys unique?\n"));
326  GNUNET_free (elements);
327  return;
328  }
329  GNUNET_free (elements);
331  NULL);
332  ret = 0;
333 }
334 
335 
343 int
344 main (int argc, char *const *argv)
345 {
346  struct GNUNET_GETOPT_CommandLineOption options[] = {
347 
349  "elements",
350  "\"key1,val1;key2,val2;...,keyn,valn;\"",
351  gettext_noop ("A comma separated list of elements to compare as vector with our remote peer."),
352  &input_elements),
353 
355  "elements",
356  "\"key1,val1;key2,val2;...,keyn,valn;\"",
357  gettext_noop ("A comma separated list of elements to compare as vector with our remote peer."),
358  &input_elements),
359 
361  "peer",
362  "PEERID",
363  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."),
364  &input_peer_id),
365 
367  "key",
368  "TRANSACTION_ID",
369  gettext_noop ("Transaction ID shared with peer."),
371 
373  };
374 
375  return (GNUNET_OK ==
376  GNUNET_PROGRAM_run (argc,
377  argv,
378  "gnunet-scalarproduct",
379  gettext_noop ("Calculate the Vectorproduct with a GNUnet peer."),
380  options, &run, NULL)) ? ret : 1;
381 }
382 
383 /* end of gnunet-scalarproduct.c */
A handle returned for each computation.
static int ret
Global return value.
static char * input_peer_id
Option -p: destination peer identity for checking message-ids with.
static void shutdown_task(void *cls)
Task run during shutdown.
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1293
struct GNUNET_HashCode key
Key used to identify matching pairs of values to multiply.
#define LOG_GCRY(level, cmd, rc)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
Definition: scalarproduct.h:35
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Main function that will be run by the scheduler.
struct GNUNET_SCALARPRODUCT_ComputationHandle * GNUNET_SCALARPRODUCT_accept_computation(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_HashCode *key, const struct GNUNET_SCALARPRODUCT_Element *elements, uint32_t element_count, GNUNET_SCALARPRODUCT_ContinuationWithStatus cont, void *cont_cls)
Used by Bob&#39;s client to cooperate with Alice,.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
Definition of a command line option.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:524
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
static char * input_session_key
Option -p: destination peer identity for checking message-ids with.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_string(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a string.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
void GNUNET_SCALARPRODUCT_cancel(struct GNUNET_SCALARPRODUCT_ComputationHandle *h)
Cancel an ongoing computation or revoke our collaboration offer.
static struct GNUNET_HashCode session_key
the session key identifying this computation
Scalar Product API Message Types.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
static struct GNUNET_SCALARPRODUCT_ComputationHandle * computation
our Scalarproduct Computation handle
static void responder_callback(void *cls, enum GNUNET_SCALARPRODUCT_ResponseStatus status)
Callback called if we are initiating a new computation session.
uint16_t status
See PRISM_STATUS_*-constants.
static char buf[2048]
static struct GNUNET_PeerIdentity peer_id
PeerID we want to compute a scalar product with.
static int result
Global testing status.
We got disconnected from the SCALARPRODUCT service.
A 512-bit hashcode.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
int64_t value
Value to multiply in scalar product, in NBO.
int main(int argc, char *const *argv)
The main function to the scalarproduct client.
int GNUNET_CRYPTO_eddsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:501
The identity of the host (wraps the signing key of the peer).
configuration data
Definition: configuration.c:85
static void requester_callback(void *cls, enum GNUNET_SCALARPRODUCT_ResponseStatus status, gcry_mpi_t result)
Callback called if we are initiating a new computation session.
int GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:361
static char * input_elements
Option -e: vector to calculate a scalarproduct with.
#define LOG(kind,...)
GNUNET_SCALARPRODUCT_ResponseStatus
Result status values for the computation.
struct GNUNET_SCALARPRODUCT_ComputationHandle * GNUNET_SCALARPRODUCT_start_computation(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_HashCode *session_key, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_SCALARPRODUCT_Element *elements, uint32_t element_count, GNUNET_SCALARPRODUCT_DatumProcessor cont, void *cont_cls)
Request by Alice&#39;s client for computing a scalar product.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_malloc(size)
Wrapper around malloc.
An element key-value pair for scalarproduct.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
#define gettext_noop(String)
Definition: gettext.h:69