Skip to main content

Nameserver

Represents DNS nameserver information returned from RDAP queries.
object_class_name
string
Always “nameserver” for nameserver objects
conformance
array<string>
RDAP conformance levels (e.g., ["rdap_level_0"])
notices
array<Notice>
Server notices and terms of service. See common fields
handle
string
Registry-unique identifier for the nameserver
let ns_handle = nameserver.handle.unwrap_or_default();
ldh_name
string
LDH (Letters, Digits, Hyphen) representation of the nameserver hostname
let hostname = nameserver.ldh_name.as_deref().unwrap_or("N/A");
println!("Nameserver: {}", hostname);
unicode_name
string
Unicode representation of the nameserver hostname (for IDN nameservers)
ip_addresses
IpAddressSet
IP addresses for the nameserver (glue records)
entities
array<Entity>
Related entities (operators, contacts). See Entity
status
array<string>
Nameserver status values (e.g., “active”, “linked”)
if nameserver.status.contains(&"active".to_string()) {
    println!("Nameserver is active");
}
remarks
array<Remark>
Informational remarks. See common fields
Related links. See common fields
port43
string
WHOIS server hostname for port 43 queries
events
array<Event>
Lifecycle events. See common fields
lang
string
Language tag (e.g., “en”, “fr”)

Example Usage

Accessing Nameservers from Domain Query

use rdap_client::RdapClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = RdapClient::new();
    let result = client.query("example.com").await?;
    
    if let Some(domain) = result.domain() {
        println!("Nameservers for {}:", 
            domain.ldh_name.as_deref().unwrap_or("N/A")
        );
        
        for ns in &domain.nameservers {
            let hostname = ns.ldh_name.as_deref().unwrap_or("Unknown");
            println!("\n  {}", hostname);
            
            // Display IP addresses (glue records)
            if let Some(ips) = &ns.ip_addresses {
                if !ips.v4.is_empty() {
                    println!("    IPv4:");
                    for ip in &ips.v4 {
                        println!("      {}", ip);
                    }
                }
                
                if !ips.v6.is_empty() {
                    println!("    IPv6:");
                    for ip in &ips.v6 {
                        println!("      {}", ip);
                    }
                }
            }
            
            // Display status
            if !ns.status.is_empty() {
                println!("    Status: {}", ns.status.join(", "));
            }
        }
    }
    
    Ok(())
}

Direct Nameserver Query

use rdap_client::RdapClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = RdapClient::new();
    
    // Query a specific nameserver
    let result = client.query_nameserver("ns1.example.com").await?;
    
    if let Some(nameserver) = result.nameserver() {
        println!("Nameserver: {}", 
            nameserver.ldh_name.as_deref().unwrap_or("N/A")
        );
        
        println!("Handle: {}", 
            nameserver.handle.as_deref().unwrap_or("N/A")
        );
        
        // Show all IP addresses
        if let Some(ips) = &nameserver.ip_addresses {
            println!("\nIP Addresses:");
            for ip in &ips.v4 {
                println!("  {}", ip);
            }
            for ip in &ips.v6 {
                println!("  {}", ip);
            }
        }
        
        // Show status
        if !nameserver.status.is_empty() {
            println!("\nStatus: {}", nameserver.status.join(", "));
        }
        
        // Show events
        for event in &nameserver.events {
            println!("\n{}: {}", event.action, event.date);
        }
    }
    
    Ok(())
}

Checking for Glue Records

fn has_glue_records(ns: &Nameserver) -> bool {
    if let Some(ips) = &ns.ip_addresses {
        !ips.v4.is_empty() || !ips.v6.is_empty()
    } else {
        false
    }
}

fn count_ip_addresses(ns: &Nameserver) -> (usize, usize) {
    if let Some(ips) = &ns.ip_addresses {
        (ips.v4.len(), ips.v6.len())
    } else {
        (0, 0)
    }
}

// Usage
for ns in &domain.nameservers {
    let hostname = ns.ldh_name.as_deref().unwrap_or("Unknown");
    
    if has_glue_records(ns) {
        let (v4_count, v6_count) = count_ip_addresses(ns);
        println!("{} has {} IPv4 and {} IPv6 addresses", 
            hostname, v4_count, v6_count);
    } else {
        println!("{} has no glue records", hostname);
    }
}

Filtering Nameservers by Status

// Find all active nameservers
let active_nameservers: Vec<_> = domain.nameservers.iter()
    .filter(|ns| ns.status.contains(&"active".to_string()))
    .collect();

println!("Active nameservers: {}", active_nameservers.len());

for ns in active_nameservers {
    println!("  {}", ns.ldh_name.as_deref().unwrap_or("Unknown"));
}

Build docs developers (and LLMs) love