Help us shape the future of Go! Take the 2026 Go Developer Survey

retryabledns

package module
v1.0.116 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 27, 2026 License: MIT Imports: 22 Imported by: 118

README

Retryable dns resolver

Based on miekg/dns and freely inspired by bogdanovich/dns_resolver.

Features

  • Supports both system default DNS resolvers and user-provided ones
  • Retries DNS requests in case of I/O errors, timeouts, or network failures
  • Allows arbitrary query types
  • Resolution with random resolvers
  • Compatible with various DNS resolver protocols (TCP, UDP, DoH, and DoT)
Using go get
$ go get github.com/projectdiscovery/retryabledns

After this command retryabledns library source will be in your $GOPATH

/etc/hosts file processing

By default, the library processes the /etc/hosts file up to a maximum amount of lines for efficiency (4096). If your setup has a larger hosts file and you want to process more lines, you can easily configure this limit by adjusting the hostsfile.MaxLines variable.

For example:

hostsfile.MaxLines = 10000  // Now the library will process up to 10000 lines from the hosts file

Example

Usage Example:

package main

import (
    "log"

    "github.com/projectdiscovery/retryabledns"
    "github.com/miekg/dns"
)

func main() {
    // It requires a list of resolvers.
    // Valid protocols are "udp", "tcp", "doh", "dot". Default are "udp".
    resolvers := []string{"8.8.8.8:53", "8.8.4.4:53", "tcp:1.1.1.1"}
    retries := 2
    hostname := "hackerone.com"

    dnsClient, err := retryabledns.New(resolvers, retries)
    if err != nil {
        log.Fatal(err)
    }

    ips, err := dnsClient.Resolve(hostname)
    if err != nil {
        log.Fatal(err)
    }

    log.Println(ips)

    // Query Types: dns.TypeA, dns.TypeNS, dns.TypeCNAME, dns.TypeSOA, dns.TypePTR, dns.TypeMX, dns.TypeANY
    // dns.TypeTXT, dns.TypeAAAA, dns.TypeSRV (from github.com/miekg/dns)
    // retryabledns.ErrRetriesExceeded will be returned if a result isn't returned in max retries
    dnsResponses, err := dnsClient.Query(hostname, dns.TypeA)
    if err != nil {
        log.Fatal(err)
    }

    log.Println(dnsResponses)
}

Credits:

  • https://github.com/lixiangzhong/dnsutil
  • https://github.com/rs/dnstrace

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// DefaultMaxPerCNAMEFollows is the default number of times a CNAME can be followed within a trace
	DefaultMaxPerCNAMEFollows = 32

	// ErrRetriesExceeded is the error returned when the max retries are exceeded
	ErrRetriesExceeded = errors.New("could not resolve, max retries exceeded")
)
View Source
var (
	ErrMaxRetriesZero = errors.New("retries must be at least 1")
	ErrResolversEmpty = errors.New("resolvers list must not be empty")

	BaseResolvers = []string{
		"1.1.1.1:53",
		"1.0.0.1:53",
		"8.8.8.8:53",
		"8.8.4.4:53",
	}
	DefaultOptions = Options{
		BaseResolvers: BaseResolvers,
		MaxRetries:    1,
		Timeout:       3 * time.Second,
	}
)
View Source
var CheckInternalIPs = false

CheckInternalIPs when set to true returns if DNS response IPs belong to internal IP ranges.

