Documentation ¶
Overview ¶
Package dnsmessage provides a mostly RFC 1035 compliant implementation of DNS message packing and unpacking.
This implementation is designed to minimize heap allocations and avoid unnecessary packing and unpacking as much as possible.
Index ¶
- Constants
- Variables
- type AAAAResource
- type AResource
- type Builder
- func (b *Builder) AAAAResource(h ResourceHeader, r AAAAResource) error
- func (b *Builder) AResource(h ResourceHeader, r AResource) error
- func (b *Builder) CNAMEResource(h ResourceHeader, r CNAMEResource) error
- func (b *Builder) EnableCompression()
- func (b *Builder) Finish() ([]byte, error)
- func (b *Builder) MXResource(h ResourceHeader, r MXResource) error
- func (b *Builder) NSResource(h ResourceHeader, r NSResource) error
- func (b *Builder) PTRResource(h ResourceHeader, r PTRResource) error
- func (b *Builder) Question(q Question) error
- func (b *Builder) SOAResource(h ResourceHeader, r SOAResource) error
- func (b *Builder) SRVResource(h ResourceHeader, r SRVResource) error
- func (b *Builder) StartAdditionals() error
- func (b *Builder) StartAnswers() error
- func (b *Builder) StartAuthorities() error
- func (b *Builder) StartQuestions() error
- func (b *Builder) TXTResource(h ResourceHeader, r TXTResource) error
- type CNAMEResource
- type Class
- type Header
- type MXResource
- type Message
- type NSResource
- type Name
- type OpCode
- type PTRResource
- type Parser
- func (p *Parser) AAAAResource() (AAAAResource, error)
- func (p *Parser) AResource() (AResource, error)
- func (p *Parser) Additional() (Resource, error)
- func (p *Parser) AdditionalHeader() (ResourceHeader, error)
- func (p *Parser) AllAdditionals() ([]Resource, error)
- func (p *Parser) AllAnswers() ([]Resource, error)
- func (p *Parser) AllAuthorities() ([]Resource, error)
- func (p *Parser) AllQuestions() ([]Question, error)
- func (p *Parser) Answer() (Resource, error)
- func (p *Parser) AnswerHeader() (ResourceHeader, error)
- func (p *Parser) Authority() (Resource, error)
- func (p *Parser) AuthorityHeader() (ResourceHeader, error)
- func (p *Parser) CNAMEResource() (CNAMEResource, error)
- func (p *Parser) MXResource() (MXResource, error)
- func (p *Parser) NSResource() (NSResource, error)
- func (p *Parser) PTRResource() (PTRResource, error)
- func (p *Parser) Question() (Question, error)
- func (p *Parser) SOAResource() (SOAResource, error)
- func (p *Parser) SRVResource() (SRVResource, error)
- func (p *Parser) SkipAdditional() error
- func (p *Parser) SkipAllAdditionals() error
- func (p *Parser) SkipAllAnswers() error
- func (p *Parser) SkipAllAuthorities() error
- func (p *Parser) SkipAllQuestions() error
- func (p *Parser) SkipAnswer() error
- func (p *Parser) SkipAuthority() error
- func (p *Parser) SkipQuestion() error
- func (p *Parser) Start(msg []byte) (Header, error)
- func (p *Parser) TXTResource() (TXTResource, error)
- type Question
- type RCode
- type Resource
- type ResourceBody
- type ResourceHeader
- type SOAResource
- type SRVResource
- type TXTResource
- type Type
Examples ¶
Constants ¶
const ( // ResourceHeader.Type and Question.Type TypeA Type = 1 TypeNS Type = 2 TypeCNAME Type = 5 TypeSOA Type = 6 TypePTR Type = 12 TypeMX Type = 15 TypeTXT Type = 16 TypeAAAA Type = 28 TypeSRV Type = 33 // Question.Type TypeWKS Type = 11 TypeHINFO Type = 13 TypeMINFO Type = 14 TypeAXFR Type = 252 TypeALL Type = 255 // ResourceHeader.Class and Question.Class ClassINET Class = 1 ClassCSNET Class = 2 ClassCHAOS Class = 3 ClassHESIOD Class = 4 // Question.Class ClassANY Class = 255 // Message.Rcode RCodeSuccess RCode = 0 RCodeFormatError RCode = 1 RCodeServerFailure RCode = 2 RCodeNameError RCode = 3 RCodeNotImplemented RCode = 4 RCodeRefused RCode = 5 )
Wire constants.
Variables ¶
var ( // ErrNotStarted indicates that the prerequisite information isn't // available yet because the previous records haven't been appropriately // parsed, skipped or finished. ErrNotStarted = errors.New("parsing/packing of this type isn't available yet") // ErrSectionDone indicated that all records in the section have been // parsed or finished. ErrSectionDone = errors.New("parsing/packing of this section has completed") )
Functions ¶
This section is empty.
Types ¶
type AAAAResource ¶
type AAAAResource struct {
AAAA [16]byte
}
An AAAAResource is an AAAA Resource record.
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
A Builder allows incrementally packing a DNS message.
Example usage:
buf := make([]byte, 2, 514) b := NewBuilder(buf, Header{...}) b.EnableCompression() // Optionally start a section and add things to that section. // Repeat adding sections as necessary. buf, err := b.Finish() // If err is nil, buf[2:] will contain the built bytes.
func NewBuilder ¶
NewBuilder creates a new builder with compression disabled.
Note: Most users will want to immediately enable compression with the EnableCompression method. See that method's comment for why you may or may not want to enable compression.
The DNS message is appended to the provided initial buffer buf (which may be nil) as it is built. The final message is returned by the (*Builder).Finish method, which may return the same underlying array if there was sufficient capacity in the slice.
func (*Builder) AAAAResource ¶
func (b *Builder) AAAAResource(h ResourceHeader, r AAAAResource) error
AAAAResource adds a single AAAAResource.
func (*Builder) AResource ¶
func (b *Builder) AResource(h ResourceHeader, r AResource) error
AResource adds a single AResource.
func (*Builder) CNAMEResource ¶
func (b *Builder) CNAMEResource(h ResourceHeader, r CNAMEResource) error
CNAMEResource adds a single CNAMEResource.
func (*Builder) EnableCompression ¶
func (b *Builder) EnableCompression()
EnableCompression enables compression in the Builder.
Leaving compression disabled avoids compression related allocations, but can result in larger message sizes. Be careful with this mode as it can cause messages to exceed the UDP size limit.
According to RFC 1035, section 4.1.4, the use of compression is optional, but all implementations must accept both compressed and uncompressed DNS messages.
Compression should be enabled before any sections are added for best results.
func (*Builder) MXResource ¶
func (b *Builder) MXResource(h ResourceHeader, r MXResource) error
MXResource adds a single MXResource.
func (*Builder) NSResource ¶
func (b *Builder) NSResource(h ResourceHeader, r NSResource) error
NSResource adds a single NSResource.
func (*Builder) PTRResource ¶
func (b *Builder) PTRResource(h ResourceHeader, r PTRResource) error
PTRResource adds a single PTRResource.
func (*Builder) SOAResource ¶
func (b *Builder) SOAResource(h ResourceHeader, r SOAResource) error
SOAResource adds a single SOAResource.
func (*Builder) SRVResource ¶
func (b *Builder) SRVResource(h ResourceHeader, r SRVResource) error
SRVResource adds a single SRVResource.
func (*Builder) StartAdditionals ¶
StartAdditionals prepares the builder for packing Additionals.
func (*Builder) StartAnswers ¶
StartAnswers prepares the builder for packing Answers.
func (*Builder) StartAuthorities ¶
StartAuthorities prepares the builder for packing Authorities.
func (*Builder) StartQuestions ¶
StartQuestions prepares the builder for packing Questions.
func (*Builder) TXTResource ¶
func (b *Builder) TXTResource(h ResourceHeader, r TXTResource) error
TXTResource adds a single TXTResource.
type CNAMEResource ¶
type CNAMEResource struct {
CNAME Name
}
A CNAMEResource is a CNAME Resource record.
type Header ¶
type Header struct { ID uint16 Response bool OpCode OpCode Authoritative bool Truncated bool RecursionDesired bool RecursionAvailable bool RCode RCode }
Header is a representation of a DNS message header.
type MXResource ¶
An MXResource is an MX Resource record.
type Message ¶
type Message struct { Header Questions []Question Answers []Resource Authorities []Resource Additionals []Resource }
Message is a representation of a DNS message.
func (*Message) AppendPack ¶
AppendPack is like Pack but appends the full Message to b and returns the extended buffer.
type Name ¶
A Name is a non-encoded domain name. It is used instead of strings to avoid allocations.
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
A Parser allows incrementally parsing a DNS message.
When parsing is started, the Header is parsed. Next, each Question can be either parsed or skipped. Alternatively, all Questions can be skipped at once. When all Questions have been parsed, attempting to parse Questions will return (nil, nil) and attempting to skip Questions will return (true, nil). After all Questions have been either parsed or skipped, all Answers, Authorities and Additionals can be either parsed or skipped in the same way, and each type of Resource must be fully parsed or skipped before proceeding to the next type of Resource.
Note that there is no requirement to fully skip or parse the message.
Example ¶
package main import ( "fmt" "net" "strings" "internal/x/net/dns/dnsmessage" ) func mustNewName(name string) dnsmessage.Name { n, err := dnsmessage.NewName(name) if err != nil { panic(err) } return n } func main() { msg := dnsmessage.Message{ Header: dnsmessage.Header{Response: true, Authoritative: true}, Questions: []dnsmessage.Question{ { Name: mustNewName("foo.bar.example.com."), Type: dnsmessage.TypeA, Class: dnsmessage.ClassINET, }, { Name: mustNewName("bar.example.com."), Type: dnsmessage.TypeA, Class: dnsmessage.ClassINET, }, }, Answers: []dnsmessage.Resource{ { Header: dnsmessage.ResourceHeader{ Name: mustNewName("foo.bar.example.com."), Type: dnsmessage.TypeA, Class: dnsmessage.ClassINET, }, Body: &dnsmessage.AResource{A: [4]byte{127, 0, 0, 1}}, }, { Header: dnsmessage.ResourceHeader{ Name: mustNewName("bar.example.com."), Type: dnsmessage.TypeA, Class: dnsmessage.ClassINET, }, Body: &dnsmessage.AResource{A: [4]byte{127, 0, 0, 2}}, }, }, } buf, err := msg.Pack() if err != nil { panic(err) } wantName := "bar.example.com." var p dnsmessage.Parser if _, err := p.Start(buf); err != nil { panic(err) } for { q, err := p.Question() if err == dnsmessage.ErrSectionDone { break } if err != nil { panic(err) } if q.Name.String() != wantName { continue } fmt.Println("Found question for name", wantName) if err := p.SkipAllQuestions(); err != nil { panic(err) } break } var gotIPs []net.IP for { h, err := p.AnswerHeader() if err == dnsmessage.ErrSectionDone { break } if err != nil { panic(err) } if (h.Type != dnsmessage.TypeA && h.Type != dnsmessage.TypeAAAA) || h.Class != dnsmessage.ClassINET { continue } if !strings.EqualFold(h.Name.String(), wantName) { if err := p.SkipAnswer(); err != nil { panic(err) } continue } switch h.Type { case dnsmessage.TypeA: r, err := p.AResource() if err != nil { panic(err) } gotIPs = append(gotIPs, r.A[:]) case dnsmessage.TypeAAAA: r, err := p.AAAAResource() if err != nil { panic(err) } gotIPs = append(gotIPs, r.AAAA[:]) } } fmt.Printf("Found A/AAAA records for name %s: %v\n", wantName, gotIPs) }
Output: Found question for name bar.example.com. Found A/AAAA records for name bar.example.com.: [127.0.0.2]
func (*Parser) AAAAResource ¶
func (p *Parser) AAAAResource() (AAAAResource, error)
AAAAResource parses a single AAAAResource.
One of the XXXHeader methods must have been called before calling this method.
func (*Parser) AResource ¶
AResource parses a single AResource.
One of the XXXHeader methods must have been called before calling this method.
func (*Parser) Additional ¶
Additional parses a single Additional Resource.
func (*Parser) AdditionalHeader ¶
func (p *Parser) AdditionalHeader() (ResourceHeader, error)
AdditionalHeader parses a single Additional ResourceHeader.
func (*Parser) AllAdditionals ¶
AllAdditionals parses all Additional Resources.
func (*Parser) AllAnswers ¶
AllAnswers parses all Answer Resources.
func (*Parser) AllAuthorities ¶
AllAuthorities parses all Authority Resources.
func (*Parser) AllQuestions ¶
AllQuestions parses all Questions.
func (*Parser) AnswerHeader ¶
func (p *Parser) AnswerHeader() (ResourceHeader, error)
AnswerHeader parses a single Answer ResourceHeader.
func (*Parser) AuthorityHeader ¶
func (p *Parser) AuthorityHeader() (ResourceHeader, error)
AuthorityHeader parses a single Authority ResourceHeader.
func (*Parser) CNAMEResource ¶
func (p *Parser) CNAMEResource() (CNAMEResource, error)
CNAMEResource parses a single CNAMEResource.
One of the XXXHeader methods must have been called before calling this method.
func (*Parser) MXResource ¶
func (p *Parser) MXResource() (MXResource, error)
MXResource parses a single MXResource.
One of the XXXHeader methods must have been called before calling this method.
func (*Parser) NSResource ¶
func (p *Parser) NSResource() (NSResource, error)
NSResource parses a single NSResource.
One of the XXXHeader methods must have been called before calling this method.
func (*Parser) PTRResource ¶
func (p *Parser) PTRResource() (PTRResource, error)
PTRResource parses a single PTRResource.
One of the XXXHeader methods must have been called before calling this method.
func (*Parser) SOAResource ¶
func (p *Parser) SOAResource() (SOAResource, error)
SOAResource parses a single SOAResource.
One of the XXXHeader methods must have been called before calling this method.
func (*Parser) SRVResource ¶
func (p *Parser) SRVResource() (SRVResource, error)
SRVResource parses a single SRVResource.
One of the XXXHeader methods must have been called before calling this method.
func (*Parser) SkipAdditional ¶
SkipAdditional skips a single Additional Resource.
func (*Parser) SkipAllAdditionals ¶
SkipAllAdditionals skips all Additional Resources.
func (*Parser) SkipAllAnswers ¶
SkipAllAnswers skips all Answer Resources.
func (*Parser) SkipAllAuthorities ¶
SkipAllAuthorities skips all Authority Resources.
func (*Parser) SkipAllQuestions ¶
SkipAllQuestions skips all Questions.
func (*Parser) SkipAnswer ¶
SkipAnswer skips a single Answer Resource.
func (*Parser) SkipAuthority ¶
SkipAuthority skips a single Authority Resource.
func (*Parser) SkipQuestion ¶
SkipQuestion skips a single Question.
func (*Parser) TXTResource ¶
func (p *Parser) TXTResource() (TXTResource, error)
TXTResource parses a single TXTResource.
One of the XXXHeader methods must have been called before calling this method.
type Resource ¶
type Resource struct { Header ResourceHeader Body ResourceBody }
A Resource is a DNS resource record.
type ResourceBody ¶
type ResourceBody interface {
// contains filtered or unexported methods
}
A ResourceBody is a DNS resource record minus the header.
type ResourceHeader ¶
type ResourceHeader struct { // Name is the domain name for which this resource record pertains. Name Name // Type is the type of DNS resource record. // // This field will be set automatically during packing. Type Type // Class is the class of network to which this DNS resource record // pertains. Class Class // TTL is the length of time (measured in seconds) which this resource // record is valid for (time to live). All Resources in a set should // have the same TTL (RFC 2181 Section 5.2). TTL uint32 // Length is the length of data in the resource record after the header. // // This field will be set automatically during packing. Length uint16 }
A ResourceHeader is the header of a DNS resource record. There are many types of DNS resource records, but they all share the same header.
type SOAResource ¶
type SOAResource struct { NS Name MBox Name Serial uint32 Refresh uint32 Retry uint32 Expire uint32 // MinTTL the is the default TTL of Resources records which did not // contain a TTL value and the TTL of negative responses. (RFC 2308 // Section 4) MinTTL uint32 }
An SOAResource is an SOA Resource record.