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/>.
20 * @author Christian Grothoff
21 * @author Milan Bouchet-Valat
23 * @file nat-auto/nat_auto_api.c
24 * Routines for NAT auto configuration.
27 #include "gnunet_nat_service.h"
28 #include "gnunet_nat_auto_service.h"
34 * Handle to auto-configuration in progress.
36 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;
63 * Converts `enum GNUNET_NAT_StatusCode` to string
65 * @param err error code to resolve to a string
66 * @return point to a static string containing the error code
69 GNUNET_NAT_AUTO_status2string (enum GNUNET_NAT_StatusCode err)
73 case GNUNET_NAT_ERROR_SUCCESS:
74 return _ ("Operation Successful");
75 case GNUNET_NAT_ERROR_IPC_FAILURE:
76 return _ ("IPC failure");
77 case GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR:
78 return _ ("Failure in network subsystem, check permissions.");
79 case GNUNET_NAT_ERROR_TIMEOUT:
80 return _ ("Encountered timeout while performing operation");
81 case GNUNET_NAT_ERROR_NOT_ONLINE:
82 return _ ("detected that we are offline");
83 case GNUNET_NAT_ERROR_UPNPC_NOT_FOUND:
84 return _ ("`upnpc` command not found");
85 case GNUNET_NAT_ERROR_UPNPC_FAILED:
86 return _ ("Failed to run `upnpc` command");
87 case GNUNET_NAT_ERROR_UPNPC_TIMEOUT:
88 return _ ("`upnpc' command took too long, process killed");
89 case GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED:
90 return _ ("`upnpc' command failed to establish port mapping");
91 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND:
92 return _ ("`external-ip' command not found");
93 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED:
94 return _ ("Failed to run `external-ip` command");
95 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID:
96 return _ ("`external-ip' command output invalid");
97 case GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID:
98 return _ ("no valid address was returned by `external-ip'");
99 case GNUNET_NAT_ERROR_NO_VALID_IF_IP_COMBO:
100 return _ ("Could not determine interface with internal/local network address");
101 case GNUNET_NAT_ERROR_HELPER_NAT_SERVER_NOT_FOUND:
102 return _ ("No functioning gnunet-helper-nat-server installation found");
103 case GNUNET_NAT_ERROR_NAT_TEST_START_FAILED:
104 return _ ("NAT test could not be initialized");
105 case GNUNET_NAT_ERROR_NAT_TEST_TIMEOUT:
106 return _ ("NAT test timeout reached");
107 case GNUNET_NAT_ERROR_NAT_REGISTER_FAILED:
108 return _ ("could not register NAT");
109 case GNUNET_NAT_ERROR_HELPER_NAT_CLIENT_NOT_FOUND:
110 return _ ("No working gnunet-helper-nat-client installation found");
112 return "unknown status code";
118 * Check result from autoconfiguration attempt.
120 * @param cls the `struct GNUNET_NAT_AUTO_AutoHandle`
121 * @param res the result
122 * @return #GNUNET_OK if @a res is well-formed (always for now)
125 check_auto_result (void *cls,
126 const struct GNUNET_NAT_AUTO_AutoconfigResultMessage *res)
133 * Handle result from autoconfiguration attempt.
135 * @param cls the `struct GNUNET_NAT_AUTO_AutoHandle`
136 * @param res the result
139 handle_auto_result (void *cls,
140 const struct GNUNET_NAT_AUTO_AutoconfigResultMessage *res)
142 struct GNUNET_NAT_AUTO_AutoHandle *ah = cls;
144 struct GNUNET_CONFIGURATION_Handle *cfg;
145 enum GNUNET_NAT_Type type
146 = (enum GNUNET_NAT_Type) ntohl (res->type);
147 enum GNUNET_NAT_StatusCode status
148 = (enum GNUNET_NAT_StatusCode) ntohl (res->status_code);
150 left = ntohs (res->header.size) - sizeof (*res);
151 cfg = GNUNET_CONFIGURATION_create ();
153 GNUNET_CONFIGURATION_deserialize (cfg,
154 (const char *) &res[1],
159 ah->arc (ah->arc_cls,
161 GNUNET_NAT_ERROR_IPC_FAILURE,
166 ah->arc (ah->arc_cls,
171 GNUNET_CONFIGURATION_destroy (cfg);
172 GNUNET_NAT_AUTO_autoconfig_cancel (ah);
177 * Handle queue errors by reporting autoconfiguration failure.
179 * @param cls the `struct GNUNET_NAT_AUTO_AutoHandle *`
180 * @param error details about the error
183 ah_error_handler (void *cls,
184 enum GNUNET_MQ_Error error)
186 struct GNUNET_NAT_AUTO_AutoHandle *ah = cls;
188 ah->arc (ah->arc_cls,
190 GNUNET_NAT_ERROR_IPC_FAILURE,
191 GNUNET_NAT_TYPE_UNKNOWN);
192 GNUNET_NAT_AUTO_autoconfig_cancel (ah);
197 * Start auto-configuration routine. The transport adapters should
198 * be stopped while this function is called.
200 * @param cfg initial configuration
201 * @param cb function to call with autoconfiguration result
202 * @param cb_cls closure for @a cb
203 * @return handle to cancel operation
205 struct GNUNET_NAT_AUTO_AutoHandle *
206 GNUNET_NAT_AUTO_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
207 GNUNET_NAT_AUTO_AutoResultCallback cb,
210 struct GNUNET_NAT_AUTO_AutoHandle *ah = GNUNET_new (struct GNUNET_NAT_AUTO_AutoHandle);
211 struct GNUNET_MQ_MessageHandler handlers[] = {
212 GNUNET_MQ_hd_var_size (auto_result,
213 GNUNET_MESSAGE_TYPE_NAT_AUTO_CFG_RESULT,
214 struct GNUNET_NAT_AUTO_AutoconfigResultMessage,
216 GNUNET_MQ_handler_end ()
218 struct GNUNET_MQ_Envelope *env;
219 struct GNUNET_NAT_AUTO_AutoconfigRequestMessage *req;
223 buf = GNUNET_CONFIGURATION_serialize (cfg,
225 if (size > GNUNET_MAX_MESSAGE_SIZE - sizeof (*req))
233 ah->arc_cls = cb_cls;
234 ah->mq = GNUNET_CLIENT_connect (cfg,
246 env = GNUNET_MQ_msg_extra (req,
248 GNUNET_MESSAGE_TYPE_NAT_AUTO_REQUEST_CFG);
249 GNUNET_memcpy (&req[1],
253 GNUNET_MQ_send (ah->mq,
260 * Abort autoconfiguration.
262 * @param ah handle for operation to abort
265 GNUNET_NAT_AUTO_autoconfig_cancel (struct GNUNET_NAT_AUTO_AutoHandle *ah)
267 GNUNET_MQ_destroy (ah->mq);
271 /* end of nat_api_auto.c */