View Source
var RootDNSServers = []RootDNS{
	{"a.root-servers.net", "198.41.0.4", "2001:503:ba3e::2:30", "Verisign, Inc"},
	{"b.root-servers.net", "199.9.14.201", "2001:500:200::b", "University of Southern California, Information Sciences Institute"},
	{"c.root-servers.net", "192.33.4.12", "2001:500:2::c", "Cogent Communications"},
	{"d.root-servers.net", "199.7.91.13", "2001:500:2d::d", "University of Maryland"},
	{"e.root-servers.net", "192.203.230.10", "2001:500:a8::e", "NASA (Ames Research Center)"},
	{"f.root-servers.net", "192.5.5.241", "2001:500:2f::f", "Internet Systems Consortium, Inc."},
	{"g.root-servers.net", "192.112.36.4", "2001:500:12::d0d", "US Department of Defense (NIC)"},
	{"h.root-servers.net", "198.97.190.53", "2001:500:1::53", "US Army (Research Lab)"},
	{"i.root-servers.net", "192.36.148.17", "2001:7fe::53", "Netnod"},
	{"j.root-servers.net", "192.58.128.30", "2001:503:c27::2:30", "Verisign, Inc"},
	{"k.root-servers.net", "193.0.14.129", "2001:7fd::1", "RIPE NCC"},
	{"l.root-servers.net", "199.7.83.42", "2001:500:9f::42", "ICANN"},
	{"m.root-servers.net", "202.12.27.33", "2001:dc3::35", "WIDE Project"},
}
View Source
var RootDNSServersIPv4 = []string{
	"198.41.0.4:53", "199.9.14.201:53", "192.33.4.12:53", "199.7.91.13:53",
	"192.203.230.10:53", "192.5.5.241:53", "192.112.36.4:53", "198.97.190.53:53",
	"192.36.148.17:53", "192.58.128.30:53", "193.0.14.129:53", "199.7.83.42:53",
	"202.12.27.33:53",
}

Functions

This section is empty.

Types

type AXFRData added in v1.0.14

type AXFRData struct {
	Host    string     `json:"host,omitempty"`
	DNSData []*DNSData `json:"chain,omitempty"`
}

type Client

type Client struct {
	TCPFallback bool
	// contains filtered or unexported fields
}

Client is a DNS resolver client to resolve hostnames.

func New

func New(baseResolvers []string, maxRetries int) (*Client, error)

New creates a new dns client

func NewWithOptions added in v1.0.13

func NewWithOptions(options Options) (*Client, error)

New creates a new dns client with options

func (*Client) A added in v1.0.12

func (c *Client) A(host string) (*DNSData, error)

A helper function

func (*Client) AAAA added in v1.0.12

func (c *Client) AAAA(host string) (*DNSData, error)

AAAA helper function

func (*Client) ANY added in v1.0.24

func (c *Client) ANY(host string) (*DNSData, error)

ANY helper function

func (*Client) AXFR added in v1.0.14

func (c *Client) AXFR(host string) (*AXFRData, error)

func (*Client) CAA added in v1.0.14

func (c *Client) CAA(host string) (*DNSData, error)

CAA helper function

func (*Client) CNAME added in v1.0.12

func (c *Client) CNAME(host string) (*DNSData, error)

CNAME helper function

func (*Client) Close added in v1.0.34

func (c *Client) Close()

func (*Client) Do

func (c *Client) Do(msg *dns.Msg) (*dns.Msg, error)

Do sends a provided dns request and return the raw native response

func (*Client) MX added in v1.0.12

func (c *Client) MX(host string) (*DNSData, error)

MX helper function

func (*Client) NS added in v1.0.12

func (c *Client) NS(host string) (*DNSData, error)

NS helper function

func (*Client) PTR added in v1.0.12

func (c *Client) PTR(host string) (*DNSData, error)

PTR helper function

func (*Client) Query

func (c *Client) Query(host string, requestType uint16) (*DNSData, error)

Query sends a provided dns request and return enriched response

func (*Client) QueryMultiple

func (c *Client) QueryMultiple(host string, requestTypes []uint16) (*DNSData, error)

QueryMultiple sends a provided dns request and return the data

func (*Client) QueryMultipleWithResolver added in v1.0.14

func (c *Client) QueryMultipleWithResolver(host string, requestTypes []uint16, resolver Resolver) (*DNSData, error)

QueryMultiple sends a provided dns request and return the data with a specific resolver

func (*Client) QueryParallel added in v1.0.12

func (c *Client) QueryParallel(host string, requestType uint16, resolvers []string) ([]*DNSData, error)

QueryParallel sends a provided dns request to multiple resolvers in parallel

func (*Client) Resolve

func (c *Client) Resolve(host string) (*DNSData, error)

Resolve is the underlying resolve function that actually resolves a host and gets the ip records for that host.

