Complete DNS library for Go with full protocol control, DNSSEC support, and both client and server programming capabilities
npx @tessl/cli install tessl/golang-github-com-miekg--dns@1.1.0Complete DNS library for Go providing full-featured interface to the Domain Name System with support for both server-side and client-side programming.
go get github.com/miekg/dnsimport "github.com/miekg/dns"For the utility sub-package:
import "github.com/miekg/dns/dnsutil"Simple DNS query example:
package main
import (
"fmt"
"github.com/miekg/dns"
)
func main() {
// Create a new DNS message
m := new(dns.Msg)
m.SetQuestion(dns.Fqdn("example.com"), dns.TypeA)
m.RecursionDesired = true
// Send the query
c := new(dns.Client)
in, rtt, err := c.Exchange(m, "8.8.8.8:53")
if err != nil {
panic(err)
}
// Process answers
for _, ans := range in.Answer {
if a, ok := ans.(*dns.A); ok {
fmt.Printf("A record: %s\n", a.A)
}
}
}Simple DNS server example:
package main
import (
"github.com/miekg/dns"
"log"
"net"
)
func handleRequest(w dns.ResponseWriter, r *dns.Msg) {
m := new(dns.Msg)
m.SetReply(r)
m.Authoritative = true
// Add answer
rr := &dns.A{
Hdr: dns.RR_Header{
Name: r.Question[0].Name,
Rrtype: dns.TypeA,
Class: dns.ClassINET,
Ttl: 3600,
},
A: net.ParseIP("192.0.2.1"),
}
m.Answer = append(m.Answer, rr)
w.WriteMsg(m)
}
func main() {
dns.HandleFunc(".", handleRequest)
server := &dns.Server{Addr: ":53", Net: "udp"}
log.Fatal(server.ListenAndServe())
}The library is organized around these key components:
Core DNS message construction, parsing, and manipulation with full control over all message fields and sections.
// Msg represents a DNS message
type Msg struct {
Id uint16
Response bool
Opcode int
Authoritative bool
Truncated bool
RecursionDesired bool
RecursionAvailable bool
Zero bool
AuthenticatedData bool
CheckingDisabled bool
Rcode int
Compress bool
Question []Question
Answer []RR
Ns []RR
Extra []RR
}
func (dns *Msg) Pack() ([]byte, error)
func (dns *Msg) PackBuffer(buf []byte) ([]byte, error)
func (dns *Msg) Unpack(msg []byte) error
func (dns *Msg) SetQuestion(z string, t uint16) *Msg
func (dns *Msg) SetReply(request *Msg) *Msg
func (dns *Msg) SetEdns0(udpsize uint16, do bool) *Msg
func (dns *Msg) IsTsig() *TSIG
func (dns *Msg) IsEdns0() *OPT
func (dns *Msg) Copy() *Msg
func (dns *Msg) String() string
func (dns *Msg) Len() int
// Question represents a DNS question
type Question struct {
Name string
Qtype uint16
Qclass uint16
}
// Message ID generation
func Id() uint16DNS client for making queries with support for UDP, TCP, and TLS transports.
// Client performs DNS queries
type Client struct {
Net string
UDPSize uint16
TLSConfig *tls.Config
Dialer *net.Dialer
Timeout time.Duration
DialTimeout time.Duration
ReadTimeout time.Duration
WriteTimeout time.Duration
TsigSecret map[string]string
TsigProvider TsigProvider
SingleInflight bool
}
func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, err error)
func (c *Client) ExchangeContext(ctx context.Context, m *Msg, address string) (r *Msg, rtt time.Duration, err error)
func (c *Client) Dial(address string) (conn *Conn, err error)
func (c *Client) DialContext(ctx context.Context, address string) (conn *Conn, err error)
// Simple query functions
func Exchange(m *Msg, address string) (r *Msg, err error)
func ExchangeContext(ctx context.Context, m *Msg, address string) (r *Msg, err error)
// Connection functions
func Dial(network, address string) (*Conn, error)
func DialTimeout(network, address string, timeout time.Duration) (*Conn, error)
func DialWithTLS(network, address string, tlsConfig *tls.Config) (*Conn, error)
func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout time.Duration) (*Conn, error)DNS server framework with handler pattern for building authoritative servers and resolvers.
// Server defines parameters for running a DNS server
type Server struct {
Addr string
Net string
TLSConfig *tls.Config
Handler Handler
UDPSize uint16
MaxTCPQueries int
ReusePort bool
ReuseAddr bool
TsigSecret map[string]string
TsigProvider TsigProvider
MsgAcceptFunc MsgAcceptFunc
NotifyStartedFunc func()
}
func (srv *Server) ListenAndServe() error
func (srv *Server) ActivateAndServe() error
func (srv *Server) Shutdown() error
func (srv *Server) ShutdownContext(ctx context.Context) error
// Handler interface for DNS request handlers
type Handler interface {
ServeDNS(w ResponseWriter, r *Msg)
}
// HandlerFunc adapter
type HandlerFunc func(ResponseWriter, *Msg)
func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg)
// ResponseWriter interface for writing responses
type ResponseWriter interface {
LocalAddr() net.Addr
RemoteAddr() net.Addr
WriteMsg(*Msg) error
Write([]byte) (int, error)
Close() error
TsigStatus() error
TsigTimersOnly(bool)
Hijack()
}
// ServeMux multiplexes DNS requests
type ServeMux struct{}
func NewServeMux() *ServeMux
func (mux *ServeMux) Handle(pattern string, handler Handler)
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg))
func (mux *ServeMux) HandleRemove(pattern string)
func (mux *ServeMux) ServeDNS(w ResponseWriter, r *Msg)
// Package-level convenience functions
func Handle(pattern string, handler Handler)
func HandleFunc(pattern string, handler func(ResponseWriter, *Msg))
func HandleRemove(pattern string)
func ListenAndServe(addr string, network string, handler Handler) error
func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) errorComplete support for all DNS resource record types including A, AAAA, CNAME, MX, SOA, SRV, TXT, and 70+ other types.
// RR is the base interface for all resource records
type RR interface {
Header() *RR_Header
String() string
}
// RR_Header is the common header for all resource records
type RR_Header struct {
Name string
Rrtype uint16
Class uint16
Ttl uint32
Rdlength uint16
}
func (h *RR_Header) Header() *RR_Header
// Common RR creation functions
func NewRR(s string) (RR, error)
func Copy(r RR) RRComplete DNSSEC support including signing, validation, key generation, and all standard algorithms.
// DNSKEY represents a DNSSEC public key
type DNSKEY struct {
Hdr RR_Header
Flags uint16
Protocol uint8
Algorithm uint8
PublicKey string
}
func (k *DNSKEY) KeyTag() uint16
func (k *DNSKEY) ToDS(h uint8) *DS
func (k *DNSKEY) ToCDNSKEY() *CDNSKEY
func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error)
// DS represents a delegation signer record
type DS struct {
Hdr RR_Header
KeyTag uint16
Algorithm uint8
DigestType uint8
Digest string
}
func (ds *DS) ToCDS() *CDS
// RRSIG represents a resource record signature
type RRSIG struct {
Hdr RR_Header
TypeCovered uint16
Algorithm uint8
Labels uint8
OrigTtl uint32
Expiration uint32
Inception uint32
KeyTag uint16
SignerName string
Signature string
}
func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error
func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error
func (rr *RRSIG) ValidityPeriod(t time.Time) boolRFC 1035 compliant zone file parser with support for $INCLUDE, $ORIGIN, $TTL, and $GENERATE directives.
// ZoneParser parses RFC 1035 style zone files
type ZoneParser struct{}
func NewZoneParser(r io.Reader, origin, file string) *ZoneParser
func (zp *ZoneParser) Next() (RR, bool)
func (zp *ZoneParser) Err() error
func (zp *ZoneParser) Comment() string
func (zp *ZoneParser) SetDefaultTTL(ttl uint32)
func (zp *ZoneParser) SetIncludeAllowed(v bool)
func (zp *ZoneParser) SetIncludeFS(fs fs.FS)
// Parse single RR from string
func NewRR(s string) (RR, error)
func ReadRR(r io.Reader, file string) (RR, error)Support for AXFR (full zone transfer) and IXFR (incremental zone transfer) operations.
// Transfer handles zone transfers
type Transfer struct {
*Conn
DialTimeout time.Duration
ReadTimeout time.Duration
WriteTimeout time.Duration
TsigSecret map[string]string
TsigProvider TsigProvider
TLS *tls.Config
}
func (t *Transfer) In(m *Msg, a string) (env chan *Envelope, err error)
func (t *Transfer) Out(w ResponseWriter, q *Msg, ch chan *Envelope) error
// Envelope wraps zone transfer records
type Envelope struct {
RR []RR
Error error
}HMAC-based transaction signatures for authenticated DNS operations.
// TSIG algorithms
const (
HmacSHA1 = "hmac-sha1."
HmacSHA224 = "hmac-sha224."
HmacSHA256 = "hmac-sha256."
HmacSHA384 = "hmac-sha384."
HmacSHA512 = "hmac-sha512."
)
// TSIG represents a transaction signature record
type TSIG struct {
Hdr RR_Header
Algorithm string
TimeSigned uint64
Fudge uint16
MACSize uint16
MAC string
OrigId uint16
Error uint16
OtherLen uint16
OtherData string
}
// TsigProvider allows custom TSIG implementations
type TsigProvider interface {
Generate(msg []byte, t *TSIG) ([]byte, error)
Verify(msg []byte, t *TSIG) error
}
// TSIG functions
func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error)
func TsigGenerateWithProvider(m *Msg, provider TsigProvider, requestMAC string, timersOnly bool) ([]byte, string, error)
func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error
func TsigVerifyWithProvider(msg []byte, provider TsigProvider, requestMAC string, timersOnly bool) error
// Msg TSIG methods
func (dns *Msg) SetTsig(z, algo string, fudge uint16, timeSigned int64) *Msg
func (dns *Msg) IsTsig() *TSIGExtended DNS mechanism with support for larger messages, DNSSEC OK bit, client subnet, cookies, and more.
// OPT represents an EDNS0 pseudo-record
type OPT struct {
Hdr RR_Header
Option []EDNS0
}
func (rr *OPT) Do() bool
func (rr *OPT) SetDo(do bool)
func (rr *OPT) Version() uint8
func (rr *OPT) SetVersion(v uint8)
func (rr *OPT) ExtendedRcode() int
func (rr *OPT) SetExtendedRcode(v uint8)
func (rr *OPT) UDPSize() uint16
func (rr *OPT) SetUDPSize(size uint16)
// EDNS0 option interface
type EDNS0 interface {
Option() uint16
pack() ([]byte, error)
unpack([]byte) error
String() string
copy() EDNS0
}
// Msg EDNS0 methods
func (dns *Msg) SetEdns0(udpsize uint16, do bool) *Msg
func (dns *Msg) IsEdns0() *OPTRFC 2136 dynamic update support with prerequisites and update operations.
// Msg methods for dynamic updates
func (dns *Msg) SetUpdate(z string) *Msg
func (dns *Msg) NameUsed(rr []RR)
func (dns *Msg) NameNotUsed(rr []RR)
func (dns *Msg) Used(rr []RR)
func (dns *Msg) RRsetUsed(rr []RR)
func (dns *Msg) RRsetNotUsed(rr []RR)
func (dns *Msg) Insert(rr []RR)
func (dns *Msg) RemoveRRset(rr []RR)
func (dns *Msg) RemoveName(rr []RR)
func (dns *Msg) Remove(rr []RR)Domain name operations, type/class conversions, and other helper functions.
// Domain name operations
func Fqdn(s string) string
func IsFqdn(s string) bool
func CanonicalName(s string) string
func IsDomainName(s string) (labels int, ok bool)
func IsSubDomain(parent, child string) bool
func SplitDomainName(s string) []string
func CountLabel(s string) int
func Split(s string) []int
func CompareDomainName(s1, s2 string) int
func ReverseAddr(addr string) (arpa string, err error)
// Type and class operations
func TypeToString(t uint16) string
func StringToType(s string) (uint16, bool)
func ClassToString(c uint16) string
func StringToClass(s string) (uint16, bool)
// RR utilities
func Copy(r RR) RR
func IsDuplicate(r1, r2 RR) bool
func IsRRset(rrset []RR) boolconst (
DefaultMsgSize = 4096 // Standard default for messages larger than 512 bytes
MinMsgSize = 512 // Minimal size of a DNS packet
MaxMsgSize = 65535 // Largest possible DNS packet
)const (
ClassINET = 1 // Internet
ClassCSNET = 2 // CSNET (obsolete)
ClassCHAOS = 3 // Chaos
ClassHESIOD = 4 // Hesiod
ClassNONE = 254 // None
ClassANY = 255 // Any
)const (
OpcodeQuery = 0 // Standard query
OpcodeIQuery = 1 // Inverse query (obsolete)
OpcodeStatus = 2 // Server status request
OpcodeNotify = 4 // Notify
OpcodeUpdate = 5 // Dynamic update
)const (
RcodeSuccess = 0 // NOERROR - No error
RcodeFormatError = 1 // FORMERR - Format error
RcodeServerFailure = 2 // SERVFAIL - Server failure
RcodeNameError = 3 // NXDOMAIN - Non-existent domain
RcodeNotImplemented = 4 // NOTIMP - Not implemented
RcodeRefused = 5 // REFUSED - Query refused
RcodeYXDomain = 6 // YXDOMAIN - Name exists when it should not
RcodeYXRrset = 7 // YXRRSET - RR set exists when it should not
RcodeNXRrset = 8 // NXRRSET - RR set that should exist does not
RcodeNotAuth = 9 // NOTAUTH - Server not authoritative
RcodeNotZone = 10 // NOTZONE - Name not contained in zone
RcodeStatefulTypeNotImplemented = 11 // DSOTYPENI - DSO-type not implemented
RcodeBadSig = 16 // BADSIG - TSIG signature failure
RcodeBadKey = 17 // BADKEY - Key not recognized
RcodeBadTime = 18 // BADTIME - Signature out of time window
RcodeBadMode = 19 // BADMODE - Bad TKEY mode
RcodeBadName = 20 // BADNAME - Duplicate key name
RcodeBadAlg = 21 // BADALG - Algorithm not supported
RcodeBadTrunc = 22 // BADTRUNC - Bad truncation
RcodeBadCookie = 23 // BADCOOKIE - Bad/missing server cookie
)Utility functions for domain name manipulation.
import "github.com/miekg/dns/dnsutil"
// AddOrigin adds origin to relative domain names
func AddOrigin(s, origin string) string
// TrimDomainName trims origin from absolute domain names
// Returns @ for zone apex
func TrimDomainName(s, origin string) stringThe package defines DNS type codes for all standard resource record types. Use these constants when constructing queries or checking record types:
TypeA, TypeNS, TypeMD, TypeMF, TypeCNAME, TypeSOA, TypeMB, TypeMG,
TypeMR, TypeNULL, TypePTR, TypeHINFO, TypeMINFO, TypeMX, TypeTXT,
TypeRP, TypeAFSDB, TypeX25, TypeISDN, TypeRT, TypeNSAPPTR, TypeSIG,
TypeKEY, TypePX, TypeGPOS, TypeAAAA, TypeLOC, TypeNXT, TypeEID,
TypeNIMLOC, TypeSRV, TypeATMA, TypeNAPTR, TypeKX, TypeCERT, TypeDNAME,
TypeOPT, TypeAPL, TypeDS, TypeSSHFP, TypeIPSECKEY, TypeRRSIG, TypeNSEC,
TypeDNSKEY, TypeDHCID, TypeNSEC3, TypeNSEC3PARAM, TypeTLSA, TypeSMIMEA,
TypeHIP, TypeNINFO, TypeRKEY, TypeTALINK, TypeCDS, TypeCDNSKEY,
TypeOPENPGPKEY, TypeCSYNC, TypeZONEMD, TypeSVCB, TypeHTTPS, TypeSPF,
TypeUINFO, TypeUID, TypeGID, TypeUNSPEC, TypeNID, TypeL32, TypeL64,
TypeLP, TypeEUI48, TypeEUI64, TypeNXNAME, TypeURI, TypeCAA, TypeAVC,
TypeAMTRELAY, TypeRESINFO, TypeTKEY, TypeTSIG, TypeIXFR, TypeAXFR,
TypeMAILB, TypeMAILA, TypeANY, TypeTA, TypeDLV, TypeReservedSee Complete Type Reference for details on each record type structure and usage.
DNS library error constants.
var (
ErrAlg error // Unsupported algorithm
ErrAuth error // Authentication failed
ErrBuf error // Buffer size too small
ErrConnEmpty error // Connection is nil or not initialized
ErrExtendedRcode error // Extended rcode error
ErrFqdn error // Domain must be fully qualified
ErrId error // Message ID mismatch
ErrKey error // Key error
ErrKeyAlg error // Unsupported key algorithm
ErrKeySize error // Invalid key size
ErrLongDomain error // Domain name too long
ErrNoSig error // No signature found
ErrPrivKey error // Private key error
ErrRcode error // Response code error
ErrRdata error // Bad rdata
ErrRRset error // RRset error
ErrSecret error // Secret key error
ErrShortRead error // Short read from connection
ErrSig error // Signature error
ErrSoa error // SOA record error
ErrTime error // Time error
)Message ID generator (can be replaced for testing).
// Id generates a 16-bit random identifier for DNS messages
// Can be reassigned for testing or custom ID generation
var Id func() uint16Library version information.
var Version struct {
Major int
Minor int
Patch int
}