Skip to content

feat: add LookupTXTWithTTL to Resolver#75

Open
lidel wants to merge 1 commit into
masterfrom
feat/lookup-txt-with-ttl
Open

feat: add LookupTXTWithTTL to Resolver#75
lidel wants to merge 1 commit into
masterfrom
feat/lookup-txt-with-ttl

Conversation

@lidel
Copy link
Copy Markdown
Member

@lidel lidel commented Jun 3, 2026

Problem

Resolver.LookupTXT routes to the matched per-domain resolver but returns only the record values, dropping any TTL. A resolver that knows the TTL (such as a DNS-over-HTTPS resolver) has no way to report it, so callers cannot tell how long a TXT record set is valid or when to re-resolve it. Correct caching and expiration needs that TTL for both kinds of TXT records this library resolves:

  • DNSADDR (dnsaddr=): the TTL bounds how long a resolved multiaddr is valid. Multiaddrs increasingly carry rotating /certhash/ segments (AutoTLS WebTransport / WebRTC-direct nodes, including libp2p bootstrappers). Without the TTL these cannot be cached or expired correctly, so a peer cannot reliably publish addresses whose certhash changes over time: stale certhashes linger and dials fail.
  • DNSLink (dnslink=): the TTL lets an IPFS gateway set Cache-Control: max-age=<ttl> for /ipns/<dnslink-host> responses (see Gateway: Cache-Control, max-age=ttl, ETag for /ipns requests ipfs/boxo#329).

Fix

  • Add TXTWithTTLResolver, an optional interface a BasicResolver may implement to report the TTL of a TXT record set.
  • Add Resolver.LookupTXTWithTTL, which routes to the matched per-domain resolver and returns its TTL when that resolver implements TXTWithTTLResolver. Resolvers without TTL support (such as the default OS resolver) report 0, meaning unknown.
  • Resolver itself implements TXTWithTTLResolver, so a Resolver used as a per-domain resolver routes TTL too.

LookupTXT and the BasicResolver interface are unchanged, so this is additive. A DoH resolver that implements LookupTXTWithTTL (libp2p/go-doh-resolver#33) flows its TTL through to consumers: libp2p address resolution for DNSADDR, and boxo's DNSLink resolution.

Resolver.LookupTXT returns only TXT values and drops the TTL, so a
resolver that knows it (such as DNS-over-HTTPS) cannot report it and
callers cannot tell how long a record set is valid or when to
re-resolve. Correct caching and expiration needs that TTL for both
kinds of TXT records this library resolves:

- DNSADDR (dnsaddr=): the TTL bounds how long a resolved multiaddr is
  valid. Multiaddrs increasingly carry rotating /certhash/ segments
  (AutoTLS WebTransport and WebRTC-direct nodes, including libp2p
  bootstrappers); without the TTL these cannot be cached or expired
  correctly, so a peer cannot reliably publish addresses whose certhash
  changes over time.
- DNSLink (dnslink=): the TTL lets an IPFS gateway set Cache-Control
  max-age for /ipns/<dnslink-host> responses (ipfs/boxo#329).

Add LookupTXTWithTTL, which routes to the matched per-domain resolver
and returns its TTL when it implements the new TXTWithTTLResolver
interface; resolvers without TTL support (such as the OS resolver)
report 0 (unknown). LookupTXT and BasicResolver are unchanged, so this
is additive.
lidel added a commit to ipfs/boxo that referenced this pull request Jun 3, 2026
The DNS resolver dropped the TXT record TTL, so a gateway could not set
Cache-Control max-age for DNSLink (/ipns/<dnslink-host>) responses, and a
recursive name was cached for only its final hop's TTL.

- add LookupTXTWithTTLFunc and NewDNSResolverWithTTL; LookupTXTFunc and
  NewDNSResolver keep their signatures and report an unknown TTL (0)
- carry the looked-up TTL into AsyncResult.TTL in the DNS resolver
- WithDNSResolver detects a resolver implementing
  multiformats/go-multiaddr-dns#75 TXTWithTTLResolver and propagates the
  TTL; add WithDNSResolverWithTTL for a TTL-aware lookup
- cap a resolved name's TTL to its shortest hop, so a DNSLink or
  recursive IPNS name is not cached past its earliest-expiring link

Refs #329
@lidel lidel requested review from MarcoPolo and sukunrt June 3, 2026 22:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant