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,103 @@
|
|
|
1
|
+
#include "librats/node/nat_status.h"
|
|
2
|
+
|
|
3
|
+
#include <algorithm>
|
|
4
|
+
|
|
5
|
+
namespace librats {
|
|
6
|
+
|
|
7
|
+
const char* to_string(NatMapping m) noexcept {
|
|
8
|
+
switch (m) {
|
|
9
|
+
case NatMapping::Unknown: return "unknown";
|
|
10
|
+
case NatMapping::Open: return "open";
|
|
11
|
+
case NatMapping::EndpointIndependent: return "endpoint-independent";
|
|
12
|
+
case NatMapping::EndpointDependent: return "endpoint-dependent";
|
|
13
|
+
}
|
|
14
|
+
return "unknown";
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
void NatStatus::record_udp_observation(const PeerId& reporter, const Address& external,
|
|
18
|
+
bool is_own_address) {
|
|
19
|
+
if (!external.is_valid()) return;
|
|
20
|
+
|
|
21
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
|
22
|
+
|
|
23
|
+
auto it = seen_.find(reporter);
|
|
24
|
+
if (it == seen_.end()) {
|
|
25
|
+
// Bounded by observers rather than by observations, so the cap is only ever
|
|
26
|
+
// reached by a node with a genuinely large mesh — and once it is, the ones
|
|
27
|
+
// already held are the ones that have been confirmed longest.
|
|
28
|
+
if (seen_.size() >= kMaxObservers) return;
|
|
29
|
+
it = seen_.emplace(reporter, Observation{}).first;
|
|
30
|
+
}
|
|
31
|
+
it->second.endpoint = external;
|
|
32
|
+
it->second.is_own_address = is_own_address;
|
|
33
|
+
it->second.seq = next_seq_++;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
void NatStatus::forget(const PeerId& reporter) {
|
|
37
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
|
38
|
+
seen_.erase(reporter);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
void NatStatus::reset() {
|
|
42
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
|
43
|
+
seen_.clear();
|
|
44
|
+
next_seq_ = 1;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
size_t NatStatus::observation_count() const {
|
|
48
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
|
49
|
+
return seen_.size();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
std::vector<Address> NatStatus::external_udp_endpoints() const {
|
|
53
|
+
std::vector<Observation> all;
|
|
54
|
+
{
|
|
55
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
|
56
|
+
all.reserve(seen_.size());
|
|
57
|
+
for (const auto& [id, obs] : seen_) all.push_back(obs);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Freshest first: under a NAT that has just remapped us, the endpoint the most
|
|
61
|
+
// recent peer saw is the one a punch should be aimed at, and the stale ones
|
|
62
|
+
// behind it are worth keeping only as fallbacks.
|
|
63
|
+
std::sort(all.begin(), all.end(),
|
|
64
|
+
[](const Observation& a, const Observation& b) { return a.seq > b.seq; });
|
|
65
|
+
|
|
66
|
+
std::vector<Address> out;
|
|
67
|
+
out.reserve(all.size());
|
|
68
|
+
for (const Observation& obs : all)
|
|
69
|
+
if (std::find(out.begin(), out.end(), obs.endpoint) == out.end())
|
|
70
|
+
out.push_back(obs.endpoint);
|
|
71
|
+
return out;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
NatMapping NatStatus::udp_mapping() const {
|
|
75
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
|
76
|
+
|
|
77
|
+
// Observations from peers that see us at an address we hold ourselves say
|
|
78
|
+
// nothing about a NAT — they are LAN peers, or there is no NAT at all. They are
|
|
79
|
+
// counted separately so a node whose only peers are on its own segment reports
|
|
80
|
+
// Open rather than the Unknown a bare "not enough samples" would give, while a
|
|
81
|
+
// single peer out on the internet still decides the answer for everybody.
|
|
82
|
+
size_t own = 0;
|
|
83
|
+
size_t external = 0;
|
|
84
|
+
bool all_same = true;
|
|
85
|
+
Address first{};
|
|
86
|
+
|
|
87
|
+
for (const auto& [id, obs] : seen_) {
|
|
88
|
+
if (obs.is_own_address) { ++own; continue; }
|
|
89
|
+
if (external == 0) first = obs.endpoint;
|
|
90
|
+
else if (obs.endpoint != first) all_same = false;
|
|
91
|
+
++external;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (external == 0) return own > 0 ? NatMapping::Open : NatMapping::Unknown;
|
|
95
|
+
|
|
96
|
+
// One vantage point cannot tell a stable mapping from a per-destination one: it
|
|
97
|
+
// has only ever seen the mapping made for itself. Two disagreeing ones prove the
|
|
98
|
+
// NAT picks per destination; two agreeing ones are what a punch relies on.
|
|
99
|
+
if (external < 2) return NatMapping::Unknown;
|
|
100
|
+
return all_same ? NatMapping::EndpointIndependent : NatMapping::EndpointDependent;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
} // namespace librats
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file nat_status.h
|
|
5
|
+
* @brief What the mesh has told us about our own side of the NAT.
|
|
6
|
+
*
|
|
7
|
+
* A node behind a NAT cannot see its own external endpoint; only somebody on the
|
|
8
|
+
* other side can. The usual answer is a STUN server, but a connected mesh already
|
|
9
|
+
* carries the same information for free — and, unlike a single STUN reply, it
|
|
10
|
+
* carries it from *several* independent vantage points, which is what turns a bare
|
|
11
|
+
* address into a statement about how the NAT behaves.
|
|
12
|
+
*
|
|
13
|
+
* The source is the identify exchange (node/identify.h). Each peer reports the
|
|
14
|
+
* address it observed us connecting from; on a DATAGRAM link that address is the
|
|
15
|
+
* NAT's rewriting of the one socket every UDP peer shares, so its port is exactly
|
|
16
|
+
* the port a third party must aim at to reach us. (On TCP the port is an ephemeral
|
|
17
|
+
* one our OS picked per connection and means nothing, so it is not reported and
|
|
18
|
+
* never reaches this class.)
|
|
19
|
+
*
|
|
20
|
+
* Two peers are then enough to classify the mapping:
|
|
21
|
+
*
|
|
22
|
+
* - both see the SAME external port → the NAT maps our socket to one port
|
|
23
|
+
* regardless of who we are talking to (endpoint-independent, "cone"). This is
|
|
24
|
+
* the case a hole punch works in: the port one peer tells us about is the port
|
|
25
|
+
* another peer can dial.
|
|
26
|
+
* - they see DIFFERENT ports → the NAT picks a fresh mapping per
|
|
27
|
+
* destination (endpoint-dependent, "symmetric"). Nothing we learn from one peer
|
|
28
|
+
* predicts what a third will see, so punching to an advertised endpoint cannot
|
|
29
|
+
* work and a relay is the only way through.
|
|
30
|
+
* - the observed endpoint is one of our own local addresses → there is no NAT in
|
|
31
|
+
* the path at all, and an ordinary dial already reaches us.
|
|
32
|
+
*
|
|
33
|
+
* Threading: observations arrive on reactor threads (possibly several), readers are
|
|
34
|
+
* application/subsystem threads. One small mutex; nothing on a data path.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
#include "librats/util/rats_export.h"
|
|
38
|
+
#include "librats/core/address.h"
|
|
39
|
+
#include "librats/peer/peer_id.h"
|
|
40
|
+
|
|
41
|
+
#include <cstddef>
|
|
42
|
+
#include <mutex>
|
|
43
|
+
#include <unordered_map>
|
|
44
|
+
#include <vector>
|
|
45
|
+
|
|
46
|
+
namespace librats {
|
|
47
|
+
|
|
48
|
+
/// How the NAT in front of our shared datagram socket maps it, as far as the mesh
|
|
49
|
+
/// has been able to show.
|
|
50
|
+
enum class NatMapping : uint8_t {
|
|
51
|
+
Unknown, ///< not enough independent observations yet
|
|
52
|
+
Open, ///< no NAT: peers see us at an address we hold ourselves
|
|
53
|
+
EndpointIndependent, ///< one external port for every destination — punchable
|
|
54
|
+
EndpointDependent, ///< a fresh mapping per destination (symmetric) — not punchable
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
RATS_API const char* to_string(NatMapping) noexcept;
|
|
58
|
+
|
|
59
|
+
/// The read side, published in the node's ServiceRegistry so a NAT-traversal module
|
|
60
|
+
/// can consult it without holding the Node:
|
|
61
|
+
///
|
|
62
|
+
/// if (auto* nat = ctx.services.get<ExternalAddressService>())
|
|
63
|
+
/// if (nat->udp_mapping() == NatMapping::EndpointDependent) return; // don't bother
|
|
64
|
+
class ExternalAddressService {
|
|
65
|
+
public:
|
|
66
|
+
virtual ~ExternalAddressService() = default;
|
|
67
|
+
|
|
68
|
+
/// Endpoints peers have reported observing our shared datagram socket at, most
|
|
69
|
+
/// recently confirmed first. Empty until at least one peer has said so over a
|
|
70
|
+
/// datagram link. These are what a hole punch advertises to its target.
|
|
71
|
+
virtual std::vector<Address> external_udp_endpoints() const = 0;
|
|
72
|
+
|
|
73
|
+
/// What the observations so far say about the mapping.
|
|
74
|
+
virtual NatMapping udp_mapping() const = 0;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
class RATS_API NatStatus final : public ExternalAddressService {
|
|
78
|
+
public:
|
|
79
|
+
/// Observations kept. One per reporting peer, so a node with many peers does not
|
|
80
|
+
/// grow this without bound and a single peer cannot flood it either — a second
|
|
81
|
+
/// report from the same peer replaces its first rather than adding to it.
|
|
82
|
+
static constexpr size_t kMaxObservers = 32;
|
|
83
|
+
|
|
84
|
+
/// Record that `reporter` observed our datagram socket at `external`.
|
|
85
|
+
/// @param is_own_address whether that endpoint is one this node holds locally
|
|
86
|
+
/// (the caller knows its interfaces; this class does not) — the signal
|
|
87
|
+
/// that there is no NAT in the path.
|
|
88
|
+
void record_udp_observation(const PeerId& reporter, const Address& external,
|
|
89
|
+
bool is_own_address);
|
|
90
|
+
|
|
91
|
+
/// Forget a reporter's observation — its link is gone and what it saw may have
|
|
92
|
+
/// been a mapping that died with it.
|
|
93
|
+
void forget(const PeerId& reporter);
|
|
94
|
+
|
|
95
|
+
/// Drop everything. The node is restarting, or the host's network changed and
|
|
96
|
+
/// every mapping learned under the old one is now a guess.
|
|
97
|
+
void reset();
|
|
98
|
+
|
|
99
|
+
/// How many distinct peers have reported an endpoint.
|
|
100
|
+
size_t observation_count() const;
|
|
101
|
+
|
|
102
|
+
// — ExternalAddressService —
|
|
103
|
+
std::vector<Address> external_udp_endpoints() const override;
|
|
104
|
+
NatMapping udp_mapping() const override;
|
|
105
|
+
|
|
106
|
+
private:
|
|
107
|
+
struct Observation {
|
|
108
|
+
Address endpoint;
|
|
109
|
+
bool is_own_address = false;
|
|
110
|
+
uint64_t seq = 0; ///< arrival order, so the freshest endpoint sorts first
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
mutable std::mutex mutex_;
|
|
114
|
+
std::unordered_map<PeerId, Observation, PeerId::Hash> seen_;
|
|
115
|
+
uint64_t next_seq_ = 1;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
} // namespace librats
|