Iroh Address Lookup Services for Endpoint Discovery: Pkarr, DNS, and Mainline-DHT
Iroh discovers remote endpoints through a pluggable address lookup system that supports Pkarr relays, DNS TXT records, in-memory storage for testing, and optional Mainline-DHT resolution.
The n0-computer/iroh repository provides a robust framework for peer discovery through the AddressLookup trait. These iroh address lookup services allow applications to publish their endpoint information and resolve remote peers using multiple discovery mechanisms that can be combined for redundancy.
How Iroh Endpoint Discovery Works
Iroh’s endpoint discovery relies on the AddressLookup trait, which abstracts how EndpointInfo—containing relay URLs, IP addresses, and other connection details—is published and retrieved. The Builder struct in iroh/src/endpoint.rs exposes an address_lookup method that accepts any implementation of this trait, allowing developers to chain multiple lookup services together.
Supported Address Lookup Services
Iroh ships with four concrete address lookup implementations in the core crate, plus an optional external crate for decentralized DHT resolution.
Pkarr Publisher and Resolver
The PkarrPublisher and PkarrResolver structs—defined in iroh/src/address_lookup/pkarr.rs—provide bidirectional endpoint discovery through Pkarr relays.
- Publishing:
PkarrPublishersends an HTTP PUT request to a configured pkarr relay, storing a signed packet containing the endpoint’sEndpointInfo. The relay stores this in the Mainline-DHT or a local cache. - Resolution:
PkarrResolverqueries the same relay via HTTP GET to retrieve the signed packet and parse it into anAddressLookupItem.
These services support both production and staging relays through builder APIs that configure the TLS context and relay endpoints.
DNS Address Lookup
The DnsAddressLookup service in iroh/src/address_lookup/dns.rs resolves endpoints by querying DNS TXT records. It looks up records following the format:
_iroh.<z32-encoded-EndpointId>.<origin-domain>
For example: _iroh.abc123.n0.com. The TXT records contain key-value pairs such as relay=<url> that describe how to reach the endpoint. This service supports both staging and production origin domains.
In-Memory Lookup
The MemoryLookup struct in iroh/src/address_lookup/memory.rs stores EndpointInfo objects in a local HashMap. This implementation is designed for unit tests and temporary setups where no external network service is required, allowing for fast, isolated endpoint discovery during development.
Mainline-DHT Lookup
For decentralized discovery without relying on Pkarr relays, iroh supports Mainline-DHT resolution through the auxiliary crate iroh-mainline-address-lookup. This crate exposes the same PkarrResolver and PkarrPublisher APIs but forwards queries directly to the BitTorrent Mainline DHT rather than through an HTTP relay.
Configuring Address Lookup in Iroh
You can configure iroh to use multiple lookup services simultaneously through the endpoint builder pattern.
Combined Publishing and Resolution
To publish via Pkarr while resolving via both Pkarr and DNS:
use iroh::endpoint::Builder;
use iroh::address_lookup::{PkarrPublisher, DnsAddressLookup};
let builder = Builder::default()
// Publish endpoint info to the public pkarr relay
.address_lookup(PkarrPublisher::n0_dns())
// Resolve peers via DNS TXT records under iroh.link
.address_lookup(DnsAddressLookup::n0_dns());
let endpoint = builder.build().await?;
Resolver-Only Configuration
For clients that only need to resolve remote endpoints without publishing their own:
use iroh::address_lookup::PkarrResolver;
let resolver = PkarrResolver::n0_dns().build(tls_config);
let lookup_item = resolver.resolve(endpoint_id).await?;
Using the N0 Preset
The N0 preset in iroh/src/endpoint/presets.rs wires both Pkarr and DNS services together automatically:
use iroh::endpoint::presets::N0;
let endpoint = N0::new(secret_key).await?;
Key Source Files and Implementation Details
| File | Purpose |
|---|---|
iroh/src/address_lookup/pkarr.rs |
Implements PkarrPublisher and PkarrResolver with HTTP PUT/GET logic and relay constants |
iroh/src/address_lookup/dns.rs |
Contains DnsAddressLookup with TXT record parsing for _iroh.* subdomains |
iroh/src/address_lookup/memory.rs |
Provides MemoryLookup for test environments using in-memory storage |
iroh/src/endpoint/presets.rs |
Defines the N0 preset that combines Pkarr and DNS lookups |
iroh/src/endpoint.rs |
Exposes Builder::address_lookup() for registering any AddressLookup implementation |
Summary
- Pkarr services (
PkarrPublisher/PkarrResolver) use HTTP requests to relays that store data in the Mainline-DHT. - DNS lookup (
DnsAddressLookup) queries TXT records at_iroh.<z32-id>.<domain>to find relay URLs. - In-memory lookup (
MemoryLookup) provides local hashing for unit tests. - Mainline-DHT resolution is available via the external
iroh-mainline-address-lookupcrate for decentralized operation. - The
AddressLookuptrait allows composable configuration throughBuilder::address_lookup().
Frequently Asked Questions
What is the difference between PkarrPublisher and PkarrResolver?
PkarrPublisher publishes your local endpoint's information to a Pkarr relay using HTTP PUT, making it discoverable by other peers. PkarrResolver queries that same relay via HTTP GET to retrieve endpoint information for a specific EndpointId. Both are implemented in iroh/src/address_lookup/pkarr.rs and share the same underlying packet format but serve opposite directions of data flow.
How does iroh DNS address lookup format endpoint information?
Iroh uses DNS TXT records with the subdomain pattern _iroh.<z32-encoded-endpoint-id>.<origin-domain>, such as _iroh.abc123.n0.com. These records contain key-value pairs like relay=https://relay.example.com that the DnsAddressLookup service parses to construct connection paths to remote endpoints.
Can I use multiple address lookup services simultaneously?
Yes. The Builder::address_lookup() method in iroh/src/endpoint.rs can be called multiple times to chain services. For example, you can register both PkarrPublisher for publishing and DnsAddressLookup for resolution, or multiple resolvers for redundant peer discovery across different namespaces.
What is the N0 preset in iroh endpoint configuration?
The N0 preset, defined in iroh/src/endpoint/presets.rs, is a convenience configuration that automatically wires both PkarrPublisher and DnsAddressLookup using n0's production infrastructure. It provides a one-line setup (N0::new(secret_key).await?) for applications that want standard, production-ready endpoint discovery without manually configuring individual lookup services.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →