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?
66 static unsigned int do_auto;
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),
177 /* Shortcut: if there are no changes suggested, bail out early. */
179 GNUNET_CONFIGURATION_is_dirty (diff))
185 /* Apply diff to original configuration and show changes
187 new_cfg = write_cfg ? GNUNET_CONFIGURATION_dup (cfg) : NULL;
191 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
192 _("Suggested configuration changes:\n"));
193 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. */
204 struct GNUNET_CONFIGURATION_Handle *def_cfg;
206 GNUNET_CONFIGURATION_set_value_string (new_cfg,
210 def_cfg = GNUNET_CONFIGURATION_create ();
211 GNUNET_break (GNUNET_OK ==
212 GNUNET_CONFIGURATION_load (def_cfg,
215 GNUNET_CONFIGURATION_write_diffs (def_cfg,
219 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
220 _("Failed to write configuration to `%s'\n"),
226 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
227 _("Wrote updated configuration to `%s'\n"),
230 GNUNET_CONFIGURATION_destroy (def_cfg);
234 GNUNET_CONFIGURATION_destroy (new_cfg);
240 * Function called to report success or failure for
241 * NAT configuration test.
244 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
247 test_report_cb (void *cls,
248 enum GNUNET_NAT_StatusCode result)
251 PRINTF ("NAT test result: %s\n",
252 GNUNET_NAT_AUTO_status2string (result));
258 * Task run on shutdown.
263 do_shutdown (void *cls)
267 GNUNET_NAT_AUTO_autoconfig_cancel (ah);
272 GNUNET_NAT_AUTO_test_stop (nt);
279 * Main function that will be run.
282 * @param args remaining command-line arguments
283 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
284 * @param c configuration
290 const struct GNUNET_CONFIGURATION_Handle *c)
295 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
300 ah = GNUNET_NAT_AUTO_autoconfig_start (c,
305 if (use_tcp && use_udp)
309 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
310 "Cannot use TCP and UDP\n");
320 if (NULL != section_name)
322 nt = GNUNET_NAT_AUTO_test_start (c,
333 * Main function of gnunet-nat-auto
335 * @param argc number of command-line arguments
336 * @param argv command line
337 * @return 0 on success, -1 on error
343 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
345 gettext_noop ("run autoconfiguration"),
346 GNUNET_NO, &GNUNET_GETOPT_set_one, &do_auto },
347 {'S', "section", "NAME",
348 gettext_noop ("section name providing the configuration for the adapter"),
349 GNUNET_YES, &GNUNET_GETOPT_set_string, §ion_name },
351 gettext_noop ("use TCP"),
352 GNUNET_NO, &GNUNET_GETOPT_set_one, &use_tcp },
354 gettext_noop ("use UDP"),
355 GNUNET_NO, &GNUNET_GETOPT_set_one, &use_udp },
357 gettext_noop ("write configuration file (for autoconfiguration)"),
358 GNUNET_NO, &GNUNET_GETOPT_set_one, &write_cfg },
359 GNUNET_GETOPT_OPTION_END
363 GNUNET_STRINGS_get_utf8_args (argc, argv,
367 GNUNET_PROGRAM_run (argc, argv,
368 "gnunet-nat-auto [options]",
369 _("GNUnet NAT traversal autoconfiguration"),
376 GNUNET_free ((void*) argv);
381 /* end of gnunet-nat-auto.c */