#dns #rdap #whois #networking

seer-core

Core library for Seer domain name utilities

19 releases

0.10.1 Feb 7, 2026
0.10.0 Feb 5, 2026
0.1.94 Jan 27, 2026

#1935 in Network programming


Used in seer-cli

MIT license

360KB
8K SLoC

seer-core

Core Rust library containing all business logic for the Seer domain utility suite.

Overview

seer-core is the foundation of Seer, providing WHOIS, RDAP, DNS, and domain status functionality. All other Seer packages (CLI, Python bindings, API) are thin wrappers around this library.

Modules

Module Description
whois WHOIS protocol client with referral following
rdap RDAP (Registration Data Access Protocol) client
dns DNS resolver, propagation checker, and DNS follower
status Domain health checking (HTTP, SSL, expiration)
bulk Concurrent bulk operation executor
output Human and JSON output formatters
lookup Smart lookup orchestration (RDAP → WHOIS fallback)
validation Domain normalization and SSRF protection
error Centralized error types
colors Catppuccin color palette for terminal output

Public API

Core Types

use seer_core::{SeerError, Result};
  • SeerError - Comprehensive error enum for all operations
  • Result<T> - Type alias for std::result::Result<T, SeerError>

Clients

use seer_core::{
    WhoisClient,      // WHOIS lookups
    RdapClient,       // RDAP lookups (domain, IP, ASN)
    DnsResolver,      // DNS queries
    StatusClient,     // Domain health checks
    SmartLookup,      // RDAP-first with WHOIS fallback
    BulkExecutor,     // Concurrent bulk operations
};

Data Types

use seer_core::{
    // WHOIS
    WhoisResponse,

    // RDAP
    RdapResponse,

    // DNS
    DnsRecord, RecordType, PropagationResult,
    DnsFollower, FollowConfig, FollowResult,

    // Status
    StatusResponse, CertificateInfo, DomainExpiration, DnsResolution,

    // Lookup
    LookupResult,

    // Bulk
    BulkOperation, BulkResult,

    // Output
    OutputFormat, OutputFormatter,
};

Utility Functions

use seer_core::{normalize_domain, validate_domain_safe};

Usage Examples

Smart Lookup (RDAP with WHOIS Fallback)

use seer_core::SmartLookup;

#[tokio::main]
async fn main() -> seer_core::Result<()> {
    let lookup = SmartLookup::new();
    let result = lookup.lookup("example.com").await?;

    match result {
        seer_core::LookupResult::Rdap { data, .. } => {
            println!("RDAP: {:?}", data.domain_name());
        }
        seer_core::LookupResult::Whois { data, .. } => {
            println!("WHOIS: {}", data.domain);
        }
    }
    Ok(())
}

WHOIS Lookup

use seer_core::WhoisClient;

#[tokio::main]
async fn main() -> seer_core::Result<()> {
    let client = WhoisClient::new();
    let response = client.lookup("example.com").await?;

    println!("Registrar: {:?}", response.registrar);
    println!("Expires: {:?}", response.expiration_date);
    Ok(())
}

RDAP Lookups

use seer_core::RdapClient;

#[tokio::main]
async fn main() -> seer_core::Result<()> {
    let client = RdapClient::new();

    // Domain lookup
    let domain = client.lookup_domain("example.com").await?;

    // IP lookup
    let ip = client.lookup_ip("8.8.8.8").await?;

    // ASN lookup
    let asn = client.lookup_asn(15169).await?;

    Ok(())
}

DNS Resolution

use seer_core::{DnsResolver, RecordType};

#[tokio::main]
async fn main() -> seer_core::Result<()> {
    let resolver = DnsResolver::new();

    // Basic A record lookup
    let records = resolver.resolve("example.com", RecordType::A, None).await?;

    // MX records with custom nameserver
    let mx = resolver.resolve("example.com", RecordType::MX, Some("8.8.8.8")).await?;

    for record in records {
        println!("{}: {}", record.record_type, record.data);
    }
    Ok(())
}

DNS Propagation Check

use seer_core::dns::{PropagationChecker, RecordType};

#[tokio::main]
async fn main() -> seer_core::Result<()> {
    let checker = PropagationChecker::new();
    let result = checker.check("example.com", RecordType::A).await?;

    println!("Propagation: {:.1}%", result.propagation_percentage);
    println!("Servers responding: {}/{}", result.servers_responding, result.servers_checked);
    Ok(())
}

Domain Status Check

use seer_core::StatusClient;

#[tokio::main]
async fn main() -> seer_core::Result<()> {
    let client = StatusClient::new();
    let status = client.check("example.com").await?;

    println!("HTTP Status: {:?}", status.http_status);
    println!("SSL Valid: {:?}", status.certificate.map(|c| c.is_valid));
    println!("Domain Expires: {:?}", status.domain_expiration.map(|e| e.expiration_date));
    Ok(())
}

Bulk Operations

use seer_core::BulkExecutor;

#[tokio::main]
async fn main() -> seer_core::Result<()> {
    let executor = BulkExecutor::new()
        .with_concurrency(20);

    let domains = vec![
        "example.com".to_string(),
        "google.com".to_string(),
        "github.com".to_string(),
    ];

    let results = executor.execute_lookup(domains).await;

    for result in results {
        println!("{}: success={}",
            result.operation, result.success);
    }
    Ok(())
}

Configuration

Timeouts

All clients support configurable timeouts via builder pattern:

use std::time::Duration;
use seer_core::{WhoisClient, RdapClient, DnsResolver, StatusClient};

let whois = WhoisClient::new().with_timeout(Duration::from_secs(15));
let rdap = RdapClient::new().with_timeout(Duration::from_secs(45));
let dns = DnsResolver::new().with_timeout(Duration::from_secs(10));
let status = StatusClient::new().with_timeout(Duration::from_secs(20));

Default Timeout Values

Client Default Timeout
WHOIS 10 seconds
RDAP 30 seconds
DNS 5 seconds (with 2 retries)
HTTP/SSL 10 seconds

Error Handling

All operations return Result<T, SeerError>. Error variants include:

  • WhoisError - WHOIS lookup failures
  • WhoisServerNotFound - No WHOIS server for TLD
  • RdapError - RDAP lookup failures
  • RdapBootstrapError - IANA bootstrap failures
  • DnsError - DNS resolution failures
  • InvalidDomain - Invalid domain format
  • InvalidIpAddress - Invalid IP address format
  • HttpError - HTTP request failures
  • Timeout - Operation timeout
  • CertificateError - SSL certificate issues
  • LookupFailed - Both RDAP and WHOIS failed

Dependencies

  • tokio - Async runtime
  • reqwest - HTTP client (rustls-tls)
  • hickory-resolver - DNS resolution with DNSSEC
  • serde / serde_json - Serialization
  • thiserror - Error handling
  • chrono - Date/time handling
  • regex - WHOIS parsing
  • native-tls / x509-parser - SSL certificate handling

License

MIT License - See LICENSE file in repository root.

Dependencies

~25–48MB
~741K SLoC