gnunet_nat_lib.h 16 KB

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