- disable try_connect to force topology
[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_configuration_lib.h"
28 #include "gnunet_getopt_lib.h"
29 #include "gnunet_mesh_service.h"
30 #include "gnunet_program_lib.h"
31
32
33 /**
34  * Option -m.
35  */
36 static int monitor_connections;
37
38 /**
39  * Option -t
40  */
41 static char *tunnel_id;
42
43 /**
44  * Mesh handle.
45  */
46 static struct GNUNET_MESH_Handle *mh;
47
48 /**
49  * Shutdown task handle.
50  */
51 GNUNET_SCHEDULER_TaskIdentifier sd;
52
53 /**
54  * Task run in monitor mode when the user presses CTRL-C to abort.
55  * Stops monitoring activity.
56  *
57  * @param cls Closure (unused).
58  * @param tc scheduler context
59  */
60 static void
61 shutdown_task (void *cls,
62                const struct GNUNET_SCHEDULER_TaskContext *tc)
63 {
64   if (NULL != mh)
65   {
66     GNUNET_MESH_disconnect (mh);
67         mh = NULL;
68   }
69 }
70
71
72 /**
73  * Method called to retrieve information about each tunnel the mesh peer
74  * is aware of.
75  *
76  * @param cls Closure (unused).
77  * @param initiator Peer that started the tunnel (owner).
78  * @param tunnel_number Tunnel number.
79  * @param peers Array of peer identities that participate in the tunnel.
80  * @param npeers Number of peers in peers.
81  */
82 static void
83 tunnels_callback (void *cls,
84                  const struct GNUNET_PeerIdentity *initiator,
85                  unsigned int tunnel_number,
86                  const struct GNUNET_PeerIdentity *peers,
87                  unsigned int npeers)
88 {
89   unsigned int i;
90
91   fprintf (stdout, "Tunnel %s [%u]: %u peers\n",
92            GNUNET_i2s_full (initiator), tunnel_number, npeers);
93   for (i = 0; i < npeers; i++)
94     fprintf (stdout, " * %s\n", GNUNET_i2s_full (&peers[i]));
95   fprintf (stdout, "\n");
96 }
97
98
99 /**
100  * Method called to retrieve information about each tunnel the mesh peer
101  * is aware of.
102  *
103  * @param cls Closure.
104  * @param peer Peer in the tunnel's tree.
105  * @param parent Parent of the current peer. All 0 when peer is root.
106  * 
107  */
108 static void
109 tunnel_callback (void *cls,
110                  const struct GNUNET_PeerIdentity *peer,
111                  const struct GNUNET_PeerIdentity *parent)
112 {
113 }
114
115
116 /**
117  * Call MESH's monitor API, get all tunnels known to peer.
118  *
119  * @param cls Closure (unused).
120  * @param tc TaskContext
121  */
122 static void
123 get_tunnels (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
124 {
125   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
126   {
127     return;
128   }
129   GNUNET_MESH_get_tunnels (mh, &tunnels_callback, NULL);
130   if (GNUNET_YES != monitor_connections)
131   {
132     GNUNET_SCHEDULER_shutdown();
133   }
134 }
135
136 /**
137  * Call MESH's monitor API, get info of one tunnel.
138  *
139  * @param cls Closure (unused).
140  * @param tc TaskContext
141  */
142 static void
143 show_tunnel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
144 {
145   struct GNUNET_PeerIdentity pid;
146
147   if (GNUNET_OK !=
148       GNUNET_CRYPTO_hash_from_string (tunnel_id, &pid.hashPubKey))
149   {
150     GNUNET_SCHEDULER_shutdown();
151     return;
152   }
153   GNUNET_MESH_show_tunnel (mh, &pid, 0, tunnel_callback, NULL);
154 }
155
156
157 /**
158  * Main function that will be run by the scheduler.
159  *
160  * @param cls closure
161  * @param args remaining command-line arguments
162  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
163  * @param cfg configuration
164  */
165 static void
166 run (void *cls, char *const *args, const char *cfgfile,
167      const struct GNUNET_CONFIGURATION_Handle *cfg)
168 {
169   static const struct GNUNET_MESH_MessageHandler handlers[] = {
170     {NULL, 0, 0} /* FIXME add option to monitor msg types */
171   };
172   GNUNET_MESH_ApplicationType apps = 0; /* FIXME add option to monitor apps */
173
174   if (args[0] != NULL)
175   {
176     FPRINTF (stderr, _("Invalid command line argument `%s'\n"), args[0]);
177     return;
178   }
179   mh = GNUNET_MESH_connect (cfg,
180                             NULL, /* cls */
181                             NULL, /* nt */
182                             NULL, /* cleaner */
183                             handlers,
184                             &apps);
185   if (NULL == mh)
186     GNUNET_SCHEDULER_add_now (shutdown_task, NULL);
187   else
188     sd = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
189                                        shutdown_task, NULL);
190
191   if (NULL != tunnel_id)
192     GNUNET_SCHEDULER_add_now (&show_tunnel, NULL);
193   else
194     GNUNET_SCHEDULER_add_now (&get_tunnels, NULL);
195 }
196
197
198 /**
199  * The main function to obtain peer information.
200  *
201  * @param argc number of arguments from the command line
202  * @param argv command line arguments
203  * @return 0 ok, 1 on error
204  */
205 int
206 main (int argc, char *const *argv)
207 {
208   int res;
209   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
210     {'m', "monitor", NULL,
211      gettext_noop ("provide information about all tunnels (continuously) NOT IMPLEMENTED"), /* FIXME */
212      GNUNET_NO, &GNUNET_GETOPT_set_one, &monitor_connections},
213     {'t', "tunnel", "OWNER_ID:TUNNEL_ID",
214      gettext_noop ("provide information about a particular tunnel"),
215      GNUNET_YES, &GNUNET_GETOPT_set_string, &tunnel_id},
216     GNUNET_GETOPT_OPTION_END
217   };
218
219   if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
220     return 2;
221
222   res = GNUNET_PROGRAM_run (argc, argv, "gnunet-mesh",
223                       gettext_noop
224                       ("Print information about mesh tunnels and peers."),
225                       options, &run, NULL);
226
227   GNUNET_free ((void *) argv);
228
229   if (GNUNET_OK == res)
230     return 0;
231   else
232     return 1;
233 }
234
235 /* end of gnunet-mesh.c */