2 This file is part of GNUnet.
3 Copyright (C) 2013, 2014 GNUnet e.V.
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.
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.
17 * @file scalarproduct/gnunet-scalarproduct.c
18 * @brief scalarproduct client
19 * @author Christian M. Fuchs
21 #define GCRYPT_NO_DEPRECATED
26 #include "gnunet_util_lib.h"
27 #include "gnunet_scalarproduct_service.h"
28 #include "gnunet_protocols.h"
29 #include "scalarproduct.h"
31 #define LOG(kind,...) GNUNET_log_from (kind, "gnunet-scalarproduct",__VA_ARGS__)
35 * the session key identifying this computation
37 static struct GNUNET_HashCode session_key;
40 * PeerID we want to compute a scalar product with
42 static struct GNUNET_PeerIdentity peer_id;
45 * Option -p: destination peer identity for checking message-ids with
47 static char *input_peer_id;
50 * Option -p: destination peer identity for checking message-ids with
52 static char *input_session_key;
55 * Option -e: vector to calculate a scalarproduct with
57 static char *input_elements;
65 * our Scalarproduct Computation handle
67 static struct GNUNET_SCALARPRODUCT_ComputationHandle *computation;
71 * Callback called if we are initiating a new computation session
74 * @param status if our job was successfully processed
77 responder_callback (void *cls,
78 enum GNUNET_SCALARPRODUCT_ResponseStatus status)
82 case GNUNET_SCALARPRODUCT_STATUS_SUCCESS:
84 LOG (GNUNET_ERROR_TYPE_INFO,
85 "Session %s concluded.\n",
86 GNUNET_h2s (&session_key));
88 case GNUNET_SCALARPRODUCT_STATUS_INVALID_RESPONSE:
89 LOG (GNUNET_ERROR_TYPE_ERROR,
90 "Session %s failed: invalid response\n",
91 GNUNET_h2s (&session_key));
93 case GNUNET_SCALARPRODUCT_STATUS_FAILURE:
94 LOG (GNUNET_ERROR_TYPE_ERROR,
95 "Session %s failed: service failure\n",
96 GNUNET_h2s (&session_key));
98 case GNUNET_SCALARPRODUCT_STATUS_DISCONNECTED:
99 LOG (GNUNET_ERROR_TYPE_ERROR,
100 "Session %s failed: service disconnect!\n",
101 GNUNET_h2s (&session_key));
104 LOG (GNUNET_ERROR_TYPE_ERROR,
105 "Session %s failed: return code %d\n",
106 GNUNET_h2s (&session_key),
110 GNUNET_SCHEDULER_shutdown ();
115 * Callback called if we are initiating a new computation session
118 * @param status if our job was successfully processed
119 * @param result the result in gnu/gcry MPI format
122 requester_callback (void *cls,
123 enum GNUNET_SCALARPRODUCT_ResponseStatus status,
131 case GNUNET_SCALARPRODUCT_STATUS_SUCCESS:
132 if (0 == (rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, result)))
141 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
145 case GNUNET_SCALARPRODUCT_STATUS_INVALID_RESPONSE:
146 LOG (GNUNET_ERROR_TYPE_ERROR,
147 "Session %s with peer %s failed: invalid response received\n",
148 GNUNET_h2s (&session_key),
149 GNUNET_i2s (&peer_id));
151 case GNUNET_SCALARPRODUCT_STATUS_FAILURE:
152 LOG (GNUNET_ERROR_TYPE_ERROR,
153 "Session %s with peer %s failed: API failure\n",
154 GNUNET_h2s (&session_key),
155 GNUNET_i2s (&peer_id));
157 case GNUNET_SCALARPRODUCT_STATUS_DISCONNECTED:
158 LOG (GNUNET_ERROR_TYPE_ERROR,
159 "Session %s with peer %s was disconnected from service.\n",
160 GNUNET_h2s (&session_key),
161 GNUNET_i2s (&peer_id));
164 LOG (GNUNET_ERROR_TYPE_ERROR,
165 "Session %s with peer %s failed: return code %d\n",
166 GNUNET_h2s (&session_key),
167 GNUNET_i2s (&peer_id),
171 GNUNET_SCHEDULER_shutdown ();
176 * Task run during shutdown.
182 shutdown_task (void *cls)
184 if (NULL != computation)
186 GNUNET_SCALARPRODUCT_cancel (computation);
187 ret = 1; /* aborted */
193 * Main function that will be run by the scheduler.
196 * @param args remaining command-line arguments
197 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
198 * @param cfg configuration
204 const struct GNUNET_CONFIGURATION_Handle *cfg)
206 char *begin = input_elements;
209 struct GNUNET_SCALARPRODUCT_Element *elements;
210 uint32_t element_count = 0;
212 if (NULL == input_elements)
214 LOG (GNUNET_ERROR_TYPE_ERROR,
215 _("You must specify at least one message ID to check!\n"));
218 if ( (NULL == input_session_key) ||
219 (0 == strlen (input_session_key)) )
221 LOG (GNUNET_ERROR_TYPE_ERROR,
222 _("This program needs a session identifier for comparing vectors.\n"));
225 GNUNET_CRYPTO_hash (input_session_key,
226 strlen (input_session_key),
228 if ( (NULL != input_peer_id) &&
230 GNUNET_CRYPTO_eddsa_public_key_from_string (input_peer_id,
231 strlen (input_peer_id),
232 &peer_id.public_key)) )
234 LOG (GNUNET_ERROR_TYPE_ERROR,
235 _("Tried to set initiator mode, as peer ID was given. "
236 "However, `%s' is not a valid peer identifier.\n"),
240 if ( ('\'' == *begin) &&
241 ('\'' == begin[strlen(begin)-1]) )
243 begin[strlen(begin)-1] = '\0';
244 if (strlen (begin) > 0)
247 for (end = begin; 0 != *end; end++)
250 if (0 == element_count)
252 LOG (GNUNET_ERROR_TYPE_ERROR,
253 _("Need elements to compute the scalarproduct, got none.\n"));
257 elements = GNUNET_malloc (sizeof(struct GNUNET_SCALARPRODUCT_Element) * element_count);
259 for (i = 0; i < element_count;i++)
261 struct GNUNET_SCALARPRODUCT_Element element;
262 char* separator = NULL;
264 /* get the length of the current key,value; tupel */
265 for (end = begin; *end != ';'; end++)
270 if ( (NULL == separator) ||
271 (begin == separator) ||
272 (separator == end - 1) )
274 LOG (GNUNET_ERROR_TYPE_ERROR,
275 _("Malformed input, could not parse `%s'\n"),
277 GNUNET_free (elements);
281 /* read the element's key */
282 GNUNET_CRYPTO_hash (begin,
286 /* read the element's value */
288 sscanf (separator + 1,
292 LOG (GNUNET_ERROR_TYPE_ERROR,
293 _("Could not convert `%s' to int64_t.\n"),
295 GNUNET_free (elements);
298 element.value = GNUNET_htonll (element.value);
299 elements[i] = element;
303 if ( ( (NULL != input_peer_id) &&
304 (NULL == (computation
305 = GNUNET_SCALARPRODUCT_start_computation (cfg,
308 elements, element_count,
311 ( (NULL == input_peer_id) &&
312 (NULL == (computation
313 = GNUNET_SCALARPRODUCT_accept_computation (cfg,
315 elements, element_count,
320 _("Failed to initiate computation, were all keys unique?\n"));
321 GNUNET_free (elements);
324 GNUNET_free (elements);
325 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
332 * The main function to the scalarproduct client.
334 * @param argc number of arguments from the command line
335 * @param argv command line arguments
336 * @return 0 ok, 1 on error
339 main (int argc, char *const *argv)
341 struct GNUNET_GETOPT_CommandLineOption options[] = {
343 GNUNET_GETOPT_option_string ('e',
345 "\"key1,val1;key2,val2;...,keyn,valn;\"",
346 gettext_noop ("A comma separated list of elements to compare as vector with our remote peer."),
349 GNUNET_GETOPT_option_string ('e',
351 "\"key1,val1;key2,val2;...,keyn,valn;\"",
352 gettext_noop ("A comma separated list of elements to compare as vector with our remote peer."),
355 GNUNET_GETOPT_option_string ('p',
358 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."),
361 GNUNET_GETOPT_option_string ('k',
364 gettext_noop ("Transaction ID shared with peer."),
367 GNUNET_GETOPT_OPTION_END
371 GNUNET_PROGRAM_run (argc,
373 "gnunet-scalarproduct",
374 gettext_noop ("Calculate the Vectorproduct with a GNUnet peer."),
375 options, &run, NULL)) ? ret : 1;
378 /* end of gnunet-scalarproduct.c */