func (*Client) ResolveWithSyscall added in v1.0.7

func (c *Client) ResolveWithSyscall(host string) (*DNSData, error)

ResolveWithSyscall attempts to resolve the host through system calls

func (*Client) SOA added in v1.0.12

func (c *Client) SOA(host string) (*DNSData, error)

SOA helper function

func (*Client) SRV added in v1.0.16

func (c *Client) SRV(host string) (*DNSData, error)

SRV helper function

func (*Client) TXT added in v1.0.12

func (c *Client) TXT(host string) (*DNSData, error)

TXT helper function

func (*Client) Trace added in v1.0.12

func (c *Client) Trace(host string, requestType uint16, maxrecursion int) (*TraceData, error)

Trace the requested domain with the provided query type

type ConnPool added in v1.0.34

type ConnPool struct {
	// contains filtered or unexported fields
}

func NewConnPool added in v1.0.34

func NewConnPool(resolver NetworkResolver, poolSize int) (*ConnPool, error)

func (*ConnPool) Close added in v1.0.34

func (cp *ConnPool) Close()

func (*ConnPool) Exchange added in v1.0.34

func (cp *ConnPool) Exchange(ctx context.Context, client *dns.Client, msg *dns.Msg) (r *dns.Msg, rtt time.Duration, err error)

func (*ConnPool) LocalAddrs added in v1.0.34

func (cp *ConnPool) LocalAddrs() []*net.UDPAddr

func (*ConnPool) Resolver added in v1.0.34

func (cp *ConnPool) Resolver() NetworkResolver

type DNSData

type DNSData struct {
	Host           string     `json:"host,omitempty"`
	TTL            uint32     `json:"ttl,omitempty"`
	Resolver       []string   `json:"resolver,omitempty"`
	A              []string   `json:"a,omitempty"`
	AAAA           []string   `json:"aaaa,omitempty"`
	CNAME          []string   `json:"cname,omitempty"`
	MX             []string   `json:"mx,omitempty"`
	PTR            []string   `json:"ptr,omitempty"`
	SOA            []SOA      `json:"soa,omitempty"`
	NS             []string   `json:"ns,omitempty"`
	TXT            []string   `json:"txt,omitempty"`
	SRV            []string   `json:"srv,omitempty"`
	CAA            []string   `json:"caa,omitempty"`
	AllRecords     []string   `json:"all,omitempty"`
	Raw            string     `json:"raw,omitempty"`
	HasInternalIPs bool       `json:"has_internal_ips,omitempty"`
	InternalIPs    []string   `json:"internal_ips,omitempty"`
	StatusCode     string     `json:"status_code,omitempty"`
	StatusCodeRaw  int        `json:"status_code_raw,omitempty"`
	TraceData      *TraceData `json:"trace,omitempty"`
	AXFRData       *AXFRData  `json:"axfr,omitempty"`
	RawResp        *dns.Msg   `json:"raw_resp,omitempty"`
	Timestamp      time.Time  `json:"timestamp,omitempty"`
	HostsFile      bool       `json:"hosts_file,omitempty"`
}

DNSData is the data for a DNS request response

func (*DNSData) GetSOARecords added in v1.0.28

func (d *DNSData) GetSOARecords() []string

GetSOARecords returns the NS and Mbox of all SOA records as a string slice

func (*DNSData) JSON

func (d *DNSData) JSON() (string, error)

JSON returns the object as json string

func (*DNSData) Marshal

func (d *DNSData) Marshal() ([]byte, error)

Marshal encodes the dnsdata to a binary representation

func (*DNSData) ParseFromEnvelopeChan added in v1.0.14

func (d *DNSData) ParseFromEnvelopeChan(envChan chan *dns.Envelope) error

func (*DNSData) ParseFromMsg

func (d *DNSData) ParseFromMsg(msg *dns.Msg) error

ParseFromMsg and enrich data

func (*DNSData) ParseFromRR added in v1.0.14

func (d *DNSData) ParseFromRR(rrs []dns.RR) error

func (*DNSData) Unmarshal

func (d *DNSData) Unmarshal(b []byte) error

