SET service: accurate results for symmetric mode
[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., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, 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 /**
75  * What the situation of the NAT connectivity
76  */
77 enum GNUNET_NAT_Type
78 {
79   /**
80    * We have a direct connection
81    */
82   GNUNET_NAT_TYPE_NO_NAT = GNUNET_OK,
83   /**
84    * We are under a NAT but cannot traverse it
85    */
86   GNUNET_NAT_TYPE_UNREACHABLE_NAT,
87   /**
88    * We can traverse using STUN
89    */
90   GNUNET_NAT_TYPE_STUN_PUNCHED_NAT,
91   /**
92    * WE can traverse using UPNP
93    */
94   GNUNET_NAT_TYPE_UPNP_NAT
95
96 };
97
98 /**
99  * Error Types for the NAT subsystem (which can then later be converted/resolved to a string)
100  */
101 enum GNUNET_NAT_StatusCode
102 {
103   /**
104    * Just the default
105    */
106   GNUNET_NAT_ERROR_SUCCESS = GNUNET_OK,
107
108   /**
109    * IPC Failure
110    */
111   GNUNET_NAT_ERROR_IPC_FAILURE,
112
113   /**
114    * Failure in network subsystem, check permissions
115    */
116   GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR,
117
118   /**
119    * test timed out
120    */
121   GNUNET_NAT_ERROR_TIMEOUT,
122
123   /**
124    * detected that we are offline
125    */
126   GNUNET_NAT_ERROR_NOT_ONLINE,
127
128   /**
129    * `upnpc` command not found
130    */
131   GNUNET_NAT_ERROR_UPNPC_NOT_FOUND,
132
133   /**
134    * Failed to run `upnpc` command
135    */
136   GNUNET_NAT_ERROR_UPNPC_FAILED,
137
138   /**
139    * `upnpc' command took too long, process killed
140    */
141   GNUNET_NAT_ERROR_UPNPC_TIMEOUT,
142
143   /**
144    * `upnpc' command failed to establish port mapping
145    */
146   GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED,
147
148   /**
149    * `external-ip' command not found
150    */
151   GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND,
152
153   /**
154    * Failed to run `external-ip` command
155    */
156   GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED,
157
158   /**
159    * `external-ip' command output invalid
160    */
161   GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID,
162
163   /**
164    * "no valid address was returned by `external-ip'"
165    */
166   GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID,
167
168   /**
169    * Could not determine interface with internal/local network address
170    */
171   GNUNET_NAT_ERROR_NO_VALID_IF_IP_COMBO,
172
173   /**
174    * No working gnunet-helper-nat-server found
175    */
176   GNUNET_NAT_ERROR_HELPER_NAT_SERVER_NOT_FOUND,
177
178   /**
179    * NAT test could not be initialized
180    */
181   GNUNET_NAT_ERROR_NAT_TEST_START_FAILED,
182
183   /**
184    * NAT test timeout
185    */
186   GNUNET_NAT_ERROR_NAT_TEST_TIMEOUT,
187
188   /**
189    * NAT test failed to initiate
190    */
191   GNUNET_NAT_ERROR_NAT_REGISTER_FAILED,
192
193   /**
194    *
195    */
196   GNUNET_NAT_ERROR_HELPER_NAT_CLIENT_NOT_FOUND,
197
198
199
200   /**
201    *
202    */
203   GNUNET_NAT_ERROR_
204 };
205
206
207 /**
208  * Converts `enum GNUNET_NAT_StatusCode` to string
209  *
210  * @param err error code to resolve to a string
211  * @return point to a static string containing the error code
212  */
213 const char *
214 GNUNET_NAT_status2string (enum GNUNET_NAT_StatusCode err);
215
216
217 /**
218  * Attempt to enable port redirection and detect public IP address
219  * contacting UPnP or NAT-PMP routers on the local network. Use addr
220  * to specify to which of the local host's addresses should the
221  * external port be mapped. The port is taken from the corresponding
222  * sockaddr_in[6] field.  The NAT module should call the given
223  * callback for any 'plausible' external address.
224  *
225  * @param cfg configuration to use
226  * @param is_tcp #GNUNET_YES for TCP, #GNUNET_NO for UDP
227  * @param adv_port advertised port (port we are either bound to or that our OS
228  *                 locally performs redirection from to our bound port).
229  * @param num_addrs number of addresses in @a addrs
230  * @param addrs list of local addresses packets should be redirected to
231  * @param addrlens actual lengths of the addresses in @a addrs
232  * @param address_callback function to call everytime the public IP address changes
233  * @param reversal_callback function to call if someone wants connection reversal from us,
234  *        NULL if connection reversal is not supported
235  * @param callback_cls closure for callbacks
236  * @return NULL on error, otherwise handle that can be used to unregister
237  */
238 struct GNUNET_NAT_Handle *
239 GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
240                      int is_tcp,
241                      uint16_t adv_port,
242                      unsigned int num_addrs,
243                      const struct sockaddr **addrs,
244                      const socklen_t *addrlens,
245                      GNUNET_NAT_AddressCallback address_callback,
246                      GNUNET_NAT_ReversalCallback reversal_callback,
247                      void *callback_cls,
248                      struct GNUNET_NETWORK_Handle* sock);
249
250
251 /**
252  * Test if the given address is (currently) a plausible IP address for
253  * this peer.
254  *
255  * @param h the handle returned by register
256  * @param addr IP address to test (IPv4 or IPv6)
257  * @param addrlen number of bytes in @a addr
258  * @return #GNUNET_YES if the address is plausible,
259  *         #GNUNET_NO if the address is not plausible,
260  *         #GNUNET_SYSERR if the address is malformed
261  */
262 int
263 GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h,
264                          const void *addr,
265                          socklen_t addrlen);
266
267
268 /**
269  * We learned about a peer (possibly behind NAT) so run the
270  * gnunet-nat-client to send dummy ICMP responses to cause
271  * that peer to connect to us (connection reversal).
272  *
273  * @param h handle (used for configuration)
274  * @param sa the address of the peer (IPv4-only)
275  * @return #GNUNET_SYSERR on error, #GNUNET_NO if nat client is disabled,
276  *         #GNUNET_OK otherwise
277  */
278 int
279 GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h,
280                        const struct sockaddr_in *sa);
281
282
283 /**
284  * Stop port redirection and public IP address detection for the given
285  * handle.  This frees the handle, after having sent the needed
286  * commands to close open ports.
287  *
288  * @param h the handle to stop
289  */
290 void
291 GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h);
292
293
294 /**
295  * Handle to a NAT test.
296  */
297 struct GNUNET_NAT_Test;
298
299
300 /**
301  * Function called to report success or failure for
302  * NAT configuration test.
303  *
304  * @param cls closure
305  * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
306  */
307 typedef void (*GNUNET_NAT_TestCallback) (void *cls,
308                                          enum GNUNET_NAT_StatusCode result);
309
310
311 /**
312  * Start testing if NAT traversal works using the
313  * given configuration (IPv4-only).
314  *
315  * @param cfg configuration for the NAT traversal
316  * @param is_tcp #GNUNET_YES to test TCP, #GNUNET_NO to test UDP
317  * @param bnd_port port to bind to, 0 for connection reversal
318  * @param adv_port externally advertised port to use
319  * @param timeout delay after which the test should be aborted
320  * @param report function to call with the result of the test;
321  *               you still must call #GNUNET_NAT_test_stop().
322  * @param report_cls closure for @a report
323  * @return handle to cancel NAT test
324  */
325 struct GNUNET_NAT_Test *
326 GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
327                        int is_tcp,
328                        uint16_t bnd_port,
329                        uint16_t adv_port,
330                        struct GNUNET_TIME_Relative timeout,
331                        GNUNET_NAT_TestCallback report,
332                        void *report_cls);
333
334
335 /**
336  * Stop an active NAT test.
337  *
338  * @param tst test to stop.
339  */
340 void
341 GNUNET_NAT_test_stop (struct GNUNET_NAT_Test *tst);
342
343
344 /**
345  * Signature of a callback that is given an IP address.
346  *
347  * @param cls closure
348  * @param addr the address, NULL on errors
349  * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
350  */
351 typedef void (*GNUNET_NAT_IPCallback) (void *cls,
352                                        const struct in_addr *addr,
353                                        enum GNUNET_NAT_StatusCode result);
354
355
356
357 /**
358  * Opaque handle to cancel #GNUNET_NAT_mini_get_external_ipv4() operation.
359  */
360 struct GNUNET_NAT_ExternalHandle;
361
362
363 /**
364  * Try to get the external IPv4 address of this peer.
365  *
366  * @param timeout when to fail
367  * @param cb function to call with result
368  * @param cb_cls closure for @a cb
369  * @return handle for cancellation (can only be used until @a cb is called), NULL on error
370  */
371 struct GNUNET_NAT_ExternalHandle *
372 GNUNET_NAT_mini_get_external_ipv4 (struct GNUNET_TIME_Relative timeout,
373                                    GNUNET_NAT_IPCallback cb,
374                                    void *cb_cls);
375
376
377 /**
378  * Cancel operation.
379  *
380  * @param eh operation to cancel
381  */
382 void
383 GNUNET_NAT_mini_get_external_ipv4_cancel (struct GNUNET_NAT_ExternalHandle *eh);
384
385
386 /**
387  * Handle to a mapping created with upnpc.
388  */
389 struct GNUNET_NAT_MiniHandle;
390
391
392 /**
393  * Signature of the callback passed to #GNUNET_NAT_register() for
394  * a function to call whenever our set of 'valid' addresses changes.
395  *
396  * @param cls closure
397  * @param add_remove #GNUNET_YES to mean the new public IP address, #GNUNET_NO to mean
398  *     the previous (now invalid) one, #GNUNET_SYSERR indicates an error
399  * @param addr either the previous or the new public IP address
400  * @param addrlen actual length of the @a addr
401  * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
402  */
403 typedef void
404 (*GNUNET_NAT_MiniAddressCallback) (void *cls,
405                                    int add_remove,
406                                    const struct sockaddr *addr,
407                                    socklen_t addrlen,
408                                    enum GNUNET_NAT_StatusCode result);
409
410
411 /**
412  * Start mapping the given port using (mini)upnpc.  This function
413  * should typically not be used directly (it is used within the
414  * general-purpose #GNUNET_NAT_register() code).  However, it can be
415  * used if specifically UPnP-based NAT traversal is to be used or
416  * tested.
417  *
418  * @param port port to map
419  * @param is_tcp #GNUNET_YES to map TCP, #GNUNET_NO for UDP
420  * @param ac function to call with mapping result
421  * @param ac_cls closure for @a ac
422  * @return NULL on error
423  */
424 struct GNUNET_NAT_MiniHandle *
425 GNUNET_NAT_mini_map_start (uint16_t port,
426                            int is_tcp,
427                            GNUNET_NAT_MiniAddressCallback ac,
428                            void *ac_cls);
429
430
431 /**
432  * Remove a mapping created with (mini)upnpc.  Calling
433  * this function will give 'upnpc' 1s to remove the mapping,
434  * so while this function is non-blocking, a task will be
435  * left with the scheduler for up to 1s past this call.
436  *
437  * @param mini the handle
438  */
439 void
440 GNUNET_NAT_mini_map_stop (struct GNUNET_NAT_MiniHandle *mini);
441
442
443 /**
444  * Handle to auto-configuration in progress.
445  */
446 struct GNUNET_NAT_AutoHandle;
447
448
449 /**
450  * Function called with the result from the autoconfiguration.
451  *
452  * @param cls closure
453  * @param diff minimal suggested changes to the original configuration
454  *             to make it work (as best as we can)
455  * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
456  * @param type what the situation of the NAT
457  */
458 typedef void
459 (*GNUNET_NAT_AutoResultCallback)(void *cls,
460                                  const struct GNUNET_CONFIGURATION_Handle *diff,
461                                  enum GNUNET_NAT_StatusCode result,
462                                  enum GNUNET_NAT_Type type);
463
464
465 /**
466  * Start auto-configuration routine.  The resolver service should
467  * be available when this function is called.
468  *
469  * @param cfg initial configuration
470  * @param cb function to call with autoconfiguration result
471  * @param cb_cls closure for @a cb
472  * @return handle to cancel operation
473  */
474 struct GNUNET_NAT_AutoHandle *
475 GNUNET_NAT_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
476                              GNUNET_NAT_AutoResultCallback cb,
477                              void *cb_cls);
478
479
480 /**
481  * Abort autoconfiguration.
482  *
483  * @param ah handle for operation to abort
484  */
485 void
486 GNUNET_NAT_autoconfig_cancel (struct GNUNET_NAT_AutoHandle *ah);
487
488 /**
489  * Handle for active STUN Requests.
490  */
491 struct GNUNET_NAT_STUN_Handle;
492
493
494
495
496 /**
497  * Function called with the result if an error happened during STUN request.
498  *
499  * @param cls closure
500  * @param result the specific error code
501  */
502 typedef void
503 (*GNUNET_NAT_STUN_ErrorCallback)(void *cls,
504                                  enum GNUNET_NAT_StatusCode error);
505
506
507 /**
508  * Make Generic STUN request and
509  * Send a generic stun request to the server specified using the specified socket.
510  * possibly waiting for a reply and filling the 'reply' field with
511  * the externally visible address.
512  *
513
514  * @param server, the address of the stun server
515  * @param port, port of the stun server
516  * @param sock the socket used to send the request
517  * @param cb callback in case of error
518  * @return #GNUNET_OK success, #GNUNET_NO on error.
519  */
520 int
521 GNUNET_NAT_stun_make_request(char * server,
522                              int port,
523                              struct GNUNET_NETWORK_Handle * sock, GNUNET_NAT_STUN_ErrorCallback cb,
524                              void *cb_cls);
525
526
527 /**
528  *
529  * Handle an incoming STUN message, Do some basic sanity checks on packet size and content,
530  * try to extract a bit of information, and possibly reply.
531  * At the moment this only processes BIND requests, and returns
532  * the externally visible address of the request.
533  * If a callback is specified, invoke it with the attribute.
534  *
535  * @param data, the packet
536  * @param len, the length of the packet
537  * @param arg, sockaddr_in where we will set our discovered packet
538  *
539  * @return, #GNUNET_OK on OK, #GNUNET_NO if the packet is invalid ( not a stun packet)
540  */
541 int
542 GNUNET_NAT_stun_handle_packet(const void *data,
543                               size_t len,
544                               struct sockaddr_in *arg);
545
546 /**
547  * CHECK if is a valid STUN packet sending to GNUNET_NAT_stun_handle_packet.
548  * It also check if it can handle the packet based on the NAT handler.
549  * You don't need to call anything else to check if the packet is valid,
550  *
551  * @param cls the NAT handle
552  * @param data, packet
553  * @param len, packet length
554  *
555  * @return #GNUNET_NO if it can't decode,# GNUNET_YES if is a packet
556  */
557 int
558 GNUNET_NAT_is_valid_stun_packet(void *cls,
559                                   const void *data,
560                                   size_t len);
561
562
563
564 #endif
565
566 /* end of gnunet_nat_lib.h */