diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-10-23 19:53:59 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-10-23 19:53:59 +0000 |
commit | 10f9bc91ab9d758d0d60dd672206027cd136342a (patch) | |
tree | cb8c09ffe145ae925d5a51d4bd85029bb61f7df2 /src/nat/nat_api.c | |
parent | 588f820301bf298496e7bf0e6dea7b2c60ab3936 (diff) | |
download | gnunet-10f9bc91ab9d758d0d60dd672206027cd136342a.tar.gz gnunet-10f9bc91ab9d758d0d60dd672206027cd136342a.zip |
new NAT lib client api skeleton
Diffstat (limited to 'src/nat/nat_api.c')
-rw-r--r-- | src/nat/nat_api.c | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/src/nat/nat_api.c b/src/nat/nat_api.c new file mode 100644 index 000000000..6488fdf88 --- /dev/null +++ b/src/nat/nat_api.c | |||
@@ -0,0 +1,367 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2007-2016 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @author Christian Grothoff | ||
23 | * @author Milan Bouchet-Valat | ||
24 | * | ||
25 | * @file nat/nat_api.c | ||
26 | * Service for handling UPnP and NAT-PMP port forwarding | ||
27 | * and external IP address retrieval | ||
28 | */ | ||
29 | #include "platform.h" | ||
30 | #include "gnunet_nat_service.h" | ||
31 | |||
32 | |||
33 | /** | ||
34 | * Handle for active NAT registrations. | ||
35 | */ | ||
36 | struct GNUNET_NAT_Handle | ||
37 | { | ||
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 | * Our registration message. | ||
51 | */ | ||
52 | struct GNUNET_MessageHeader *reg; | ||
53 | |||
54 | /** | ||
55 | * Function to call when our addresses change. | ||
56 | */ | ||
57 | GNUNET_NAT_AddressCallback address_callback; | ||
58 | |||
59 | /** | ||
60 | * Function to call when another peer requests connection reversal. | ||
61 | */ | ||
62 | GNUNET_NAT_ReversalCallback reversal_callback; | ||
63 | |||
64 | /** | ||
65 | * Closure for the various callbacks. | ||
66 | */ | ||
67 | void *callback_cls; | ||
68 | |||
69 | }; | ||
70 | |||
71 | |||
72 | /** | ||
73 | * Attempt to enable port redirection and detect public IP address | ||
74 | * contacting UPnP or NAT-PMP routers on the local network. Use @a | ||
75 | * addr to specify to which of the local host's addresses should the | ||
76 | * external port be mapped. The port is taken from the corresponding | ||
77 | * sockaddr_in[6] field. The NAT module should call the given @a | ||
78 | * address_callback for any 'plausible' external address. | ||
79 | * | ||
80 | * @param cfg configuration to use | ||
81 | * @param proto protocol this is about, IPPROTO_TCP or IPPROTO_UDP | ||
82 | * @param adv_port advertised port (port we are either bound to or that our OS | ||
83 | * locally performs redirection from to our bound port). | ||
84 | * @param num_addrs number of addresses in @a addrs | ||
85 | * @param addrs list of local addresses packets should be redirected to | ||
86 | * @param addrlens actual lengths of the addresses in @a addrs | ||
87 | * @param address_callback function to call everytime the public IP address changes | ||
88 | * @param reversal_callback function to call if someone wants connection reversal from us, | ||
89 | * NULL if connection reversal is not supported | ||
90 | * @param callback_cls closure for callbacks | ||
91 | * @return NULL on error, otherwise handle that can be used to unregister | ||
92 | */ | ||
93 | struct GNUNET_NAT_Handle * | ||
94 | GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
95 | uint8_t proto, | ||
96 | uint16_t adv_port, | ||
97 | unsigned int num_addrs, | ||
98 | const struct sockaddr **addrs, | ||
99 | const socklen_t *addrlens, | ||
100 | GNUNET_NAT_AddressCallback address_callback, | ||
101 | GNUNET_NAT_ReversalCallback reversal_callback, | ||
102 | void *callback_cls) | ||
103 | { | ||
104 | struct GNUNET_NAT_Handle *nh = GNUNET_new (struct GNUNET_NAT_Handle); | ||
105 | |||
106 | nh->cfg = cfg; | ||
107 | nh->address_callback = address_callback; | ||
108 | nh->reversal_callback = reversal_callback; | ||
109 | nh->callback_cls = callback_cls; | ||
110 | GNUNET_break (0); | ||
111 | return nh; | ||
112 | } | ||
113 | |||
114 | |||
115 | /** | ||
116 | * Handle an incoming STUN message. This function is useful as | ||
117 | * some GNUnet service may be listening on a UDP port and might | ||
118 | * thus receive STUN messages while trying to receive other data. | ||
119 | * In this case, this function can be used to act as a proper | ||
120 | * STUN server (if desired). | ||
121 | * | ||
122 | * The function does some basic sanity checks on packet size and | ||
123 | * content, try to extract a bit of information, and possibly replies | ||
124 | * if this is an actual STUN message. | ||
125 | * | ||
126 | * At the moment this only processes BIND requests, and returns the | ||
127 | * externally visible address of the request. | ||
128 | * | ||
129 | * @param nh handle to the NAT service | ||
130 | * @param sender_addr address from which we got @a data | ||
131 | * @param data the packet | ||
132 | * @param data_size number of bytes in @a data | ||
133 | * @return #GNUNET_OK on success | ||
134 | * #GNUNET_NO if the packet is not a STUN packet | ||
135 | * #GNUNET_SYSERR on internal error handling the packet | ||
136 | */ | ||
137 | int | ||
138 | GNUNET_NAT_stun_handle_packet (struct GNUNET_NAT_Handle *nh, | ||
139 | const struct sockaddr *sender_addr, | ||
140 | const void *data, | ||
141 | size_t data_size) | ||
142 | { | ||
143 | GNUNET_break (0); | ||
144 | return GNUNET_SYSERR; | ||
145 | } | ||
146 | |||
147 | |||
148 | /** | ||
149 | * Test if the given address is (currently) a plausible IP address for | ||
150 | * this peer. Mostly a convenience function so that clients do not | ||
151 | * have to explicitly track all IPs that the #GNUNET_NAT_AddressCallback | ||
152 | * has returned so far. | ||
153 | * | ||
154 | * @param nh the handle returned by register | ||
155 | * @param addr IP address to test (IPv4 or IPv6) | ||
156 | * @param addrlen number of bytes in @a addr | ||
157 | * @return #GNUNET_YES if the address is plausible, | ||
158 | * #GNUNET_NO if the address is not plausible, | ||
159 | * #GNUNET_SYSERR if the address is malformed | ||
160 | */ | ||
161 | int | ||
162 | GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *nh, | ||
163 | const void *addr, | ||
164 | socklen_t addrlen) | ||
165 | { | ||
166 | GNUNET_break (0); | ||
167 | return GNUNET_SYSERR; | ||
168 | } | ||
169 | |||
170 | |||
171 | /** | ||
172 | * We learned about a peer (possibly behind NAT) so run the | ||
173 | * gnunet-nat-client to send dummy ICMP responses to cause | ||
174 | * that peer to connect to us (connection reversal). | ||
175 | * | ||
176 | * @param nh handle (used for configuration) | ||
177 | * @param local_sa our local address of the peer (IPv4-only) | ||
178 | * @param remote_sa the remote address of the peer (IPv4-only) | ||
179 | * @return #GNUNET_SYSERR on error, | ||
180 | * #GNUNET_NO if connection reversal is unavailable, | ||
181 | * #GNUNET_OK otherwise (presumably in progress) | ||
182 | */ | ||
183 | int | ||
184 | GNUNET_NAT_request_reversal (struct GNUNET_NAT_Handle *nh, | ||
185 | const struct sockaddr_in *local_sa, | ||
186 | const struct sockaddr_in *remote_sa) | ||
187 | { | ||
188 | GNUNET_break (0); | ||
189 | return GNUNET_SYSERR; | ||
190 | } | ||
191 | |||
192 | |||
193 | /** | ||
194 | * Stop port redirection and public IP address detection for the given | ||
195 | * handle. This frees the handle, after having sent the needed | ||
196 | * commands to close open ports. | ||
197 | * | ||
198 | * @param nh the handle to stop | ||
199 | */ | ||
200 | void | ||
201 | GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *nh) | ||
202 | { | ||
203 | GNUNET_MQ_destroy (nh->mq); | ||
204 | GNUNET_free (nh->reg); | ||
205 | GNUNET_free (nh); | ||
206 | } | ||
207 | |||
208 | |||
209 | /** | ||
210 | * Handle to a NAT test. | ||
211 | */ | ||
212 | struct GNUNET_NAT_Test | ||
213 | { | ||
214 | |||
215 | /** | ||
216 | * Configuration we use. | ||
217 | */ | ||
218 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
219 | |||
220 | /** | ||
221 | * Message queue for communicating with the NAT service. | ||
222 | */ | ||
223 | struct GNUNET_MQ_Handle *mq; | ||
224 | |||
225 | /** | ||
226 | * Function called to report success or failure for | ||
227 | * NAT configuration test. | ||
228 | */ | ||
229 | GNUNET_NAT_TestCallback cb; | ||
230 | |||
231 | /** | ||
232 | * Closure for @e cb. | ||
233 | */ | ||
234 | void *cb_cls; | ||
235 | |||
236 | }; | ||
237 | |||
238 | |||
239 | /** | ||
240 | * Start testing if NAT traversal works using the given configuration | ||
241 | * (IPv4-only). The transport adapters should be down while using | ||
242 | * this function. | ||
243 | * | ||
244 | * @param cfg configuration for the NAT traversal | ||
245 | * @param proto protocol to test, i.e. IPPROTO_TCP or IPPROTO_UDP | ||
246 | * @param bind_ip IPv4 address to bind to | ||
247 | * @param bnd_port port to bind to, 0 to test connection reversal | ||
248 | * @param extern_ip IPv4 address to externally advertise | ||
249 | * @param extern_port externally advertised port to use | ||
250 | * @param report function to call with the result of the test | ||
251 | * @param report_cls closure for @a report | ||
252 | * @return handle to cancel NAT test | ||
253 | */ | ||
254 | struct GNUNET_NAT_Test * | ||
255 | GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
256 | uint8_t proto, | ||
257 | struct in_addr bind_ip, | ||
258 | uint16_t bnd_port, | ||
259 | struct in_addr extern_ip, | ||
260 | uint16_t extern_port, | ||
261 | GNUNET_NAT_TestCallback report, | ||
262 | void *report_cls) | ||
263 | { | ||
264 | struct GNUNET_NAT_Test *tst = GNUNET_new (struct GNUNET_NAT_Test); | ||
265 | |||
266 | tst->cb = report; | ||
267 | tst->cb_cls = report_cls; | ||
268 | GNUNET_break (0); | ||
269 | return tst; | ||
270 | } | ||
271 | |||
272 | |||
273 | /** | ||
274 | * Stop an active NAT test. | ||
275 | * | ||
276 | * @param tst test to stop. | ||
277 | */ | ||
278 | void | ||
279 | GNUNET_NAT_test_stop (struct GNUNET_NAT_Test *tst) | ||
280 | { | ||
281 | GNUNET_break (0); | ||
282 | GNUNET_MQ_destroy (tst->mq); | ||
283 | GNUNET_free (tst); | ||
284 | } | ||
285 | |||
286 | |||
287 | /** | ||
288 | * Handle to auto-configuration in progress. | ||
289 | */ | ||
290 | struct GNUNET_NAT_AutoHandle | ||
291 | { | ||
292 | |||
293 | /** | ||
294 | * Configuration we use. | ||
295 | */ | ||
296 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
297 | |||
298 | /** | ||
299 | * Message queue for communicating with the NAT service. | ||
300 | */ | ||
301 | struct GNUNET_MQ_Handle *mq; | ||
302 | |||
303 | /** | ||
304 | * Function called with the result from the autoconfiguration. | ||
305 | */ | ||
306 | GNUNET_NAT_AutoResultCallback arc; | ||
307 | |||
308 | /** | ||
309 | * Closure for @e arc. | ||
310 | */ | ||
311 | void *arc_cls; | ||
312 | |||
313 | }; | ||
314 | |||
315 | |||
316 | /** | ||
317 | * Converts `enum GNUNET_NAT_StatusCode` to string | ||
318 | * | ||
319 | * @param err error code to resolve to a string | ||
320 | * @return point to a static string containing the error code | ||
321 | */ | ||
322 | const char * | ||
323 | GNUNET_NAT_status2string (enum GNUNET_NAT_StatusCode err) | ||
324 | { | ||
325 | GNUNET_break (0); | ||
326 | return NULL; | ||
327 | } | ||
328 | |||
329 | |||
330 | /** | ||
331 | * Start auto-configuration routine. The transport adapters should | ||
332 | * be stopped while this function is called. | ||
333 | * | ||
334 | * @param cfg initial configuration | ||
335 | * @param cb function to call with autoconfiguration result | ||
336 | * @param cb_cls closure for @a cb | ||
337 | * @return handle to cancel operation | ||
338 | */ | ||
339 | struct GNUNET_NAT_AutoHandle * | ||
340 | GNUNET_NAT_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
341 | GNUNET_NAT_AutoResultCallback cb, | ||
342 | void *cb_cls) | ||
343 | { | ||
344 | struct GNUNET_NAT_AutoHandle *ah = GNUNET_new (struct GNUNET_NAT_AutoHandle); | ||
345 | |||
346 | ah->cfg = cfg; | ||
347 | ah->arc = cb; | ||
348 | ah->arc_cls = cb_cls; | ||
349 | GNUNET_break (0); | ||
350 | return ah; | ||
351 | } | ||
352 | |||
353 | |||
354 | /** | ||
355 | * Abort autoconfiguration. | ||
356 | * | ||
357 | * @param ah handle for operation to abort | ||
358 | */ | ||
359 | void | ||
360 | GNUNET_NAT_autoconfig_cancel (struct GNUNET_NAT_AutoHandle *ah) | ||
361 | { | ||
362 | GNUNET_break (0); | ||
363 | GNUNET_MQ_destroy (ah->mq); | ||
364 | GNUNET_free (ah); | ||
365 | } | ||
366 | |||
367 | /* end of nat_api.c */ | ||