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 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.
17 * @file src/nat/gnunet-nat-auto.c
18 * @brief Command-line tool for testing and autoconfiguration of NAT traversal
19 * @author Christian Grothoff
20 * @author Bruno Cabral
23 #include "gnunet_util_lib.h"
24 #include "gnunet_nat_service.h"
25 #include "gnunet_nat_auto_service.h"
28 * Value to return from #main().
30 static int global_ret;
33 * Handle to ongoing autoconfiguration.
35 static struct GNUNET_NAT_AUTO_AutoHandle *ah;
38 * If we do auto-configuration, should we write the result
44 * Configuration filename.
46 static const char *cfg_file;
49 * Original configuration.
51 static const struct GNUNET_CONFIGURATION_Handle *cfg;
54 * Adapter we are supposed to test.
56 static char *section_name;
59 * Should we run autoconfiguration?
64 * Handle to a NAT test operation.
66 static struct GNUNET_NAT_AUTO_Test *nt;
69 * Flag set to 1 if we use IPPROTO_UDP.
74 * Flag set to 1 if we use IPPROTO_TCP.
84 * Test if all activities have finished, and if so,
94 GNUNET_SCHEDULER_shutdown ();
99 * Function to iterate over sugested changes options
102 * @param section name of the section
103 * @param option name of the option
104 * @param value value of the option
107 auto_conf_iter (void *cls,
112 struct GNUNET_CONFIGURATION_Handle *new_cfg = cls;
118 GNUNET_CONFIGURATION_set_value_string (new_cfg,
126 * Function called with the result from the autoconfiguration.
129 * @param diff minimal suggested changes to the original configuration
130 * to make it work (as best as we can)
131 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
132 * @param type what the situation of the NAT
135 auto_config_cb (void *cls,
136 const struct GNUNET_CONFIGURATION_Handle *diff,
137 enum GNUNET_NAT_StatusCode result,
138 enum GNUNET_NAT_Type type)
140 const char *nat_type;
141 char unknown_type[64];
142 struct GNUNET_CONFIGURATION_Handle *new_cfg;
147 case GNUNET_NAT_TYPE_NO_NAT:
150 case GNUNET_NAT_TYPE_UNREACHABLE_NAT:
151 nat_type = "NAT but we can traverse";
153 case GNUNET_NAT_TYPE_STUN_PUNCHED_NAT:
154 nat_type = "NAT but STUN is able to identify the correct information";
156 case GNUNET_NAT_TYPE_UPNP_NAT:
157 nat_type = "NAT but UPNP opened the ports";
160 SPRINTF (unknown_type,
161 "NAT unknown, type %u",
163 nat_type = unknown_type;
167 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
168 "NAT status: %s/%s\n",
169 GNUNET_NAT_AUTO_status2string (result),
175 /* Shortcut: if there are no changes suggested, bail out early. */
177 GNUNET_CONFIGURATION_is_dirty (diff))
183 /* Apply diff to original configuration and show changes
185 new_cfg = write_cfg ? GNUNET_CONFIGURATION_dup (cfg) : NULL;
187 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
188 _("Suggested configuration changes:\n"));
189 GNUNET_CONFIGURATION_iterate_section_values (diff,
194 /* If desired, write configuration to file; we write only the
195 changes to the defaults to keep things compact. */
198 struct GNUNET_CONFIGURATION_Handle *def_cfg;
200 GNUNET_CONFIGURATION_set_value_string (new_cfg,
204 def_cfg = GNUNET_CONFIGURATION_create ();
205 GNUNET_break (GNUNET_OK ==
206 GNUNET_CONFIGURATION_load (def_cfg,
209 GNUNET_CONFIGURATION_write_diffs (def_cfg,
213 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
214 _("Failed to write configuration to `%s'\n"),
220 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
221 _("Wrote updated configuration to `%s'\n"),
224 GNUNET_CONFIGURATION_destroy (def_cfg);
228 GNUNET_CONFIGURATION_destroy (new_cfg);
234 * Function called to report success or failure for
235 * NAT configuration test.
238 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
241 test_report_cb (void *cls,
242 enum GNUNET_NAT_StatusCode result)
245 PRINTF ("NAT test result: %s\n",
246 GNUNET_NAT_AUTO_status2string (result));
252 * Task run on shutdown.
257 do_shutdown (void *cls)
261 GNUNET_NAT_AUTO_autoconfig_cancel (ah);
266 GNUNET_NAT_AUTO_test_stop (nt);
273 * Main function that will be run.
276 * @param args remaining command-line arguments
277 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
278 * @param c configuration
284 const struct GNUNET_CONFIGURATION_Handle *c)
289 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
294 ah = GNUNET_NAT_AUTO_autoconfig_start (c,
299 if (use_tcp && use_udp)
303 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
304 "Cannot use TCP and UDP\n");
314 if (NULL != section_name)
316 nt = GNUNET_NAT_AUTO_test_start (c,
327 * Main function of gnunet-nat-auto
329 * @param argc number of command-line arguments
330 * @param argv command line
331 * @return 0 on success, -1 on error
337 struct GNUNET_GETOPT_CommandLineOption options[] = {
338 GNUNET_GETOPT_option_flag ('a',
340 gettext_noop ("run autoconfiguration"),
343 GNUNET_GETOPT_option_string ('S',
346 gettext_noop ("section name providing the configuration for the adapter"),
349 GNUNET_GETOPT_option_flag ('t',
351 gettext_noop ("use TCP"),
354 GNUNET_GETOPT_option_flag ('u',
356 gettext_noop ("use UDP"),
359 GNUNET_GETOPT_option_flag ('w',
361 gettext_noop ("write configuration file (for autoconfiguration)"),
363 GNUNET_GETOPT_OPTION_END
367 GNUNET_STRINGS_get_utf8_args (argc, argv,
371 GNUNET_PROGRAM_run (argc, argv,
372 "gnunet-nat-auto [options]",
373 _("GNUnet NAT traversal autoconfiguration"),
380 GNUNET_free ((void*) argv);
385 /* end of gnunet-nat-auto.c */