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,81 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file node_entry.h
|
|
5
|
+
* @brief A single contact in the routing table: who it is, where to reach it, and
|
|
6
|
+
* the liveness/quality bookkeeping that decides who to keep or evict.
|
|
7
|
+
*
|
|
8
|
+
* Quality model (mirrors libtorrent's node_entry):
|
|
9
|
+
* - rtt — smoothed round-trip time; kRttUnknown until the first reply.
|
|
10
|
+
* - fail_count — consecutive failed queries; kNeverPinged means we've only ever
|
|
11
|
+
* *heard about* this node (from someone else's reply) and never had
|
|
12
|
+
* a reply from it ourselves.
|
|
13
|
+
* - verified — its id is derived from its IP per BEP 42, so it's harder to spoof
|
|
14
|
+
* and is preferred when we have to choose who to drop.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#include "librats/core/address.h"
|
|
18
|
+
#include "librats/dht/id.h"
|
|
19
|
+
|
|
20
|
+
#include <chrono>
|
|
21
|
+
#include <cstdint>
|
|
22
|
+
#include <utility>
|
|
23
|
+
|
|
24
|
+
namespace librats {
|
|
25
|
+
namespace dht {
|
|
26
|
+
|
|
27
|
+
struct NodeEntry {
|
|
28
|
+
static constexpr uint16_t kRttUnknown = 0xffff; // no RTT sample yet
|
|
29
|
+
static constexpr uint8_t kNeverPinged = 0xff; // only heard about, never replied
|
|
30
|
+
|
|
31
|
+
NodeId id{};
|
|
32
|
+
Address endpoint;
|
|
33
|
+
// Last time we "touched" this contact: a reply received OR a probe issued to it.
|
|
34
|
+
// Defaults to the clock minimum so a never-contacted contact sorts as most stale
|
|
35
|
+
// (refreshed first). Read only by RoutingTable::next_to_refresh for its ordering.
|
|
36
|
+
std::chrono::steady_clock::time_point last_seen{(std::chrono::steady_clock::time_point::min)()};
|
|
37
|
+
uint16_t rtt = kRttUnknown;
|
|
38
|
+
uint8_t fail_count = kNeverPinged;
|
|
39
|
+
bool verified = false;
|
|
40
|
+
|
|
41
|
+
NodeEntry() = default;
|
|
42
|
+
NodeEntry(const NodeId& id, Address endpoint)
|
|
43
|
+
: id(id), endpoint(std::move(endpoint)) {}
|
|
44
|
+
|
|
45
|
+
// Have we ever had a reply from this node (vs only heard it mentioned)?
|
|
46
|
+
bool pinged() const noexcept { return fail_count != kNeverPinged; }
|
|
47
|
+
// Replied with no outstanding failures — safe to hand out and keep.
|
|
48
|
+
bool confirmed() const noexcept { return fail_count == 0; }
|
|
49
|
+
|
|
50
|
+
// A reply arrived: clear failures, refresh last_seen, fold in the RTT sample.
|
|
51
|
+
void record_success(uint16_t rtt_sample = kRttUnknown) noexcept {
|
|
52
|
+
fail_count = 0;
|
|
53
|
+
last_seen = std::chrono::steady_clock::now();
|
|
54
|
+
update_rtt(rtt_sample);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// A query to this node timed out. Only meaningful once pinged; saturates just
|
|
58
|
+
// below kNeverPinged so a long-dead node never wraps back to "never pinged".
|
|
59
|
+
void record_failure() noexcept {
|
|
60
|
+
if (pinged() && fail_count < kNeverPinged - 1) ++fail_count;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Exponential moving average (2/3 old + 1/3 new), seeded by the first sample.
|
|
64
|
+
void update_rtt(uint16_t sample) noexcept {
|
|
65
|
+
if (sample == kRttUnknown) return;
|
|
66
|
+
rtt = (rtt == kRttUnknown)
|
|
67
|
+
? sample
|
|
68
|
+
: static_cast<uint16_t>(rtt * 2 / 3 + sample / 3);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Eviction ordering: true if *this is the worse contact and should go first.
|
|
72
|
+
// Worse = more failures, then unverified before verified, then higher RTT.
|
|
73
|
+
bool is_worse_than(const NodeEntry& other) const noexcept {
|
|
74
|
+
if (fail_count != other.fail_count) return fail_count > other.fail_count;
|
|
75
|
+
if (verified != other.verified) return !verified; // unverified is worse
|
|
76
|
+
return rtt > other.rtt;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
} // namespace dht
|
|
81
|
+
} // namespace librats
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file observer.h
|
|
5
|
+
* @brief One outstanding query to a single node.
|
|
6
|
+
*
|
|
7
|
+
* An Observer is both the RPC callback the RpcManager invokes when a reply or
|
|
8
|
+
* timeout arrives, and the little bag of per-node state (id, endpoint, flags) the
|
|
9
|
+
* issuer tracks. It is owned via shared_ptr by whoever started the query (a
|
|
10
|
+
* Traversal); the RpcManager holds a shared_ptr only while the query is in flight,
|
|
11
|
+
* and takes a local copy across each callback so an observer can't be freed in the
|
|
12
|
+
* middle of handling its own reply (e.g. if the traversal truncates it meanwhile).
|
|
13
|
+
*
|
|
14
|
+
* Observers reference their Traversal by plain reference, never owning it, so there
|
|
15
|
+
* is no ownership cycle to untangle.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include "librats/core/address.h"
|
|
19
|
+
#include "librats/dht/id.h"
|
|
20
|
+
|
|
21
|
+
#include <chrono>
|
|
22
|
+
#include <cstdint>
|
|
23
|
+
#include <memory>
|
|
24
|
+
|
|
25
|
+
namespace librats {
|
|
26
|
+
struct KrpcMessage; // defined in dht/krpc.h; only referenced by const& here
|
|
27
|
+
|
|
28
|
+
namespace dht {
|
|
29
|
+
|
|
30
|
+
using TimePoint = std::chrono::steady_clock::time_point;
|
|
31
|
+
|
|
32
|
+
class Observer {
|
|
33
|
+
public:
|
|
34
|
+
enum Flag : uint8_t {
|
|
35
|
+
kQueried = 1 << 0, // a query was sent
|
|
36
|
+
kAlive = 1 << 1, // a reply was received
|
|
37
|
+
kFailed = 1 << 2, // fully timed out / errored
|
|
38
|
+
kShortTimeout = 1 << 3, // exceeded the short timeout (slot freed, still waiting)
|
|
39
|
+
kInitial = 1 << 4, // a seed/router node (id may be unknown until it replies)
|
|
40
|
+
kDone = 1 << 5, // abandoned by the traversal; ignore any late reply
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
Observer(const NodeId& id, const Address& endpoint) : id_(id), endpoint_(endpoint) {}
|
|
44
|
+
virtual ~Observer() = default;
|
|
45
|
+
Observer(const Observer&) = delete;
|
|
46
|
+
Observer& operator=(const Observer&) = delete;
|
|
47
|
+
|
|
48
|
+
const NodeId& id() const noexcept { return id_; }
|
|
49
|
+
const Address& endpoint() const noexcept { return endpoint_; }
|
|
50
|
+
|
|
51
|
+
bool has(Flag f) const noexcept { return (flags_ & f) != 0; }
|
|
52
|
+
void set(Flag f) noexcept { flags_ = static_cast<uint8_t>(flags_ | f); }
|
|
53
|
+
|
|
54
|
+
// Invoked by the RpcManager exactly once, when the query resolves.
|
|
55
|
+
virtual void on_response(const KrpcMessage& msg, uint16_t rtt_ms, TimePoint now) = 0;
|
|
56
|
+
virtual void on_timeout(TimePoint now) = 0;
|
|
57
|
+
virtual void on_short_timeout(TimePoint now) = 0;
|
|
58
|
+
|
|
59
|
+
protected:
|
|
60
|
+
NodeId id_;
|
|
61
|
+
Address endpoint_;
|
|
62
|
+
uint8_t flags_ = 0;
|
|
63
|
+
|
|
64
|
+
private:
|
|
65
|
+
friend class RpcManager;
|
|
66
|
+
uint16_t txn_ = 0; // transaction id, owned by the RpcManager while in flight
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
using ObserverPtr = std::shared_ptr<Observer>;
|
|
70
|
+
|
|
71
|
+
} // namespace dht
|
|
72
|
+
} // namespace librats
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#include "librats/dht/persistence.h"
|
|
2
|
+
#include "librats/dht/log.h"
|
|
3
|
+
#include "librats/util/json.h"
|
|
4
|
+
|
|
5
|
+
#include <fstream>
|
|
6
|
+
#include <iterator>
|
|
7
|
+
|
|
8
|
+
namespace librats {
|
|
9
|
+
namespace dht {
|
|
10
|
+
|
|
11
|
+
bool save_routing_table(const std::string& path, const NodeId& self,
|
|
12
|
+
const std::vector<NodeEntry>& contacts) {
|
|
13
|
+
Json root;
|
|
14
|
+
root["version"] = 1;
|
|
15
|
+
root["node_id"] = to_hex(self);
|
|
16
|
+
|
|
17
|
+
Json nodes = Json::array();
|
|
18
|
+
for (const auto& n : contacts) {
|
|
19
|
+
if (!n.confirmed()) continue; // only persist good contacts
|
|
20
|
+
Json e;
|
|
21
|
+
e["id"] = to_hex(n.id);
|
|
22
|
+
e["ip"] = n.endpoint.ip.to_string();
|
|
23
|
+
e["port"] = static_cast<int>(n.endpoint.port);
|
|
24
|
+
if (n.rtt != NodeEntry::kRttUnknown) e["rtt"] = static_cast<int>(n.rtt);
|
|
25
|
+
nodes.push_back(e);
|
|
26
|
+
}
|
|
27
|
+
root["nodes"] = nodes;
|
|
28
|
+
|
|
29
|
+
std::ofstream file(path);
|
|
30
|
+
if (!file.is_open()) {
|
|
31
|
+
// The headline "saved N contact(s)" lives in the facade; here we surface the
|
|
32
|
+
// failure it can't see — a silent write failure means losing the warm set on restart.
|
|
33
|
+
LOG_WARN("dht", "could not open routing table for writing: " << path);
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
file << root.dump(2);
|
|
37
|
+
if (!file.good()) {
|
|
38
|
+
LOG_WARN("dht", "failed writing routing table to " << path);
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
bool load_routing_table(const std::string& path, NodeId& self,
|
|
45
|
+
std::vector<NodeEntry>& contacts) {
|
|
46
|
+
std::ifstream file(path);
|
|
47
|
+
if (!file.is_open()) return false;
|
|
48
|
+
const std::string text((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
Json root = Json::parse(text);
|
|
52
|
+
if (!root.contains("version") || !root.contains("nodes")) {
|
|
53
|
+
LOG_WARN("dht", "routing table at " << path << " missing required fields, ignoring");
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
NodeId loaded_self = self;
|
|
58
|
+
if (root.contains("node_id")) loaded_self = from_hex(root["node_id"].get<std::string>());
|
|
59
|
+
|
|
60
|
+
std::vector<NodeEntry> loaded;
|
|
61
|
+
std::size_t skipped = 0;
|
|
62
|
+
for (const auto& e : root["nodes"]) {
|
|
63
|
+
if (!e.contains("id") || !e.contains("ip") || !e.contains("port")) { ++skipped; continue; }
|
|
64
|
+
const auto ip = IpAddress::parse(e["ip"].get<std::string>());
|
|
65
|
+
if (!ip) { ++skipped; continue; }
|
|
66
|
+
NodeEntry n(from_hex(e["id"].get<std::string>()),
|
|
67
|
+
Address(*ip, static_cast<uint16_t>(e["port"].get<int>())));
|
|
68
|
+
const uint16_t rtt = e.contains("rtt")
|
|
69
|
+
? static_cast<uint16_t>(e["rtt"].get<int>())
|
|
70
|
+
: NodeEntry::kRttUnknown;
|
|
71
|
+
n.record_success(rtt); // a saved contact starts life confirmed
|
|
72
|
+
loaded.push_back(n);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
self = loaded_self;
|
|
76
|
+
contacts = std::move(loaded);
|
|
77
|
+
// The loaded count is the facade's INFO line; only the malformed-entry detail is
|
|
78
|
+
// new here, so stay silent unless some entries were actually dropped.
|
|
79
|
+
if (skipped)
|
|
80
|
+
LOG_DEBUG("dht", "loaded routing table from " << path << ": " << contacts.size()
|
|
81
|
+
<< " contact(s), " << skipped << " malformed entr(ies) skipped");
|
|
82
|
+
return true;
|
|
83
|
+
} catch (const std::exception& ex) {
|
|
84
|
+
LOG_WARN("dht", "malformed routing table at " << path << " (" << ex.what() << "), ignoring");
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
} // namespace dht
|
|
90
|
+
} // namespace librats
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file persistence.h
|
|
5
|
+
* @brief Save/restore the routing table across restarts as JSON.
|
|
6
|
+
*
|
|
7
|
+
* Persists our node id (so our identity is stable) plus the confirmed contacts (a
|
|
8
|
+
* warm set to bootstrap from). The JSON schema is unchanged from earlier releases, so
|
|
9
|
+
* previously saved tables still load (the file is named dht_routing[_v6].json under the
|
|
10
|
+
* data dir; the name is port-independent so an ephemeral node restores on restart).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
#include "librats/dht/id.h"
|
|
14
|
+
#include "librats/dht/node_entry.h"
|
|
15
|
+
|
|
16
|
+
#include <string>
|
|
17
|
+
#include <vector>
|
|
18
|
+
|
|
19
|
+
namespace librats {
|
|
20
|
+
namespace dht {
|
|
21
|
+
|
|
22
|
+
// Writes `self` + the given (confirmed) contacts to `path`. Returns false on I/O error.
|
|
23
|
+
bool save_routing_table(const std::string& path, const NodeId& self,
|
|
24
|
+
const std::vector<NodeEntry>& contacts);
|
|
25
|
+
|
|
26
|
+
// Reads `path` into `self` and `contacts` (restored as confirmed). Returns false if
|
|
27
|
+
// the file is missing or malformed; outputs are only written on success.
|
|
28
|
+
bool load_routing_table(const std::string& path, NodeId& self,
|
|
29
|
+
std::vector<NodeEntry>& contacts);
|
|
30
|
+
|
|
31
|
+
} // namespace dht
|
|
32
|
+
} // namespace librats
|