7450d8dc3e66bd367dc611782aebb0521cfc9f0b
[oweals/gnunet.git] / src / mesh / gnunet-mesh.c
1 /*
2      This file is part of GNUnet.
3      (C) 2012 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 mesh/gnunet-mesh.c
23  * @brief Print information about mesh tunnels and peers.
24  * @author Bartlomiej Polot
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_mesh_service.h"
29
30
31 /**
32  * Option -m.
33  */
34 static int monitor_connections;
35
36 /**
37  * Option -i.
38  */
39 static int get_info;
40
41 /**
42  * Option --tunnel
43  */
44 static char *tunnel_id;
45
46 /**
47  * Option --connection
48  */
49 static char *conn_id;
50
51 /**
52  * Option --channel
53  */
54 static char *channel_id;
55
56 /**
57  * Port to listen on (-p).
58  */
59 static uint32_t listen_port;
60
61 /**
62  * Peer to connect to.
63  */
64 static char *target_id;
65
66 /**
67  * Port to connect to
68  */
69 static uint32_t target_port;
70
71 /**
72  * Mesh handle.
73  */
74 static struct GNUNET_MESH_Handle *mh;
75
76 /**
77  * Shutdown task handle.
78  */
79 GNUNET_SCHEDULER_TaskIdentifier sd;
80
81 /**
82  * Task run in monitor mode when the user presses CTRL-C to abort.
83  * Stops monitoring activity.
84  *
85  * @param cls Closure (unused).
86  * @param tc scheduler context
87  */
88 static void
89 shutdown_task (void *cls,
90                const struct GNUNET_SCHEDULER_TaskContext *tc)
91 {
92   if (NULL != mh)
93   {
94     GNUNET_MESH_disconnect (mh);
95         mh = NULL;
96   }
97 }
98
99
100 /**
101  * Function called whenever a channel is destroyed.  Should clean up
102  * any associated state.
103  *
104  * It must NOT call #GNUNET_MESH_channel_destroy on the channel.
105  *
106  * @param cls closure (set from #GNUNET_MESH_connect)
107  * @param channel connection to the other end (henceforth invalid)
108  * @param channel_ctx place where local state associated
109  *                   with the channel is stored
110  */
111 static void
112 channel_ended (void *cls,
113                const struct GNUNET_MESH_Channel *channel,
114                void *channel_ctx)
115 {
116   FPRINTF (stdout, "Channel ended!\n");
117 }
118
119
120 /**
121  * Method called whenever another peer has added us to a channel
122  * the other peer initiated.
123  * Only called (once) upon reception of data with a message type which was
124  * subscribed to in #GNUNET_MESH_connect.
125  *
126  * A call to #GNUNET_MESH_channel_destroy causes te channel to be ignored. In
127  * this case the handler MUST return NULL.
128  *
129  * @param cls closure
130  * @param channel new handle to the channel
131  * @param initiator peer that started the channel
132  * @param port Port this channel is for.
133  * @param options MeshOption flag field, with all active option bits set to 1.
134  *
135  * @return initial channel context for the channel
136  *         (can be NULL -- that's not an error)
137  */
138 void *
139 channel_incoming (void *cls,
140                   struct GNUNET_MESH_Channel * channel,
141                   const struct GNUNET_PeerIdentity * initiator,
142                   uint32_t port, enum MeshOption options)
143 {
144   FPRINTF (stdout, "Incoming channel!\n");
145   return NULL;
146 }
147
148
149
150 /**
151  * Call MESH's monitor API, get info of one connection.
152  *
153  * @param cls Closure (unused).
154  * @param tc TaskContext
155  */
156 static void
157 create_channel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
158 {
159   struct GNUNET_PeerIdentity pid;
160
161   if (GNUNET_OK !=
162       GNUNET_CRYPTO_eddsa_public_key_from_string (target_id,
163                                                   strlen (target_id),
164                                                   &pid.public_key))
165   {
166     FPRINTF (stderr,
167              _("Invalid target `%s'\n"),
168              target_id);
169     GNUNET_SCHEDULER_shutdown();
170     return;
171   }
172 //   GNUNET_MESH_channel_create ()
173 }
174
175
176 /**
177  * Method called to retrieve information about each tunnel the mesh peer
178  * is aware of.
179  *
180  * @param cls Closure.
181  * @param tunnel_number Tunnel number.
182  * @param origin that started the tunnel (owner).
183  * @param target other endpoint of the tunnel
184  */
185 void /* FIXME static */
186 tunnels_callback (void *cls,
187                   uint32_t tunnel_number,
188                   const struct GNUNET_PeerIdentity *origin,
189                   const struct GNUNET_PeerIdentity *target)
190 {
191   fprintf (stdout, "Tunnel %s [%u]\n",
192            GNUNET_i2s_full (origin), tunnel_number);
193   fprintf (stdout, "\n");
194 }
195
196
197 /**
198  * Method called to retrieve information about each tunnel the mesh peer
199  * is aware of.
200  *
201  * @param cls Closure.
202  * @param peer Peer in the tunnel's tree.
203  * @param parent Parent of the current peer. All 0 when peer is root.
204  *
205  */
206 void /* FIXME static */
207 tunnel_callback (void *cls,
208                  const struct GNUNET_PeerIdentity *peer,
209                  const struct GNUNET_PeerIdentity *parent)
210 {
211 }
212
213
214 /**
215  * Call MESH's monitor API, get all tunnels known to peer.
216  *
217  * @param cls Closure (unused).
218  * @param tc TaskContext
219  */
220 static void
221 get_tunnels (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
222 {
223   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
224   {
225     return;
226   }
227 //   GNUNET_MESH_get_tunnels (mh, &tunnels_callback, NULL);
228   if (GNUNET_YES != monitor_connections)
229   {
230     GNUNET_SCHEDULER_shutdown();
231   }
232 }
233
234
235 /**
236  * Call MESH's monitor API, get info of one tunnel.
237  *
238  * @param cls Closure (unused).
239  * @param tc TaskContext
240  */
241 static void
242 show_tunnel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
243 {
244   struct GNUNET_PeerIdentity pid;
245
246   if (GNUNET_OK !=
247       GNUNET_CRYPTO_eddsa_public_key_from_string (tunnel_id,
248                                                   strlen (tunnel_id),
249                                                   &pid.public_key))
250   {
251     fprintf (stderr,
252              _("Invalid tunnel owner `%s'\n"),
253              tunnel_id);
254     GNUNET_SCHEDULER_shutdown();
255     return;
256   }
257 //   GNUNET_MESH_show_tunnel (mh, &pid, 0, tunnel_callback, NULL);
258 }
259
260
261 /**
262  * Call MESH's monitor API, get info of one channel.
263  *
264  * @param cls Closure (unused).
265  * @param tc TaskContext
266  */
267 static void
268 show_channel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
269 {
270
271 }
272
273
274 /**
275  * Call MESH's monitor API, get info of one connection.
276  *
277  * @param cls Closure (unused).
278  * @param tc TaskContext
279  */
280 static void
281 show_connection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
282 {
283
284 }
285
286
287 /**
288  * Main function that will be run by the scheduler.
289  *
290  * @param cls closure
291  * @param args remaining command-line arguments
292  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
293  * @param cfg configuration
294  */
295 static void
296 run (void *cls, char *const *args, const char *cfgfile,
297      const struct GNUNET_CONFIGURATION_Handle *cfg)
298 {
299   static const struct GNUNET_MESH_MessageHandler handlers[] = {
300     {NULL, 0, 0} /* FIXME add option to monitor msg types */
301   };
302   /* FIXME add option to monitor apps */
303
304   target_id = args[0];
305   target_port = args[0] && args[1] ? atoi(args[1]) : 0;
306   if ( (0 != get_info
307         || 0 != monitor_connections
308         || NULL != tunnel_id
309         || NULL != conn_id
310         || NULL != channel_id)
311        && target_id != NULL)
312   {
313     FPRINTF (stderr, _("You must NOT give a TARGET when using options\n"));
314     return;
315   }
316
317   if (NULL != target_id)
318   {
319     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
320                 "Creating channel to %s\n",
321                 target_id);
322     GNUNET_SCHEDULER_add_now (&create_channel, NULL);
323   }
324   else if (NULL != tunnel_id)
325   {
326     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show tunnel\n");
327     GNUNET_SCHEDULER_add_now (&show_tunnel, NULL);
328   }
329   else if (NULL != channel_id)
330   {
331     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show channel\n");
332     GNUNET_SCHEDULER_add_now (&show_channel, NULL);
333   }
334   else if (NULL != conn_id)
335   {
336     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show connection\n");
337     GNUNET_SCHEDULER_add_now (&show_connection, NULL);
338   }
339   else if (GNUNET_YES == get_info)
340   {
341     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show all tunnels\n");
342     GNUNET_SCHEDULER_add_now (&get_tunnels, NULL);
343   }
344   else
345   {
346     FPRINTF (stderr, "No action requested\n");
347     return;
348   }
349
350   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to mesh\n");
351   mh = GNUNET_MESH_connect (cfg,
352                             NULL, /* cls */
353                             NULL, /* new tunnel */
354                             NULL, /* cleaner */
355                             handlers,
356                             NULL);
357   FPRINTF (stdout, "Done\n");
358   if (NULL == mh)
359     GNUNET_SCHEDULER_add_now (shutdown_task, NULL);
360   else
361     sd = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
362                                        shutdown_task, NULL);
363
364 }
365
366
367 /**
368  * The main function to obtain peer information.
369  *
370  * @param argc number of arguments from the command line
371  * @param argv command line arguments
372  * @return 0 ok, 1 on error
373  */
374 int
375 main (int argc, char *const *argv)
376 {
377   int res;
378   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
379     {'a', "channel", "TUNNEL_ID:CHANNEL_ID",
380      gettext_noop ("provide information about a particular channel"),
381      GNUNET_YES, &GNUNET_GETOPT_set_string, &channel_id},
382     {'b', "connection", "TUNNEL_ID:CONNECTION_ID",
383      gettext_noop ("provide information about a particular connection"),
384      GNUNET_YES, &GNUNET_GETOPT_set_string, &conn_id},
385     {'i', "info", NULL,
386      gettext_noop ("provide information about all tunnels"),
387      GNUNET_NO, &GNUNET_GETOPT_set_one, &get_info},
388     {'m', "monitor", NULL,
389      gettext_noop ("provide information about all tunnels (continuously) NOT IMPLEMENTED"), /* FIXME */
390      GNUNET_NO, &GNUNET_GETOPT_set_one, &monitor_connections},
391     {'p', "port", NULL,
392      gettext_noop ("port to listen to (default; 0)"),
393      GNUNET_YES, &GNUNET_GETOPT_set_uint, &listen_port},
394     {'t', "tunnel", "TUNNEL_ID",
395      gettext_noop ("provide information about a particular tunnel"),
396      GNUNET_YES, &GNUNET_GETOPT_set_string, &tunnel_id},
397     GNUNET_GETOPT_OPTION_END
398   };
399
400   if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
401     return 2;
402
403   res = GNUNET_PROGRAM_run (argc, argv, "gnunet-mesh (OPTIONS | TARGET PORT)",
404                       gettext_noop
405                       ("Create channels and retreive info about meshs status."),
406                       options, &run, NULL);
407
408   GNUNET_free ((void *) argv);
409
410   if (GNUNET_OK == res)
411     return 0;
412   else
413     return 1;
414 }
415
416 /* end of gnunet-mesh.c */