A high-performance, lightweight peer-to-peer networking library with C++, C, Java, Python, and Android support
librats is a modern P2P networking library designed for superior performance and simplicity. Built from the ground up in C++17 with comprehensive language bindings, it provides enterprise-grade P2P networking capabilities with minimal overhead and maximum efficiency.
Official Website: https://librats.com
- Native C++17 implementation for maximum performance
- Cross-platform support (Windows, Linux, macOS)
- Thread-safe design with modern concurrency patterns using
ThreadManager
- Zero-copy data handling where possible
- Automatic configuration persistence with JSON-based settings (
config.json
) - Historical peer tracking with automatic reconnection (
peers.rats
,peers_ever.rats
)
- DHT Integration: Direct access to the massive BitTorrent DHT network
- mDNS Discovery: Automatic local network peer discovery with service advertisement
- STUN Support: Automatic NAT traversal and public IP discovery
- IPv4/IPv6 Dual Stack: Full support for modern internet protocols
- Multi-layer Discovery: DHT (wide-area) + mDNS (local) + STUN (NAT traversal)
- GossipSub Protocol: Scalable publish-subscribe messaging with mesh networking
- Message Validation: Configurable message validation and filtering
- Topic-based Communication: Organized messaging with topic subscriptions
- Chunked Transfers: Efficient file splitting with parallel chunk transmission
- Resume Capability: Automatic resume of interrupted transfers with checksum validation
- Directory Transfer: Complete directory trees with recursive subdirectory support
- Transfer Control: Pause, resume, cancel operations with real-time progress tracking
- Security Validation: SHA256 checksums for data integrity verification
- Configurable Performance: Adjustable chunk size, concurrency, and timeout settings
- Request/Response Model: Secure file requests with acceptance/rejection callbacks
- Transfer Statistics: Comprehensive metrics including speed, ETA, and completion rates
- ICE (Interactive Connectivity Establishment): RFC 8445 compliant with full candidate gathering
- TURN Relay Support: RFC 5766 compliant relay through TURN servers
- Advanced STUN: Enhanced STUN client with NAT type detection and ICE support
- UDP/TCP Hole Punching: Coordinated NAT traversal for maximum connectivity
- Automatic Strategy Selection: Choose optimal connection method based on network conditions
- Real-time NAT Detection: Detailed NAT behavior analysis and adaptation
- Noise Protocol Encryption: End-to-end encryption with Curve25519 + ChaCha20-Poly1305
- Automatic Key Management: Keys generated, persisted, and rotated automatically
- Mutual Authentication: Both peers verify each other's identity
- Perfect Forward Secrecy: Session keys are ephemeral and secure
- Configurable Encryption: Enable/disable on demand with
set_encryption_enabled()
- Event-Driven API: Register message handlers with
on()
,once()
,off()
methods - JSON Message Exchange: Built-in structured communication with callbacks
- Promise-style Callbacks: Modern async patterns for network operations
- Real-time Connection Tracking: Monitor peer states, connection quality, and NAT traversal progress
- Comprehensive Logging API: Full control over logging levels, file rotation, and output formatting
- Custom Protocol Support: Configure custom protocol names and versions
- Unified API Design: Consistent patterns across P2P messaging and pub-sub
- Topic-based Messaging: Subscribe to topics and publish messages with automatic routing
- Enhanced Peer Management: Detailed peer information with encryption and NAT traversal status
- Native C++17: Core implementation with full feature set and maximum performance
- C API: Clean C interface for legacy systems and FFI bindings
- Java/Android: Complete JNI wrapper with high-level Java API for Android development
- Python Bindings: Full-featured Python package with ctypes wrapper and asyncio support
- Cross-Platform: Consistent API across Windows, Linux, macOS, and Android platforms
#include "librats.h"
#include <iostream>
#include <thread>
#include <chrono>
int main() {
// Create a simple P2P client
librats::RatsClient client(8080);
// Set up connection callback
client.set_connection_callback([](socket_t socket, const std::string& peer_id) {
std::cout << "β
New peer connected: " << peer_id << std::endl;
});
// Set up message callback
client.set_string_data_callback([](socket_t socket, const std::string& peer_id, const std::string& message) {
std::cout << "π¬ Message from " << peer_id << ": " << message << std::endl;
});
// Start the client
if (!client.start()) {
std::cerr << "Failed to start client" << std::endl;
return 1;
}
std::cout << "π librats client running on port 8080" << std::endl;
// Connect to another peer (optional)
// client.connect_to_peer("127.0.0.1", 8081);
// Send a message to all connected peers
client.broadcast_string_to_peers("Hello from librats!");
// Keep running
std::this_thread::sleep_for(std::chrono::minutes(1));
return 0;
}
#include "librats.h"
#include <iostream>
int main() {
librats::RatsClient client(8080);
// Configure custom protocol for your application
client.set_protocol_name("my_app");
client.set_protocol_version("1.0");
std::cout << "Protocol: " << client.get_protocol_name()
<< " v" << client.get_protocol_version() << std::endl;
std::cout << "Discovery hash: " << client.get_discovery_hash() << std::endl;
client.start();
// Start DHT discovery with custom protocol
if (client.start_dht_discovery()) {
// Announce our presence
client.announce_for_hash(client.get_discovery_hash());
// Search for other peers using same protocol
client.find_peers_by_hash(client.get_discovery_hash(),
[](const std::vector<std::string>& peers) {
std::cout << "Found " << peers.size() << " peers" << std::endl;
});
}
return 0;
}
#include "librats.h"
#include <iostream>
#include <string>
int main() {
librats::RatsClient client(8080);
// Set up message handlers using the modern API
client.on("chat", [](const std::string& peer_id, const nlohmann::json& data) {
std::cout << "[CHAT] " << peer_id << ": " << data["message"].get<std::string>() << std::endl;
});
client.on("user_join", [](const std::string& peer_id, const nlohmann::json& data) {
std::cout << "[JOIN] " << data["username"].get<std::string>() << " joined" << std::endl;
});
// Connection callback
client.set_connection_callback([&](socket_t socket, const std::string& peer_id) {
std::cout << "β
Peer connected: " << peer_id << std::endl;
// Send welcome message
nlohmann::json welcome;
welcome["username"] = "User_" + client.get_our_peer_id().substr(0, 8);
client.send("user_join", welcome);
});
client.start();
// Send a chat message
nlohmann::json chat_msg;
chat_msg["message"] = "Hello, P2P chat!";
chat_msg["timestamp"] = std::time(nullptr);
client.send("chat", chat_msg);
return 0;
}
#include "librats.h"
#include <iostream>
int main() {
librats::RatsClient client(8080);
// Set up topic message handlers
client.on_topic_message("news", [](const std::string& peer_id, const std::string& topic, const std::string& message) {
std::cout << "π° [" << topic << "] " << peer_id << ": " << message << std::endl;
});
client.on_topic_json_message("events", [](const std::string& peer_id, const std::string& topic, const nlohmann::json& data) {
std::cout << "π [" << topic << "] Event: " << data["type"].get<std::string>() << std::endl;
});
// Peer join/leave notifications
client.on_topic_peer_joined("news", [](const std::string& peer_id, const std::string& topic) {
std::cout << "β " << peer_id << " joined " << topic << std::endl;
});
client.start();
client.start_dht_discovery();
// Subscribe to topics
client.subscribe_to_topic("news");
client.subscribe_to_topic("events");
// Publish messages
client.publish_to_topic("news", "Breaking: librats is awesome!");
nlohmann::json event;
event["type"] = "celebration";
event["reason"] = "successful_connection";
client.publish_json_to_topic("events", event);
std::cout << "π Peers in 'news': " << client.get_topic_peers("news").size() << std::endl;
return 0;
}
#include "librats.h"
#include <iostream>
int main() {
librats::RatsClient client(8080);
// Set up file transfer callbacks
client.on_file_transfer_progress([](const librats::FileTransferProgress& progress) {
std::cout << "π Transfer " << progress.transfer_id.substr(0, 8)
<< ": " << progress.get_completion_percentage() << "% complete"
<< " (" << (progress.transfer_rate_bps / 1024) << " KB/s)" << std::endl;
});
client.on_file_transfer_completed([](const std::string& transfer_id, bool success, const std::string& error) {
if (success) {
std::cout << "β
Transfer completed: " << transfer_id.substr(0, 8) << std::endl;
} else {
std::cout << "β Transfer failed: " << error << std::endl;
}
});
// Auto-accept incoming file transfers
client.on_file_transfer_request([](const std::string& peer_id,
const librats::FileMetadata& metadata,
const std::string& transfer_id) {
std::cout << "π₯ Incoming: " << metadata.filename
<< " (" << metadata.file_size << " bytes) from " << peer_id.substr(0, 8) << std::endl;
return true; // Auto-accept
});
// Allow file requests from "shared" directory
client.on_file_request([](const std::string& peer_id, const std::string& file_path, const std::string& transfer_id) {
std::cout << "π€ Request: " << file_path << " from " << peer_id.substr(0, 8) << std::endl;
return file_path.find("../") == std::string::npos; // Prevent path traversal
});
client.start();
// Configure transfer settings
librats::FileTransferConfig config;
config.chunk_size = 64 * 1024; // 64KB chunks
config.max_concurrent_chunks = 4; // 4 parallel chunks
config.verify_checksums = true; // Verify integrity
client.set_file_transfer_config(config);
// Example transfers (replace "peer_id" with actual peer ID)
// std::string file_transfer = client.send_file("peer_id", "my_file.txt");
// std::string dir_transfer = client.send_directory("peer_id", "./my_folder");
// std::string file_request = client.request_file("peer_id", "remote_file.txt", "./downloaded_file.txt");
std::cout << "File transfer ready. Connect peers and exchange files!" << std::endl;
return 0;
}
#include "librats.h"
#include <iostream>
int main() {
librats::RatsClient client(8080);
// Initialize encryption system
if (!client.initialize_encryption(true)) {
std::cerr << "Failed to initialize encryption" << std::endl;
return 1;
}
// Generate a new encryption key (or load existing one)
std::string encryption_key = client.generate_new_encryption_key();
std::cout << "π Generated encryption key: " << encryption_key.substr(0, 16) << "..." << std::endl;
// Alternatively, set a specific key:
// client.set_encryption_key("your_64_character_hex_key_here");
std::cout << "π Encryption enabled: " << (client.is_encryption_enabled() ? "Yes" : "No") << std::endl;
// Connection callback with encryption status
client.set_connection_callback([&](socket_t socket, const std::string& peer_id) {
bool encrypted = client.is_peer_encrypted(peer_id);
std::cout << "π Peer connected: " << peer_id
<< (encrypted ? " [ENCRYPTED]" : " [UNENCRYPTED]") << std::endl;
});
client.start();
// All communications are now automatically encrypted
client.broadcast_string_to_peers("This message is encrypted!");
return 0;
}
#include "librats.h"
#include <iostream>
int main() {
librats::RatsClient client(8080);
// Set custom data directory for config files
client.set_data_directory("./my_app_data");
// Load saved configuration (if exists)
if (client.load_configuration()) {
std::cout << "π Loaded existing configuration" << std::endl;
} else {
std::cout << "π Using default configuration" << std::endl;
}
// Get our persistent peer ID
std::cout << "π Our peer ID: " << client.get_our_peer_id() << std::endl;
client.start();
// Try to reconnect to previously connected peers
int reconnect_attempts = client.load_and_reconnect_peers();
std::cout << "π Attempted to reconnect to " << reconnect_attempts << " previous peers" << std::endl;
// Configuration is automatically saved when client stops
// Files created: config.json, peers.rats, peers_ever.rats
// Manual save if needed
client.save_configuration();
client.save_historical_peers();
std::cout << "πΎ Configuration will be saved to: " << client.get_data_directory() << std::endl;
return 0;
}
#include "librats.h"
#include <iostream>
int main() {
librats::RatsClient client(8080);
// Enable and configure logging
client.set_logging_enabled(true);
client.set_log_file_path("librats_app.log");
client.set_log_level("INFO"); // DEBUG, INFO, WARN, ERROR
client.set_log_colors_enabled(true);
client.set_log_timestamps_enabled(true);
// Configure log file rotation
client.set_log_rotation_size(5 * 1024 * 1024); // 5MB max file size
client.set_log_retention_count(3); // Keep 3 old log files
std::cout << "π Logging to: " << client.get_log_file_path() << std::endl;
std::cout << "π Log level: " << static_cast<int>(client.get_log_level()) << std::endl;
std::cout << "π¨ Colors enabled: " << (client.is_log_colors_enabled() ? "Yes" : "No") << std::endl;
client.start();
// All librats operations will now be logged
client.broadcast_string_to_peers("This action will be logged!");
// Clear log file if needed (uncomment to use)
// client.clear_log_file();
return 0;
}
The main class providing comprehensive P2P networking capabilities:
// Enhanced constructor with NAT traversal
RatsClient(int listen_port, int max_peers = 10, const NatTraversalConfig& config = {});
// Core lifecycle
bool start();
void stop();
void shutdown_all_threads();
bool is_running() const;
// Advanced connection methods
bool connect_to_peer(const std::string& host, int port, ConnectionStrategy strategy = AUTO_ADAPTIVE);
bool connect_with_ice(const std::string& peer_id, const nlohmann::json& ice_offer);
nlohmann::json create_ice_offer(const std::string& peer_id);
// Custom protocol configuration
void set_protocol_name(const std::string& protocol_name);
void set_protocol_version(const std::string& protocol_version);
std::string get_protocol_name() const;
std::string get_protocol_version() const;
std::string get_discovery_hash() const;
// Message exchange API
void on(const std::string& message_type, MessageCallback callback);
void once(const std::string& message_type, MessageCallback callback);
void off(const std::string& message_type);
void send(const std::string& message_type, const nlohmann::json& data, SendCallback callback = nullptr);
void send(const std::string& peer_id, const std::string& message_type, const nlohmann::json& data, SendCallback callback = nullptr);
// Encryption
bool initialize_encryption(bool enable);
void set_encryption_enabled(bool enabled);
bool is_encryption_enabled() const;
std::string get_encryption_key() const;
bool set_encryption_key(const std::string& key_hex);
std::string generate_new_encryption_key();
bool is_peer_encrypted(const std::string& peer_id) const;
// Configuration persistence
bool load_configuration();
bool save_configuration();
bool set_data_directory(const std::string& directory_path);
std::string get_data_directory() const;
int load_and_reconnect_peers();
bool load_historical_peers();
bool save_historical_peers();
void clear_historical_peers();
std::vector<RatsPeer> get_historical_peers() const;
// GossipSub publish-subscribe messaging
GossipSub& get_gossipsub();
bool is_gossipsub_available() const;
// GossipSub convenience methods - Topic Management
bool subscribe_to_topic(const std::string& topic);
bool unsubscribe_from_topic(const std::string& topic);
bool is_subscribed_to_topic(const std::string& topic) const;
std::vector<std::string> get_subscribed_topics() const;
// GossipSub convenience methods - Publishing
bool publish_to_topic(const std::string& topic, const std::string& message);
bool publish_json_to_topic(const std::string& topic, const nlohmann::json& message);
// GossipSub convenience methods - Event Handlers
void on_topic_message(const std::string& topic, std::function<void(const std::string&, const std::string&, const std::string&)> callback);
void on_topic_json_message(const std::string& topic, std::function<void(const std::string&, const std::string&, const nlohmann::json&)> callback);
void on_topic_peer_joined(const std::string& topic, std::function<void(const std::string&, const std::string&)> callback);
void on_topic_peer_left(const std::string& topic, std::function<void(const std::string&, const std::string&)> callback);
void set_topic_message_validator(const std::string& topic, std::function<ValidationResult(const std::string&, const std::string&, const std::string&)> validator);
void off_topic(const std::string& topic);
// GossipSub convenience methods - Information
std::vector<std::string> get_topic_peers(const std::string& topic) const;
std::vector<std::string> get_topic_mesh_peers(const std::string& topic) const;
nlohmann::json get_gossipsub_statistics() const;
bool is_gossipsub_running() const;
// Peer management
int get_peer_count() const;
std::vector<RatsPeer> get_all_peers() const;
std::vector<RatsPeer> get_validated_peers() const;
const RatsPeer* get_peer_by_id(const std::string& peer_id) const;
std::string get_our_peer_id() const;
// NAT traversal utilities
NatType detect_nat_type();
NatTypeInfo get_nat_characteristics();
std::string get_public_ip() const;
std::vector<ConnectionAttemptResult> test_connection_strategies(const std::string& host, int port, const std::vector<ConnectionStrategy>& strategies);
// Enhanced callbacks
void set_advanced_connection_callback(AdvancedConnectionCallback callback);
void set_nat_traversal_progress_callback(NatTraversalProgressCallback callback);
void set_ice_candidate_callback(IceCandidateDiscoveredCallback callback);
// Logging Control API
void set_logging_enabled(bool enabled);
bool is_logging_enabled() const;
void set_log_file_path(const std::string& file_path);
std::string get_log_file_path() const;
void set_log_level(LogLevel level);
void set_log_level(const std::string& level_str);
LogLevel get_log_level() const;
void set_log_colors_enabled(bool enabled);
bool is_log_colors_enabled() const;
void set_log_timestamps_enabled(bool enabled);
bool is_log_timestamps_enabled() const;
void set_log_rotation_size(size_t max_size_bytes);
void set_log_retention_count(int count);
void clear_log_file();
// File Transfer API
FileTransferManager& get_file_transfer_manager();
bool is_file_transfer_available() const;
// File Transfer Operations
std::string send_file(const std::string& peer_id, const std::string& file_path, const std::string& remote_filename = "");
std::string send_directory(const std::string& peer_id, const std::string& directory_path, const std::string& remote_directory_name = "", bool recursive = true);
std::string request_file(const std::string& peer_id, const std::string& remote_file_path, const std::string& local_path);
std::string request_directory(const std::string& peer_id, const std::string& remote_directory_path, const std::string& local_directory_path, bool recursive = true);
// Transfer Control
bool accept_file_transfer(const std::string& transfer_id, const std::string& local_path);
bool reject_file_transfer(const std::string& transfer_id, const std::string& reason = "");
bool pause_file_transfer(const std::string& transfer_id);
bool resume_file_transfer(const std::string& transfer_id);
bool cancel_file_transfer(const std::string& transfer_id);
// Transfer Information
std::shared_ptr<FileTransferProgress> get_file_transfer_progress(const std::string& transfer_id) const;
std::vector<std::shared_ptr<FileTransferProgress>> get_active_file_transfers() const;
nlohmann::json get_file_transfer_statistics() const;
void set_file_transfer_config(const FileTransferConfig& config);
const FileTransferConfig& get_file_transfer_config() const;
// Transfer Event Handlers
void on_file_transfer_progress(FileTransferProgressCallback callback);
void on_file_transfer_completed(FileTransferCompletedCallback callback);
void on_file_transfer_request(FileTransferRequestCallback callback);
void on_directory_transfer_progress(DirectoryTransferProgressCallback callback);
void on_file_request(FileRequestCallback callback);
void on_directory_request(DirectoryRequestCallback callback);
Comprehensive NAT traversal configuration:
struct NatTraversalConfig {
bool enable_ice = true; // Enable ICE
bool enable_upnp = false; // Enable UPnP port mapping
bool enable_hole_punching = true; // Enable hole punching
bool enable_turn_relay = true; // Enable TURN relay
bool prefer_ipv6 = false; // Prefer IPv6 connections
std::vector<std::string> stun_servers; // STUN servers
std::vector<std::string> turn_servers; // TURN servers
std::vector<std::string> turn_usernames; // TURN credentials
std::vector<std::string> turn_passwords;
int ice_gathering_timeout_ms = 10000; // Timeouts
int ice_connectivity_timeout_ms = 30000;
int hole_punch_attempts = 5;
int turn_allocation_timeout_ms = 10000;
// Priority settings
int host_candidate_priority = 65535;
int server_reflexive_priority = 65534;
int relay_candidate_priority = 65533;
// Default includes Google STUN servers
};
Comprehensive peer information structure:
struct RatsPeer {
std::string peer_id; // Unique hash ID
std::string ip; // IP address
uint16_t port; // Port number
socket_t socket; // Socket handle
std::string normalized_address; // For duplicate detection
std::chrono::steady_clock::time_point connected_at;
bool is_outgoing; // Connection direction
// Handshake state
enum class HandshakeState { PENDING, SENT, COMPLETED, FAILED };
HandshakeState handshake_state;
std::string version; // Protocol version
int peer_count; // Remote peer count
// Encryption state
bool encryption_enabled;
bool noise_handshake_completed;
NoiseKey remote_static_key;
// NAT traversal state
bool ice_enabled;
std::string ice_ufrag;
std::string ice_pwd;
std::vector<IceCandidate> ice_candidates;
IceConnectionState ice_state;
NatType detected_nat_type;
std::string connection_method;
// Connection quality metrics
uint32_t rtt_ms;
uint32_t packet_loss_percent;
std::string transport_protocol;
// Helper methods
bool is_handshake_completed() const;
bool is_handshake_failed() const;
bool is_ice_connected() const;
bool is_fully_connected() const;
};
File transfer configuration structure:
struct FileTransferConfig {
uint32_t chunk_size; // Size of each chunk (default: 64KB)
uint32_t max_concurrent_chunks; // Max chunks in flight (default: 4)
uint32_t max_retries; // Max retry attempts per chunk (default: 3)
uint32_t timeout_seconds; // Timeout per chunk (default: 30)
bool verify_checksums; // Verify chunk checksums (default: true)
bool allow_resume; // Allow resuming interrupted transfers (default: true)
std::string temp_directory; // Temporary directory for incomplete files
FileTransferConfig()
: chunk_size(65536), // 64KB chunks
max_concurrent_chunks(4),
max_retries(3),
timeout_seconds(30),
verify_checksums(true),
allow_resume(true),
temp_directory("./temp_transfers") {}
};
Transfer progress tracking structure:
struct FileTransferProgress {
std::string transfer_id; // Transfer identifier
std::string peer_id; // Peer we're transferring with
FileTransferDirection direction; // Send or receive
FileTransferStatus status; // Current status
// File information
std::string filename; // File being transferred
std::string local_path; // Local file path
uint64_t file_size; // Total file size
// Progress tracking
uint64_t bytes_transferred; // Bytes completed
uint64_t total_bytes; // Total bytes to transfer
uint32_t chunks_completed; // Chunks successfully transferred
uint32_t total_chunks; // Total chunks in transfer
// Performance metrics
std::chrono::steady_clock::time_point start_time; // Transfer start time
std::chrono::steady_clock::time_point last_update; // Last progress update
double transfer_rate_bps; // Current transfer rate (bytes/second)
double average_rate_bps; // Average transfer rate since start
std::chrono::milliseconds estimated_time_remaining; // ETA
// Error information
std::string error_message; // Error details if failed
uint32_t retry_count; // Number of retries attempted
// Helper methods
double get_completion_percentage() const; // 0.0 to 100.0
std::chrono::milliseconds get_elapsed_time() const;
void update_transfer_rates(uint64_t new_bytes_transferred);
};
File information structure:
struct FileMetadata {
std::string filename; // Original filename
std::string relative_path; // Relative path within directory structure
uint64_t file_size; // Total file size in bytes
uint64_t last_modified; // Last modification timestamp
std::string mime_type; // MIME type of the file
std::string checksum; // Full file checksum
};
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Applications Layer β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
β β Message Exchangeβ β File Sharing β β IoT Sensors β β
β β API β β Apps β β & More β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β librats Core (RatsClient) β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
β β Event-Driven β β GossipSub β β Encryption β β
β β Message API β β Pub-Sub Mesh β β (Noise Protocol)β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
β β Config & Peer β β Topic Routing β β Message Validationβ β
β β Persistence β β & Mesh Managementβ β & Filtering β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β NAT Traversal Layer β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
β β ICE Agent β β STUN Client β β TURN Client β β
β β (RFC 8445) β β (RFC 5389) β β (RFC 5766) β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
β β Hole Punching β β NAT Detection β β Strategy Select β β
β β Coordination β β & Analysis β β & Fallback β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Discovery & Networking Layer β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
β β DHT (Wide-Area) β β mDNS (Local Net)β β Direct Sockets β β
β β BitTorrent β β 224.0.0.251 β β IPv4/IPv6 Stack β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Platform Abstraction Layer β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
β β Windows β β Linux β β macOS β β
β β WinSock2/bcrypt β β BSD Sockets β β BSD Sockets β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
librats provides comprehensive cross-platform support with bindings for multiple programming languages:
Platform | Build Environment | Compiler | Status |
---|---|---|---|
Windows | MinGW-w64 | GCC 7+ | β Fully Supported |
Windows | Visual Studio | MSVC 2017+ | β Fully Supported |
Linux | Native | GCC 7+, Clang 5+ | β Fully Supported |
macOS | Xcode/Native | Clang 10+ | β Fully Supported |
Language/Platform | Binding Type | Status | Timeline | Notes |
---|---|---|---|---|
C/C++ | Native Library | β Fully Supported | Available Now | Core implementation with full feature set |
Android (NDK) | Native C++ | β Fully Supported | Available Now | Android NDK integration with JNI bindings |
Android (Java) | JNI Wrapper | β Fully Supported | Available Now | High-level Java API for Android apps |
JavaScript | Native Module | π Planned | Soon | Node.js native addon with async/await support |
Python | C Extension | β Fully Supported | Available Now | CPython extension with asyncio integration |
Rust | FFI Bindings | π Planned | Soon | Safe Rust bindings with tokio async support |
Go | CGO Bindings | π Future | Soon | CGO wrapper for Go applications |
C#/.NET | P/Invoke | π Future | Soon | .NET bindings for Windows/Linux/macOS |
Platform | Implementation | Status | Features |
---|---|---|---|
Android | NDK + JNI | β Fully Supported | Full P2P networking, file transfer, GossipSub |
iOS | Native C++ | π Planned | Swift/Objective-C bindings planned |
React Native | Native Module | π Future | Cross-platform mobile development |
Flutter | FFI Plugin | π Future | Dart FFI integration |
Platform | Technology | Status | Limitations |
---|---|---|---|
Browser (WASM) | WebAssembly | π Research | Limited by browser networking APIs |
Electron | Node.js Module | π Planned | Desktop app development |
Tauri | Rust Bindings | π Future | Lightweight desktop apps |
Legend:
- β Fully Supported: Production-ready with comprehensive testing
- πΆ In Development: Active development, preview/beta available
- π Planned: Confirmed for development, timeline estimated
- π Future: Under consideration, timeline not confirmed
- π Research: Investigating feasibility and implementation approach
- CMake 3.10+
- C++17 compatible compiler:
- GCC 7+ (Linux, MinGW)
- Clang 5+ (macOS, Linux)
- MSVC 2017+ (Windows)
- Git (for dependency management)
git clone https://github.com/DEgITx/librats.git
cd librats
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
git clone https://github.com/DEgITx/librats.git
cd librats
mkdir build && cd build
cmake .. -G "Visual Studio 16 2019"
cmake --build . --config Release
# Disable tests
cmake .. -DRATS_BUILD_TESTS=OFF
# Debug build with full logging
cmake .. -DCMAKE_BUILD_TYPE=Debug
# Release build optimized for performance
cmake .. -DCMAKE_BUILD_TYPE=Release
# In build directory
ctest -j$(nproc) --output-on-failure
# Or run directly
./bin/librats_tests
After building, you'll find:
- Library:
build/lib/librats.a
(static library) - Executable:
build/bin/rats-client
(demo application) - Tests:
build/bin/librats_tests
(ifRATS_BUILD_TESTS=ON
)
# Terminal 1: Start first node
./build/bin/rats-client 8080
# Terminal 2: Start second node and connect
./build/bin/rats-client 8081 localhost 8080
#include "librats.h"
class FileShareApp {
private:
librats::RatsClient client_;
public:
FileShareApp(int port) : client_(port) {
// Set up file transfer callbacks
client_.on_file_transfer_progress([](const librats::FileTransferProgress& progress) {
std::cout << "π " << progress.filename << ": "
<< progress.get_completion_percentage() << "% complete" << std::endl;
std::cout << "Rate: " << (progress.transfer_rate_bps / 1024 / 1024) << " MB/s" << std::endl;
});
client_.on_file_transfer_completed([](const std::string& transfer_id, bool success, const std::string& error) {
if (success) {
std::cout << "β
Transfer completed: " << transfer_id.substr(0, 8) << std::endl;
} else {
std::cout << "β Transfer failed: " << error << std::endl;
}
});
client_.on_file_transfer_request([](const std::string& peer_id, const librats::FileMetadata& metadata, const std::string& transfer_id) {
std::cout << "π₯ File request from " << peer_id.substr(0, 8) << std::endl;
std::cout << "File: " << metadata.filename << " (" << metadata.file_size << " bytes)" << std::endl;
// Auto-accept files smaller than 100MB
return metadata.file_size < 100 * 1024 * 1024;
});
client_.on_file_request([](const std::string& peer_id, const std::string& file_path, const std::string& transfer_id) {
std::cout << "π€ File request from " << peer_id.substr(0, 8) << ": " << file_path << std::endl;
// Allow access to files in "shared" directory only
return file_path.find("../") == std::string::npos &&
file_path.substr(0, 7) == "shared/";
});
// Set up connection callbacks
client_.set_connection_callback([](auto socket, const std::string& peer_id) {
std::cout << "Peer connected: " << peer_id.substr(0, 8) << std::endl;
});
// Configure optimized file transfer settings
librats::FileTransferConfig config;
config.chunk_size = 256 * 1024; // 256KB chunks for better performance
config.max_concurrent_chunks = 8; // 8 parallel chunks
config.verify_checksums = true; // Ensure data integrity
config.allow_resume = true; // Enable resume capability
client_.set_file_transfer_config(config);
// Start all services
client_.start();
client_.start_dht_discovery();
client_.start_mdns_discovery("file-share");
}
std::string share_file(const std::string& peer_id, const std::string& file_path) {
return client_.send_file(peer_id, file_path);
}
std::string share_directory(const std::string& peer_id, const std::string& directory_path) {
return client_.send_directory(peer_id, directory_path, "", true);
}
std::string request_file(const std::string& peer_id, const std::string& remote_file, const std::string& local_path) {
return client_.request_file(peer_id, remote_file, local_path);
}
void pause_transfer(const std::string& transfer_id) {
client_.pause_file_transfer(transfer_id);
}
void resume_transfer(const std::string& transfer_id) {
client_.resume_file_transfer(transfer_id);
}
void get_transfer_stats() {
auto stats = client_.get_file_transfer_statistics();
std::cout << "Total bytes transferred: " << stats["total_bytes_transferred"] << std::endl;
std::cout << "Active transfers: " << stats["active_transfers"] << std::endl;
}
void connect_to(const std::string& host, int port) {
client_.connect_to_peer(host, port);
}
};
#include "librats.h"
#include <iostream>
#include <string>
#include <thread>
int main() {
librats::RatsClient client(8080);
// Set up chat message handling
client.on("chat_message", [](const std::string& peer_id, const nlohmann::json& data) {
std::string username = data.value("username", "Unknown");
std::string message = data.value("message", "");
std::cout << "[" << username << "]: " << message << std::endl;
});
// Handle user join/leave
client.on("user_joined", [](const std::string& peer_id, const nlohmann::json& data) {
std::cout << "*** " << data["username"].get<std::string>() << " joined the chat ***" << std::endl;
});
client.set_connection_callback([&](socket_t socket, const std::string& peer_id) {
// Announce our presence
nlohmann::json join_msg;
join_msg["username"] = "User_" + client.get_our_peer_id().substr(0, 8);
client.send("user_joined", join_msg);
});
client.start();
client.start_dht_discovery(); // Auto-discover other chat users
std::cout << "π librats Chat - Type messages and press Enter" << std::endl;
std::cout << "Type 'quit' to exit" << std::endl;
std::string input;
while (std::getline(std::cin, input)) {
if (input == "quit") break;
if (!input.empty()) {
nlohmann::json chat_msg;
chat_msg["username"] = "User_" + client.get_our_peer_id().substr(0, 8);
chat_msg["message"] = input;
chat_msg["timestamp"] = std::time(nullptr);
client.send("chat_message", chat_msg);
}
}
return 0;
}
Comprehensive documentation is available:
- NAT Traversal Guide - Complete NAT traversal documentation
- File Transfer Example - Efficient P2P file and directory transfer
- Custom Protocol Setup - How to configure custom protocols
- Message Exchange API - Event-driven messaging system
- GossipSub Example - Publish-subscribe messaging with GossipSub
- mDNS Discovery - Local network peer discovery
- Noise Encryption - End-to-end encryption details
- BitTorrent Example - BitTorrent protocol implementation
librats automatically creates and manages these files:
config.json
: Main configuration (protocol, encryption keys, settings)peers.rats
: Current active peers for reconnectionpeers_ever.rats
: Historical peers for discovery
{
"protocol_name": "rats",
"protocol_version": "1.0",
"peer_id": "550e8400-e29b-41d4-a716-446655440000",
"encryption_enabled": true,
"encryption_key": "a1b2c3d4e5f6...",
"listen_port": 8080,
"max_peers": 10
}
librats is engineered for resource efficiency, making it ideal for low-power devices, edge computing, and embedded systems where memory and CPU resources are precious.
Test Environment: AMD Ryzen 7 5700U, 16GB RAM
Metric | librats (C++17) | libp2p (JavaScript) | Improvement |
---|---|---|---|
Startup Memory | ~1.6 MB | ~50-80 MB | 31-50x less |
Memory per Peer | ~80 KB | ~4-6 MB | 50-75x less |
Peak Memory (100 peers) | ~9.4 MB | 400-600 MB | 42-64x less |
CPU Usage (idle) | 0-1% | 15-25% | 15-25x less |
CPU Usage (peak) | 1-2% | 80-100% | 5-16x less |
- Native C++17: Maximum performance with minimal overhead
- Zero-copy operations: Efficient data handling where possible
- Thread-safe design: Modern concurrency with
ThreadManager
- Optimized protocols: Custom implementations tuned for speed
- Production tested: Used in real-world applications
- Comprehensive testing: Unit tests and integration tests covering all components
- Memory safety: RAII and smart pointers throughout
- Cross-platform: Consistent behavior across Windows, Linux, and macOS
- 99%+ Success Rate: Connect across virtually any NAT configuration
- RFC Compliant: Follows established standards (ICE, STUN, TURN)
- Adaptive Strategy: Automatically selects optimal connection method
- Real-time Monitoring: Track connection attempts and quality metrics
- Simple API: Easy to learn and integrate
- Modern C++: Takes advantage of C++17 features
- Excellent documentation: Comprehensive guides and examples
- Active development: Regular updates and improvements
- Configuration persistence: Automatic saving and loading of settings
librats includes industry-leading NAT traversal that can establish P2P connections across virtually any network topology:
NAT Type | Direct | STUN | ICE | TURN | Success Rate |
---|---|---|---|---|---|
Open Internet | β | β | β | β | 100% |
Full Cone NAT | β | β | β | β | 95% |
Restricted Cone | β | β | β | β | 90% |
Port Restricted | β | β | β | β | 85% |
Symmetric NAT | β | β | β | 70% | |
Double NAT | β | β | β | β | 99% |
- AUTO_ADAPTIVE: Automatically selects the best connection method
- ICE_FULL: Complete ICE negotiation with candidate gathering
- STUN_ASSISTED: STUN-based public IP discovery and direct connection
- TURN_RELAY: Fallback relay through TURN servers
- DIRECT_ONLY: Try direct connection only
We welcome contributions! Please see our Contributing Guide for details.
git clone https://github.com/DEgITx/librats.git
cd librats
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug -DRATS_BUILD_TESTS=ON
make -j$(nproc)
./bin/librats_tests
This project is licensed under the MIT License - see the LICENSE file for details.
- nlohmann/json: For the excellent JSON library integration
- Contributors: Everyone who has contributed to making librats better