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.
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/>.
20 * @file scalarproduct/gnunet-scalarproduct.c
21 * @brief scalarproduct client
22 * @author Christian M. Fuchs
24 #define GCRYPT_NO_DEPRECATED
29 #include "gnunet_util_lib.h"
30 #include "gnunet_scalarproduct_service.h"
31 #include "gnunet_protocols.h"
32 #include "scalarproduct.h"
34 #define LOG(kind,...) GNUNET_log_from (kind, "gnunet-scalarproduct",__VA_ARGS__)
38 * the session key identifying this computation
40 static struct GNUNET_HashCode session_key;
43 * PeerID we want to compute a scalar product with
45 static struct GNUNET_PeerIdentity peer_id;
48 * Option -p: destination peer identity for checking message-ids with
50 static char *input_peer_id;
53 * Option -p: destination peer identity for checking message-ids with
55 static char *input_session_key;
58 * Option -e: vector to calculate a scalarproduct with
60 static char *input_elements;
68 * our Scalarproduct Computation handle
70 static struct GNUNET_SCALARPRODUCT_ComputationHandle *computation;
74 * Callback called if we are initiating a new computation session
77 * @param status if our job was successfully processed
80 responder_callback (void *cls,
81 enum GNUNET_SCALARPRODUCT_ResponseStatus status)
85 case GNUNET_SCALARPRODUCT_STATUS_SUCCESS:
87 LOG (GNUNET_ERROR_TYPE_INFO,
88 "Session %s concluded.\n",
89 GNUNET_h2s (&session_key));
91 case GNUNET_SCALARPRODUCT_STATUS_INVALID_RESPONSE:
92 LOG (GNUNET_ERROR_TYPE_ERROR,
93 "Session %s failed: invalid response\n",
94 GNUNET_h2s (&session_key));
96 case GNUNET_SCALARPRODUCT_STATUS_FAILURE:
97 LOG (GNUNET_ERROR_TYPE_ERROR,
98 "Session %s failed: service failure\n",
99 GNUNET_h2s (&session_key));
101 case GNUNET_SCALARPRODUCT_STATUS_DISCONNECTED:
102 LOG (GNUNET_ERROR_TYPE_ERROR,
103 "Session %s failed: service disconnect!\n",
104 GNUNET_h2s (&session_key));
107 LOG (GNUNET_ERROR_TYPE_ERROR,
108 "Session %s failed: return code %d\n",
109 GNUNET_h2s (&session_key),
113 GNUNET_SCHEDULER_shutdown ();
118 * Callback called if we are initiating a new computation session
121 * @param status if our job was successfully processed
122 * @param result the result in gnu/gcry MPI format
125 requester_callback (void *cls,
126 enum GNUNET_SCALARPRODUCT_ResponseStatus status,
134 case GNUNET_SCALARPRODUCT_STATUS_SUCCESS:
135 if (0 == (rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, result)))
144 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
148 case GNUNET_SCALARPRODUCT_STATUS_INVALID_RESPONSE:
149 LOG (GNUNET_ERROR_TYPE_ERROR,
150 "Session %s with peer %s failed: invalid response received\n",
151 GNUNET_h2s (&session_key),
152 GNUNET_i2s (&peer_id));
154 case GNUNET_SCALARPRODUCT_STATUS_FAILURE:
155 LOG (GNUNET_ERROR_TYPE_ERROR,
156 "Session %s with peer %s failed: API failure\n",
157 GNUNET_h2s (&session_key),
158 GNUNET_i2s (&peer_id));
160 case GNUNET_SCALARPRODUCT_STATUS_DISCONNECTED:
161 LOG (GNUNET_ERROR_TYPE_ERROR,
162 "Session %s with peer %s was disconnected from service.\n",
163 GNUNET_h2s (&session_key),
164 GNUNET_i2s (&peer_id));
167 LOG (GNUNET_ERROR_TYPE_ERROR,
168 "Session %s with peer %s failed: return code %d\n",
169 GNUNET_h2s (&session_key),
170 GNUNET_i2s (&peer_id),
174 GNUNET_SCHEDULER_shutdown ();
179 * Task run during shutdown.
185 shutdown_task (void *cls)
187 if (NULL != computation)
189 GNUNET_SCALARPRODUCT_cancel (computation);
190 ret = 1; /* aborted */
196 * Main function that will be run by the scheduler.
199 * @param args remaining command-line arguments
200 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
201 * @param cfg configuration
207 const struct GNUNET_CONFIGURATION_Handle *cfg)
209 char *begin = input_elements;
212 struct GNUNET_SCALARPRODUCT_Element *elements;
213 uint32_t element_count = 0;
215 if (NULL == input_elements)
217 LOG (GNUNET_ERROR_TYPE_ERROR,
218 _("You must specify at least one message ID to check!\n"));
221 if ( (NULL == input_session_key) ||
222 (0 == strlen (input_session_key)) )
224 LOG (GNUNET_ERROR_TYPE_ERROR,
225 _("This program needs a session identifier for comparing vectors.\n"));
228 GNUNET_CRYPTO_hash (input_session_key,
229 strlen (input_session_key),
231 if ( (NULL != input_peer_id) &&
233 GNUNET_CRYPTO_eddsa_public_key_from_string (input_peer_id,
234 strlen (input_peer_id),
235 &peer_id.public_key)) )
237 LOG (GNUNET_ERROR_TYPE_ERROR,
238 _("Tried to set initiator mode, as peer ID was given. "
239 "However, `%s' is not a valid peer identifier.\n"),
243 if ( ('\'' == *begin) &&
244 ('\'' == begin[strlen(begin)-1]) )
246 begin[strlen(begin)-1] = '\0';
247 if (strlen (begin) > 0)
250 for (end = begin; 0 != *end; end++)
253 if (0 == element_count)
255 LOG (GNUNET_ERROR_TYPE_ERROR,
256 _("Need elements to compute the scalarproduct, got none.\n"));
260 elements = GNUNET_malloc (sizeof(struct GNUNET_SCALARPRODUCT_Element) * element_count);
262 for (i = 0; i < element_count;i++)
264 struct GNUNET_SCALARPRODUCT_Element element;
265 char* separator = NULL;
267 /* get the length of the current key,value; tupel */
268 for (end = begin; *end != ';'; end++)
273 if ( (NULL == separator) ||
274 (begin == separator) ||
275 (separator == end - 1) )
277 LOG (GNUNET_ERROR_TYPE_ERROR,
278 _("Malformed input, could not parse `%s'\n"),
280 GNUNET_free (elements);
284 /* read the element's key */
285 GNUNET_CRYPTO_hash (begin,
289 /* read the element's value */
291 sscanf (separator + 1,
295 LOG (GNUNET_ERROR_TYPE_ERROR,
296 _("Could not convert `%s' to int64_t.\n"),
298 GNUNET_free (elements);
301 element.value = GNUNET_htonll (element.value);
302 elements[i] = element;
306 if ( ( (NULL != input_peer_id) &&
307 (NULL == (computation
308 = GNUNET_SCALARPRODUCT_start_computation (cfg,
311 elements, element_count,
314 ( (NULL == input_peer_id) &&
315 (NULL == (computation
316 = GNUNET_SCALARPRODUCT_accept_computation (cfg,
318 elements, element_count,
323 _("Failed to initiate computation, were all keys unique?\n"));
324 GNUNET_free (elements);
327 GNUNET_free (elements);
328 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
335 * The main function to the scalarproduct client.
337 * @param argc number of arguments from the command line
338 * @param argv command line arguments
339 * @return 0 ok, 1 on error
342 main (int argc, char *const *argv)
344 struct GNUNET_GETOPT_CommandLineOption options[] = {
346 GNUNET_GETOPT_option_string ('e',
348 "\"key1,val1;key2,val2;...,keyn,valn;\"",
349 gettext_noop ("A comma separated list of elements to compare as vector with our remote peer."),
352 GNUNET_GETOPT_option_string ('e',
354 "\"key1,val1;key2,val2;...,keyn,valn;\"",
355 gettext_noop ("A comma separated list of elements to compare as vector with our remote peer."),
358 GNUNET_GETOPT_option_string ('p',
361 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 GNUNET_GETOPT_option_string ('k',
367 gettext_noop ("Transaction ID shared with peer."),
370 GNUNET_GETOPT_OPTION_END
374 GNUNET_PROGRAM_run (argc,
376 "gnunet-scalarproduct",
377 gettext_noop ("Calculate the Vectorproduct with a GNUnet peer."),
378 options, &run, NULL)) ? ret : 1;
381 /* end of gnunet-scalarproduct.c */