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 | |
parent | 588f820301bf298496e7bf0e6dea7b2c60ab3936 (diff) | |
download | gnunet-10f9bc91ab9d758d0d60dd672206027cd136342a.tar.gz gnunet-10f9bc91ab9d758d0d60dd672206027cd136342a.zip |
new NAT lib client api skeleton
-rw-r--r-- | src/include/gnunet_nat_service.h | 198 | ||||
-rw-r--r-- | src/include/gnunet_protocols.h | 14 | ||||
-rw-r--r-- | src/nat/Makefile.am | 17 | ||||
-rw-r--r-- | src/nat/nat.h | 38 | ||||
-rw-r--r-- | src/nat/nat_api.c | 367 |
5 files changed, 480 insertions, 154 deletions
diff --git a/src/include/gnunet_nat_service.h b/src/include/gnunet_nat_service.h index 5ac936065..28a6bc59f 100644 --- a/src/include/gnunet_nat_service.h +++ b/src/include/gnunet_nat_service.h | |||
@@ -108,7 +108,8 @@ enum GNUNET_NAT_AddressClass | |||
108 | * a function to call whenever our set of 'valid' addresses changes. | 108 | * a function to call whenever our set of 'valid' addresses changes. |
109 | * | 109 | * |
110 | * @param cls closure | 110 | * @param cls closure |
111 | * @param add_remove #GNUNET_YES to add a new public IP address, #GNUNET_NO to remove a previous (now invalid) one | 111 | * @param add_remove #GNUNET_YES to add a new public IP address, |
112 | * #GNUNET_NO to remove a previous (now invalid) one | ||
112 | * @param ac address class the address belongs to | 113 | * @param ac address class the address belongs to |
113 | * @param addr either the previous or the new public IP address | 114 | * @param addr either the previous or the new public IP address |
114 | * @param addrlen actual length of the @a addr | 115 | * @param addrlen actual length of the @a addr |
@@ -137,24 +138,6 @@ typedef void | |||
137 | 138 | ||
138 | 139 | ||
139 | /** | 140 | /** |
140 | * Signature of a callback that is given an IPv4 address | ||
141 | * which is now presumably a global IPv4 address under which | ||
142 | * this peer is visible (external IP address of our NAT). | ||
143 | * Note that the NAT may not have punched holes, so it is | ||
144 | * possible that while this is "our" IPv4 address, it still | ||
145 | * does not work for receiving traffic. | ||
146 | * | ||
147 | * @param cls closure | ||
148 | * @param add_remove #GNUNET_YES to add a new public IP address, #GNUNET_NO to remove a previous (now invalid) one | ||
149 | * @param addr the address to add or remove | ||
150 | */ | ||
151 | typedef void | ||
152 | (*GNUNET_NAT_IPv4Callback) (void *cls, | ||
153 | int add_remove, | ||
154 | const struct in_addr *addr); | ||
155 | |||
156 | |||
157 | /** | ||
158 | * Handle for active NAT registrations. | 141 | * Handle for active NAT registrations. |
159 | */ | 142 | */ |
160 | struct GNUNET_NAT_Handle; | 143 | struct GNUNET_NAT_Handle; |
@@ -175,7 +158,6 @@ struct GNUNET_NAT_Handle; | |||
175 | * @param num_addrs number of addresses in @a addrs | 158 | * @param num_addrs number of addresses in @a addrs |
176 | * @param addrs list of local addresses packets should be redirected to | 159 | * @param addrs list of local addresses packets should be redirected to |
177 | * @param addrlens actual lengths of the addresses in @a addrs | 160 | * @param addrlens actual lengths of the addresses in @a addrs |
178 | * @param ip_callback function to call whenever our (external) IPv4 address changes (or becomes known) | ||
179 | * @param address_callback function to call everytime the public IP address changes | 161 | * @param address_callback function to call everytime the public IP address changes |
180 | * @param reversal_callback function to call if someone wants connection reversal from us, | 162 | * @param reversal_callback function to call if someone wants connection reversal from us, |
181 | * NULL if connection reversal is not supported | 163 | * NULL if connection reversal is not supported |
@@ -184,12 +166,11 @@ struct GNUNET_NAT_Handle; | |||
184 | */ | 166 | */ |
185 | struct GNUNET_NAT_Handle * | 167 | struct GNUNET_NAT_Handle * |
186 | GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | 168 | GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, |
187 | int proto, | 169 | uint8_t proto, |
188 | uint16_t adv_port, | 170 | uint16_t adv_port, |
189 | unsigned int num_addrs, | 171 | unsigned int num_addrs, |
190 | const struct sockaddr **addrs, | 172 | const struct sockaddr **addrs, |
191 | const socklen_t *addrlens, | 173 | const socklen_t *addrlens, |
192 | GNUNET_NAT_IPv4Callback ip_callback, | ||
193 | GNUNET_NAT_AddressCallback address_callback, | 174 | GNUNET_NAT_AddressCallback address_callback, |
194 | GNUNET_NAT_ReversalCallback reversal_callback, | 175 | GNUNET_NAT_ReversalCallback reversal_callback, |
195 | void *callback_cls); | 176 | void *callback_cls); |
@@ -209,7 +190,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
209 | * At the moment this only processes BIND requests, and returns the | 190 | * At the moment this only processes BIND requests, and returns the |
210 | * externally visible address of the request. | 191 | * externally visible address of the request. |
211 | * | 192 | * |
212 | * @param nat handle to the NAT service | 193 | * @param nh handle to the NAT service |
213 | * @param sender_addr address from which we got @a data | 194 | * @param sender_addr address from which we got @a data |
214 | * @param data the packet | 195 | * @param data the packet |
215 | * @param data_size number of bytes in @a data | 196 | * @param data_size number of bytes in @a data |
@@ -218,7 +199,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
218 | * #GNUNET_SYSERR on internal error handling the packet | 199 | * #GNUNET_SYSERR on internal error handling the packet |
219 | */ | 200 | */ |
220 | int | 201 | int |
221 | GNUNET_NAT_stun_handle_packet (struct GNUNET_NAT_Handle *nat, | 202 | GNUNET_NAT_stun_handle_packet (struct GNUNET_NAT_Handle *nh, |
222 | const struct sockaddr *sender_addr, | 203 | const struct sockaddr *sender_addr, |
223 | const void *data, | 204 | const void *data, |
224 | size_t data_size); | 205 | size_t data_size); |
@@ -230,7 +211,7 @@ GNUNET_NAT_stun_handle_packet (struct GNUNET_NAT_Handle *nat, | |||
230 | * have to explicitly track all IPs that the #GNUNET_NAT_AddressCallback | 211 | * have to explicitly track all IPs that the #GNUNET_NAT_AddressCallback |
231 | * has returned so far. | 212 | * has returned so far. |
232 | * | 213 | * |
233 | * @param h the handle returned by register | 214 | * @param nh the handle returned by register |
234 | * @param addr IP address to test (IPv4 or IPv6) | 215 | * @param addr IP address to test (IPv4 or IPv6) |
235 | * @param addrlen number of bytes in @a addr | 216 | * @param addrlen number of bytes in @a addr |
236 | * @return #GNUNET_YES if the address is plausible, | 217 | * @return #GNUNET_YES if the address is plausible, |
@@ -238,7 +219,7 @@ GNUNET_NAT_stun_handle_packet (struct GNUNET_NAT_Handle *nat, | |||
238 | * #GNUNET_SYSERR if the address is malformed | 219 | * #GNUNET_SYSERR if the address is malformed |
239 | */ | 220 | */ |
240 | int | 221 | int |
241 | GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h, | 222 | GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *nh, |
242 | const void *addr, | 223 | const void *addr, |
243 | socklen_t addrlen); | 224 | socklen_t addrlen); |
244 | 225 | ||
@@ -248,7 +229,7 @@ GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h, | |||
248 | * gnunet-nat-client to send dummy ICMP responses to cause | 229 | * gnunet-nat-client to send dummy ICMP responses to cause |
249 | * that peer to connect to us (connection reversal). | 230 | * that peer to connect to us (connection reversal). |
250 | * | 231 | * |
251 | * @param h handle (used for configuration) | 232 | * @param nh handle (used for configuration) |
252 | * @param local_sa our local address of the peer (IPv4-only) | 233 | * @param local_sa our local address of the peer (IPv4-only) |
253 | * @param remote_sa the remote address of the peer (IPv4-only) | 234 | * @param remote_sa the remote address of the peer (IPv4-only) |
254 | * @return #GNUNET_SYSERR on error, | 235 | * @return #GNUNET_SYSERR on error, |
@@ -256,7 +237,7 @@ GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h, | |||
256 | * #GNUNET_OK otherwise (presumably in progress) | 237 | * #GNUNET_OK otherwise (presumably in progress) |
257 | */ | 238 | */ |
258 | int | 239 | int |
259 | GNUNET_NAT_request_reversal (struct GNUNET_NAT_Handle *h, | 240 | GNUNET_NAT_request_reversal (struct GNUNET_NAT_Handle *nh, |
260 | const struct sockaddr_in *local_sa, | 241 | const struct sockaddr_in *local_sa, |
261 | const struct sockaddr_in *remote_sa); | 242 | const struct sockaddr_in *remote_sa); |
262 | 243 | ||
@@ -266,10 +247,10 @@ GNUNET_NAT_request_reversal (struct GNUNET_NAT_Handle *h, | |||
266 | * handle. This frees the handle, after having sent the needed | 247 | * handle. This frees the handle, after having sent the needed |
267 | * commands to close open ports. | 248 | * commands to close open ports. |
268 | * | 249 | * |
269 | * @param h the handle to stop | 250 | * @param nh the handle to unregister |
270 | */ | 251 | */ |
271 | void | 252 | void |
272 | GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h); | 253 | GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *nh); |
273 | 254 | ||
274 | 255 | ||
275 | /** | 256 | /** |
@@ -279,82 +260,6 @@ struct GNUNET_NAT_Test; | |||
279 | 260 | ||
280 | 261 | ||
281 | /** | 262 | /** |
282 | * Function called to report success or failure for | ||
283 | * NAT configuration test. | ||
284 | * | ||
285 | * @param cls closure | ||
286 | * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code | ||
287 | */ | ||
288 | typedef void | ||
289 | (*GNUNET_NAT_TestCallback) (void *cls, | ||
290 | enum GNUNET_NAT_StatusCode result); | ||
291 | |||
292 | |||
293 | /** | ||
294 | * Start testing if NAT traversal works using the given configuration | ||
295 | * (IPv4-only). The transport adapters should be down while using | ||
296 | * this function. | ||
297 | * | ||
298 | * @param cfg configuration for the NAT traversal | ||
299 | * @param proto protocol to test, i.e. IPPROTO_TCP or IPPROTO_UDP | ||
300 | * @param bnd_port port to bind to, 0 to test connection reversal | ||
301 | * @param adv_port externally advertised port to use | ||
302 | * @param report function to call with the result of the test | ||
303 | * @param report_cls closure for @a report | ||
304 | * @return handle to cancel NAT test | ||
305 | */ | ||
306 | struct GNUNET_NAT_Test * | ||
307 | GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
308 | int proto, | ||
309 | uint16_t bnd_port, | ||
310 | uint16_t adv_port, | ||
311 | GNUNET_NAT_TestCallback report, | ||
312 | void *report_cls); | ||
313 | |||
314 | |||
315 | /** | ||
316 | * Stop an active NAT test. | ||
317 | * | ||
318 | * @param tst test to stop. | ||
319 | */ | ||
320 | void | ||
321 | GNUNET_NAT_test_stop (struct GNUNET_NAT_Test *tst); | ||
322 | |||
323 | |||
324 | /** | ||
325 | * Handle to auto-configuration in progress. | ||
326 | */ | ||
327 | struct GNUNET_NAT_AutoHandle; | ||
328 | |||
329 | |||
330 | /** | ||
331 | * What the situation of the NAT connectivity | ||
332 | */ | ||
333 | enum GNUNET_NAT_Type | ||
334 | { | ||
335 | /** | ||
336 | * We have a direct connection | ||
337 | */ | ||
338 | GNUNET_NAT_TYPE_NO_NAT = GNUNET_OK, | ||
339 | |||
340 | /** | ||
341 | * We are under a NAT but cannot traverse it | ||
342 | */ | ||
343 | GNUNET_NAT_TYPE_UNREACHABLE_NAT, | ||
344 | |||
345 | /** | ||
346 | * We can traverse using STUN | ||
347 | */ | ||
348 | GNUNET_NAT_TYPE_STUN_PUNCHED_NAT, | ||
349 | |||
350 | /** | ||
351 | * WE can traverse using UPNP | ||
352 | */ | ||
353 | GNUNET_NAT_TYPE_UPNP_NAT | ||
354 | |||
355 | }; | ||
356 | |||
357 | /** | ||
358 | * Error Types for the NAT subsystem (which can then later be converted/resolved to a string) | 263 | * Error Types for the NAT subsystem (which can then later be converted/resolved to a string) |
359 | */ | 264 | */ |
360 | enum GNUNET_NAT_StatusCode | 265 | enum GNUNET_NAT_StatusCode |
@@ -458,6 +363,87 @@ enum GNUNET_NAT_StatusCode | |||
458 | 363 | ||
459 | 364 | ||
460 | /** | 365 | /** |
366 | * Function called to report success or failure for | ||
367 | * NAT configuration test. | ||
368 | * | ||
369 | * @param cls closure | ||
370 | * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code | ||
371 | */ | ||
372 | typedef void | ||
373 | (*GNUNET_NAT_TestCallback) (void *cls, | ||
374 | enum GNUNET_NAT_StatusCode result); | ||
375 | |||
376 | |||
377 | /** | ||
378 | * Start testing if NAT traversal works using the given configuration | ||
379 | * (IPv4-only). The transport adapters should be down while using | ||
380 | * this function. | ||
381 | * | ||
382 | * @param cfg configuration for the NAT traversal | ||
383 | * @param proto protocol to test, i.e. IPPROTO_TCP or IPPROTO_UDP | ||
384 | * @param bind_ip IPv4 address to bind to | ||
385 | * @param bnd_port port to bind to, 0 to test connection reversal | ||
386 | * @param extern_ip IPv4 address to externally advertise | ||
387 | * @param extern_port externally advertised port to use | ||
388 | * @param report function to call with the result of the test | ||
389 | * @param report_cls closure for @a report | ||
390 | * @return handle to cancel NAT test | ||
391 | */ | ||
392 | struct GNUNET_NAT_Test * | ||
393 | GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
394 | uint8_t proto, | ||
395 | struct in_addr bind_ip, | ||
396 | uint16_t bnd_port, | ||
397 | struct in_addr extern_ip, | ||
398 | uint16_t extern_port, | ||
399 | GNUNET_NAT_TestCallback report, | ||
400 | void *report_cls); | ||
401 | |||
402 | |||
403 | /** | ||
404 | * Stop an active NAT test. | ||
405 | * | ||
406 | * @param tst test to stop. | ||
407 | */ | ||
408 | void | ||
409 | GNUNET_NAT_test_stop (struct GNUNET_NAT_Test *tst); | ||
410 | |||
411 | |||
412 | /** | ||
413 | * Handle to auto-configuration in progress. | ||
414 | */ | ||
415 | struct GNUNET_NAT_AutoHandle; | ||
416 | |||
417 | |||
418 | /** | ||
419 | * What the situation of the NAT connectivity | ||
420 | */ | ||
421 | enum GNUNET_NAT_Type | ||
422 | { | ||
423 | /** | ||
424 | * We have a direct connection | ||
425 | */ | ||
426 | GNUNET_NAT_TYPE_NO_NAT = GNUNET_OK, | ||
427 | |||
428 | /** | ||
429 | * We are under a NAT but cannot traverse it | ||
430 | */ | ||
431 | GNUNET_NAT_TYPE_UNREACHABLE_NAT, | ||
432 | |||
433 | /** | ||
434 | * We can traverse using STUN | ||
435 | */ | ||
436 | GNUNET_NAT_TYPE_STUN_PUNCHED_NAT, | ||
437 | |||
438 | /** | ||
439 | * WE can traverse using UPNP | ||
440 | */ | ||
441 | GNUNET_NAT_TYPE_UPNP_NAT | ||
442 | |||
443 | }; | ||
444 | |||
445 | |||
446 | /** | ||
461 | * Converts `enum GNUNET_NAT_StatusCode` to string | 447 | * Converts `enum GNUNET_NAT_StatusCode` to string |
462 | * | 448 | * |
463 | * @param err error code to resolve to a string | 449 | * @param err error code to resolve to a string |
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index aeb55f99f..ea94645c5 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -2810,30 +2810,24 @@ extern "C" | |||
2810 | #define GNUNET_MESSAGE_TYPE_NAT_ADDRESS_CHANGE 1064 | 2810 | #define GNUNET_MESSAGE_TYPE_NAT_ADDRESS_CHANGE 1064 |
2811 | 2811 | ||
2812 | /** | 2812 | /** |
2813 | * Message to from NAT service notifying us that one of our | ||
2814 | * "global" IPv4 addresses changed. | ||
2815 | */ | ||
2816 | #define GNUNET_MESSAGE_TYPE_NAT_IPV4_CHANGE 1065 | ||
2817 | |||
2818 | /** | ||
2819 | * Message to ask NAT service to test an address. | 2813 | * Message to ask NAT service to test an address. |
2820 | */ | 2814 | */ |
2821 | #define GNUNET_MESSAGE_TYPE_NAT_REQUEST_TEST 1066 | 2815 | #define GNUNET_MESSAGE_TYPE_NAT_REQUEST_TEST 1065 |
2822 | 2816 | ||
2823 | /** | 2817 | /** |
2824 | * Message from NAT service with the address test result. | 2818 | * Message from NAT service with the address test result. |
2825 | */ | 2819 | */ |
2826 | #define GNUNET_MESSAGE_TYPE_NAT_TEST_RESULT 1067 | 2820 | #define GNUNET_MESSAGE_TYPE_NAT_TEST_RESULT 1066 |
2827 | 2821 | ||
2828 | /** | 2822 | /** |
2829 | * Message to ask NAT service to request autoconfiguration. | 2823 | * Message to ask NAT service to request autoconfiguration. |
2830 | */ | 2824 | */ |
2831 | #define GNUNET_MESSAGE_TYPE_NAT_REQUEST_AUTO_CFG 1068 | 2825 | #define GNUNET_MESSAGE_TYPE_NAT_REQUEST_AUTO_CFG 1067 |
2832 | 2826 | ||
2833 | /** | 2827 | /** |
2834 | * Message from NAT service with the autoconfiguration result. | 2828 | * Message from NAT service with the autoconfiguration result. |
2835 | */ | 2829 | */ |
2836 | #define GNUNET_MESSAGE_TYPE_NAT_AUTO_CFG_RESULT 1069 | 2830 | #define GNUNET_MESSAGE_TYPE_NAT_AUTO_CFG_RESULT 1068 |
2837 | 2831 | ||
2838 | 2832 | ||
2839 | /** | 2833 | /** |
diff --git a/src/nat/Makefile.am b/src/nat/Makefile.am index 5e89ac24d..e4b013916 100644 --- a/src/nat/Makefile.am +++ b/src/nat/Makefile.am | |||
@@ -52,7 +52,7 @@ gnunet_helper_nat_server_SOURCES = \ | |||
52 | gnunet_helper_nat_client_SOURCES = \ | 52 | gnunet_helper_nat_client_SOURCES = \ |
53 | $(NATCLIENT) | 53 | $(NATCLIENT) |
54 | 54 | ||
55 | 55 | ||
56 | gnunet_nat_SOURCES = \ | 56 | gnunet_nat_SOURCES = \ |
57 | gnunet-nat.c nat.h | 57 | gnunet-nat.c nat.h |
58 | gnunet_nat_LDADD = \ | 58 | gnunet_nat_LDADD = \ |
@@ -64,7 +64,9 @@ if USE_COVERAGE | |||
64 | AM_CFLAGS = -fprofile-arcs -ftest-coverage | 64 | AM_CFLAGS = -fprofile-arcs -ftest-coverage |
65 | endif | 65 | endif |
66 | 66 | ||
67 | lib_LTLIBRARIES = libgnunetnat.la | 67 | lib_LTLIBRARIES = \ |
68 | libgnunetnat.la \ | ||
69 | libgnunetnatnew.la | ||
68 | 70 | ||
69 | libgnunetnat_la_SOURCES = \ | 71 | libgnunetnat_la_SOURCES = \ |
70 | nat.c nat.h \ | 72 | nat.c nat.h \ |
@@ -72,15 +74,22 @@ libgnunetnat_la_SOURCES = \ | |||
72 | nat_test.c \ | 74 | nat_test.c \ |
73 | nat_mini.c \ | 75 | nat_mini.c \ |
74 | nat_stun.c | 76 | nat_stun.c |
75 | |||
76 | libgnunetnat_la_LIBADD = \ | 77 | libgnunetnat_la_LIBADD = \ |
77 | $(top_builddir)/src/util/libgnunetutil.la \ | 78 | $(top_builddir)/src/util/libgnunetutil.la \ |
78 | $(GN_LIBINTL) @EXT_LIBS@ | 79 | $(GN_LIBINTL) @EXT_LIBS@ |
79 | |||
80 | libgnunetnat_la_LDFLAGS = \ | 80 | libgnunetnat_la_LDFLAGS = \ |
81 | $(GN_LIB_LDFLAGS) $(WINFLAGS) \ | 81 | $(GN_LIB_LDFLAGS) $(WINFLAGS) \ |
82 | -version-info 1:1:1 | 82 | -version-info 1:1:1 |
83 | 83 | ||
84 | libgnunetnatnew_la_SOURCES = \ | ||
85 | nat_api.c nat.h | ||
86 | libgnunetnatnew_la_LIBADD = \ | ||
87 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
88 | $(GN_LIBINTL) @EXT_LIBS@ | ||
89 | libgnunetnatnew_la_LDFLAGS = \ | ||
90 | $(GN_LIB_LDFLAGS) $(WINFLAGS) \ | ||
91 | -version-info 2:0:0 | ||
92 | |||
84 | check_PROGRAMS = \ | 93 | check_PROGRAMS = \ |
85 | test_nat \ | 94 | test_nat \ |
86 | test_nat_mini \ | 95 | test_nat_mini \ |
diff --git a/src/nat/nat.h b/src/nat/nat.h index 9ab402c1d..debe011ef 100644 --- a/src/nat/nat.h +++ b/src/nat/nat.h | |||
@@ -77,21 +77,15 @@ enum GNUNET_NAT_RegisterFlags | |||
77 | GNUNET_NAT_RF_NONE = 0, | 77 | GNUNET_NAT_RF_NONE = 0, |
78 | 78 | ||
79 | /** | 79 | /** |
80 | * This client wants to be informed about our IPv4 address | ||
81 | * changing. | ||
82 | */ | ||
83 | GNUNET_NAT_RF_IPV4 = 1, | ||
84 | |||
85 | /** | ||
86 | * This client wants to be informed about changes to our | 80 | * This client wants to be informed about changes to our |
87 | * external addresses. | 81 | * external addresses. |
88 | */ | 82 | */ |
89 | GNUNET_NAT_RF_ADDRESSES = 2, | 83 | GNUNET_NAT_RF_ADDRESSES = 1, |
90 | 84 | ||
91 | /** | 85 | /** |
92 | * This client supports address reversal. | 86 | * This client supports address reversal. |
93 | */ | 87 | */ |
94 | GNUNET_NAT_RF_REVERSAL = 4 | 88 | GNUNET_NAT_RF_REVERSAL = 2 |
95 | }; | 89 | }; |
96 | 90 | ||
97 | 91 | ||
@@ -108,12 +102,12 @@ struct GNUNET_NAT_RegisterMessage | |||
108 | /** | 102 | /** |
109 | * An `enum GNUNET_NAT_RegisterFlags`. | 103 | * An `enum GNUNET_NAT_RegisterFlags`. |
110 | */ | 104 | */ |
111 | uint8_t flags GNUNET_PACKED; | 105 | uint8_t flags; |
112 | 106 | ||
113 | /** | 107 | /** |
114 | * Client's IPPROTO, e.g. IPPROTO_UDP or IPPROTO_TCP. | 108 | * Client's IPPROTO, e.g. IPPROTO_UDP or IPPROTO_TCP. |
115 | */ | 109 | */ |
116 | uint8_t proto GNUNET_PACKED; | 110 | uint8_t proto; |
117 | 111 | ||
118 | /** | 112 | /** |
119 | * Port we would like as we are configured to use this one for | 113 | * Port we would like as we are configured to use this one for |
@@ -236,30 +230,6 @@ struct GNUNET_NAT_AddressChangeNotificationMessage | |||
236 | 230 | ||
237 | 231 | ||
238 | /** | 232 | /** |
239 | * Service notifying the client about a change of our | ||
240 | * known external IPv4 address. | ||
241 | */ | ||
242 | struct GNUNET_NAT_Ipv4ChangeNotificationMessage | ||
243 | { | ||
244 | /** | ||
245 | * Header with type #GNUNET_MESSAGE_TYPE_NAT_IPV4_CHANGE | ||
246 | */ | ||
247 | struct GNUNET_MessageHeader header; | ||
248 | |||
249 | /** | ||
250 | * #GNUNET_YES to add, #GNUNET_NO to remove the address from the list. | ||
251 | */ | ||
252 | int32_t add_remove GNUNET_PACKED; | ||
253 | |||
254 | /** | ||
255 | * IPv4 address affected. | ||
256 | */ | ||
257 | struct in_addr addr GNUNET_PACKED; | ||
258 | |||
259 | }; | ||
260 | |||
261 | |||
262 | /** | ||
263 | * Client requesting test of network connectivity. | 233 | * Client requesting test of network connectivity. |
264 | */ | 234 | */ |
265 | struct GNUNET_NAT_RequestTestMessage | 235 | struct GNUNET_NAT_RequestTestMessage |
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 */ | ||