librats 1.0.2 → 2.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (313) hide show
  1. package/README.md +137 -332
  2. package/binding.gyp +16 -3
  3. package/lib/index.d.ts +271 -696
  4. package/lib/index.js +383 -44
  5. package/native-src/3rdparty/android/ifaddrs-android.c +1 -0
  6. package/native-src/3rdparty/android/ifaddrs-android.h +1 -0
  7. package/native-src/CMakeLists.txt +396 -179
  8. package/native-src/LICENSE +1 -1
  9. package/native-src/src/librats/bindings/rats.cpp +731 -0
  10. package/native-src/src/librats/bindings/rats.h +352 -0
  11. package/native-src/src/librats/bittorrent/bencode.cpp +437 -0
  12. package/native-src/src/librats/bittorrent/bencode.h +176 -0
  13. package/native-src/src/librats/bittorrent/bitfield.cpp +97 -0
  14. package/native-src/src/librats/bittorrent/bitfield.h +76 -0
  15. package/native-src/src/librats/bittorrent/byte_io.h +58 -0
  16. package/native-src/src/librats/bittorrent/choker.cpp +25 -0
  17. package/native-src/src/librats/bittorrent/choker.h +46 -0
  18. package/native-src/src/librats/bittorrent/client.cpp +413 -0
  19. package/native-src/src/librats/bittorrent/client.h +227 -0
  20. package/native-src/src/librats/bittorrent/disk_io.cpp +209 -0
  21. package/native-src/src/librats/bittorrent/disk_io.h +150 -0
  22. package/native-src/src/librats/bittorrent/extensions.cpp +191 -0
  23. package/native-src/src/librats/bittorrent/extensions.h +94 -0
  24. package/native-src/src/librats/bittorrent/file_storage.cpp +77 -0
  25. package/native-src/src/librats/bittorrent/file_storage.h +79 -0
  26. package/native-src/src/librats/bittorrent/log.h +42 -0
  27. package/native-src/src/librats/bittorrent/magnet_uri.cpp +98 -0
  28. package/native-src/src/librats/bittorrent/magnet_uri.h +35 -0
  29. package/native-src/src/librats/bittorrent/peer_connection.cpp +502 -0
  30. package/native-src/src/librats/bittorrent/peer_connection.h +194 -0
  31. package/native-src/src/librats/bittorrent/peer_list.cpp +68 -0
  32. package/native-src/src/librats/bittorrent/peer_list.h +75 -0
  33. package/native-src/src/librats/bittorrent/piece_picker.cpp +352 -0
  34. package/native-src/src/librats/bittorrent/piece_picker.h +201 -0
  35. package/native-src/src/librats/bittorrent/reactor.cpp +97 -0
  36. package/native-src/src/librats/bittorrent/reactor.h +89 -0
  37. package/native-src/src/librats/bittorrent/resume_data.cpp +72 -0
  38. package/native-src/src/librats/bittorrent/resume_data.h +41 -0
  39. package/native-src/src/librats/bittorrent/store_buffer.cpp +48 -0
  40. package/native-src/src/librats/bittorrent/store_buffer.h +47 -0
  41. package/native-src/src/librats/bittorrent/torrent.cpp +870 -0
  42. package/native-src/src/librats/bittorrent/torrent.h +260 -0
  43. package/native-src/src/librats/bittorrent/torrent_creator.cpp +129 -0
  44. package/native-src/src/librats/bittorrent/torrent_creator.h +58 -0
  45. package/native-src/src/librats/bittorrent/torrent_info.cpp +314 -0
  46. package/native-src/src/librats/bittorrent/torrent_info.h +118 -0
  47. package/native-src/src/librats/bittorrent/tracker.cpp +374 -0
  48. package/native-src/src/librats/bittorrent/tracker.h +108 -0
  49. package/native-src/src/librats/bittorrent/types.cpp +206 -0
  50. package/native-src/src/librats/bittorrent/types.h +86 -0
  51. package/native-src/src/librats/core/address.cpp +35 -0
  52. package/native-src/src/librats/core/address.h +78 -0
  53. package/native-src/src/librats/core/bytes.h +69 -0
  54. package/native-src/src/librats/core/chained_send_buffer.cpp +172 -0
  55. package/native-src/src/librats/core/chained_send_buffer.h +183 -0
  56. package/native-src/src/librats/core/endpoint_parse.cpp +41 -0
  57. package/native-src/src/librats/core/endpoint_parse.h +31 -0
  58. package/native-src/src/librats/core/event_bus.h +70 -0
  59. package/native-src/src/librats/core/host_endpoint.h +56 -0
  60. package/native-src/src/{io_poller.cpp → librats/core/io_poller.cpp} +520 -65
  61. package/native-src/src/{io_poller.h → librats/core/io_poller.h} +12 -6
  62. package/native-src/src/librats/core/ip_address.cpp +120 -0
  63. package/native-src/src/librats/core/ip_address.h +109 -0
  64. package/native-src/src/librats/core/mpsc_queue.h +47 -0
  65. package/native-src/src/librats/core/notifier.h +74 -0
  66. package/native-src/src/librats/core/receive_buffer.cpp +219 -0
  67. package/native-src/src/librats/core/receive_buffer.h +171 -0
  68. package/native-src/src/librats/core/service_registry.h +58 -0
  69. package/native-src/src/{socket.cpp → librats/core/socket.cpp} +625 -118
  70. package/native-src/src/librats/core/socket.h +496 -0
  71. package/native-src/src/librats/core/timer_queue.h +105 -0
  72. package/native-src/src/librats/core/types.cpp +42 -0
  73. package/native-src/src/librats/core/types.h +93 -0
  74. package/native-src/src/librats/core/wakeup_pipe.h +83 -0
  75. package/native-src/src/{crypto → librats/crypto}/blake2_endian.h +21 -23
  76. package/native-src/src/{crypto → librats/crypto}/blake2b.c +34 -33
  77. package/native-src/src/{crypto → librats/crypto}/blake2b.h +7 -6
  78. package/native-src/src/{crypto → librats/crypto}/blake2s.c +55 -54
  79. package/native-src/src/{crypto → librats/crypto}/blake2s.h +13 -12
  80. package/native-src/src/{crypto → librats/crypto}/chacha.c +22 -21
  81. package/native-src/src/{crypto → librats/crypto}/chacha.h +14 -13
  82. package/native-src/src/{crypto → librats/crypto}/chachapoly.c +56 -56
  83. package/native-src/src/{crypto → librats/crypto}/chachapoly.h +24 -17
  84. package/native-src/src/{crc32.cpp → librats/crypto/crc32.cpp} +1 -1
  85. package/native-src/src/{crc32.h → librats/crypto/crc32.h} +3 -1
  86. package/native-src/src/{crypto → librats/crypto}/curve25519.c +6 -4
  87. package/native-src/src/{crypto → librats/crypto}/curve25519.h +6 -3
  88. package/native-src/src/librats/crypto/hkdf.c +266 -0
  89. package/native-src/src/{crypto → librats/crypto}/hkdf.h +19 -19
  90. package/native-src/src/{noise.cpp → librats/crypto/noise.cpp} +84 -73
  91. package/native-src/src/{noise.h → librats/crypto/noise.h} +18 -8
  92. package/native-src/src/{crypto → librats/crypto}/poly1305.c +47 -46
  93. package/native-src/src/librats/crypto/poly1305.h +37 -0
  94. package/native-src/src/{sha1.cpp → librats/crypto/sha1.cpp} +33 -1
  95. package/native-src/src/{sha1.h → librats/crypto/sha1.h} +14 -6
  96. package/native-src/src/{crypto → librats/crypto}/sha256.c +15 -14
  97. package/native-src/src/{crypto → librats/crypto}/sha256.h +8 -7
  98. package/native-src/src/{crypto → librats/crypto}/sha512.c +15 -14
  99. package/native-src/src/{crypto → librats/crypto}/sha512.h +8 -7
  100. package/native-src/src/librats/dht/announce.cpp +37 -0
  101. package/native-src/src/librats/dht/announce.h +41 -0
  102. package/native-src/src/librats/dht/bep42.cpp +109 -0
  103. package/native-src/src/librats/dht/bep42.h +48 -0
  104. package/native-src/src/librats/dht/dht.cpp +501 -0
  105. package/native-src/src/librats/dht/dht.h +119 -0
  106. package/native-src/src/librats/dht/dht_runner.cpp +103 -0
  107. package/native-src/src/librats/dht/dht_runner.h +71 -0
  108. package/native-src/src/librats/dht/dos_blocker.cpp +42 -0
  109. package/native-src/src/librats/dht/dos_blocker.h +47 -0
  110. package/native-src/src/librats/dht/find_peers.cpp +52 -0
  111. package/native-src/src/librats/dht/find_peers.h +73 -0
  112. package/native-src/src/librats/dht/id.h +167 -0
  113. package/native-src/src/{krpc.cpp → librats/dht/krpc.cpp} +32 -81
  114. package/native-src/src/{krpc.h → librats/dht/krpc.h} +19 -23
  115. package/native-src/src/librats/dht/log.h +38 -0
  116. package/native-src/src/librats/dht/node.cpp +473 -0
  117. package/native-src/src/librats/dht/node.h +164 -0
  118. package/native-src/src/librats/dht/node_entry.h +81 -0
  119. package/native-src/src/librats/dht/observer.h +72 -0
  120. package/native-src/src/librats/dht/persistence.cpp +90 -0
  121. package/native-src/src/librats/dht/persistence.h +32 -0
  122. package/native-src/src/librats/dht/routing_table.cpp +559 -0
  123. package/native-src/src/librats/dht/routing_table.h +185 -0
  124. package/native-src/src/librats/dht/rpc_manager.cpp +127 -0
  125. package/native-src/src/librats/dht/rpc_manager.h +77 -0
  126. package/native-src/src/librats/dht/storage.cpp +92 -0
  127. package/native-src/src/librats/dht/storage.h +74 -0
  128. package/native-src/src/librats/dht/transport.h +27 -0
  129. package/native-src/src/librats/dht/traversal.cpp +326 -0
  130. package/native-src/src/librats/dht/traversal.h +120 -0
  131. package/native-src/src/librats/dht/udp_transport.cpp +49 -0
  132. package/native-src/src/librats/dht/udp_transport.h +51 -0
  133. package/native-src/src/librats/mdns/log.h +22 -0
  134. package/native-src/src/{mdns.cpp → librats/mdns/mdns.cpp} +75 -40
  135. package/native-src/src/{mdns.h → librats/mdns/mdns.h} +9 -8
  136. package/native-src/src/{natpmp.cpp → librats/nat/natpmp.cpp} +12 -9
  137. package/native-src/src/{natpmp.h → librats/nat/natpmp.h} +3 -3
  138. package/native-src/src/{port_mapping.h → librats/nat/port_mapping.h} +3 -2
  139. package/native-src/src/{stun.cpp → librats/nat/stun.cpp} +4 -4
  140. package/native-src/src/{stun.h → librats/nat/stun.h} +1 -1
  141. package/native-src/src/{upnp.cpp → librats/nat/upnp.cpp} +6 -6
  142. package/native-src/src/{upnp.h → librats/nat/upnp.h} +2 -2
  143. package/native-src/src/librats/node/config.h +110 -0
  144. package/native-src/src/librats/node/dial_service.h +54 -0
  145. package/native-src/src/librats/node/dialer.cpp +264 -0
  146. package/native-src/src/librats/node/dialer.h +188 -0
  147. package/native-src/src/librats/node/host_events.h +26 -0
  148. package/native-src/src/librats/node/identify.cpp +130 -0
  149. package/native-src/src/librats/node/identify.h +71 -0
  150. package/native-src/src/librats/node/nat_status.cpp +103 -0
  151. package/native-src/src/librats/node/nat_status.h +118 -0
  152. package/native-src/src/librats/node/node.cpp +826 -0
  153. package/native-src/src/librats/node/node.h +333 -0
  154. package/native-src/src/librats/node/node_context.h +33 -0
  155. package/native-src/src/librats/node/peer_network.h +91 -0
  156. package/native-src/src/librats/peer/peer.h +49 -0
  157. package/native-src/src/librats/peer/peer_book.cpp +181 -0
  158. package/native-src/src/librats/peer/peer_book.h +88 -0
  159. package/native-src/src/librats/peer/peer_id.cpp +72 -0
  160. package/native-src/src/librats/peer/peer_id.h +62 -0
  161. package/native-src/src/librats/peer/peer_info.h +37 -0
  162. package/native-src/src/librats/peer/peer_table.cpp +137 -0
  163. package/native-src/src/librats/peer/peer_table.h +148 -0
  164. package/native-src/src/librats/security/handshaker.h +66 -0
  165. package/native-src/src/librats/security/identity.h +43 -0
  166. package/native-src/src/librats/security/noise_security.cpp +122 -0
  167. package/native-src/src/librats/security/noise_security.h +37 -0
  168. package/native-src/src/librats/security/plaintext_security.h +106 -0
  169. package/native-src/src/librats/security/session.h +37 -0
  170. package/native-src/src/{storage.cpp → librats/storage/storage.cpp} +369 -522
  171. package/native-src/src/{storage.h → librats/storage/storage.h} +135 -299
  172. package/native-src/src/librats/subsystems/bittorrent.cpp +211 -0
  173. package/native-src/src/librats/subsystems/bittorrent.h +136 -0
  174. package/native-src/src/librats/subsystems/dht_discovery.cpp +202 -0
  175. package/native-src/src/librats/subsystems/dht_discovery.h +123 -0
  176. package/native-src/src/librats/subsystems/dht_service.h +36 -0
  177. package/native-src/src/librats/subsystems/file_transfer.cpp +972 -0
  178. package/native-src/src/librats/subsystems/file_transfer.h +367 -0
  179. package/native-src/src/librats/subsystems/hole_punch.cpp +532 -0
  180. package/native-src/src/librats/subsystems/hole_punch.h +266 -0
  181. package/native-src/src/librats/subsystems/hole_punch_service.h +38 -0
  182. package/native-src/src/librats/subsystems/mdns_discovery.cpp +66 -0
  183. package/native-src/src/librats/subsystems/mdns_discovery.h +55 -0
  184. package/native-src/src/librats/subsystems/message_json.cpp +112 -0
  185. package/native-src/src/librats/subsystems/message_json.h +88 -0
  186. package/native-src/src/librats/subsystems/peer_exchange.cpp +241 -0
  187. package/native-src/src/librats/subsystems/peer_exchange.h +136 -0
  188. package/native-src/src/librats/subsystems/ping_service.cpp +98 -0
  189. package/native-src/src/librats/subsystems/ping_service.h +66 -0
  190. package/native-src/src/librats/subsystems/port_mapping_service.cpp +192 -0
  191. package/native-src/src/librats/subsystems/port_mapping_service.h +84 -0
  192. package/native-src/src/librats/subsystems/pubsub.cpp +567 -0
  193. package/native-src/src/librats/subsystems/pubsub.h +175 -0
  194. package/native-src/src/librats/subsystems/reconnection.cpp +239 -0
  195. package/native-src/src/librats/subsystems/reconnection.h +126 -0
  196. package/native-src/src/librats/transport/connection.cpp +343 -0
  197. package/native-src/src/librats/transport/connection.h +283 -0
  198. package/native-src/src/librats/transport/link.h +96 -0
  199. package/native-src/src/librats/transport/reactor.cpp +540 -0
  200. package/native-src/src/librats/transport/reactor.h +224 -0
  201. package/native-src/src/librats/transport/reactor_pool.h +81 -0
  202. package/native-src/src/librats/transport/tcp_link.cpp +49 -0
  203. package/native-src/src/librats/transport/tcp_link.h +43 -0
  204. package/native-src/src/librats/transport/udp_mux.cpp +617 -0
  205. package/native-src/src/librats/transport/udp_mux.h +363 -0
  206. package/native-src/src/librats/transport/udp_packet.cpp +121 -0
  207. package/native-src/src/librats/transport/udp_packet.h +190 -0
  208. package/native-src/src/librats/transport/udp_stream.cpp +1194 -0
  209. package/native-src/src/librats/transport/udp_stream.h +614 -0
  210. package/native-src/src/librats/util/features.h.in +51 -0
  211. package/native-src/src/{fs.cpp → librats/util/fs.cpp} +51 -3
  212. package/native-src/src/librats/util/fs.h +136 -0
  213. package/native-src/src/librats/util/json.cpp +1002 -0
  214. package/native-src/src/librats/util/json.h +444 -0
  215. package/native-src/src/{logger.cpp → librats/util/logger.cpp} +1 -1
  216. package/native-src/src/{logger.h → librats/util/logger.h} +43 -31
  217. package/native-src/src/{network_monitor.cpp → librats/util/network_monitor.cpp} +12 -4
  218. package/native-src/src/{network_monitor.h → librats/util/network_monitor.h} +2 -1
  219. package/native-src/src/{network_utils.cpp → librats/util/network_utils.cpp} +38 -23
  220. package/native-src/src/{network_utils.h → librats/util/network_utils.h} +15 -8
  221. package/native-src/src/{os.cpp → librats/util/os.cpp} +48 -18
  222. package/native-src/src/librats/util/rats_export.h +69 -0
  223. package/native-src/src/{version.cpp → librats/util/version.cpp} +2 -2
  224. package/native-src/src/{version.h.in → librats/util/version.h.in} +1 -1
  225. package/native-src/src/librats/wire/frame.cpp +76 -0
  226. package/native-src/src/librats/wire/frame.h +110 -0
  227. package/native-src/src/librats/wire/message_router.cpp +45 -0
  228. package/native-src/src/librats/wire/message_router.h +47 -0
  229. package/package.json +5 -4
  230. package/scripts/build-librats.js +1 -0
  231. package/scripts/postinstall.js +3 -3
  232. package/scripts/prepare-package.js +4 -4
  233. package/scripts/verify-installation.js +63 -105
  234. package/src/librats_node.cpp +1042 -1324
  235. package/native-src/src/bencode.cpp +0 -485
  236. package/native-src/src/bencode.h +0 -145
  237. package/native-src/src/bittorrent.cpp +0 -14
  238. package/native-src/src/bittorrent.h +0 -74
  239. package/native-src/src/bt_bitfield.cpp +0 -372
  240. package/native-src/src/bt_bitfield.h +0 -316
  241. package/native-src/src/bt_choker.cpp +0 -228
  242. package/native-src/src/bt_choker.h +0 -147
  243. package/native-src/src/bt_client.cpp +0 -1047
  244. package/native-src/src/bt_client.h +0 -445
  245. package/native-src/src/bt_create_torrent.cpp +0 -677
  246. package/native-src/src/bt_create_torrent.h +0 -473
  247. package/native-src/src/bt_extension.cpp +0 -469
  248. package/native-src/src/bt_extension.h +0 -309
  249. package/native-src/src/bt_file_storage.cpp +0 -261
  250. package/native-src/src/bt_file_storage.h +0 -298
  251. package/native-src/src/bt_handshake.cpp +0 -134
  252. package/native-src/src/bt_handshake.h +0 -157
  253. package/native-src/src/bt_messages.cpp +0 -364
  254. package/native-src/src/bt_messages.h +0 -324
  255. package/native-src/src/bt_network.cpp +0 -1007
  256. package/native-src/src/bt_network.h +0 -417
  257. package/native-src/src/bt_peer_connection.cpp +0 -742
  258. package/native-src/src/bt_peer_connection.h +0 -592
  259. package/native-src/src/bt_piece_picker.cpp +0 -786
  260. package/native-src/src/bt_piece_picker.h +0 -473
  261. package/native-src/src/bt_resume_data.cpp +0 -410
  262. package/native-src/src/bt_resume_data.h +0 -249
  263. package/native-src/src/bt_torrent.cpp +0 -2120
  264. package/native-src/src/bt_torrent.h +0 -641
  265. package/native-src/src/bt_torrent_info.cpp +0 -659
  266. package/native-src/src/bt_torrent_info.h +0 -418
  267. package/native-src/src/bt_types.h +0 -621
  268. package/native-src/src/chained_send_buffer.cpp +0 -75
  269. package/native-src/src/chained_send_buffer.h +0 -137
  270. package/native-src/src/crypto/hkdf.c +0 -266
  271. package/native-src/src/crypto/poly1305.h +0 -36
  272. package/native-src/src/dht.cpp +0 -3311
  273. package/native-src/src/dht.h +0 -717
  274. package/native-src/src/disk_io.cpp +0 -632
  275. package/native-src/src/disk_io.h +0 -315
  276. package/native-src/src/file_transfer.cpp +0 -1415
  277. package/native-src/src/file_transfer.h +0 -286
  278. package/native-src/src/fs.h +0 -108
  279. package/native-src/src/gossipsub.cpp +0 -1139
  280. package/native-src/src/gossipsub.h +0 -403
  281. package/native-src/src/ice.cpp +0 -893
  282. package/native-src/src/ice.h +0 -559
  283. package/native-src/src/json.hpp +0 -25526
  284. package/native-src/src/librats.cpp +0 -2378
  285. package/native-src/src/librats.h +0 -2324
  286. package/native-src/src/librats_bittorrent.cpp +0 -601
  287. package/native-src/src/librats_c.cpp +0 -1557
  288. package/native-src/src/librats_c.h +0 -323
  289. package/native-src/src/librats_discovery.cpp +0 -402
  290. package/native-src/src/librats_encryption.cpp +0 -275
  291. package/native-src/src/librats_file_transfer.cpp +0 -144
  292. package/native-src/src/librats_gossipsub.cpp +0 -289
  293. package/native-src/src/librats_ice.cpp +0 -213
  294. package/native-src/src/librats_log_macros.h +0 -36
  295. package/native-src/src/librats_logging.cpp +0 -173
  296. package/native-src/src/librats_mdns.cpp +0 -166
  297. package/native-src/src/librats_persistence.cpp +0 -796
  298. package/native-src/src/librats_portmap.cpp +0 -419
  299. package/native-src/src/librats_reconnection.cpp +0 -218
  300. package/native-src/src/librats_statistic.cpp +0 -105
  301. package/native-src/src/librats_storage.cpp +0 -189
  302. package/native-src/src/rats_export.h +0 -17
  303. package/native-src/src/receive_buffer.cpp +0 -82
  304. package/native-src/src/receive_buffer.h +0 -127
  305. package/native-src/src/socket.h +0 -228
  306. package/native-src/src/threadmanager.cpp +0 -105
  307. package/native-src/src/threadmanager.h +0 -53
  308. package/native-src/src/tracker.cpp +0 -1264
  309. package/native-src/src/tracker.h +0 -319
  310. package/native-src/src/turn.cpp +0 -762
  311. package/native-src/src/turn.h +0 -460
  312. package/native-src/src/wakeup_pipe.h +0 -60
  313. /package/native-src/src/{os.h → librats/util/os.h} +0 -0
