/ core / node / dns.go
dns.go
 1  package node
 2  
 3  import (
 4  	"math"
 5  	"time"
 6  
 7  	"github.com/ipfs/boxo/gateway"
 8  	config "github.com/ipfs/kubo/config"
 9  	doh "github.com/libp2p/go-doh-resolver"
10  	madns "github.com/multiformats/go-multiaddr-dns"
11  )
12  
13  // Compile-time interface check: *madns.Resolver (returned by gateway.NewDNSResolver
14  // and madns.NewResolver) must implement madns.BasicResolver for p2pForgeResolver fallback.
15  var _ madns.BasicResolver = (*madns.Resolver)(nil)
16  
17  func DNSResolver(cfg *config.Config) (*madns.Resolver, error) {
18  	var dohOpts []doh.Option
19  	if !cfg.DNS.MaxCacheTTL.IsDefault() {
20  		dohOpts = append(dohOpts, doh.WithMaxCacheTTL(cfg.DNS.MaxCacheTTL.WithDefault(time.Duration(math.MaxUint32)*time.Second)))
21  	}
22  
23  	// Replace "auto" DNS resolver placeholders with autoconf values
24  	resolvers := cfg.DNSResolversWithAutoConf()
25  
26  	// Get base resolver from boxo (handles custom DoH resolvers per eTLD)
27  	baseResolver, err := gateway.NewDNSResolver(resolvers, dohOpts...)
28  	if err != nil {
29  		return nil, err
30  	}
31  
32  	// Check if we should skip network DNS lookups for p2p-forge domains
33  	skipAutoTLSDNS := cfg.AutoTLS.SkipDNSLookup.WithDefault(config.DefaultAutoTLSSkipDNSLookup)
34  	if !skipAutoTLSDNS {
35  		// Local resolution disabled, use network DNS for everything
36  		return baseResolver, nil
37  	}
38  
39  	// Build list of p2p-forge domains to resolve locally without network I/O.
40  	// AutoTLS hostnames encode IP addresses directly (e.g., 1-2-3-4.peerID.libp2p.direct),
41  	// so DNS lookups are wasteful. We resolve these in-memory when possible.
42  	forgeDomains := []string{config.DefaultDomainSuffix}
43  	customDomain := cfg.AutoTLS.DomainSuffix.WithDefault(config.DefaultDomainSuffix)
44  	if customDomain != config.DefaultDomainSuffix {
45  		forgeDomains = append(forgeDomains, customDomain)
46  	}
47  	forgeResolver := NewP2PForgeResolver(forgeDomains, baseResolver)
48  
49  	// Register p2p-forge resolver for each domain, fallback to baseResolver for others
50  	opts := []madns.Option{madns.WithDefaultResolver(baseResolver)}
51  	for _, domain := range forgeDomains {
52  		opts = append(opts, madns.WithDomainResolver(domain+".", forgeResolver))
53  	}
54  
55  	return madns.NewResolver(opts...)
56  }