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"
35 * Handle to auto-configuration in progress.
37 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:
113 "Could not determine interface with internal/local network address");
115 case GNUNET_NAT_ERROR_HELPER_NAT_SERVER_NOT_FOUND:
116 return _ ("No functioning gnunet-helper-nat-server installation found");
118 case GNUNET_NAT_ERROR_NAT_TEST_START_FAILED:
119 return _ ("NAT test could not be initialized");
121 case GNUNET_NAT_ERROR_NAT_TEST_TIMEOUT:
122 return _ ("NAT test timeout reached");
124 case GNUNET_NAT_ERROR_NAT_REGISTER_FAILED:
125 return _ ("could not register NAT");
127 case GNUNET_NAT_ERROR_HELPER_NAT_CLIENT_NOT_FOUND:
128 return _ ("No working gnunet-helper-nat-client installation found");
131 return "unknown status code";
137 * Check result from autoconfiguration attempt.
139 * @param cls the `struct GNUNET_NAT_AUTO_AutoHandle`
140 * @param res the result
141 * @return #GNUNET_OK if @a res is well-formed (always for now)
144 check_auto_result (void *cls,
145 const struct GNUNET_NAT_AUTO_AutoconfigResultMessage *res)
152 * Handle result from autoconfiguration attempt.
154 * @param cls the `struct GNUNET_NAT_AUTO_AutoHandle`
155 * @param res the result
158 handle_auto_result (void *cls,
159 const struct GNUNET_NAT_AUTO_AutoconfigResultMessage *res)
161 struct GNUNET_NAT_AUTO_AutoHandle *ah = cls;
163 struct GNUNET_CONFIGURATION_Handle *cfg;
164 enum GNUNET_NAT_Type type
165 = (enum GNUNET_NAT_Type) ntohl (res->type);
166 enum GNUNET_NAT_StatusCode status
167 = (enum GNUNET_NAT_StatusCode) ntohl (res->status_code);
169 left = ntohs (res->header.size) - sizeof(*res);
170 cfg = GNUNET_CONFIGURATION_create ();
172 GNUNET_CONFIGURATION_deserialize (cfg,
173 (const char *) &res[1],
178 ah->arc (ah->arc_cls,
180 GNUNET_NAT_ERROR_IPC_FAILURE,
185 ah->arc (ah->arc_cls,
190 GNUNET_CONFIGURATION_destroy (cfg);
191 GNUNET_NAT_AUTO_autoconfig_cancel (ah);
196 * Handle queue errors by reporting autoconfiguration failure.
198 * @param cls the `struct GNUNET_NAT_AUTO_AutoHandle *`
199 * @param error details about the error
202 ah_error_handler (void *cls,
203 enum GNUNET_MQ_Error error)
205 struct GNUNET_NAT_AUTO_AutoHandle *ah = cls;
207 ah->arc (ah->arc_cls,
209 GNUNET_NAT_ERROR_IPC_FAILURE,
210 GNUNET_NAT_TYPE_UNKNOWN);
211 GNUNET_NAT_AUTO_autoconfig_cancel (ah);
216 * Start auto-configuration routine. The transport adapters should
217 * be stopped while this function is called.
219 * @param cfg initial configuration
220 * @param cb function to call with autoconfiguration result
221 * @param cb_cls closure for @a cb
222 * @return handle to cancel operation
224 struct GNUNET_NAT_AUTO_AutoHandle *
225 GNUNET_NAT_AUTO_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
226 GNUNET_NAT_AUTO_AutoResultCallback cb,
229 struct GNUNET_NAT_AUTO_AutoHandle *ah = GNUNET_new (struct
230 GNUNET_NAT_AUTO_AutoHandle);
231 struct GNUNET_MQ_MessageHandler handlers[] = {
232 GNUNET_MQ_hd_var_size (auto_result,
233 GNUNET_MESSAGE_TYPE_NAT_AUTO_CFG_RESULT,
234 struct GNUNET_NAT_AUTO_AutoconfigResultMessage,
236 GNUNET_MQ_handler_end ()
238 struct GNUNET_MQ_Envelope *env;
239 struct GNUNET_NAT_AUTO_AutoconfigRequestMessage *req;
243 buf = GNUNET_CONFIGURATION_serialize (cfg,
245 if (size > GNUNET_MAX_MESSAGE_SIZE - sizeof(*req))
253 ah->arc_cls = cb_cls;
254 ah->mq = GNUNET_CLIENT_connect (cfg,
266 env = GNUNET_MQ_msg_extra (req,
268 GNUNET_MESSAGE_TYPE_NAT_AUTO_REQUEST_CFG);
269 GNUNET_memcpy (&req[1],
273 GNUNET_MQ_send (ah->mq,
280 * Abort autoconfiguration.
282 * @param ah handle for operation to abort
285 GNUNET_NAT_AUTO_autoconfig_cancel (struct GNUNET_NAT_AUTO_AutoHandle *ah)
287 GNUNET_MQ_destroy (ah->mq);
292 /* end of nat_api_auto.c */