aboutsummaryrefslogtreecommitdiff
path: root/src/nat-auto/nat_auto_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nat-auto/nat_auto_api.c')
-rw-r--r--src/nat-auto/nat_auto_api.c274
1 files changed, 274 insertions, 0 deletions
diff --git a/src/nat-auto/nat_auto_api.c b/src/nat-auto/nat_auto_api.c
new file mode 100644
index 000000000..e6b0512c6
--- /dev/null
+++ b/src/nat-auto/nat_auto_api.c
@@ -0,0 +1,274 @@
1
2/*
3 This file is part of GNUnet.
4 Copyright (C) 2007-2016 GNUnet e.V.
5
6 GNUnet is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 3, or (at your
9 option) any later version.
10
11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNUnet; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22/**
23 * @author Christian Grothoff
24 * @author Milan Bouchet-Valat
25 *
26 * @file nat/nat_auto_api.c
27 * Routines for NAT auto configuration.
28 */
29#include "platform.h"
30#include "gnunet_nat_service.h"
31#include "gnunet_nat_auto_service.h"
32#include "nat-auto.h"
33
34
35
36/**
37 * Handle to auto-configuration in progress.
38 */
39struct GNUNET_NAT_AutoHandle
40{
41
42 /**
43 * Configuration we use.
44 */
45 const struct GNUNET_CONFIGURATION_Handle *cfg;
46
47 /**
48 * Message queue for communicating with the NAT service.
49 */
50 struct GNUNET_MQ_Handle *mq;
51
52 /**
53 * Function called with the result from the autoconfiguration.
54 */
55 GNUNET_NAT_AutoResultCallback arc;
56
57 /**
58 * Closure for @e arc.
59 */
60 void *arc_cls;
61
62};
63
64
65/**
66 * Converts `enum GNUNET_NAT_StatusCode` to string
67 *
68 * @param err error code to resolve to a string
69 * @return point to a static string containing the error code
70 */
71const char *
72GNUNET_NAT_status2string (enum GNUNET_NAT_StatusCode err)
73{
74 switch (err)
75 {
76 case GNUNET_NAT_ERROR_SUCCESS:
77 return _ ("Operation Successful");
78 case GNUNET_NAT_ERROR_IPC_FAILURE:
79 return _ ("IPC failure");
80 case GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR:
81 return _ ("Failure in network subsystem, check permissions.");
82 case GNUNET_NAT_ERROR_TIMEOUT:
83 return _ ("Encountered timeout while performing operation");
84 case GNUNET_NAT_ERROR_NOT_ONLINE:
85 return _ ("detected that we are offline");
86 case GNUNET_NAT_ERROR_UPNPC_NOT_FOUND:
87 return _ ("`upnpc` command not found");
88 case GNUNET_NAT_ERROR_UPNPC_FAILED:
89 return _ ("Failed to run `upnpc` command");
90 case GNUNET_NAT_ERROR_UPNPC_TIMEOUT:
91 return _ ("`upnpc' command took too long, process killed");
92 case GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED:
93 return _ ("`upnpc' command failed to establish port mapping");
94 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND:
95 return _ ("`external-ip' command not found");
96 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED:
97 return _ ("Failed to run `external-ip` command");
98 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID:
99 return _ ("`external-ip' command output invalid");
100 case GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID:
101 return _ ("no valid address was returned by `external-ip'");
102 case GNUNET_NAT_ERROR_NO_VALID_IF_IP_COMBO:
103 return _ ("Could not determine interface with internal/local network address");
104 case GNUNET_NAT_ERROR_HELPER_NAT_SERVER_NOT_FOUND:
105 return _ ("No functioning gnunet-helper-nat-server installation found");
106 case GNUNET_NAT_ERROR_NAT_TEST_START_FAILED:
107 return _ ("NAT test could not be initialized");
108 case GNUNET_NAT_ERROR_NAT_TEST_TIMEOUT:
109 return _ ("NAT test timeout reached");
110 case GNUNET_NAT_ERROR_NAT_REGISTER_FAILED:
111 return _ ("could not register NAT");
112 case GNUNET_NAT_ERROR_HELPER_NAT_CLIENT_NOT_FOUND:
113 return _ ("No working gnunet-helper-nat-client installation found");
114 default:
115 return "unknown status code";
116 }
117}
118
119
120/**
121 * Check result from autoconfiguration attempt.
122 *
123 * @param cls the `struct GNUNET_NAT_AutoHandle`
124 * @param res the result
125 * @return #GNUNET_OK if @a res is well-formed (always for now)
126 */
127static int
128check_auto_result (void *cls,
129 const struct GNUNET_NAT_AutoconfigResultMessage *res)
130{
131 return GNUNET_OK;
132}
133
134
135/**
136 * Handle result from autoconfiguration attempt.
137 *
138 * @param cls the `struct GNUNET_NAT_AutoHandle`
139 * @param res the result
140 */
141static void
142handle_auto_result (void *cls,
143 const struct GNUNET_NAT_AutoconfigResultMessage *res)
144{
145 struct GNUNET_NAT_AutoHandle *ah = cls;
146 size_t left;
147 struct GNUNET_CONFIGURATION_Handle *cfg;
148 enum GNUNET_NAT_Type type
149 = (enum GNUNET_NAT_Type) ntohl (res->type);
150 enum GNUNET_NAT_StatusCode status
151 = (enum GNUNET_NAT_StatusCode) ntohl (res->status_code);
152
153 left = ntohs (res->header.size) - sizeof (*res);
154 cfg = GNUNET_CONFIGURATION_create ();
155 if (GNUNET_OK !=
156 GNUNET_CONFIGURATION_deserialize (cfg,
157 (const char *) &res[1],
158 left,
159 GNUNET_NO))
160 {
161 GNUNET_break (0);
162 ah->arc (ah->arc_cls,
163 NULL,
164 GNUNET_NAT_ERROR_IPC_FAILURE,
165 type);
166 }
167 else
168 {
169 ah->arc (ah->arc_cls,
170 cfg,
171 status,
172 type);
173 }
174 GNUNET_CONFIGURATION_destroy (cfg);
175 GNUNET_NAT_autoconfig_cancel (ah);
176}
177
178
179/**
180 * Handle queue errors by reporting autoconfiguration failure.
181 *
182 * @param cls the `struct GNUNET_NAT_AutoHandle *`
183 * @param error details about the error
184 */
185static void
186ah_error_handler (void *cls,
187 enum GNUNET_MQ_Error error)
188{
189 struct GNUNET_NAT_AutoHandle *ah = cls;
190
191 ah->arc (ah->arc_cls,
192 NULL,
193 GNUNET_NAT_ERROR_IPC_FAILURE,
194 GNUNET_NAT_TYPE_UNKNOWN);
195 GNUNET_NAT_autoconfig_cancel (ah);
196}
197
198
199/**
200 * Start auto-configuration routine. The transport adapters should
201 * be stopped while this function is called.
202 *
203 * @param cfg initial configuration
204 * @param cb function to call with autoconfiguration result
205 * @param cb_cls closure for @a cb
206 * @return handle to cancel operation
207 */
208struct GNUNET_NAT_AutoHandle *
209GNUNET_NAT_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
210 GNUNET_NAT_AutoResultCallback cb,
211 void *cb_cls)
212{
213 struct GNUNET_NAT_AutoHandle *ah = GNUNET_new (struct GNUNET_NAT_AutoHandle);
214 struct GNUNET_MQ_MessageHandler handlers[] = {
215 GNUNET_MQ_hd_var_size (auto_result,
216 GNUNET_MESSAGE_TYPE_NAT_AUTO_CFG_RESULT,
217 struct GNUNET_NAT_AutoconfigResultMessage,
218 ah),
219 GNUNET_MQ_handler_end ()
220 };
221 struct GNUNET_MQ_Envelope *env;
222 struct GNUNET_NAT_AutoconfigRequestMessage *req;
223 char *buf;
224 size_t size;
225
226 buf = GNUNET_CONFIGURATION_serialize (cfg,
227 &size);
228 if (size > GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*req))
229 {
230 GNUNET_break (0);
231 GNUNET_free (buf);
232 GNUNET_free (ah);
233 return NULL;
234 }
235 ah->arc = cb;
236 ah->arc_cls = cb_cls;
237 ah->mq = GNUNET_CLIENT_connecT (cfg,
238 "nat",
239 handlers,
240 &ah_error_handler,
241 ah);
242 if (NULL == ah->mq)
243 {
244 GNUNET_break (0);
245 GNUNET_free (buf);
246 GNUNET_free (ah);
247 return NULL;
248 }
249 env = GNUNET_MQ_msg_extra (req,
250 size,
251 GNUNET_MESSAGE_TYPE_NAT_AUTO_REQUEST_CFG);
252 GNUNET_memcpy (&req[1],
253 buf,
254 size);
255 GNUNET_free (buf);
256 GNUNET_MQ_send (ah->mq,
257 env);
258 return ah;
259}
260
261
262/**
263 * Abort autoconfiguration.
264 *
265 * @param ah handle for operation to abort
266 */
267void
268GNUNET_NAT_autoconfig_cancel (struct GNUNET_NAT_AutoHandle *ah)
269{
270 GNUNET_MQ_destroy (ah->mq);
271 GNUNET_free (ah);
272}
273
274/* end of nat_api_auto.c */