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
@@ -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