@@ -1,419 +0,0 @@
1
- /**
2
- * @file librats_portmap.cpp
3
- * @brief Automatic port forwarding (UPnP IGD + NAT-PMP) integration for RatsClient
4
- *
5
- * Wires the standalone @ref UpnpClient and @ref NatPmpClient backends into the
6
- * RatsClient lifecycle. Both run in parallel; whichever the router supports maps
7
- * the TCP listen port so peers behind NAT can accept inbound connections. The
8
- * backends are started from RatsClient::start() and torn down in stop().
9
- */
10
-
11
- #include "librats.h"
12
- #include "librats_log_macros.h"
13
- #include "network_utils.h"
14
- #include "network_monitor.h"
15
- #include "logger.h"
16
-
17
- namespace librats {
18
-
19
- // ============================================================================
20
- // Configuration
21
- // ============================================================================
22
-
23
- void RatsClient::set_port_mapping_enabled(bool enabled) {
24
- bool was_enabled;
25
- {
26
- std::lock_guard<std::mutex> lock(port_mapping_mutex_);
27
- was_enabled = port_mapping_config_.enabled;
28
- port_mapping_config_.enabled = enabled;
29
- }
30
-
31
- if (was_enabled != enabled) {
32
- LOG_INFO("portmap", "Automatic port forwarding " << (enabled ? "enabled" : "disabled"));
33
- if (running_.load()) {
34
- if (enabled) {
35
- start_port_mapping();
36
- } else {
37
- stop_port_mapping();
38
- }
39
- }
40
- // Persist the new preference
41
- save_configuration();
42
- }
43
- }
44
-
45
- bool RatsClient::is_port_mapping_enabled() const {
46
- std::lock_guard<std::mutex> lock(port_mapping_mutex_);
47
- return port_mapping_config_.enabled;
48
- }
49
-
50
- void RatsClient::set_port_mapping_config(const PortMappingConfig& config) {
51
- {
52
- std::lock_guard<std::mutex> lock(port_mapping_mutex_);
53
- port_mapping_config_ = config;
54
- }
55
- LOG_DEBUG("portmap", "Port mapping config updated (upnp=" << config.enable_upnp
56
- << " natpmp=" << config.enable_natpmp << " lease=" << config.lease_duration_seconds << ")");
57
- }
58
-
59
- PortMappingConfig RatsClient::get_port_mapping_config() const {
60
- std::lock_guard<std::mutex> lock(port_mapping_mutex_);
61
- return port_mapping_config_;
62
- }
63
-
64
- void RatsClient::on_port_mapping(PortMapCallback callback) {
65
- std::lock_guard<std::mutex> lock(port_mapping_mutex_);
66
- port_mapping_callback_ = std::move(callback);
67
- }
68
-
69
- std::optional<std::pair<std::string, uint16_t>> RatsClient::get_mapped_public_address() const {
70
- std::lock_guard<std::mutex> lock(port_mapping_mutex_);
71
- // The "public address" peers should reach us on is the TCP peer-listen mapping.
72
- if (mapped_external_tcp_port_ == 0 || mapped_external_ip_.empty()) {
73
- return std::nullopt;
74
- }
75
- return std::make_pair(mapped_external_ip_, mapped_external_tcp_port_);
76
- }
77
-
78
- uint16_t RatsClient::get_advertised_port() const {
79
- std::lock_guard<std::mutex> lock(port_mapping_mutex_);
80
- return mapped_external_tcp_port_ != 0
81
- ? mapped_external_tcp_port_
82
- : static_cast<uint16_t>(listen_port_);
83
- }
84
-
85
- void RatsClient::add_port_mapping(PortMapProtocol protocol, uint16_t port) {
86
- std::lock_guard<std::mutex> lock(port_mapping_mutex_);
87
- if (upnp_client_) upnp_client_->add_mapping(protocol, port);
88
- if (natpmp_client_) natpmp_client_->add_mapping(protocol, port);
89
- }
90
-
91
- // ============================================================================
92
- // Result handling
93
- // ============================================================================
94
-
95
- void RatsClient::handle_port_mapping_result(const PortMapResult& result) {
96
- // A gateway whose reported "external" IP is itself private means we're behind a
97
- // second NAT (double-NAT): the mapping forwards a port on the inner router, but
98
- // that doesn't make us reachable from the internet, and the inner port won't
99
- // match whatever the outer NAT assigns. So such a mapping must NOT be treated as
100
- // a public endpoint — we leave mapped_external_* untouched and let the advertised
101
- // address fall back to listen_port_ / the STUN-discovered reflexive address.
102
- // An empty external IP (gateway didn't report one) is "unknown", not private, so
103
- // we keep the previous best-effort behavior for it.
104
- const bool ip_is_private = !result.external_ip.empty() && !network_utils::is_public_ip(result.external_ip);
105
-
106
- PortMapCallback user_cb;
107
- bool tcp_port_changed = false;
108
- bool warn_double_nat = false;
109
- {
110
- std::lock_guard<std::mutex> lock(port_mapping_mutex_);
111
- if (result.success && !ip_is_private) {
112
- if (!result.external_ip.empty()) {
113
- mapped_external_ip_ = result.external_ip;
114
- }
115
- // Track the external port per protocol so the TCP (peer) and UDP (DHT)
116
- // mappings don't overwrite each other.
117
- if (result.protocol == PortMapProtocol::TCP) {
118
- tcp_port_changed = (mapped_external_tcp_port_ != result.external_port);
119
- mapped_external_tcp_port_ = result.external_port;
120
- } else {
121
- mapped_external_udp_port_ = result.external_port;
122
- }
123
- } else if (result.success && ip_is_private && !double_nat_warning_logged_) {
124
- double_nat_warning_logged_ = true;
125
- warn_double_nat = true;
126
- }
127
- user_cb = port_mapping_callback_;
128
- }
129
-
130
- if (result.success && ip_is_private) {
131
- LOG_INFO("portmap", to_string(result.transport) << " mapped " << to_string(result.protocol)
132
- << " port " << result.internal_port << " -> external " << result.external_ip << ":"
133
- << result.external_port << " (gateway external IP is private — not a usable public address)");
134
- if (warn_double_nat) {
135
- LOG_WARN("portmap", "Gateway reports a private external IP (" << result.external_ip
136
- << ") — likely double-NAT. Port forwarding alone won't make this host publicly "
137
- "reachable; relying on STUN for the public address.");
138
- }
139
- } else if (result.success) {
140
- LOG_INFO("portmap", to_string(result.transport) << " mapped " << to_string(result.protocol)
141
- << " port " << result.internal_port << " -> external "
142
- << (result.external_ip.empty() ? "?" : result.external_ip) << ":" << result.external_port);
143
- // Avoid trying to connect to ourselves through the public address. Only a
144
- // genuinely public IP belongs on the ignore list — a private one could be a
145
- // real LAN peer we still want to reach.
146
- if (!result.external_ip.empty()) {
147
- add_ignored_address(result.external_ip);
148
- }
149
- // A new/changed public TCP port means the address peers should reach us on
150
- // changed: re-announce to the DHT so it advertises the mapped port instead
151
- // of the (NATed) local listen port. Done outside the lock below.
152
- } else {
153
- LOG_DEBUG("portmap", to_string(result.transport) << " mapping failed: " << result.error);
154
- }
155
-
156
- // Invoke the user callback outside the lock to avoid re-entrancy deadlocks.
157
- if (user_cb) {
158
- user_cb(result);
159
- }
160
-
161
- // Re-announce with the freshly mapped public port (outside any lock).
162
- if (tcp_port_changed && is_dht_running()) {
163
- announce_rats_peer();
164
- }
165
- }
166
-
167
- // ============================================================================
168
- // Lifecycle
169
- // ============================================================================
170
-
171
- void RatsClient::start_port_mapping() {
172
- PortMappingConfig config;
173
- int port;
174
- {
175
- std::lock_guard<std::mutex> lock(port_mapping_mutex_);
176
- config = port_mapping_config_;
177
- // Already started?
178
- if (upnp_client_ || natpmp_client_) {
179
- return;
180
- }
181
- port = listen_port_;
182
- }
183
-
184
- if (!config.enabled) {
185
- return;
186
- }
187
- if (port <= 0) {
188
- LOG_WARN("portmap", "Skipping port mapping: invalid listen port");
189
- return;
190
- }
191
-
192
- LOG_INFO("portmap", "Starting automatic port forwarding for TCP port " << port
193
- << " (upnp=" << config.enable_upnp << " natpmp=" << config.enable_natpmp << ")");
194
-
195
- auto callback = [this](const PortMapResult& r) { handle_port_mapping_result(r); };
196
-
197
- std::unique_ptr<UpnpClient> upnp;
198
- std::unique_ptr<NatPmpClient> natpmp;
199
-
200
- if (config.enable_upnp) {
201
- upnp = std::make_unique<UpnpClient>();
202
- upnp->set_lease_duration(config.lease_duration_seconds);
203
- upnp->set_callback(callback);
204
- upnp->add_mapping(PortMapProtocol::TCP, static_cast<uint16_t>(port), 0, "rats");
205
- }
206
- if (config.enable_natpmp) {
207
- natpmp = std::make_unique<NatPmpClient>();
208
- natpmp->set_lease_duration(config.lease_duration_seconds);
209
- natpmp->set_callback(callback);
210
- natpmp->add_mapping(PortMapProtocol::TCP, static_cast<uint16_t>(port));
211
- }
212
-
213
- // Publish the clients before starting their workers so add_port_mapping() can
214
- // reach them, then kick off discovery.
215
- {
216
- std::lock_guard<std::mutex> lock(port_mapping_mutex_);
217
- upnp_client_ = std::move(upnp);
218
- natpmp_client_ = std::move(natpmp);
219
- }
220
- {
221
- std::lock_guard<std::mutex> lock(port_mapping_mutex_);
222
- if (upnp_client_) upnp_client_->start();
223
- if (natpmp_client_) natpmp_client_->start();
224
- }
225
- }
226
-
227
- void RatsClient::stop_port_mapping() {
228
- // Move the clients out under the lock, then stop() them outside it: stop()
229
- // joins worker threads which may call handle_port_mapping_result() (and thus
230
- // re-acquire port_mapping_mutex_), so holding it here would deadlock.
231
- std::unique_ptr<UpnpClient> upnp;
232
- std::unique_ptr<NatPmpClient> natpmp;
233
- {
234
- std::lock_guard<std::mutex> lock(port_mapping_mutex_);
235
- upnp = std::move(upnp_client_);
236
- natpmp = std::move(natpmp_client_);
237
- }
238
-
239
- if (upnp || natpmp) {
240
- LOG_INFO("portmap", "Removing port mappings and stopping backends");
241
- }
242
- if (upnp) upnp->stop();
243
- if (natpmp) natpmp->stop();
244
- }
245
-
246
- // ============================================================================
247
- // Network change detection
248
- // ============================================================================
249
-
250
- void RatsClient::set_network_change_detection_enabled(bool enabled) {
251
- bool was_enabled;
252
- {
253
- std::lock_guard<std::mutex> lock(network_monitor_mutex_);
254
- was_enabled = network_change_detection_enabled_;
255
- network_change_detection_enabled_ = enabled;
256
- }
257
- if (was_enabled == enabled) {
258
- return;
259
- }
260
- LOG_INFO("netmon", "Network change detection " << (enabled ? "enabled" : "disabled"));
261
- if (running_.load()) {
262
- if (enabled) {
263
- start_network_monitor();
264
- } else {
265
- stop_network_monitor();
266
- }
267
- }
268
- }
269
-
270
- bool RatsClient::is_network_change_detection_enabled() const {
271
- std::lock_guard<std::mutex> lock(network_monitor_mutex_);
272
- return network_change_detection_enabled_;
273
- }
274
-
275
- void RatsClient::on_network_changed(NetworkChangeCallback callback) {
276
- std::lock_guard<std::mutex> lock(network_monitor_mutex_);
277
- network_change_callback_ = std::move(callback);
278
- }
279
-
280
- void RatsClient::start_network_monitor() {
281
- {
282
- std::lock_guard<std::mutex> lock(network_monitor_mutex_);
283
- if (!network_change_detection_enabled_ || network_monitor_) {
284
- return; // disabled or already running
285
- }
286
- }
287
-
288
- // Spin up the recovery worker before the monitor so it can never miss the
289
- // first wake-up.
290
- {
291
- std::lock_guard<std::mutex> lock(network_recovery_mutex_);
292
- network_recovery_stop_ = false;
293
- network_recovery_pending_ = false;
294
- }
295
- network_recovery_thread_ = std::thread([this]() { network_recovery_loop(); });
296
-
297
- auto monitor = std::make_unique<NetworkMonitor>();
298
- monitor->start([this](const std::vector<std::string>& addrs) {
299
- handle_network_change(addrs);
300
- });
301
- {
302
- std::lock_guard<std::mutex> lock(network_monitor_mutex_);
303
- network_monitor_ = std::move(monitor);
304
- }
305
- LOG_INFO("netmon", "Network change detection active");
306
- }
307
-
308
- void RatsClient::stop_network_monitor() {
309
- // Stop the OS watcher first so no further change events are queued.
310
- std::unique_ptr<NetworkMonitor> monitor;
311
- {
312
- std::lock_guard<std::mutex> lock(network_monitor_mutex_);
313
- monitor = std::move(network_monitor_);
314
- }
315
- if (monitor) {
316
- monitor->stop(); // joins the monitor's worker thread
317
- }
318
-
319
- // Then wake and join the recovery worker. Done after the monitor is down so
320
- // no new recovery can be scheduled while we shut it down.
321
- {
322
- std::lock_guard<std::mutex> lock(network_recovery_mutex_);
323
- network_recovery_stop_ = true;
324
- }
325
- network_recovery_cv_.notify_all();
326
- if (network_recovery_thread_.joinable()) {
327
- network_recovery_thread_.join();
328
- }
329
- }
330
-
331
- void RatsClient::network_recovery_loop() {
332
- while (true) {
333
- {
334
- std::unique_lock<std::mutex> lock(network_recovery_mutex_);
335
- network_recovery_cv_.wait(lock, [this]() {
336
- return network_recovery_pending_ || network_recovery_stop_;
337
- });
338
- if (network_recovery_stop_) {
339
- break;
340
- }
341
- network_recovery_pending_ = false;
342
- }
343
- recover_after_network_change();
344
- }
345
- }
346
-
347
- void RatsClient::handle_network_change(const std::vector<std::string>& current_addresses) {
348
- if (!running_.load()) {
349
- return;
350
- }
351
- LOG_CLIENT_INFO("Network change detected (" << current_addresses.size()
352
- << " local address(es)); refreshing network state");
353
-
354
- // Cheap and synchronous: refresh the self-address set so a freshly added
355
- // local address isn't misjudged as a remote peer, and a removed one stops
356
- // being blocked. (Diff-based; preserves STUN/mapped/ignored entries.)
357
- initialize_local_addresses();
358
-
359
- // Notify the application.
360
- NetworkChangeCallback cb;
361
- {
362
- std::lock_guard<std::mutex> lock(network_monitor_mutex_);
363
- cb = network_change_callback_;
364
- }
365
- if (cb) {
366
- cb(current_addresses);
367
- }
368
-
369
- // Hand the slow recovery (port re-mapping + STUN + re-announce) to the
370
- // dedicated worker so we don't block the monitor thread. Coalesced: if a
371
- // recovery is already running, this just marks another pass is needed.
372
- {
373
- std::lock_guard<std::mutex> lock(network_recovery_mutex_);
374
- network_recovery_pending_ = true;
375
- }
376
- network_recovery_cv_.notify_all();
377
- }
378
-
379
- void RatsClient::recover_after_network_change() {
380
- if (!running_.load()) {
381
- return;
382
- }
383
- LOG_CLIENT_INFO("Recovering after network change: renewing port mappings and re-announcing");
384
-
385
- // 1. Renew router port mappings. Our LAN IP and/or the gateway likely
386
- // changed, so existing UPnP/NAT-PMP leases are stale or aimed at the wrong
387
- // internal address. Tear down and re-run discovery from scratch.
388
- if (is_port_mapping_enabled()) {
389
- stop_port_mapping();
390
- if (running_.load()) {
391
- start_port_mapping();
392
- }
393
- }
394
-
395
- if (!running_.load()) {
396
- return;
397
- }
398
-
399
- // 2. Re-discover our public address via STUN, update the BEP 42 node IDs and
400
- // re-announce so the DHT advertises our current reachable endpoint rather
401
- // than the one from the previous network. This runs on the recovery
402
- // thread, which stop() joins before the DHT clients are destroyed, so the
403
- // set_external_ip()/announce calls can never touch a freed DhtClient.
404
- if (is_dht_running()) {
405
- auto mapped = discover_public_address("stun.l.google.com", 19302, 4000);
406
- if (mapped) {
407
- if (dht_client_) dht_client_->set_external_ip(mapped->address);
408
- if (dht_client_v6_) dht_client_v6_->set_external_ip(mapped->address);
409
- LOG_CLIENT_INFO("Public address after network change: " << mapped->address);
410
- } else {
411
- LOG_CLIENT_DEBUG("STUN public address discovery failed after network change");
412
- }
413
- if (running_.load()) {
414
- announce_rats_peer();
415
- }
416
- }
417
- }
418
-
419
- } // namespace librats
@@ -1,218 +0,0 @@
1
- #include "librats.h"
2
- #include "librats_log_macros.h"
3
-
4
- namespace librats {
5
-
6
-
7
- // =========================================================================
8
- // Automatic Reconnection System
9
- // =========================================================================
10
-
11
- void RatsClient::set_reconnect_enabled(bool enabled) {
12
- std::lock_guard<std::mutex> lock(reconnect_mutex_);
13
- reconnect_config_.enabled = enabled;
14
- LOG_CLIENT_INFO("Automatic reconnection " << (enabled ? "enabled" : "disabled"));
15
- }
16
-
17
- bool RatsClient::is_reconnect_enabled() const {
18
- std::lock_guard<std::mutex> lock(reconnect_mutex_);
19
- return reconnect_config_.enabled;
20
- }
21
-
22
- void RatsClient::set_reconnect_config(const ReconnectConfig& config) {
23
- std::lock_guard<std::mutex> lock(reconnect_mutex_);
24
- reconnect_config_ = config;
25
- LOG_CLIENT_INFO("Reconnection config updated: max_attempts=" << config.max_attempts
26
- << ", stable_threshold=" << config.stable_connection_threshold_seconds << "s");
27
- }
28
-
29
- ReconnectConfig RatsClient::get_reconnect_config() const {
30
- std::lock_guard<std::mutex> lock(reconnect_mutex_);
31
- return reconnect_config_;
32
- }
33
-
34
- size_t RatsClient::get_reconnect_queue_size() const {
35
- std::lock_guard<std::mutex> lock(reconnect_mutex_);
36
- return reconnect_queue_.size();
37
- }
38
-
39
- void RatsClient::clear_reconnect_queue() {
40
- std::lock_guard<std::mutex> lock(reconnect_mutex_);
41
- size_t cleared = reconnect_queue_.size();
42
- reconnect_queue_.clear();
43
- manual_disconnect_peers_.clear();
44
- LOG_CLIENT_INFO("Cleared " << cleared << " peers from reconnection queue");
45
- }
46
-
47
- std::vector<ReconnectInfo> RatsClient::get_reconnect_queue() const {
48
- std::lock_guard<std::mutex> lock(reconnect_mutex_);
49
- std::vector<ReconnectInfo> result;
50
- result.reserve(reconnect_queue_.size());
51
- for (const auto& pair : reconnect_queue_) {
52
- result.push_back(pair.second);
53
- }
54
- return result;
55
- }
56
-
57
- int RatsClient::get_retry_interval_seconds(int attempt, bool is_stable) const {
58
- // For stable peers, use faster first retry
59
- if (attempt == 0 && is_stable) {
60
- return reconnect_config_.stable_first_retry_seconds;
61
- }
62
-
63
- // Use configured intervals, defaulting to last interval if attempt exceeds array size
64
- const auto& intervals = reconnect_config_.retry_intervals_seconds;
65
- if (intervals.empty()) {
66
- return 30; // Default fallback
67
- }
68
-
69
- size_t index = static_cast<size_t>(attempt);
70
- if (index >= intervals.size()) {
71
- return intervals.back();
72
- }
73
- return intervals[index];
74
- }
75
-
76
- void RatsClient::schedule_reconnect(const RatsPeer& peer) {
77
- if (!running_.load()) {
78
- return;
79
- }
80
-
81
- // Check if reconnection is enabled
82
- {
83
- std::lock_guard<std::mutex> lock(reconnect_mutex_);
84
- if (!reconnect_config_.enabled) {
85
- LOG_CLIENT_DEBUG("Reconnection disabled, not scheduling reconnect for " << peer.peer_id);
86
- return;
87
- }
88
-
89
- // Check if this peer was manually disconnected
90
- if (manual_disconnect_peers_.find(peer.peer_id) != manual_disconnect_peers_.end()) {
91
- LOG_CLIENT_DEBUG("Peer " << peer.peer_id << " was manually disconnected, not scheduling reconnect");
92
- manual_disconnect_peers_.erase(peer.peer_id);
93
- return;
94
- }
95
-
96
- // Check if already in queue
97
- if (reconnect_queue_.find(peer.peer_id) != reconnect_queue_.end()) {
98
- LOG_CLIENT_DEBUG("Peer " << peer.peer_id << " already in reconnection queue");
99
- return;
100
- }
101
- }
102
-
103
- // Calculate connection duration
104
- auto now = std::chrono::steady_clock::now();
105
- auto connection_duration = std::chrono::duration_cast<std::chrono::milliseconds>(now - peer.connected_at);
106
-
107
- // Determine if this was a stable connection
108
- bool is_stable = connection_duration.count() >=
109
- (reconnect_config_.stable_connection_threshold_seconds * 1000);
110
-
111
- // Create reconnect info
112
- ReconnectInfo info(peer.peer_id, peer.ip, peer.port, connection_duration, is_stable);
113
-
114
- // Calculate first retry interval
115
- int first_retry_seconds = get_retry_interval_seconds(0, is_stable);
116
- info.next_attempt_time = now + std::chrono::seconds(first_retry_seconds);
117
-
118
- // Add to queue
119
- {
120
- std::lock_guard<std::mutex> lock(reconnect_mutex_);
121
- reconnect_queue_[peer.peer_id] = info;
122
- }
123
-
124
- LOG_CLIENT_INFO("Scheduled reconnection for peer " << peer.peer_id
125
- << " (" << peer.ip << ":" << peer.port << ")"
126
- << " - stable=" << is_stable
127
- << ", connection_duration=" << connection_duration.count() << "ms"
128
- << ", first_retry_in=" << first_retry_seconds << "s");
129
- }
130
-
131
- void RatsClient::remove_from_reconnect_queue(const std::string& peer_id) {
132
- std::lock_guard<std::mutex> lock(reconnect_mutex_);
133
- auto it = reconnect_queue_.find(peer_id);
134
- if (it != reconnect_queue_.end()) {
135
- LOG_CLIENT_DEBUG("Removed peer " << peer_id << " from reconnection queue");
136
- reconnect_queue_.erase(it);
137
- }
138
- }
139
-
140
- void RatsClient::process_reconnect_queue() {
141
- if (!running_.load()) {
142
- return;
143
- }
144
-
145
- // Get list of peers to attempt reconnection (copy to avoid holding lock during connect)
146
- std::vector<ReconnectInfo> peers_to_reconnect;
147
-
148
- {
149
- std::lock_guard<std::mutex> lock(reconnect_mutex_);
150
-
151
- if (!reconnect_config_.enabled || reconnect_queue_.empty()) {
152
- return;
153
- }
154
-
155
- auto now = std::chrono::steady_clock::now();
156
-
157
- for (auto& pair : reconnect_queue_) {
158
- ReconnectInfo& info = pair.second;
159
-
160
- // Check if it's time for next attempt
161
- if (now >= info.next_attempt_time) {
162
- peers_to_reconnect.push_back(info);
163
- }
164
- }
165
- }
166
-
167
- // Process reconnection attempts outside of lock
168
- for (const auto& info : peers_to_reconnect) {
169
- // Check if we're already connected to this peer
170
- std::string normalized_address = normalize_peer_address(info.ip, static_cast<int>(info.port));
171
- if (is_already_connected_to_address(normalized_address)) {
172
- LOG_CLIENT_INFO("Already reconnected to peer " << info.peer_id << ", removing from queue");
173
- remove_from_reconnect_queue(info.peer_id);
174
- continue;
175
- }
176
-
177
- // Check if peer limit is reached
178
- if (is_peer_limit_reached()) {
179
- LOG_CLIENT_DEBUG("Peer limit reached, skipping reconnection attempt for " << info.peer_id);
180
- continue;
181
- }
182
-
183
- LOG_CLIENT_INFO("Attempting reconnection to peer " << info.peer_id
184
- << " (" << info.ip << ":" << info.port << ")"
185
- << " - attempt " << (info.attempt_count + 1) << "/" << reconnect_config_.max_attempts);
186
-
187
- // Attempt to connect
188
- bool connected = connect_to_peer(info.ip, static_cast<int>(info.port));
189
-
190
- if (connected) {
191
- LOG_CLIENT_INFO("Successfully reconnected to peer " << info.peer_id);
192
- remove_from_reconnect_queue(info.peer_id);
193
- } else {
194
- // Update attempt count and schedule next attempt
195
- std::lock_guard<std::mutex> lock(reconnect_mutex_);
196
- auto it = reconnect_queue_.find(info.peer_id);
197
- if (it != reconnect_queue_.end()) {
198
- it->second.attempt_count++;
199
-
200
- // Check if we've exceeded max attempts
201
- if (it->second.attempt_count >= reconnect_config_.max_attempts) {
202
- LOG_CLIENT_INFO("Max reconnection attempts reached for peer " << info.peer_id
203
- << ", removing from queue");
204
- reconnect_queue_.erase(it);
205
- } else {
206
- // Schedule next attempt
207
- int next_interval = get_retry_interval_seconds(it->second.attempt_count, it->second.is_stable);
208
- it->second.next_attempt_time = std::chrono::steady_clock::now() +
209
- std::chrono::seconds(next_interval);
210
- LOG_CLIENT_DEBUG("Scheduled next reconnection attempt for " << info.peer_id
211
- << " in " << next_interval << " seconds");
212
- }
213
- }
214
- }
215
- }
216
- }
217
-
218
- }