2 This file is part of GNUnet.
3 Copyright (C) 2015, 2016, 2017 GNUnet e.V.
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., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
22 * @file src/nat/gnunet-nat-auto.c
23 * @brief Command-line tool for testing and autoconfiguration of NAT traversal
24 * @author Christian Grothoff
25 * @author Bruno Cabral
28 #include "gnunet_util_lib.h"
29 #include "gnunet_nat_service.h"
30 #include "gnunet_nat_auto_service.h"
33 * Value to return from #main().
35 static int global_ret;
38 * Handle to ongoing autoconfiguration.
40 static struct GNUNET_NAT_AUTO_AutoHandle *ah;
43 * If we do auto-configuration, should we write the result
49 * Configuration filename.
51 static const char *cfg_file;
54 * Original configuration.
56 static const struct GNUNET_CONFIGURATION_Handle *cfg;
59 * Adapter we are supposed to test.
61 static char *section_name;
64 * Should we run autoconfiguration?
69 * Handle to a NAT test operation.
71 static struct GNUNET_NAT_AUTO_Test *nt;
74 * Flag set to 1 if we use IPPROTO_UDP.
79 * Flag set to 1 if we use IPPROTO_TCP.
89 * Test if all activities have finished, and if so,
99 GNUNET_SCHEDULER_shutdown ();
104 * Function to iterate over sugested changes options
107 * @param section name of the section
108 * @param option name of the option
109 * @param value value of the option
112 auto_conf_iter (void *cls,
117 struct GNUNET_CONFIGURATION_Handle *new_cfg = cls;
123 GNUNET_CONFIGURATION_set_value_string (new_cfg,
131 * Function called with the result from the autoconfiguration.
134 * @param diff minimal suggested changes to the original configuration
135 * to make it work (as best as we can)
136 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
137 * @param type what the situation of the NAT
140 auto_config_cb (void *cls,
141 const struct GNUNET_CONFIGURATION_Handle *diff,
142 enum GNUNET_NAT_StatusCode result,
143 enum GNUNET_NAT_Type type)
145 const char *nat_type;
146 char unknown_type[64];
147 struct GNUNET_CONFIGURATION_Handle *new_cfg;
152 case GNUNET_NAT_TYPE_NO_NAT:
155 case GNUNET_NAT_TYPE_UNREACHABLE_NAT:
156 nat_type = "NAT but we can traverse";
158 case GNUNET_NAT_TYPE_STUN_PUNCHED_NAT:
159 nat_type = "NAT but STUN is able to identify the correct information";
161 case GNUNET_NAT_TYPE_UPNP_NAT:
162 nat_type = "NAT but UPNP opened the ports";
165 SPRINTF (unknown_type,
166 "NAT unknown, type %u",
168 nat_type = unknown_type;
172 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
173 "NAT status: %s/%s\n",
174 GNUNET_NAT_AUTO_status2string (result),
180 /* Shortcut: if there are no changes suggested, bail out early. */
182 GNUNET_CONFIGURATION_is_dirty (diff))
188 /* Apply diff to original configuration and show changes
190 new_cfg = write_cfg ? GNUNET_CONFIGURATION_dup (cfg) : NULL;
192 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
193 _("Suggested configuration changes:\n"));
194 GNUNET_CONFIGURATION_iterate_section_values (diff,
199 /* If desired, write configuration to file; we write only the
200 changes to the defaults to keep things compact. */
203 struct GNUNET_CONFIGURATION_Handle *def_cfg;
205 GNUNET_CONFIGURATION_set_value_string (new_cfg,
209 def_cfg = GNUNET_CONFIGURATION_create ();
210 GNUNET_break (GNUNET_OK ==
211 GNUNET_CONFIGURATION_load (def_cfg,
214 GNUNET_CONFIGURATION_write_diffs (def_cfg,
218 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
219 _("Failed to write configuration to `%s'\n"),
225 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
226 _("Wrote updated configuration to `%s'\n"),
229 GNUNET_CONFIGURATION_destroy (def_cfg);
233 GNUNET_CONFIGURATION_destroy (new_cfg);
239 * Function called to report success or failure for
240 * NAT configuration test.
243 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
246 test_report_cb (void *cls,
247 enum GNUNET_NAT_StatusCode result)
250 PRINTF ("NAT test result: %s\n",
251 GNUNET_NAT_AUTO_status2string (result));
257 * Task run on shutdown.
262 do_shutdown (void *cls)
266 GNUNET_NAT_AUTO_autoconfig_cancel (ah);
271 GNUNET_NAT_AUTO_test_stop (nt);
278 * Main function that will be run.
281 * @param args remaining command-line arguments
282 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
283 * @param c configuration
289 const struct GNUNET_CONFIGURATION_Handle *c)
294 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
299 ah = GNUNET_NAT_AUTO_autoconfig_start (c,
304 if (use_tcp && use_udp)
308 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
309 "Cannot use TCP and UDP\n");
319 if (NULL != section_name)
321 nt = GNUNET_NAT_AUTO_test_start (c,
332 * Main function of gnunet-nat-auto
334 * @param argc number of command-line arguments
335 * @param argv command line
336 * @return 0 on success, -1 on error
342 struct GNUNET_GETOPT_CommandLineOption options[] = {
343 GNUNET_GETOPT_OPTION_SET_ONE ('a',
345 gettext_noop ("run autoconfiguration"),
348 GNUNET_GETOPT_OPTION_STRING ('S',
351 gettext_noop ("section name providing the configuration for the adapter"),
354 GNUNET_GETOPT_OPTION_SET_ONE ('t',
356 gettext_noop ("use TCP"),
359 GNUNET_GETOPT_OPTION_SET_ONE ('u',
361 gettext_noop ("use UDP"),
364 GNUNET_GETOPT_OPTION_SET_ONE ('w',
366 gettext_noop ("write configuration file (for autoconfiguration)"),
368 GNUNET_GETOPT_OPTION_END
372 GNUNET_STRINGS_get_utf8_args (argc, argv,
376 GNUNET_PROGRAM_run (argc, argv,
377 "gnunet-nat-auto [options]",
378 _("GNUnet NAT traversal autoconfiguration"),
385 GNUNET_free ((void*) argv);
390 /* end of gnunet-nat-auto.c */