Introduction
IronRDP is a collection of Rust crates providing an implementation of the Microsoft Remote Desktop Protocol with a focus on security, correctness, and maintainability. The architecture follows a tiered design that separates foundational protocol libraries from higher-level I/O implementations.This document describes the high-level architecture of IronRDP. For detailed information about specific crates, see their individual documentation.
Design Philosophy
The IronRDP architecture is guided by several key principles:Separation of Concerns
The codebase is organized into distinct architectural tiers, each with specific responsibilities and constraints. This separation ensures that:- Protocol logic remains independent of I/O implementation
- Core libraries can be used in any environment (including
no_std) - Testing and fuzzing can focus on protocol correctness without I/O complexity
- Multiple I/O models (blocking, async, WebAssembly) can share the same core
API Boundaries
Certain crates are designated as API Boundaries - public interfaces that external code depends on. These crates receive special attention regarding:- Stability and backward compatibility
- Documentation quality
- Performance characteristics
- Breaking change policies
Security-First Development
All core protocol handling code is designed with security in mind:- Mandatory fuzzing for all protocol parsing code
- No I/O in core tier to reduce attack surface and facilitate testing
- Explicit error handling with structured error types
- Memory safety through Rust’s type system and strict linting
Architectural Tiers
The IronRDP codebase is organized into four distinct tiers, each with specific purposes and constraints:Core Tier
Foundational libraries with strict quality standards - no I/O, must be fuzzed,
no_std-compatibleExtra Tier
Higher-level libraries and binaries built on the core tier with relaxed constraints
Internal Tier
Test generators, fuzzing oracles, and build tools - not published as libraries
Community Tier
Community-maintained crates with dedicated maintainers outside the core team
Key Components
Protocol Stack
The protocol implementation follows a layered approach:Virtual Channels
IronRDP supports both static (SVC) and dynamic (DVC) virtual channels:ironrdp-svc: Traits and abstractions for static virtual channelsironrdp-dvc: DRDYNVC implementation and traits for dynamic channels- Channel implementations: CLIPRDR (clipboard), RDPDR (device redirection), RDPSND (audio), and more
I/O Abstractions
Multiple I/O models are supported through separate crates:ironrdp-blocking: Synchronous/blocking I/O wrapperironrdp-async: AsyncFuture-based wrapperironrdp-tokioandironrdp-futures: Runtime-specific integrationsironrdp-web: WebAssembly bindings for browser environments
State Machines
IronRDP uses explicit state machines to drive protocol sequences:- Connection sequence (
ironrdp-connector): Handles initial handshake, security negotiation, authentication - Session management (
ironrdp-session): Manages active RDP session state, graphics updates, input handling - Server acceptance (
ironrdp-acceptor): Drives the server-side connection acceptance (community tier)
Cross-Cutting Concerns
Dependency Injection
Core tier crates never make system calls directly. Runtime information (like hostname, current time) must be injected by the caller. This enables:- Testing without mocking system APIs
- Use in embedded or
no_stdenvironments - Deterministic behavior for fuzzing
Error Handling
IronRDP uses structured error types throughout:- Libraries use concrete error types (hand-crafted or using
thiserror) - The
ironrdp-errorcrate provides lightweightErrorandReporttypes - Error messages follow consistent formatting conventions
Testing Strategy
Testing focuses on API boundaries rather than implementation details:ironrdp-testsuite-core: Integration tests for core tier cratesironrdp-testsuite-extra: Integration tests for extra tier crates- Fuzzing: All core tier crates must have fuzz targets
- Property testing: Using
proptestfor generalized test cases - Snapshot testing: Using
expect-testfor structured data comparison
Build and CI
The project usescargo xtask for automation:
Architecture Invariant:
cargo xtask ci and the CI workflow must be logically equivalent. A successful local run should imply a successful CI run.Performance Considerations
Compilation Time
The architecture prioritizes reasonable compilation times:- No proc-macro dependencies in core tier - reduces compilation bottlenecks
- Minimal monomorphization - generic code uses
&dynimplementations to avoid code bloat - Careful dependency management - only essential dependencies in foundational crates
Runtime Performance
While security and correctness are primary concerns, performance is not neglected:- Zero-copy parsing where possible using
ReadCursorandWriteCursor - Allocation avoidance in hot paths
no_stdsupport enables embedded use cases
Further Reading
Crate Tiers
Detailed breakdown of each architectural tier and its crates
Design Principles
In-depth explanation of architectural invariants and design decisions

