MQ doc
[oweals/gnunet.git] / src / include / gnunet_nat_lib.h
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2007-2014 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
26  * Library handling UPnP and NAT-PMP port forwarding
27  * and external IP address retrieval
28  *
29  * @defgroup nat  NAT library
30  * Library handling UPnP and NAT-PMP port forwarding
31  * and external IP address retrieval
32  *
33  * @{
34  */
35
36 #ifndef GNUNET_NAT_LIB_H
37 #define GNUNET_NAT_LIB_H
38
39 #include "gnunet_util_lib.h"
40
41
42 /**
43  * Signature of the callback passed to #GNUNET_NAT_register() for
44  * a function to call whenever our set of 'valid' addresses changes.
45  *
46  * @param cls closure
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
51  */
52 typedef void
53 (*GNUNET_NAT_AddressCallback) (void *cls,
54                                int add_remove,
55                                const struct sockaddr *addr,
56                                socklen_t addrlen);
57
58
59 /**
60  * Signature of the callback passed to #GNUNET_NAT_register().
61  * for a function to call whenever someone asks us to do connection
62  * reversal.
63  *
64  * @param cls closure
65  * @param addr public IP address of the other peer
66  * @param addrlen actual lenght of the @a addr
67  */
68 typedef void
69 (*GNUNET_NAT_ReversalCallback) (void *cls,
70                                 const struct sockaddr *addr,
71                                 socklen_t addrlen);
72
73
74 /**
75  * Handle for active NAT registrations.
76  */
77 struct GNUNET_NAT_Handle;
78
79
80
81 /**
82  * What the situation of the NAT connectivity
83  */
84 enum GNUNET_NAT_Type
85 {
86   /**
87    * We have a direct connection
88    */
89   GNUNET_NAT_TYPE_NO_NAT = GNUNET_OK,
90
91   /**
92    * We are under a NAT but cannot traverse it
93    */
94   GNUNET_NAT_TYPE_UNREACHABLE_NAT,
95
96   /**
97    * We can traverse using STUN
98    */
99   GNUNET_NAT_TYPE_STUN_PUNCHED_NAT,
100
101   /**
102    * WE can traverse using UPNP
103    */
104   GNUNET_NAT_TYPE_UPNP_NAT
105
106 };
107
108 /**
109  * Error Types for the NAT subsystem (which can then later be converted/resolved to a string)
110  */
111 enum GNUNET_NAT_StatusCode
112 {
113   /**
114    * Just the default
115    */
116   GNUNET_NAT_ERROR_SUCCESS = GNUNET_OK,
117
118   /**
119    * IPC Failure
120    */
121   GNUNET_NAT_ERROR_IPC_FAILURE,
122
123   /**
124    * Failure in network subsystem, check permissions
125    */
126   GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR,
127
128   /**
129    * test timed out
130    */
131   GNUNET_NAT_ERROR_TIMEOUT,
132
133   /**
134    * detected that we are offline
135    */
136   GNUNET_NAT_ERROR_NOT_ONLINE,
137
138   /**
139    * `upnpc` command not found
140    */
141   GNUNET_NAT_ERROR_UPNPC_NOT_FOUND,
142
143   /**
144    * Failed to run `upnpc` command
145    */
146   GNUNET_NAT_ERROR_UPNPC_FAILED,
147
148   /**
149    * `upnpc' command took too long, process killed
150    */
151   GNUNET_NAT_ERROR_UPNPC_TIMEOUT,
152
153   /**
154    * `upnpc' command failed to establish port mapping
155    */
156   GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED,
157
158   /**
159    * `external-ip' command not found
160    */
161   GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND,
162
163   /**
164    * Failed to run `external-ip` command
165    */
166   GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED,
167
168   /**
169    * `external-ip' command output invalid
170    */
171   GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID,
172
173   /**
174    * "no valid address was returned by `external-ip'"
175    */
176   GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID,
177
178   /**
179    * Could not determine interface with internal/local network address
180    */
181   GNUNET_NAT_ERROR_NO_VALID_IF_IP_COMBO,
182
183   /**
184    * No working gnunet-helper-nat-server found
185    */
186   GNUNET_NAT_ERROR_HELPER_NAT_SERVER_NOT_FOUND,
187
188   /**
189    * NAT test could not be initialized
190    */
191   GNUNET_NAT_ERROR_NAT_TEST_START_FAILED,
192
193   /**
194    * NAT test timeout
195    */
196   GNUNET_NAT_ERROR_NAT_TEST_TIMEOUT,
197
198   /**
199    * NAT test failed to initiate
200    */
201   GNUNET_NAT_ERROR_NAT_REGISTER_FAILED,
202
203   /**
204    *
205    */
206   GNUNET_NAT_ERROR_HELPER_NAT_CLIENT_NOT_FOUND,
207
208   /**
209    *
210    */
211   GNUNET_NAT_ERROR_
212 };
213
214
215 /**
216  * Converts `enum GNUNET_NAT_StatusCode` to string
217  *
218  * @param err error code to resolve to a string
219  * @return point to a static string containing the error code
220  */
221 const char *
222 GNUNET_NAT_status2string (enum GNUNET_NAT_StatusCode err);
223
224
225 /**
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.
232  *
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
245  */
246 struct GNUNET_NAT_Handle *
247 GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
248                      int is_tcp,
249                      uint16_t adv_port,
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,
255                      void *callback_cls,
256                      struct GNUNET_NETWORK_Handle* sock);
257
258
259 /**
260  * Test if the given address is (currently) a plausible IP address for
261  * this peer.
262  *
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
269  */
270 int
271 GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h,
272                          const void *addr,
273                          socklen_t addrlen);
274
275
276 /**
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).
280  *
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
285  */
286 int
287 GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h,
288                        const struct sockaddr_in *sa);
289
290
291 /**
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.
295  *
296  * @param h the handle to stop
297  */
298 void
299 GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h);
300
301
302 /**
303  * Handle to a NAT test.
304  */
305 struct GNUNET_NAT_Test;
306
307
308 /**
309  * Function called to report success or failure for
310  * NAT configuration test.
311  *
312  * @param cls closure
313  * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
314  */
315 typedef void (*GNUNET_NAT_TestCallback) (void *cls,
316                                          enum GNUNET_NAT_StatusCode result);
317
318
319 /**
320  * Start testing if NAT traversal works using the
321  * given configuration (IPv4-only).
322  *
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
332  */
333 struct GNUNET_NAT_Test *
334 GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
335                        int is_tcp,
336                        uint16_t bnd_port,
337                        uint16_t adv_port,
338                        struct GNUNET_TIME_Relative timeout,
339                        GNUNET_NAT_TestCallback report,
340                        void *report_cls);
341
342
343 /**
344  * Stop an active NAT test.
345  *
346  * @param tst test to stop.
347  */
348 void
349 GNUNET_NAT_test_stop (struct GNUNET_NAT_Test *tst);
350
351
352 /**
353  * Signature of a callback that is given an IP address.
354  *
355  * @param cls closure
356  * @param addr the address, NULL on errors
357  * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
358  */
359 typedef void
360 (*GNUNET_NAT_IPCallback) (void *cls,
361                           const struct in_addr *addr,
362                           enum GNUNET_NAT_StatusCode result);
363
364
365 /**
366  * Opaque handle to cancel #GNUNET_NAT_mini_get_external_ipv4() operation.
367  */
368 struct GNUNET_NAT_ExternalHandle;
369
370
371 /**
372  * Try to get the external IPv4 address of this peer.
373  *
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
378  */
379 struct GNUNET_NAT_ExternalHandle *
380 GNUNET_NAT_mini_get_external_ipv4 (struct GNUNET_TIME_Relative timeout,
381                                    GNUNET_NAT_IPCallback cb,
382                                    void *cb_cls);
383
384
385 /**
386  * Cancel operation.
387  *
388  * @param eh operation to cancel
389  */
390 void
391 GNUNET_NAT_mini_get_external_ipv4_cancel (struct GNUNET_NAT_ExternalHandle *eh);
392
393
394 /**
395  * Handle to a mapping created with upnpc.
396  */
397 struct GNUNET_NAT_MiniHandle;
398
399
400 /**
401  * Signature of the callback passed to #GNUNET_NAT_register() for
402  * a function to call whenever our set of 'valid' addresses changes.
403  *
404  * @param cls closure
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
410  */
411 typedef void
412 (*GNUNET_NAT_MiniAddressCallback) (void *cls,
413                                    int add_remove,
414                                    const struct sockaddr *addr,
415                                    socklen_t addrlen,
416                                    enum GNUNET_NAT_StatusCode result);
417
418
419 /**
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
424  * tested.
425  *
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
431  */
432 struct GNUNET_NAT_MiniHandle *
433 GNUNET_NAT_mini_map_start (uint16_t port,
434                            int is_tcp,
435                            GNUNET_NAT_MiniAddressCallback ac,
436                            void *ac_cls);
437
438
439 /**
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.
444  *
445  * @param mini the handle
446  */
447 void
448 GNUNET_NAT_mini_map_stop (struct GNUNET_NAT_MiniHandle *mini);
449
450
451 /**
452  * Handle to auto-configuration in progress.
453  */
454 struct GNUNET_NAT_AutoHandle;
455
456
457 /**
458  * Function called with the result from the autoconfiguration.
459  *
460  * @param cls closure
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
465  */
466 typedef void
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);
471
472
473 /**
474  * Start auto-configuration routine.  The resolver service should
475  * be available when this function is called.
476  *
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
481  */
482 struct GNUNET_NAT_AutoHandle *
483 GNUNET_NAT_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
484                              GNUNET_NAT_AutoResultCallback cb,
485                              void *cb_cls);
486
487
488 /**
489  * Abort autoconfiguration.
490  *
491  * @param ah handle for operation to abort
492  */
493 void
494 GNUNET_NAT_autoconfig_cancel (struct GNUNET_NAT_AutoHandle *ah);
495
496 /**
497  * Handle for active STUN Requests.
498  */
499 struct GNUNET_NAT_STUN_Handle;
500
501
502 /**
503  * Function called with the result if an error happened during STUN request.
504  *
505  * @param cls closure
506  * @param result the specific error code
507  */
508 typedef void
509 (*GNUNET_NAT_STUN_ErrorCallback)(void *cls,
510                                  enum GNUNET_NAT_StatusCode error);
511
512
513 /**
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.
517  */
518 struct GNUNET_NAT_STUN_Handle;
519
520
521 /**
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.
526  *
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
533  */
534 struct GNUNET_NAT_STUN_Handle *
535 GNUNET_NAT_stun_make_request (const char *server,
536                               uint16_t port,
537                               struct GNUNET_NETWORK_Handle *sock,
538                               GNUNET_NAT_STUN_ErrorCallback cb,
539                               void *cb_cls);
540
541
542 /**
543  * Cancel active STUN request. Frees associated resources
544  * and ensures that the callback is no longer invoked.
545  *
546  * @param rh request to cancel
547  */
548 void
549 GNUNET_NAT_stun_make_request_cancel (struct GNUNET_NAT_STUN_Handle *rh);
550
551
552 /**
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.
558  *
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
564  */
565 int
566 GNUNET_NAT_stun_handle_packet (const void *data,
567                                size_t len,
568                                struct sockaddr_in *arg);
569
570
571 /**
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,
575  *
576  * @param cls the NAT handle
577  * @param data packet
578  * @param len length of @a data
579  * @return #GNUNET_NO if it can't decode, #GNUNET_YES if is a packet
580  */
581 int
582 GNUNET_NAT_is_valid_stun_packet (void *cls,
583                                  const void *data,
584                                  size_t len);
585
586
587 #endif
588
589 /** @} */  /* end of group */
590
591 /* end of gnunet_nat_lib.h */