Skip to content

DNS Resolver

opencode-agent[bot] edited this page May 11, 2026 · 1 revision

DNS Resolver

DNS resolver for hostname-to-address lookups, bridging DHCP-configured nameservers to application network calls.

Overview

JNode's DNS resolver is a singleton service that translates hostnames into IPv4 addresses. It integrates with DHCP for dynamic server configuration and uses the dnsjava library (xbill) for protocol handling. Applications access name resolution through Resolver.getByName(), which is called from NetAPIImpl and the IPv4 network layer.

Key Components

Class/File Location Purpose
Resolver net/src/net/org/jnode/net/Resolver.java Public interface for name resolution
ResolverImpl net/src/net/org/jnode/net/ipv4/util/ResolverImpl.java Singleton implementation using dnsjava
DHCPClient net/src/net/org/jnode/net/ipv4/dhcp/DHCPClient.java Configures DNS servers from DHCP lease
IPv4NetworkLayer net/src/net/org/jnode/net/ipv4/layer/IPv4NetworkLayer.java Uses Resolver for address resolution
NetAPIImpl net/src/net/org/jnode/net/service/NetAPIImpl.java Exposes Resolver to application layer

How It Works

Resolver Interface

The Resolver interface defines two operations:

public interface Resolver {
    ProtocolAddress[] getByName(String hostname) throws UnknownHostException;
    String[] getByAddress(ProtocolAddress address) throws UnknownHostException;
}

The first method resolves a hostname to IP addresses; the second (reverse DNS) is stubbed out.

Singleton Implementation

ResolverImpl is a @SharedStatics class implementing the Resolver interface. It uses the dnsjava library (org.xbill.DNS) for DNS protocol operations. The singleton is obtained via getInstance():

@SharedStatics
public class ResolverImpl implements Resolver {
    private static ExtendedResolver resolver;
    private static Map<String, org.xbill.DNS.Resolver> resolvers;
    private static Map<String, ProtocolAddress[]> hosts; // /etc/hosts-like
    private static Resolver res = null;

    public static Resolver getInstance() {
        if (res == null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    System.setProperty("dns.server", "127.0.0.1");
                    System.setProperty("dns.search", "localdomain");
                    return null;
                }
            });
            res = new ResolverImpl();
        }
        return res;
    }
}

getByName Flow

sequenceDiagram
    participant App as Application
    participant NetAPI as NetAPIImpl / IPv4NetworkLayer
    participant Resolver as ResolverImpl
    participant DNS as dnsjava (ExtendedResolver)

    App->>NetAPI: getByName("example.com")
    NetAPI->>Resolver: ResolverImpl.getInstance().getByName(hostname)
    alt hostname in hosts map
        Resolver->>Resolver: return cached IPv4Address[]
    else DNS query
        Resolver->>DNS: Lookup.setDefaultResolver(resolver)
        Resolver->>DNS: new Lookup(hostname)
        DNS->>DNS: lookup.run()
        alt SUCCESS
            DNS-->>Resolver: Record[] answers
            Resolver->>Resolver: convert to ProtocolAddress[]
        else FAILURE
            Resolver--xNetAPI: UnknownHostException
        end
    end
    NetAPI-->>App: IPv4Address[]
Loading

DNS Server Management

DNS servers are added dynamically via addDnsServer():

public static void addDnsServer(ProtocolAddress _dnsserver) throws NetworkException {
    if (resolver == null) {
        final String[] server = new String[] {_dnsserver.toString()};
        AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
            public Object run() throws Exception {
                resolver = new ExtendedResolver(server);
                Lookup.setDefaultResolver(resolver);
                return null;
            }
        });
    }
    // Add to ExtendedResolver for failover
    SimpleResolver simpleResolver = new SimpleResolver(key);
    resolver.addResolver(simpleResolver);
}

DHCP Integration

When DHCP assigns a lease, DHCPClient extracts DNS server addresses and adds them:

final byte[] dnsValue = msg.getOption(DHCPMessage.DNS_OPTION);
if (dnsValue != null) {
    for (int i = 0; i < dnsValue.length; i += 4) {
        final IPv4Address dnsIP = new IPv4Address(dnsValue, i);
        try {
            ResolverImpl.addDnsServer(dnsIP);
        } catch (NetworkException ex) {
            log.error("Failed to configure DNS server");
        }
    }
}

Gotchas

  1. getByAddress is stubbed — The reverse DNS method returns an empty array. This means InetAddress.getByAddress() won't produce a hostname.

  2. Hardcoded default DNS — On first access, getInstance() sets dns.server=127.0.0.1 and dns.search=localdomain. If no servers are configured, lookups fail.

  3. No DNS cache — Each getByName() call queries the DNS server. There is no TTL-based caching layer.

  4. @SharedStatics usage — The class is marked @SharedStatics, meaning static fields are shared across isolates. This is appropriate since DNS is a system-wide service.

  5. dnsjava version — The code references org.xbill.DNS.ExtendedResolver from the dnsjava library. The FIXME comment notes the library may need upgrading.

  6. Hosts file is minimal — Only localhost is pre-populated in the hosts map. There is no /etc/hosts file parsing.

  7. Singleton pattern inconsistency — The FIXME notes that management methods are static while state is static, but the class isn't a proper singleton (no private constructor enforcement, multiple static maps).

Related Pages

Clone this wiki locally