2 This file is part of GNUnet.
3 Copyright (C) 2007-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/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
22 * @author Christian Grothoff
23 * @author Milan Bouchet-Valat
25 * @file nat-auto/nat_auto_api.c
26 * Routines for NAT auto configuration.
29 #include "gnunet_nat_service.h"
30 #include "gnunet_nat_auto_service.h"
36 * Handle to auto-configuration in progress.
38 struct GNUNET_NAT_AUTO_AutoHandle {
40 * Configuration we use.
42 const struct GNUNET_CONFIGURATION_Handle *cfg;
45 * Message queue for communicating with the NAT service.
47 struct GNUNET_MQ_Handle *mq;
50 * Function called with the result from the autoconfiguration.
52 GNUNET_NAT_AUTO_AutoResultCallback arc;
62 * Converts `enum GNUNET_NAT_StatusCode` to string
64 * @param err error code to resolve to a string
65 * @return point to a static string containing the error code
68 GNUNET_NAT_AUTO_status2string(enum GNUNET_NAT_StatusCode err)
72 case GNUNET_NAT_ERROR_SUCCESS:
73 return _("Operation Successful");
75 case GNUNET_NAT_ERROR_IPC_FAILURE:
76 return _("IPC failure");
78 case GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR:
79 return _("Failure in network subsystem, check permissions.");
81 case GNUNET_NAT_ERROR_TIMEOUT:
82 return _("Encountered timeout while performing operation");
84 case GNUNET_NAT_ERROR_NOT_ONLINE:
85 return _("detected that we are offline");
87 case GNUNET_NAT_ERROR_UPNPC_NOT_FOUND:
88 return _("`upnpc` command not found");
90 case GNUNET_NAT_ERROR_UPNPC_FAILED:
91 return _("Failed to run `upnpc` command");
93 case GNUNET_NAT_ERROR_UPNPC_TIMEOUT:
94 return _("`upnpc' command took too long, process killed");
96 case GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED:
97 return _("`upnpc' command failed to establish port mapping");
99 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND:
100 return _("`external-ip' command not found");
102 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED:
103 return _("Failed to run `external-ip` command");
105 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID:
106 return _("`external-ip' command output invalid");
108 case GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID:
109 return _("no valid address was returned by `external-ip'");
111 case GNUNET_NAT_ERROR_NO_VALID_IF_IP_COMBO:
112 return _("Could not determine interface with internal/local network address");
114 case GNUNET_NAT_ERROR_HELPER_NAT_SERVER_NOT_FOUND:
115 return _("No functioning gnunet-helper-nat-server installation found");
117 case GNUNET_NAT_ERROR_NAT_TEST_START_FAILED:
118 return _("NAT test could not be initialized");
120 case GNUNET_NAT_ERROR_NAT_TEST_TIMEOUT:
121 return _("NAT test timeout reached");
123 case GNUNET_NAT_ERROR_NAT_REGISTER_FAILED:
124 return _("could not register NAT");
126 case GNUNET_NAT_ERROR_HELPER_NAT_CLIENT_NOT_FOUND:
127 return _("No working gnunet-helper-nat-client installation found");
130 return "unknown status code";
136 * Check result from autoconfiguration attempt.
138 * @param cls the `struct GNUNET_NAT_AUTO_AutoHandle`
139 * @param res the result
140 * @return #GNUNET_OK if @a res is well-formed (always for now)
143 check_auto_result(void *cls,
144 const struct GNUNET_NAT_AUTO_AutoconfigResultMessage *res)
151 * Handle result from autoconfiguration attempt.
153 * @param cls the `struct GNUNET_NAT_AUTO_AutoHandle`
154 * @param res the result
157 handle_auto_result(void *cls,
158 const struct GNUNET_NAT_AUTO_AutoconfigResultMessage *res)
160 struct GNUNET_NAT_AUTO_AutoHandle *ah = cls;
162 struct GNUNET_CONFIGURATION_Handle *cfg;
163 enum GNUNET_NAT_Type type
164 = (enum GNUNET_NAT_Type)ntohl(res->type);
165 enum GNUNET_NAT_StatusCode status
166 = (enum GNUNET_NAT_StatusCode)ntohl(res->status_code);
168 left = ntohs(res->header.size) - sizeof(*res);
169 cfg = GNUNET_CONFIGURATION_create();
171 GNUNET_CONFIGURATION_deserialize(cfg,
172 (const char *)&res[1],
179 GNUNET_NAT_ERROR_IPC_FAILURE,
189 GNUNET_CONFIGURATION_destroy(cfg);
190 GNUNET_NAT_AUTO_autoconfig_cancel(ah);
195 * Handle queue errors by reporting autoconfiguration failure.
197 * @param cls the `struct GNUNET_NAT_AUTO_AutoHandle *`
198 * @param error details about the error
201 ah_error_handler(void *cls,
202 enum GNUNET_MQ_Error error)
204 struct GNUNET_NAT_AUTO_AutoHandle *ah = cls;
208 GNUNET_NAT_ERROR_IPC_FAILURE,
209 GNUNET_NAT_TYPE_UNKNOWN);
210 GNUNET_NAT_AUTO_autoconfig_cancel(ah);
215 * Start auto-configuration routine. The transport adapters should
216 * be stopped while this function is called.
218 * @param cfg initial configuration
219 * @param cb function to call with autoconfiguration result
220 * @param cb_cls closure for @a cb
221 * @return handle to cancel operation
223 struct GNUNET_NAT_AUTO_AutoHandle *
224 GNUNET_NAT_AUTO_autoconfig_start(const struct GNUNET_CONFIGURATION_Handle *cfg,
225 GNUNET_NAT_AUTO_AutoResultCallback cb,
228 struct GNUNET_NAT_AUTO_AutoHandle *ah = GNUNET_new(struct GNUNET_NAT_AUTO_AutoHandle);
229 struct GNUNET_MQ_MessageHandler handlers[] = {
230 GNUNET_MQ_hd_var_size(auto_result,
231 GNUNET_MESSAGE_TYPE_NAT_AUTO_CFG_RESULT,
232 struct GNUNET_NAT_AUTO_AutoconfigResultMessage,
234 GNUNET_MQ_handler_end()
236 struct GNUNET_MQ_Envelope *env;
237 struct GNUNET_NAT_AUTO_AutoconfigRequestMessage *req;
241 buf = GNUNET_CONFIGURATION_serialize(cfg,
243 if (size > GNUNET_MAX_MESSAGE_SIZE - sizeof(*req))
251 ah->arc_cls = cb_cls;
252 ah->mq = GNUNET_CLIENT_connect(cfg,
264 env = GNUNET_MQ_msg_extra(req,
266 GNUNET_MESSAGE_TYPE_NAT_AUTO_REQUEST_CFG);
267 GNUNET_memcpy(&req[1],
271 GNUNET_MQ_send(ah->mq,
278 * Abort autoconfiguration.
280 * @param ah handle for operation to abort
283 GNUNET_NAT_AUTO_autoconfig_cancel(struct GNUNET_NAT_AUTO_AutoHandle *ah)
285 GNUNET_MQ_destroy(ah->mq);
289 /* end of nat_api_auto.c */