2 This file is part of GNUnet.
3 (C) 2012 Christian Grothoff (and other contributing authors)
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.
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.
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.
22 * @file mesh/gnunet-mesh.c
23 * @brief Print information about mesh tunnels and peers.
24 * @author Bartlomiej Polot
27 #include "gnunet_util_lib.h"
28 #include "gnunet_mesh_service.h"
34 static int monitor_connections;
44 static char *tunnel_id;
54 static char *channel_id;
57 * Port to listen on (-p).
59 static uint32_t listen_port;
64 static char *target_id;
69 static uint32_t target_port;
76 static struct GNUNET_MESH_Handle *mh;
78 static struct GNUNET_MESH_Channel *ch;
81 * Shutdown task handle.
83 GNUNET_SCHEDULER_TaskIdentifier sd;
86 * Task run in monitor mode when the user presses CTRL-C to abort.
87 * Stops monitoring activity.
89 * @param cls Closure (unused).
90 * @param tc scheduler context
93 shutdown_task (void *cls,
94 const struct GNUNET_SCHEDULER_TaskContext *tc)
98 GNUNET_MESH_channel_destroy (ch);
103 GNUNET_MESH_disconnect (mh);
110 * Function called whenever a channel is destroyed. Should clean up
111 * any associated state.
113 * It must NOT call #GNUNET_MESH_channel_destroy on the channel.
115 * @param cls closure (set from #GNUNET_MESH_connect)
116 * @param channel connection to the other end (henceforth invalid)
117 * @param channel_ctx place where local state associated
118 * with the channel is stored
121 channel_ended (void *cls,
122 const struct GNUNET_MESH_Channel *channel,
125 FPRINTF (stdout, "Channel ended!\n");
126 GNUNET_break (channel == ch);
127 GNUNET_SCHEDULER_shutdown ();
132 * Method called whenever another peer has added us to a channel
133 * the other peer initiated.
134 * Only called (once) upon reception of data with a message type which was
135 * subscribed to in #GNUNET_MESH_connect.
137 * A call to #GNUNET_MESH_channel_destroy causes te channel to be ignored. In
138 * this case the handler MUST return NULL.
141 * @param channel new handle to the channel
142 * @param initiator peer that started the channel
143 * @param port Port this channel is for.
144 * @param options MeshOption flag field, with all active option bits set to 1.
146 * @return initial channel context for the channel
147 * (can be NULL -- that's not an error)
150 channel_incoming (void *cls,
151 struct GNUNET_MESH_Channel * channel,
152 const struct GNUNET_PeerIdentity * initiator,
153 uint32_t port, enum MeshOption options)
155 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Incoming channel on port %u\n", port);
158 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "A channel already exists\n");
161 if (0 == listen_port)
163 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not listening to channels\n");
173 * Call MESH's monitor API, get info of one connection.
175 * @param cls Closure (unused).
176 * @param tc TaskContext
179 create_channel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
181 struct GNUNET_PeerIdentity pid;
184 GNUNET_CRYPTO_eddsa_public_key_from_string (target_id,
189 _("Invalid target `%s'\n"),
191 GNUNET_SCHEDULER_shutdown ();
194 // GNUNET_MESH_channel_create ()
199 * Function called whenever a message is received.
201 * Each time the function must call #GNUNET_MESH_receive_done on the channel
202 * in order to receive the next message. This doesn't need to be immediate:
203 * can be delayed if some processing is done on the message.
205 * @param cls Closure (set from #GNUNET_MESH_connect).
206 * @param channel Connection to the other end.
207 * @param channel_ctx Place to store local state associated with the channel.
208 * @param message The actual message.
209 * @return #GNUNET_OK to keep the channel open,
210 * #GNUNET_SYSERR to close it (signal serious error).
213 data_callback (void *cls,
214 struct GNUNET_MESH_Channel *channel,
216 const struct GNUNET_MessageHeader *message)
219 GNUNET_break (ch == channel);
221 len = ntohs (message->size) - sizeof (*message);
222 FPRINTF (stdout, "%.*s", len, (char *) &message[1]);
228 * Method called to retrieve information about each tunnel the mesh peer
231 * @param cls Closure.
232 * @param tunnel_number Tunnel number.
233 * @param origin that started the tunnel (owner).
234 * @param target other endpoint of the tunnel
236 void /* FIXME static */
237 tunnels_callback (void *cls,
238 uint32_t tunnel_number,
239 const struct GNUNET_PeerIdentity *origin,
240 const struct GNUNET_PeerIdentity *target)
242 FPRINTF (stdout, "Tunnel %s [%u]\n",
243 GNUNET_i2s_full (origin), tunnel_number);
244 FPRINTF (stdout, "\n");
249 * Method called to retrieve information about each tunnel the mesh peer
252 * @param cls Closure.
253 * @param peer Peer in the tunnel's tree.
254 * @param parent Parent of the current peer. All 0 when peer is root.
257 void /* FIXME static */
258 tunnel_callback (void *cls,
259 const struct GNUNET_PeerIdentity *peer,
260 const struct GNUNET_PeerIdentity *parent)
266 * Call MESH's monitor API, get all tunnels known to peer.
268 * @param cls Closure (unused).
269 * @param tc TaskContext
272 get_tunnels (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
274 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
278 // GNUNET_MESH_get_tunnels (mh, &tunnels_callback, NULL);
279 if (GNUNET_YES != monitor_connections)
281 GNUNET_SCHEDULER_shutdown();
287 * Call MESH's monitor API, get info of one tunnel.
289 * @param cls Closure (unused).
290 * @param tc TaskContext
293 show_tunnel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
295 struct GNUNET_PeerIdentity pid;
298 GNUNET_CRYPTO_eddsa_public_key_from_string (tunnel_id,
303 _("Invalid tunnel owner `%s'\n"),
305 GNUNET_SCHEDULER_shutdown();
308 // GNUNET_MESH_show_tunnel (mh, &pid, 0, tunnel_callback, NULL);
313 * Call MESH's monitor API, get info of one channel.
315 * @param cls Closure (unused).
316 * @param tc TaskContext
319 show_channel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
326 * Call MESH's monitor API, get info of one connection.
328 * @param cls Closure (unused).
329 * @param tc TaskContext
332 show_connection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
339 * Main function that will be run by the scheduler.
342 * @param args remaining command-line arguments
343 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
344 * @param cfg configuration
347 run (void *cls, char *const *args, const char *cfgfile,
348 const struct GNUNET_CONFIGURATION_Handle *cfg)
350 GNUNET_MESH_InboundChannelNotificationHandler *newch = NULL;
351 GNUNET_MESH_ChannelEndHandler *endch = NULL;
352 static const struct GNUNET_MESH_MessageHandler handlers[] = {
353 {&data_callback, GNUNET_MESSAGE_TYPE_MESH_CLI, 0},
354 {NULL, 0, 0} /* FIXME add option to monitor msg types */
356 /* FIXME add option to monitor apps */
359 target_port = args[0] && args[1] ? atoi(args[1]) : 0;
361 || 0 != monitor_connections
364 || NULL != channel_id)
365 && target_id != NULL)
367 FPRINTF (stderr, _("You must NOT give a TARGET when using options\n"));
371 if (NULL != target_id)
373 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
374 "Creating channel to %s\n",
376 GNUNET_SCHEDULER_add_now (&create_channel, NULL);
377 endch = &channel_ended;
379 else if (0 != listen_port)
381 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Listen\n");
382 newch = &channel_incoming;
384 else if (NULL != tunnel_id)
386 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show tunnel\n");
387 GNUNET_SCHEDULER_add_now (&show_tunnel, NULL);
389 else if (NULL != channel_id)
391 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show channel\n");
392 GNUNET_SCHEDULER_add_now (&show_channel, NULL);
394 else if (NULL != conn_id)
396 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show connection\n");
397 GNUNET_SCHEDULER_add_now (&show_connection, NULL);
399 else if (GNUNET_YES == get_info)
401 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show all tunnels\n");
402 GNUNET_SCHEDULER_add_now (&get_tunnels, NULL);
406 FPRINTF (stderr, "No action requested\n");
410 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to mesh\n");
411 mh = GNUNET_MESH_connect (cfg,
413 newch, /* new channel */
417 FPRINTF (stdout, "Done\n");
419 GNUNET_SCHEDULER_add_now (shutdown_task, NULL);
421 sd = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
422 shutdown_task, NULL);
428 * The main function to obtain peer information.
430 * @param argc number of arguments from the command line
431 * @param argv command line arguments
432 * @return 0 ok, 1 on error
435 main (int argc, char *const *argv)
438 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
439 {'a', "channel", "TUNNEL_ID:CHANNEL_ID",
440 gettext_noop ("provide information about a particular channel"),
441 GNUNET_YES, &GNUNET_GETOPT_set_string, &channel_id},
442 {'b', "connection", "TUNNEL_ID:CONNECTION_ID",
443 gettext_noop ("provide information about a particular connection"),
444 GNUNET_YES, &GNUNET_GETOPT_set_string, &conn_id},
446 gettext_noop ("provide information about all tunnels"),
447 GNUNET_NO, &GNUNET_GETOPT_set_one, &get_info},
448 {'m', "monitor", NULL,
449 gettext_noop ("provide information about all tunnels (continuously) NOT IMPLEMENTED"), /* FIXME */
450 GNUNET_NO, &GNUNET_GETOPT_set_one, &monitor_connections},
452 gettext_noop ("port to listen to (default; 0)"),
453 GNUNET_YES, &GNUNET_GETOPT_set_uint, &listen_port},
454 {'t', "tunnel", "TUNNEL_ID",
455 gettext_noop ("provide information about a particular tunnel"),
456 GNUNET_YES, &GNUNET_GETOPT_set_string, &tunnel_id},
457 GNUNET_GETOPT_OPTION_END
460 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
463 res = GNUNET_PROGRAM_run (argc, argv, "gnunet-mesh (OPTIONS | TARGET PORT)",
465 ("Create channels and retreive info about meshs status."),
466 options, &run, NULL);
468 GNUNET_free ((void *) argv);
470 if (GNUNET_OK == res)
476 /* end of gnunet-mesh.c */