lanspread-peer
A peer-to-peer networking component for the Lanspread system that enables distributed game sharing and discovery across local networks using QUIC protocol and mDNS service discovery.
Overview
The lanspread-peer crate implements a peer-to-peer networking layer that allows multiple instances of Lanspread to discover each other on the local network, share game libraries, and distribute game files efficiently. It operates as both a server (providing local games to other peers) and a client (discovering and downloading games from other peers).
Core Architecture
Main Components
- Peer System (
run_peer): The main orchestrator that manages all peer operations - Server Component (
run_server_component): Handles incoming connections from other peers - Peer Discovery (
run_peer_discovery): Continuously discovers new peers via mDNS - Ping Service (
run_ping_service): Maintains peer connectivity through health checks - Download Manager: Handles parallel file downloads from multiple peers
Key Data Structures
PeerGameDB: Central database managing all discovered peers and their game collectionsPeerInfo: Contains information about a single peer including address, last seen time, and available gamesPeerEvent: Events sent to the UI layer (peer discovery, connection status, download progress)PeerCommand: Commands received from the UI layer (list games, download, etc.)
Network Protocol
Communication Layer
The crate uses QUIC (via s2n-quic) for all peer-to-peer communication with TLS encryption:
- Certificate-based security: Uses embedded TLS certificates for secure communication
- Bidirectional streams: Each peer interaction uses separate QUIC streams
- Connection management: Built-in connection pooling and keep-alive mechanisms
Message Protocol
Messages are serialized using JSON and follow the request/response pattern defined in lanspread-proto:
Request Types:
Ping: Health checkListGames: Request available games from a peerGetGame: Request detailed file list for a specific gameGetGameFileData: Request complete file downloadGetGameFileChunk: Request specific file chunk for parallel downloads
Response Types:
Pong: Health check responseListGames(Vec<Game>): List of available gamesGetGame: Game file descriptionsGameNotFound: Game not available- Error responses for various failure conditions
Peer Discovery
mDNS Integration
The crate uses mDNS (multicast DNS) for automatic peer discovery:
- Service Type:
_lanspread._udp.local. - Instance Naming:
{hostname}-{uuid}format to ensure uniqueness - Continuous Discovery: Scans every 10 seconds for new peers
- Automatic Advertising: Each peer advertises its availability via mDNS
Discovery Process
- mDNS Browser: Continuously scans for
_lanspread._udp.local.services - Peer Registration: New peers are added to
PeerGameDB - Game Synchronization: Automatically requests game lists from newly discovered peers
- UI Notification: Notifies the UI layer about peer discovery events
Game Distribution System
File Management
The system supports efficient game file distribution with these features:
File Description:
GameFileDescription: Metadata for each file including path, size, and directory structure- Version Tracking: Reads
version.inifiles for ETI game version management - Directory Structure: Preserves complete game directory hierarchies
Download Strategies:
- Chunked Downloads: Large files are split into 512KB chunks for parallel processing
- Multi-peer Downloads: Chunks are distributed across available peers for maximum throughput
- Retry Mechanism: Failed chunks are retried up to 3 times with different peers
- Integrity Verification: File integrity is verified after download completion
Download Process
// Simplified download flow
1. Prepare local storage (create directories and pre-allocate files)
2. Build download plan (distribute chunks across available peers)
3. Execute parallel downloads from multiple peers
4. Retry failed chunks with alternative peers
5. Verify file integrity and notify completion
Concurrency Model
Async Architecture
The system uses Tokio's async runtime with these concurrent tasks:
- Main Peer Loop: Handles UI commands and orchestrates operations
- Server Task: Accepts incoming peer connections
- Discovery Task: Continuously scans for new peers
- Ping Service: Maintains peer health monitoring
- Connection Handlers: Spawns per-connection tasks for request handling
- Download Tasks: Parallel download workers for file transfers
Thread Safety
- Arc<RwLock>: Used for shared data structures to enable concurrent reads
- Message Passing: Uses Tokio channels (
UnboundedSender/Receiver) for task communication - Connection Isolation: Each peer connection is handled in an independent task
Integration Points
UI Interface
The crate communicates with the UI layer through two channels:
Events to UI (PeerEvent):
- Game list updates
- Peer discovery/connection events
- Download progress and completion
- Error notifications
Commands from UI (PeerCommand):
- Set game directory
- List available games
- Request game details
- Initiate game downloads
Dependency Integration
lanspread-db: Game metadata and file description structureslanspread-proto: Message serialization and protocol definitionslanspread-mdns: Service discovery functionalitylanspread-utils: Common utilities and macros
Configuration Constants
const CHUNK_SIZE: u64 = 512 * 1024; // 512KB file chunks
const MAX_RETRY_COUNT: usize = 3; // Maximum download retries
const PING_INTERVAL: Duration = 10s; // Peer health check interval
const DISCOVERY_INTERVAL: Duration = 10s; // mDNS scan interval
const STALE_TIMEOUT: Duration = 30s; // Peer inactivity timeout
Usage Example
// Start the peer system
let (tx_notify_ui, rx_notify_ui) = tokio::sync::mpsc::unbounded_channel();
let tx_control = lanspread_peer::start_peer(
"/path/to/games".to_string(),
tx_notify_ui,
)?;
// Send commands to the peer
tx_control.send(PeerCommand::ListGames)?;
tx_control.send(PeerCommand::DownloadGameFiles {
id: "game_id".to_string(),
file_descriptions: vec![/* file descriptions */],
})?;
// Receive events from the peer
while let Some(event) = rx_notify_ui.recv().await {
match event {
PeerEvent::ListGames(games) => println!("Available games: {:?}", games),
PeerEvent::DownloadGameFilesFinished { id } => println!("Downloaded: {}", id),
// Handle other events...
}
}
Error Handling
The crate implements comprehensive error handling:
- Connection Errors: Automatic reconnection and peer removal
- Download Failures: Retry with alternative peers and fallback strategies
- Protocol Errors: Graceful degradation and error reporting
- File System Errors: Proper cleanup and rollback on failures
Security Considerations
- TLS Encryption: All peer communication is encrypted using QUIC with TLS
- Certificate Validation: Uses embedded certificates for peer authentication
- Network Isolation: Operates only on local network via mDNS discovery
- File Access: Restricted to configured game directory boundaries
Performance Optimizations
- Parallel Downloads: Maximizes bandwidth by downloading from multiple peers simultaneously
- Chunked Transfer: Large files are split for parallel processing and resume capability
- Connection Reuse: Maintains persistent connections to reduce handshake overhead
- Incremental Discovery: Only synchronizes changed game metadata
This crate provides the foundation for Lanspread's distributed game sharing capabilities, enabling efficient peer-to-peer game distribution across local networks.