Overview
The RDAP Rust client is designed with a modular architecture that separates concerns between query detection, bootstrap discovery, caching, HTTP communication, and response formatting. The client implements RFCs 7480-7484 for RDAP protocol compliance.Core Components
Client Layer (client.rs)
The RdapClient is the main orchestrator that:
- Manages HTTP connections with connection pooling via
reqwest - Coordinates with the bootstrap service for server discovery
- Handles multi-layer RDAP queries (registry + registrar for domains)
- Parses JSON responses into typed Rust structs
- Follows registrar referral links automatically
- Implements retry logic for IPv6 CIDR queries
Bootstrap Discovery (bootstrap.rs)
The BootstrapClient implements RFC 7484 service discovery:
- Fetches IANA bootstrap registries (DNS, ASN, IPv4, IPv6)
- Matches queries to authoritative RDAP servers
- Supports TLD overrides for ccTLDs not in IANA bootstrap
- Handles domain matching from most specific to least specific
- Performs IP-to-CIDR matching using
ipnetcrate - Matches AS number ranges
- TLD overrides from
tlds.json(for ccTLDs) - IANA bootstrap registry matching
Request Building (request.rs)
The RdapRequest structure:
- Auto-detects query type from input string
- Normalizes IP addresses (shorthand → standard)
- Builds proper RDAP URLs for each query type
- Supports explicit server override
Configuration System (config.rs)
Multi-tier configuration with priority loading:
Configuration Priority Order
Configuration Priority Order
config.json- Bootstrap URLs for IANA RDAP servicestlds.json- TLD-to-server mappings for ccTLDstlds.txt- IANA TLD list for query type detection*.local.json- User overrides (merged, not replaced)
Cache Layer (cache.rs)
Disk-based caching for bootstrap files:
- Location:
~/.cache/rdap/ - Default TTL: 24 hours
- Automatically expires stale entries
- Reduces latency for repeated queries
- Minimizes load on IANA bootstrap services
Query Flow Diagram
Multi-Layer RDAP Queries
For domain queries, the client implements a two-tier query system:Registry vs Registrar DataRDAP follows a hierarchical model:
- Registry (e.g., Verisign for .com) - Maintains authoritative data for the TLD
- Registrar (e.g., MarkMonitor) - Manages individual domain registrations
Multi-Layer Query Process
-
Registry Query: Query the TLD registry first
-
Extract Referral: Parse registry response for registrar link
-
Registrar Query: Follow the referral link automatically
-
Result: Return both registry and registrar data
- Registry data: Nameservers, DNSSEC, basic status
- Registrar data: Detailed contacts, updated status, additional info
IP Address Handling
Normalization
The client supports shorthand IP notation:CIDR Support
Both standard IPs and CIDR ranges are supported:8.8.8.8- Single IP query8.8.8.0/24- CIDR range query2001:db8::/32- IPv6 CIDR
IPv6 CIDR Retry Logic
Some RDAP servers (e.g., TWNIC) don’t support host-level IPv6 queries. The client automatically retries with CIDR prefixes:Response Parsing
The client uses Rust’s type system for safe response handling:- Checking for
errorCodefield →Error - Checking for search result fields →
*Search - Reading
objectClassNamefield → specific type - Default →
Help
Configuration Update Mechanism
Therdap --update command:
-
Downloads latest configs from GitHub:
config.json- Bootstrap URLstlds.json- TLD overridestlds.txt- IANA TLD list
- Validates JSON before saving
-
Preserves
*.local.jsonuser overrides -
Saves to
~/.config/rdap/
Error Handling
The client uses a comprehensive error type:Performance Optimizations
Connection Pooling
- Uses
reqwest::Clientwith automatic connection reuse - Single client instance for all queries
- Reduces TLS handshake overhead
Caching
- Bootstrap registries cached for 24 hours
- Eliminates repeated IANA queries
- Significant latency reduction for batch queries
Async I/O
- Built on Tokio async runtime
- Non-blocking HTTP requests
- Concurrent registrar queries
Binary Size
- Release binary: ~4MB (stripped)
- Embedded configs reduce runtime I/O
- Static linking for portability
Thread Safety
The
RdapClient is NOT Sync by default due to internal HTTP client state. For concurrent usage, wrap in Arc<Mutex<RdapClient>> or create separate client instances per thread.