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