-more datacache integration work
[oweals/gnunet.git] / src / include / gnunet_nat_lib.h
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2007-2014 Christian Grothoff (and other contributing authors)
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., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file include/gnunet_nat_lib.h
23  * @brief Library handling UPnP and NAT-PMP port forwarding and
24  *     external IP address retrieval
25  * @author Christian Grothoff
26  * @author Milan Bouchet-Valat
27  */
28
29 #ifndef GNUNET_NAT_LIB_H
30 #define GNUNET_NAT_LIB_H
31
32 #include "gnunet_util_lib.h"
33
34
35 /**
36  * Signature of the callback passed to #GNUNET_NAT_register() for
37  * a function to call whenever our set of 'valid' addresses changes.
38  *
39  * @param cls closure
40  * @param add_remove #GNUNET_YES to mean the new public IP address, #GNUNET_NO to mean
41  *     the previous (now invalid) one
42  * @param addr either the previous or the new public IP address
43  * @param addrlen actual length of the @a addr
44  */
45 typedef void
46 (*GNUNET_NAT_AddressCallback) (void *cls,
47                                int add_remove,
48                                const struct sockaddr *addr,
49                                socklen_t addrlen);
50
51
52 /**
53  * Signature of the callback passed to #GNUNET_NAT_register().
54  * for a function to call whenever someone asks us to do connection
55  * reversal.
56  *
57  * @param cls closure
58  * @param addr public IP address of the other peer
59  * @param addrlen actual lenght of the @a addr
60  */
61 typedef void
62 (*GNUNET_NAT_ReversalCallback) (void *cls,
63                                 const struct sockaddr *addr,
64                                 socklen_t addrlen);
65
66
67 /**
68  * Handle for active NAT registrations.
69  */
70 struct GNUNET_NAT_Handle;
71
72
73 /**
74  * Error Types for the NAT subsystem (which can then later be converted/resolved to a string)
75  */
76 enum GNUNET_NAT_StatusCode
77 {
78   /**
79    * Just the default
80    */
81   GNUNET_NAT_ERROR_SUCCESS = GNUNET_OK,
82
83   /**
84    * IPC Failure
85    */
86   GNUNET_NAT_ERROR_IPC_FAILURE,
87
88   /**
89    * Failure in network subsystem, check permissions
90    */
91   GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR,
92
93   /**
94    * test timed out
95    */
96   GNUNET_NAT_ERROR_TIMEOUT,
97
98   /**
99    * detected that we are offline
100    */
101   GNUNET_NAT_ERROR_NOT_ONLINE,
102
103   /**
104    * `upnpc` command not found
105    */
106   GNUNET_NAT_ERROR_UPNPC_NOT_FOUND,
107
108   /**
109    * Failed to run `upnpc` command
110    */
111   GNUNET_NAT_ERROR_UPNPC_FAILED,
112
113   /**
114    * `upnpc' command took too long, process killed
115    */
116   GNUNET_NAT_ERROR_UPNPC_TIMEOUT,
117
118   /**
119    * `upnpc' command failed to establish port mapping
120    */
121   GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED,
122
123   /**
124    * `external-ip' command not found
125    */
126   GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND,
127
128   /**
129    * Failed to run `external-ip` command
130    */
131   GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED,
132
133   /**
134    * `external-ip' command output invalid
135    */
136   GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID,
137
138   /**
139    * "no valid address was returned by `external-ip'"
140    */
141   GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID,
142
143   /**
144    * Could not determine interface with internal/local network address
145    */
146   GNUNET_NAT_ERROR_NO_VALID_IF_IP_COMBO,
147
148   /**
149    * No working gnunet-helper-nat-server found
150    */
151   GNUNET_NAT_ERROR_HELPER_NAT_SERVER_NOT_FOUND,
152
153   /**
154    * NAT test could not be initialized
155    */
156   GNUNET_NAT_ERROR_NAT_TEST_START_FAILED,
157
158   /**
159    * NAT test timeout
160    */
161   GNUNET_NAT_ERROR_NAT_TEST_TIMEOUT,
162
163   /**
164    * NAT test failed to initiate
165    */
166   GNUNET_NAT_ERROR_NAT_REGISTER_FAILED,
167
168   /**
169    *
170    */
171   GNUNET_NAT_ERROR_HELPER_NAT_CLIENT_NOT_FOUND,
172
173   /**
174    *
175    */
176   GNUNET_NAT_ERROR_
177 };
178
179
180 /**
181  * Converts `enum GNUNET_NAT_StatusCode` to string
182  *
183  * @param err error code to resolve to a string
184  * @return point to a static string containing the error code
185  */
186 const char *
187 GNUNET_NAT_status2string (enum GNUNET_NAT_StatusCode err);
188
189
190 /**
191  * Attempt to enable port redirection and detect public IP address
192  * contacting UPnP or NAT-PMP routers on the local network. Use addr
193  * to specify to which of the local host's addresses should the
194  * external port be mapped. The port is taken from the corresponding
195  * sockaddr_in[6] field.  The NAT module should call the given
196  * callback for any 'plausible' external address.
197  *
198  * @param cfg configuration to use
199  * @param is_tcp #GNUNET_YES for TCP, #GNUNET_NO for UDP
200  * @param adv_port advertised port (port we are either bound to or that our OS
201  *                 locally performs redirection from to our bound port).
202  * @param num_addrs number of addresses in @a addrs
203  * @param addrs list of local addresses packets should be redirected to
204  * @param addrlens actual lengths of the addresses in @a addrs
205  * @param address_callback function to call everytime the public IP address changes
206  * @param reversal_callback function to call if someone wants connection reversal from us,
207  *        NULL if connection reversal is not supported
208  * @param callback_cls closure for callbacks
209  * @return NULL on error, otherwise handle that can be used to unregister
210  */
211 struct GNUNET_NAT_Handle *
212 GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
213                      int is_tcp,
214                      uint16_t adv_port,
215                      unsigned int num_addrs,
216                      const struct sockaddr **addrs,
217                      const socklen_t *addrlens,
218                      GNUNET_NAT_AddressCallback address_callback,
219                      GNUNET_NAT_ReversalCallback reversal_callback,
220                      void *callback_cls);
221
222
223 /**
224  * Test if the given address is (currently) a plausible IP address for
225  * this peer.
226  *
227  * @param h the handle returned by register
228  * @param addr IP address to test (IPv4 or IPv6)
229  * @param addrlen number of bytes in @a addr
230  * @return #GNUNET_YES if the address is plausible,
231  *         #GNUNET_NO if the address is not plausible,
232  *         #GNUNET_SYSERR if the address is malformed
233  */
234 int
235 GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h,
236                          const void *addr,
237                          socklen_t addrlen);
238
239
240 /**
241  * We learned about a peer (possibly behind NAT) so run the
242  * gnunet-nat-client to send dummy ICMP responses to cause
243  * that peer to connect to us (connection reversal).
244  *
245  * @param h handle (used for configuration)
246  * @param sa the address of the peer (IPv4-only)
247  * @return #GNUNET_SYSERR on error, #GNUNET_NO if nat client is disabled,
248  *         #GNUNET_OK otherwise
249  */
250 int
251 GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h,
252                        const struct sockaddr_in *sa);
253
254
255 /**
256  * Stop port redirection and public IP address detection for the given
257  * handle.  This frees the handle, after having sent the needed
258  * commands to close open ports.
259  *
260  * @param h the handle to stop
261  */
262 void
263 GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h);
264
265
266 /**
267  * Handle to a NAT test.
268  */
269 struct GNUNET_NAT_Test;
270
271
272 /**
273  * Function called to report success or failure for
274  * NAT configuration test.
275  *
276  * @param cls closure
277  * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
278  */
279 typedef void (*GNUNET_NAT_TestCallback) (void *cls,
280                                          enum GNUNET_NAT_StatusCode result);
281
282
283 /**
284  * Start testing if NAT traversal works using the
285  * given configuration (IPv4-only).
286  *
287  * @param cfg configuration for the NAT traversal
288  * @param is_tcp #GNUNET_YES to test TCP, #GNUNET_NO to test UDP
289  * @param bnd_port port to bind to, 0 for connection reversal
290  * @param adv_port externally advertised port to use
291  * @param timeout delay after which the test should be aborted
292  * @param report function to call with the result of the test;
293  *               you still must call #GNUNET_NAT_test_stop().
294  * @param report_cls closure for @a report
295  * @return handle to cancel NAT test
296  */
297 struct GNUNET_NAT_Test *
298 GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
299                        int is_tcp,
300                        uint16_t bnd_port,
301                        uint16_t adv_port,
302                        struct GNUNET_TIME_Relative timeout,
303                        GNUNET_NAT_TestCallback report,
304                        void *report_cls);
305
306
307 /**
308  * Stop an active NAT test.
309  *
310  * @param tst test to stop.
311  */
312 void
313 GNUNET_NAT_test_stop (struct GNUNET_NAT_Test *tst);
314
315
316 /**
317  * Signature of a callback that is given an IP address.
318  *
319  * @param cls closure
320  * @param addr the address, NULL on errors
321  * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
322  */
323 typedef void (*GNUNET_NAT_IPCallback) (void *cls,
324                                        const struct in_addr *addr,
325                                        enum GNUNET_NAT_StatusCode result);
326
327
328
329 /**
330  * Opaque handle to cancel #GNUNET_NAT_mini_get_external_ipv4() operation.
331  */
332 struct GNUNET_NAT_ExternalHandle;
333
334
335 /**
336  * Try to get the external IPv4 address of this peer.
337  *
338  * @param timeout when to fail
339  * @param cb function to call with result
340  * @param cb_cls closure for @a cb
341  * @return handle for cancellation (can only be used until @a cb is called), NULL on error
342  */
343 struct GNUNET_NAT_ExternalHandle *
344 GNUNET_NAT_mini_get_external_ipv4 (struct GNUNET_TIME_Relative timeout,
345                                    GNUNET_NAT_IPCallback cb,
346                                    void *cb_cls);
347
348
349 /**
350  * Cancel operation.
351  *
352  * @param eh operation to cancel
353  */
354 void
355 GNUNET_NAT_mini_get_external_ipv4_cancel (struct GNUNET_NAT_ExternalHandle *eh);
356
357
358 /**
359  * Handle to a mapping created with upnpc.
360  */
361 struct GNUNET_NAT_MiniHandle;
362
363
364 /**
365  * Signature of the callback passed to #GNUNET_NAT_register() for
366  * a function to call whenever our set of 'valid' addresses changes.
367  *
368  * @param cls closure
369  * @param add_remove #GNUNET_YES to mean the new public IP address, #GNUNET_NO to mean
370  *     the previous (now invalid) one, #GNUNET_SYSERR indicates an error
371  * @param addr either the previous or the new public IP address
372  * @param addrlen actual length of the @a addr
373  * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
374  */
375 typedef void
376 (*GNUNET_NAT_MiniAddressCallback) (void *cls,
377                                    int add_remove,
378                                    const struct sockaddr *addr,
379                                    socklen_t addrlen,
380                                    enum GNUNET_NAT_StatusCode result);
381
382
383 /**
384  * Start mapping the given port using (mini)upnpc.  This function
385  * should typically not be used directly (it is used within the
386  * general-purpose #GNUNET_NAT_register() code).  However, it can be
387  * used if specifically UPnP-based NAT traversal is to be used or
388  * tested.
389  *
390  * @param port port to map
391  * @param is_tcp #GNUNET_YES to map TCP, #GNUNET_NO for UDP
392  * @param ac function to call with mapping result
393  * @param ac_cls closure for @a ac
394  * @return NULL on error
395  */
396 struct GNUNET_NAT_MiniHandle *
397 GNUNET_NAT_mini_map_start (uint16_t port,
398                            int is_tcp,
399                            GNUNET_NAT_MiniAddressCallback ac,
400                            void *ac_cls);
401
402
403 /**
404  * Remove a mapping created with (mini)upnpc.  Calling
405  * this function will give 'upnpc' 1s to remove the mapping,
406  * so while this function is non-blocking, a task will be
407  * left with the scheduler for up to 1s past this call.
408  *
409  * @param mini the handle
410  */
411 void
412 GNUNET_NAT_mini_map_stop (struct GNUNET_NAT_MiniHandle *mini);
413
414
415 /**
416  * Handle to auto-configuration in progress.
417  */
418 struct GNUNET_NAT_AutoHandle;
419
420
421 /**
422  * Function called with the result from the autoconfiguration.
423  *
424  * @param cls closure
425  * @param diff minimal suggested changes to the original configuration
426  *             to make it work (as best as we can)
427  * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
428  */
429 typedef void
430 (*GNUNET_NAT_AutoResultCallback)(void *cls,
431                                  const struct GNUNET_CONFIGURATION_Handle *diff,
432                                  enum GNUNET_NAT_StatusCode result);
433
434
435 /**
436  * Start auto-configuration routine.  The resolver service should
437  * be available when this function is called.
438  *
439  * @param cfg initial configuration
440  * @param cb function to call with autoconfiguration result
441  * @param cb_cls closure for @a cb
442  * @return handle to cancel operation
443  */
444 struct GNUNET_NAT_AutoHandle *
445 GNUNET_NAT_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
446                              GNUNET_NAT_AutoResultCallback cb,
447                              void *cb_cls);
448
449
450 /**
451  * Abort autoconfiguration.
452  *
453  * @param ah handle for operation to abort
454  */
455 void
456 GNUNET_NAT_autoconfig_cancel (struct GNUNET_NAT_AutoHandle *ah);
457
458 #endif
459
460 /* end of gnunet_nat_lib.h */