Documentation
¶
Overview ¶
Package dns implements a full featured interface to the Domain Name System. Both server- and client-side programming is supported. The package allows complete control over what is sent out to the DNS. The API follows the less-is-more principle, by presenting a small, clean interface.
It supports (asynchronous) querying/replying, incoming/outgoing zone transfers, TSIG, EDNS0, dynamic updates, notifies and DNSSEC validation/signing.
Note that domain names MUST be fully qualified before sending them, unqualified names in a message will result in a packing failure.
Resource records are native types. They are not stored in wire format. Basic usage pattern for creating a new resource record:
r := new(dns.MX) r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 3600} r.Preference = 10 r.Mx = "mx.miek.nl."
Or directly from a string:
mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.")
Or when the default origin (.) and TTL (3600) and class (IN) suit you:
mx, err := dns.NewRR("miek.nl MX 10 mx.miek.nl")
Or even:
mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek")
In the DNS messages are exchanged, these messages contain resource records (sets). Use pattern for creating a message:
m := new(dns.Msg) m.SetQuestion("miek.nl.", dns.TypeMX)
Or when not certain if the domain name is fully qualified:
m.SetQuestion(dns.Fqdn("miek.nl"), dns.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(dns.Msg) m1.Id = dns.Id() m1.RecursionDesired = true m1.Question = make([]dns.Question, 1) m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}
After creating a message it can be sent. Basic use pattern for synchronous querying the DNS at a server configured on 127.0.0.1 and port 53:
c := new(dns.Client) in, rtt, err := c.Exchange(m1, "127.0.0.1:53")
Suppressing multiple outstanding queries (with the same question, type and class) is as easy as setting:
c.SingleInflight = true
More advanced options are available using a net.Dialer and the corresponding API. For example it is possible to set a timeout, or to specify a source IP address and port to use for the connection:
c := new(dns.Client) laddr := net.UDPAddr{ IP: net.ParseIP("[::1]"), Port: 12345, Zone: "", } c.Dialer := &net.Dialer{ Timeout: 200 * time.Millisecond, LocalAddr: &laddr, } in, rtt, err := c.Exchange(m1, "8.8.8.8:53")
If these "advanced" features are not needed, a simple UDP query can be sent, with:
in, err := dns.Exchange(m1, "127.0.0.1:53")
When this functions returns you will get DNS message. A DNS message consists out of four sections. The question section: in.Question, the answer section: in.Answer, the authority section: in.Ns and the additional section: in.Extra.
Each of these sections (except the Question section) contain a []RR. Basic use pattern for accessing the rdata of a TXT RR as the first RR in the Answer section:
if t, ok := in.Answer[0].(*dns.TXT); ok { // do something with t.Txt }
Domain Name and TXT Character String Representations ¶
Both domain names and TXT character strings are converted to presentation form both when unpacked and when converted to strings.
For TXT character strings, tabs, carriage returns and line feeds will be converted to \t, \r and \n respectively. Back slashes and quotations marks will be escaped. Bytes below 32 and above 127 will be converted to \DDD form.
For domain names, in addition to the above rules brackets, periods, spaces, semicolons and the at symbol are escaped.
DNSSEC ¶
DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It uses public key cryptography to sign resource records. The public keys are stored in DNSKEY records and the signatures in RRSIG records.
Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK) bit to a request.
m := new(dns.Msg) m.SetEdns0(4096, true)
Signature generation, signature verification and key generation are all supported.
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 dns.NameUsed ANY rrset empty RRset exists (value indep) dns.RRsetUsed NONE ANY empty Name is not in use dns.NameNotUsed NONE rrset empty RRset does not exist dns.RRsetNotUsed zone rrset rr RRset exists (value dep) dns.Used
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 dns.RemoveName ANY rrset empty Delete an RRset dns.RemoveRRset NONE rrset rr Delete an RR from RRset dns.Remove zone rrset rr Add to an RRset dns.Insert
TRANSACTION SIGNATURE ¶
An TSIG or transaction signature adds a HMAC TSIG record to each message sent. The supported algorithms include: HmacMD5, HmacSHA1, HmacSHA256 and HmacSHA512.
Basic use pattern when querying with a TSIG name "axfr." (note that these key names must be fully qualified - as they are domain names) and the base64 secret "so6ZGir4GPAqINNh9U5c3A==":
If an incoming message contains a TSIG record it MUST be the last record in the additional section (RFC2845 3.2). This means that you should make the call to SetTsig last, right before executing the query. If you make any changes to the RRset after calling SetTsig() the signature will be incorrect.
c := new(dns.Client) c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="} m := new(dns.Msg) m.SetQuestion("miek.nl.", dns.TypeMX) m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix()) ... // When sending the TSIG RR is calculated and filled in before sending
When requesting an zone transfer (almost all TSIG usage is when requesting zone transfers), with TSIG, this is the basic use pattern. In this example we request an AXFR for miek.nl. with TSIG key named "axfr." and secret "so6ZGir4GPAqINNh9U5c3A==" and using the server 176.58.119.54:
t := new(dns.Transfer) m := new(dns.Msg) t.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="} m.SetAxfr("miek.nl.") m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix()) c, err := t.In(m, "176.58.119.54:53") for r := range c { ... }
You can now read the records from the transfer as they come in. Each envelope is checked with TSIG. If something is not correct an error is returned.
A custom TSIG implementation can be used. This requires additional code to perform any session establishment and signature generation/verification. The client must be configured with an implementation of the TsigProvider interface:
type Provider struct{} func (*Provider) Generate(msg []byte, tsig *dns.TSIG) ([]byte, error) { // Use tsig.Hdr.Name and tsig.Algorithm in your code to // generate the MAC using msg as the payload. } func (*Provider) Verify(msg []byte, tsig *dns.TSIG) error { // Use tsig.Hdr.Name and tsig.Algorithm in your code to verify // that msg matches the value in tsig.MAC. } c := new(dns.Client) c.TsigProvider = new(Provider) m := new(dns.Msg) m.SetQuestion("miek.nl.", dns.TypeMX) m.SetTsig(keyname, dns.HmacSHA1, 300, time.Now().Unix()) ... // TSIG RR is calculated by calling your Generate method
Basic use pattern validating and replying to a message that has TSIG set.
server := &dns.Server{Addr: ":53", Net: "udp"} server.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="} go server.ListenAndServe() dns.HandleFunc(".", handleRequest) func handleRequest(w dns.ResponseWriter, r *dns.Msg) { m := new(dns.Msg) m.SetReply(r) if r.IsTsig() != nil { if w.TsigStatus() == nil { // *Msg r has an TSIG record and it was validated m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix()) } else { // *Msg r has an TSIG records and it was not validated } } w.WriteMsg(m) }
PRIVATE RRS ¶
RFC 6895 sets aside a range of type codes for private use. This range is 65,280 - 65,534 (0xFF00 - 0xFFFE). When experimenting with new Resource Records these can be used, before requesting an official type code from IANA.
See https://miek.nl/2014/september/21/idn-and-private-rr-in-go-dns/ for more information.
EDNS0 ¶
EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated by RFC 6891. It defines an new RR type, the OPT RR, which is then completely abused.
Basic use pattern for creating an (empty) OPT RR:
o := new(dns.OPT) o.Hdr.Name = "." // MUST be the root zone, per definition. o.Hdr.Rrtype = dns.TypeOPT
The rdata of an OPT RR consists out of a slice of EDNS0 (RFC 6891) interfaces. Currently only a few have been standardized: EDNS0_NSID (RFC 5001) and EDNS0_SUBNET (RFC 7871). Note that these options may be combined in an OPT RR. Basic use pattern for a server to check if (and which) options are set:
// o is a dns.OPT for _, s := range o.Option { switch e := s.(type) { case *dns.EDNS0_NSID: // do stuff with e.Nsid case *dns.EDNS0_SUBNET: // access e.Family, e.Address, etc. } }
SIG(0)
From RFC 2931:
SIG(0) provides protection for DNS transactions and requests .... ... protection for glue records, DNS requests, protection for message headers on requests and responses, and protection of the overall integrity of a response.
It works like TSIG, except that SIG(0) uses public key cryptography, instead of the shared secret approach in TSIG. Supported algorithms: ECDSAP256SHA256, ECDSAP384SHA384, RSASHA1, RSASHA256 and RSASHA512.
Signing subsequent messages in multi-message sessions is not implemented.
Index ¶
- Constants
- Variables
- func CanonicalName(s string) string
- func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) (string, error)
- func CompareDomainName(s1, s2 string) (n int)
- func CountLabel(s string) (labels int)
- func Fqdn(s string) string
- func IsDomainName(s string) (labels int, ok bool)
- func IsFqdn(s string) bool
- func IsMsg(buf []byte) error
- func IsRRset(rrset []RR) bool
- func IsSubDomain(parent, child string) bool
- func Len(r RR) int
- func NextLabel(s string, offset int) (i int, end bool)
- func PackDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error)
- func PackRR(rr RR, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error)
- func PrevLabel(s string, n int) (i int, start bool)
- func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata)
- func PrivateHandleRemove(rtype uint16)
- func ReverseAddr(addr string) (arpa string, err error)
- func SMIMEAName(email, domain string) (string, error)
- func Split(s string) []int
- func SplitDomainName(s string) (labels []string)
- func StringToTime(s string) (uint32, error)
- func TLSAName(name, service, network string) (string, error)
- func TimeToString(t uint32) string
- func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error)
- func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error
- func UnpackDomainName(msg []byte, off int) (string, int, error)
- type A
- type AAAA
- type AFSDB
- type ANY
- type APL
- type APLPrefix
- type AVC
- type CAA
- type CDNSKEY
- type CDS
- type CERT
- type CNAME
- type CSYNC
- type Class
- type DHCID
- type DLV
- type DNAME
- type DNSKEY
- func (k *DNSKEY) Generate(bits int) (crypto.PrivateKey, error)
- func (rr *DNSKEY) Header() *RR_Header
- func (k *DNSKEY) KeyTag() uint16
- func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error)
- func (r *DNSKEY) PrivateKeyString(p crypto.PrivateKey) string
- func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, error)
- func (rr *DNSKEY) String() string
- func (k *DNSKEY) ToCDNSKEY() *CDNSKEY
- func (k *DNSKEY) ToDS(h uint8) *DS
- type DS
- type EDNS0
- type EDNS0_COOKIE
- type EDNS0_DAU
- type EDNS0_DHU
- type EDNS0_EXPIRE
- type EDNS0_LLQ
- type EDNS0_LOCAL
- type EDNS0_N3U
- type EDNS0_NSID
- type EDNS0_PADDING
- type EDNS0_SUBNET
- type EDNS0_TCP_KEEPALIVE
- type EDNS0_UL
- type EUI48
- type EUI64
- type Error
- type GPOS
- type HINFO
- type HIP
- type HTTPS
- type Header
- type KEY
- type KX
- type L32
- type L64
- type LOC
- type LP
- type MF
- type MINFO
- type MX
- type Msg
- func (dns *Msg) IsEdns0() *OPT
- func (dns *Msg) IsTsig() *TSIG
- func (dns *Msg) Len() int
- func (dns *Msg) Pack() (msg []byte, err error)
- func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error)
- func (dns *Msg) SetAxfr(z string) *Msg
- func (dns *Msg) SetEdns0(udpsize uint16, do bool) *Msg
- func (dns *Msg) SetIxfr(z string, serial uint32, ns, mbox string) *Msg
- func (dns *Msg) SetNotify(z string) *Msg
- func (dns *Msg) SetQuestion(z string, t uint16) *Msg
- func (dns *Msg) SetRcode(request *Msg, rcode int) *Msg
- func (dns *Msg) SetRcodeFormatError(request *Msg) *Msg
- func (dns *Msg) SetReply(request *Msg) *Msg
- func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned int64) *Msg
- func (dns *Msg) SetUpdate(z string) *Msg
- func (dns *Msg) String() string
- func (dns *Msg) Truncate(size int)
- func (dns *Msg) Unpack(msg []byte) (err error)
- func (dns *Msg) UnpackWithTypes(dh *Header, msg []byte, off int, known_types map[uint16]func() RR) (err error)
- func (dns *Msg) Unpack_TS(msg []byte, known_types map[uint16]func() RR) (err error)
- type MsgHdr
- type NAPTR
- type NID
- type NINFO
- type NS
- type NSAPPTR
- type NSEC
- type NSEC3
- type NSEC3PARAM
- type Name
- type OPENPGPKEY
- type OPT
- func (rr *OPT) Do() bool
- func (rr *OPT) ExtendedRcode() int
- func (rr *OPT) Header() *RR_Header
- func (rr *OPT) SetDo(do ...bool)
- func (rr *OPT) SetExtendedRcode(v uint16)
- func (rr *OPT) SetUDPSize(size uint16)
- func (rr *OPT) SetVersion(v uint8)
- func (rr *OPT) String() string
- func (rr *OPT) UDPSize() uint16
- func (rr *OPT) Version() uint8
- type PTR
- type PX
- type ParseError
- type PrivateRR
- type PrivateRdata
- type Question
- type RFC3597
- type RKEY
- type RP
- type RR
- type RRSIG
- type RR_Header
- type RT
- type SIG
- type SMIMEA
- type SOA
- type SPF
- type SRV
- type SSHFP
- type SVCB
- type SVCBAlpn
- type SVCBECHConfig
- type SVCBIPv4Hint
- type SVCBIPv6Hint
- type SVCBKey
- type SVCBKeyValue
- type SVCBLocal
- type SVCBMandatory
- type SVCBNoDefaultAlpn
- type SVCBPort
- type TA
- type TALINK
- type TKEY
- type TLSA
- type TSIG
- type TXT
- type TsigProvider
- type Type
- type URI
- type UnknownRR
- type X25
Constants ¶
const ( // DefaultMsgSize is the standard default for messages larger than 512 bytes. DefaultMsgSize = 4096 // MinMsgSize is the minimal size of a DNS packet. MinMsgSize = 512 // MaxMsgSize is the largest possible DNS packet. MaxMsgSize = 65535 )
const ( RSAMD5 uint8 DH DSA RSASHA1 DSANSEC3SHA1 RSASHA1NSEC3SHA1 RSASHA256 RSASHA512 ECCGOST ECDSAP256SHA256 ECDSAP384SHA384 ED25519 ED448 INDIRECT uint8 = 252 PRIVATEDNS uint8 = 253 // Private (experimental keys) PRIVATEOID uint8 = 254 )
DNSSEC encryption algorithm codes.
const ( SHA1 uint8 // RFC 4034 SHA256 // RFC 4509 GOST94 // RFC 5933 SHA384 // Experimental SHA512 // Experimental )
DNSSEC hashing algorithm codes.
const ( SEP = 1 REVOKE = 1 << 7 ZONE = 1 << 8 )
DNSKEY flag values.
const ( EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt EDNS0NSID = 0x3 // nsid (See RFC 5001) EDNS0DAU = 0x5 // DNSSEC Algorithm Understood EDNS0DHU = 0x6 // DS Hash Understood EDNS0N3U = 0x7 // NSEC3 Hash Understood EDNS0SUBNET = 0x8 // client-subnet (See RFC 7871) EDNS0EXPIRE = 0x9 // EDNS0 expire EDNS0COOKIE = 0xa // EDNS0 Cookie EDNS0TCPKEEPALIVE = 0xb // EDNS0 tcp keep alive (See RFC 7828) EDNS0PADDING = 0xc // EDNS0 padding (See RFC 7830) EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (See RFC 6891) EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (See RFC 6891) )
EDNS0 Option codes.
const ( HmacSHA1 = "hmac-sha1." HmacSHA224 = "hmac-sha224." HmacSHA256 = "hmac-sha256." HmacSHA384 = "hmac-sha384." HmacSHA512 = "hmac-sha512." HmacMD5 = "hmac-md5.sig-alg.reg.int." // Deprecated: HmacMD5 is no longer supported. )
HMAC hashing codes. These are transmitted as domain names.
const ( TypeNone uint16 = 0 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 TypePTR uint16 = 12 TypeHINFO uint16 = 13 TypeMINFO uint16 = 14 TypeMX uint16 = 15 TypeTXT uint16 = 16 TypeRP uint16 = 17 TypeAFSDB uint16 = 18 TypeX25 uint16 = 19 TypeISDN uint16 = 20 TypeRT uint16 = 21 TypeNSAPPTR uint16 = 23 TypeSIG uint16 = 24 TypeKEY uint16 = 25 TypePX uint16 = 26 TypeGPOS uint16 = 27 TypeAAAA uint16 = 28 TypeLOC uint16 = 29 TypeNXT uint16 = 30 TypeEID uint16 = 31 TypeNIMLOC uint16 = 32 TypeSRV uint16 = 33 TypeATMA uint16 = 34 TypeNAPTR uint16 = 35 TypeKX uint16 = 36 TypeCERT uint16 = 37 TypeDNAME uint16 = 39 TypeSINK uint16 = 40 // Donald E. Eastlake TypeOPT uint16 = 41 // EDNS TypeAPL uint16 = 42 TypeDS uint16 = 43 TypeSSHFP uint16 = 44 TypeIPSECKEY uint16 = 45 TypeRRSIG uint16 = 46 TypeNSEC uint16 = 47 TypeDNSKEY uint16 = 48 TypeDHCID uint16 = 49 TypeNSEC3 uint16 = 50 TypeNSEC3PARAM uint16 = 51 TypeTLSA uint16 = 52 TypeSMIMEA uint16 = 53 TypeHIP uint16 = 55 TypeNINFO uint16 = 56 TypeRKEY uint16 = 57 TypeTALINK uint16 = 58 TypeCDS uint16 = 59 TypeCDNSKEY uint16 = 60 TypeOPENPGPKEY uint16 = 61 TypeCSYNC uint16 = 62 TypeSVCB uint16 = 64 TypeHTTPS uint16 = 65 TypeSPF uint16 = 99 TypeUINFO uint16 = 100 TypeUID uint16 = 101 TypeGID uint16 = 102 TypeUNSPEC uint16 = 103 TypeNID uint16 = 104 TypeL32 uint16 = 105 TypeL64 uint16 = 106 TypeLP uint16 = 107 TypeEUI48 uint16 = 108 TypeEUI64 uint16 = 109 TypeURI uint16 = 256 TypeCAA uint16 = 257 TypeAVC uint16 = 258 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 TypeTA uint16 = 32768 TypeDLV uint16 = 32769 TypeReserved uint16 = 65535 // valid Question.Qclass ClassINET = 1 ClassCHAOS = 3 ClassHESIOD = 4 ClassNONE = 254 ClassANY = 255 // Message Response Codes, see https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml RcodeSuccess = 0 // NoError - No Error [DNS] RcodeFormatError = 1 // FormErr - Format Error [DNS] RcodeServerFailure = 2 // ServFail - Server Failure [DNS] RcodeNameError = 3 // NXDomain - Non-Existent Domain [DNS] RcodeNotImplemented = 4 // NotImp - Not Implemented [DNS] RcodeRefused = 5 // Refused - Query Refused [DNS] RcodeYXDomain = 6 // YXDomain - Name Exists when it should not [DNS Update] RcodeYXRrset = 7 // YXRRSet - RR Set Exists when it should not [DNS Update] RcodeNXRrset = 8 // NXRRSet - RR Set that should exist does not [DNS Update] RcodeNotAuth = 9 // NotAuth - Server Not Authoritative for zone [DNS Update] RcodeNotZone = 10 // NotZone - Name not contained in zone [DNS Update/TSIG] RcodeBadSig = 16 // BADSIG - TSIG Signature Failure [TSIG] RcodeBadVers = 16 // BADVERS - Bad OPT Version [EDNS0] RcodeBadKey = 17 // BADKEY - Key not recognized [TSIG] RcodeBadTime = 18 // BADTIME - Signature out of time window [TSIG] RcodeBadMode = 19 // BADMODE - Bad TKEY Mode [TKEY] RcodeBadName = 20 // BADNAME - Duplicate key name [TKEY] RcodeBadAlg = 21 // BADALG - Algorithm not supported [TKEY] RcodeBadTrunc = 22 // BADTRUNC - Bad Truncation [TSIG] RcodeBadCookie = 23 // BADCOOKIE - Bad/missing Server Cookie [DNS Cookies] // Message Opcodes. There is no 3. OpcodeQuery = 0 OpcodeIQuery = 1 OpcodeStatus = 2 OpcodeNotify = 4 OpcodeUpdate = 5 )
Wire constants and supported types.
const ( LOC_EQUATOR = 1 << 31 // RFC 1876, Section 2. LOC_PRIMEMERIDIAN = 1 << 31 // RFC 1876, Section 2. LOC_HOURS = 60 * 1000 LOC_DEGREES = 60 * LOC_HOURS LOC_ALTITUDEBASE = 100000 )
Various constants used in the LOC RR. See RFC 1887.
const ( CertPKIX = 1 + iota CertSPKI CertPGP CertIPIX CertISPKI CertIPGP CertACPKIX CertIACPKIX CertURI = 253 CertOID = 254 )
Different Certificate Types, see RFC 4398, Section 2.1
Variables ¶
var ( ErrAlg error = &Error{err: "bad algorithm"} // ErrAlg indicates an error with the (DNSSEC) algorithm. ErrAuth error = &Error{err: "bad authentication"} // ErrAuth indicates an error in the TSIG authentication. ErrBuf error = &Error{err: "buffer size too small"} // ErrBuf indicates that the buffer used is too small for the message. ErrConnEmpty error = &Error{err: "conn has no connection"} // ErrConnEmpty indicates a connection is being used before it is initialized. ErrExtendedRcode error = &Error{err: "bad extended rcode"} // ErrExtendedRcode ... ErrFqdn error = &Error{err: "domain must be fully qualified"} // ErrFqdn indicates that a domain name does not have a closing dot. ErrId error = &Error{err: "id mismatch"} // ErrId indicates there is a mismatch with the message's ID. ErrKeyAlg error = &Error{err: "bad key algorithm"} // ErrKeyAlg indicates that the algorithm in the key is not valid. ErrKey error = &Error{err: "bad key"} ErrKeySize error = &Error{err: "bad key size"} ErrLongDomain error = &Error{err: fmt.Sprintf("domain name exceeded %d wire-format octets", maxDomainNameWireOctets)} ErrNoSig error = &Error{err: "no signature found"} ErrPrivKey error = &Error{err: "bad private key"} ErrRcode error = &Error{err: "bad rcode"} ErrRdata error = &Error{err: "bad rdata"} ErrRRset error = &Error{err: "bad rrset"} ErrSecret error = &Error{err: "no secrets defined"} ErrShortRead error = &Error{err: "short read"} ErrSig error = &Error{err: "bad signature"} // ErrSig indicates that a signature can not be cryptographically validated. ErrSoa error = &Error{err: "no SOA"} // ErrSOA indicates that no SOA RR was seen when doing zone transfers. ErrTime error = &Error{err: "bad time"} // ErrTime indicates a timing error in TSIG authentication. )
Errors defined in this package.
var AlgorithmToHash = map[uint8]crypto.Hash{ RSAMD5: crypto.MD5, DSA: crypto.SHA1, RSASHA1: crypto.SHA1, RSASHA1NSEC3SHA1: crypto.SHA1, RSASHA256: crypto.SHA256, ECDSAP256SHA256: crypto.SHA256, ECDSAP384SHA384: crypto.SHA384, RSASHA512: crypto.SHA512, ED25519: crypto.Hash(0), }
AlgorithmToHash is a map of algorithm crypto hash IDs to crypto.Hash's.
var AlgorithmToString = 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", ED25519: "ED25519", ED448: "ED448", INDIRECT: "INDIRECT", PRIVATEDNS: "PRIVATEDNS", PRIVATEOID: "PRIVATEOID", }
AlgorithmToString is a map of algorithm IDs to algorithm names.
var CertTypeToString = map[uint16]string{ CertPKIX: "PKIX", CertSPKI: "SPKI", CertPGP: "PGP", CertIPIX: "IPIX", CertISPKI: "ISPKI", CertIPGP: "IPGP", CertACPKIX: "ACPKIX", CertIACPKIX: "IACPKIX", CertURI: "URI", CertOID: "OID", }
CertTypeToString converts the Cert Type to its string representation. See RFC 4398 and RFC 6944.
var ClassToString = map[uint16]string{
ClassINET: "IN",
ClassCHAOS: "CH",
ClassHESIOD: "HS",
ClassNONE: "NONE",
ClassANY: "ANY",
}
ClassToString is a maps Classes to strings for each CLASS wire type.
var HashToString = map[uint8]string{ SHA1: "SHA1", SHA256: "SHA256", GOST94: "GOST94", SHA384: "SHA384", SHA512: "SHA512", }
HashToString is a map of hash IDs to names.
var Id = id
Id by default returns a 16-bit random number to be used as a message id. The number is drawn from a cryptographically secure random number generator. This being a variable the function can be reassigned to a custom function. For instance, to make it return a static value for testing:
dns.Id = func() uint16 { return 3 }
var OpcodeToString = map[int]string{
OpcodeQuery: "QUERY",
OpcodeIQuery: "IQUERY",
OpcodeStatus: "STATUS",
OpcodeNotify: "NOTIFY",
OpcodeUpdate: "UPDATE",
}
OpcodeToString maps Opcodes to strings.
var RcodeToString = map[int]string{
RcodeSuccess: "NOERROR",
RcodeFormatError: "FORMERR",
RcodeServerFailure: "SERVFAIL",
RcodeNameError: "NXDOMAIN",
RcodeNotImplemented: "NOTIMP",
RcodeRefused: "REFUSED",
RcodeYXDomain: "YXDOMAIN",
RcodeYXRrset: "YXRRSET",
RcodeNXRrset: "NXRRSET",
RcodeNotAuth: "NOTAUTH",
RcodeNotZone: "NOTZONE",
RcodeBadSig: "BADSIG",
RcodeBadKey: "BADKEY",
RcodeBadTime: "BADTIME",
RcodeBadMode: "BADMODE",
RcodeBadName: "BADNAME",
RcodeBadAlg: "BADALG",
RcodeBadTrunc: "BADTRUNC",
RcodeBadCookie: "BADCOOKIE",
}
RcodeToString maps Rcodes to strings.
var StringToAlgorithm = reverseInt8(AlgorithmToString)
StringToAlgorithm is the reverse of AlgorithmToString.
var StringToCertType = reverseInt16(CertTypeToString)
StringToCertType is the reverseof CertTypeToString.
var StringToClass = reverseInt16(ClassToString)
StringToClass is the reverse of ClassToString, needed for string parsing.
var StringToHash = reverseInt8(HashToString)
StringToHash is a map of names to hash IDs.
var StringToOpcode = reverseInt(OpcodeToString)
StringToOpcode is a map of opcodes to strings.
var StringToRcode = reverseInt(RcodeToString)
StringToRcode is a map of rcodes to strings.
var StringToType = reverseInt16(TypeToString)
StringToType is the reverse of TypeToString, needed for string parsing.
var TypeToRR = map[uint16]func() RR{ TypeA: func() RR { return new(A) }, TypeAAAA: func() RR { return new(AAAA) }, TypeAFSDB: func() RR { return new(AFSDB) }, TypeANY: func() RR { return new(ANY) }, TypeAPL: func() RR { return new(APL) }, TypeAVC: func() RR { return new(AVC) }, TypeCAA: func() RR { return new(CAA) }, TypeCDNSKEY: func() RR { return new(CDNSKEY) }, TypeCDS: func() RR { return new(CDS) }, TypeCERT: func() RR { return new(CERT) }, TypeCNAME: func() RR { return new(CNAME) }, TypeCSYNC: func() RR { return new(CSYNC) }, TypeDHCID: func() RR { return new(DHCID) }, TypeDLV: func() RR { return new(DLV) }, TypeDNAME: func() RR { return new(DNAME) }, TypeDNSKEY: func() RR { return new(DNSKEY) }, TypeDS: func() RR { return new(DS) }, TypeEUI48: func() RR { return new(EUI48) }, TypeEUI64: func() RR { return new(EUI64) }, TypeGPOS: func() RR { return new(GPOS) }, TypeHINFO: func() RR { return new(HINFO) }, TypeHIP: func() RR { return new(HIP) }, TypeHTTPS: func() RR { return new(HTTPS) }, TypeKEY: func() RR { return new(KEY) }, TypeKX: func() RR { return new(KX) }, TypeL32: func() RR { return new(L32) }, TypeL64: func() RR { return new(L64) }, TypeLOC: func() RR { return new(LOC) }, TypeLP: func() RR { return new(LP) }, TypeMF: func() RR { return new(MF) }, TypeMINFO: func() RR { return new(MINFO) }, TypeMX: func() RR { return new(MX) }, TypeNAPTR: func() RR { return new(NAPTR) }, TypeNID: func() RR { return new(NID) }, TypeNINFO: func() RR { return new(NINFO) }, TypeNS: func() RR { return new(NS) }, TypeNSAPPTR: func() RR { return new(NSAPPTR) }, TypeNSEC: func() RR { return new(NSEC) }, TypeNSEC3: func() RR { return new(NSEC3) }, TypeNSEC3PARAM: func() RR { return new(NSEC3PARAM) }, TypeOPENPGPKEY: func() RR { return new(OPENPGPKEY) }, TypeOPT: func() RR { return new(OPT) }, TypePTR: func() RR { return new(PTR) }, TypePX: func() RR { return new(PX) }, TypeRKEY: func() RR { return new(RKEY) }, TypeRP: func() RR { return new(RP) }, TypeRRSIG: func() RR { return new(RRSIG) }, TypeRT: func() RR { return new(RT) }, TypeSIG: func() RR { return new(SIG) }, TypeSMIMEA: func() RR { return new(SMIMEA) }, TypeSOA: func() RR { return new(SOA) }, TypeSPF: func() RR { return new(SPF) }, TypeSRV: func() RR { return new(SRV) }, TypeSSHFP: func() RR { return new(SSHFP) }, TypeSVCB: func() RR { return new(SVCB) }, TypeTA: func() RR { return new(TA) }, TypeTALINK: func() RR { return new(TALINK) }, TypeTKEY: func() RR { return new(TKEY) }, TypeTLSA: func() RR { return new(TLSA) }, TypeTSIG: func() RR { return new(TSIG) }, TypeTXT: func() RR { return new(TXT) }, TypeURI: func() RR { return new(URI) }, TypeX25: func() RR { return new(X25) }, }
TypeToRR is a map of constructors for each RR type.
var TypeToString = map[uint16]string{
TypeA: "A",
TypeAAAA: "AAAA",
TypeAFSDB: "AFSDB",
TypeANY: "ANY",
TypeAPL: "APL",
TypeATMA: "ATMA",
TypeAVC: "AVC",
TypeAXFR: "AXFR",
TypeCAA: "CAA",
TypeCDNSKEY: "CDNSKEY",
TypeCDS: "CDS",
TypeCERT: "CERT",
TypeCNAME: "CNAME",
TypeCSYNC: "CSYNC",
TypeDHCID: "DHCID",
TypeDLV: "DLV",
TypeDNAME: "DNAME",
TypeDNSKEY: "DNSKEY",
TypeDS: "DS",
TypeEID: "EID",
TypeEUI48: "EUI48",
TypeEUI64: "EUI64",
TypeGID: "GID",
TypeGPOS: "GPOS",
TypeHINFO: "HINFO",
TypeHIP: "HIP",
TypeHTTPS: "HTTPS",
TypeIPSECKEY: "IPSECKEY",
TypeISDN: "ISDN",
TypeIXFR: "IXFR",
TypeKEY: "KEY",
TypeKX: "KX",
TypeL32: "L32",
TypeL64: "L64",
TypeLOC: "LOC",
TypeLP: "LP",
TypeMAILA: "MAILA",
TypeMAILB: "MAILB",
TypeMB: "MB",
TypeMD: "MD",
TypeMF: "MF",
TypeMG: "MG",
TypeMINFO: "MINFO",
TypeMR: "MR",
TypeMX: "MX",
TypeNAPTR: "NAPTR",
TypeNID: "NID",
TypeNIMLOC: "NIMLOC",
TypeNINFO: "NINFO",
TypeNS: "NS",
TypeNSEC: "NSEC",
TypeNSEC3: "NSEC3",
TypeNSEC3PARAM: "NSEC3PARAM",
TypeNULL: "NULL",
TypeNXT: "NXT",
TypeNone: "None",
TypeOPENPGPKEY: "OPENPGPKEY",
TypeOPT: "OPT",
TypePTR: "PTR",
TypePX: "PX",
TypeRKEY: "RKEY",
TypeRP: "RP",
TypeRRSIG: "RRSIG",
TypeRT: "RT",
TypeReserved: "Reserved",
TypeSIG: "SIG",
TypeSINK: "SINK",
TypeSMIMEA: "SMIMEA",
TypeSOA: "SOA",
TypeSPF: "SPF",
TypeSRV: "SRV",
TypeSSHFP: "SSHFP",
TypeSVCB: "SVCB",
TypeTA: "TA",
TypeTALINK: "TALINK",
TypeTKEY: "TKEY",
TypeTLSA: "TLSA",
TypeTSIG: "TSIG",
TypeTXT: "TXT",
TypeUID: "UID",
TypeUINFO: "UINFO",
TypeUNSPEC: "UNSPEC",
TypeURI: "URI",
TypeX25: "X25",
TypeNSAPPTR: "NSAP-PTR",
}
TypeToString is a map of strings for each RR type.
var Version = v{&shadows, 1, 1, 39}
Version is current release version sync with miekg/dns
Functions ¶
func CanonicalName ¶
CanonicalName returns the domain name in canonical form. A name in canonical form is lowercase and fully qualified. See Section 6.2 in RFC 4034.
func CertificateToDANE ¶
func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) (string, error)
CertificateToDANE converts a certificate to a hex string as used in the TLSA or SMIMEA records.
func CompareDomainName ¶
CompareDomainName compares the names s1 and s2 and returns how many labels they have in common starting from the *right*. The comparison stops at the first inequality. The names are downcased before the comparison.
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
s1 and s2 must be syntactically valid domain names.
func CountLabel ¶
CountLabel counts the number of labels in the string s. s must be a syntactically valid domain name.
func Fqdn ¶
Fqdn return the fully qualified domain name from s. If s is already fully qualified, it behaves as the identity function.
func IsDomainName ¶
IsDomainName checks if s is a valid domain name, it returns the number of labels and true, when a domain name is valid. Note that non fully qualified domain name is considered valid, in this case the last label is counted in the number of labels. When false is returned the number of labels is not defined. Also note that this function is extremely liberal; almost any string is a valid domain name as the DNS is 8 bit protocol. It checks if each label fits in 63 characters and that the entire name will fit into the 255 octet wire format limit.
func IsMsg ¶
IsMsg sanity checks buf and returns an error if it isn't a valid DNS packet. The checking is performed on the binary payload.
func IsRRset ¶
IsRRset checks if a set of RRs is a valid RRset as defined by RFC 2181. This means the RRs need to have the same type, name, and class. Returns true if the RR set is valid, otherwise false.
func IsSubDomain ¶
IsSubDomain checks if child is indeed a child of the parent. If child and parent are the same domain true is returned as well.
func NextLabel ¶
NextLabel returns the index of the start of the next label in the string s starting at offset. The bool end is true when the end of the string has been reached. Also see PrevLabel.
func PackDomainName ¶
func PackDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error)
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 PackRR ¶
func PackRR(rr RR, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error)
PackRR packs a resource record rr into msg[off:]. See PackDomainName for documentation about the compression.
func PrevLabel ¶
PrevLabel returns the index of the label when starting from the right and jumping n labels to the left. The bool start is true when the start of the string has been overshot. Also see NextLabel.
func PrivateHandle ¶
func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata)
PrivateHandle registers a private resource record type. It requires string and numeric representation of private RR type and generator function as argument.
func PrivateHandleRemove ¶
func PrivateHandleRemove(rtype uint16)
PrivateHandleRemove removes definitions required to support private RR type.
func ReverseAddr ¶
ReverseAddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP address suitable for reverse DNS (PTR) record lookups or an error if it fails to parse the IP address.
func SMIMEAName ¶
SMIMEAName returns the ownername of a SMIMEA resource record as per the format specified in RFC 'draft-ietf-dane-smime-12' Section 2 and 3
func Split ¶
Split splits a name s into its label indexes. www.miek.nl. returns []int{0, 4, 9}, www.miek.nl also returns []int{0, 4, 9}. The root name (.) returns nil. Also see SplitDomainName. s must be a syntactically valid domain name.
func SplitDomainName ¶
SplitDomainName splits a name string into it's labels. www.miek.nl. returns []string{"www", "miek", "nl"} .www.miek.nl. returns []string{"", "www", "miek", "nl"}, The root label (.) returns nil. Note that using strings.Split(s) will work in most cases, but does not handle escaped dots (\.) for instance. s must be a syntactically valid domain name, see IsDomainName.
func StringToTime ¶
StringToTime translates the RRSIG's incep. and expir. times from string values like "20110403154150" to an 32 bit integer. It takes serial arithmetic (RFC 1982) into account.
func TLSAName ¶
TLSAName returns the ownername of a TLSA resource record as per the rules specified in RFC 6698, Section 3.
func TimeToString ¶
TimeToString translates the RRSIG's incep. and expir. times to the string representation used when printing the record. It takes serial arithmetic (RFC 1982) into account.
func TsigGenerate ¶
TsigGenerate fills out the TSIG record attached to the message. The message should contain a "stub" TSIG RR with the algorithm, key name (owner name of the RR), time fudge (defaults to 300 seconds) and the current time The TSIG MAC is saved in that Tsig RR. When TsigGenerate is called for the first time requestMAC is set to the empty string and timersOnly is false. 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 unpacks a domain name into a string. It returns the name, the new offset into msg and any error that occurred.
When an error is encountered, the unpacked name will be discarded and len(msg) will be returned as the offset.
Types ¶
type ANY ¶
type ANY struct {
Hdr RR_Header
}
ANY is a wild card record. See RFC 1035, Section 3.2.3. ANY is named "*" there.
type AVC ¶
AVC RR. See https://www.iana.org/assignments/dns-parameters/AVC/avc-completed-template.
type CAA ¶
CAA RR. See RFC 6844.
func (*CAA) String ¶
rr.Value Is the character-string encoding of the value field as specified in RFC 1035, Section 5.1.
type CERT ¶
type CERT struct { Hdr RR_Header Type uint16 KeyTag uint16 Algorithm uint8 Certificate string `dns:"base64"` }
CERT RR. See RFC 4398.
type DNSKEY ¶
type DNSKEY struct { Hdr RR_Header Flags uint16 Protocol uint8 Algorithm uint8 PublicKey string `dns:"base64"` }
DNSKEY RR. See RFC 4034 and RFC 3755.
func (*DNSKEY) Generate ¶
func (k *DNSKEY) Generate(bits int) (crypto.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 (*DNSKEY) NewPrivateKey ¶
func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error)
NewPrivateKey returns a PrivateKey by parsing the string s. s should be in the same form of the BIND private key files.
func (*DNSKEY) PrivateKeyString ¶
func (r *DNSKEY) PrivateKeyString(p crypto.PrivateKey) 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 (the algorithm), so its a method of the DNSKEY. It supports *rsa.PrivateKey, *ecdsa.PrivateKey and ed25519.PrivateKey.
func (*DNSKEY) ReadPrivateKey ¶
ReadPrivateKey reads a private key from the io.Reader q. The string file is only used in error reporting. The public key must be known, because some cryptographic algorithms embed the public inside the privatekey.
type DS ¶
type EDNS0 ¶
type EDNS0 interface { // Option returns the option code for the option. Option() uint16 // String returns the string representation of the option. String() string // contains filtered or unexported methods }
EDNS0 defines an EDNS0 Option. An OPT RR can have multiple options appended to it.
type EDNS0_COOKIE ¶
type EDNS0_COOKIE struct { Code uint16 // Always EDNS0COOKIE Cookie string // Hex-encoded cookie data }
The EDNS0_COOKIE option is used to add a DNS Cookie to a message.
o := new(dns.OPT) o.Hdr.Name = "." o.Hdr.Rrtype = dns.TypeOPT e := new(dns.EDNS0_COOKIE) e.Code = dns.EDNS0COOKIE e.Cookie = "24a5ac.." o.Option = append(o.Option, e)
The Cookie field consists out of a client cookie (RFC 7873 Section 4), that is always 8 bytes. It may then optionally be followed by the server cookie. The server cookie is of variable length, 8 to a maximum of 32 bytes. In other words:
cCookie := o.Cookie[:16] sCookie := o.Cookie[16:]
There is no guarantee that the Cookie string has a specific length.
func (*EDNS0_COOKIE) Option ¶
func (e *EDNS0_COOKIE) Option() uint16
Option implements the EDNS0 interface.
func (*EDNS0_COOKIE) String ¶
func (e *EDNS0_COOKIE) String() string
type EDNS0_DAU ¶
EDNS0_DUA implements the EDNS0 "DNSSEC Algorithm Understood" option. See RFC 6975.
type EDNS0_DHU ¶
EDNS0_DHU implements the EDNS0 "DS Hash Understood" option. See RFC 6975.
type EDNS0_EXPIRE ¶
EDNS0_EXPIRE implementes the EDNS0 option as described in RFC 7314.
func (*EDNS0_EXPIRE) Option ¶
func (e *EDNS0_EXPIRE) Option() uint16
Option implements the EDNS0 interface.
func (*EDNS0_EXPIRE) String ¶
func (e *EDNS0_EXPIRE) String() string
type EDNS0_LLQ ¶
type EDNS0_LLQ struct { Code uint16 // Always EDNS0LLQ Version uint16 Opcode uint16 Error uint16 Id uint64 LeaseLife uint32 }
EDNS0_LLQ stands for Long Lived Queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 Implemented for completeness, as the EDNS0 type code is assigned.
type EDNS0_LOCAL ¶
The EDNS0_LOCAL option is used for local/experimental purposes. The option code is recommended to be within the range [EDNS0LOCALSTART, EDNS0LOCALEND] (RFC6891), although any unassigned code can actually be used. The content of the option is made available in Data, unaltered. Basic use pattern for creating a local option:
o := new(dns.OPT) o.Hdr.Name = "." o.Hdr.Rrtype = dns.TypeOPT e := new(dns.EDNS0_LOCAL) e.Code = dns.EDNS0LOCALSTART e.Data = []byte{72, 82, 74} o.Option = append(o.Option, e)
func (*EDNS0_LOCAL) Option ¶
func (e *EDNS0_LOCAL) Option() uint16
Option implements the EDNS0 interface.
func (*EDNS0_LOCAL) String ¶
func (e *EDNS0_LOCAL) String() string
type EDNS0_N3U ¶
EDNS0_N3U implements the EDNS0 "NSEC3 Hash Understood" option. See RFC 6975.
type EDNS0_NSID ¶
type EDNS0_NSID struct { Code uint16 // Always EDNS0NSID Nsid string // This string needs to be hex encoded }
EDNS0_NSID option is used to retrieve a nameserver identifier. When sending a request Nsid must be set to the empty string The identifier is an opaque string encoded as hex. Basic use pattern for creating an nsid option:
o := new(dns.OPT) o.Hdr.Name = "." o.Hdr.Rrtype = dns.TypeOPT e := new(dns.EDNS0_NSID) e.Code = dns.EDNS0NSID e.Nsid = "AA" o.Option = append(o.Option, e)
func (*EDNS0_NSID) Option ¶
func (e *EDNS0_NSID) Option() uint16
Option implements the EDNS0 interface.
func (*EDNS0_NSID) String ¶
func (e *EDNS0_NSID) String() string
type EDNS0_PADDING ¶
type EDNS0_PADDING struct {
Padding []byte
}
EDNS0_PADDING option is used to add padding to a request/response. The default value of padding SHOULD be 0x0 but other values MAY be used, for instance if compression is applied before encryption which may break signatures.
func (*EDNS0_PADDING) Option ¶
func (e *EDNS0_PADDING) Option() uint16
Option implements the EDNS0 interface.
func (*EDNS0_PADDING) String ¶
func (e *EDNS0_PADDING) String() string
type EDNS0_SUBNET ¶
type EDNS0_SUBNET struct { Code uint16 // Always EDNS0SUBNET Family uint16 // 1 for IP, 2 for IP6 SourceNetmask uint8 SourceScope uint8 Address net.IP }
EDNS0_SUBNET is the subnet option that is used to give the remote nameserver an idea of where the client lives. See RFC 7871. It can then give back a different answer depending on the location or network topology. Basic use pattern for creating an subnet option:
o := new(dns.OPT) o.Hdr.Name = "." o.Hdr.Rrtype = dns.TypeOPT e := new(dns.EDNS0_SUBNET) e.Code = dns.EDNS0SUBNET e.Family = 1 // 1 for IPv4 source address, 2 for IPv6 e.SourceNetmask = 32 // 32 for IPV4, 128 for IPv6 e.SourceScope = 0 e.Address = net.ParseIP("127.0.0.1").To4() // for IPv4 // e.Address = net.ParseIP("2001:7b8:32a::2") // for IPV6 o.Option = append(o.Option, e)
This code will parse all the available bits when unpacking (up to optlen). When packing it will apply SourceNetmask. If you need more advanced logic, patches welcome and good luck.
func (*EDNS0_SUBNET) Option ¶
func (e *EDNS0_SUBNET) Option() uint16
Option implements the EDNS0 interface.
func (*EDNS0_SUBNET) String ¶
func (e *EDNS0_SUBNET) String() (s string)
type EDNS0_TCP_KEEPALIVE ¶
type EDNS0_TCP_KEEPALIVE struct { Code uint16 // Always EDNSTCPKEEPALIVE Length uint16 // the value 0 if the TIMEOUT is omitted, the value 2 if it is present; Timeout uint16 // an idle timeout value for the TCP connection, specified in units of 100 milliseconds, encoded in network byte order. }
EDNS0_TCP_KEEPALIVE is an EDNS0 option that instructs the server to keep the TCP connection alive. See RFC 7828.
func (*EDNS0_TCP_KEEPALIVE) Option ¶
func (e *EDNS0_TCP_KEEPALIVE) Option() uint16
Option implements the EDNS0 interface.
func (*EDNS0_TCP_KEEPALIVE) String ¶
func (e *EDNS0_TCP_KEEPALIVE) String() (s string)
type EDNS0_UL ¶
The EDNS0_UL (Update Lease) (draft RFC) option is used to tell the server to set an expiration on an update RR. This is helpful for clients that cannot clean up after themselves. This is a draft RFC and more information can be found at https://tools.ietf.org/html/draft-sekar-dns-ul-02
o := new(dns.OPT) o.Hdr.Name = "." o.Hdr.Rrtype = dns.TypeOPT e := new(dns.EDNS0_UL) e.Code = dns.EDNS0UL e.Lease = 120 // in seconds o.Option = append(o.Option, e)
type Error ¶
type Error struct {
// contains filtered or unexported fields
}
Error represents a DNS error.
type HIP ¶
type HIP struct { Hdr RR_Header HitLength uint8 PublicKeyAlgorithm uint8 PublicKeyLength uint16 Hit string `dns:"size-hex:HitLength"` PublicKey string `dns:"size-base64:PublicKeyLength"` RendezvousServers []string `dns:"domain-name"` }
HIP RR. See RFC 8005.
type HTTPS ¶
type HTTPS struct {
SVCB
}
HTTPS RR. Everything valid for SVCB applies to HTTPS as well. Except that the HTTPS record is intended for use with the HTTP and HTTPS protocols.
type LOC ¶
type LOC struct { Hdr RR_Header Version uint8 Size uint8 HorizPre uint8 VertPre uint8 Latitude uint32 Longitude uint32 Altitude uint32 }
LOC RR. See RFC RFC 1876.
type MINFO ¶
type MINFO struct { Hdr RR_Header Rmail string `dns:"cdomain-name"` Email string `dns:"cdomain-name"` }
MINFO RR. See RFC 1035.
type Msg ¶
type Msg struct { MsgHdr Compress bool `json:"-"` // If true, the message will be compressed when converted to wire format. Question []Question // Holds the RR(s) of the question section. Answer []RR // Holds the RR(s) of the answer section. Ns []RR // Holds the RR(s) of the authority section. Extra []RR // Holds the RR(s) of the additional section. }
Msg contains the layout of a DNS message.
func (*Msg) IsEdns0 ¶
IsEdns0 checks if the message has a EDNS0 (OPT) record, any EDNS0 record in the additional section will do. It returns the OPT record found or nil.
func (*Msg) IsTsig ¶
IsTsig checks if the message has a TSIG record as the last record in the additional section. It returns the TSIG record found or nil.
func (*Msg) Len ¶
Len returns the message length when in (un)compressed wire format. If dns.Compress is true compression it is taken into account. Len() is provided to be a faster way to get the size of the resulting packet, than packing it, measuring the size and discarding the buffer.
func (*Msg) Pack ¶
Pack packs a Msg: it is converted to to wire format. If the dns.Compress is true the message will be in compressed wire format.
func (*Msg) PackBuffer ¶
PackBuffer packs a Msg, using the given buffer buf. If buf is too small a new buffer is allocated.
func (*Msg) SetEdns0 ¶
SetEdns0 appends a EDNS0 OPT RR to the message. TSIG should always the last RR in a message.
func (*Msg) SetNotify ¶
SetNotify creates a notify message, it sets the Question section, generates an Id and sets the Authoritative (AA) bit to true.
func (*Msg) SetQuestion ¶
SetQuestion creates a question message, it sets the Question section, generates an Id and sets the RecursionDesired (RD) bit to true.
func (*Msg) SetRcodeFormatError ¶
SetRcodeFormatError creates a message 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 TSIG is calculated when the message is being send.
func (*Msg) SetUpdate ¶
SetUpdate makes the message a dynamic update message. It sets the ZONE section to: z, TypeSOA, ClassINET.
func (*Msg) Truncate ¶
Truncate ensures the reply message will fit into the requested buffer size by removing records that exceed the requested size.
It will first check if the reply fits without compression and then with compression. If it won't fit with compression, Truncate then walks the record adding as many records as possible without exceeding the requested buffer size.
The TC bit will be set if any records were excluded from the message. If the TC bit is already set on the message it will be retained. TC indicates that the client should retry over TCP.
According to RFC 2181, the TC bit should only be set if not all of the "required" RRs can be included in the response. Unfortunately, we have no way of knowing which RRs are required so we set the TC bit if any RR had to be omitted from the response.
The appropriate buffer size can be retrieved from the requests OPT record, if present, and is transport specific otherwise. dns.MinMsgSize should be used for UDP requests without an OPT record, and dns.MaxMsgSize for TCP requests without an OPT record.
func (*Msg) UnpackWithTypes ¶
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 }
MsgHdr is a a manually-unpacked version of (id, bits).
type NAPTR ¶
type NAPTR struct { Hdr RR_Header Order uint16 Preference uint16 Flags string Service string Regexp string Replacement string `dns:"domain-name"` }
NAPTR RR. See RFC 2915.
type NINFO ¶
NINFO RR. See https://www.iana.org/assignments/dns-parameters/NINFO/ninfo-completed-template.
type NSEC ¶
type NSEC3 ¶
type NSEC3 struct { Hdr RR_Header Hash uint8 Flags uint8 Iterations uint16 SaltLength uint8 Salt string `dns:"size-hex:SaltLength"` HashLength uint8 NextDomain string `dns:"size-base32:HashLength"` TypeBitMap []uint16 `dns:"nsec"` }
NSEC3 RR. See RFC 5155.
type NSEC3PARAM ¶
type NSEC3PARAM struct { Hdr RR_Header Hash uint8 Flags uint8 Iterations uint16 SaltLength uint8 Salt string `dns:"size-hex:SaltLength"` }
NSEC3PARAM RR. See RFC 5155.
func (*NSEC3PARAM) Header ¶
func (rr *NSEC3PARAM) Header() *RR_Header
func (*NSEC3PARAM) String ¶
func (rr *NSEC3PARAM) String() string
type OPENPGPKEY ¶
OPENPGPKEY RR. See RFC 7929.
func (*OPENPGPKEY) Header ¶
func (rr *OPENPGPKEY) Header() *RR_Header
func (*OPENPGPKEY) String ¶
func (rr *OPENPGPKEY) String() string
type OPT ¶
OPT is the EDNS0 RR appended to messages to convey extra (meta) information. See RFC 6891.
func (*OPT) ExtendedRcode ¶
ExtendedRcode returns the EDNS extended RCODE field (the upper 8 bits of the TTL).
func (*OPT) SetDo ¶
SetDo sets the DO (DNSSEC OK) bit. If we pass an argument, set the DO bit to that value. It is possible to pass 2 or more arguments. Any arguments after the 1st is silently ignored.
func (*OPT) SetExtendedRcode ¶
SetExtendedRcode sets the EDNS extended RCODE field.
If the RCODE is not an extended RCODE, will reset the extended RCODE field to 0.
func (*OPT) SetUDPSize ¶
SetUDPSize sets the UDP buffer size.
func (*OPT) SetVersion ¶
SetVersion sets the version of EDNS. This is usually zero.
type PX ¶
type PX struct { Hdr RR_Header Preference uint16 Map822 string `dns:"domain-name"` Mapx400 string `dns:"domain-name"` }
PX RR. See RFC 2163.
type ParseError ¶
type ParseError struct {
// contains filtered or unexported fields
}
ParseError is a parsing error. It contains the parse error and the location in the io.Reader where the error occurred.
func (*ParseError) Error ¶
func (e *ParseError) Error() (s string)
type PrivateRR ¶
type PrivateRR struct { Hdr RR_Header Data PrivateRdata // contains filtered or unexported fields }
PrivateRR represents an RR that uses a PrivateRdata user-defined type. It mocks normal RRs and implements dns.RR interface.
type PrivateRdata ¶
type PrivateRdata interface { // String returns the text presentaton of the Rdata of the Private RR. String() string // Pack is used when packing a private RR into a buffer. Pack([]byte) (int, error) // Unpack is used when unpacking a private RR from a buffer. Unpack([]byte) (int, error) // Len returns the length in octets of the Rdata. Len() int }
PrivateRdata is an interface used for implementing "Private Use" RR types, see RFC 6895. This allows one to experiment with new RR types, without requesting an official type code. Also see dns.PrivateHandle and dns.PrivateHandleRemove.
type Question ¶
type Question struct { Name string `dns:"cdomain-name"` // "cdomain-name" specifies encoding (and may be compressed) Qtype uint16 Qclass uint16 }
Question holds a DNS question. Usually there is just one. While the original DNS RFCs allow multiple questions in the question section of a message, in practice it never works. Because most DNS servers see multiple questions as an error, it is recommended to only have one question per message.
type RKEY ¶
type RKEY struct { Hdr RR_Header Flags uint16 Protocol uint8 Algorithm uint8 PublicKey string `dns:"base64"` }
RKEY RR. See https://www.iana.org/assignments/dns-parameters/RKEY/rkey-completed-template.
type RP ¶
RP RR. See RFC 1138, Section 2.2.
type RR ¶
type RR interface { // Header returns the header of an resource record. The header contains // everything up to the rdata. Header() *RR_Header // String returns the text representation of the resource record. String() string // contains filtered or unexported methods }
An RR represents a resource record.
type RRSIG ¶
type RRSIG struct { Hdr RR_Header TypeCovered uint16 Algorithm uint8 Labels uint8 OrigTtl uint32 Expiration uint32 Inception uint32 KeyTag uint16 SignerName string `dns:"domain-name"` Signature string `dns:"base64"` }
RRSIG RR. See RFC 4034 and RFC 3755.
func (*RRSIG) Sign ¶
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 a non-nill error when the signing went OK. There is no check if RRSet is a proper (RFC 2181) RRSet. If OrigTTL is non zero, it is used as-is, otherwise the TTL of the RRset is used as the OrigTTL.
func (*RRSIG) ValidityPeriod ¶
ValidityPeriod uses RFC1982 serial arithmetic to calculate if a signature period is valid. If t is the zero time, the current time is taken other t is. Returns true if the signature is valid at the given time, otherwise returns false.
type RR_Header ¶
type RR_Header struct { Name string `dns:"cdomain-name"` Rrtype uint16 Class uint16 Ttl uint32 Rdlength uint16 // Length of data after header. }
RR_Header is the header all DNS resource records share.
type RT ¶
type RT struct { Hdr RR_Header Preference uint16 Host string `dns:"domain-name"` // RFC 3597 prohibits compressing records not defined in RFC 1035. }
RT RR. See RFC 1183, Section 3.3.
type SIG ¶
type SIG struct {
RRSIG
}
SIG RR. See RFC 2535. The SIG RR is identical to RRSIG and nowadays only used for SIG(0), See RFC 2931.
type SMIMEA ¶
type SMIMEA struct { Hdr RR_Header Usage uint8 Selector uint8 MatchingType uint8 Certificate string `dns:"hex"` }
SMIMEA RR. See RFC 8162.
type SOA ¶
type SOA struct { Hdr RR_Header Ns string `dns:"cdomain-name"` Mbox string `dns:"cdomain-name"` Serial uint32 Refresh uint32 Retry uint32 Expire uint32 Minttl uint32 }
SOA RR. See RFC 1035.
type SPF ¶
SPF RR. See RFC 4408, Section 3.1.1.
type SRV ¶
type SRV struct { Hdr RR_Header Priority uint16 Weight uint16 Port uint16 Target string `dns:"domain-name"` }
SRV RR. See RFC 2782.
type SVCB ¶
type SVCB struct { Hdr RR_Header Priority uint16 Target string `dns:"domain-name"` Value []SVCBKeyValue `dns:"pairs"` // Value must be empty if Priority is zero. }
SVCB RR. See RFC xxxx (https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-01).
type SVCBAlpn ¶
type SVCBAlpn struct {
Alpn []string
}
SVCBAlpn pair is used to list supported connection protocols. Protocol ids can be found at: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids Basic use pattern for creating an alpn option:
h := new(dns.HTTPS) h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET} e := new(dns.SVCBAlpn) e.Alpn = []string{"h2", "http/1.1"} h.Value = append(o.Value, e)
type SVCBECHConfig ¶
type SVCBECHConfig struct {
ECH []byte
}
SVCBECHConfig pair contains the ECHConfig structure defined in draft-ietf-tls-esni [RFC xxxx]. Basic use pattern for creating an echconfig option:
h := new(dns.HTTPS) h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET} e := new(dns.SVCBECHConfig) e.ECH = []byte{0xfe, 0x08, ...} h.Value = append(h.Value, e)
func (*SVCBECHConfig) Key ¶
func (*SVCBECHConfig) Key() SVCBKey
func (*SVCBECHConfig) String ¶
func (s *SVCBECHConfig) String() string
type SVCBIPv4Hint ¶
SVCBIPv4Hint pair suggests an IPv4 address which may be used to open connections if A and AAAA record responses for SVCB's Target domain haven't been received. In that case, optionally, A and AAAA requests can be made, after which the connection to the hinted IP address may be terminated and a new connection may be opened. Basic use pattern for creating an ipv4hint option:
h := new(dns.HTTPS) h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET} e := new(dns.SVCBIPv4Hint) e.Hint = []net.IP{net.IPv4(1,1,1,1).To4()} Or e.Hint = []net.IP{net.ParseIP("1.1.1.1").To4()} h.Value = append(h.Value, e)
func (*SVCBIPv4Hint) Key ¶
func (*SVCBIPv4Hint) Key() SVCBKey
func (*SVCBIPv4Hint) String ¶
func (s *SVCBIPv4Hint) String() string
type SVCBIPv6Hint ¶
SVCBIPv6Hint pair suggests an IPv6 address which may be used to open connections if A and AAAA record responses for SVCB's Target domain haven't been received. In that case, optionally, A and AAAA requests can be made, after which the connection to the hinted IP address may be terminated and a new connection may be opened. Basic use pattern for creating an ipv6hint option:
h := new(dns.HTTPS) h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET} e := new(dns.SVCBIPv6Hint) e.Hint = []net.IP{net.ParseIP("2001:db8::1")} h.Value = append(h.Value, e)
func (*SVCBIPv6Hint) Key ¶
func (*SVCBIPv6Hint) Key() SVCBKey
func (*SVCBIPv6Hint) String ¶
func (s *SVCBIPv6Hint) String() string
type SVCBKey ¶
type SVCBKey uint16
type SVCBKeyValue ¶
type SVCBKeyValue interface { Key() SVCBKey // Key returns the numerical key code. String() string // String returns the string representation of the value. // contains filtered or unexported methods }
SVCBKeyValue defines a key=value pair for the SVCB RR type. An SVCB RR can have multiple SVCBKeyValues appended to it.
type SVCBLocal ¶
type SVCBLocal struct { KeyCode SVCBKey // Never 65535 or any assigned keys. Data []byte // All byte sequences are allowed. }
SVCBLocal pair is intended for experimental/private use. The key is recommended to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER]. Basic use pattern for creating a keyNNNNN option:
h := new(dns.HTTPS) h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET} e := new(dns.SVCBLocal) e.KeyCode = 65400 e.Data = []byte("abc") h.Value = append(h.Value, e)
type SVCBMandatory ¶
type SVCBMandatory struct {
Code []SVCBKey // Must not include mandatory
}
SVCBMandatory pair adds to required keys that must be interpreted for the RR to be functional. Basic use pattern for creating a mandatory option:
s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}} e := new(dns.SVCBMandatory) e.Code = []uint16{65403} s.Value = append(s.Value, e)
func (*SVCBMandatory) Key ¶
func (*SVCBMandatory) Key() SVCBKey
func (*SVCBMandatory) String ¶
func (s *SVCBMandatory) String() string
type SVCBNoDefaultAlpn ¶
type SVCBNoDefaultAlpn struct{}
SVCBNoDefaultAlpn pair signifies no support for default connection protocols. Basic use pattern for creating a no-default-alpn option:
s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}} e := new(dns.SVCBNoDefaultAlpn) s.Value = append(s.Value, e)
func (*SVCBNoDefaultAlpn) Key ¶
func (*SVCBNoDefaultAlpn) Key() SVCBKey
func (*SVCBNoDefaultAlpn) String ¶
func (*SVCBNoDefaultAlpn) String() string
type SVCBPort ¶
type SVCBPort struct {
Port uint16
}
SVCBPort pair defines the port for connection. Basic use pattern for creating a port option:
s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}} e := new(dns.SVCBPort) e.Port = 80 s.Value = append(s.Value, e)
type TA ¶
type TA struct { Hdr RR_Header KeyTag uint16 Algorithm uint8 DigestType uint8 Digest string `dns:"hex"` }
TA RR. See http://www.watson.org/~weiler/INI1999-19.pdf.
type TALINK ¶
type TALINK struct { Hdr RR_Header PreviousName string `dns:"domain-name"` NextName string `dns:"domain-name"` }
TALINK RR. See https://www.iana.org/assignments/dns-parameters/TALINK/talink-completed-template.
type TKEY ¶
type TKEY struct { Hdr RR_Header Algorithm string `dns:"domain-name"` Inception uint32 Expiration uint32 Mode uint16 Error uint16 KeySize uint16 Key string `dns:"size-hex:KeySize"` OtherLen uint16 OtherData string `dns:"size-hex:OtherLen"` }
TKEY RR. See RFC 2930.
type TLSA ¶
type TLSA struct { Hdr RR_Header Usage uint8 Selector uint8 MatchingType uint8 Certificate string `dns:"hex"` }
TLSA RR. See RFC 6698.
type TSIG ¶
type TSIG struct { Hdr RR_Header Algorithm string `dns:"domain-name"` TimeSigned uint64 `dns:"uint48"` Fudge uint16 MACSize uint16 MAC string `dns:"size-hex:MACSize"` OrigId uint16 Error uint16 OtherLen uint16 OtherData string `dns:"size-hex:OtherLen"` }
TSIG is the RR the holds the transaction signature of a message. See RFC 2845 and RFC 4635.
type TsigProvider ¶
type TsigProvider interface { // Generate is passed the DNS message to be signed and the partial TSIG RR. It returns the signature and nil, otherwise an error. Generate(msg []byte, t *TSIG) ([]byte, error) // Verify is passed the DNS message to be verified and the TSIG RR. If the signature is valid it will return nil, otherwise an error. Verify(msg []byte, t *TSIG) error }
TsigProvider provides the API to plug-in a custom TSIG implementation.