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.
- package/README.md +145 -331
- package/binding.gyp +16 -3
- package/lib/index.d.ts +288 -696
- package/lib/index.js +407 -44
- package/native-src/3rdparty/android/ifaddrs-android.c +1 -0
- package/native-src/3rdparty/android/ifaddrs-android.h +1 -0
- package/native-src/CMakeLists.txt +404 -179
- package/native-src/LICENSE +1 -1
- package/native-src/src/librats/bindings/rats.cpp +762 -0
- package/native-src/src/librats/bindings/rats.h +380 -0
- package/native-src/src/librats/bittorrent/bencode.cpp +437 -0
- package/native-src/src/librats/bittorrent/bencode.h +176 -0
- package/native-src/src/librats/bittorrent/bitfield.cpp +97 -0
- package/native-src/src/librats/bittorrent/bitfield.h +76 -0
- package/native-src/src/librats/bittorrent/byte_io.h +58 -0
- package/native-src/src/librats/bittorrent/choker.cpp +25 -0
- package/native-src/src/librats/bittorrent/choker.h +46 -0
- package/native-src/src/librats/bittorrent/client.cpp +413 -0
- package/native-src/src/librats/bittorrent/client.h +227 -0
- package/native-src/src/librats/bittorrent/disk_io.cpp +209 -0
- package/native-src/src/librats/bittorrent/disk_io.h +150 -0
- package/native-src/src/librats/bittorrent/extensions.cpp +191 -0
- package/native-src/src/librats/bittorrent/extensions.h +94 -0
- package/native-src/src/librats/bittorrent/file_storage.cpp +77 -0
- package/native-src/src/librats/bittorrent/file_storage.h +79 -0
- package/native-src/src/librats/bittorrent/log.h +42 -0
- package/native-src/src/librats/bittorrent/magnet_uri.cpp +98 -0
- package/native-src/src/librats/bittorrent/magnet_uri.h +35 -0
- package/native-src/src/librats/bittorrent/peer_connection.cpp +502 -0
- package/native-src/src/librats/bittorrent/peer_connection.h +194 -0
- package/native-src/src/librats/bittorrent/peer_list.cpp +68 -0
- package/native-src/src/librats/bittorrent/peer_list.h +75 -0
- package/native-src/src/librats/bittorrent/piece_picker.cpp +352 -0
- package/native-src/src/librats/bittorrent/piece_picker.h +201 -0
- package/native-src/src/librats/bittorrent/reactor.cpp +97 -0
- package/native-src/src/librats/bittorrent/reactor.h +89 -0
- package/native-src/src/librats/bittorrent/resume_data.cpp +72 -0
- package/native-src/src/librats/bittorrent/resume_data.h +41 -0
- package/native-src/src/librats/bittorrent/store_buffer.cpp +48 -0
- package/native-src/src/librats/bittorrent/store_buffer.h +47 -0
- package/native-src/src/librats/bittorrent/torrent.cpp +870 -0
- package/native-src/src/librats/bittorrent/torrent.h +260 -0
- package/native-src/src/librats/bittorrent/torrent_creator.cpp +129 -0
- package/native-src/src/librats/bittorrent/torrent_creator.h +58 -0
- package/native-src/src/librats/bittorrent/torrent_info.cpp +314 -0
- package/native-src/src/librats/bittorrent/torrent_info.h +118 -0
- package/native-src/src/librats/bittorrent/tracker.cpp +374 -0
- package/native-src/src/librats/bittorrent/tracker.h +108 -0
- package/native-src/src/librats/bittorrent/types.cpp +206 -0
- package/native-src/src/librats/bittorrent/types.h +86 -0
- package/native-src/src/librats/core/address.cpp +35 -0
- package/native-src/src/librats/core/address.h +78 -0
- package/native-src/src/librats/core/bytes.h +69 -0
- package/native-src/src/librats/core/chained_send_buffer.cpp +172 -0
- package/native-src/src/librats/core/chained_send_buffer.h +183 -0
- package/native-src/src/librats/core/endpoint_parse.cpp +41 -0
- package/native-src/src/librats/core/endpoint_parse.h +31 -0
- package/native-src/src/librats/core/event_bus.h +70 -0
- package/native-src/src/librats/core/host_endpoint.h +56 -0
- package/native-src/src/{io_poller.cpp → librats/core/io_poller.cpp} +520 -65
- package/native-src/src/{io_poller.h → librats/core/io_poller.h} +12 -6
- package/native-src/src/librats/core/ip_address.cpp +120 -0
- package/native-src/src/librats/core/ip_address.h +109 -0
- package/native-src/src/librats/core/mpsc_queue.h +47 -0
- package/native-src/src/librats/core/notifier.h +74 -0
- package/native-src/src/librats/core/receive_buffer.cpp +219 -0
- package/native-src/src/librats/core/receive_buffer.h +171 -0
- package/native-src/src/librats/core/service_registry.h +58 -0
- package/native-src/src/{socket.cpp → librats/core/socket.cpp} +625 -118
- package/native-src/src/librats/core/socket.h +496 -0
- package/native-src/src/librats/core/timer_queue.h +105 -0
- package/native-src/src/librats/core/types.cpp +43 -0
- package/native-src/src/librats/core/types.h +103 -0
- package/native-src/src/librats/core/wakeup_pipe.h +83 -0
- package/native-src/src/{crypto → librats/crypto}/blake2_endian.h +21 -23
- package/native-src/src/{crypto → librats/crypto}/blake2b.c +34 -33
- package/native-src/src/{crypto → librats/crypto}/blake2b.h +7 -6
- package/native-src/src/{crypto → librats/crypto}/blake2s.c +55 -54
- package/native-src/src/{crypto → librats/crypto}/blake2s.h +13 -12
- package/native-src/src/{crypto → librats/crypto}/chacha.c +22 -21
- package/native-src/src/{crypto → librats/crypto}/chacha.h +14 -13
- package/native-src/src/{crypto → librats/crypto}/chachapoly.c +56 -56
- package/native-src/src/{crypto → librats/crypto}/chachapoly.h +24 -17
- package/native-src/src/{crc32.cpp → librats/crypto/crc32.cpp} +1 -1
- package/native-src/src/{crc32.h → librats/crypto/crc32.h} +3 -1
- package/native-src/src/{crypto → librats/crypto}/curve25519.c +6 -4
- package/native-src/src/{crypto → librats/crypto}/curve25519.h +6 -3
- package/native-src/src/librats/crypto/hkdf.c +266 -0
- package/native-src/src/{crypto → librats/crypto}/hkdf.h +19 -19
- package/native-src/src/{noise.cpp → librats/crypto/noise.cpp} +84 -73
- package/native-src/src/{noise.h → librats/crypto/noise.h} +18 -8
- package/native-src/src/{crypto → librats/crypto}/poly1305.c +47 -46
- package/native-src/src/librats/crypto/poly1305.h +37 -0
- package/native-src/src/{sha1.cpp → librats/crypto/sha1.cpp} +33 -1
- package/native-src/src/{sha1.h → librats/crypto/sha1.h} +14 -6
- package/native-src/src/{crypto → librats/crypto}/sha256.c +15 -14
- package/native-src/src/{crypto → librats/crypto}/sha256.h +8 -7
- package/native-src/src/{crypto → librats/crypto}/sha512.c +15 -14
- package/native-src/src/{crypto → librats/crypto}/sha512.h +8 -7
- package/native-src/src/librats/dht/announce.cpp +37 -0
- package/native-src/src/librats/dht/announce.h +41 -0
- package/native-src/src/librats/dht/bep42.cpp +109 -0
- package/native-src/src/librats/dht/bep42.h +48 -0
- package/native-src/src/librats/dht/dht.cpp +501 -0
- package/native-src/src/librats/dht/dht.h +119 -0
- package/native-src/src/librats/dht/dht_runner.cpp +103 -0
- package/native-src/src/librats/dht/dht_runner.h +71 -0
- package/native-src/src/librats/dht/dos_blocker.cpp +42 -0
- package/native-src/src/librats/dht/dos_blocker.h +47 -0
- package/native-src/src/librats/dht/find_peers.cpp +52 -0
- package/native-src/src/librats/dht/find_peers.h +73 -0
- package/native-src/src/librats/dht/id.h +167 -0
- package/native-src/src/{krpc.cpp → librats/dht/krpc.cpp} +32 -81
- package/native-src/src/{krpc.h → librats/dht/krpc.h} +19 -23
- package/native-src/src/librats/dht/log.h +38 -0
- package/native-src/src/librats/dht/node.cpp +473 -0
- package/native-src/src/librats/dht/node.h +164 -0
- package/native-src/src/librats/dht/node_entry.h +81 -0
- package/native-src/src/librats/dht/observer.h +72 -0
- package/native-src/src/librats/dht/persistence.cpp +90 -0
- package/native-src/src/librats/dht/persistence.h +32 -0
- package/native-src/src/librats/dht/routing_table.cpp +559 -0
- package/native-src/src/librats/dht/routing_table.h +185 -0
- package/native-src/src/librats/dht/rpc_manager.cpp +127 -0
- package/native-src/src/librats/dht/rpc_manager.h +77 -0
- package/native-src/src/librats/dht/storage.cpp +92 -0
- package/native-src/src/librats/dht/storage.h +74 -0
- package/native-src/src/librats/dht/transport.h +27 -0
- package/native-src/src/librats/dht/traversal.cpp +326 -0
- package/native-src/src/librats/dht/traversal.h +120 -0
- package/native-src/src/librats/dht/udp_transport.cpp +49 -0
- package/native-src/src/librats/dht/udp_transport.h +51 -0
- package/native-src/src/librats/mdns/log.h +22 -0
- package/native-src/src/{mdns.cpp → librats/mdns/mdns.cpp} +75 -40
- package/native-src/src/{mdns.h → librats/mdns/mdns.h} +9 -8
- package/native-src/src/{natpmp.cpp → librats/nat/natpmp.cpp} +12 -9
- package/native-src/src/{natpmp.h → librats/nat/natpmp.h} +3 -3
- package/native-src/src/{port_mapping.h → librats/nat/port_mapping.h} +3 -2
- package/native-src/src/{stun.cpp → librats/nat/stun.cpp} +4 -4
- package/native-src/src/{stun.h → librats/nat/stun.h} +1 -1
- package/native-src/src/{upnp.cpp → librats/nat/upnp.cpp} +6 -6
- package/native-src/src/{upnp.h → librats/nat/upnp.h} +2 -2
- package/native-src/src/librats/node/circuit_service.h +84 -0
- package/native-src/src/librats/node/config.h +110 -0
- package/native-src/src/librats/node/dial_service.h +54 -0
- package/native-src/src/librats/node/dialer.cpp +264 -0
- package/native-src/src/librats/node/dialer.h +188 -0
- package/native-src/src/librats/node/host_events.h +26 -0
- package/native-src/src/librats/node/identify.cpp +130 -0
- package/native-src/src/librats/node/identify.h +71 -0
- package/native-src/src/librats/node/nat_status.cpp +103 -0
- package/native-src/src/librats/node/nat_status.h +118 -0
- package/native-src/src/librats/node/node.cpp +865 -0
- package/native-src/src/librats/node/node.h +344 -0
- package/native-src/src/librats/node/node_context.h +33 -0
- package/native-src/src/librats/node/peer_network.h +91 -0
- package/native-src/src/librats/peer/peer.h +49 -0
- package/native-src/src/librats/peer/peer_book.cpp +181 -0
- package/native-src/src/librats/peer/peer_book.h +88 -0
- package/native-src/src/librats/peer/peer_id.cpp +72 -0
- package/native-src/src/librats/peer/peer_id.h +62 -0
- package/native-src/src/librats/peer/peer_info.h +37 -0
- package/native-src/src/librats/peer/peer_table.cpp +170 -0
- package/native-src/src/librats/peer/peer_table.h +148 -0
- package/native-src/src/librats/security/handshaker.h +66 -0
- package/native-src/src/librats/security/identity.h +43 -0
- package/native-src/src/librats/security/noise_security.cpp +122 -0
- package/native-src/src/librats/security/noise_security.h +37 -0
- package/native-src/src/librats/security/plaintext_security.h +106 -0
- package/native-src/src/librats/security/session.h +37 -0
- package/native-src/src/{storage.cpp → librats/storage/storage.cpp} +369 -522
- package/native-src/src/{storage.h → librats/storage/storage.h} +135 -299
- package/native-src/src/librats/subsystems/bittorrent.cpp +211 -0
- package/native-src/src/librats/subsystems/bittorrent.h +136 -0
- package/native-src/src/librats/subsystems/dht_discovery.cpp +202 -0
- package/native-src/src/librats/subsystems/dht_discovery.h +123 -0
- package/native-src/src/librats/subsystems/dht_service.h +36 -0
- package/native-src/src/librats/subsystems/file_transfer.cpp +972 -0
- package/native-src/src/librats/subsystems/file_transfer.h +367 -0
- package/native-src/src/librats/subsystems/hole_punch.cpp +605 -0
- package/native-src/src/librats/subsystems/hole_punch.h +290 -0
- package/native-src/src/librats/subsystems/hole_punch_service.h +38 -0
- package/native-src/src/librats/subsystems/mdns_discovery.cpp +66 -0
- package/native-src/src/librats/subsystems/mdns_discovery.h +55 -0
- package/native-src/src/librats/subsystems/message_json.cpp +112 -0
- package/native-src/src/librats/subsystems/message_json.h +88 -0
- package/native-src/src/librats/subsystems/peer_exchange.cpp +241 -0
- package/native-src/src/librats/subsystems/peer_exchange.h +136 -0
- package/native-src/src/librats/subsystems/ping_service.cpp +98 -0
- package/native-src/src/librats/subsystems/ping_service.h +66 -0
- package/native-src/src/librats/subsystems/port_mapping_service.cpp +192 -0
- package/native-src/src/librats/subsystems/port_mapping_service.h +84 -0
- package/native-src/src/librats/subsystems/pubsub.cpp +567 -0
- package/native-src/src/librats/subsystems/pubsub.h +175 -0
- package/native-src/src/librats/subsystems/reconnection.cpp +239 -0
- package/native-src/src/librats/subsystems/reconnection.h +126 -0
- package/native-src/src/librats/subsystems/relay.cpp +1142 -0
- package/native-src/src/librats/subsystems/relay.h +211 -0
- package/native-src/src/librats/subsystems/relay_service.h +46 -0
- package/native-src/src/librats/transport/connection.cpp +343 -0
- package/native-src/src/librats/transport/connection.h +283 -0
- package/native-src/src/librats/transport/link.h +96 -0
- package/native-src/src/librats/transport/reactor.cpp +588 -0
- package/native-src/src/librats/transport/reactor.h +262 -0
- package/native-src/src/librats/transport/reactor_pool.h +81 -0
- package/native-src/src/librats/transport/relay_link.cpp +208 -0
- package/native-src/src/librats/transport/relay_link.h +303 -0
- package/native-src/src/librats/transport/tcp_link.cpp +49 -0
- package/native-src/src/librats/transport/tcp_link.h +43 -0
- package/native-src/src/librats/transport/udp_mux.cpp +617 -0
- package/native-src/src/librats/transport/udp_mux.h +363 -0
- package/native-src/src/librats/transport/udp_packet.cpp +121 -0
- package/native-src/src/librats/transport/udp_packet.h +190 -0
- package/native-src/src/librats/transport/udp_stream.cpp +1194 -0
- package/native-src/src/librats/transport/udp_stream.h +614 -0
- package/native-src/src/librats/util/features.h.in +51 -0
- package/native-src/src/{fs.cpp → librats/util/fs.cpp} +51 -3
- package/native-src/src/librats/util/fs.h +136 -0
- package/native-src/src/librats/util/json.cpp +1002 -0
- package/native-src/src/librats/util/json.h +444 -0
- package/native-src/src/{logger.cpp → librats/util/logger.cpp} +1 -1
- package/native-src/src/{logger.h → librats/util/logger.h} +43 -31
- package/native-src/src/{network_monitor.cpp → librats/util/network_monitor.cpp} +12 -4
- package/native-src/src/{network_monitor.h → librats/util/network_monitor.h} +2 -1
- package/native-src/src/{network_utils.cpp → librats/util/network_utils.cpp} +38 -23
- package/native-src/src/{network_utils.h → librats/util/network_utils.h} +15 -8
- package/native-src/src/{os.cpp → librats/util/os.cpp} +48 -18
- package/native-src/src/librats/util/rats_export.h +69 -0
- package/native-src/src/{version.cpp → librats/util/version.cpp} +2 -2
- package/native-src/src/{version.h.in → librats/util/version.h.in} +1 -1
- package/native-src/src/librats/wire/frame.cpp +76 -0
- package/native-src/src/librats/wire/frame.h +111 -0
- package/native-src/src/librats/wire/message_router.cpp +45 -0
- package/native-src/src/librats/wire/message_router.h +47 -0
- package/package.json +5 -4
- package/scripts/build-librats.js +1 -0
- package/scripts/postinstall.js +3 -3
- package/scripts/prepare-package.js +4 -4
- package/scripts/verify-installation.js +63 -105
- package/src/librats_node.cpp +1067 -1323
- package/native-src/src/bencode.cpp +0 -485
- package/native-src/src/bencode.h +0 -145
- package/native-src/src/bittorrent.cpp +0 -14
- package/native-src/src/bittorrent.h +0 -74
- package/native-src/src/bt_bitfield.cpp +0 -372
- package/native-src/src/bt_bitfield.h +0 -316
- package/native-src/src/bt_choker.cpp +0 -228
- package/native-src/src/bt_choker.h +0 -147
- package/native-src/src/bt_client.cpp +0 -1047
- package/native-src/src/bt_client.h +0 -445
- package/native-src/src/bt_create_torrent.cpp +0 -677
- package/native-src/src/bt_create_torrent.h +0 -473
- package/native-src/src/bt_extension.cpp +0 -469
- package/native-src/src/bt_extension.h +0 -309
- package/native-src/src/bt_file_storage.cpp +0 -261
- package/native-src/src/bt_file_storage.h +0 -298
- package/native-src/src/bt_handshake.cpp +0 -134
- package/native-src/src/bt_handshake.h +0 -157
- package/native-src/src/bt_messages.cpp +0 -364
- package/native-src/src/bt_messages.h +0 -324
- package/native-src/src/bt_network.cpp +0 -1007
- package/native-src/src/bt_network.h +0 -417
- package/native-src/src/bt_peer_connection.cpp +0 -742
- package/native-src/src/bt_peer_connection.h +0 -592
- package/native-src/src/bt_piece_picker.cpp +0 -786
- package/native-src/src/bt_piece_picker.h +0 -473
- package/native-src/src/bt_resume_data.cpp +0 -410
- package/native-src/src/bt_resume_data.h +0 -249
- package/native-src/src/bt_torrent.cpp +0 -2120
- package/native-src/src/bt_torrent.h +0 -641
- package/native-src/src/bt_torrent_info.cpp +0 -659
- package/native-src/src/bt_torrent_info.h +0 -418
- package/native-src/src/bt_types.h +0 -621
- package/native-src/src/chained_send_buffer.cpp +0 -75
- package/native-src/src/chained_send_buffer.h +0 -137
- package/native-src/src/crypto/hkdf.c +0 -266
- package/native-src/src/crypto/poly1305.h +0 -36
- package/native-src/src/dht.cpp +0 -3311
- package/native-src/src/dht.h +0 -717
- package/native-src/src/disk_io.cpp +0 -632
- package/native-src/src/disk_io.h +0 -315
- package/native-src/src/file_transfer.cpp +0 -1415
- package/native-src/src/file_transfer.h +0 -286
- package/native-src/src/fs.h +0 -108
- package/native-src/src/gossipsub.cpp +0 -1139
- package/native-src/src/gossipsub.h +0 -403
- package/native-src/src/ice.cpp +0 -893
- package/native-src/src/ice.h +0 -559
- package/native-src/src/json.hpp +0 -25526
- package/native-src/src/librats.cpp +0 -2378
- package/native-src/src/librats.h +0 -2324
- package/native-src/src/librats_bittorrent.cpp +0 -601
- package/native-src/src/librats_c.cpp +0 -1557
- package/native-src/src/librats_c.h +0 -323
- package/native-src/src/librats_discovery.cpp +0 -402
- package/native-src/src/librats_encryption.cpp +0 -275
- package/native-src/src/librats_file_transfer.cpp +0 -144
- package/native-src/src/librats_gossipsub.cpp +0 -289
- package/native-src/src/librats_ice.cpp +0 -213
- package/native-src/src/librats_log_macros.h +0 -36
- package/native-src/src/librats_logging.cpp +0 -173
- package/native-src/src/librats_mdns.cpp +0 -166
- package/native-src/src/librats_persistence.cpp +0 -796
- package/native-src/src/librats_portmap.cpp +0 -419
- package/native-src/src/librats_reconnection.cpp +0 -218
- package/native-src/src/librats_statistic.cpp +0 -105
- package/native-src/src/librats_storage.cpp +0 -189
- package/native-src/src/rats_export.h +0 -17
- package/native-src/src/receive_buffer.cpp +0 -82
- package/native-src/src/receive_buffer.h +0 -127
- package/native-src/src/socket.h +0 -228
- package/native-src/src/threadmanager.cpp +0 -105
- package/native-src/src/threadmanager.h +0 -53
- package/native-src/src/tracker.cpp +0 -1264
- package/native-src/src/tracker.h +0 -319
- package/native-src/src/turn.cpp +0 -762
- package/native-src/src/turn.h +0 -460
- package/native-src/src/wakeup_pipe.h +0 -60
- /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
|
|
400
|
-
|
|
410
|
+
bool is_public_ip(const IpAddress& ip) {
|
|
411
|
+
const ByteView bytes = ip.bytes();
|
|
401
412
|
|
|
402
|
-
if (
|
|
403
|
-
|
|
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
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
123
|
+
char CPUBrandString[0x40] = {0};
|
|
124
|
+
|
|
93
125
|
__cpuid(CPUInfo, 0x80000000);
|
|
94
|
-
nExIds = CPUInfo[0];
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
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
|
|
@@ -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": "
|
|
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
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
30
|
+
"nat-pmp",
|
|
31
|
+
"upnp",
|
|
32
|
+
"noise",
|
|
32
33
|
"encryption",
|
|
33
34
|
"native"
|
|
34
35
|
],
|