librats 1.0.2 → 2.2.0

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 (319) hide show
  1. package/README.md +145 -331
  2. package/binding.gyp +16 -3
  3. package/lib/index.d.ts +288 -696
  4. package/lib/index.js +407 -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 +404 -179
  8. package/native-src/LICENSE +1 -1
  9. package/native-src/src/librats/bindings/rats.cpp +762 -0
  10. package/native-src/src/librats/bindings/rats.h +380 -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 +43 -0
  73. package/native-src/src/librats/core/types.h +103 -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/circuit_service.h +84 -0
  144. package/native-src/src/librats/node/config.h +110 -0
  145. package/native-src/src/librats/node/dial_service.h +54 -0
  146. package/native-src/src/librats/node/dialer.cpp +264 -0
  147. package/native-src/src/librats/node/dialer.h +188 -0
  148. package/native-src/src/librats/node/host_events.h +26 -0
  149. package/native-src/src/librats/node/identify.cpp +130 -0
  150. package/native-src/src/librats/node/identify.h +71 -0
  151. package/native-src/src/librats/node/nat_status.cpp +103 -0
  152. package/native-src/src/librats/node/nat_status.h +118 -0
  153. package/native-src/src/librats/node/node.cpp +865 -0
  154. package/native-src/src/librats/node/node.h +344 -0
  155. package/native-src/src/librats/node/node_context.h +33 -0
  156. package/native-src/src/librats/node/peer_network.h +91 -0
  157. package/native-src/src/librats/peer/peer.h +49 -0
  158. package/native-src/src/librats/peer/peer_book.cpp +181 -0
  159. package/native-src/src/librats/peer/peer_book.h +88 -0
  160. package/native-src/src/librats/peer/peer_id.cpp +72 -0
  161. package/native-src/src/librats/peer/peer_id.h +62 -0
  162. package/native-src/src/librats/peer/peer_info.h +37 -0
  163. package/native-src/src/librats/peer/peer_table.cpp +170 -0
  164. package/native-src/src/librats/peer/peer_table.h +148 -0
  165. package/native-src/src/librats/security/handshaker.h +66 -0
  166. package/native-src/src/librats/security/identity.h +43 -0
  167. package/native-src/src/librats/security/noise_security.cpp +122 -0
  168. package/native-src/src/librats/security/noise_security.h +37 -0
  169. package/native-src/src/librats/security/plaintext_security.h +106 -0
  170. package/native-src/src/librats/security/session.h +37 -0
  171. package/native-src/src/{storage.cpp → librats/storage/storage.cpp} +369 -522
  172. package/native-src/src/{storage.h → librats/storage/storage.h} +135 -299
  173. package/native-src/src/librats/subsystems/bittorrent.cpp +211 -0
  174. package/native-src/src/librats/subsystems/bittorrent.h +136 -0
  175. package/native-src/src/librats/subsystems/dht_discovery.cpp +202 -0
  176. package/native-src/src/librats/subsystems/dht_discovery.h +123 -0
  177. package/native-src/src/librats/subsystems/dht_service.h +36 -0
  178. package/native-src/src/librats/subsystems/file_transfer.cpp +972 -0
  179. package/native-src/src/librats/subsystems/file_transfer.h +367 -0
  180. package/native-src/src/librats/subsystems/hole_punch.cpp +605 -0
  181. package/native-src/src/librats/subsystems/hole_punch.h +290 -0
  182. package/native-src/src/librats/subsystems/hole_punch_service.h +38 -0
  183. package/native-src/src/librats/subsystems/mdns_discovery.cpp +66 -0
  184. package/native-src/src/librats/subsystems/mdns_discovery.h +55 -0
  185. package/native-src/src/librats/subsystems/message_json.cpp +112 -0
  186. package/native-src/src/librats/subsystems/message_json.h +88 -0
  187. package/native-src/src/librats/subsystems/peer_exchange.cpp +241 -0
  188. package/native-src/src/librats/subsystems/peer_exchange.h +136 -0
  189. package/native-src/src/librats/subsystems/ping_service.cpp +98 -0
  190. package/native-src/src/librats/subsystems/ping_service.h +66 -0
  191. package/native-src/src/librats/subsystems/port_mapping_service.cpp +192 -0
  192. package/native-src/src/librats/subsystems/port_mapping_service.h +84 -0
  193. package/native-src/src/librats/subsystems/pubsub.cpp +567 -0
  194. package/native-src/src/librats/subsystems/pubsub.h +175 -0
  195. package/native-src/src/librats/subsystems/reconnection.cpp +239 -0
  196. package/native-src/src/librats/subsystems/reconnection.h +126 -0
  197. package/native-src/src/librats/subsystems/relay.cpp +1142 -0
  198. package/native-src/src/librats/subsystems/relay.h +211 -0
  199. package/native-src/src/librats/subsystems/relay_service.h +46 -0
  200. package/native-src/src/librats/transport/connection.cpp +343 -0
  201. package/native-src/src/librats/transport/connection.h +283 -0
  202. package/native-src/src/librats/transport/link.h +96 -0
  203. package/native-src/src/librats/transport/reactor.cpp +588 -0
  204. package/native-src/src/librats/transport/reactor.h +262 -0
  205. package/native-src/src/librats/transport/reactor_pool.h +81 -0
  206. package/native-src/src/librats/transport/relay_link.cpp +208 -0
  207. package/native-src/src/librats/transport/relay_link.h +303 -0
  208. package/native-src/src/librats/transport/tcp_link.cpp +49 -0
  209. package/native-src/src/librats/transport/tcp_link.h +43 -0
  210. package/native-src/src/librats/transport/udp_mux.cpp +617 -0
  211. package/native-src/src/librats/transport/udp_mux.h +363 -0
  212. package/native-src/src/librats/transport/udp_packet.cpp +121 -0
  213. package/native-src/src/librats/transport/udp_packet.h +190 -0
  214. package/native-src/src/librats/transport/udp_stream.cpp +1194 -0
  215. package/native-src/src/librats/transport/udp_stream.h +614 -0
  216. package/native-src/src/librats/util/features.h.in +51 -0
  217. package/native-src/src/{fs.cpp → librats/util/fs.cpp} +51 -3
  218. package/native-src/src/librats/util/fs.h +136 -0
  219. package/native-src/src/librats/util/json.cpp +1002 -0
  220. package/native-src/src/librats/util/json.h +444 -0
  221. package/native-src/src/{logger.cpp → librats/util/logger.cpp} +1 -1
  222. package/native-src/src/{logger.h → librats/util/logger.h} +43 -31
  223. package/native-src/src/{network_monitor.cpp → librats/util/network_monitor.cpp} +12 -4
  224. package/native-src/src/{network_monitor.h → librats/util/network_monitor.h} +2 -1
  225. package/native-src/src/{network_utils.cpp → librats/util/network_utils.cpp} +38 -23
  226. package/native-src/src/{network_utils.h → librats/util/network_utils.h} +15 -8
  227. package/native-src/src/{os.cpp → librats/util/os.cpp} +48 -18
  228. package/native-src/src/librats/util/rats_export.h +69 -0
  229. package/native-src/src/{version.cpp → librats/util/version.cpp} +2 -2
  230. package/native-src/src/{version.h.in → librats/util/version.h.in} +1 -1
  231. package/native-src/src/librats/wire/frame.cpp +76 -0
  232. package/native-src/src/librats/wire/frame.h +111 -0
  233. package/native-src/src/librats/wire/message_router.cpp +45 -0
  234. package/native-src/src/librats/wire/message_router.h +47 -0
  235. package/package.json +5 -4
  236. package/scripts/build-librats.js +1 -0
  237. package/scripts/postinstall.js +3 -3
  238. package/scripts/prepare-package.js +4 -4
  239. package/scripts/verify-installation.js +63 -105
  240. package/src/librats_node.cpp +1067 -1323
  241. package/native-src/src/bencode.cpp +0 -485
  242. package/native-src/src/bencode.h +0 -145
  243. package/native-src/src/bittorrent.cpp +0 -14
  244. package/native-src/src/bittorrent.h +0 -74
  245. package/native-src/src/bt_bitfield.cpp +0 -372
  246. package/native-src/src/bt_bitfield.h +0 -316
  247. package/native-src/src/bt_choker.cpp +0 -228
  248. package/native-src/src/bt_choker.h +0 -147
  249. package/native-src/src/bt_client.cpp +0 -1047
  250. package/native-src/src/bt_client.h +0 -445
  251. package/native-src/src/bt_create_torrent.cpp +0 -677
  252. package/native-src/src/bt_create_torrent.h +0 -473
  253. package/native-src/src/bt_extension.cpp +0 -469
  254. package/native-src/src/bt_extension.h +0 -309
  255. package/native-src/src/bt_file_storage.cpp +0 -261
  256. package/native-src/src/bt_file_storage.h +0 -298
  257. package/native-src/src/bt_handshake.cpp +0 -134
  258. package/native-src/src/bt_handshake.h +0 -157
  259. package/native-src/src/bt_messages.cpp +0 -364
  260. package/native-src/src/bt_messages.h +0 -324
  261. package/native-src/src/bt_network.cpp +0 -1007
  262. package/native-src/src/bt_network.h +0 -417
  263. package/native-src/src/bt_peer_connection.cpp +0 -742
  264. package/native-src/src/bt_peer_connection.h +0 -592
  265. package/native-src/src/bt_piece_picker.cpp +0 -786
  266. package/native-src/src/bt_piece_picker.h +0 -473
  267. package/native-src/src/bt_resume_data.cpp +0 -410
  268. package/native-src/src/bt_resume_data.h +0 -249
  269. package/native-src/src/bt_torrent.cpp +0 -2120
  270. package/native-src/src/bt_torrent.h +0 -641
  271. package/native-src/src/bt_torrent_info.cpp +0 -659
  272. package/native-src/src/bt_torrent_info.h +0 -418
  273. package/native-src/src/bt_types.h +0 -621
  274. package/native-src/src/chained_send_buffer.cpp +0 -75
  275. package/native-src/src/chained_send_buffer.h +0 -137
  276. package/native-src/src/crypto/hkdf.c +0 -266
  277. package/native-src/src/crypto/poly1305.h +0 -36
  278. package/native-src/src/dht.cpp +0 -3311
  279. package/native-src/src/dht.h +0 -717
  280. package/native-src/src/disk_io.cpp +0 -632
  281. package/native-src/src/disk_io.h +0 -315
  282. package/native-src/src/file_transfer.cpp +0 -1415
  283. package/native-src/src/file_transfer.h +0 -286
  284. package/native-src/src/fs.h +0 -108
  285. package/native-src/src/gossipsub.cpp +0 -1139
  286. package/native-src/src/gossipsub.h +0 -403
  287. package/native-src/src/ice.cpp +0 -893
  288. package/native-src/src/ice.h +0 -559
  289. package/native-src/src/json.hpp +0 -25526
  290. package/native-src/src/librats.cpp +0 -2378
  291. package/native-src/src/librats.h +0 -2324
  292. package/native-src/src/librats_bittorrent.cpp +0 -601
  293. package/native-src/src/librats_c.cpp +0 -1557
  294. package/native-src/src/librats_c.h +0 -323
  295. package/native-src/src/librats_discovery.cpp +0 -402
  296. package/native-src/src/librats_encryption.cpp +0 -275
  297. package/native-src/src/librats_file_transfer.cpp +0 -144
  298. package/native-src/src/librats_gossipsub.cpp +0 -289
  299. package/native-src/src/librats_ice.cpp +0 -213
  300. package/native-src/src/librats_log_macros.h +0 -36
  301. package/native-src/src/librats_logging.cpp +0 -173
  302. package/native-src/src/librats_mdns.cpp +0 -166
  303. package/native-src/src/librats_persistence.cpp +0 -796
  304. package/native-src/src/librats_portmap.cpp +0 -419
  305. package/native-src/src/librats_reconnection.cpp +0 -218
  306. package/native-src/src/librats_statistic.cpp +0 -105
  307. package/native-src/src/librats_storage.cpp +0 -189
  308. package/native-src/src/rats_export.h +0 -17
  309. package/native-src/src/receive_buffer.cpp +0 -82
  310. package/native-src/src/receive_buffer.h +0 -127
  311. package/native-src/src/socket.h +0 -228
  312. package/native-src/src/threadmanager.cpp +0 -105
  313. package/native-src/src/threadmanager.h +0 -53
  314. package/native-src/src/tracker.cpp +0 -1264
  315. package/native-src/src/tracker.h +0 -319
  316. package/native-src/src/turn.cpp +0 -762
  317. package/native-src/src/turn.h +0 -460
  318. package/native-src/src/wakeup_pipe.h +0 -60
  319. /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
- }