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
@@ -31,8 +31,8 @@
31
31
 
32
32
 
33
33
 
34
- #include "network_utils.h"
35
- #include "logger.h"
34
+ #include "librats/util/network_utils.h"
35
+ #include "librats/util/logger.h"
36
36
  #include <cstring>
37
37
  #include <iostream>
38
38
  #include <vector>
@@ -278,7 +278,18 @@ std::string resolve_hostname_v6(const std::string& hostname) {
278
278
  LOG_NETUTILS_DEBUG("Already an IPv6 address: " << hostname);
279
279
  return hostname;
280
280
  }
281
-
281
+
282
+ // An IPv4 literal has no genuine IPv6 form, so report "no v6" and let the
283
+ // caller dial it over IPv4. Without this, macOS/BSD getaddrinfo() synthesises
284
+ // an IPv4-mapped "::ffff:a.b.c.d" for a numeric IPv4 host even without
285
+ // AI_V4MAPPED (Linux/Windows return an error here). That made us dial IPv4
286
+ // endpoints over an AF_INET6 socket, so getpeername()/remote_ip() reported
287
+ // "::ffff:127.0.0.1" instead of "127.0.0.1"
288
+ if (is_valid_ipv4(hostname)) {
289
+ LOG_NETUTILS_DEBUG("IPv4 literal has no IPv6 form: " << hostname);
290
+ return "";
291
+ }
292
+
282
293
  struct addrinfo hints, *result;
283
294
  memset(&hints, 0, sizeof(hints));
284
295
  hints.ai_family = AF_INET6;
@@ -396,13 +407,11 @@ bool is_hostname(const std::string& str) {
396
407
  return true;
397
408
  }
398
409
 
