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
|
@@ -1,419 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file librats_portmap.cpp
|
|
3
|
-
* @brief Automatic port forwarding (UPnP IGD + NAT-PMP) integration for RatsClient
|
|
4
|
-
*
|
|
5
|
-
* Wires the standalone @ref UpnpClient and @ref NatPmpClient backends into the
|
|
6
|
-
* RatsClient lifecycle. Both run in parallel; whichever the router supports maps
|
|
7
|
-
* the TCP listen port so peers behind NAT can accept inbound connections. The
|
|
8
|
-
* backends are started from RatsClient::start() and torn down in stop().
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
#include "librats.h"
|
|
12
|
-
#include "librats_log_macros.h"
|
|
13
|
-
#include "network_utils.h"
|
|
14
|
-
#include "network_monitor.h"
|
|
15
|
-
#include "logger.h"
|
|
16
|
-
|
|
17
|
-
namespace librats {
|
|
18
|
-
|
|
19
|
-
// ============================================================================
|
|
20
|
-
// Configuration
|
|
21
|
-
// ============================================================================
|
|
22
|
-
|
|
23
|
-
void RatsClient::set_port_mapping_enabled(bool enabled) {
|
|
24
|
-
bool was_enabled;
|
|
25
|
-
{
|
|
26
|
-
std::lock_guard<std::mutex> lock(port_mapping_mutex_);
|
|
27
|
-
was_enabled = port_mapping_config_.enabled;
|
|
28
|
-
port_mapping_config_.enabled = enabled;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (was_enabled != enabled) {
|
|
32
|
-
LOG_INFO("portmap", "Automatic port forwarding " << (enabled ? "enabled" : "disabled"));
|
|
33
|
-
if (running_.load()) {
|
|
34
|
-
if (enabled) {
|
|
35
|
-
start_port_mapping();
|
|
36
|
-
} else {
|
|
37
|
-
stop_port_mapping();
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
// Persist the new preference
|
|
41
|
-
save_configuration();
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
bool RatsClient::is_port_mapping_enabled() const {
|
|
46
|
-
std::lock_guard<std::mutex> lock(port_mapping_mutex_);
|
|
47
|
-
return port_mapping_config_.enabled;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
void RatsClient::set_port_mapping_config(const PortMappingConfig& config) {
|
|
51
|
-
{
|
|
52
|
-
std::lock_guard<std::mutex> lock(port_mapping_mutex_);
|
|
53
|
-
port_mapping_config_ = config;
|
|
54
|
-
}
|
|
55
|
-
LOG_DEBUG("portmap", "Port mapping config updated (upnp=" << config.enable_upnp
|
|
56
|
-
<< " natpmp=" << config.enable_natpmp << " lease=" << config.lease_duration_seconds << ")");
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
PortMappingConfig RatsClient::get_port_mapping_config() const {
|
|
60
|
-
std::lock_guard<std::mutex> lock(port_mapping_mutex_);
|
|
61
|
-
return port_mapping_config_;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
void RatsClient::on_port_mapping(PortMapCallback callback) {
|
|
65
|
-
std::lock_guard<std::mutex> lock(port_mapping_mutex_);
|
|
66
|
-
port_mapping_callback_ = std::move(callback);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
std::optional<std::pair<std::string, uint16_t>> RatsClient::get_mapped_public_address() const {
|
|
70
|
-
std::lock_guard<std::mutex> lock(port_mapping_mutex_);
|
|
71
|
-
// The "public address" peers should reach us on is the TCP peer-listen mapping.
|
|
72
|
-
if (mapped_external_tcp_port_ == 0 || mapped_external_ip_.empty()) {
|
|
73
|
-
return std::nullopt;
|
|
74
|
-
}
|
|
75
|
-
return std::make_pair(mapped_external_ip_, mapped_external_tcp_port_);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
uint16_t RatsClient::get_advertised_port() const {
|
|
79
|
-
std::lock_guard<std::mutex> lock(port_mapping_mutex_);
|
|
80
|
-
return mapped_external_tcp_port_ != 0
|
|
81
|
-
? mapped_external_tcp_port_
|
|
82
|
-
: static_cast<uint16_t>(listen_port_);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
void RatsClient::add_port_mapping(PortMapProtocol protocol, uint16_t port) {
|
|
86
|
-
std::lock_guard<std::mutex> lock(port_mapping_mutex_);
|
|
87
|
-
if (upnp_client_) upnp_client_->add_mapping(protocol, port);
|
|
88
|
-
if (natpmp_client_) natpmp_client_->add_mapping(protocol, port);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// ============================================================================
|
|
92
|
-
// Result handling
|
|
93
|
-
// ============================================================================
|
|
94
|
-
|
|
95
|
-
void RatsClient::handle_port_mapping_result(const PortMapResult& result) {
|
|
96
|
-
// A gateway whose reported "external" IP is itself private means we're behind a
|
|
97
|
-
// second NAT (double-NAT): the mapping forwards a port on the inner router, but
|
|
98
|
-
// that doesn't make us reachable from the internet, and the inner port won't
|
|
99
|
-
// match whatever the outer NAT assigns. So such a mapping must NOT be treated as
|
|
100
|
-
// a public endpoint — we leave mapped_external_* untouched and let the advertised
|
|
101
|
-
// address fall back to listen_port_ / the STUN-discovered reflexive address.
|
|
102
|
-
// An empty external IP (gateway didn't report one) is "unknown", not private, so
|
|
103
|
-
// we keep the previous best-effort behavior for it.
|
|
104
|
-
const bool ip_is_private = !result.external_ip.empty() && !network_utils::is_public_ip(result.external_ip);
|
|
105
|
-
|
|
106
|
-
PortMapCallback user_cb;
|
|
107
|
-
bool tcp_port_changed = false;
|
|
108
|
-
bool warn_double_nat = false;
|
|
109
|
-
{
|
|
110
|
-
std::lock_guard<std::mutex> lock(port_mapping_mutex_);
|
|
111
|
-
if (result.success && !ip_is_private) {
|
|
112
|
-
if (!result.external_ip.empty()) {
|
|
113
|
-
mapped_external_ip_ = result.external_ip;
|
|
114
|
-
}
|
|
115
|
-
// Track the external port per protocol so the TCP (peer) and UDP (DHT)
|
|
116
|
-
// mappings don't overwrite each other.
|
|
117
|
-
if (result.protocol == PortMapProtocol::TCP) {
|
|
118
|
-
tcp_port_changed = (mapped_external_tcp_port_ != result.external_port);
|
|
119
|
-
mapped_external_tcp_port_ = result.external_port;
|
|
120
|
-
} else {
|
|
121
|
-
mapped_external_udp_port_ = result.external_port;
|
|
122
|
-
}
|
|
123
|
-
} else if (result.success && ip_is_private && !double_nat_warning_logged_) {
|
|
124
|
-
double_nat_warning_logged_ = true;
|
|
125
|
-
warn_double_nat = true;
|
|
126
|
-
}
|
|
127
|
-
user_cb = port_mapping_callback_;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (result.success && ip_is_private) {
|
|
131
|
-
LOG_INFO("portmap", to_string(result.transport) << " mapped " << to_string(result.protocol)
|
|
132
|
-
<< " port " << result.internal_port << " -> external " << result.external_ip << ":"
|
|
133
|
-
<< result.external_port << " (gateway external IP is private — not a usable public address)");
|
|
134
|
-
if (warn_double_nat) {
|
|
135
|
-
LOG_WARN("portmap", "Gateway reports a private external IP (" << result.external_ip
|
|
136
|
-
<< ") — likely double-NAT. Port forwarding alone won't make this host publicly "
|
|
137
|
-
"reachable; relying on STUN for the public address.");
|
|
138
|
-
}
|
|
139
|
-
} else if (result.success) {
|
|
140
|
-
LOG_INFO("portmap", to_string(result.transport) << " mapped " << to_string(result.protocol)
|
|
141
|
-
<< " port " << result.internal_port << " -> external "
|
|
142
|
-
<< (result.external_ip.empty() ? "?" : result.external_ip) << ":" << result.external_port);
|
|
143
|
-
// Avoid trying to connect to ourselves through the public address. Only a
|
|
144
|
-
// genuinely public IP belongs on the ignore list — a private one could be a
|
|
145
|
-
// real LAN peer we still want to reach.
|
|
146
|
-
if (!result.external_ip.empty()) {
|
|
147
|
-
add_ignored_address(result.external_ip);
|
|
148
|
-
}
|
|
149
|
-
// A new/changed public TCP port means the address peers should reach us on
|
|
150
|
-
// changed: re-announce to the DHT so it advertises the mapped port instead
|
|
151
|
-
// of the (NATed) local listen port. Done outside the lock below.
|
|
152
|
-
} else {
|
|
153
|
-
LOG_DEBUG("portmap", to_string(result.transport) << " mapping failed: " << result.error);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Invoke the user callback outside the lock to avoid re-entrancy deadlocks.
|
|
157
|
-
if (user_cb) {
|
|
158
|
-
user_cb(result);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Re-announce with the freshly mapped public port (outside any lock).
|
|
162
|
-
if (tcp_port_changed && is_dht_running()) {
|
|
163
|
-
announce_rats_peer();
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// ============================================================================
|
|
168
|
-
// Lifecycle
|
|
169
|
-
// ============================================================================
|
|
170
|
-
|
|
171
|
-
void RatsClient::start_port_mapping() {
|
|
172
|
-
PortMappingConfig config;
|
|
173
|
-
int port;
|
|
174
|
-
{
|
|
175
|
-
std::lock_guard<std::mutex> lock(port_mapping_mutex_);
|
|
176
|
-
config = port_mapping_config_;
|
|
177
|
-
// Already started?
|
|
178
|
-
if (upnp_client_ || natpmp_client_) {
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
port = listen_port_;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (!config.enabled) {
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
if (port <= 0) {
|
|
188
|
-
LOG_WARN("portmap", "Skipping port mapping: invalid listen port");
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
LOG_INFO("portmap", "Starting automatic port forwarding for TCP port " << port
|
|
193
|
-
<< " (upnp=" << config.enable_upnp << " natpmp=" << config.enable_natpmp << ")");
|
|
194
|
-
|
|
195
|
-
auto callback = [this](const PortMapResult& r) { handle_port_mapping_result(r); };
|
|
196
|
-
|
|
197
|
-
std::unique_ptr<UpnpClient> upnp;
|
|
198
|
-
std::unique_ptr<NatPmpClient> natpmp;
|
|
199
|
-
|
|
200
|
-
if (config.enable_upnp) {
|
|
201
|
-
upnp = std::make_unique<UpnpClient>();
|
|
202
|
-
upnp->set_lease_duration(config.lease_duration_seconds);
|
|
203
|
-
upnp->set_callback(callback);
|
|
204
|
-
upnp->add_mapping(PortMapProtocol::TCP, static_cast<uint16_t>(port), 0, "rats");
|
|
205
|
-
}
|
|
206
|
-
if (config.enable_natpmp) {
|
|
207
|
-
natpmp = std::make_unique<NatPmpClient>();
|
|
208
|
-
natpmp->set_lease_duration(config.lease_duration_seconds);
|
|
209
|
-
natpmp->set_callback(callback);
|
|
210
|
-
natpmp->add_mapping(PortMapProtocol::TCP, static_cast<uint16_t>(port));
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Publish the clients before starting their workers so add_port_mapping() can
|
|
214
|
-
// reach them, then kick off discovery.
|
|
215
|
-
{
|
|
216
|
-
std::lock_guard<std::mutex> lock(port_mapping_mutex_);
|
|
217
|
-
upnp_client_ = std::move(upnp);
|
|
218
|
-
natpmp_client_ = std::move(natpmp);
|
|
219
|
-
}
|
|
220
|
-
{
|
|
221
|
-
std::lock_guard<std::mutex> lock(port_mapping_mutex_);
|
|
222
|
-
if (upnp_client_) upnp_client_->start();
|
|
223
|
-
if (natpmp_client_) natpmp_client_->start();
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
void RatsClient::stop_port_mapping() {
|
|
228
|
-
// Move the clients out under the lock, then stop() them outside it: stop()
|
|
229
|
-
// joins worker threads which may call handle_port_mapping_result() (and thus
|
|
230
|
-
// re-acquire port_mapping_mutex_), so holding it here would deadlock.
|
|
231
|
-
std::unique_ptr<UpnpClient> upnp;
|
|
232
|
-
std::unique_ptr<NatPmpClient> natpmp;
|
|
233
|
-
{
|
|
234
|
-
std::lock_guard<std::mutex> lock(port_mapping_mutex_);
|
|
235
|
-
upnp = std::move(upnp_client_);
|
|
236
|
-
natpmp = std::move(natpmp_client_);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
if (upnp || natpmp) {
|
|
240
|
-
LOG_INFO("portmap", "Removing port mappings and stopping backends");
|
|
241
|
-
}
|
|
242
|
-
if (upnp) upnp->stop();
|
|
243
|
-
if (natpmp) natpmp->stop();
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// ============================================================================
|
|
247
|
-
// Network change detection
|
|
248
|
-
// ============================================================================
|
|
249
|
-
|
|
250
|
-
void RatsClient::set_network_change_detection_enabled(bool enabled) {
|
|
251
|
-
bool was_enabled;
|
|
252
|
-
{
|
|
253
|
-
std::lock_guard<std::mutex> lock(network_monitor_mutex_);
|
|
254
|
-
was_enabled = network_change_detection_enabled_;
|
|
255
|
-
network_change_detection_enabled_ = enabled;
|
|
256
|
-
}
|
|
257
|
-
if (was_enabled == enabled) {
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
LOG_INFO("netmon", "Network change detection " << (enabled ? "enabled" : "disabled"));
|
|
261
|
-
if (running_.load()) {
|
|
262
|
-
if (enabled) {
|
|
263
|
-
start_network_monitor();
|
|
264
|
-
} else {
|
|
265
|
-
stop_network_monitor();
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
bool RatsClient::is_network_change_detection_enabled() const {
|
|
271
|
-
std::lock_guard<std::mutex> lock(network_monitor_mutex_);
|
|
272
|
-
return network_change_detection_enabled_;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
void RatsClient::on_network_changed(NetworkChangeCallback callback) {
|
|
276
|
-
std::lock_guard<std::mutex> lock(network_monitor_mutex_);
|
|
277
|
-
network_change_callback_ = std::move(callback);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
void RatsClient::start_network_monitor() {
|
|
281
|
-
{
|
|
282
|
-
std::lock_guard<std::mutex> lock(network_monitor_mutex_);
|
|
283
|
-
if (!network_change_detection_enabled_ || network_monitor_) {
|
|
284
|
-
return; // disabled or already running
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// Spin up the recovery worker before the monitor so it can never miss the
|
|
289
|
-
// first wake-up.
|
|
290
|
-
{
|
|
291
|
-
std::lock_guard<std::mutex> lock(network_recovery_mutex_);
|
|
292
|
-
network_recovery_stop_ = false;
|
|
293
|
-
network_recovery_pending_ = false;
|
|
294
|
-
}
|
|
295
|
-
network_recovery_thread_ = std::thread([this]() { network_recovery_loop(); });
|
|
296
|
-
|
|
297
|
-
auto monitor = std::make_unique<NetworkMonitor>();
|
|
298
|
-
monitor->start([this](const std::vector<std::string>& addrs) {
|
|
299
|
-
handle_network_change(addrs);
|
|
300
|
-
});
|
|
301
|
-
{
|
|
302
|
-
std::lock_guard<std::mutex> lock(network_monitor_mutex_);
|
|
303
|
-
network_monitor_ = std::move(monitor);
|
|
304
|
-
}
|
|
305
|
-
LOG_INFO("netmon", "Network change detection active");
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
void RatsClient::stop_network_monitor() {
|
|
309
|
-
// Stop the OS watcher first so no further change events are queued.
|
|
310
|
-
std::unique_ptr<NetworkMonitor> monitor;
|
|
311
|
-
{
|
|
312
|
-
std::lock_guard<std::mutex> lock(network_monitor_mutex_);
|
|
313
|
-
monitor = std::move(network_monitor_);
|
|
314
|
-
}
|
|
315
|
-
if (monitor) {
|
|
316
|
-
monitor->stop(); // joins the monitor's worker thread
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// Then wake and join the recovery worker. Done after the monitor is down so
|
|
320
|
-
// no new recovery can be scheduled while we shut it down.
|
|
321
|
-
{
|
|
322
|
-
std::lock_guard<std::mutex> lock(network_recovery_mutex_);
|
|
323
|
-
network_recovery_stop_ = true;
|
|
324
|
-
}
|
|
325
|
-
network_recovery_cv_.notify_all();
|
|
326
|
-
if (network_recovery_thread_.joinable()) {
|
|
327
|
-
network_recovery_thread_.join();
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
void RatsClient::network_recovery_loop() {
|
|
332
|
-
while (true) {
|
|
333
|
-
{
|
|
334
|
-
std::unique_lock<std::mutex> lock(network_recovery_mutex_);
|
|
335
|
-
network_recovery_cv_.wait(lock, [this]() {
|
|
336
|
-
return network_recovery_pending_ || network_recovery_stop_;
|
|
337
|
-
});
|
|
338
|
-
if (network_recovery_stop_) {
|
|
339
|
-
break;
|
|
340
|
-
}
|
|
341
|
-
network_recovery_pending_ = false;
|
|
342
|
-
}
|
|
343
|
-
recover_after_network_change();
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
void RatsClient::handle_network_change(const std::vector<std::string>& current_addresses) {
|
|
348
|
-
if (!running_.load()) {
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
LOG_CLIENT_INFO("Network change detected (" << current_addresses.size()
|
|
352
|
-
<< " local address(es)); refreshing network state");
|
|
353
|
-
|
|
354
|
-
// Cheap and synchronous: refresh the self-address set so a freshly added
|
|
355
|
-
// local address isn't misjudged as a remote peer, and a removed one stops
|
|
356
|
-
// being blocked. (Diff-based; preserves STUN/mapped/ignored entries.)
|
|
357
|
-
initialize_local_addresses();
|
|
358
|
-
|
|
359
|
-
// Notify the application.
|
|
360
|
-
NetworkChangeCallback cb;
|
|
361
|
-
{
|
|
362
|
-
std::lock_guard<std::mutex> lock(network_monitor_mutex_);
|
|
363
|
-
cb = network_change_callback_;
|
|
364
|
-
}
|
|
365
|
-
if (cb) {
|
|
366
|
-
cb(current_addresses);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
// Hand the slow recovery (port re-mapping + STUN + re-announce) to the
|
|
370
|
-
// dedicated worker so we don't block the monitor thread. Coalesced: if a
|
|
371
|
-
// recovery is already running, this just marks another pass is needed.
|
|
372
|
-
{
|
|
373
|
-
std::lock_guard<std::mutex> lock(network_recovery_mutex_);
|
|
374
|
-
network_recovery_pending_ = true;
|
|
375
|
-
}
|
|
376
|
-
network_recovery_cv_.notify_all();
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
void RatsClient::recover_after_network_change() {
|
|
380
|
-
if (!running_.load()) {
|
|
381
|
-
return;
|
|
382
|
-
}
|
|
383
|
-
LOG_CLIENT_INFO("Recovering after network change: renewing port mappings and re-announcing");
|
|
384
|
-
|
|
385
|
-
// 1. Renew router port mappings. Our LAN IP and/or the gateway likely
|
|
386
|
-
// changed, so existing UPnP/NAT-PMP leases are stale or aimed at the wrong
|
|
387
|
-
// internal address. Tear down and re-run discovery from scratch.
|
|
388
|
-
if (is_port_mapping_enabled()) {
|
|
389
|
-
stop_port_mapping();
|
|
390
|
-
if (running_.load()) {
|
|
391
|
-
start_port_mapping();
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
if (!running_.load()) {
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
// 2. Re-discover our public address via STUN, update the BEP 42 node IDs and
|
|
400
|
-
// re-announce so the DHT advertises our current reachable endpoint rather
|
|
401
|
-
// than the one from the previous network. This runs on the recovery
|
|
402
|
-
// thread, which stop() joins before the DHT clients are destroyed, so the
|
|
403
|
-
// set_external_ip()/announce calls can never touch a freed DhtClient.
|
|
404
|
-
if (is_dht_running()) {
|
|
405
|
-
auto mapped = discover_public_address("stun.l.google.com", 19302, 4000);
|
|
406
|
-
if (mapped) {
|
|
407
|
-
if (dht_client_) dht_client_->set_external_ip(mapped->address);
|
|
408
|
-
if (dht_client_v6_) dht_client_v6_->set_external_ip(mapped->address);
|
|
409
|
-
LOG_CLIENT_INFO("Public address after network change: " << mapped->address);
|
|
410
|
-
} else {
|
|
411
|
-
LOG_CLIENT_DEBUG("STUN public address discovery failed after network change");
|
|
412
|
-
}
|
|
413
|
-
if (running_.load()) {
|
|
414
|
-
announce_rats_peer();
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
} // namespace librats
|
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
#include "librats.h"
|
|
2
|
-
#include "librats_log_macros.h"
|
|
3
|
-
|
|
4
|
-
namespace librats {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// =========================================================================
|
|
8
|
-
// Automatic Reconnection System
|
|
9
|
-
// =========================================================================
|
|
10
|
-
|
|
11
|
-
void RatsClient::set_reconnect_enabled(bool enabled) {
|
|
12
|
-
std::lock_guard<std::mutex> lock(reconnect_mutex_);
|
|
13
|
-
reconnect_config_.enabled = enabled;
|
|
14
|
-
LOG_CLIENT_INFO("Automatic reconnection " << (enabled ? "enabled" : "disabled"));
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
bool RatsClient::is_reconnect_enabled() const {
|
|
18
|
-
std::lock_guard<std::mutex> lock(reconnect_mutex_);
|
|
19
|
-
return reconnect_config_.enabled;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
void RatsClient::set_reconnect_config(const ReconnectConfig& config) {
|
|
23
|
-
std::lock_guard<std::mutex> lock(reconnect_mutex_);
|
|
24
|
-
reconnect_config_ = config;
|
|
25
|
-
LOG_CLIENT_INFO("Reconnection config updated: max_attempts=" << config.max_attempts
|
|
26
|
-
<< ", stable_threshold=" << config.stable_connection_threshold_seconds << "s");
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
ReconnectConfig RatsClient::get_reconnect_config() const {
|
|
30
|
-
std::lock_guard<std::mutex> lock(reconnect_mutex_);
|
|
31
|
-
return reconnect_config_;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
size_t RatsClient::get_reconnect_queue_size() const {
|
|
35
|
-
std::lock_guard<std::mutex> lock(reconnect_mutex_);
|
|
36
|
-
return reconnect_queue_.size();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
void RatsClient::clear_reconnect_queue() {
|
|
40
|
-
std::lock_guard<std::mutex> lock(reconnect_mutex_);
|
|
41
|
-
size_t cleared = reconnect_queue_.size();
|
|
42
|
-
reconnect_queue_.clear();
|
|
43
|
-
manual_disconnect_peers_.clear();
|
|
44
|
-
LOG_CLIENT_INFO("Cleared " << cleared << " peers from reconnection queue");
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
std::vector<ReconnectInfo> RatsClient::get_reconnect_queue() const {
|
|
48
|
-
std::lock_guard<std::mutex> lock(reconnect_mutex_);
|
|
49
|
-
std::vector<ReconnectInfo> result;
|
|
50
|
-
result.reserve(reconnect_queue_.size());
|
|
51
|
-
for (const auto& pair : reconnect_queue_) {
|
|
52
|
-
result.push_back(pair.second);
|
|
53
|
-
}
|
|
54
|
-
return result;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
int RatsClient::get_retry_interval_seconds(int attempt, bool is_stable) const {
|
|
58
|
-
// For stable peers, use faster first retry
|
|
59
|
-
if (attempt == 0 && is_stable) {
|
|
60
|
-
return reconnect_config_.stable_first_retry_seconds;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Use configured intervals, defaulting to last interval if attempt exceeds array size
|
|
64
|
-
const auto& intervals = reconnect_config_.retry_intervals_seconds;
|
|
65
|
-
if (intervals.empty()) {
|
|
66
|
-
return 30; // Default fallback
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
size_t index = static_cast<size_t>(attempt);
|
|
70
|
-
if (index >= intervals.size()) {
|
|
71
|
-
return intervals.back();
|
|
72
|
-
}
|
|
73
|
-
return intervals[index];
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
void RatsClient::schedule_reconnect(const RatsPeer& peer) {
|
|
77
|
-
if (!running_.load()) {
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Check if reconnection is enabled
|
|
82
|
-
{
|
|
83
|
-
std::lock_guard<std::mutex> lock(reconnect_mutex_);
|
|
84
|
-
if (!reconnect_config_.enabled) {
|
|
85
|
-
LOG_CLIENT_DEBUG("Reconnection disabled, not scheduling reconnect for " << peer.peer_id);
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Check if this peer was manually disconnected
|
|
90
|
-
if (manual_disconnect_peers_.find(peer.peer_id) != manual_disconnect_peers_.end()) {
|
|
91
|
-
LOG_CLIENT_DEBUG("Peer " << peer.peer_id << " was manually disconnected, not scheduling reconnect");
|
|
92
|
-
manual_disconnect_peers_.erase(peer.peer_id);
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Check if already in queue
|
|
97
|
-
if (reconnect_queue_.find(peer.peer_id) != reconnect_queue_.end()) {
|
|
98
|
-
LOG_CLIENT_DEBUG("Peer " << peer.peer_id << " already in reconnection queue");
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Calculate connection duration
|
|
104
|
-
auto now = std::chrono::steady_clock::now();
|
|
105
|
-
auto connection_duration = std::chrono::duration_cast<std::chrono::milliseconds>(now - peer.connected_at);
|
|
106
|
-
|
|
107
|
-
// Determine if this was a stable connection
|
|
108
|
-
bool is_stable = connection_duration.count() >=
|
|
109
|
-
(reconnect_config_.stable_connection_threshold_seconds * 1000);
|
|
110
|
-
|
|
111
|
-
// Create reconnect info
|
|
112
|
-
ReconnectInfo info(peer.peer_id, peer.ip, peer.port, connection_duration, is_stable);
|
|
113
|
-
|
|
114
|
-
// Calculate first retry interval
|
|
115
|
-
int first_retry_seconds = get_retry_interval_seconds(0, is_stable);
|
|
116
|
-
info.next_attempt_time = now + std::chrono::seconds(first_retry_seconds);
|
|
117
|
-
|
|
118
|
-
// Add to queue
|
|
119
|
-
{
|
|
120
|
-
std::lock_guard<std::mutex> lock(reconnect_mutex_);
|
|
121
|
-
reconnect_queue_[peer.peer_id] = info;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
LOG_CLIENT_INFO("Scheduled reconnection for peer " << peer.peer_id
|
|
125
|
-
<< " (" << peer.ip << ":" << peer.port << ")"
|
|
126
|
-
<< " - stable=" << is_stable
|
|
127
|
-
<< ", connection_duration=" << connection_duration.count() << "ms"
|
|
128
|
-
<< ", first_retry_in=" << first_retry_seconds << "s");
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
void RatsClient::remove_from_reconnect_queue(const std::string& peer_id) {
|
|
132
|
-
std::lock_guard<std::mutex> lock(reconnect_mutex_);
|
|
133
|
-
auto it = reconnect_queue_.find(peer_id);
|
|
134
|
-
if (it != reconnect_queue_.end()) {
|
|
135
|
-
LOG_CLIENT_DEBUG("Removed peer " << peer_id << " from reconnection queue");
|
|
136
|
-
reconnect_queue_.erase(it);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
void RatsClient::process_reconnect_queue() {
|
|
141
|
-
if (!running_.load()) {
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Get list of peers to attempt reconnection (copy to avoid holding lock during connect)
|
|
146
|
-
std::vector<ReconnectInfo> peers_to_reconnect;
|
|
147
|
-
|
|
148
|
-
{
|
|
149
|
-
std::lock_guard<std::mutex> lock(reconnect_mutex_);
|
|
150
|
-
|
|
151
|
-
if (!reconnect_config_.enabled || reconnect_queue_.empty()) {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
auto now = std::chrono::steady_clock::now();
|
|
156
|
-
|
|
157
|
-
for (auto& pair : reconnect_queue_) {
|
|
158
|
-
ReconnectInfo& info = pair.second;
|
|
159
|
-
|
|
160
|
-
// Check if it's time for next attempt
|
|
161
|
-
if (now >= info.next_attempt_time) {
|
|
162
|
-
peers_to_reconnect.push_back(info);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Process reconnection attempts outside of lock
|
|
168
|
-
for (const auto& info : peers_to_reconnect) {
|
|
169
|
-
// Check if we're already connected to this peer
|
|
170
|
-
std::string normalized_address = normalize_peer_address(info.ip, static_cast<int>(info.port));
|
|
171
|
-
if (is_already_connected_to_address(normalized_address)) {
|
|
172
|
-
LOG_CLIENT_INFO("Already reconnected to peer " << info.peer_id << ", removing from queue");
|
|
173
|
-
remove_from_reconnect_queue(info.peer_id);
|
|
174
|
-
continue;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Check if peer limit is reached
|
|
178
|
-
if (is_peer_limit_reached()) {
|
|
179
|
-
LOG_CLIENT_DEBUG("Peer limit reached, skipping reconnection attempt for " << info.peer_id);
|
|
180
|
-
continue;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
LOG_CLIENT_INFO("Attempting reconnection to peer " << info.peer_id
|
|
184
|
-
<< " (" << info.ip << ":" << info.port << ")"
|
|
185
|
-
<< " - attempt " << (info.attempt_count + 1) << "/" << reconnect_config_.max_attempts);
|
|
186
|
-
|
|
187
|
-
// Attempt to connect
|
|
188
|
-
bool connected = connect_to_peer(info.ip, static_cast<int>(info.port));
|
|
189
|
-
|
|
190
|
-
if (connected) {
|
|
191
|
-
LOG_CLIENT_INFO("Successfully reconnected to peer " << info.peer_id);
|
|
192
|
-
remove_from_reconnect_queue(info.peer_id);
|
|
193
|
-
} else {
|
|
194
|
-
// Update attempt count and schedule next attempt
|
|
195
|
-
std::lock_guard<std::mutex> lock(reconnect_mutex_);
|
|
196
|
-
auto it = reconnect_queue_.find(info.peer_id);
|
|
197
|
-
if (it != reconnect_queue_.end()) {
|
|
198
|
-
it->second.attempt_count++;
|
|
199
|
-
|
|
200
|
-
// Check if we've exceeded max attempts
|
|
201
|
-
if (it->second.attempt_count >= reconnect_config_.max_attempts) {
|
|
202
|
-
LOG_CLIENT_INFO("Max reconnection attempts reached for peer " << info.peer_id
|
|
203
|
-
<< ", removing from queue");
|
|
204
|
-
reconnect_queue_.erase(it);
|
|
205
|
-
} else {
|
|
206
|
-
// Schedule next attempt
|
|
207
|
-
int next_interval = get_retry_interval_seconds(it->second.attempt_count, it->second.is_stable);
|
|
208
|
-
it->second.next_attempt_time = std::chrono::steady_clock::now() +
|
|
209
|
-
std::chrono::seconds(next_interval);
|
|
210
|
-
LOG_CLIENT_DEBUG("Scheduled next reconnection attempt for " << info.peer_id
|
|
211
|
-
<< " in " << next_interval << " seconds");
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
}
|