-wip
[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  * Call MESH's monitor API, get info of one connection.
102  *
103  * @param cls Closure (unused).
104  * @param tc TaskContext
105  */
106 static void
107 create_channel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
108 {
109   struct GNUNET_PeerIdentity pid;
110
111   if (GNUNET_OK !=
112       GNUNET_CRYPTO_eddsa_public_key_from_string (target_id,
113                                                   strlen (target_id),
114                                                   &pid.public_key))
115   {
116     FPRINTF (stderr,
117              _("Invalid target `%s'\n"),
118              target_id);
119     GNUNET_SCHEDULER_shutdown();
120     return;
121   }
122 //   GNUNET_MESH_channel_create ()
123 }
124
125
126 /**
127  * Method called to retrieve information about each tunnel the mesh peer
128  * is aware of.
129  *
130  * @param cls Closure.
131  * @param tunnel_number Tunnel number.
132  * @param origin that started the tunnel (owner).
133  * @param target other endpoint of the tunnel
134  */
135 void /* FIXME static */
136 tunnels_callback (void *cls,
137                   uint32_t tunnel_number,
138                   const struct GNUNET_PeerIdentity *origin,
139                   const struct GNUNET_PeerIdentity *target)
140 {
141   fprintf (stdout, "Tunnel %s [%u]\n",
142            GNUNET_i2s_full (origin), tunnel_number);
143   fprintf (stdout, "\n");
144 }
145
146
147 /**
148  * Method called to retrieve information about each tunnel the mesh peer
149  * is aware of.
150  *
151  * @param cls Closure.
152  * @param peer Peer in the tunnel's tree.
153  * @param parent Parent of the current peer. All 0 when peer is root.
154  *
155  */
156 void /* FIXME static */
157 tunnel_callback (void *cls,
158                  const struct GNUNET_PeerIdentity *peer,
159                  const struct GNUNET_PeerIdentity *parent)
160 {
161 }
162
163
164 /**
165  * Call MESH's monitor API, get all tunnels known to peer.
166  *
167  * @param cls Closure (unused).
168  * @param tc TaskContext
169  */
170 static void
171 get_tunnels (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
172 {
173   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
174   {
175     return;
176   }
177 //   GNUNET_MESH_get_tunnels (mh, &tunnels_callback, NULL);
178   if (GNUNET_YES != monitor_connections)
179   {
180     GNUNET_SCHEDULER_shutdown();
181   }
182 }
183
184
185 /**
186  * Call MESH's monitor API, get info of one tunnel.
187  *
188  * @param cls Closure (unused).
189  * @param tc TaskContext
190  */
191 static void
192 show_tunnel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
193 {
194   struct GNUNET_PeerIdentity pid;
195
196   if (GNUNET_OK !=
197       GNUNET_CRYPTO_eddsa_public_key_from_string (tunnel_id,
198                                                   strlen (tunnel_id),
199                                                   &pid.public_key))
200   {
201     fprintf (stderr,
202              _("Invalid tunnel owner `%s'\n"),
203              tunnel_id);
204     GNUNET_SCHEDULER_shutdown();
205     return;
206   }
207 //   GNUNET_MESH_show_tunnel (mh, &pid, 0, tunnel_callback, NULL);
208 }
209
210
211 /**
212  * Call MESH's monitor API, get info of one channel.
213  *
214  * @param cls Closure (unused).
215  * @param tc TaskContext
216  */
217 static void
218 show_channel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
219 {
220
221 }
222
223
224 /**
225  * Call MESH's monitor API, get info of one connection.
226  *
227  * @param cls Closure (unused).
228  * @param tc TaskContext
229  */
230 static void
231 show_connection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
232 {
233
234 }
235
236
237
238 /**
239  * Method called whenever another peer has added us to a channel
240  * the other peer initiated.
241  * Only called (once) upon reception of data with a message type which was
242  * subscribed to in #GNUNET_MESH_connect.
243  *
244  * A call to #GNUNET_MESH_channel_destroy causes te channel to be ignored. In
245  * this case the handler MUST return NULL.
246  *
247  * @param cls closure
248  * @param channel new handle to the channel
249  * @param initiator peer that started the channel
250  * @param port Port this channel is for.
251  * @param options MeshOption flag field, with all active option bits set to 1.
252  *
253  * @return initial channel context for the channel
254  *         (can be NULL -- that's not an error)
255  */
256 void *
257 incoming_channel (void *cls,
258                   struct GNUNET_MESH_Channel * channel,
259                   const struct GNUNET_PeerIdentity * initiator,
260                   uint32_t port, enum MeshOption options)
261 {
262   FPRINTF (stdout, "Incoming channel!\n");
263   return NULL;
264 }
265
266
267
268 /**
269  * Main function that will be run by the scheduler.
270  *
271  * @param cls closure
272  * @param args remaining command-line arguments
273  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
274  * @param cfg configuration
275  */
276 static void
277 run (void *cls, char *const *args, const char *cfgfile,
278      const struct GNUNET_CONFIGURATION_Handle *cfg)
279 {
280   static const struct GNUNET_MESH_MessageHandler handlers[] = {
281     {NULL, 0, 0} /* FIXME add option to monitor msg types */
282   };
283   /* FIXME add option to monitor apps */
284
285   target_id = args[0];
286   target_port = args[0] && args[1] ? atoi(args[1]) : 0;
287   if ( (0 != get_info
288         || 0 != monitor_connections
289         || NULL != tunnel_id
290         || NULL != conn_id
291         || NULL != channel_id)
292        && target_id != NULL)
293   {
294     FPRINTF (stderr, _("You must NOT give a TARGET when using options\n"));
295     return;
296   }
297
298   if (NULL != target_id)
299   {
300     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
301                 "Creating channel to %s\n",
302                 target_id);
303     GNUNET_SCHEDULER_add_now (&create_channel, NULL);
304   }
305   else if (NULL != tunnel_id)
306   {
307     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show tunnel\n");
308     GNUNET_SCHEDULER_add_now (&show_tunnel, NULL);
309   }
310   else if (NULL != channel_id)
311   {
312     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show channel\n");
313     GNUNET_SCHEDULER_add_now (&show_channel, NULL);
314   }
315   else if (NULL != conn_id)
316   {
317     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show connection\n");
318     GNUNET_SCHEDULER_add_now (&show_connection, NULL);
319   }
320   else if (GNUNET_YES == get_info)
321   {
322     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show all tunnels\n");
323     GNUNET_SCHEDULER_add_now (&get_tunnels, NULL);
324   }
325   else
326   {
327     FPRINTF (stderr, "No action requested\n");
328     return;
329   }
330
331   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to mesh\n");
332   mh = GNUNET_MESH_connect (cfg,
333                             NULL, /* cls */
334                             NULL, /* new tunnel */
335                             NULL, /* cleaner */
336                             handlers,
337                             NULL);
338   FPRINTF (stdout, "Done\n");
339   if (NULL == mh)
340     GNUNET_SCHEDULER_add_now (shutdown_task, NULL);
341   else
342     sd = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
343                                        shutdown_task, NULL);
344
345 }
346
347
348 /**
349  * The main function to obtain peer information.
350  *
351  * @param argc number of arguments from the command line
352  * @param argv command line arguments
353  * @return 0 ok, 1 on error
354  */
355 int
356 main (int argc, char *const *argv)
357 {
358   int res;
359   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
360     {'a', "channel", "TUNNEL_ID:CHANNEL_ID",
361      gettext_noop ("provide information about a particular channel"),
362      GNUNET_YES, &GNUNET_GETOPT_set_string, &channel_id},
363     {'b', "connection", "TUNNEL_ID:CONNECTION_ID",
364      gettext_noop ("provide information about a particular connection"),
365      GNUNET_YES, &GNUNET_GETOPT_set_string, &conn_id},
366     {'i', "info", NULL,
367      gettext_noop ("provide information about all tunnels"),
368      GNUNET_NO, &GNUNET_GETOPT_set_one, &get_info},
369     {'m', "monitor", NULL,
370      gettext_noop ("provide information about all tunnels (continuously) NOT IMPLEMENTED"), /* FIXME */
371      GNUNET_NO, &GNUNET_GETOPT_set_one, &monitor_connections},
372     {'p', "port", NULL,
373      gettext_noop ("port to listen to (default; 0)"),
374      GNUNET_YES, &GNUNET_GETOPT_set_uint, &listen_port},
375     {'t', "tunnel", "TUNNEL_ID",
376      gettext_noop ("provide information about a particular tunnel"),
377      GNUNET_YES, &GNUNET_GETOPT_set_string, &tunnel_id},
378     GNUNET_GETOPT_OPTION_END
379   };
380
381   if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
382     return 2;
383
384   res = GNUNET_PROGRAM_run (argc, argv, "gnunet-mesh (OPTIONS | TARGET PORT)",
385                       gettext_noop
386                       ("Create channels and retreive info about meshs status."),
387                       options, &run, NULL);
388
389   GNUNET_free ((void *) argv);
390
391   if (GNUNET_OK == res)
392     return 0;
393   else
394     return 1;
395 }
396
397 /* end of gnunet-mesh.c */