GNUnet  0.19.2
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 "platform.h"
28 #include <gcrypt.h>
29 #include <inttypes.h>
30 
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", \
37  __VA_ARGS__)
38 
39 
43 static struct GNUNET_HashCode session_key;
44 
48 static struct GNUNET_PeerIdentity peer_id;
49 
53 static char *input_peer_id;
54 
58 static char *input_session_key;
59 
63 static char *input_elements;
64 
68 static int ret = -1;
69 
74 
75 
82 static void
83 responder_callback (void *cls,
85 {
86  switch (status)
87  {
89  ret = 0;
91  "Session %s concluded.\n",
93  break;
94 
97  "Session %s failed: invalid response\n",
99  break;
100 
103  "Session %s failed: service failure\n",
105  break;
106 
109  "Session %s failed: service disconnect!\n",
111  break;
112 
113  default:
115  "Session %s failed: return code %d\n",
117  status);
118  }
119  computation = NULL;
121 }
122 
123 
131 static void
134  gcry_mpi_t result)
135 {
136  unsigned char *buf;
137  gcry_error_t rc;
138 
139  switch (status)
140  {
142  if (0 == (rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, result)))
143  {
144  ret = 0;
145  fprintf (stdout,
146  "%s\n",
147  buf);
148  fflush (stdout);
149  }
150  else
152  "gcry_mpi_aprint",
153  rc);
154  break;
155 
158  "Session %s with peer %s failed: invalid response received\n",
160  GNUNET_i2s (&peer_id));
161  break;
162 
165  "Session %s with peer %s failed: API failure\n",
167  GNUNET_i2s (&peer_id));
168  break;
169 
172  "Session %s with peer %s was disconnected from service.\n",
174  GNUNET_i2s (&peer_id));
175  break;
176 
177  default:
179  "Session %s with peer %s failed: return code %d\n",
181  GNUNET_i2s (&peer_id),
182  status);
183  }
184  computation = NULL;
186 }
187 
188 
194 static void
195 shutdown_task (void *cls)
196 {
197  if (NULL != computation)
198  {
200  ret = 1; /* aborted */
201  }
202 }
203 
204 
213 static void
214 run (void *cls,
215  char *const *args,
216  const char *cfgfile,
217  const struct GNUNET_CONFIGURATION_Handle *cfg)
218 {
219  char *begin = input_elements;
220  char *end;
221  unsigned int i;
222  struct GNUNET_SCALARPRODUCT_Element *elements;
223  uint32_t element_count = 0;
224 
225  if (NULL == input_elements)
226  {
228  _ ("You must specify at least one message ID to check!\n"));
229  return;
230  }
231  if ((NULL == input_session_key) ||
232  (0 == strlen (input_session_key)))
233  {
235  _ (
236  "This program needs a session identifier for comparing vectors.\n"));
237  return;
238  }
240  strlen (input_session_key),
241  &session_key);
242  if ((NULL != input_peer_id) &&
243  (GNUNET_OK !=
245  strlen (input_peer_id),
246  &peer_id.public_key)))
247  {
249  _ ("Tried to set initiator mode, as peer ID was given. "
250  "However, `%s' is not a valid peer identifier.\n"),
251  input_peer_id);
252  return;
253  }
254  if (('\'' == *begin) &&
255  ('\'' == begin[strlen (begin) - 1]))
256  {
257  begin[strlen (begin) - 1] = '\0';
258  if (strlen (begin) > 0)
259  begin++;
260  }
261  for (end = begin; 0 != *end; end++)
262  if (*end == ';')
263  element_count++;
264  if (0 == element_count)
265  {
267  _ ("Need elements to compute the scalarproduct, got none.\n"));
268  return;
269  }
270 
271  elements = GNUNET_malloc (sizeof(struct GNUNET_SCALARPRODUCT_Element)
272  * element_count);
273 
274  for (i = 0; i < element_count; i++)
275  {
276  struct GNUNET_SCALARPRODUCT_Element element;
277  char*separator = NULL;
278 
279  /* get the length of the current key,value; tuple */
280  for (end = begin; *end != ';'; end++)
281  if (*end == ',')
282  separator = end;
283 
284  /* final element */
285  if ((NULL == separator) ||
286  (begin == separator) ||
287  (separator == end - 1))
288  {
290  _ ("Malformed input, could not parse `%s'\n"),
291  begin);
292  GNUNET_free (elements);
293  return;
294  }
295  *separator = 0;
296  /* read the element's key */
297  GNUNET_CRYPTO_hash (begin,
298  strlen (begin),
299  &element.key);
300 
301  /* read the element's value */
302  if (1 !=
303  sscanf (separator + 1,
304  "%" SCNd64 ";",
305  &element.value))
306  {
308  _ ("Could not convert `%s' to int64_t.\n"),
309  begin);
310  GNUNET_free (elements);
311  return;
312  }
313  element.value = GNUNET_htonll (element.value);
314  elements[i] = element;
315  begin = end + 1;
316  }
317 
318  if (((NULL != input_peer_id) &&
319  (NULL == (computation
321  &session_key,
322  &peer_id,
323  elements,
324  element_count,
326  NULL)))) ||
327  ((NULL == input_peer_id) &&
328  (NULL == (computation
330  &session_key,
331  elements,
332  element_count,
333  &
335  NULL)))))
336  {
337  fprintf (stderr,
338  _ ("Failed to initiate computation, were all keys unique?\n"));
339  GNUNET_free (elements);
340  return;
341  }
342  GNUNET_free (elements);
344  NULL);
345  ret = 0;
346 }
347 
348 
356 int
357 main (int argc, char *const *argv)
358 {
361  "elements",
362  "\"key1,val1;key2,val2;...,keyn,valn;\"",
363  gettext_noop (
364  "A comma separated list of elements to compare as vector with our remote peer."),
365  &input_elements),
366 
368  "elements",
369  "\"key1,val1;key2,val2;...,keyn,valn;\"",
370  gettext_noop (
371  "A comma separated list of elements to compare as vector with our remote peer."),
372  &input_elements),
373 
375  "peer",
376  "PEERID",
377  gettext_noop (
378  "[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."),
379  &input_peer_id),
380 
382  "key",
383  "TRANSACTION_ID",
384  gettext_noop (
385  "Transaction ID shared with peer."),
387 
389  };
390 
391  return (GNUNET_OK ==
392  GNUNET_PROGRAM_run (argc,
393  argv,
394  "gnunet-scalarproduct",
395  gettext_noop (
396  "Calculate the Vectorproduct with a GNUnet peer."),
397  options, &run, NULL)) ? ret : 1;
398 }
399 
400 
401 /* end of gnunet-scalarproduct.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define gettext_noop(String)
Definition: gettext.h:70
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
uint16_t status
See PRISM_STATUS_*-constants.
static int result
Global testing status.
static struct GNUNET_HashCode session_key
the session key identifying this computation
static char * input_elements
Option -e: vector to calculate a scalarproduct with.
static void shutdown_task(void *cls)
Task run during shutdown.
static int ret
Global return value.
static char * input_peer_id
Option -p: destination peer identity for checking message-ids with.
static char * input_session_key
Option -p: destination peer identity for checking message-ids with.
static void responder_callback(void *cls, enum GNUNET_SCALARPRODUCT_ResponseStatus status)
Callback called if we are initiating a new computation session.
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.
static struct GNUNET_PeerIdentity peer_id
PeerID we want to compute a scalar product with.
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.
#define LOG(kind,...)
int main(int argc, char *const *argv)
The main function to the scalarproduct client.
static struct GNUNET_SCALARPRODUCT_ComputationHandle * computation
our Scalarproduct Computation handle
static char buf[2048]
Constants for network protocols.
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.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
enum GNUNET_GenericReturnValue 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:357
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:37
@ GNUNET_OK
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue 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,...
Definition: program.c:400
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's client for computing a scalar product.
GNUNET_SCALARPRODUCT_ResponseStatus
Result status values for the computation.
void GNUNET_SCALARPRODUCT_cancel(struct GNUNET_SCALARPRODUCT_ComputationHandle *h)
Cancel an ongoing computation or revoke our collaboration offer.
struct GNUNET_SCALARPRODUCT_ComputationHandle * GNUNET_SCALARPRODUCT_accept_computation(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_HashCode *session_key, const struct GNUNET_SCALARPRODUCT_Element *elements, uint32_t element_count, GNUNET_SCALARPRODUCT_ContinuationWithStatus cont, void *cont_cls)
Used by Bob's client to cooperate with Alice,.
@ GNUNET_SCALARPRODUCT_STATUS_SUCCESS
The computation was successful.
@ GNUNET_SCALARPRODUCT_STATUS_FAILURE
We encountered some error.
@ GNUNET_SCALARPRODUCT_STATUS_DISCONNECTED
We got disconnected from the SCALARPRODUCT service.
@ GNUNET_SCALARPRODUCT_STATUS_INVALID_RESPONSE
We got an invalid response.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:534
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,...
Definition: scheduler.c:1303
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
Scalar Product API Message Types.
#define LOG_GCRY(level, cmd, rc)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
Definition: scalarproduct.h:35
Definition of a command line option.
A 512-bit hashcode.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
A handle returned for each computation.
An element key-value pair for scalarproduct.
struct GNUNET_HashCode key
Key used to identify matching pairs of values to multiply.
int64_t value
Value to multiply in scalar product, in NBO.