15#ifdef RATS_SEARCH_FEATURES
16#include "bittorrent.h"
25#include <unordered_map>
28#include <condition_variable>
29#include <unordered_set>
32#include "rats_export.h"
75 RatsPeer(
const std::string&
id,
const std::string& peer_ip, uint16_t peer_port,
76 socket_t sock,
const std::string& norm_addr,
bool outgoing)
123 ReconnectInfo(
const std::string&
id,
const std::string& peer_ip, uint16_t peer_port,
124 std::chrono::milliseconds duration,
bool stable)
166 uint32_t network_magic = htonl(
magic);
167 memcpy(data.data(), &network_magic, 4);
168 data[4] =
static_cast<uint8_t
>(
type);
181 uint32_t network_magic;
182 memcpy(&network_magic, data.data(), 4);
183 header.
magic = ntohl(network_magic);
218 using MessageCallback = std::function<void(
const std::string&,
const nlohmann::json&)>;
231 RatsClient(
int listen_port,
int max_peers = 10,
const std::string& bind_address =
"");
558 std::function<
void(
const std::vector<std::string>&)> callback);
569 std::function<
void(
const std::vector<std::string>&)> callback =
nullptr);
591 const std::map<std::string, std::string>& txt_records = {});
608 void set_mdns_callback(std::function<
void(
const std::string&,
int,
const std::string&)> callback);
714 void off(
const std::string& message_type);
722 void send(
const std::string& message_type,
const nlohmann::json& data,
SendCallback callback =
nullptr);
731 void send(
const std::string& peer_id,
const std::string& message_type,
const nlohmann::json& data,
SendCallback callback =
nullptr);
934 void on_topic_message(
const std::string& topic, std::function<
void(
const std::string&,
const std::string&,
const std::string&)> callback);
941 void on_topic_json_message(
const std::string& topic, std::function<
void(
const std::string&,
const std::string&,
const nlohmann::json&)> callback);
948 void on_topic_peer_joined(
const std::string& topic, std::function<
void(
const std::string&,
const std::string&)> callback);
955 void on_topic_peer_left(
const std::string& topic, std::function<
void(
const std::string&,
const std::string&)> callback);
1137 std::string
send_file(
const std::string& peer_id,
const std::string& file_path,
1138 const std::string& remote_filename =
"");
1148 std::string
send_directory(
const std::string& peer_id,
const std::string& directory_path,
1149 const std::string& remote_directory_name =
"",
bool recursive =
true);
1158 std::string
request_file(
const std::string& peer_id,
const std::string& remote_file_path,
1159 const std::string& local_path);
1170 const std::string& local_directory_path,
bool recursive =
true);
1328 const std::string& username,
const std::string& password);
1372 const std::string& server =
"stun.l.google.com",
1373 uint16_t port = 19302,
1374 int timeout_ms = 5000);
1527 bool storage_put(
const std::string& key,
const std::vector<uint8_t>& value);
1653#ifdef RATS_SEARCH_FEATURES
1690 std::shared_ptr<TorrentDownload>
add_torrent(
const std::string& torrent_file,
1691 const std::string& download_path);
1699 std::shared_ptr<TorrentDownload>
add_torrent(
const TorrentInfo& torrent_info,
1700 const std::string& download_path);
1710 const std::string& download_path);
1720 const std::string& download_path);
1761 std::function<
void(
const TorrentInfo&,
bool,
const std::string&)> callback);
1770 std::function<
void(
const TorrentInfo&,
bool,
const std::string&)> callback);
1782 const std::string& peer_ip,
1784 std::function<
void(
const TorrentInfo&,
bool,
const std::string&)> callback);
1795 const std::string& peer_ip,
1797 std::function<
void(
const TorrentInfo&,
bool,
const std::string&)> callback);
1821 const std::string& path,
1822 const std::vector<std::string>& trackers = {},
1823 const std::string& comment =
"",
1824 TorrentCreationProgressCallback progress_callback =
nullptr);
1835 const std::string& path,
1836 const std::vector<std::string>& trackers = {},
1837 const std::string& comment =
"",
1838 TorrentCreationProgressCallback progress_callback =
nullptr);
1850 const std::string& path,
1851 const std::string& output_file,
1852 const std::vector<std::string>& trackers = {},
1853 const std::string& comment =
"",
1854 TorrentCreationProgressCallback progress_callback =
nullptr);
1867 const std::string& path,
1868 const std::vector<std::string>& trackers = {},
1869 const std::string& comment =
"",
1870 TorrentCreationProgressCallback progress_callback =
nullptr);
1947 std::string bind_address_;
1950 std::atomic<bool> running_;
1968 mutable std::mutex config_mutex_;
1969 std::string our_peer_id_;
1970 std::string data_directory_;
1971 static const std::string CONFIG_FILE_NAME;
1972 static const std::string PEERS_FILE_NAME;
1973 static const std::string PEERS_EVER_FILE_NAME;
1976 mutable std::mutex protocol_config_mutex_;
1977 std::string custom_protocol_name_;
1978 std::string custom_protocol_version_;
1981 mutable std::mutex encryption_mutex_;
1982 bool encryption_enabled_;
1983 rats::NoiseKeyPair noise_static_keypair_;
1984 bool noise_keypair_initialized_;
1987 mutable std::mutex local_addresses_mutex_;
1988 std::vector<std::string> local_interface_addresses_;
1991 mutable std::mutex peers_mutex_;
1992 std::unordered_map<std::string, RatsPeer> peers_;
1993 std::unordered_map<socket_t, std::string> socket_to_peer_id_;
1994 std::unordered_map<std::string, std::string> address_to_peer_id_;
1997 mutable std::mutex socket_send_mutexes_mutex_;
1998 std::unordered_map<socket_t, std::shared_ptr<std::mutex>> socket_send_mutexes_;
2001 std::thread server_thread_;
2002 std::thread management_thread_;
2011 std::unique_ptr<DhtClient> dht_client_;
2014 std::unique_ptr<MdnsClient> mdns_client_;
2015 std::function<void(
const std::string&,
int,
const std::string&)> mdns_callback_;
2018 std::unique_ptr<GossipSub> gossipsub_;
2021 std::unique_ptr<FileTransferManager> file_transfer_manager_;
2024 std::unique_ptr<IceManager> ice_manager_;
2028 std::unique_ptr<StorageManager> storage_manager_;
2031#ifdef RATS_SEARCH_FEATURES
2033 std::unique_ptr<BitTorrentClient> bittorrent_client_;
2036 void initialize_modules();
2037 void destroy_modules();
2040 void management_loop();
2041 void handle_client(
socket_t client_socket,
const std::string& peer_hash_id);
2043 std::string generate_peer_hash_id(
socket_t socket,
const std::string& connection_info);
2044 void handle_dht_peer_discovery(
const std::vector<Peer>& peers,
const InfoHash& info_hash);
2045 void handle_mdns_service_discovery(
const MdnsService& service,
bool is_new);
2048 std::vector<uint8_t> create_message_with_header(
const std::vector<uint8_t>& payload,
MessageDataType type);
2049 bool parse_message_with_header(
const std::vector<uint8_t>& message,
MessageHeader& header, std::vector<uint8_t>& payload)
const;
2052 void add_peer(
const RatsPeer& peer);
2053 void add_peer_unlocked(
const RatsPeer& peer);
2054 void remove_peer_by_id(
const std::string& peer_id);
2055 void remove_peer_by_id_unlocked(
const std::string& peer_id);
2056 bool is_already_connected_to_address(
const std::string& normalized_address)
const;
2057 std::string normalize_peer_address(
const std::string& ip,
int port)
const;
2060 bool send_binary_to_peer_unlocked(
socket_t socket,
const std::vector<uint8_t>& data,
2062 rats::NoiseCipherState* send_cipher,
2063 const std::string& peer_id_for_logging);
2066 void initialize_local_addresses();
2067 bool is_blocked_address(
const std::string& ip_address)
const;
2068 bool should_ignore_peer(
const std::string& ip,
int port)
const;
2069 static bool parse_address_string(
const std::string& address_str, std::string& out_ip,
int& out_port);
2072 int get_peer_count_unlocked()
const;
2075 static constexpr const char* RATS_PROTOCOL_VERSION =
"1.0";
2076 static constexpr int HANDSHAKE_TIMEOUT_SECONDS = 10;
2078 struct HandshakeMessage {
2079 std::string protocol;
2080 std::string version;
2081 std::string peer_id;
2082 std::string message_type;
2084 bool encryption_enabled;
2085 uint16_t listen_port;
2088 std::string create_handshake_message(
const std::string& message_type,
const std::string& our_peer_id)
const;
2089 bool parse_handshake_message(
const std::vector<uint8_t>& data, HandshakeMessage& out_msg)
const;
2090 bool validate_handshake_message(
const HandshakeMessage& msg)
const;
2091 bool is_handshake_message(
const std::vector<uint8_t>& data)
const;
2092 bool send_handshake(
socket_t socket,
const std::string& our_peer_id);
2093 bool send_handshake_unlocked(
socket_t socket,
const std::string& our_peer_id);
2094 bool handle_handshake_message(
socket_t socket,
const std::string& peer_hash_id,
const std::vector<uint8_t>& data);
2095 void check_handshake_timeouts();
2096 void log_handshake_completion_unlocked(
const RatsPeer& peer);
2099 std::atomic<bool> auto_discovery_running_;
2100 std::thread auto_discovery_thread_;
2101 void automatic_discovery_loop();
2102 void announce_rats_peer();
2105 nlohmann::json create_rats_message(
const std::string& type,
const nlohmann::json& payload,
const std::string& sender_peer_id);
2106 void handle_rats_message(
socket_t socket,
const std::string& peer_hash_id,
const nlohmann::json& message);
2109 void handle_peer_exchange_message(
socket_t socket,
const std::string& peer_hash_id,
const nlohmann::json& payload);
2110 void handle_peers_request_message(
socket_t socket,
const std::string& peer_hash_id,
const nlohmann::json& payload);
2111 void handle_peers_response_message(
socket_t socket,
const std::string& peer_hash_id,
const nlohmann::json& payload);
2114 nlohmann::json create_peer_exchange_message(
const RatsPeer& peer);
2115 void broadcast_peer_exchange_message(
const RatsPeer& new_peer);
2116 nlohmann::json create_peers_request_message(
const std::string& sender_peer_id);
2117 nlohmann::json create_peers_response_message(
const std::vector<RatsPeer>& peers,
const std::string& sender_peer_id);
2118 std::vector<RatsPeer> get_random_peers(
int max_count,
const std::string& exclude_peer_id =
"")
const;
2119 void send_peers_request(
socket_t socket,
const std::string& our_peer_id);
2121 int broadcast_rats_message(
const nlohmann::json& message,
const std::string& exclude_peer_id =
"");
2122 int broadcast_rats_message_to_validated_peers(
const nlohmann::json& message,
const std::string& exclude_peer_id =
"");
2125 mutable std::mutex message_handlers_mutex_;
2127 MessageCallback callback;
2130 MessageHandler(MessageCallback cb,
bool once) : callback(cb), is_once(once) {}
2132 std::unordered_map<std::string, std::vector<MessageHandler>> message_handlers_;
2134 void call_message_handlers(
const std::string& message_type,
const std::string& peer_id,
const nlohmann::json& data);
2137 mutable std::mutex reconnect_mutex_;
2138 std::unordered_map<std::string, ReconnectInfo> reconnect_queue_;
2139 ReconnectConfig reconnect_config_;
2140 std::unordered_set<std::string> manual_disconnect_peers_;
2143 void schedule_reconnect(
const RatsPeer& peer);
2144 void process_reconnect_queue();
2145 void remove_from_reconnect_queue(
const std::string& peer_id);
2146 int get_retry_interval_seconds(
int attempt,
bool is_stable)
const;
2149 std::shared_ptr<std::mutex> get_socket_send_mutex(
socket_t socket);
2150 void cleanup_socket_send_mutex(
socket_t socket);
2153 std::string generate_persistent_peer_id()
const;
2154 nlohmann::json serialize_peer_for_persistence(
const RatsPeer& peer)
const;
2155 bool deserialize_peer_from_persistence(
const nlohmann::json& json, std::string& ip,
int& port, std::string& peer_id)
const;
2156 std::string get_config_file_path()
const;
2157 std::string get_peers_file_path()
const;
2158 std::string get_peers_ever_file_path()
const;
2159 bool save_peers_to_file();
2160 bool append_peer_to_historical_file(
const RatsPeer& peer);
2161 int load_and_reconnect_historical_peers();
2164 void initialize_noise_keypair();
2165 bool perform_noise_handshake(
socket_t socket,
const std::string& peer_id,
bool is_initiator);
2166 bool send_noise_message(
socket_t socket,
const uint8_t* data,
size_t len);
2167 bool recv_noise_message(
socket_t socket, std::vector<uint8_t>& out_data,
int timeout_ms = 10000);
2168 bool encrypt_and_send(
socket_t socket,
const std::string& peer_id,
const std::vector<uint8_t>& plaintext);
2169 bool receive_and_decrypt(
socket_t socket,
const std::string& peer_id, std::vector<uint8_t>& plaintext);
File transfer manager class Handles efficient chunked file transfers with resume capability.
Main GossipSub implementation class.
ICE-lite Manager for NAT traversal.
RatsClient - Core peer-to-peer networking client.
std::function< void(socket_t, const std::string &, const std::vector< uint8_t > &)> BinaryDataCallback
std::vector< ReconnectInfo > get_reconnect_queue() const
Get information about peers pending reconnection.
LogLevel get_log_level() const
Get the current log level.
std::vector< MdnsService > get_mdns_services() const
Get recently discovered mDNS services.
void on_ice_gathering_state_changed(IceGatheringStateCallback callback)
Set callback for ICE gathering state changes.
std::vector< RatsPeer > get_all_peers() const
Get all connected peers.
bool reject_directory_transfer(const std::string &transfer_id, const std::string &reason="")
Reject an incoming directory transfer.
void set_encryption_enabled(bool enabled)
Set encryption enabled/disabled.
std::vector< uint8_t > create_torrent_data(const std::string &path, const std::vector< std::string > &trackers={}, const std::string &comment="", TorrentCreationProgressCallback progress_callback=nullptr)
Create a torrent from a file or directory and return raw torrent data.
bool subscribe_to_topic(const std::string &topic)
Subscribe to a GossipSub topic.
bool save_historical_peers()
Save current peers to a historical file.
void stop_mdns_discovery()
Stop mDNS discovery.
std::optional< StunMappedAddress > discover_public_address(const std::string &server="stun.l.google.com", uint16_t port=19302, int timeout_ms=5000)
Perform a simple STUN binding request to discover public address This is a convenience method that do...
std::function< void(socket_t, const std::string &, const nlohmann::json &)> JsonDataCallback
std::function< void(bool, const std::string &)> SendCallback
void set_log_level(const std::string &level_str)
Set the minimum log level using string.
bool cancel_file_transfer(const std::string &transfer_id)
Cancel an active or paused file transfer.
void set_file_transfer_config(const FileTransferConfig &config)
Set file transfer configuration.
bool is_file_transfer_available() const
Check if file transfer is available.
size_t get_spider_pool_size() const
Get the size of the spider node pool.
bool initialize_encryption(bool enable)
Initialize encryption system.
void set_spider_announce_callback(SpiderAnnounceCallback callback)
Set callback for announce_peer requests (spider mode) Called when other peers announce they have a to...
bool is_dht_running() const
Check if DHT is currently running.
void on_file_transfer_progress(FileTransferProgressCallback callback)
Set file transfer progress callback.
std::function< void(socket_t, const std::string &)> DisconnectCallback
void start_automatic_peer_discovery()
Start automatic peer discovery.
std::string get_log_file_path() const
Get the current log file path.
void set_log_rotation_size(size_t max_size_bytes)
Set log file rotation size.
const StorageConfig & get_storage_config() const
Get current storage configuration.
void set_log_rotate_on_startup(bool enabled)
Enable or disable log rotation on application startup When enabled, the existing log file will be rot...
IceGatheringState get_ice_gathering_state() const
Get ICE gathering state.
void set_string_data_callback(StringDataCallback callback)
Set string data callback (called when string data is received)
int broadcast_binary_to_peers(const std::vector< uint8_t > &data, MessageDataType message_type=MessageDataType::BINARY)
Broadcast binary data to all connected peers (primary method)
const RatsPeer * get_peer_by_socket(socket_t socket) const
Get peer information by socket.
bool set_noise_static_keypair(const uint8_t private_key[32])
Set a custom static keypair for Noise Protocol If not set, a new keypair is generated automatically.
std::vector< std::shared_ptr< TorrentDownload > > get_all_torrents()
Get all active torrents.
size_t storage_size() const
Get the number of entries in storage.
int broadcast_string_to_peers(const std::string &data)
Broadcast string data to all connected peers.
int broadcast_json_to_peers(const nlohmann::json &data)
Broadcast JSON data to all connected peers.
std::function< void(const std::string &info_hash, const std::string &peer_address)> SpiderAnnounceCallback
Spider announce callback type Called when a peer announces they have a torrent (announce_peer request...
bool send_binary_to_peer_id(const std::string &peer_id, const std::vector< uint8_t > &data, MessageDataType message_type=MessageDataType::BINARY)
Send binary data to a peer by peer_id (preferred)
std::string request_directory(const std::string &peer_id, const std::string &remote_directory_path, const std::string &local_directory_path, bool recursive=true)
Request a directory from a remote peer.
void on_ice_selected_pair(IceSelectedPairCallback callback)
Set callback for ICE selected pair.
std::optional< std::pair< std::string, uint16_t > > get_public_address() const
Get our public IP address (discovered via STUN)
void clear_spider_state()
Clear spider state (pool and visited nodes) Useful for resetting the spider walk.
void set_spider_mode(bool enable)
Enable spider mode on DHT In spider mode:
std::string get_discovery_hash() const
Get the discovery hash for current protocol configuration.
void set_spider_ignore(bool ignore)
Set spider ignore mode - when true, incoming requests are not processed Useful for rate limiting in s...
bool parse_json_message(const std::string &message, nlohmann::json &out_json)
Parse a JSON message.
bool is_storage_available() const
Check if storage is available.
void add_remote_ice_candidates_from_sdp(const std::vector< std::string > &sdp_lines)
Add remote ICE candidates from SDP attribute lines.
void get_torrent_metadata_from_peer(const InfoHash &info_hash, const std::string &peer_ip, uint16_t peer_port, std::function< void(const TorrentInfo &, bool, const std::string &)> callback)
Get torrent metadata directly from a specific peer (fast path - no DHT search needed) This is more ef...
std::string get_bind_address() const
Get the bind address being used.
bool is_log_timestamps_enabled() const
Check if timestamps are enabled in log output.
void clear_ice_servers()
Clear all ICE (STUN/TURN) servers.
void on_ice_candidates_gathered(IceCandidatesCallback callback)
Set callback for ICE candidates gathered.
std::shared_ptr< TorrentDownload > add_torrent_by_hash(const std::string &info_hash_hex, const std::string &download_path)
Add a torrent by info hash hex string (magnet link style - uses DHT to find peers)
void set_reconnect_enabled(bool enabled)
Enable or disable automatic reconnection to disconnected peers.
bool is_encryption_enabled() const
Check if encryption is enabled.
bool publish_to_topic(const std::string &topic, const std::string &message)
Publish a message to a GossipSub topic.
std::vector< RatsPeer > get_validated_peers() const
Get all peers that have completed handshake.
std::function< void(uint32_t current_piece, uint32_t total_pieces)> TorrentCreationProgressCallback
Torrent creation progress callback type Called during piece hashing to report progress.
void add_remote_ice_candidate(const IceCandidate &candidate)
Add a remote ICE candidate (received from peer via signaling)
void close_ice()
Close ICE manager and release resources.
bool send_string_to_peer(socket_t socket, const std::string &data)
Send string data to a specific peer.
std::string get_our_peer_id() const
Get our own peer ID.
void set_ice_config(const IceConfig &config)
Set ICE configuration.
size_t get_active_torrents_count() const
Get the number of active torrents.
bool storage_has(const std::string &key) const
Check if a key exists in storage.
std::optional< std::vector< uint8_t > > storage_get_binary(const std::string &key) const
Get binary data.
bool unsubscribe_from_topic(const std::string &topic)
Unsubscribe from a GossipSub topic.
void off_topic(const std::string &topic)
Remove all event handlers for a GossipSub topic.
void set_log_level(LogLevel level)
Set the minimum log level.
bool save_configuration()
Save configuration to files.
void disable_bittorrent()
Disable BitTorrent functionality.
std::shared_ptr< TorrentDownload > add_torrent(const std::string &torrent_file, const std::string &download_path)
Add a torrent from a file.
void stop_automatic_peer_discovery()
Stop automatic peer discovery.
std::shared_ptr< TorrentDownload > create_and_seed_torrent(const std::string &path, const std::vector< std::string > &trackers={}, const std::string &comment="", TorrentCreationProgressCallback progress_callback=nullptr)
Create a torrent, add it to the BitTorrent client, and start seeding This combines torrent creation w...
bool storage_delete(const std::string &key)
Delete a key from storage.
bool accept_directory_transfer(const std::string &transfer_id, const std::string &local_path)
Accept an incoming directory transfer.
void on_storage_sync_complete(StorageSyncCompleteCallback callback)
Set storage sync complete callback.
void off(const std::string &message_type)
Remove all handlers for a message type.
bool is_peer_encrypted(const std::string &peer_id) const
Check if a peer connection is encrypted.
void shutdown_all_threads()
Shutdown all background threads.
void disconnect_peer_by_id(const std::string &peer_id)
Disconnect from a peer by peer_id (preferred)
std::vector< std::string > storage_keys_with_prefix(const std::string &prefix) const
Get keys matching a prefix.
void add_turn_server(const std::string &host, uint16_t port, const std::string &username, const std::string &password)
Add a TURN server for relay-based NAT traversal.
void set_topic_message_validator(const std::string &topic, std::function< ValidationResult(const std::string &, const std::string &, const std::string &)> validator)
Set a message validator for a GossipSub topic.
bool storage_put(const std::string &key, const std::string &value)
Store a string value.
StorageManager & get_storage_manager()
Get the storage manager instance.
bool is_console_logging_enabled() const
Check if console logging is currently enabled.
void set_log_file_path(const std::string &file_path)
Set the log file path.
void send(const std::string &message_type, const nlohmann::json &data, SendCallback callback=nullptr)
Send a message to all peers.
bool find_peers_by_hash(const std::string &content_hash, std::function< void(const std::vector< std::string > &)> callback)
Find peers by content hash using DHT.
void on_file_transfer_request(FileTransferRequestCallback callback)
Set incoming file transfer request callback.
bool load_configuration()
Load configuration from files.
std::shared_ptr< FileTransferProgress > get_file_transfer_progress(const std::string &transfer_id) const
Get file transfer progress information.
void clear_log_file()
Clear/reset the current log file.
void set_console_logging_enabled(bool enabled)
Enable or disable console logging When disabled, log messages will not be printed to stdout/stderr Fi...
std::string send_directory(const std::string &peer_id, const std::string &directory_path, const std::string &remote_directory_name="", bool recursive=true)
Send an entire directory to a peer.
bool storage_request_sync()
Request storage sync from connected peers.
std::string request_file(const std::string &peer_id, const std::string &remote_file_path, const std::string &local_path)
Request a file from a remote peer.
bool connect_to_peer(const std::string &host, int port)
Connect to a peer via direct TCP connection.
bool is_ice_connected() const
Check if ICE is connected.
bool publish_json_to_topic(const std::string &topic, const nlohmann::json &message)
Publish a JSON message to a GossipSub topic.
void clear_historical_peers()
Clear all historical peers.
void stop()
Stop the RatsClient and close all connections.
std::pair< uint64_t, uint64_t > get_bittorrent_stats() const
Get BitTorrent statistics (downloaded and uploaded bytes)
std::optional< std::string > storage_get_string(const std::string &key) const
Get a string value.
bool enable_bittorrent(int listen_port=6881)
Enable BitTorrent functionality.
GossipSub & get_gossipsub()
Get GossipSub instance for publish-subscribe messaging.
void on_file_transfer_completed(FileTransferCompletedCallback callback)
Set file transfer completion callback.
void on_topic_message(const std::string &topic, std::function< void(const std::string &, const std::string &, const std::string &)> callback)
Set a message handler for a GossipSub topic using unified event API pattern.
size_t get_spider_visited_count() const
Get the number of visited nodes in spider mode.
bool accept_file_transfer(const std::string &transfer_id, const std::string &local_path)
Accept an incoming file transfer.
bool send_binary_to_peer(socket_t socket, const std::vector< uint8_t > &data, MessageDataType message_type=MessageDataType::BINARY)
Send binary data to a specific peer (primary method)
void get_torrent_metadata(const std::string &info_hash_hex, std::function< void(const TorrentInfo &, bool, const std::string &)> callback)
Get torrent metadata without downloading by hex string (requires DHT to be running)
bool is_spider_mode() const
Check if spider mode is enabled.
std::function< void(socket_t, const std::string &)> ConnectionCallback
void on(const std::string &message_type, MessageCallback callback)
Register a persistent message handler.
void on_directory_request(DirectoryRequestCallback callback)
Set directory request callback (called when receiving directory requests)
void set_storage_config(const StorageConfig &config)
Set storage configuration.
void add_ignored_address(const std::string &ip_address)
Add an IP address to the ignore list (for blocking connections to self)
void set_connection_callback(ConnectionCallback callback)
Set connection callback (called when a new peer connects)
bool is_peer_limit_reached() const
Check if peer limit has been reached.
void set_log_retention_count(int count)
Set the number of log files to retain during rotation.
std::vector< std::shared_ptr< FileTransferProgress > > get_active_file_transfers() const
Get all active file transfers.
bool query_mdns_services()
Manually query for mDNS services.
const RatsPeer * get_peer_by_id(const std::string &peer_id) const
Get peer information by peer ID.
std::string send_file(const std::string &peer_id, const std::string &file_path, const std::string &remote_filename="")
Send a file to a peer.
std::optional< IceCandidatePair > get_ice_selected_pair() const
Get the selected ICE candidate pair.
void set_mdns_callback(std::function< void(const std::string &, int, const std::string &)> callback)
Set mDNS service discovery callback.
void on_storage_change(StorageChangeCallback callback)
Set storage change callback.
FileTransferManager & get_file_transfer_manager()
Get the file transfer manager instance.
bool start_mdns_discovery(const std::string &service_instance_name="", const std::map< std::string, std::string > &txt_records={})
Start mDNS service discovery and announcement.
bool is_ice_available() const
Check if ICE is available.
bool start_dht_discovery(int dht_port=6881)
Start DHT discovery on specified port.
void set_disconnect_callback(DisconnectCallback callback)
Set disconnect callback (called when a peer disconnects)
std::shared_ptr< TorrentDownload > add_torrent(const TorrentInfo &torrent_info, const std::string &download_path)
Add a torrent from TorrentInfo.
const FileTransferConfig & get_file_transfer_config() const
Get current file transfer configuration.
int load_and_reconnect_peers()
Load saved peers and attempt to reconnect.
void spider_walk()
Trigger a single spider walk iteration Sends find_node to a random node from the spider pool Call thi...
void on_directory_transfer_progress(DirectoryTransferProgressCallback callback)
Set directory transfer progress callback.
nlohmann::json get_storage_statistics() const
Get storage statistics.
IceManager & get_ice_manager()
Get the ICE manager instance.
bool is_reconnect_enabled() const
Check if automatic reconnection is enabled.
void set_protocol_name(const std::string &protocol_name)
Set custom protocol name for handshakes and DHT discovery.
static std::string get_rats_peer_discovery_hash()
Get the well-known RATS peer discovery hash.
void get_torrent_metadata(const InfoHash &info_hash, std::function< void(const TorrentInfo &, bool, const std::string &)> callback)
Get torrent metadata without downloading (requires DHT to be running)
bool is_mdns_running() const
Check if mDNS is currently running.
nlohmann::json get_file_transfer_statistics() const
Get file transfer statistics.
void set_resume_data_path(const std::string &path)
Set the directory for storing resume data files Resume data allows torrents to resume from where they...
bool start()
Start the RatsClient and begin listening for connections.
void on_ice_connection_state_changed(IceConnectionStateCallback callback)
Set callback for ICE connection state changes.
std::vector< uint8_t > get_peer_noise_public_key(const std::string &peer_id) const
Get the remote peer's Noise static public key.
void set_logging_enabled(bool enabled)
Enable or disable file logging When enabled, logs will be written to "rats.log" by default.
bool is_logging_enabled() const
Check if file logging is currently enabled.
std::optional< int64_t > storage_get_int(const std::string &key) const
Get a 64-bit integer value.
void set_binary_data_callback(BinaryDataCallback callback)
Set binary data callback (called when binary data is received)
bool storage_put_json(const std::string &key, const nlohmann::json &value)
Store a JSON document.
bool create_torrent_file(const std::string &path, const std::string &output_file, const std::vector< std::string > &trackers={}, const std::string &comment="", TorrentCreationProgressCallback progress_callback=nullptr)
Create a torrent and save it to a file.
void on_topic_peer_joined(const std::string &topic, std::function< void(const std::string &, const std::string &)> callback)
Set a peer joined handler for a GossipSub topic using unified event API pattern.
void stop_dht_discovery()
Stop DHT discovery.
bool remove_torrent(const InfoHash &info_hash)
Remove a torrent by info hash.
int get_peer_count() const
Get the number of currently connected peers.
bool is_automatic_discovery_running() const
Check if automatic discovery is running.
void add_stun_server(const std::string &host, uint16_t port=STUN_DEFAULT_PORT)
Add a STUN server for NAT traversal.
std::vector< std::string > storage_keys() const
Get all keys in storage.
std::optional< nlohmann::json > storage_get_json(const std::string &key) const
Get a JSON document.
bool is_gossipsub_available() const
Check if GossipSub is available.
size_t get_reconnect_queue_size() const
Get the number of peers pending reconnection.
socket_t get_peer_socket_by_id(const std::string &peer_id) const
Get socket for a peer by peer_id (preferred)
nlohmann::json get_gossipsub_statistics() const
Get GossipSub statistics.
std::vector< uint8_t > get_noise_static_public_key() const
Get our Noise Protocol static public key.
void set_reconnect_config(const ReconnectConfig &config)
Set reconnection configuration.
bool load_historical_peers()
Load historical peers from a file.
RatsClient(int listen_port, int max_peers=10, const std::string &bind_address="")
Constructor.
bool pause_file_transfer(const std::string &transfer_id)
Pause an active file transfer.
int get_max_peers() const
Get maximum number of peers.
bool send_string_to_peer_id(const std::string &peer_id, const std::string &data)
Send string data to a peer by peer_id (preferred)
void set_json_data_callback(JsonDataCallback callback)
Set JSON data callback (called when JSON data is received)
std::chrono::seconds calculate_discovery_interval() const
Calculate discovery interval based on current peer count Uses graduated scaling: more aggressive when...
bool storage_put(const std::string &key, double value)
Store a double-precision floating point value.
int get_listen_port() const
bool send_json_to_peer_id(const std::string &peer_id, const nlohmann::json &data)
Send JSON data to a peer by peer_id (preferred)
std::function< void(socket_t, const std::string &, const std::string &)> StringDataCallback
void end_of_remote_ice_candidates()
Signal end of remote candidates (trickle ICE complete)
std::vector< std::string > get_topic_mesh_peers(const std::string &topic) const
Get mesh peers for a GossipSub topic.
void disconnect_peer(socket_t socket)
Disconnect from a specific peer.
bool is_gossipsub_running() const
Check if GossipSub is running.
bool is_bittorrent_enabled() const
Check if BitTorrent is enabled.
const ReconnectConfig & get_reconnect_config() const
Get current reconnection configuration.
bool is_subscribed_to_topic(const std::string &topic) const
Check if subscribed to a GossipSub topic.
void restart_ice()
Restart ICE (re-gather candidates and restart checks)
std::shared_ptr< TorrentDownload > add_torrent_by_hash(const InfoHash &info_hash, const std::string &download_path)
Add a torrent by info hash (magnet link style - uses DHT to find peers)
bool is_spider_ignoring() const
Check if spider ignore mode is enabled.
bool is_log_rotate_on_startup_enabled() const
Check if log rotation on startup is enabled.
bool reject_file_transfer(const std::string &transfer_id, const std::string &reason="")
Reject an incoming file transfer.
void set_max_peers(int max_peers)
Set maximum number of peers.
IceConnectionState get_ice_connection_state() const
Get current ICE connection state.
std::string get_protocol_version() const
Get current protocol version.
bool announce_for_hash(const std::string &content_hash, uint16_t port=0, std::function< void(const std::vector< std::string > &)> callback=nullptr)
Announce our presence for a content hash with optional peer discovery callback If callback is provide...
std::optional< double > storage_get_double(const std::string &key) const
Get a double-precision floating point value.
std::shared_ptr< TorrentDownload > get_torrent(const InfoHash &info_hash)
Get a torrent by info hash.
void set_protocol_version(const std::string &protocol_version)
Set custom protocol version for handshakes.
bool storage_put(const std::string &key, int64_t value)
Store a 64-bit integer value.
std::string get_protocol_name() const
Get current protocol name.
std::vector< std::string > get_topic_peers(const std::string &topic) const
Get peers subscribed to a GossipSub topic.
void start_ice_checks()
Start ICE connectivity checks.
void on_ice_new_candidate(IceNewCandidateCallback callback)
Set callback for new ICE candidate (trickle ICE)
size_t get_dht_routing_table_size() const
Get the size of the DHT routing table.
std::vector< IceCandidate > get_ice_candidates() const
Get our local ICE candidates Call after gathering is complete.
std::string get_peer_id(socket_t socket) const
Get peer_id for a peer by socket (preferred)
void get_torrent_metadata_from_peer(const std::string &info_hash_hex, const std::string &peer_ip, uint16_t peer_port, std::function< void(const TorrentInfo &, bool, const std::string &)> callback)
Get torrent metadata directly from a specific peer by hex string (fast path)
bool is_running() const
Check if the client is currently running.
const IceConfig & get_ice_config() const
Get current ICE configuration.
bool resume_file_transfer(const std::string &transfer_id)
Resume a paused file transfer.
void clear_reconnect_queue()
Clear all pending reconnection attempts.
void set_log_timestamps_enabled(bool enabled)
Enable or disable timestamps in log output.
std::vector< std::string > get_subscribed_topics() const
Get list of subscribed GossipSub topics.
bool gather_ice_candidates()
Start gathering ICE candidates This discovers our public address and generates connection candidates.
bool send_json_to_peer(socket_t socket, const nlohmann::json &data)
Send JSON data to a specific peer.
std::vector< RatsPeer > get_historical_peers() const
Get all historical peers.
void on_topic_peer_left(const std::string &topic, std::function< void(const std::string &, const std::string &)> callback)
Set a peer left handler for a GossipSub topic using unified event API pattern
std::optional< TorrentInfo > create_torrent_from_path(const std::string &path, const std::vector< std::string > &trackers={}, const std::string &comment="", TorrentCreationProgressCallback progress_callback=nullptr)
Create a torrent from a file or directory and return TorrentInfo This is a synchronous operation that...
void send(const std::string &peer_id, const std::string &message_type, const nlohmann::json &data, SendCallback callback=nullptr)
Send a message to a specific peer.
void set_log_colors_enabled(bool enabled)
Enable or disable colored log output.
std::vector< uint8_t > get_peer_handshake_hash(const std::string &peer_id) const
Get the handshake hash for a peer connection (for channel binding)
bool is_ice_gathering_complete() const
Check if ICE candidate gathering is complete.
void on_file_request(FileRequestCallback callback)
Set file request callback (called when receiving file requests)
bool set_data_directory(const std::string &directory_path)
Set directory where data files will be stored.
void once(const std::string &message_type, MessageCallback callback)
Register a one-time message handler.
bool is_storage_synced() const
Check if storage is synchronized.
nlohmann::json get_connection_statistics() const
Get connection statistics.
std::string get_data_directory() const
Get current data directory path.
bool is_log_colors_enabled() const
Check if colored log output is enabled.
void on_topic_json_message(const std::string &topic, std::function< void(const std::string &, const std::string &, const nlohmann::json &)> callback)
Set a JSON message handler for a GossipSub topic using unified event API pattern.
std::function< void(const std::string &, const nlohmann::json &)> MessageCallback
bool storage_put(const std::string &key, const std::vector< uint8_t > &value)
Store binary data.
ThreadManager - Manages background threads with graceful shutdown.
ICE-lite (Interactive Connectivity Establishment) Implementation.
IceGatheringState
ICE gathering state.
std::function< void(IceGatheringState)> IceGatheringStateCallback
Callback when gathering state changes.
std::function< void(const std::string &topic, const std::string &message, const std::string &sender_peer_id)> MessageHandler
MessageDataType
Message data types for librats message headers.
uint32_t rats_get_library_abi()
std::function< void(const std::string &transfer_id, bool success, const std::string &error_message)> FileTransferCompletedCallback
const char * rats_get_library_version_string()
std::function< void(const IceCandidate &)> IceNewCandidateCallback
Callback when a new candidate is discovered (trickle ICE)
std::function< void(const std::vector< IceCandidate > &)> IceCandidatesCallback
Callback when candidates are gathered.
std::function< bool(const std::string &peer_id, const std::string &file_path, const std::string &transfer_id)> FileRequestCallback
std::function< bool(const std::string &peer_id, const std::string &directory_path, bool recursive, const std::string &transfer_id)> DirectoryRequestCallback
std::function< void(IceConnectionState)> IceConnectionStateCallback
Callback when connection state changes.
std::function< void(const FileTransferProgress &)> FileTransferProgressCallback
Callback function types for file transfer events.
std::function< void(const IceCandidatePair &)> IceSelectedPairCallback
Callback when ICE completes with selected pair.
ValidationResult
Message validation result.
std::unique_ptr< RatsClient > create_rats_client(int listen_port)
std::array< uint8_t, NODE_ID_SIZE > InfoHash
void rats_get_library_version(int *major, int *minor, int *patch, int *build)
std::function< void(const std::string &transfer_id, const std::string ¤t_file, uint64_t files_completed, uint64_t total_files, uint64_t bytes_completed, uint64_t total_bytes)> DirectoryTransferProgressCallback
const char * rats_get_library_git_describe()
IceConnectionState
ICE connection state.
std::function< bool(const std::string &peer_id, const FileMetadata &metadata, const std::string &transfer_id)> FileTransferRequestCallback
File transfer configuration.
RatsPeer struct - comprehensive information about a connected rats peer.
std::shared_ptr< rats::NoiseCipherState > recv_cipher
std::vector< uint8_t > remote_static_key
bool is_noise_encrypted() const
std::shared_ptr< rats::NoiseCipherState > send_cipher
bool is_handshake_completed() const
bool noise_handshake_completed
HandshakeState handshake_state
RatsPeer(const std::string &id, const std::string &peer_ip, uint16_t peer_port, socket_t sock, const std::string &norm_addr, bool outgoing)
bool is_handshake_failed() const
std::chrono::steady_clock::time_point handshake_start_time
std::string normalized_address
std::chrono::steady_clock::time_point connected_at
ReconnectConfig - Configuration for automatic peer reconnection.
std::vector< int > retry_intervals_seconds
int stable_first_retry_seconds
int stable_connection_threshold_seconds
ReconnectInfo - Information about a peer pending reconnection.
ReconnectInfo(const std::string &id, const std::string &peer_ip, uint16_t peer_port, std::chrono::milliseconds duration, bool stable)
std::chrono::milliseconds connection_duration
std::chrono::steady_clock::time_point next_attempt_time