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 it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * @file src/nat/gnunet-nat-auto.c
21 * @brief Command-line tool for testing and autoconfiguration of NAT traversal
22 * @author Christian Grothoff
23 * @author Bruno Cabral
26 #include "gnunet_util_lib.h"
27 #include "gnunet_nat_service.h"
28 #include "gnunet_nat_auto_service.h"
31 * Value to return from #main().
33 static int global_ret;
36 * Handle to ongoing autoconfiguration.
38 static struct GNUNET_NAT_AUTO_AutoHandle *ah;
41 * If we do auto-configuration, should we write the result
47 * Configuration filename.
49 static const char *cfg_file;
52 * Original configuration.
54 static const struct GNUNET_CONFIGURATION_Handle *cfg;
57 * Adapter we are supposed to test.
59 static char *section_name;
62 * Should we run autoconfiguration?
67 * Handle to a NAT test operation.
69 static struct GNUNET_NAT_AUTO_Test *nt;
72 * Flag set to 1 if we use IPPROTO_UDP.
77 * Flag set to 1 if we use IPPROTO_TCP.
87 * Test if all activities have finished, and if so,
97 GNUNET_SCHEDULER_shutdown ();
102 * Function to iterate over sugested changes options
105 * @param section name of the section
106 * @param option name of the option
107 * @param value value of the option
110 auto_conf_iter (void *cls,
115 struct GNUNET_CONFIGURATION_Handle *new_cfg = cls;
121 GNUNET_CONFIGURATION_set_value_string (new_cfg,
129 * Function called with the result from the autoconfiguration.
132 * @param diff minimal suggested changes to the original configuration
133 * to make it work (as best as we can)
134 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
135 * @param type what the situation of the NAT
138 auto_config_cb (void *cls,
139 const struct GNUNET_CONFIGURATION_Handle *diff,
140 enum GNUNET_NAT_StatusCode result,
141 enum GNUNET_NAT_Type type)
143 const char *nat_type;
144 char unknown_type[64];
145 struct GNUNET_CONFIGURATION_Handle *new_cfg;
150 case GNUNET_NAT_TYPE_NO_NAT:
153 case GNUNET_NAT_TYPE_UNREACHABLE_NAT:
154 nat_type = "NAT but we can traverse";
156 case GNUNET_NAT_TYPE_STUN_PUNCHED_NAT:
157 nat_type = "NAT but STUN is able to identify the correct information";
159 case GNUNET_NAT_TYPE_UPNP_NAT:
160 nat_type = "NAT but UPNP opened the ports";
163 SPRINTF (unknown_type,
164 "NAT unknown, type %u",
166 nat_type = unknown_type;
170 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
171 "NAT status: %s/%s\n",
172 GNUNET_NAT_AUTO_status2string (result),
178 /* Shortcut: if there are no changes suggested, bail out early. */
180 GNUNET_CONFIGURATION_is_dirty (diff))
186 /* Apply diff to original configuration and show changes
188 new_cfg = write_cfg ? GNUNET_CONFIGURATION_dup (cfg) : NULL;
190 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
191 _("Suggested configuration changes:\n"));
192 GNUNET_CONFIGURATION_iterate_section_values (diff,
197 /* If desired, write configuration to file; we write only the
198 changes to the defaults to keep things compact. */
201 struct GNUNET_CONFIGURATION_Handle *def_cfg;
203 GNUNET_CONFIGURATION_set_value_string (new_cfg,
207 def_cfg = GNUNET_CONFIGURATION_create ();
208 GNUNET_break (GNUNET_OK ==
209 GNUNET_CONFIGURATION_load (def_cfg,
212 GNUNET_CONFIGURATION_write_diffs (def_cfg,
216 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
217 _("Failed to write configuration to `%s'\n"),
223 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
224 _("Wrote updated configuration to `%s'\n"),
227 GNUNET_CONFIGURATION_destroy (def_cfg);
231 GNUNET_CONFIGURATION_destroy (new_cfg);
237 * Function called to report success or failure for
238 * NAT configuration test.
241 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
244 test_report_cb (void *cls,
245 enum GNUNET_NAT_StatusCode result)
248 PRINTF ("NAT test result: %s\n",
249 GNUNET_NAT_AUTO_status2string (result));
255 * Task run on shutdown.
260 do_shutdown (void *cls)
264 GNUNET_NAT_AUTO_autoconfig_cancel (ah);
269 GNUNET_NAT_AUTO_test_stop (nt);
276 * Main function that will be run.
279 * @param args remaining command-line arguments
280 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
281 * @param c configuration
287 const struct GNUNET_CONFIGURATION_Handle *c)
292 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
297 ah = GNUNET_NAT_AUTO_autoconfig_start (c,
302 if (use_tcp && use_udp)
306 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
307 "Cannot use TCP and UDP\n");
317 if (NULL != section_name)
319 nt = GNUNET_NAT_AUTO_test_start (c,
330 * Main function of gnunet-nat-auto
332 * @param argc number of command-line arguments
333 * @param argv command line
334 * @return 0 on success, -1 on error
340 struct GNUNET_GETOPT_CommandLineOption options[] = {
341 GNUNET_GETOPT_option_flag ('a',
343 gettext_noop ("run autoconfiguration"),
346 GNUNET_GETOPT_option_string ('S',
349 gettext_noop ("section name providing the configuration for the adapter"),
352 GNUNET_GETOPT_option_flag ('t',
354 gettext_noop ("use TCP"),
357 GNUNET_GETOPT_option_flag ('u',
359 gettext_noop ("use UDP"),
362 GNUNET_GETOPT_option_flag ('w',
364 gettext_noop ("write configuration file (for autoconfiguration)"),
366 GNUNET_GETOPT_OPTION_END
370 GNUNET_STRINGS_get_utf8_args (argc, argv,
374 GNUNET_PROGRAM_run (argc, argv,
375 "gnunet-nat-auto [options]",
376 _("GNUnet NAT traversal autoconfiguration"),
383 GNUNET_free ((void*) argv);
388 /* end of gnunet-nat-auto.c */