Unmarshal decodes the dnsdata from a binary representation

type DohProtocol added in v1.0.13

type DohProtocol string
const (
	JsonAPI DohProtocol = "jsonapi"
	GET     DohProtocol = "get"
	POST    DohProtocol = "post"
)

func (DohProtocol) String added in v1.0.13

func (p DohProtocol) String() string

func (DohProtocol) StringWithSemicolon added in v1.0.13

func (p DohProtocol) StringWithSemicolon() string

type DohResolver added in v1.0.13

type DohResolver struct {
	Protocol DohProtocol
	URL      string
}

func (DohResolver) Method added in v1.0.13

func (r DohResolver) Method() string

func (DohResolver) String added in v1.0.13

func (r DohResolver) String() string

type NetworkResolver added in v1.0.13

type NetworkResolver struct {
	Protocol Protocol
	Host     string
	Port     string
}

func (NetworkResolver) String added in v1.0.13

func (r NetworkResolver) String() string

type Options added in v1.0.13

type Options struct {
	BaseResolvers         []string
	MaxRetries            int
	Timeout               time.Duration
	Hostsfile             bool
	LocalAddrIP           net.IP
	LocalAddrPort         uint16
	ConnectionPoolThreads int
	MaxPerCNAMEFollows    int
	Proxy                 string

	// ExitOnStatusCodes lists DNS rcodes that terminate the retry
	// loop. When non-empty, only attempts whose rcode is in this list
	// are considered definitive: the response is parsed into the
	// returned DNSData and the loop exits. Attempts with any other
	// rcode are treated like transport errors - the response is not
	// parsed, DNSData is not mutated, and the loop continues with the
	// next resolver.
	//
	// Common values:
	//
	//	[]int{dns.RcodeSuccess}                       // NOERROR only
	//	[]int{dns.RcodeSuccess, dns.RcodeNameError}   // NOERROR or NXDOMAIN
	//
	// An empty/nil list preserves the legacy behavior: every attempt
	// is parsed, DNSData.Raw accumulates across retries, and only
	// RcodeSuccess breaks the loop.
	ExitOnStatusCodes []int
}

func (*Options) GetLocalAddr added in v1.0.27

func (options *Options) GetLocalAddr(proto Protocol) net.Addr

Returns a net.Addr of a UDP or TCP type depending on whats required

func (*Options) SetLocalAddrIP added in v1.0.27

func (options *Options) SetLocalAddrIP(ip string)

Sets the ip from a string, if invalid sets as nil

func (*Options) SetLocalAddrIPFromNetInterface added in v1.0.27

func (options *Options) SetLocalAddrIPFromNetInterface(ifaceName string) error

Sets the first available IP from a network interface name e.g. eth0

func (*Options) Validate added in v1.0.14

func (options *Options) Validate() error

type Protocol added in v1.0.13

type Protocol string
const (
	UDP Protocol = "udp"
	TCP Protocol = "tcp"
	DOH Protocol = "doh"
	DOT Protocol = "dot"
)

func (Protocol) String added in v1.0.13

func (p Protocol) String() string

func (Protocol) StringWithSemicolon added in v1.0.13

func (p Protocol) StringWithSemicolon() string

type Resolver added in v1.0.13

type Resolver interface {
	String() string
}

type RootDNS added in v1.0.12

type RootDNS struct {
	Host     string
	IPv4     string
	IPv6     string
	Operator string
}

type SOA added in v1.0.26

type SOA struct {
	Name    string `json:"name,omitempty"`
	NS      string `json:"ns,omitempty"`
	Mbox    string `json:"mailbox,omitempty"`
	Serial  uint32 `json:"serial,omitempty"`
	Refresh uint32 `json:"refresh,omitempty"`
	Retry   uint32 `json:"retry,omitempty"`
	Expire  uint32 `json:"expire,omitempty"`
	Minttl  uint32 `json:"minttl,omitempty"`
}

type TraceData added in v1.0.12

type TraceData struct {
	Host    string     `json:"host,omitempty"`
	DNSData []*DNSData `json:"chain,omitempty"`
}

TraceData contains the trace information for a dns query

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL