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
@@ -0,0 +1,81 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file node_entry.h
5
+ * @brief A single contact in the routing table: who it is, where to reach it, and
6
+ * the liveness/quality bookkeeping that decides who to keep or evict.
7
+ *
8
+ * Quality model (mirrors libtorrent's node_entry):
9
+ * - rtt — smoothed round-trip time; kRttUnknown until the first reply.
10
+ * - fail_count — consecutive failed queries; kNeverPinged means we've only ever
11
+ * *heard about* this node (from someone else's reply) and never had
12
+ * a reply from it ourselves.
13
+ * - verified — its id is derived from its IP per BEP 42, so it's harder to spoof
14
+ * and is preferred when we have to choose who to drop.
15
+ */
16
+
17
+ #include "librats/core/address.h"
18
+ #include "librats/dht/id.h"
19
+
20
+ #include <chrono>
21
+ #include <cstdint>
22
+ #include <utility>
23
+
24
+ namespace librats {
25
+ namespace dht {
26
+
27
+ struct NodeEntry {
28
+ static constexpr uint16_t kRttUnknown = 0xffff; // no RTT sample yet
29
+ static constexpr uint8_t kNeverPinged = 0xff; // only heard about, never replied
30
+
31
+ NodeId id{};
32
+ Address endpoint;
33
+ // Last time we "touched" this contact: a reply received OR a probe issued to it.
34
+ // Defaults to the clock minimum so a never-contacted contact sorts as most stale
35
+ // (refreshed first). Read only by RoutingTable::next_to_refresh for its ordering.
36
+ std::chrono::steady_clock::time_point last_seen{(std::chrono::steady_clock::time_point::min)()};
37
+ uint16_t rtt = kRttUnknown;
38
+ uint8_t fail_count = kNeverPinged;
39
+ bool verified = false;
40
+
41
+ NodeEntry() = default;
42
+ NodeEntry(const NodeId& id, Address endpoint)
43
+ : id(id), endpoint(std::move(endpoint)) {}
44
+
45
+ // Have we ever had a reply from this node (vs only heard it mentioned)?
46
+ bool pinged() const noexcept { return fail_count != kNeverPinged; }
47
+ // Replied with no outstanding failures — safe to hand out and keep.
48
+ bool confirmed() const noexcept { return fail_count == 0; }
49
+
50
+ // A reply arrived: clear failures, refresh last_seen, fold in the RTT sample.
51
+ void record_success(uint16_t rtt_sample = kRttUnknown) noexcept {
52
+ fail_count = 0;
53
+ last_seen = std::chrono::steady_clock::now();
54
+ update_rtt(rtt_sample);
55
+ }
56
+
57
+ // A query to this node timed out. Only meaningful once pinged; saturates just
58
+ // below kNeverPinged so a long-dead node never wraps back to "never pinged".
59
+ void record_failure() noexcept {
60
+ if (pinged() && fail_count < kNeverPinged - 1) ++fail_count;
61
+ }
62
+
63
+ // Exponential moving average (2/3 old + 1/3 new), seeded by the first sample.
64
+ void update_rtt(uint16_t sample) noexcept {
65
+ if (sample == kRttUnknown) return;
66
+ rtt = (rtt == kRttUnknown)
67
+ ? sample
68
+ : static_cast<uint16_t>(rtt * 2 / 3 + sample / 3);
69
+ }
70
+
71
+ // Eviction ordering: true if *this is the worse contact and should go first.
72
+ // Worse = more failures, then unverified before verified, then higher RTT.
73
+ bool is_worse_than(const NodeEntry& other) const noexcept {
74
+ if (fail_count != other.fail_count) return fail_count > other.fail_count;
75
+ if (verified != other.verified) return !verified; // unverified is worse
76
+ return rtt > other.rtt;
77
+ }
78
+ };
79
+
80
+ } // namespace dht
81
+ } // namespace librats
@@ -0,0 +1,72 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file observer.h
5
+ * @brief One outstanding query to a single node.
6
+ *
7
+ * An Observer is both the RPC callback the RpcManager invokes when a reply or
8
+ * timeout arrives, and the little bag of per-node state (id, endpoint, flags) the
9
+ * issuer tracks. It is owned via shared_ptr by whoever started the query (a
10
+ * Traversal); the RpcManager holds a shared_ptr only while the query is in flight,
11
+ * and takes a local copy across each callback so an observer can't be freed in the
12
+ * middle of handling its own reply (e.g. if the traversal truncates it meanwhile).
13
+ *
14
+ * Observers reference their Traversal by plain reference, never owning it, so there
15
+ * is no ownership cycle to untangle.
16
+ */
17
+
18
+ #include "librats/core/address.h"
19
+ #include "librats/dht/id.h"
20
+
21
+ #include <chrono>
22
+ #include <cstdint>
23
+ #include <memory>
24
+
25
+ namespace librats {
26
+ struct KrpcMessage; // defined in dht/krpc.h; only referenced by const& here
27
+
28
+ namespace dht {
29
+
30
+ using TimePoint = std::chrono::steady_clock::time_point;
31
+
32
+ class Observer {
33
+ public:
34
+ enum Flag : uint8_t {
35
+ kQueried = 1 << 0, // a query was sent
36
+ kAlive = 1 << 1, // a reply was received
37
+ kFailed = 1 << 2, // fully timed out / errored
38
+ kShortTimeout = 1 << 3, // exceeded the short timeout (slot freed, still waiting)
39
+ kInitial = 1 << 4, // a seed/router node (id may be unknown until it replies)
40
+ kDone = 1 << 5, // abandoned by the traversal; ignore any late reply
41
+ };
42
+
43
+ Observer(const NodeId& id, const Address& endpoint) : id_(id), endpoint_(endpoint) {}
44
+ virtual ~Observer() = default;
45
+ Observer(const Observer&) = delete;
46
+ Observer& operator=(const Observer&) = delete;
47
+
48
+ const NodeId& id() const noexcept { return id_; }
49
+ const Address& endpoint() const noexcept { return endpoint_; }
50
+
51
+ bool has(Flag f) const noexcept { return (flags_ & f) != 0; }
52
+ void set(Flag f) noexcept { flags_ = static_cast<uint8_t>(flags_ | f); }
53
+
54
+ // Invoked by the RpcManager exactly once, when the query resolves.
55
+ virtual void on_response(const KrpcMessage& msg, uint16_t rtt_ms, TimePoint now) = 0;
56
+ virtual void on_timeout(TimePoint now) = 0;
57
+ virtual void on_short_timeout(TimePoint now) = 0;
58
+
59
+ protected:
60
+ NodeId id_;
61
+ Address endpoint_;
62
+ uint8_t flags_ = 0;
63
+
64
+ private:
65
+ friend class RpcManager;
66
+ uint16_t txn_ = 0; // transaction id, owned by the RpcManager while in flight
67
+ };
68
+
69
+ using ObserverPtr = std::shared_ptr<Observer>;
70
+
71
+ } // namespace dht
72
+ } // namespace librats
@@ -0,0 +1,90 @@
1
+ #include "librats/dht/persistence.h"
2
+ #include "librats/dht/log.h"
3
+ #include "librats/util/json.h"
4
+
5
+ #include <fstream>
6
+ #include <iterator>
7
+
8
+ namespace librats {
9
+ namespace dht {
10
+
11
+ bool save_routing_table(const std::string& path, const NodeId& self,
12
+ const std::vector<NodeEntry>& contacts) {
13
+ Json root;
14
+ root["version"] = 1;
15
+ root["node_id"] = to_hex(self);
16
+
17
+ Json nodes = Json::array();
18
+ for (const auto& n : contacts) {
19
+ if (!n.confirmed()) continue; // only persist good contacts
20
+ Json e;
21
+ e["id"] = to_hex(n.id);
22
+ e["ip"] = n.endpoint.ip.to_string();
23
+ e["port"] = static_cast<int>(n.endpoint.port);
24
+ if (n.rtt != NodeEntry::kRttUnknown) e["rtt"] = static_cast<int>(n.rtt);
25
+ nodes.push_back(e);
26
+ }
27
+ root["nodes"] = nodes;
28
+
29
+ std::ofstream file(path);
30
+ if (!file.is_open()) {
31
+ // The headline "saved N contact(s)" lives in the facade; here we surface the
32
+ // failure it can't see — a silent write failure means losing the warm set on restart.
33
+ LOG_WARN("dht", "could not open routing table for writing: " << path);
34
+ return false;
35
+ }
36
+ file << root.dump(2);
37
+ if (!file.good()) {
38
+ LOG_WARN("dht", "failed writing routing table to " << path);
39
+ return false;
40
+ }
41
+ return true;
42
+ }
43
+
44
+ bool load_routing_table(const std::string& path, NodeId& self,
45
+ std::vector<NodeEntry>& contacts) {
46
+ std::ifstream file(path);
47
+ if (!file.is_open()) return false;
48
+ const std::string text((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
49
+
50
+ try {
51
+ Json root = Json::parse(text);
52
+ if (!root.contains("version") || !root.contains("nodes")) {
53
+ LOG_WARN("dht", "routing table at " << path << " missing required fields, ignoring");
54
+ return false;
55
+ }
56
+
57
+ NodeId loaded_self = self;
58
+ if (root.contains("node_id")) loaded_self = from_hex(root["node_id"].get<std::string>());
59
+
60
+ std::vector<NodeEntry> loaded;
61
+ std::size_t skipped = 0;
62
+ for (const auto& e : root["nodes"]) {
63
+ if (!e.contains("id") || !e.contains("ip") || !e.contains("port")) { ++skipped; continue; }
64
+ const auto ip = IpAddress::parse(e["ip"].get<std::string>());
65
+ if (!ip) { ++skipped; continue; }
66
+ NodeEntry n(from_hex(e["id"].get<std::string>()),
67
+ Address(*ip, static_cast<uint16_t>(e["port"].get<int>())));
68
+ const uint16_t rtt = e.contains("rtt")
69
+ ? static_cast<uint16_t>(e["rtt"].get<int>())
70
+ : NodeEntry::kRttUnknown;
71
+ n.record_success(rtt); // a saved contact starts life confirmed
72
+ loaded.push_back(n);
73
+ }
74
+
75
+ self = loaded_self;
76
+ contacts = std::move(loaded);
77
+ // The loaded count is the facade's INFO line; only the malformed-entry detail is
78
+ // new here, so stay silent unless some entries were actually dropped.
79
+ if (skipped)
80
+ LOG_DEBUG("dht", "loaded routing table from " << path << ": " << contacts.size()
81
+ << " contact(s), " << skipped << " malformed entr(ies) skipped");
82
+ return true;
83
+ } catch (const std::exception& ex) {
84
+ LOG_WARN("dht", "malformed routing table at " << path << " (" << ex.what() << "), ignoring");
85
+ return false;
86
+ }
87
+ }
88
+
89
+ } // namespace dht
90
+ } // namespace librats
@@ -0,0 +1,32 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file persistence.h
5
+ * @brief Save/restore the routing table across restarts as JSON.
6
+ *
7
+ * Persists our node id (so our identity is stable) plus the confirmed contacts (a
8
+ * warm set to bootstrap from). The JSON schema is unchanged from earlier releases, so
9
+ * previously saved tables still load (the file is named dht_routing[_v6].json under the
10
+ * data dir; the name is port-independent so an ephemeral node restores on restart).
11
+ */
12
+
13
+ #include "librats/dht/id.h"
14
+ #include "librats/dht/node_entry.h"
15
+
16
+ #include <string>
17
+ #include <vector>
18
+
19
+ namespace librats {
20
+ namespace dht {
21
+
22
+ // Writes `self` + the given (confirmed) contacts to `path`. Returns false on I/O error.
23
+ bool save_routing_table(const std::string& path, const NodeId& self,
24
+ const std::vector<NodeEntry>& contacts);
25
+
26
+ // Reads `path` into `self` and `contacts` (restored as confirmed). Returns false if
27
+ // the file is missing or malformed; outputs are only written on success.
28
+ bool load_routing_table(const std::string& path, NodeId& self,
29
+ std::vector<NodeEntry>& contacts);
30
+
31
+ } // namespace dht
32
+ } // namespace librats