aboutsummaryrefslogtreecommitdiff
path: root/src/service/nat-auto/nat_auto_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service/nat-auto/nat_auto_api.c')
-rw-r--r--src/service/nat-auto/nat_auto_api.c292
1 files changed, 292 insertions, 0 deletions
diff --git a/src/service/nat-auto/nat_auto_api.c b/src/service/nat-auto/nat_auto_api.c
new file mode 100644
index 000000000..3c982f883
--- /dev/null
+++ b/src/service/nat-auto/nat_auto_api.c
@@ -0,0 +1,292 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2007-2017 GNUnet e.V.
4
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.
9
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.
14
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/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @author Christian Grothoff
23 * @author Milan Bouchet-Valat
24 *
25 * @file nat-auto/nat_auto_api.c
26 * Routines for NAT auto configuration.
27 */
28#include "platform.h"
29#include "gnunet_nat_service.h"
30#include "gnunet_nat_auto_service.h"
31#include "nat-auto.h"
32
33
34/**
35 * Handle to auto-configuration in progress.
36 */
37struct GNUNET_NAT_AUTO_AutoHandle
38{
39 /**
40 * Configuration we use.
41 */
42 const struct GNUNET_CONFIGURATION_Handle *cfg;
43
44 /**
45 * Message queue for communicating with the NAT service.
46 */
47 struct GNUNET_MQ_Handle *mq;
48
49 /**
50 * Function called with the result from the autoconfiguration.
51 */
52 GNUNET_NAT_AUTO_AutoResultCallback arc;
53
54 /**
55 * Closure for @e arc.
56 */
57 void *arc_cls;
58};
59
60
61/**
62 * Converts `enum GNUNET_NAT_StatusCode` to string
63 *
64 * @param err error code to resolve to a string
65 * @return point to a static string containing the error code
66 */
67const char *
68GNUNET_NAT_AUTO_status2string (enum GNUNET_NAT_StatusCode err)
69{
70 switch (err)
71 {
72 case GNUNET_NAT_ERROR_SUCCESS:
73 return _ ("Operation Successful");
74
75 case GNUNET_NAT_ERROR_IPC_FAILURE:
76 return _ ("IPC failure");
77
78 case GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR:
79 return _ ("Failure in network subsystem, check permissions.");
80
81 case GNUNET_NAT_ERROR_TIMEOUT:
82 return _ ("Encountered timeout while performing operation");
83
84 case GNUNET_NAT_ERROR_NOT_ONLINE:
85 return _ ("detected that we are offline");
86
87 case GNUNET_NAT_ERROR_UPNPC_NOT_FOUND:
88 return _ ("`upnpc` command not found");
89
90 case GNUNET_NAT_ERROR_UPNPC_FAILED:
91 return _ ("Failed to run `upnpc` command");
92
93 case GNUNET_NAT_ERROR_UPNPC_TIMEOUT:
94 return _ ("`upnpc' command took too long, process killed");
95
96 case GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED:
97 return _ ("`upnpc' command failed to establish port mapping");
98
99 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND:
100 return _ ("`external-ip' command not found");
101
102 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED:
103 return _ ("Failed to run `external-ip` command");
104
105 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID:
106 return _ ("`external-ip' command output invalid");
107
108 case GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID:
109 return _ ("no valid address was returned by `external-ip'");
110
111 case GNUNET_NAT_ERROR_NO_VALID_IF_IP_COMBO:
112 return _ (
113 "Could not determine interface with internal/local network address");
114
115 case GNUNET_NAT_ERROR_HELPER_NAT_SERVER_NOT_FOUND:
116 return _ ("No functioning gnunet-helper-nat-server installation found");
117
118 case GNUNET_NAT_ERROR_NAT_TEST_START_FAILED:
119 return _ ("NAT test could not be initialized");
120
121 case GNUNET_NAT_ERROR_NAT_TEST_TIMEOUT:
122 return _ ("NAT test timeout reached");
123
124 case GNUNET_NAT_ERROR_NAT_REGISTER_FAILED:
125 return _ ("could not register NAT");
126
127 case GNUNET_NAT_ERROR_HELPER_NAT_CLIENT_NOT_FOUND:
128 return _ ("No working gnunet-helper-nat-client installation found");
129
130 default:
131 return "unknown status code";
132 }
133}
134
135
136/**
137 * Check result from autoconfiguration attempt.
138 *
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)
142 */
143static int
144check_auto_result (void *cls,
145 const struct GNUNET_NAT_AUTO_AutoconfigResultMessage *res)
146{
147 return GNUNET_OK;
148}
149
150
151/**
152 * Handle result from autoconfiguration attempt.
153 *
154 * @param cls the `struct GNUNET_NAT_AUTO_AutoHandle`
155 * @param res the result
156 */
157static void
158handle_auto_result (void *cls,
159 const struct GNUNET_NAT_AUTO_AutoconfigResultMessage *res)
160{
161 struct GNUNET_NAT_AUTO_AutoHandle *ah = cls;
162 size_t left;
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);
168
169 left = ntohs (res->header.size) - sizeof(*res);
170 cfg = GNUNET_CONFIGURATION_create ();
171 if (GNUNET_OK !=
172 GNUNET_CONFIGURATION_deserialize (cfg,
173 (const char *) &res[1],
174 left,
175 NULL))
176 {
177 GNUNET_break (0);
178 ah->arc (ah->arc_cls,
179 NULL,
180 GNUNET_NAT_ERROR_IPC_FAILURE,
181 type);
182 }
183 else
184 {
185 ah->arc (ah->arc_cls,
186 cfg,
187 status,
188 type);
189 }
190 GNUNET_CONFIGURATION_destroy (cfg);
191 GNUNET_NAT_AUTO_autoconfig_cancel (ah);
192}
193
194
195/**
196 * Handle queue errors by reporting autoconfiguration failure.
197 *
198 * @param cls the `struct GNUNET_NAT_AUTO_AutoHandle *`
199 * @param error details about the error
200 */
201static void
202ah_error_handler (void *cls,
203 enum GNUNET_MQ_Error error)
204{
205 struct GNUNET_NAT_AUTO_AutoHandle *ah = cls;
206
207 ah->arc (ah->arc_cls,
208 NULL,
209 GNUNET_NAT_ERROR_IPC_FAILURE,
210 GNUNET_NAT_TYPE_UNKNOWN);
211 GNUNET_NAT_AUTO_autoconfig_cancel (ah);
212}
213
214
215/**
216 * Start auto-configuration routine. The transport adapters should
217 * be stopped while this function is called.
218 *
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
223 */
224struct GNUNET_NAT_AUTO_AutoHandle *
225GNUNET_NAT_AUTO_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
226 GNUNET_NAT_AUTO_AutoResultCallback cb,
227 void *cb_cls)
228{
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,
235 ah),
236 GNUNET_MQ_handler_end ()
237 };
238 struct GNUNET_MQ_Envelope *env;
239 struct GNUNET_NAT_AUTO_AutoconfigRequestMessage *req;
240 char *buf;
241 size_t size;
242
243 buf = GNUNET_CONFIGURATION_serialize (cfg,
244 &size);
245 if (size > GNUNET_MAX_MESSAGE_SIZE - sizeof(*req))
246 {
247 GNUNET_break (0);
248 GNUNET_free (buf);
249 GNUNET_free (ah);
250 return NULL;
251 }
252 ah->arc = cb;
253 ah->arc_cls = cb_cls;
254 ah->mq = GNUNET_CLIENT_connect (cfg,
255 "nat",
256 handlers,
257 &ah_error_handler,
258 ah);
259 if (NULL == ah->mq)
260 {
261 GNUNET_break (0);
262 GNUNET_free (buf);
263 GNUNET_free (ah);
264 return NULL;
265 }
266 env = GNUNET_MQ_msg_extra (req,
267 size,
268 GNUNET_MESSAGE_TYPE_NAT_AUTO_REQUEST_CFG);
269 GNUNET_memcpy (&req[1],
270 buf,
271 size);
272 GNUNET_free (buf);
273 GNUNET_MQ_send (ah->mq,
274 env);
275 return ah;
276}
277
278
279/**
280 * Abort autoconfiguration.
281 *
282 * @param ah handle for operation to abort
283 */
284void
285GNUNET_NAT_AUTO_autoconfig_cancel (struct GNUNET_NAT_AUTO_AutoHandle *ah)
286{
287 GNUNET_MQ_destroy (ah->mq);
288 GNUNET_free (ah);
289}
290
291
292/* end of nat_api_auto.c */