Documentation ¶
Overview ¶
DOMAIN NAME SYSTEM
Package dns implements a full featured interface to the Domain Name System. The package allows complete control over what is send out to the DNS.
Resource records are native types. They are not stored in wire format. Basic usage pattern for creating a new resource record:
r := new(RR_TXT) r.Hdr = RR_Header{Name: "a.miek.nl.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 3600} r.TXT = "This is the content of the TXT record"
Or directly from a string:
mx := NewRR("miek.nl. IN MX 10 mx.miek.nl.")
The package dns supports (async) querying/replying, incoming/outgoing Axfr/Ixfr, TSIG, EDNS0, dynamic updates, notifies and DNSSEC validation/signing. Note that domain names MUST be full qualified, before sending them. The packages enforces this, by throwing a panic().
In the DNS messages are exchanged. Use pattern for creating one:
m := new(Msg) m.SetQuestion("miek.nl.", TypeMX)
The message m is now a message with the question section set to ask the MX records for the miek.nl. zone.
The following is slightly more verbose, but more flexible:
m1 := new(Msg) m1.MsgHdr.Id = Id() m1.MsgHdr.RecursionDesired = false m1.Question = make([]Question, 1) m1.Question[0] = Question{"miek.nl.", TypeMX, ClassINET}
After creating a message it can be send. Basic use pattern for synchronous querying the DNS:
// We are sending the message 'm' to the server 127.0.0.1 // on port 53 and wait for the reply. c := NewClient() // c.Net = "tcp" // If you want to use TCP in := c.Exchange(m, "127.0.0.1:53")
An asynchronous query is also possible, setting up is more elaborate then a synchronous query. The Basic use pattern is:
HandleQueryFunc(".", handler) ListenAndQuery(nil, nil) c.Do(m1, "127.0.0.1:53") // Do something else r := <- DefaultReplyChan // r.Reply is the answer // r.Request is the original request
DNSSEC ¶
DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It uses public key cryptography to securely sign resource records. The public keys are stored in DNSKEY records and the signatures in RRSIG records.
TRANSACTION SIGNATURE (TSIG)
A TSIG or transaction signature adds a HMAC TSIG record to each message sent. Basic use pattern when querying with TSIG:
m := new(Msg) m.SetAxfr("miek.nl.") // Add a skeleton TSIG record. m.SetTsig("axfr.", HmacMD5, 300, uint64(time.Seconds())) // Generate the contents of the complete TSIG record. TsigGenerate(m, "so6ZGir4GPAqINNh9U5c3A==", "", false) // A map holds all the secrets secrets := make(map[string]string) secrets["axfr."] = "so6ZGir4GPAqINNh9U5c3A==" // don't forget the . here
The secrets' map index is set to 'axfr.'. This must match the ownername of the TSIG record, which in the above example, is also set to 'axfr.'
The message requesting an AXFR (almost all TSIG usage is when requesting zone transfers) for miek.nl with the TSIG record added is now ready to use. We now need a new client with access to the secrets:
c := NewClient() c.TsigSecret = secrets err := c.XfrReceive(m, "85.223.71.124:53")
You can now read the records from the AXFR as they come in. Each envelope is checked with TSIG. If something is not correct an error is returned.
Basic use pattern replying to a message that has TSIG set. TODO(mg)
DYNAMIC UPDATES ¶
Dynamic updates reuses the DNS message format, but renames three of the sections. Question is Zone, Answer is Prerequisite, Authority is Update, only the Additional is not renamed. See RFC 2136 for the gory details.
You can set a rather complex set of rules for the existence of absence of certain resource records or names in a zone to specify if resource records should be added or removed. The table from RFC 2136 supplemented with the Go DNS function shows which functions exist to specify the prerequisites.
3.2.4 - Table Of Metavalues Used In Prerequisite Section
CLASS TYPE RDATA Meaning Function -------------------------------------------------------------- ANY ANY empty Name is in use NameUsed ANY rrset empty RRset exists (value indep) RRsetUsedNoRdata NONE ANY empty Name is not in use NameNotUsed NONE rrset empty RRset does not exist RRsetNotUsed zone rrset rr RRset exists (value dep) RRsetUsedRdata
The prerequisite section can also be left empty. If you have decided on the prerequisites you can tell what RRs should be added or deleted. The next table shows the options you have and what functions to call.
3.4.2.6 - Table Of Metavalues Used In Update Section
CLASS TYPE RDATA Meaning Function --------------------------------------------------------------- ANY ANY empty Delete all RRsets from name NameDelete ANY rrset empty Delete an RRset RRsetDelete NONE rrset rr Delete an RR from RRset RRsetDeleteRR zone rrset rr Add to an RRset RRsetAddRdata
Index ¶
- Constants
- Variables
- func CompareLabels(s1, s2 string) (n int)
- func Fqdn(s string) string
- func Handle(pattern string, handler Handler)
- func HandleFunc(pattern string, handler func(ResponseWriter, *Msg))
- func HandleQueryFunc(pattern string, handler func(RequestWriter, *Msg))
- func HashName(label string, ha uint8, iter uint16, salt string) string
- func Id() uint16
- func IsDomainName(s string) (uint8, bool)
- func IsFqdn(s string) bool
- func ListenAndQuery(request chan *Request, handler QueryHandler)
- func ListenAndServe(addr string, network string, handler Handler, size int) error
- func PackDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, ok bool)
- func ParseZone(r io.Reader, file string) chan Token
- func RawSetId(msg []byte, off int, id uint16) bool
- func RawSetRdlength(msg []byte, off, end int) bool
- func Refused(w ResponseWriter, r *Msg)
- func SplitLabels(s string) []string
- func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) error
- func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error
- func UnpackDomainName(msg []byte, off int) (s string, off1 int, ok bool)
- func XfrSend(w ResponseWriter, q *Msg, a string) error
- type Client
- type ClientConfig
- type Error
- type Exchange
- type Handler
- type HandlerFunc
- type HandlerQueryFunc
- type Header
- type Msg
- func (dns *Msg) CompressedLen() int
- func (dns *Msg) IsAxfr() (ok bool)
- func (dns *Msg) IsEdns0() (ok bool)
- func (dns *Msg) IsIxfr() (ok bool)
- func (dns *Msg) IsNotify() (ok bool)
- func (dns *Msg) IsQuestion() (ok bool)
- func (dns *Msg) IsRcode(rcode int) (ok bool)
- func (dns *Msg) IsRcodeFormatError() (ok bool)
- func (dns *Msg) IsTsig() (ok bool)
- func (dns *Msg) IsUpdate() (ok bool)
- func (dns *Msg) Len() int
- func (u *Msg) NameDelete(rr []RR)
- func (u *Msg) NameNotUsed(rr []RR)
- func (u *Msg) NameUsed(rr []RR)
- func (m *Msg) Nsec3Verify(q Question) (int, error)
- func (m *Msg) NsecVerify(q Question) error
- func (dns *Msg) Pack() (msg []byte, ok bool)
- func (u *Msg) RRsetAddRdata(rr []RR)
- func (u *Msg) RRsetDelete(rr []RR)
- func (u *Msg) RRsetDeleteRR(rr []RR)
- func (u *Msg) RRsetNotUsed(rr []RR)
- func (u *Msg) RRsetUsedNoRdata(rr []RR)
- func (u *Msg) RRsetUsedRdata(rr []RR)
- func (dns *Msg) SetAxfr(z string)
- func (dns *Msg) SetEdns0(udpsize uint16, do bool)
- func (dns *Msg) SetIxfr(z string, serial uint32)
- func (dns *Msg) SetNotify(z string)
- func (dns *Msg) SetQuestion(z string, t uint16)
- func (dns *Msg) SetRcode(request *Msg, rcode int)
- func (dns *Msg) SetRcodeFormatError(request *Msg)
- func (dns *Msg) SetReply(request *Msg)
- func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned uint64)
- func (dns *Msg) SetUpdate(z string)
- func (dns *Msg) String() string
- func (dns *Msg) Unpack(msg []byte) bool
- type MsgHdr
- type Option
- type ParseError
- type PrivateKey
- type Query
- type QueryHandler
- type QueryMux
- type Question
- type RR
- type RR_A
- type RR_AAAA
- type RR_ANY
- type RR_CERT
- type RR_CNAME
- type RR_DHCID
- type RR_DLV
- type RR_DNAME
- type RR_DNSKEY
- func (r *RR_DNSKEY) Generate(bits int) (PrivateKey, error)
- func (rr *RR_DNSKEY) Header() *RR_Header
- func (k *RR_DNSKEY) KeyTag() uint16
- func (rr *RR_DNSKEY) Len() int
- func (r *RR_DNSKEY) PrivateKeyString(p PrivateKey) (s string)
- func (rr *RR_DNSKEY) String() string
- func (k *RR_DNSKEY) ToDS(h int) *RR_DS
- type RR_DS
- type RR_HINFO
- type RR_Header
- type RR_KX
- type RR_LOC
- type RR_MB
- type RR_MG
- type RR_MINFO
- type RR_MR
- type RR_MX
- type RR_NAPTR
- type RR_NS
- type RR_NSEC
- type RR_NSEC3
- type RR_NSEC3PARAM
- type RR_OPT
- func (rr *RR_OPT) Do() bool
- func (rr *RR_OPT) Header() *RR_Header
- func (rr *RR_OPT) Len() int
- func (rr *RR_OPT) Nsid() string
- func (rr *RR_OPT) SetDo()
- func (rr *RR_OPT) SetNsid(hexnsid string)
- func (rr *RR_OPT) SetUDPSize(size uint16)
- func (rr *RR_OPT) SetVersion(v uint8)
- func (rr *RR_OPT) String() string
- func (rr *RR_OPT) UDPSize() uint16
- func (rr *RR_OPT) Version() uint8
- type RR_PTR
- type RR_RFC3597
- type RR_RRSIG
- type RR_SOA
- type RR_SPF
- type RR_SRV
- type RR_SSHFP
- type RR_TA
- type RR_TALINK
- type RR_TKEY
- type RR_TLSA
- type RR_TSIG
- type RR_TXT
- type RR_URI
- type RRset
- type Request
- type RequestWriter
- type ResponseWriter
- type ServeMux
- type Server
- type Token
Constants ¶
const ( Year68 = 1 << 32 // For RFC1982 (Serial Arithmetic) calculations in 32 bits. DefaultMsgSize = 4096 // Standard default for larger than 512 packets. UDPReceiveMsgSize = 360 // Default buffer size for servers receiving UDP packets. MaxMsgSize = 65536 // Largest possible DNS packet. DefaultTtl = 3600 // Default TTL. )
const ( RSAMD5 = 1 DH = 2 DSA = 3 ECC = 4 RSASHA1 = 5 DSANSEC3SHA1 = 6 RSASHA1NSEC3SHA1 = 7 RSASHA256 = 8 RSASHA512 = 10 ECCGOST = 12 ECDSAP256SHA256 = 13 ECDSAP384SHA384 = 14 PRIVATEDNS = 253 // Private (experimental keys) PRIVATEOID = 254 )
DNSSEC encryption algorithm codes.
const ( SHA1 // RFC 4034 SHA256 // RFC 4509 GOST94 // RFC 5933 SHA384 // Experimental )
DNSSEC hashing algorithm codes.
const ( SEP = 1 ZONE = 1 << 7 REVOKE = 1 << 8 )
DNSKEY flag values.
const ( OptionCodeLLQ // not used OptionCodeUL // not used OptionCodeNSID // NSID, RFC5001 )
EDNS0 Option codes.
const ( NSEC3_NXDOMAIN NSEC3_NODATA )
const ( HmacMD5 = "hmac-md5.sig-alg.reg.int." HmacSHA1 = "hmac-sha1." HmacSHA256 = "hmac-sha256." )
HMAC hashing codes. These are transmitted as domain names.
const ( // valid RR_Header.Rrtype and Question.qtype TypeA uint16 = 1 TypeNS uint16 = 2 TypeMD uint16 = 3 TypeMF uint16 = 4 TypeCNAME uint16 = 5 TypeSOA uint16 = 6 TypeMB uint16 = 7 TypeMG uint16 = 8 TypeMR uint16 = 9 TypeNULL uint16 = 10 TypeWKS uint16 = 11 TypePTR uint16 = 12 TypeHINFO uint16 = 13 TypeMINFO uint16 = 14 TypeMX uint16 = 15 TypeTXT uint16 = 16 TypeAAAA uint16 = 28 TypeLOC uint16 = 29 TypeSRV uint16 = 33 TypeNAPTR uint16 = 35 TypeKX uint16 = 36 TypeCERT uint16 = 37 TypeDNAME uint16 = 39 // EDNS TypeOPT uint16 = 41 TypeSIG uint16 = 24 TypeKEY uint16 = 25 TypeNXT uint16 = 30 TypeDS uint16 = 43 TypeSSHFP uint16 = 44 TypeIPSECKEY uint16 = 45 // No type implemented TypeRRSIG uint16 = 46 TypeNSEC uint16 = 47 TypeDNSKEY uint16 = 48 TypeDHCID uint16 = 49 TypeNSEC3 uint16 = 50 TypeNSEC3PARAM uint16 = 51 TypeTALINK uint16 = 58 TypeSPF uint16 = 99 TypeTKEY uint16 = 249 TypeTSIG uint16 = 250 // valid Question.Qtype only TypeIXFR uint16 = 251 TypeAXFR uint16 = 252 TypeMAILB uint16 = 253 TypeMAILA uint16 = 254 TypeANY uint16 = 255 TypeURI uint16 = 256 TypeTA uint16 = 32768 TypeDLV uint16 = 32769 TypeTLSA uint16 = 65468 // Experimental // valid Question.Qclass ClassINET = 1 ClassCSNET = 2 ClassCHAOS = 3 ClassHESIOD = 4 ClassNONE = 254 ClassANY = 255 // Msg.rcode RcodeSuccess = 0 RcodeFormatError = 1 RcodeServerFailure = 2 RcodeNameError = 3 RcodeNotImplemented = 4 RcodeRefused = 5 RcodeYXDomain = 6 RcodeYXRrset = 7 RcodeNXRrset = 8 RcodeNotAuth = 9 RcodeNotZone = 10 RcodeBadSig = 16 // TSIG RcodeBadKey = 17 RcodeBadTime = 18 RcodeBadMode = 19 // TKEY RcodeBadName = 20 RcodeBadAlg = 21 RcodeBadTrunc = 22 // TSIG // Opcode OpcodeQuery = 0 OpcodeIQuery = 1 OpcodeStatus = 2 // There is no 3 OpcodeNotify = 4 OpcodeUpdate = 5 )
Wire constants and supported types.
Variables ¶
var ( // DefaultReplyChan is the channel on which the replies are // coming back. Is it a channel of *Exchange, so that the original // question is included with the answer. DefaultReplyChan = newQueryChanSlice() // DefaultQueryChan is the channel were you can send the questions to. DefaultQueryChan = newQueryChan() )
Default channels to use for the resolver
var ( ErrUnpack error = &Error{Err: "unpacking failed"} ErrPack error = &Error{Err: "packing failed"} ErrId error = &Error{Err: "id mismatch"} ErrShortRead error = &Error{Err: "short read"} ErrConn error = &Error{Err: "conn holds both UDP and TCP connection"} ErrConnEmpty error = &Error{Err: "conn has no connection"} ErrServ error = &Error{Err: "no servers could be reached"} ErrKey error = &Error{Err: "bad key"} ErrPrivKey error = &Error{Err: "bad private key"} ErrKeySize error = &Error{Err: "bad key size"} ErrKeyAlg error = &Error{Err: "bad key algorithm"} ErrAlg error = &Error{Err: "bad algorithm"} ErrTime error = &Error{Err: "bad time"} ErrNoSig error = &Error{Err: "no signature found"} ErrSig error = &Error{Err: "bad signature"} ErrSecret error = &Error{Err: "no secret defined"} ErrSigGen error = &Error{Err: "bad signature generation"} ErrAuth error = &Error{Err: "bad authentication"} ErrXfrSoa error = &Error{Err: "no SOA seen"} ErrXfrLast error = &Error{Err: "last SOA"} ErrXfrType error = &Error{Err: "no ixfr, nor axfr"} ErrHandle error = &Error{Err: "handle is nil"} ErrChan error = &Error{Err: "channel is nil"} ErrName error = &Error{Err: "type not found for name"} ErrRRset error = &Error{Err: "invalid rrset"} ErrDenialNsec3 error = &Error{Err: "no NSEC3 records"} ErrDenialCe error = &Error{Err: "no matching closest encloser found"} ErrDenialNc error = &Error{Err: "no covering NSEC3 found for next closer"} ErrDenialSo error = &Error{Err: "no covering NSEC3 found for source of synthesis"} ErrDenialBit error = &Error{Err: "type not denied in NSEC3 bitmap"} )
var Alg_str = map[uint8]string{ RSAMD5: "RSAMD5", DH: "DH", DSA: "DSA", RSASHA1: "RSASHA1", DSANSEC3SHA1: "DSA-NSEC3-SHA1", RSASHA1NSEC3SHA1: "RSASHA1-NSEC3-SHA1", RSASHA256: "RSASHA256", RSASHA512: "RSASHA512", ECCGOST: "ECC-GOST", ECDSAP256SHA256: "ECDSAP256SHA256", ECDSAP384SHA384: "ECDSAP384SHA384", PRIVATEDNS: "PRIVATEDNS", PRIVATEOID: "PRIVATEOID", }
Map for algorithm names.
var Class_str = map[uint16]string{
ClassINET: "IN",
ClassCSNET: "CS",
ClassCHAOS: "CH",
ClassHESIOD: "HS",
ClassNONE: "NONE",
ClassANY: "ANY",
}
Map of strings for each CLASS wire type.
var DefaultQueryMux = NewQueryMux()
DefaultQueryMux is the default QueryMux used by Query.
var DefaultServeMux = NewServeMux()
DefaultServeMux is the default ServeMux used by Serve.
var Opcode_str = map[int]string{
OpcodeQuery: "QUERY",
OpcodeIQuery: "IQUERY",
OpcodeStatus: "STATUS",
OpcodeNotify: "NOTIFY",
OpcodeUpdate: "UPDATE",
}
Map of strings for opcodes.
var Rcode_str = map[int]string{
RcodeSuccess: "NOERROR",
RcodeFormatError: "FORMERR",
RcodeServerFailure: "SERVFAIL",
RcodeNameError: "NXDOMAIN",
RcodeNotImplemented: "NOTIMPL",
RcodeRefused: "REFUSED",
RcodeYXDomain: "YXDOMAIN",
RcodeYXRrset: "YXRRSET",
RcodeNXRrset: "NXRRSET",
RcodeNotAuth: "NOTAUTH",
RcodeNotZone: "NOTZONE",
}
Map of strings for rcodes.
var Rr_str = map[uint16]string{
TypeCNAME: "CNAME",
TypeHINFO: "HINFO",
TypeMB: "MB",
TypeMG: "MG",
TypeMINFO: "MINFO",
TypeMR: "MR",
TypeMX: "MX",
TypeNS: "NS",
TypePTR: "PTR",
TypeSOA: "SOA",
TypeTXT: "TXT",
TypeSRV: "SRV",
TypeNAPTR: "NAPTR",
TypeKX: "KX",
TypeCERT: "CERT",
TypeDNAME: "DNAME",
TypeA: "A",
TypeAAAA: "AAAA",
TypeLOC: "LOC",
TypeOPT: "OPT",
TypeDS: "DS",
TypeDHCID: "DHCID",
TypeIPSECKEY: "IPSECKEY",
TypeSSHFP: "SSHFP",
TypeRRSIG: "RRSIG",
TypeNSEC: "NSEC",
TypeDNSKEY: "DNSKEY",
TypeNSEC3: "NSEC3",
TypeNSEC3PARAM: "NSEC3PARAM",
TypeTALINK: "TALINK",
TypeSPF: "SPF",
TypeTKEY: "TKEY",
TypeTSIG: "TSIG",
TypeAXFR: "AXFR",
TypeIXFR: "IXFR",
TypeANY: "ANY",
TypeURI: "URI",
TypeTA: "TA",
TypeDLV: "DLV",
}
Map of strings for each RR wire type.
var Str_class = reverseInt16(Class_str)
var Str_opcode = reverseInt(Opcode_str)
Map of opcodes strings.
var Str_rcode = reverseInt(Rcode_str)
Map of rcodes strings.
var Str_rr = reverseInt16(Rr_str)
Reverse, needed for string parsing.
Functions ¶
func CompareLabels ¶
CompareLabels compares the strings s1 and s2 and returns how many labels they have in common starting from the right. The comparison stops at the first inequality.
www.miek.nl and miek.nl have two labels in common: miek and nl www.miek.nl and www.bla.nl have one label in common: nl
func Fqdn ¶
Fqdns return the fully qualified domain name from s. Is s is already fq, then it behaves as the identity function.
func Handle ¶
Handle register the handler the given pattern in the DefaultServeMux. The documentation for ServeMux explains how patters are matched.
func HandleFunc ¶
func HandleFunc(pattern string, handler func(ResponseWriter, *Msg))
func HandleQueryFunc ¶
func HandleQueryFunc(pattern string, handler func(RequestWriter, *Msg))
func HashName ¶
HashName hashes a string (label) according to RFC5155. It returns the hashed string.
func Id ¶
func Id() uint16
Id return a 16 bits random number to be used as a message id. The random provided should be good enough.
func IsDomainName ¶
IsDomainName checks if s is a valid domainname, it returns the number of labels and true, when a domain name is valid. When false the returned labelcount isn't specified.
func ListenAndQuery ¶
func ListenAndQuery(request chan *Request, handler QueryHandler)
ListenAndQuery starts the listener for firing off the queries. If c is nil DefaultQueryChan is used. If handler is nil DefaultQueryMux is used.
func ListenAndServe ¶
...
func PackDomainName ¶
func PackDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, ok bool)
PackDomainName packs a domain name s into msg[off:]. If compression is wanted compress must be true and the compression map, needs to hold a mapping between domain names and offsets pointing into msg[].
func ParseZone ¶
ParseZone reads a RFC 1035 zone from r. It returns each parsed RR or on error on the returned channel. The channel t is closed by ParseZone when the end of r is reached.
func RawSetId ¶
RawSetId sets the message ID in buf. The offset 'off' must be positioned at the beginning of the message.
func RawSetRdlength ¶
RawSetRdlength sets the rdlength in the header of the RR. The offset 'off' must be positioned at the start of the header of the RR, 'end' must be the end of the RR.
func Refused ¶
func Refused(w ResponseWriter, r *Msg)
Helper handler that returns an answer with RCODE = refused for every request.
func SplitLabels ¶
SplitLabels splits a domainname string into its labels.
func TsigGenerate ¶
TsigGenerate adds an TSIG RR to a message. The TSIG MAC is saved in the Tsig RR that is added. When TsigGenerate is called for the first time requestMAC is set to the empty string. If something goes wrong an error is returned, otherwise it is nil.
func TsigVerify ¶
TsigVerify verifies the TSIG on a message. If the signature does not validate err contains the error, otherwise it is nil.
func UnpackDomainName ¶
UnpackDomainName unpack a domain name.
Types ¶
type Client ¶
type Client struct { Net string // if "tcp" a TCP query will be initiated, otherwise an UDP one Attempts int // number of attempts Retry bool // retry with TCP QueryChan chan *Request // read DNS request from this channel ReplyChan chan *Exchange // write the reply (together with the DNS request) to this channel ReadTimeout time.Duration // the net.Conn.SetReadTimeout value for new connections (ns) WriteTimeout time.Duration // the net.Conn.SetWriteTimeout value for new connections (ns) TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret> Hijacked net.Conn // if set the calling code takes care of the connection }
func NewClient ¶
func NewClient() *Client
NewClient creates a new client, with Net set to "udp" and Attempts to 1. The client's ReplyChan is set to DefaultReplyChan and QueryChan to DefaultQueryChan.
func (*Client) Do ¶
Do performs an asynchronous query. The result is returned on the QueryChan channel set in the Client c.
func (*Client) Exchange ¶
Exchange performs an synchronous query. It sends the message m to the address contained in a and waits for an reply.
func (*Client) ExchangeBuffer ¶
ExchangeBuffer performs a synchronous query. It sends the buffer m to the address contained in a.
func (*Client) XfrReceive ¶
XfrReceives requests an incoming Ixfr or Axfr. If the message q's question section contains an AXFR type an Axfr is performed, if it is IXFR it does an Ixfr. Each message will be send along the Client's reply channel as it is received. The last message send has Exchange.Error set to ErrXfrLast to signal there is nothing more to come.
type ClientConfig ¶
type ClientConfig struct { Servers []string // servers to use Search []string // suffixes to append to local name Port string // what port to use Ndots int // number of dots in name to trigger absolute lookup Timeout int // seconds before giving up on packet Attempts int // lost packets before giving up on server }
Wraps the contents of the /etc/resolv.conf.
func ClientConfigFromFile ¶
func ClientConfigFromFile(conf string) (*ClientConfig, error)
ClientConfigFromFile parses a resolv.conf(5) like file and returns a *ClientConfig.
type Exchange ¶
type Exchange struct { Request *Msg // The question sent. Reply *Msg // The answer to the question that was sent. Error error // If something went wrong, this contains the error. }
Exchange is used in communicating with the resolver.
type Handler ¶
type Handler interface {
ServeDNS(w ResponseWriter, r *Msg)
}
func RefusedHandler ¶
func RefusedHandler() Handler
RefusedHandler returns HandlerFunc with Refused.
type HandlerFunc ¶
type HandlerFunc func(ResponseWriter, *Msg)
The HandlerFunc type is an adapter to allow the use of ordinary functions as DNS handlers. If f is a function with the appropriate signature, HandlerFunc(f) is a Handler object that calls f.
func (HandlerFunc) ServeDNS ¶
func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg)
ServerDNS calls f(w, r)
type HandlerQueryFunc ¶
type HandlerQueryFunc func(RequestWriter, *Msg)
The HandlerQueryFunc type is an adapter to allow the use of ordinary functions as DNS query handlers. If f is a function with the appropriate signature, HandlerQueryFunc(f) is a QueryHandler object that calls f.
func (HandlerQueryFunc) QueryDNS ¶
func (f HandlerQueryFunc) QueryDNS(w RequestWriter, r *Msg)
QueryDNS calls f(w, reg)
type Msg ¶
type Msg struct { MsgHdr Compress bool // If true, the message will be compressed when converted to wire format. Question []Question Answer []RR Ns []RR Extra []RR }
The layout of a DNS message.
func NewUpdate ¶
NewUpdate creates a new DNS update packet. This returns a normal dns *Msg, but sets some options.
func (*Msg) CompressedLen ¶
CompressedLen returns the length of the message when in compressed wire format.
func (*Msg) IsEdns0 ¶
IsEdns0 checks if the message has a Edns0 record, any EDNS0 record in the additional section will do
func (*Msg) IsQuestion ¶
IsQuestion returns true if the packet is a question.
func (*Msg) IsRcodeFormatError ¶
IsRcodeFormatError checks if the message has FormErr set.
func (*Msg) IsTsig ¶
IsTsig checks if the message has a TSIG record as the last record in the additional section.
func (*Msg) NameDelete ¶
NameDelete deletes all RRsets of a name, see RFC 2136 section 2.5.3
func (*Msg) NameNotUsed ¶
NameNotUsed sets the RRs in the prereq section to "Name is in not use" RRs. RFC 2136 section 2.4.5.
func (*Msg) NameUsed ¶
NameUsed sets the RRs in the prereq section to "Name is in use" RRs. RFC 2136 section 2.4.4.
func (*Msg) Nsec3Verify ¶
Nsec3Verify verifies an denial of existence response with NSEC3s. This function does not validate the NSEC3s.
func (*Msg) NsecVerify ¶
NsecVerify verifies an denial of existence response with NSECs NsecVerify returns nil when the NSECs in the message contain the correct proof. This function does not validates the NSECs.
func (*Msg) RRsetAddRdata ¶
RRsetAddRdata adds an complete RRset, see RFC 2136 section 2.5.1
func (*Msg) RRsetDelete ¶
RRsetDelete deletes an RRset, see RFC 2136 section 2.5.2
func (*Msg) RRsetDeleteRR ¶
RRsetDeleteRR deletes RR from the RRSset, see RFC 2136 section 2.5.4
func (*Msg) RRsetNotUsed ¶
RRsetNotUsed sets the RRs in the prereq section to "RRset does not exist" RRs. RFC 2136 section 2.4.3.
func (*Msg) RRsetUsedNoRdata ¶
RRsetUsedNoRdata sets the RRs in the prereq section to "RRset exists (value independent -- no rdata)" RRs. RFC 2136 section 2.4.1.
func (*Msg) RRsetUsedRdata ¶
RRsetUsedRdata sets the RRs in the prereq section to "RRset exists (value dependent -- with rdata)" RRs. RFC 2136 section 2.4.2.
func (*Msg) SetEdns0 ¶
SetEdns0 appends a EDNS0 OPT RR to the message. TSIG should always the last RR in a message.
func (*Msg) SetQuestion ¶
SetQuestion creates a question packet.
func (*Msg) SetRcodeFormatError ¶
SetRcodeFormatError creates a packet with FormError set.
func (*Msg) SetTsig ¶
SetTsig appends a TSIG RR to the message. This is only a skeleton Tsig RR that is added as the last RR in the additional section. The caller should then call TsigGenerate, to generate the complete TSIG with the secret.
func (*Msg) SetUpdate ¶
SetUpdate makes the message a dynamic update packet. It sets the ZONE section to: z, TypeSOA, classINET.
type MsgHdr ¶
type MsgHdr struct { Id uint16 Response bool Opcode int Authoritative bool Truncated bool RecursionDesired bool RecursionAvailable bool Zero bool AuthenticatedData bool CheckingDisabled bool Rcode int }
A manually-unpacked version of (id, bits). This is in its own struct for easy printing.
type ParseError ¶
type ParseError struct {
// contains filtered or unexported fields
}
ParseError contains the parse error and the location in the io.Reader where the error occured.
func (*ParseError) Error ¶
func (e *ParseError) Error() (s string)
type PrivateKey ¶
type PrivateKey interface{}
Empty interface that is used as a wrapper around all possible private key implementations from the crypto package.
func ReadPrivateKey ¶
func ReadPrivateKey(q io.Reader, file string) (PrivateKey, error)
ReadPrivateKey reads a private key from the io.Reader q.
type Query ¶
type Query struct { QueryChan chan *Request // read DNS request from this channel Handler QueryHandler // handler to invoke, dns.DefaultQueryMux if nil }
func (*Query) ListenAndQuery ¶
type QueryHandler ¶
type QueryHandler interface {
QueryDNS(w RequestWriter, q *Msg)
}
Incoming (just as in os.Signal)
type QueryMux ¶
type QueryMux struct {
// contains filtered or unexported fields
}
QueryMux is an DNS request multiplexer. It matches the zone name of each incoming request against a list of registered patterns add calls the handler for the pattern that most closely matches the zone name.
func (*QueryMux) Handle ¶
func (mux *QueryMux) Handle(pattern string, handler QueryHandler)
func (*QueryMux) HandleQueryFunc ¶
func (mux *QueryMux) HandleQueryFunc(pattern string, handler func(RequestWriter, *Msg))
func (*QueryMux) QueryDNS ¶
func (mux *QueryMux) QueryDNS(w RequestWriter, r *Msg)
type Question ¶
type Question struct { Name string "cdomain-name" // "cdomain-name" specifies encoding (and may be compressed) Qtype uint16 Qclass uint16 }
DNS queries.
type RR ¶
type RR_CERT ¶
type RR_CERT struct { Hdr RR_Header Type uint16 KeyTag uint16 Algorithm uint8 Certificate string "base64" }
See RFC 4398.
type RR_DLV ¶
type RR_DNSKEY ¶
type RR_DNSKEY struct { Hdr RR_Header Flags uint16 Protocol uint8 Algorithm uint8 PublicKey string "base64" }
func (*RR_DNSKEY) Generate ¶
func (r *RR_DNSKEY) Generate(bits int) (PrivateKey, error)
Generate generates a DNSKEY of the given bit size. The public part is put inside the DNSKEY record. The Algorithm in the key must be set as this will define what kind of DNSKEY will be generated. The ECDSA algorithms imply a fixed keysize, in that case bits should be set to the size of the algorithm.
func (*RR_DNSKEY) PrivateKeyString ¶
func (r *RR_DNSKEY) PrivateKeyString(p PrivateKey) (s string)
PrivateKeyString converts a PrivateKey to a string. This string has the same format as the private-key-file of BIND9 (Private-key-format: v1.3). It needs some info from the key (hashing, keytag), so its a method of the RR_DNSKEY.
type RR_DS ¶
type RR_Header ¶
type RR_Header struct { Name string "cdomain-name" Rrtype uint16 Class uint16 Ttl uint32 Rdlength uint16 // length of data after header }
DNS resource records. There are many types of messages, but they all share the same header.
type RR_LOC ¶
type RR_NAPTR ¶
type RR_NSEC3 ¶
type RR_NSEC3 struct { Hdr RR_Header Hash uint8 Flags uint8 Iterations uint16 SaltLength uint8 Salt string "size-hex" HashLength uint8 NextDomain string "size-base32" TypeBitMap []uint16 "NSEC" }
func (*RR_NSEC3) Cover ¶
Cover checks if domain is covered by the NSEC3 record, domain must be given in plain text.
func (*RR_NSEC3) HashNames ¶
HashNames hashes the ownername and the next owner name in an NSEC3 record according to RFC 5155. It uses the paramaters as set in the NSEC3 record. The string zone is appended to the hashed ownername.
type RR_NSEC3PARAM ¶
type RR_NSEC3PARAM struct { Hdr RR_Header Hash uint8 Flags uint8 Iterations uint16 SaltLength uint8 Salt string "hex" // hexsize?? }
func (*RR_NSEC3PARAM) Header ¶
func (rr *RR_NSEC3PARAM) Header() *RR_Header
func (*RR_NSEC3PARAM) Len ¶
func (rr *RR_NSEC3PARAM) Len() int
func (*RR_NSEC3PARAM) String ¶
func (rr *RR_NSEC3PARAM) String() string
type RR_OPT ¶
Adding an EDNS0 record to a message is done as follows:
opt := new(RR_OPT) opt.Hdr = dns.RR_Header{Name: "", Rrtype: TypeOPT} opt.SetVersion(0) // set version to zero opt.SetDo() // set the DO bit opt.SetUDPSize(4096) // set the message size m.Extra = make([]RR, 1) m.Extra[0] = opt // add OPT RR to the message
func (*RR_OPT) SetNsid ¶
SetNsid sets the NSID from a hex character string. Use the empty string when requesting an NSID.
func (*RR_OPT) SetUDPSize ¶
SetUDPSize sets the UDP buffer size.
func (*RR_OPT) SetVersion ¶
SetVersion sets the version of EDNS. This is usually zero.
type RR_RFC3597 ¶
Unknown RR representation
func (*RR_RFC3597) Header ¶
func (rr *RR_RFC3597) Header() *RR_Header
func (*RR_RFC3597) Len ¶
func (rr *RR_RFC3597) Len() int
func (*RR_RFC3597) String ¶
func (rr *RR_RFC3597) String() string
type RR_RRSIG ¶
type RR_RRSIG struct { Hdr RR_Header TypeCovered uint16 Algorithm uint8 Labels uint8 OrigTtl uint32 Expiration uint32 Inception uint32 KeyTag uint16 SignerName string "domain-name" Signature string "base64" }
func (*RR_RRSIG) Sign ¶
func (s *RR_RRSIG) Sign(k PrivateKey, rrset RRset) error
Sign signs an RRSet. The signature needs to be filled in with the values: Inception, Expiration, KeyTag, SignerName and Algorithm. The rest is copied from the RRset. Sign returns true when the signing went OK, otherwise false. The signature data in the RRSIG is filled by this method. There is no check if RRSet is a proper (RFC 2181) RRSet.
func (*RR_RRSIG) ValidityPeriod ¶
ValidityPeriod uses RFC1982 serial arithmetic to calculate if a signature period is valid.
type RR_SOA ¶
type RR_SRV ¶
type RR_TA ¶
type RR_TKEY ¶
type RR_TLSA ¶
type RR_TLSA struct { Hdr RR_Header Usage uint8 Selector uint8 MatchingType uint8 Certificate string "hex" }
DANE
type RR_TSIG ¶
type RRset ¶
type RRset []RR
An RRset is a slice of RRs.
type RequestWriter ¶
type RequestWriter interface { Write(*Msg) Send(*Msg) error Receive() (*Msg, error) Close() error Dial() error }
The RequestWriter interface is used by a DNS query handler to construct a DNS request.
type ResponseWriter ¶
type ResponseWriter interface { // RemoteAddr returns the net.Addr of the client that sent the current request. RemoteAddr() net.Addr // Write a reply back to the client. Write([]byte) (int, error) }
A ResponseWriter interface is used by an DNS handler to construct an DNS response.
type ServeMux ¶
type ServeMux struct {
// contains filtered or unexported fields
}
ServeMux is an DNS request multiplexer. It matches the zone name of each incoming request against a list of registered patterns add calls the handler for the pattern that most closely matches the zone name.
func (*ServeMux) HandleFunc ¶
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg))
func (*ServeMux) ServeDNS ¶
func (mux *ServeMux) ServeDNS(w ResponseWriter, request *Msg)
ServeDNS dispatches the request to the handler whose pattern most closely matches the request message.
type Server ¶
type Server struct { Addr string // address to listen on, ":dns" if empty Net string // if "tcp" it will invoke a TCP listener, otherwise an UDP one Handler Handler // handler to invoke, dns.DefaultServeMux if nil UDPSize int // default buffer to use to read incoming UDP messages ReadTimeout time.Duration // the net.Conn.SetReadTimeout value for new connections WriteTimeout time.Duration // the net.Conn.SetWriteTimeout value for new connections TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret> }
A Server defines parameters for running an DNS server. Note how much it starts to look like 'Client struct'
func (*Server) ListenAndServe ¶
ListenAndServe starts a nameserver on the configured address.
type Token ¶
type Token struct { RR // the scanned resource record Error *ParseError // when an error occured, this is the specifics }