2 This file is part of GNUnet.
3 Copyright (C) 2007-2014 Christian Grothoff (and other contributing authors)
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.
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.
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.
22 * @author Christian Grothoff
23 * @author Milan Bouchet-Valat
26 * Library handling UPnP and NAT-PMP port forwarding
27 * and external IP address retrieval
29 * @defgroup nat NAT library
30 * Library handling UPnP and NAT-PMP port forwarding
31 * and external IP address retrieval
36 #ifndef GNUNET_NAT_LIB_H
37 #define GNUNET_NAT_LIB_H
39 #include "gnunet_util_lib.h"
43 * Signature of the callback passed to #GNUNET_NAT_register() for
44 * a function to call whenever our set of 'valid' addresses changes.
47 * @param add_remove #GNUNET_YES to mean the new public IP address, #GNUNET_NO to mean
48 * the previous (now invalid) one
49 * @param addr either the previous or the new public IP address
50 * @param addrlen actual length of the @a addr
53 (*GNUNET_NAT_AddressCallback) (void *cls,
55 const struct sockaddr *addr,
60 * Signature of the callback passed to #GNUNET_NAT_register().
61 * for a function to call whenever someone asks us to do connection
65 * @param addr public IP address of the other peer
66 * @param addrlen actual lenght of the @a addr
69 (*GNUNET_NAT_ReversalCallback) (void *cls,
70 const struct sockaddr *addr,
75 * Handle for active NAT registrations.
77 struct GNUNET_NAT_Handle;
82 * What the situation of the NAT connectivity
87 * We have a direct connection
89 GNUNET_NAT_TYPE_NO_NAT = GNUNET_OK,
92 * We are under a NAT but cannot traverse it
94 GNUNET_NAT_TYPE_UNREACHABLE_NAT,
97 * We can traverse using STUN
99 GNUNET_NAT_TYPE_STUN_PUNCHED_NAT,
102 * WE can traverse using UPNP
104 GNUNET_NAT_TYPE_UPNP_NAT
109 * Error Types for the NAT subsystem (which can then later be converted/resolved to a string)
111 enum GNUNET_NAT_StatusCode
116 GNUNET_NAT_ERROR_SUCCESS = GNUNET_OK,
121 GNUNET_NAT_ERROR_IPC_FAILURE,
124 * Failure in network subsystem, check permissions
126 GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR,
131 GNUNET_NAT_ERROR_TIMEOUT,
134 * detected that we are offline
136 GNUNET_NAT_ERROR_NOT_ONLINE,
139 * `upnpc` command not found
141 GNUNET_NAT_ERROR_UPNPC_NOT_FOUND,
144 * Failed to run `upnpc` command
146 GNUNET_NAT_ERROR_UPNPC_FAILED,
149 * `upnpc' command took too long, process killed
151 GNUNET_NAT_ERROR_UPNPC_TIMEOUT,
154 * `upnpc' command failed to establish port mapping
156 GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED,
159 * `external-ip' command not found
161 GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND,
164 * Failed to run `external-ip` command
166 GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED,
169 * `external-ip' command output invalid
171 GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID,
174 * "no valid address was returned by `external-ip'"
176 GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID,
179 * Could not determine interface with internal/local network address
181 GNUNET_NAT_ERROR_NO_VALID_IF_IP_COMBO,
184 * No working gnunet-helper-nat-server found
186 GNUNET_NAT_ERROR_HELPER_NAT_SERVER_NOT_FOUND,
189 * NAT test could not be initialized
191 GNUNET_NAT_ERROR_NAT_TEST_START_FAILED,
196 GNUNET_NAT_ERROR_NAT_TEST_TIMEOUT,
199 * NAT test failed to initiate
201 GNUNET_NAT_ERROR_NAT_REGISTER_FAILED,
206 GNUNET_NAT_ERROR_HELPER_NAT_CLIENT_NOT_FOUND,
216 * Converts `enum GNUNET_NAT_StatusCode` to string
218 * @param err error code to resolve to a string
219 * @return point to a static string containing the error code
222 GNUNET_NAT_status2string (enum GNUNET_NAT_StatusCode err);
226 * Attempt to enable port redirection and detect public IP address
227 * contacting UPnP or NAT-PMP routers on the local network. Use addr
228 * to specify to which of the local host's addresses should the
229 * external port be mapped. The port is taken from the corresponding
230 * sockaddr_in[6] field. The NAT module should call the given
231 * callback for any 'plausible' external address.
233 * @param cfg configuration to use
234 * @param is_tcp #GNUNET_YES for TCP, #GNUNET_NO for UDP
235 * @param adv_port advertised port (port we are either bound to or that our OS
236 * locally performs redirection from to our bound port).
237 * @param num_addrs number of addresses in @a addrs
238 * @param addrs list of local addresses packets should be redirected to
239 * @param addrlens actual lengths of the addresses in @a addrs
240 * @param address_callback function to call everytime the public IP address changes
241 * @param reversal_callback function to call if someone wants connection reversal from us,
242 * NULL if connection reversal is not supported
243 * @param callback_cls closure for callbacks
244 * @return NULL on error, otherwise handle that can be used to unregister
246 struct GNUNET_NAT_Handle *
247 GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
250 unsigned int num_addrs,
251 const struct sockaddr **addrs,
252 const socklen_t *addrlens,
253 GNUNET_NAT_AddressCallback address_callback,
254 GNUNET_NAT_ReversalCallback reversal_callback,
256 struct GNUNET_NETWORK_Handle* sock);
260 * Test if the given address is (currently) a plausible IP address for
263 * @param h the handle returned by register
264 * @param addr IP address to test (IPv4 or IPv6)
265 * @param addrlen number of bytes in @a addr
266 * @return #GNUNET_YES if the address is plausible,
267 * #GNUNET_NO if the address is not plausible,
268 * #GNUNET_SYSERR if the address is malformed
271 GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h,
277 * We learned about a peer (possibly behind NAT) so run the
278 * gnunet-nat-client to send dummy ICMP responses to cause
279 * that peer to connect to us (connection reversal).
281 * @param h handle (used for configuration)
282 * @param sa the address of the peer (IPv4-only)
283 * @return #GNUNET_SYSERR on error, #GNUNET_NO if nat client is disabled,
284 * #GNUNET_OK otherwise
287 GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h,
288 const struct sockaddr_in *sa);
292 * Stop port redirection and public IP address detection for the given
293 * handle. This frees the handle, after having sent the needed
294 * commands to close open ports.
296 * @param h the handle to stop
299 GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h);
303 * Handle to a NAT test.
305 struct GNUNET_NAT_Test;
309 * Function called to report success or failure for
310 * NAT configuration test.
313 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
315 typedef void (*GNUNET_NAT_TestCallback) (void *cls,
316 enum GNUNET_NAT_StatusCode result);
320 * Start testing if NAT traversal works using the
321 * given configuration (IPv4-only).
323 * @param cfg configuration for the NAT traversal
324 * @param is_tcp #GNUNET_YES to test TCP, #GNUNET_NO to test UDP
325 * @param bnd_port port to bind to, 0 for connection reversal
326 * @param adv_port externally advertised port to use
327 * @param timeout delay after which the test should be aborted
328 * @param report function to call with the result of the test;
329 * you still must call #GNUNET_NAT_test_stop().
330 * @param report_cls closure for @a report
331 * @return handle to cancel NAT test
333 struct GNUNET_NAT_Test *
334 GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
338 struct GNUNET_TIME_Relative timeout,
339 GNUNET_NAT_TestCallback report,
344 * Stop an active NAT test.
346 * @param tst test to stop.
349 GNUNET_NAT_test_stop (struct GNUNET_NAT_Test *tst);
353 * Signature of a callback that is given an IP address.
356 * @param addr the address, NULL on errors
357 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
360 (*GNUNET_NAT_IPCallback) (void *cls,
361 const struct in_addr *addr,
362 enum GNUNET_NAT_StatusCode result);
366 * Opaque handle to cancel #GNUNET_NAT_mini_get_external_ipv4() operation.
368 struct GNUNET_NAT_ExternalHandle;
372 * Try to get the external IPv4 address of this peer.
374 * @param timeout when to fail
375 * @param cb function to call with result
376 * @param cb_cls closure for @a cb
377 * @return handle for cancellation (can only be used until @a cb is called), NULL on error
379 struct GNUNET_NAT_ExternalHandle *
380 GNUNET_NAT_mini_get_external_ipv4 (struct GNUNET_TIME_Relative timeout,
381 GNUNET_NAT_IPCallback cb,
388 * @param eh operation to cancel
391 GNUNET_NAT_mini_get_external_ipv4_cancel (struct GNUNET_NAT_ExternalHandle *eh);
395 * Handle to a mapping created with upnpc.
397 struct GNUNET_NAT_MiniHandle;
401 * Signature of the callback passed to #GNUNET_NAT_register() for
402 * a function to call whenever our set of 'valid' addresses changes.
405 * @param add_remove #GNUNET_YES to mean the new public IP address, #GNUNET_NO to mean
406 * the previous (now invalid) one, #GNUNET_SYSERR indicates an error
407 * @param addr either the previous or the new public IP address
408 * @param addrlen actual length of the @a addr
409 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
412 (*GNUNET_NAT_MiniAddressCallback) (void *cls,
414 const struct sockaddr *addr,
416 enum GNUNET_NAT_StatusCode result);
420 * Start mapping the given port using (mini)upnpc. This function
421 * should typically not be used directly (it is used within the
422 * general-purpose #GNUNET_NAT_register() code). However, it can be
423 * used if specifically UPnP-based NAT traversal is to be used or
426 * @param port port to map
427 * @param is_tcp #GNUNET_YES to map TCP, #GNUNET_NO for UDP
428 * @param ac function to call with mapping result
429 * @param ac_cls closure for @a ac
430 * @return NULL on error
432 struct GNUNET_NAT_MiniHandle *
433 GNUNET_NAT_mini_map_start (uint16_t port,
435 GNUNET_NAT_MiniAddressCallback ac,
440 * Remove a mapping created with (mini)upnpc. Calling
441 * this function will give 'upnpc' 1s to remove the mapping,
442 * so while this function is non-blocking, a task will be
443 * left with the scheduler for up to 1s past this call.
445 * @param mini the handle
448 GNUNET_NAT_mini_map_stop (struct GNUNET_NAT_MiniHandle *mini);
452 * Handle to auto-configuration in progress.
454 struct GNUNET_NAT_AutoHandle;
458 * Function called with the result from the autoconfiguration.
461 * @param diff minimal suggested changes to the original configuration
462 * to make it work (as best as we can)
463 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
464 * @param type what the situation of the NAT
467 (*GNUNET_NAT_AutoResultCallback)(void *cls,
468 const struct GNUNET_CONFIGURATION_Handle *diff,
469 enum GNUNET_NAT_StatusCode result,
470 enum GNUNET_NAT_Type type);
474 * Start auto-configuration routine. The resolver service should
475 * be available when this function is called.
477 * @param cfg initial configuration
478 * @param cb function to call with autoconfiguration result
479 * @param cb_cls closure for @a cb
480 * @return handle to cancel operation
482 struct GNUNET_NAT_AutoHandle *
483 GNUNET_NAT_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
484 GNUNET_NAT_AutoResultCallback cb,
489 * Abort autoconfiguration.
491 * @param ah handle for operation to abort
494 GNUNET_NAT_autoconfig_cancel (struct GNUNET_NAT_AutoHandle *ah);
497 * Handle for active STUN Requests.
499 struct GNUNET_NAT_STUN_Handle;
503 * Function called with the result if an error happened during STUN request.
506 * @param result the specific error code
509 (*GNUNET_NAT_STUN_ErrorCallback)(void *cls,
510 enum GNUNET_NAT_StatusCode error);
514 * Handle to a request given to the resolver. Can be used to cancel
515 * the request prior to the timeout or successful execution. Also
516 * used to track our internal state for the request.
518 struct GNUNET_NAT_STUN_Handle;
522 * Make generic STUN request. Sends a generic stun request to the
523 * server specified using the specified socket. The caller must
524 * wait for a reply on the @a sock and call
525 * #GNUNET_NAT_stun_handle_packet() if a reply is received.
527 * @param server the address of the stun server
528 * @param port port of the stun server
529 * @param sock the socket used to send the request
530 * @param cb callback in case of error (or completion)
531 * @param cb_cls closure for @a cb
532 * @return NULL on error
534 struct GNUNET_NAT_STUN_Handle *
535 GNUNET_NAT_stun_make_request (const char *server,
537 struct GNUNET_NETWORK_Handle *sock,
538 GNUNET_NAT_STUN_ErrorCallback cb,
543 * Cancel active STUN request. Frees associated resources
544 * and ensures that the callback is no longer invoked.
546 * @param rh request to cancel
549 GNUNET_NAT_stun_make_request_cancel (struct GNUNET_NAT_STUN_Handle *rh);
553 * Handle an incoming STUN message. Do some basic sanity checks on
554 * packet size and content, try to extract a bit of information, and
555 * possibly reply. At the moment this only processes BIND requests,
556 * and returns the externally visible address of the request. If a
557 * callback is specified, invoke it with the attribute.
559 * @param data the packet
560 * @param len the length of the packet
561 * @param arg sockaddr_in where we will set our discovered packet
562 * @return #GNUNET_OK on OK,
563 * #GNUNET_NO if the packet is not a stun packet
566 GNUNET_NAT_stun_handle_packet (const void *data,
568 struct sockaddr_in *arg);
572 * CHECK if is a valid STUN packet sending to #GNUNET_NAT_stun_handle_packet().
573 * It also check if it can handle the packet based on the NAT handler.
574 * You don't need to call anything else to check if the packet is valid,
576 * @param cls the NAT handle
577 * @param data, packet
578 * @param len, packet length
580 * @return #GNUNET_NO if it can't decode, #GNUNET_YES if is a packet
583 GNUNET_NAT_is_valid_stun_packet (void *cls,
590 /** @} */ /* end of group */
592 /* end of gnunet_nat_lib.h */