- fixes
[oweals/gnunet.git] / src / secretsharing / gnunet-secretsharing-profiler.c
1 /*
2       This file is part of GNUnet
3       (C) 2014 Christian Grothoff (and other contributing authors)
4
5       GNUnet is free software; you can redistribute it and/or modify
6       it under the terms of the GNU General Public License as published
7       by the Free Software Foundation; either version 3, or (at your
8       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       General Public License for more details.
14
15       You should have received a copy of the GNU General Public License
16       along with GNUnet; see the file COPYING.  If not, write to the
17       Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18       Boston, MA 02111-1307, USA.
19  */
20
21 /**
22  * @file secretsharing/gnunet-secretsharing-profiler.c
23  * @brief profiling tool for distributed key generation and decryption
24  * @author Florian Dold
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_secretsharing_service.h"
29 #include "gnunet_testbed_service.h"
30
31 static unsigned int num_peers = 3;
32
33 static unsigned int threshold = 2;
34
35 static struct GNUNET_TIME_Relative timeout;
36
37 static struct GNUNET_SECRETSHARING_Session **session_handles;
38
39 static struct GNUNET_TESTBED_Operation **testbed_operations;
40
41 static unsigned int num_connected_handles;
42
43 static struct GNUNET_TESTBED_Peer **peers;
44
45 static struct GNUNET_PeerIdentity *peer_ids;
46
47 static unsigned int num_retrieved_peer_ids;
48
49 static struct GNUNET_HashCode session_id;
50
51 static int verbose;
52
53
54 /**
55  * Signature of the event handler function called by the
56  * respective event controller.
57  *
58  * @param cls closure
59  * @param event information about the event
60  */
61 static void
62 controller_cb (void *cls,
63                const struct GNUNET_TESTBED_EventInformation *event)
64 {
65   GNUNET_assert (0);
66 }
67
68
69 /**
70  * Callback to be called when a service connect operation is completed
71  *
72  * @param cls the callback closure from functions generating an operation
73  * @param op the operation that has been finished
74  * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter()
75  * @param emsg error message in case the operation has failed; will be NULL if
76  *          operation has executed successfully.
77  */
78 static void
79 connect_complete (void *cls,
80                   struct GNUNET_TESTBED_Operation *op,
81                   void *ca_result,
82                   const char *emsg)
83 {
84
85   if (NULL != emsg)
86   {
87     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
88                 "testbed connect emsg: %s\n",
89                 emsg);
90     GNUNET_assert (0);
91   }
92
93   num_connected_handles++;
94
95   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
96               "connect complete\n");
97
98   if (num_connected_handles == num_peers)
99   {
100     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
101                 "all peers connected\n");
102   }
103 }
104
105
106 static void
107 secret_ready_cb (void *cls,
108                  const struct GNUNET_SECRETSHARING_Share *my_share,
109                  const struct GNUNET_SECRETSHARING_PublicKey *public_key,
110                  unsigned int num_ready_peers,
111                  const struct GNUNET_PeerIdentity *ready_peers)
112 {
113   struct GNUNET_SECRETSHARING_Session **sp = cls;
114   unsigned int n = sp - session_handles;
115   if (NULL == my_share || NULL == public_key)
116   {
117     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "key generation failed for peer #%u\n", n);
118     return;
119   }
120   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "secret ready for peer #%u\n", n);
121   // FIXME: end profiler or try decryption if all secrets are ready
122 }
123
124
125 /**
126  * Adapter function called to establish a connection to
127  * a service.
128  *
129  * @param cls closure
130  * @param cfg configuration of the peer to connect to; will be available until
131  *          GNUNET_TESTBED_operation_done() is called on the operation returned
132  *          from GNUNET_TESTBED_service_connect()
133  * @return service handle to return in 'op_result', NULL on error
134  */
135 static void *
136 connect_adapter (void *cls,
137                  const struct GNUNET_CONFIGURATION_Handle *cfg)
138 {
139   struct GNUNET_SECRETSHARING_Session **sp = cls;
140
141   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
142               "connect adapter, %d peers\n",
143               num_peers);
144   *sp = GNUNET_SECRETSHARING_create_session (cfg,
145                                              num_peers,
146                                              peer_ids,
147                                              &session_id,
148                                              GNUNET_TIME_relative_to_absolute (timeout),
149                                              threshold,
150                                              &secret_ready_cb, sp);
151   return *sp;
152 }
153
154
155 /**
156  * Adapter function called to destroy a connection to
157  * a service.
158  *
159  * @param cls closure
160  * @param op_result service handle returned from the connect adapter
161  */
162 static void
163 disconnect_adapter(void *cls, void *op_result)
164 {
165   /* FIXME: what to do here? */
166 }
167
168
169 /**
170  * Callback to be called when the requested peer information is available
171  *
172  * @param cb_cls the closure from GNUNET_TETSBED_peer_get_information()
173  * @param op the operation this callback corresponds to
174  * @param pinfo the result; will be NULL if the operation has failed
175  * @param emsg error message if the operation has failed; will be NULL if the
176  *          operation is successfull
177  */
178 static void
179 peer_info_cb (void *cb_cls,
180               struct GNUNET_TESTBED_Operation *op,
181               const struct GNUNET_TESTBED_PeerInformation *pinfo,
182               const char *emsg)
183 {
184   struct GNUNET_PeerIdentity *p;
185   int i;
186
187   GNUNET_assert (NULL == emsg);
188
189   p = (struct GNUNET_PeerIdentity *) cb_cls;
190
191   if (pinfo->pit == GNUNET_TESTBED_PIT_IDENTITY)
192   {
193     *p = *pinfo->result.id;
194     num_retrieved_peer_ids++;
195     if (num_retrieved_peer_ids == num_peers)
196       for (i = 0; i < num_peers; i++)
197         testbed_operations[i] =
198             GNUNET_TESTBED_service_connect (NULL, peers[i], "secretsharing", connect_complete, NULL,
199                                             connect_adapter, disconnect_adapter, &session_handles[i]);
200   }
201   else
202   {
203     GNUNET_assert (0);
204   }
205
206   GNUNET_TESTBED_operation_done (op);
207 }
208
209
210 /**
211  * Signature of a main function for a testcase.
212  *
213  * @param cls closure
214  * @param h the run handle
215  * @param num_peers number of peers in 'peers'
216  * @param started_peers handle to peers run in the testbed.  NULL upon timeout (see
217  *          GNUNET_TESTBED_test_run()).
218  * @param links_succeeded the number of overlay link connection attempts that
219  *          succeeded
220  * @param links_failed the number of overlay link connection attempts that
221  *          failed
222  */
223 static void
224 test_master (void *cls,
225              struct GNUNET_TESTBED_RunHandle *h,
226              unsigned int num_peers,
227              struct GNUNET_TESTBED_Peer **started_peers,
228              unsigned int links_succeeded,
229              unsigned int links_failed)
230 {
231   int i;
232
233   GNUNET_log_setup ("gnunet-secretsharing-profiler", "INFO", NULL);
234
235   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "test master\n");
236
237   peers = started_peers;
238
239   peer_ids = GNUNET_malloc (num_peers * sizeof (struct GNUNET_PeerIdentity));
240
241   session_handles = GNUNET_malloc (num_peers * sizeof (struct GNUNET_SECRETSHARING_Session *));
242   testbed_operations = GNUNET_malloc (num_peers * sizeof (struct GNUNET_TESTBED_Operation *));
243
244   for (i = 0; i < num_peers; i++)
245     GNUNET_TESTBED_peer_get_information (peers[i],
246                                          GNUNET_TESTBED_PIT_IDENTITY,
247                                          peer_info_cb,
248                                          &peer_ids[i]);
249 }
250
251
252 static void
253 run (void *cls, char *const *args, const char *cfgfile,
254      const struct GNUNET_CONFIGURATION_Handle *cfg)
255 {
256   static char *session_str = "gnunet-secretsharing/test";
257   char *topology;
258   int topology_cmp_result;
259
260   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "testbed", "OVERLAY_TOPOLOGY", &topology))
261   {
262     fprintf (stderr,
263              "'OVERLAY_TOPOLOGY' not found in 'testbed' config section, "
264              "seems like you passed the wrong configuration file\n");
265     return;
266   }
267
268   topology_cmp_result = strcasecmp (topology, "NONE");
269   GNUNET_free (topology);
270
271   if (0 == topology_cmp_result)
272   {
273     fprintf (stderr,
274              "'OVERLAY_TOPOLOGY' set to 'NONE', "
275              "seems like you passed the wrong configuration file\n");
276     return;
277   }
278
279   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
280               "running gnunet-secretsharing-profiler\n");
281
282   GNUNET_CRYPTO_hash (session_str, strlen (session_str), &session_id);
283
284   (void) GNUNET_TESTBED_test_run ("gnunet-secretsharing-profiler",
285                                   cfgfile,
286                                   num_peers,
287                                   0,
288                                   controller_cb,
289                                   NULL,
290                                   test_master,
291                                   NULL);
292 }
293
294
295 int
296 main (int argc, char **argv)
297 {
298    static const struct GNUNET_GETOPT_CommandLineOption options[] = {
299       { 'n', "num-peers", NULL,
300         gettext_noop ("number of peers in consensus"),
301         GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_peers },
302       { 't', "timeout", NULL,
303         gettext_noop ("dkg timeout"),
304         GNUNET_YES, &GNUNET_GETOPT_set_relative_time, &timeout },
305       { 'k', "threshold", NULL,
306         gettext_noop ("threshold"),
307         GNUNET_YES, &GNUNET_GETOPT_set_uint, &threshold },
308       { 'V', "verbose", NULL,
309         gettext_noop ("be more verbose (print received values)"),
310         GNUNET_NO, &GNUNET_GETOPT_set_one, &verbose },
311       GNUNET_GETOPT_OPTION_END
312   };
313   timeout = GNUNET_TIME_UNIT_SECONDS;
314   GNUNET_PROGRAM_run2 (argc, argv, "gnunet-secretsharing-profiler",
315                       "help",
316                       options, &run, NULL, GNUNET_YES);
317   return 0;
318 }
319