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,344 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file node.h
5
+ * @brief The public entry point: a thin facade that wires the layers together.
6
+ *
7
+ * Node owns the reactor pool, the security provider, the peer table and the
8
+ * message router, and it IS the ConnectionDelegate the reactors report to. It is
9
+ * deliberately thin — it composes the layers and exposes a small async API; the
10
+ * logic lives in those layers, not here.
11
+ *
12
+ * Threading: connect/send/broadcast are non-blocking and thread-safe — they post
13
+ * work to the owning reactor. Event callbacks (on_peer_connected / on(channel,…)
14
+ * / on_peer_disconnected) run on a reactor thread; register them before start().
15
+ *
16
+ * ── What a bare Node does, and what it does NOT ──────────────────────────────
17
+ * A Node on its own is just the secure transport core. Out of the box it gives you:
18
+ * - an encrypted transport (Noise_XX, or plaintext per NodeConfig::security),
19
+ * with a self-certifying PeerId and the app protocol bound into the handshake,
20
+ * over EITHER wire: TCP, or the library's reliable stream over UDP. Both are
21
+ * offered by default on the same port, and a dial tries the preferred one
22
+ * (UDP, the better fit for P2P) and races the other after a short delay;
23
+ * - manual dialing: connect(host, port) / connect(Address) — it never discovers
24
+ * peers by itself;
25
+ * - the peer table + admission limit: peers(), peer(), peer_count(), max_peers;
26
+ * - raw channel messaging: send(to, channel, bytes) / broadcast(channel, bytes)
27
+ * / on(channel, …);
28
+ * - peer connect/disconnect events and the node-scoped EventBus + ServiceRegistry;
29
+ * - host network-change detection (NetworkChanged on the EventBus), if enabled;
30
+ * - identity persistence (NodeConfig::data_dir → identity.key).
31
+ *
32
+ * Everything else is an opt-in Subsystem you attach with add_subsystem() BEFORE
33
+ * start(): peer discovery (DhtDiscovery, MdnsDiscovery), pub/sub (PubSub), typed
34
+ * JSON messaging (MessageJson), file transfer (FileTransfer), liveness
35
+ * (PingService), NAT port mapping (PortMappingService), automatic reconnection
36
+ * (ReconnectionService), distributed storage (StorageManager). None of these are
37
+ * wired by default — a bare Node neither discovers peers nor reconnects on its own;
38
+ * the application composes exactly the capabilities it wants. This is deliberate:
39
+ * the node stays a small, predictable core, and you pay only for what you attach.
40
+ */
41
+
42
+ #include "librats/util/rats_export.h"
43
+ #include "librats/transport/connection.h" // ConnectionDelegate
44
+ #include "librats/transport/reactor_pool.h"
45
+ #include "librats/core/address.h"
46
+ #include "librats/peer/peer_table.h"
47
+ #include "librats/peer/peer_id.h"
48
+ #include "librats/peer/peer_info.h"
49
+ #include "librats/security/identity.h"
50
+ #include "librats/security/handshaker.h" // SecurityProvider
51
+ #include "librats/node/circuit_service.h"
52
+ #include "librats/node/config.h"
53
+ #include "librats/node/dial_service.h"
54
+ #include "librats/node/dialer.h"
55
+ #include "librats/node/nat_status.h"
56
+ #include "librats/node/node_context.h" // NodeContext, EventBus, ServiceRegistry
57
+ #include "librats/peer/peer.h"
58
+ #include "librats/node/peer_network.h"
59
+ #include "librats/wire/message_router.h"
60
+
61
+ #include <atomic>
62
+ #include <condition_variable>
63
+ #include <functional>
64
+ #include <memory>
65
+ #include <mutex>
66
+ #include <optional>
67
+ #include <string>
68
+ #include <string_view>
69
+ #include <thread>
70
+ #include <type_traits>
71
+ #include <vector>
72
+
73
+ namespace librats {
74
+
75
+ class NetworkMonitor; // util/network_monitor.h — owned via unique_ptr, included in node.cpp
76
+ class MessageJson; // subsystems/message_json.h — reached via json() (json.h stays out of node.h)
77
+
78
+ class RATS_API Node final : public ConnectionDelegate,
79
+ public PeerNetwork,
80
+ public DialService,
81
+ public CircuitService {
82
+ public:
83
+ /// Construct a node from its configuration (see NodeConfig). This only loads
84
+ /// the identity and prepares the layers; no socket is opened until start().
85
+ explicit Node(NodeConfig config);
86
+ /// Stops the node if still running, then releases all resources.
87
+ ~Node() override;
88
+
89
+ Node(const Node&) = delete;
90
+ Node& operator=(const Node&) = delete;
91
+
92
+ /// Attach a subsystem (DHT, GossipSub, PingService…). Call before start();
93
+ /// the node owns it (single ownership), gives it a PeerNetwork on start(), and
94
+ /// stops it on stop(). Returns a non-owning pointer to the just-added subsystem
95
+ /// so the caller can drive its API without a separate get()/move dance — valid
96
+ /// for the node's lifetime:
97
+ /// auto* files = node.add_subsystem(std::make_unique<FileTransfer>("./dl"));
98
+ template <class T>
99
+ T* add_subsystem(std::unique_ptr<T> subsystem) {
100
+ static_assert(std::is_base_of<Subsystem, T>::value, "T must derive from Subsystem");
101
+ T* raw = subsystem.get();
102
+ subsystems_.push_back(std::move(subsystem)); // upcast to unique_ptr<Subsystem>
103
+ return raw;
104
+ }
105
+
106
+ /// Bring the node up: open the listener (if enabled), start the reactor pool,
107
+ /// then start every attached subsystem. Register callbacks and attach
108
+ /// subsystems BEFORE calling this.
109
+ /// @return true on success; false if the listener could not bind.
110
+ bool start();
111
+ /// Tear the node down: stop subsystems (reverse order), close all
112
+ /// connections, and join the reactor pool. Safe to call once; idempotent.
113
+ void stop();
114
+
115
+ /// Our self-certifying peer identity (the public key peers authenticate).
116
+ const PeerId& local_id() const noexcept override { return identity_.id; }
117
+ /// The bound listen port (the actual port when the config requested 0). Both
118
+ /// transports share it, so one advertised address is dialable over either.
119
+ uint16_t listen_port() const noexcept override { return listen_port_; }
120
+
121
+ /// Transports this node is actually running, as a PeerTransports bitmask.
122
+ /// May be narrower than the config asked for — a UDP socket that could not be
123
+ /// bound leaves the node TCP-only rather than failing to start.
124
+ uint8_t transports() const noexcept override { return transports_; }
125
+
126
+ /// Application protocol identity bound into the handshake (see NodeConfig).
127
+ const std::string& protocol() const noexcept override { return config_.protocol; }
128
+
129
+ // — node-scoped coordination, shared by subsystems and the app (see NodeContext) —
130
+ // events() : fire-and-forget notifications, one→many (host events, …)
131
+ // services() : targeted synchronous calls by capability interface, one→one
132
+ EventBus& events() noexcept { return events_; }
133
+ ServiceRegistry& services() noexcept { return services_; }
134
+
135
+ // — connections —
136
+ /// Dial a peer. Non-blocking: the connection (transport + handshake) completes
137
+ /// asynchronously and surfaces via on_peer_connected. A duplicate or
138
+ /// self-connection is detected and dropped after the handshake.
139
+ ///
140
+ /// The transport is chosen by the dialer (see node/dialer.h): the preferred
141
+ /// one first, the other raced in after NodeConfig::transport_fallback_ms if
142
+ /// the first has not come up. Whichever completes its handshake first wins.
143
+ void connect(const Address& address) override;
144
+ /// @copydoc connect(const Address&)
145
+ void connect(const std::string& host, uint16_t port);
146
+
147
+ /// Number of currently-established peers.
148
+ size_t peer_count() const noexcept { return peers_.size(); }
149
+ /// Snapshot of all established peers (id, addresses, direction, timing).
150
+ std::vector<PeerInfo> peers() const override { return peers_.snapshot(); }
151
+ /// Handle to a connected peer by id, or std::nullopt if not connected.
152
+ std::optional<Peer> peer(const PeerId& id);
153
+
154
+ /// Our own addresses as remote peers reported observing us at — their observed
155
+ /// IP paired with our listen port. De-duplicated and bounded; populated as
156
+ /// peers send their identify message. Useful for NAT awareness / advertising.
157
+ std::vector<Address> observed_addresses() const;
158
+
159
+ /// What the mesh has shown about our own side of the NAT, from the endpoints
160
+ /// datagram peers report observing our shared UDP socket at (see nat_status.h).
161
+ /// Also published in services() as ExternalAddressService, which is how a
162
+ /// NAT-traversal subsystem reaches it.
163
+ const NatStatus& nat_status() const noexcept { return nat_status_; }
164
+
165
+ // — DialService: dial one endpoint over one wire, bypassing the transport race
166
+ // (see node/dial_service.h; used by hole punching) —
167
+ bool dial_direct(const Address& addr, TransportKind kind,
168
+ const DialProfile& profile) override;
169
+
170
+ // — CircuitService: make a relayed byte stream an ordinary peer connection
171
+ // (see node/circuit_service.h; used by the relay module) —
172
+ std::optional<PeerRoute> adopt_circuit(const PeerId& carrier, std::unique_ptr<Link> link,
173
+ ConnRole role, bool connected) override;
174
+ void wake_circuit(PeerRoute route, uint32_t events) override;
175
+ void close_circuit(PeerRoute route, CloseReason reason) override;
176
+
177
+ // — peer admission limit (0 = unlimited; guards inbound, not our own dials) —
178
+ size_t max_peers() const noexcept { return max_peers_.load(std::memory_order_relaxed); }
179
+ void set_max_peers(size_t n) noexcept { max_peers_.store(n, std::memory_order_relaxed); }
180
+ bool peer_limit_reached() const noexcept {
181
+ const size_t cap = max_peers_.load(std::memory_order_relaxed);
182
+ return cap != 0 && peers_.size() >= cap;
183
+ }
184
+
185
+ // — application messaging (raw bytes on a named channel) —
186
+ /// Send raw bytes to one peer on a named channel. Non-blocking; the payload
187
+ /// is copied into the peer's send queue. No-op if the peer is not connected.
188
+ /// @param to destination peer id
189
+ /// @param channel application channel name (interned to a 16-bit id)
190
+ /// @param payload message bytes (copied)
191
+ /// @return whether that peer's queue still has room. <b>False means stop</b>:
192
+ /// this message is queued like any other, but the queue is past its
193
+ /// low-water mark, and an application that keeps going regardless
194
+ /// will eventually have the peer dropped as a slow consumer. Wait for
195
+ /// on_peer_writable instead. Also false if the peer is not connected.
196
+ bool send(const PeerId& to, std::string_view channel, ByteView payload);
197
+ /// Send raw bytes on a named channel to every connected peer.
198
+ /// @return whether *every* one of them still has room — a fan-out can only
199
+ /// usefully be paced by its slowest recipient.
200
+ ///
201
+ /// Coarser than send(): the answer is the reactors' view as they last left
202
+ /// it and does not count what this call has just handed over, because a
203
+ /// broadcast is dispatched per reactor rather than per peer. Good enough to
204
+ /// pace a periodic fan-out; when precise backpressure matters — a file
205
+ /// transfer, a large stream — address peers individually with send().
206
+ bool broadcast(std::string_view channel, ByteView payload);
207
+
208
+ /// Whether a peer's send queue currently has room — the same answer send()
209
+ /// returns, without sending anything. False for a peer that is not connected.
210
+ /// Note that the answer describes the queue as the reactor last left it: a
211
+ /// message handed over a moment ago may not be counted yet, which is why the
212
+ /// signal to stop is the *return of send()* rather than a poll before it.
213
+ bool peer_writable(const PeerId& id) const;
214
+
215
+ // — events (register before start(); invoked on a reactor thread). Multiple
216
+ // listeners are supported, so subsystems and the app can both subscribe. —
217
+ /// Subscribe to peer-connected events. The handler runs on a reactor thread.
218
+ void on_peer_connected(PeerNetwork::PeerEventHandler cb) override { peer_connected_.push_back(std::move(cb)); }
219
+ /// Subscribe to peer-disconnected events. The handler runs on a reactor thread.
220
+ void on_peer_disconnected(PeerNetwork::PeerDisconnectHandler cb) override { peer_disconnected_.push_back(std::move(cb)); }
221
+ /// Subscribe to failed-outbound-dial events. The handler runs on a reactor thread.
222
+ void on_dial_failed(PeerNetwork::DialFailedHandler cb) override { dial_failed_.push_back(std::move(cb)); }
223
+ /// Subscribe to "this peer can be written to again" — fired when a peer whose
224
+ /// send queue had filled past its mark has drained back under it. The other
225
+ /// half of send() returning false; an application that never checks that
226
+ /// return never needs this. The handler runs on a reactor thread.
227
+ void on_peer_writable(PeerNetwork::PeerEventHandler cb) override { peer_writable_.push_back(std::move(cb)); }
228
+ /// Register a handler for inbound messages on a named channel. Additive:
229
+ /// multiple handlers may coexist. The handler runs on a reactor thread.
230
+ void on(std::string_view channel, MessageRouter::Handler cb) { router_.on_channel(channel, std::move(cb)); }
231
+
232
+ // — typed lookup of an attached subsystem (nullptr if none of that type) —
233
+ // reaches a module's own API without threading a pointer from add_subsystem:
234
+ // if (auto* j = node.json()) j->on("chat", …);
235
+ template <class T>
236
+ T* subsystem() noexcept {
237
+ for (auto& s : subsystems_) if (auto* p = dynamic_cast<T*>(s.get())) return p;
238
+ return nullptr;
239
+ }
240
+ /// The JSON messaging module if one was attached (add_subsystem<MessageJson>),
241
+ /// else nullptr. Convenience over subsystem<MessageJson>(); defined in node.cpp.
242
+ MessageJson* json() noexcept;
243
+
244
+ // — PeerNetwork (for subsystems) —
245
+ bool send(const PeerId& to, MessageType type, ByteView payload) override;
246
+ bool broadcast(MessageType type, ByteView payload) override;
247
+ std::vector<PeerId> connected_peers() const override;
248
+ void on(MessageType type, PeerNetwork::MessageHandler cb) override { router_.on_type(type, std::move(cb)); }
249
+
250
+ private:
251
+ friend class Peer;
252
+
253
+ // ConnectionDelegate (reactor thread)
254
+ bool admit_inbound() override;
255
+ void on_established(Connection& conn) override;
256
+ void on_frame(Connection& conn, const Frame& frame) override;
257
+ void on_closed(Connection& conn, CloseReason reason) override;
258
+ void on_writable_changed(Connection& conn, bool writable) override;
259
+ void on_dial_aborted(uint8_t reactor_index, ConnId id,
260
+ const std::string& host, uint16_t port) override;
261
+
262
+ /// Open the listeners the config asks for, keeping both transports on one
263
+ /// port. Sets listen_socket_/udp_socket_/listen_port_/transports_.
264
+ bool open_listeners();
265
+ /// Report a target every dial attempt failed on (called by the Dialer).
266
+ void report_dial_failed(const std::string& host, uint16_t port);
267
+
268
+ Peer make_peer(const PeerId& id, PeerRoute route) { return Peer(id, route, *this); }
269
+ void route_send(PeerRoute route, FrameHeader header, Bytes payload,
270
+ std::shared_ptr<std::atomic<size_t>> owed = nullptr);
271
+ /// Bytes a peer may have queued (in the connection) or in transit to its
272
+ /// reactor before send() starts answering "no room". Derived from the same
273
+ /// config knob that sets the hard limit, so the two cannot drift apart.
274
+ size_t send_low_water() const noexcept;
275
+ void route_close(PeerRoute route);
276
+
277
+ // — identify: how peers learn each other's dialable addresses (reactor thread) —
278
+ void send_identify(Connection& conn); ///< on establish
279
+ void handle_identify(Connection& conn, const Frame& frame); ///< Control frame
280
+ std::vector<Address> advertised_addresses() const; ///< our dialable addrs (sent in identify)
281
+ void rebuild_advertised_addresses(const std::vector<std::string>& local_ips);
282
+ void record_observed_address(const Address& addr);
283
+ /// Whether `addr` is an endpoint this node holds itself — i.e. a peer reporting
284
+ /// it saw us there saw no NAT in between. Compares against the advertised set.
285
+ bool is_own_endpoint(const Address& addr) const;
286
+
287
+ void start_network_monitor(); ///< spin up the monitor + maintenance thread
288
+ void stop_network_monitor(); ///< stop the monitor, drain + join maintenance
289
+ void maintenance_loop(); ///< off-monitor thread: emits NetworkChanged
290
+
291
+ NodeConfig config_;
292
+ Identity identity_;
293
+ std::unique_ptr<SecurityProvider> security_;
294
+ PeerTable peers_;
295
+ MessageRouter router_;
296
+ EventBus events_; ///< host/cross-module notifications
297
+ ServiceRegistry services_; ///< capability lookup between modules
298
+ std::unique_ptr<ReactorPool> reactors_;
299
+ std::unique_ptr<Dialer> dialer_; ///< transport choice + fallback race
300
+
301
+ std::vector<std::unique_ptr<Subsystem>> subsystems_;
302
+
303
+ // Host network-change watch. The monitor signals on its own thread; the
304
+ // maintenance thread does the (possibly blocking) EventBus emit off it, so
305
+ // subscribers may run slow recovery without stalling change detection.
306
+ std::unique_ptr<NetworkMonitor> monitor_;
307
+ std::thread maintenance_thread_;
308
+ std::mutex maintenance_mutex_;
309
+ std::condition_variable maintenance_cv_;
310
+ std::vector<std::string> pending_addresses_;
311
+ bool maintenance_pending_ = false;
312
+ bool maintenance_stop_ = false;
313
+
314
+ socket_t listen_socket_ = RATS_INVALID_SOCKET; ///< TCP listener
315
+ socket_t udp_socket_ = RATS_INVALID_SOCKET; ///< shared datagram socket
316
+ uint16_t listen_port_ = 0; ///< bound by both transports
317
+ uint8_t transports_ = 0; ///< PeerTransports bitmask actually running
318
+ std::atomic<bool> running_{false};
319
+ std::atomic<size_t> max_peers_{0}; ///< established-peer cap; 0 = unlimited
320
+
321
+ std::vector<PeerNetwork::PeerEventHandler> peer_connected_;
322
+ std::vector<PeerNetwork::PeerDisconnectHandler> peer_disconnected_;
323
+ std::vector<PeerNetwork::DialFailedHandler> dial_failed_;
324
+ std::vector<PeerNetwork::PeerEventHandler> peer_writable_;
325
+
326
+ // Our own addresses as peers observe us (their reported IP + our listen port).
327
+ mutable std::mutex observed_mutex_;
328
+ std::vector<Address> observed_addresses_;
329
+
330
+ // The datagram half of the same knowledge, which is a different thing: what a
331
+ // peer sees on a UDP link is our NAT's mapping of the one shared socket, port
332
+ // included, and several peers' views of it are what say whether that mapping is
333
+ // stable enough to punch through. Published as ExternalAddressService.
334
+ NatStatus nat_status_;
335
+
336
+ // The dialable addresses we advertise to peers in identify. Derived from local
337
+ // interfaces (and, in future, promoted observed addresses). Rebuilt once at
338
+ // start() and on NetworkMonitor changes — never re-enumerated per connection,
339
+ // since interface enumeration is a syscall and the send path is hot.
340
+ mutable std::mutex advertised_mutex_;
341
+ std::vector<Address> advertised_addresses_;
342
+ };
343
+
344
+ } // namespace librats
@@ -0,0 +1,33 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file node_context.h
5
+ * @brief What a subsystem receives at attach() — the node's gift to its plugins.
6
+ *
7
+ * Bundles the three ways a subsystem reaches the rest of the node, each a separate
8
+ * concern so none becomes a god-object:
9
+ *
10
+ * - `network` — the peer mesh (send/broadcast/connect/on_message…). See PeerNetwork.
11
+ * - `events` — fire-and-forget notifications, one→many, no return. See EventBus.
12
+ * - `services` — targeted synchronous calls by capability interface, one→one,
13
+ * with a return value. See ServiceRegistry.
14
+ *
15
+ * Rule of thumb: "something happened" → events; "do X / give me Y from module Z"
16
+ * → services; talking to peers → network. A subsystem stores only what it needs
17
+ * (most keep just `&ctx.network`). The references stay valid for the node's life;
18
+ * subscribe / provide during attach(), before start().
19
+ */
20
+
21
+ #include "librats/node/peer_network.h"
22
+ #include "librats/core/event_bus.h"
23
+ #include "librats/core/service_registry.h"
24
+
25
+ namespace librats {
26
+
27
+ struct NodeContext {
28
+ PeerNetwork& network;
29
+ EventBus& events;
30
+ ServiceRegistry& services;
31
+ };
32
+
33
+ } // namespace librats
@@ -0,0 +1,91 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file peer_network.h
5
+ * @brief The narrow contract a subsystem needs from the node — and nothing more.
6
+ *
7
+ * Subsystems (DHT, GossipSub, file transfer, …) talk to the network only through
8
+ * PeerNetwork. They never see Node's internals, never hold a Node& or are
9
+ * `friend`s of it — this narrow contract is what keeps the node a small core
10
+ * instead of a god-class that every feature reaches into.
11
+ * A subsystem is mocked in tests by implementing this one interface.
12
+ */
13
+
14
+ #include "librats/util/rats_export.h"
15
+ #include "librats/core/bytes.h"
16
+ #include "librats/wire/frame.h" // MessageType
17
+ #include "librats/peer/peer_id.h"
18
+ #include "librats/peer/peer_info.h"
19
+ #include "librats/core/address.h"
20
+
21
+ #include <cstdint>
22
+ #include <functional>
23
+ #include <string>
24
+ #include <vector>
25
+
26
+ namespace librats {
27
+
28
+ class Peer;
29
+
30
+ class RATS_API PeerNetwork {
31
+ public:
32
+ virtual ~PeerNetwork() = default;
33
+ using MessageHandler = std::function<void(const Peer&, ByteView)>;
34
+
35
+ using PeerEventHandler = std::function<void(const Peer&)>;
36
+ using PeerDisconnectHandler = std::function<void(const PeerId&)>;
37
+ using DialFailedHandler = std::function<void(const Address&)>;
38
+
39
+ virtual const PeerId& local_id() const = 0;
40
+ virtual uint16_t listen_port() const = 0; ///< our advertised listen port (shared by both transports)
41
+ /// Which transports that port actually accepts, as a PeerTransports bitmask —
42
+ /// the same value identify reports to peers. A subsystem that has to make the
43
+ /// port reachable from outside (PortMappingService) needs to know which
44
+ /// protocols to ask the router for. Default: TCP only, which is all a mock that
45
+ /// merely moves messages has to claim.
46
+ virtual uint8_t transports() const { return PeerTransportTcp; }
47
+ virtual const std::string& protocol() const = 0; ///< app protocol id (e.g. "librats/1.0"); namespaces discovery
48
+ virtual void connect(const Address& address) = 0; ///< dial a discovered peer
49
+ /// Send to one peer. @return whether that peer's send queue still has room;
50
+ /// false means "stop and wait for on_peer_writable" — the message is queued
51
+ /// either way, but continuing past this is what gets a peer dropped as a slow
52
+ /// consumer. Also false if the peer is not connected.
53
+ virtual bool send(const PeerId& to, MessageType type, ByteView payload) = 0;
54
+ /// Send to every connected peer. @return whether *every* one of them still
55
+ /// has room, so a subsystem that fans out can pause on the slowest.
56
+ virtual bool broadcast(MessageType type, ByteView payload) = 0;
57
+ virtual std::vector<PeerId> connected_peers() const = 0;
58
+ virtual std::vector<PeerInfo> peers() const = 0; ///< snapshot incl. dialable addresses
59
+ virtual void on(MessageType type, MessageHandler handler) = 0;
60
+
61
+ // Lifecycle hooks. Multiple subsystems (and the application) may subscribe;
62
+ // all run on a reactor thread. Register before start().
63
+ virtual void on_peer_connected(PeerEventHandler handler) = 0;
64
+ virtual void on_peer_disconnected(PeerDisconnectHandler handler) = 0;
65
+ // An outbound dial WE initiated closed before it ever established (TCP connect
66
+ // refused/timed out, or the handshake failed). Carries the address we dialed.
67
+ // There is no on_peer_disconnected for a connection that never came up, so this
68
+ // is the only signal a redial policy gets that an in-flight dial has resolved.
69
+ virtual void on_dial_failed(DialFailedHandler handler) = 0;
70
+ /// A peer whose send queue had filled up has drained back under its mark, so
71
+ /// sending to it may resume. The counterpart of send() returning false; a
72
+ /// subsystem that never checks that return never needs this either. Runs on a
73
+ /// reactor thread. Default: not offered (nothing subscribes).
74
+ virtual void on_peer_writable(PeerEventHandler /*handler*/) {}
75
+ };
76
+
77
+ struct NodeContext; // node/node_context.h — bundles network + events + services
78
+
79
+ /// A pluggable network subsystem. Owns its own threads/sockets if it needs them;
80
+ /// reaches the rest of the node only through the NodeContext it is attached to
81
+ /// (the peer mesh via ctx.network, host events via ctx.events, sibling modules via
82
+ /// ctx.services). A subsystem is mocked in tests by faking those interfaces.
83
+ class RATS_API Subsystem {
84
+ public:
85
+ virtual ~Subsystem() = default;
86
+ virtual void attach(NodeContext& ctx) = 0;
87
+ virtual void start() = 0;
88
+ virtual void stop() = 0;
89
+ };
90
+
91
+ } // namespace librats
@@ -0,0 +1,49 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file peer.h
5
+ * @brief A lightweight handle to a connected peer.
6
+ *
7
+ * Peer is a value passed to callbacks. It carries the peer's id and its
8
+ * route (which reactor + connection), so send()/disconnect() reach the right
9
+ * reactor directly — no PeerTable lookup on the reply path. info() does
10
+ * consult the directory, on demand, for metadata.
11
+ */
12
+
13
+ #include "librats/util/rats_export.h"
14
+ #include "librats/core/bytes.h"
15
+ #include "librats/peer/peer_id.h"
16
+ #include "librats/peer/peer_info.h"
17
+ #include "librats/peer/peer_table.h" // PeerRoute
18
+
19
+ #include <optional>
20
+ #include <string_view>
21
+
22
+ namespace librats {
23
+
24
+ class Node;
25
+
26
+ class RATS_API Peer {
27
+ public:
28
+ const PeerId& id() const noexcept { return id_; }
29
+
30
+ /// Send bytes on a named application channel.
31
+ void send(std::string_view channel, ByteView payload) const;
32
+
33
+ /// Request this peer be disconnected.
34
+ void disconnect() const;
35
+
36
+ /// Look up the peer's metadata in the directory (nullopt if gone).
37
+ std::optional<PeerInfo> info() const;
38
+
39
+ private:
40
+ friend class Node;
41
+ Peer(PeerId id, PeerRoute route, Node& node)
42
+ : id_(std::move(id)), route_(route), node_(&node) {}
43
+
44
+ PeerId id_;
45
+ PeerRoute route_;
46
+ Node* node_;
47
+ };
48
+
49
+ } // namespace librats