399
- bool is_public_ip(const std::string& ip) {
400
- if (ip.empty()) return false;
410
+ bool is_public_ip(const IpAddress& ip) {
411
+ const ByteView bytes = ip.bytes();
401
412
 
402
- if (is_valid_ipv6(ip)) {
403
- struct in6_addr a;
404
- if (inet_pton(AF_INET6, ip.c_str(), &a) != 1) return false;
405
- const uint8_t* b = a.s6_addr;
413
+ if (ip.is_v6()) {
414
+ const uint8_t* b = bytes.data();
406
415
  bool all_zero = true;
407
416
  for (int i = 0; i < 16; ++i) { if (b[i]) { all_zero = false; break; } }
408
417
  if (all_zero) return false; // :: (unspecified)
@@ -415,20 +424,26 @@ bool is_public_ip(const std::string& ip) {
415
424
  return true;
416
425
  }
417
426
 
418
- struct in_addr a;
419
- if (inet_pton(AF_INET, ip.c_str(), &a) != 1) return false;
420
- uint32_t h = ntohl(a.s_addr);
421
- uint8_t o1 = static_cast<uint8_t>((h >> 24) & 0xff);
422
- uint8_t o2 = static_cast<uint8_t>((h >> 16) & 0xff);
423
- if (o1 == 0) return false; // 0.0.0.0/8
424
- if (o1 == 127) return false; // loopback
425
- if (o1 == 10) return false; // 10.0.0.0/8
426
- if (o1 == 172 && o2 >= 16 && o2 <= 31) return false; // 172.16.0.0/12
427
- if (o1 == 192 && o2 == 168) return false; // 192.168.0.0/16
428
- if (o1 == 169 && o2 == 254) return false; // 169.254.0.0/16 link-local
429
- if (o1 == 100 && o2 >= 64 && o2 <= 127) return false; // 100.64.0.0/10 CGNAT
430
- if (o1 >= 224) return false; // multicast / reserved
431
- return true;
427
+ if (ip.is_v4()) {
428
+ const uint8_t* b = bytes.data();
429
+ const uint8_t o1 = b[0], o2 = b[1];
430
+ if (o1 == 0) return false; // 0.0.0.0/8
431
+ if (o1 == 127) return false; // loopback
432
+ if (o1 == 10) return false; // 10.0.0.0/8
433
+ if (o1 == 172 && o2 >= 16 && o2 <= 31) return false; // 172.16.0.0/12
434
+ if (o1 == 192 && o2 == 168) return false; // 192.168.0.0/16
435
+ if (o1 == 169 && o2 == 254) return false; // 169.254.0.0/16 link-local
436
+ if (o1 == 100 && o2 >= 64 && o2 <= 127) return false; // 100.64.0.0/10 CGNAT
437
+ if (o1 >= 224) return false; // multicast / reserved
438
+ return true;
439
+ }
440
+
441
+ return false; // unspecified
442
+ }
443
+
444
+ bool is_public_ip(const std::string& ip) {
445
+ const auto a = IpAddress::parse(ip);
446
+ return a && is_public_ip(*a);
432
447
  }
433
448
 
434
449
  std::vector<std::string> get_local_interface_addresses() {
@@ -1,5 +1,8 @@
1
1
  #pragma once
2
2
 
3
+ #include "librats/util/rats_export.h"
4
+ #include "librats/core/ip_address.h"
5
+
3
6
  #include <string>
4
7
  #include <vector>
5
8
 
@@ -11,35 +14,35 @@ namespace network_utils {
11
14
  * @param hostname The hostname to resolve (can be hostname or IP address)
12
15
  * @return IP address string, or empty string on error
13
16
  */
14
- std::string resolve_hostname(const std::string& hostname);
17
+ RATS_API std::string resolve_hostname(const std::string& hostname);
15
18
 
16
19
  /**
17
20
  * Resolve hostname to IPv6 address
18
21
  * @param hostname The hostname to resolve (can be hostname or IPv6 address)
19
22
  * @return IPv6 address string, or empty string on error
20
23
  */
21
- std::string resolve_hostname_v6(const std::string& hostname);
24
+ RATS_API std::string resolve_hostname_v6(const std::string& hostname);
22
25
 
23
26
  /**
24
27
  * Check if a string is a valid IPv4 address
25
28
  * @param ip_str The string to validate
26
29
  * @return true if valid IPv4 address, false otherwise
27
30
  */
28
- bool is_valid_ipv4(const std::string& ip_str);
31
+ RATS_API bool is_valid_ipv4(const std::string& ip_str);
29
32
 
30
33
  /**
31
34
  * Check if a string is a valid IPv6 address
32
35
  * @param ip_str The string to validate
33
36
  * @return true if valid IPv6 address, false otherwise
34
37
  */
35
- bool is_valid_ipv6(const std::string& ip_str);
38
+ RATS_API bool is_valid_ipv6(const std::string& ip_str);
36
39
 
37
40
  /**
38
41
  * Check if a string is a hostname (not an IP address)
39
42
  * @param str The string to check
40
43
  * @return true if it's a hostname, false if it's an IP address
41
44
  */
42
- bool is_hostname(const std::string& str);
45
+ RATS_API bool is_hostname(const std::string& str);
43
46
 
44
47
  /**
45
48
  * Check whether an IP address is publicly routable (not a private/reserved range).
@@ -52,13 +55,17 @@ bool is_hostname(const std::string& str);
52
55
  * forwarding to detect a double-NAT gateway whose reported "external" IP is itself
53
56
  * private and therefore not a usable public endpoint.
54
57
  */
55
- bool is_public_ip(const std::string& ip);
58
+ RATS_API bool is_public_ip(const std::string& ip);
59
+
60
+ /// Byte-based overload: classifies directly from the address bytes, with no textual
61
+ /// re-parse. The string overload above is a thin wrapper that parses then delegates.
62
+ RATS_API bool is_public_ip(const IpAddress& ip);
56
63
 
57
64
  /**
58
65
  * Get all local network interface addresses (IPv4 and IPv6)
59
66
  * @return Vector of local IP addresses from all network interfaces
60
67
  */
61
- std::vector<std::string> get_local_interface_addresses();
68
+ RATS_API std::vector<std::string> get_local_interface_addresses();
62
69
 
63
70
  /**
64
71
  * Get the default IPv4 gateway address(es) of the host.
@@ -72,7 +79,7 @@ std::vector<std::string> get_local_interface_addresses();
72
79
  *
73
80
  * @return Vector of gateway IPv4 addresses, most specific first. May be empty.
74
81
  */
75
- std::vector<std::string> get_default_gateways();
82
+ RATS_API std::vector<std::string> get_default_gateways();
76
83
 
77
84
  } // namespace network_utils
78
85
  } // namespace librats
@@ -1,10 +1,11 @@
1
- #include "os.h"
2
- #include "logger.h"
1
+ #include "librats/util/os.h"
2
+ #include "librats/util/logger.h"
3
3
  #include <iostream>
4
4
  #include <sstream>
5
5
  #include <fstream>
6
6
  #include <thread>
7
7
  #include <cstdlib>
8
+ #include <cstring>
8
9
 
9
10
  #ifdef _WIN32
10
11
  #include <windows.h>
@@ -85,26 +86,55 @@ std::string get_hostname() {
85
86
  return "Unknown";
86
87
  }
87
88
 
89
+ // Reads the CPU name the kernel published in the registry. Works on every
90
+ // Windows architecture, and is the only option on ARM64 (no CPUID there).
91
+ static std::string get_cpu_model_from_registry() {
92
+ HKEY key;
93
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
94
+ "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
95
+ 0, KEY_READ, &key) != ERROR_SUCCESS) {
96
+ return "Unknown";
97
+ }
98
+
99
+ char name[256] = {0};
100
+ DWORD size = sizeof(name) - 1;
101
+ DWORD type = 0;
102
+ LONG result = RegQueryValueExA(key, "ProcessorNameString", nullptr, &type,
103
+ reinterpret_cast<LPBYTE>(name), &size);
104
+ RegCloseKey(key);
105
+
106
+ if (result != ERROR_SUCCESS || type != REG_SZ) {
107
+ return "Unknown";
108
+ }
109
+
110
+ std::string model(name);
111
+ // Trim whitespace
112
+ size_t first = model.find_first_not_of(" \t");
113
+ if (first == std::string::npos) {
114
+ return "Unknown";
115
+ }
116
+ model = model.substr(first, model.find_last_not_of(" \t") - first + 1);
117
+ return model;
118
+ }
119
+
88
120
  std::string get_cpu_model() {
121
+ #if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__)
89
122
  int CPUInfo[4] = {-1};
90
- unsigned nExIds, i = 0;
91
- char CPUBrandString[0x40];
92
-
123
+ char CPUBrandString[0x40] = {0};
124
+
93
125
  __cpuid(CPUInfo, 0x80000000);
94
- nExIds = CPUInfo[0];
95
-
96
- for (i = 0x80000000; i <= nExIds; ++i) {
97
- __cpuid(CPUInfo, i);
98
-
99
- if (i == 0x80000002)
100
- memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
101
- else if (i == 0x80000003)
102
- memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
103
- else if (i == 0x80000004)
104
- memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
126
+ unsigned nExIds = static_cast<unsigned>(CPUInfo[0]);
127
+
128
+ if (nExIds >= 0x80000004) {
129
+ for (unsigned i = 0x80000002; i <= 0x80000004; ++i) {
130
+ __cpuid(CPUInfo, static_cast<int>(i));
131
+ memcpy(CPUBrandString + (i - 0x80000002) * sizeof(CPUInfo), CPUInfo, sizeof(CPUInfo));
132
+ }
133
+ return std::string(CPUBrandString);
105
134
  }
106
-
107
- return std::string(CPUBrandString);
135
+ #endif
136
+ // ARM/ARM64 (and x86 CPUs without the brand string leaf)
137
+ return get_cpu_model_from_registry();
108
138
  }
109
139
 
110
140
  int get_cpu_cores() {
@@ -0,0 +1,69 @@
1
+ #pragma once
2
+
3
+ // How this copy of librats was built: RATS_SEARCH_FEATURES, RATS_STORAGE and — for
4
+ // the shared build — RATS_IMPORT_DLL, generated by CMake. Included here because
5
+ // nearly every public header pulls in rats_export.h, so the macros are set before
6
+ // anything tests them (RATS_API below included). See features.h.in for why the
7
+ // compile definitions in CMakeLists.txt are not sufficient on their own.
8
+ #include "librats/util/features.h"
9
+
10
+ /**
11
+ * @file rats_export.h
12
+ * @brief Symbol visibility for the shared build.
13
+ *
14
+ * RATS_API marks the supported public surface — the types and functions that
15
+ * cross the library boundary. It is what makes `RATS_SHARED_LIBRARY=ON` usable:
16
+ * on MSVC a symbol without __declspec(dllexport) simply is not in the DLL, so an
17
+ * unmarked class links fine in a static build and fails to link in a shared one.
18
+ *
19
+ * Three states, selected by the build:
20
+ * - RATS_EXPORT_DLL — set PRIVATE while compiling the shared library itself.
21
+ * Tested first, so it wins over the RATS_IMPORT_DLL that features.h also
22
+ * defines in a shared build.
23
+ * - RATS_IMPORT_DLL — consumers of the shared library get __declspec(dllimport).
24
+ * It arrives from the generated features.h (and, redundantly, as an INTERFACE
25
+ * define on the exported target), so it reaches a consumer whether or not it
26
+ * goes through the CMake target — Conan's CMakeDeps and vcpkg's MSBuild
27
+ * integration both bypass ratsConfig.cmake.
28
+ * - neither — the static build, where RATS_API expands to nothing.
29
+ *
30
+ * Marking a class exports every member, including private ones and the vtable;
31
+ * that is deliberate, because inline members in these headers reach privates.
32
+ * A class whose members are all defined inline in the header needs no marking —
33
+ * the consumer's compiler emits them. The abstract interfaces (Subsystem,
34
+ * PeerNetwork, ConnectionDelegate, …) are marked anyway: MSVC warns C4275 when an
35
+ * exported class derives from a non-exported base.
36
+ *
37
+ */
38
+
39
+ #ifdef _WIN32
40
+ #if defined(RATS_EXPORT_DLL)
41
+ #define RATS_API __declspec(dllexport)
42
+ #elif defined(RATS_IMPORT_DLL)
43
+ #define RATS_API __declspec(dllimport)
44
+ #else
45
+ #define RATS_API
46
+ #endif
47
+
48
+ #if defined(_MSC_VER) && (defined(RATS_EXPORT_DLL) || defined(RATS_IMPORT_DLL))
49
+ // C4251: an exported class has a std:: data member that is not itself
50
+ // exported (Node alone has vector/mutex/thread/unique_ptr/atomic members).
51
+ // C4275: an exported class derives from a non-exported base.
52
+ //
53
+ // Both warn about the same thing: the layout of those members must match on
54
+ // both sides of the DLL. That is already a hard requirement here — the public
55
+ // API passes std::string/std::vector/std::function by value, so a consumer
56
+ // must build with the same toolset, the same runtime (/MD) and the same
57
+ // _ITERATOR_DEBUG_LEVEL regardless. Conan and vcpkg enforce it via the
58
+ // profile/triplet. Silenced for the whole translation unit rather than
59
+ // per-class so consumers including these headers stay warning-clean.
60
+ #pragma warning(disable: 4251)
61
+ #pragma warning(disable: 4275)
62
+ #endif
63
+ #else
64
+ #if __GNUC__ >= 4
65
+ #define RATS_API __attribute__((visibility("default")))
66
+ #else
67
+ #define RATS_API
68
+ #endif
69
+ #endif
@@ -1,7 +1,7 @@
1
- #include "version.h"
1
+ #include "librats/util/version.h"
2
2
  #include <iostream>
3
3
  #include <iomanip>
4
- #include "rats_export.h"
4
+ #include "librats/util/rats_export.h"
5
5
 
6
6
  namespace librats {
7
7
  namespace version {
@@ -1,6 +1,6 @@
1
1
  #pragma once
2
2
 
3
- #include "rats_export.h"
3
+ #include "librats/util/rats_export.h"
4
4
 
5
5
  // This file is auto-generated by CMake. Do not edit manually.
6
6
  #define LIBRATS_VERSION_MAJOR @VERSION_MAJOR@
@@ -0,0 +1,76 @@
1
+ #include "librats/wire/frame.h"
2
+ #include "librats/core/socket.h" // htonl/htons/ntohl/ntohs (winsock or arpa/inet)
3
+
4
+ #include <cstring>
5
+
6
+ namespace librats {
7
+ namespace framer {
8
+
9
+ // ── Outer block ─────────────────────────────────────────────────────────────
10
+
11
+ void encode_block_header(uint8_t* out, size_t body_size) {
12
+ const uint32_t net_len = htonl(static_cast<uint32_t>(body_size));
13
+ std::memcpy(out, &net_len, kLengthPrefixSize);
14
+ }
15
+
16
+ void encode_block(Bytes& out, ByteView body) {
17
+ const size_t at = out.size();
18
+ out.resize(at + kLengthPrefixSize + body.size());
19
+
20
+ uint8_t* p = out.data() + at;
21
+ encode_block_header(p, body.size());
22
+ if (!body.empty()) std::memcpy(p + kLengthPrefixSize, body.data(), body.size());
23
+ }
24
+
25
+ Block try_take_block(const uint8_t* data, size_t size) {
26
+ Block out;
27
+ if (size < kLengthPrefixSize) { out.status = Block::Incomplete; return out; }
28
+
29
+ uint32_t net_len = 0;
30
+ std::memcpy(&net_len, data, 4);
31
+ const uint32_t len = ntohl(net_len);
32
+
33
+ if (len > kMaxBlockSize) { out.status = Block::Error; return out; }
34
+
35
+ const size_t total = kLengthPrefixSize + len;
36
+ out.needed = total; // the prefix is in: we now know the whole block's size
37
+ if (size < total) { out.status = Block::Incomplete; return out; }
38
+
39
+ out.status = Block::Ok;
40
+ out.consumed = total;
41
+ out.body = ByteView(data + kLengthPrefixSize, len);
42
+ return out;
43
+ }
44
+
45
+ // ── Inner message ───────────────────────────────────────────────────────────
46
+
47
+ void encode_message(Bytes& out, FrameHeader header, ByteView payload) {
48
+ const size_t at = out.size();
49
+ out.resize(at + kHeaderSize + payload.size());
50
+
51
+ uint8_t* p = out.data() + at;
52
+ *p++ = static_cast<uint8_t>(header.type);
53
+ *p++ = header.flags;
54
+ const uint16_t net_ch = htons(header.channel);
55
+ std::memcpy(p, &net_ch, 2);
56
+ p += 2;
57
+ if (!payload.empty()) std::memcpy(p, payload.data(), payload.size());
58
+ }
59
+
60
+ Message parse_message(ByteView inner) {
61
+ Message out;
62
+ if (inner.size() < kHeaderSize) return out; // ok stays false
63
+
64
+ const uint8_t* p = inner.data();
65
+ out.frame.header.type = static_cast<MessageType>(p[0]);
66
+ out.frame.header.flags = p[1];
67
+ uint16_t net_ch = 0;
68
+ std::memcpy(&net_ch, p + 2, 2);
69
+ out.frame.header.channel = ntohs(net_ch);
70
+ out.frame.payload = ByteView(p + kHeaderSize, inner.size() - kHeaderSize);
71
+ out.ok = true;
72
+ return out;
73
+ }
74
+
75
+ } // namespace framer
76
+ } // namespace librats
@@ -0,0 +1,111 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file frame.h
5
+ * @brief Two-level wire framing: outer length-prefixed blocks, inner messages.
6
+ *
7
+ * The wire is a stream of length-prefixed **blocks**:
8
+ *
9
+ * ┌──────────────┬───────────────────────────┐
10
+ * │ length (u32) │ body │
11
+ * │ 4 bytes │ length bytes │
12
+ * └──────────────┴───────────────────────────┘
13
+ *
14
+ * A block's body is opaque at this layer. The Connection uses it for two things:
15
+ *
16
+ * - during the handshake, the body is a raw handshake message (Noise / id);
17
+ * - once established, the body is the Session-encrypted bytes of an inner
18
+ * **message**, which has its own fixed 4-byte header:
19
+ *
20
+ * ┌──────┬───────┬─────────┬───────────────┐
21
+ * │ type │ flags │ channel │ payload … │
22
+ * │ u8 │ u8 │ u16 │ │
23
+ * └──────┴───────┴─────────┴───────────────┘
24
+ *
25
+ * Splitting "outer block" from "inner message" keeps encryption clean: the
26
+ * cipher wraps the whole inner message (type included), and the block layer
27
+ * never needs to understand it. Decoding is zero-copy — views point into the
28
+ * caller's buffer and are valid only until it is consumed.
29
+ */
30
+
31
+ #include "librats/util/rats_export.h"
32
+ #include "librats/core/bytes.h"
33
+
34
+ #include <cstdint>
35
+
36
+ namespace librats {
37
+
38
+ /// Inner-message kind. Application traffic uses App, addressed by `channel`.
39
+ enum class MessageType : uint8_t {
40
+ App = 1,
41
+ Control = 2, ///< core control plane (peer exchange…)
42
+ Gossip = 3,
43
+ FileChunk = 4,
44
+ Ping = 5, ///< liveness / RTT (PingService)
45
+ Storage = 6, ///< distributed key-value store (StorageManager)
46
+ Typed = 7, ///< typed JSON message exchange (MessageJson)
47
+ Pex = 8, ///< peer exchange — gossip of known peer addresses (PeerExchange)
48
+ Punch = 9, ///< NAT hole-punch rendezvous, relayed peer→peer (HolePunch)
49
+ Relay = 10, ///< relayed circuits: a peer's connection carried through a third node (Relay)
50
+ };
51
+
52
+ /// Fixed header of an inner message.
53
+ struct FrameHeader {
54
+ MessageType type = MessageType::App;
55
+ uint8_t flags = 0;
56
+ uint16_t channel = 0; ///< interned application channel id (0 for non-App)
57
+ };
58
+
59
+ /// A decoded inner message. `payload` is a non-owning view into the source bytes.
60
+ struct Frame {
61
+ FrameHeader header;
62
+ ByteView payload;
63
+ };
64
+
65
+ namespace framer {
66
+
67
+ constexpr size_t kLengthPrefixSize = 4;
68
+ constexpr size_t kHeaderSize = 4; ///< type+flags+channel
69
+ constexpr uint32_t kMaxBlockSize = 64u * 1024 * 1024; ///< body cap
70
+
71
+ // ── Outer block (length-prefixed opaque body) ───────────────────────────────
72
+
73
+ /// Append `[u32 len][body]` to `out`.
74
+ RATS_API void encode_block(Bytes& out, ByteView body);
75
+
76
+ /// Write just the `[u32 len]` prefix into `out` (exactly kLengthPrefixSize bytes).
77
+ /// The send path uses this to queue the prefix as its own gather slice, so the body
78
+ /// — an encrypted frame, possibly megabytes — never has to be copied to be framed.
79
+ RATS_API void encode_block_header(uint8_t* out, size_t body_size);
80
+
81
+ struct RATS_API Block {
82
+ enum Status { Ok, Incomplete, Error } status = Incomplete;
83
+ size_t consumed = 0; ///< bytes to consume from the buffer (when Ok)
84
+ ByteView body{}; ///< the block body (when Ok); views the input
85
+
86
+ /// Total size of this block on the wire (prefix + body), known as soon as the
87
+ /// prefix has been read; 0 while the prefix itself is still incomplete. On an
88
+ /// Incomplete block this is what the receive path needs before it can parse,
89
+ /// so it can size the buffer for the whole block in one allocation instead of
90
+ /// climbing to it 1.5x at a time.
91
+ size_t needed = 0;
92
+ };
93
+
94
+ /// Try to take one block from the front of `[data, data+size)` without copying.
95
+ RATS_API Block try_take_block(const uint8_t* data, size_t size);
96
+
97
+ // ── Inner message (fixed header + payload, no length prefix) ─────────────────
98
+
99
+ /// Append `[type][flags][channel][payload]` to `out` (no length prefix).
100
+ RATS_API void encode_message(Bytes& out, FrameHeader header, ByteView payload);
101
+
102
+ struct Message {
103
+ bool ok = false;
104
+ Frame frame{};
105
+ };
106
+
107
+ /// Parse an inner message from `inner` (header + payload). `ok` false if short.
108
+ RATS_API Message parse_message(ByteView inner);
109
+
110
+ } // namespace framer
111
+ } // namespace librats
@@ -0,0 +1,45 @@
1
+ #include "librats/wire/message_router.h"
2
+ #include "librats/util/logger.h"
3
+
4
+ namespace librats {
5
+
6
+ uint16_t MessageRouter::channel_id(std::string_view name) {
7
+ // FNV-1a (32-bit) folded to 16 bits — deterministic across nodes/runs.
8
+ uint32_t hash = 2166136261u;
9
+ for (char c : name) {
10
+ hash ^= static_cast<uint8_t>(c);
11
+ hash *= 16777619u;
12
+ }
13
+ const uint16_t id = static_cast<uint16_t>((hash >> 16) ^ (hash & 0xFFFF));
14
+ return id == 0 ? 1 : id; // reserve 0 for "no channel"
15
+ }
16
+
17
+ void MessageRouter::on_channel(std::string_view name, Handler handler) {
18
+ const uint16_t id = channel_id(name);
19
+ auto existing = channel_names_.find(id);
20
+ if (existing != channel_names_.end() && existing->second != name) {
21
+ LOG_WARN("router", "Channel id collision: '" << name << "' and '"
22
+ << existing->second << "' both hash to " << id);
23
+ }
24
+ channel_names_[id] = std::string(name);
25
+ by_channel_[id] = std::move(handler);
26
+ }
27
+
28
+ void MessageRouter::on_type(MessageType type, Handler handler) {
29
+ by_type_[static_cast<uint8_t>(type)] = std::move(handler);
30
+ }
31
+
32
+ bool MessageRouter::dispatch(const Peer& peer, const Frame& frame) const {
33
+ if (frame.header.type == MessageType::App) {
34
+ auto it = by_channel_.find(frame.header.channel);
35
+ if (it == by_channel_.end()) return false;
36
+ it->second(peer, frame.payload);
37
+ return true;
38
+ }
39
+ const auto& handler = by_type_[static_cast<uint8_t>(frame.header.type)];
40
+ if (!handler) return false;
41
+ handler(peer, frame.payload);
42
+ return true;
43
+ }
44
+
45
+ } // namespace librats
@@ -0,0 +1,47 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file message_router.h
5
+ * @brief Routes decoded inner frames to handlers.
6
+ *
7
+ * App frames are dispatched by their `channel`; everything else by MessageType.
8
+ * Application channels are named; the name is hashed to a stable 16-bit id with
9
+ * a deterministic function so the SAME name maps to the SAME id on every node
10
+ * (no shared registry needed). Distinct names can in principle collide in the
11
+ * 16-bit space — on_channel() logs if a new name collides with a registered one.
12
+ */
13
+
14
+ #include "librats/util/rats_export.h"
15
+ #include "librats/core/bytes.h"
16
+ #include "librats/wire/frame.h"
17
+ #include "librats/peer/peer.h"
18
+
19
+ #include <array>
20
+ #include <cstdint>
21
+ #include <functional>
22
+ #include <string>
23
+ #include <string_view>
24
+ #include <unordered_map>
25
+
26
+ namespace librats {
27
+
28
+ class RATS_API MessageRouter {
29
+ public:
30
+ using Handler = std::function<void(const Peer&, ByteView)>;
31
+
32
+ /// Deterministic 16-bit channel id (FNV-1a) for a channel name.
33
+ static uint16_t channel_id(std::string_view name);
34
+
35
+ void on_channel(std::string_view name, Handler handler);
36
+ void on_type(MessageType type, Handler handler);
37
+
38
+ /// Dispatch one decoded frame to its handler, if any. Returns true if handled.
39
+ bool dispatch(const Peer& peer, const Frame& frame) const;
40
+
41
+ private:
42
+ std::unordered_map<uint16_t, Handler> by_channel_;
43
+ std::unordered_map<uint16_t, std::string> channel_names_; // for collision checks
44
+ std::array<Handler, 256> by_type_{};
45
+ };
46
+
47
+ } // namespace librats
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "librats",
3
- "version": "1.0.2",
3
+ "version": "2.2.0",
4
4
  "description": "Node.js bindings for librats - A high-performance peer-to-peer networking library",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -24,11 +24,12 @@
24
24
  "networking",
25
25
  "dht",
26
26
  "gossipsub",
27
+ "pubsub",
27
28
  "file-transfer",
28
29
  "mdns",
29
- "stun",
30
- "ice",
31
- "nat-traversal",
30
+ "nat-pmp",
31
+ "upnp",
32
+ "noise",
32
33
  "encryption",
33
34
  "native"
34
35
  ],
@@ -133,6 +133,7 @@ try {
133
133
 
134
134
  let cmakeArgs = [
135
135
  '-DRATS_BUILD_TESTS=OFF',
136
+ '-DRATS_BUILD_CLIENT=OFF',
136
137
  '-DRATS_BUILD_EXAMPLES=OFF',
137
138
  '-DRATS_STATIC_LIBRARY=ON',
138
139
  '-DRATS_BINDINGS=ON',