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,171 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file receive_buffer.h
|
|
5
|
+
* @brief Stream receive buffer: O(1) consume, amortised growth, automatic shrink.
|
|
6
|
+
*
|
|
7
|
+
* A byte stream arrives in arbitrary slices and is parsed in whole messages, so a
|
|
8
|
+
* receive buffer must hold a partial message across reads while handing complete
|
|
9
|
+
* ones to the parser. Three cursors describe it:
|
|
10
|
+
*
|
|
11
|
+
* |<-- consumed -->|<------ live ------>|<----- writable ----->|
|
|
12
|
+
* 0 start_ end_ cap_
|
|
13
|
+
*
|
|
14
|
+
* - `consumed` — already parsed; dead space, reclaimed by compact().
|
|
15
|
+
* - `live` — received but not yet parsed: data()/size().
|
|
16
|
+
* - `writable` — free tail, handed to recv() by prepare().
|
|
17
|
+
*
|
|
18
|
+
* consume() only advances `start_`, so dropping a parsed message is O(1) — the
|
|
19
|
+
* point of the class (std::vector::erase() would be O(n) per message). Draining
|
|
20
|
+
* the buffer rewinds both cursors to 0, so the steady state needs no memmove at
|
|
21
|
+
* all; a memmove only happens when the tail runs out with a partial message still
|
|
22
|
+
* live, i.e. at most once per bufferful.
|
|
23
|
+
*
|
|
24
|
+
* Memory:
|
|
25
|
+
* - Storage is raw, *uninitialised* (`new uint8_t[]`), not a std::vector: recv()
|
|
26
|
+
* overwrites it anyway, so value-initialising every byte is pure waste. It is
|
|
27
|
+
* also allocated at exactly the requested size, without the hidden ~2x
|
|
28
|
+
* over-allocation std::vector::resize() performs when it grows.
|
|
29
|
+
* - Growth is geometric (1.5x), so filling the buffer stays amortised O(1)/byte.
|
|
30
|
+
* - The buffer shrinks by itself: a running average of recent demand (the
|
|
31
|
+
* `watermark`) is sampled whenever the buffer drains, and once the allocation
|
|
32
|
+
* is more than twice that average it is reallocated down. Without this, one
|
|
33
|
+
* large message would pin a large allocation for the connection's lifetime.
|
|
34
|
+
* "Demand" is what prepare() was asked for, not merely what arrived — a caller
|
|
35
|
+
* reads with a fixed chunk size, so an allocation too small to serve the next
|
|
36
|
+
* read is not idle memory, and counting only the bytes that turned up would
|
|
37
|
+
* shrink the buffer just for the next prepare() to grow it straight back.
|
|
38
|
+
* (This mirrors libtorrent's receive_buffer watermark — which samples
|
|
39
|
+
* max(recv_end, packet_size) for the same reason — but as a plain exponential
|
|
40
|
+
* average instead of a 20-sample sliding window.)
|
|
41
|
+
*
|
|
42
|
+
* Not thread-safe: like everything on the connection path, it is owned and touched
|
|
43
|
+
* by exactly one reactor thread.
|
|
44
|
+
*
|
|
45
|
+
* Usage:
|
|
46
|
+
* ByteSpan into = buf.prepare(16 * 1024); // room for at least 16 KiB
|
|
47
|
+
* int n = recv(sock, into.data(), into.size());
|
|
48
|
+
* buf.commit(n); // n bytes are now live
|
|
49
|
+
* while (auto msg = parse(buf.data(), buf.size()))
|
|
50
|
+
* buf.consume(msg.size()); // O(1)
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
#include "librats/util/rats_export.h"
|
|
54
|
+
#include "librats/core/bytes.h"
|
|
55
|
+
|
|
56
|
+
#include <cstddef>
|
|
57
|
+
#include <cstdint>
|
|
58
|
+
#include <memory>
|
|
59
|
+
#include <utility>
|
|
60
|
+
|
|
61
|
+
namespace librats {
|
|
62
|
+
|
|
63
|
+
class RATS_API ReceiveBuffer {
|
|
64
|
+
public:
|
|
65
|
+
/// Floor for any allocation, and the size the buffer shrinks back towards.
|
|
66
|
+
static constexpr size_t kMinCapacity = 1024;
|
|
67
|
+
|
|
68
|
+
/// Starts with no allocation at all by default: a connection that never
|
|
69
|
+
/// receives anything never pays for a buffer. The first prepare() allocates.
|
|
70
|
+
explicit ReceiveBuffer(size_t initial_capacity = 0);
|
|
71
|
+
|
|
72
|
+
/// Moving leaves the source empty and unallocated — a defaulted move would carry
|
|
73
|
+
/// the cursors over while the unique_ptr went null, leaving prepare() handing out
|
|
74
|
+
/// a span into nullptr.
|
|
75
|
+
ReceiveBuffer(ReceiveBuffer&& other) noexcept { *this = std::move(other); }
|
|
76
|
+
ReceiveBuffer& operator=(ReceiveBuffer&& other) noexcept;
|
|
77
|
+
ReceiveBuffer(const ReceiveBuffer&) = delete;
|
|
78
|
+
ReceiveBuffer& operator=(const ReceiveBuffer&) = delete;
|
|
79
|
+
|
|
80
|
+
// ── Write side (recv) ───────────────────────────────────────────────────
|
|
81
|
+
|
|
82
|
+
/// Make room for at least `min_bytes` and return the writable tail. The span
|
|
83
|
+
/// is usually *larger* than asked for — pass its full size() to recv() so a
|
|
84
|
+
/// single syscall can take everything the kernel has. Invalidates data() and
|
|
85
|
+
/// any view into the buffer (it may compact or reallocate).
|
|
86
|
+
ByteSpan prepare(size_t min_bytes);
|
|
87
|
+
|
|
88
|
+
/// Publish `bytes` freshly written into the span from prepare(): they become
|
|
89
|
+
/// live. `bytes` must not exceed that span's size().
|
|
90
|
+
void commit(size_t bytes);
|
|
91
|
+
|
|
92
|
+
// ── Read side (parsing) ─────────────────────────────────────────────────
|
|
93
|
+
|
|
94
|
+
const uint8_t* data() const noexcept { return buf_.get() + start_; }
|
|
95
|
+
size_t size() const noexcept { return end_ - start_; }
|
|
96
|
+
bool empty() const noexcept { return start_ == end_; }
|
|
97
|
+
ByteView view() const noexcept { return ByteView(data(), size()); }
|
|
98
|
+
|
|
99
|
+
/// Drop `bytes` of parsed data from the front — O(1). `bytes` must not exceed
|
|
100
|
+
/// size(). Invalidates views into the consumed region only; the rest of the
|
|
101
|
+
/// live data stays put (this call never moves memory).
|
|
102
|
+
void consume(size_t bytes);
|
|
103
|
+
|
|
104
|
+
// ── Maintenance / diagnostics ───────────────────────────────────────────
|
|
105
|
+
|
|
106
|
+
/// Move the live bytes to the front, reclaiming the consumed prefix. prepare()
|
|
107
|
+
/// does this on its own when it pays off, so callers rarely need it.
|
|
108
|
+
void compact();
|
|
109
|
+
|
|
110
|
+
/// Idle tick: age the remembered demand and shrink if the allocation has outgrown
|
|
111
|
+
/// it. Call this periodically (once per keep-alive tick is plenty) from whatever
|
|
112
|
+
/// already visits the connection on a timer. May reallocate, so — like prepare() —
|
|
113
|
+
/// it invalidates data() and any view into the buffer.
|
|
114
|
+
///
|
|
115
|
+
/// The traffic-driven shrink in consume() only ever samples when a message
|
|
116
|
+
/// *arrives*, so it cannot reclaim anything from a peer that has gone quiet — and
|
|
117
|
+
/// a peer that sends one big message and then falls silent is exactly the case that
|
|
118
|
+
/// pins a big allocation. This is the other half: it halves the watermark once per
|
|
119
|
+
/// idle tick, so a silent connection halves its buffer every couple of ticks until
|
|
120
|
+
/// it is back at kMinCapacity.
|
|
121
|
+
///
|
|
122
|
+
/// A tick in which anything at all was received does not age the buffer — the
|
|
123
|
+
/// traffic-driven path already sampled it, and decaying on top of that would shrink
|
|
124
|
+
/// a live connection below its read size just for the next prepare() to grow it
|
|
125
|
+
/// straight back.
|
|
126
|
+
///
|
|
127
|
+
/// A partial message still being live does *not* stop the tick: a peer that sends
|
|
128
|
+
/// the first slice of a large frame and then stalls never drains the buffer, so
|
|
129
|
+
/// bailing out here would pin its eager allocation for the life of the connection.
|
|
130
|
+
/// The shrink never goes below the live bytes (they are moved to the front), so the
|
|
131
|
+
/// stalled data is kept and only the unused tail is handed back — and it stops once
|
|
132
|
+
/// those bytes fill half the allocation, since below that the tail is worth less
|
|
133
|
+
/// than the memcpy of keeping the data (and the next byte would grow it back).
|
|
134
|
+
void decay();
|
|
135
|
+
|
|
136
|
+
/// Drop all data, keep the allocation (e.g. re-using the buffer for a new peer).
|
|
137
|
+
void clear() noexcept;
|
|
138
|
+
|
|
139
|
+
/// Release the allocation entirely.
|
|
140
|
+
void reset() noexcept;
|
|
141
|
+
|
|
142
|
+
size_t capacity() const noexcept { return cap_; }
|
|
143
|
+
/// Consumed-but-not-yet-reclaimed bytes at the front.
|
|
144
|
+
size_t front_waste() const noexcept { return start_; }
|
|
145
|
+
/// Running average of recent peak demand; drives the shrink decision.
|
|
146
|
+
size_t watermark() const noexcept { return watermark_; }
|
|
147
|
+
|
|
148
|
+
private:
|
|
149
|
+
/// Guarantee `bytes` of writable tail, by compacting or reallocating.
|
|
150
|
+
void make_room(size_t bytes);
|
|
151
|
+
/// Reallocate upwards, and restart the usage average at the new size.
|
|
152
|
+
void grow_to(size_t new_capacity);
|
|
153
|
+
/// Reallocate to `new_capacity` (>= live size), moving the live bytes to the front.
|
|
154
|
+
void reallocate(size_t new_capacity);
|
|
155
|
+
/// Next capacity that holds `needed`: 1.5x growth, floored by kMinCapacity.
|
|
156
|
+
size_t grown_capacity(size_t needed) const noexcept;
|
|
157
|
+
/// Fold the peak demand seen since the last sample into the running average.
|
|
158
|
+
void sample_usage() noexcept;
|
|
159
|
+
/// Reallocate down when the allocation has outgrown recent demand by over 2x.
|
|
160
|
+
void maybe_shrink();
|
|
161
|
+
|
|
162
|
+
std::unique_ptr<uint8_t[]> buf_;
|
|
163
|
+
size_t cap_ = 0; ///< allocated bytes
|
|
164
|
+
size_t start_ = 0; ///< first live byte
|
|
165
|
+
size_t end_ = 0; ///< one past the last live byte (== write cursor)
|
|
166
|
+
size_t peak_ = 0; ///< max demand (live bytes, or what prepare() asked for) since the last sample
|
|
167
|
+
size_t watermark_ = 0; ///< exponential average of peak_ samples
|
|
168
|
+
bool received_since_decay_ = false; ///< anything committed since the last decay() tick
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
} // namespace librats
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file service_registry.h
|
|
5
|
+
* @brief Interface-keyed service lookup for targeted, synchronous module calls.
|
|
6
|
+
*
|
|
7
|
+
* The "do X / give me Y" half of inter-module communication, complementing
|
|
8
|
+
* EventBus (which is the fire-and-forget "something happened" half). A module
|
|
9
|
+
* publishes itself under a narrow capability *interface*; another module resolves
|
|
10
|
+
* that interface and calls it directly — with a return value, one-to-one — yet
|
|
11
|
+
* never depends on the concrete type. Resolve returns nullptr when no provider is
|
|
12
|
+
* present, so callers degrade gracefully when a module is disabled:
|
|
13
|
+
*
|
|
14
|
+
* struct PublicAddressSink { // a narrow capability
|
|
15
|
+
* virtual void set_external_ip(const std::string&) = 0;
|
|
16
|
+
* virtual void reannounce() = 0;
|
|
17
|
+
* virtual ~PublicAddressSink() = default;
|
|
18
|
+
* };
|
|
19
|
+
* // provider (e.g. DhtDiscovery) registers itself, by interface, in attach():
|
|
20
|
+
* ctx.services.provide<PublicAddressSink>(this);
|
|
21
|
+
* // consumer resolves and calls — or does nothing if the provider is absent:
|
|
22
|
+
* if (auto* sink = ctx.services.get<PublicAddressSink>()) sink->reannounce();
|
|
23
|
+
*
|
|
24
|
+
* Pointers are NON-owning: the registry never extends a provider's lifetime; the
|
|
25
|
+
* Node owns every module and outlives the registrations. Register exactly once per
|
|
26
|
+
* interface during attach() (a later provide<I> replaces the earlier one).
|
|
27
|
+
*
|
|
28
|
+
* Threading: provide()/get() are not synchronized — the contract is to provide()
|
|
29
|
+
* during attach() (single-threaded, before start) and get() afterwards, so reads
|
|
30
|
+
* never race writes. Prefer the EventBus when there is no return value or recipient.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
#include <typeindex>
|
|
34
|
+
#include <typeinfo>
|
|
35
|
+
#include <unordered_map>
|
|
36
|
+
|
|
37
|
+
namespace librats {
|
|
38
|
+
|
|
39
|
+
class ServiceRegistry {
|
|
40
|
+
public:
|
|
41
|
+
/// Register `service` as the provider of interface I (call during attach()).
|
|
42
|
+
template <class I>
|
|
43
|
+
void provide(I* service) {
|
|
44
|
+
services_[std::type_index(typeid(I))] = static_cast<void*>(service);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/// Resolve the provider of interface I, or nullptr if none is registered.
|
|
48
|
+
template <class I>
|
|
49
|
+
I* get() const {
|
|
50
|
+
auto it = services_.find(std::type_index(typeid(I)));
|
|
51
|
+
return it == services_.end() ? nullptr : static_cast<I*>(it->second);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private:
|
|
55
|
+
std::unordered_map<std::type_index, void*> services_;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
} // namespace librats
|