Source File
message.go
Belonging Package
vendor/golang.org/x/net/dns/dnsmessage
package dnsmessage
import (
)
TypeWKS Type = 11
TypeHINFO Type = 13
TypeMINFO Type = 14
TypeAXFR Type = 252
TypeALL Type = 255
)
var typeNames = map[Type]string{
TypeA: "TypeA",
TypeNS: "TypeNS",
TypeCNAME: "TypeCNAME",
TypeSOA: "TypeSOA",
TypePTR: "TypePTR",
TypeMX: "TypeMX",
TypeTXT: "TypeTXT",
TypeAAAA: "TypeAAAA",
TypeSRV: "TypeSRV",
TypeOPT: "TypeOPT",
TypeWKS: "TypeWKS",
TypeHINFO: "TypeHINFO",
TypeMINFO: "TypeMINFO",
TypeAXFR: "TypeAXFR",
TypeALL: "TypeALL",
}
func ( Type) () string {
if , := typeNames[]; {
return
}
return printUint16(uint16())
}
func ( Type) () string {
if , := typeNames[]; {
return "dnsmessage." +
}
return printUint16(uint16())
}
ClassINET Class = 1
ClassCSNET Class = 2
ClassCHAOS Class = 3
ClassHESIOD Class = 4
ClassANY Class = 255
)
var classNames = map[Class]string{
ClassINET: "ClassINET",
ClassCSNET: "ClassCSNET",
ClassCHAOS: "ClassCHAOS",
ClassHESIOD: "ClassHESIOD",
ClassANY: "ClassANY",
}
func ( Class) () string {
if , := classNames[]; {
return
}
return printUint16(uint16())
}
func ( Class) () string {
if , := classNames[]; {
return "dnsmessage." +
}
return printUint16(uint16())
}
func ( OpCode) () string {
return printUint16(uint16())
}
RCodeSuccess RCode = 0
RCodeFormatError RCode = 1
RCodeServerFailure RCode = 2
RCodeNameError RCode = 3
RCodeNotImplemented RCode = 4
RCodeRefused RCode = 5
)
var rCodeNames = map[RCode]string{
RCodeSuccess: "RCodeSuccess",
RCodeFormatError: "RCodeFormatError",
RCodeServerFailure: "RCodeServerFailure",
RCodeNameError: "RCodeNameError",
RCodeNotImplemented: "RCodeNotImplemented",
RCodeRefused: "RCodeRefused",
}
func ( RCode) () string {
if , := rCodeNames[]; {
return
}
return printUint16(uint16())
}
func ( RCode) () string {
if , := rCodeNames[]; {
return "dnsmessage." +
}
return printUint16(uint16())
}
func ( uint8) string {
:= byte()
return string([]byte{
/100 + '0',
/10%10 + '0',
%10 + '0',
})
}
func ( []byte, uint8) []byte {
:= byte()
if >= 100 {
= append(, /100+'0')
}
if >= 10 {
= append(, /10%10+'0')
}
return append(, %10+'0')
}
func ( []byte) string {
if len() == 0 {
return ""
}
:= make([]byte, 0, 5*len())
= printUint8Bytes(, uint8([0]))
for , := range [1:] {
= append(, ',', ' ')
= printUint8Bytes(, uint8())
}
return string()
}
const hexDigits = "0123456789abcdef"
func ( []byte) string {
:= make([]byte, 0, len())
for := 0; < len(); ++ {
:= []
if == '.' || == '-' || == ' ' ||
'A' <= && <= 'Z' ||
'a' <= && <= 'z' ||
'0' <= && <= '9' {
= append(, )
continue
}
:= >> 4
:= ( << 4) >> 4
= append(
,
'\\',
'x',
hexDigits[],
hexDigits[],
)
}
return string()
}
func ( uint16) string {
return printUint32(uint32())
}
ErrNotStarted = errors.New("parsing/packing of this type isn't available yet")
ErrSectionDone = errors.New("parsing/packing of this section has completed")
errBaseLen = errors.New("insufficient data for base length type")
errCalcLen = errors.New("insufficient data for calculated length type")
errReserved = errors.New("segment prefix is reserved")
errTooManyPtr = errors.New("too many pointers (>10)")
errInvalidPtr = errors.New("invalid pointer")
errNilResouceBody = errors.New("nil resource body")
errResourceLen = errors.New("insufficient data for resource body length")
errSegTooLong = errors.New("segment length too long")
errZeroSegLen = errors.New("zero length segment")
errResTooLong = errors.New("resource length too long")
errTooManyQuestions = errors.New("too many Questions to pack (>65535)")
errTooManyAnswers = errors.New("too many Answers to pack (>65535)")
errTooManyAuthorities = errors.New("too many Authorities to pack (>65535)")
errTooManyAdditionals = errors.New("too many Additionals to pack (>65535)")
errNonCanonicalName = errors.New("name is not in canonical format (it must end with a .)")
errStringTooLong = errors.New("character string exceeds maximum length (255)")
errCompressedSRV = errors.New("compressed name in SRV resource data")
)
packStartingCap = 512
uint16Len = 2
uint32Len = 4
func ( *nestedError) () string {
return .s + ": " + .err.Error()
}
type Header struct {
ID uint16
Response bool
OpCode OpCode
Authoritative bool
Truncated bool
RecursionDesired bool
RecursionAvailable bool
RCode RCode
}
func ( *Header) () ( uint16, uint16) {
= .ID
= uint16(.OpCode)<<11 | uint16(.RCode)
if .RecursionAvailable {
|= headerBitRA
}
if .RecursionDesired {
|= headerBitRD
}
if .Truncated {
|= headerBitTC
}
if .Authoritative {
|= headerBitAA
}
if .Response {
|= headerBitQR
}
return
}
func ( *Header) () string {
return "dnsmessage.Header{" +
"ID: " + printUint16(.ID) + ", " +
"Response: " + printBool(.Response) + ", " +
"OpCode: " + .OpCode.GoString() + ", " +
"Authoritative: " + printBool(.Authoritative) + ", " +
"Truncated: " + printBool(.Truncated) + ", " +
"RecursionDesired: " + printBool(.RecursionDesired) + ", " +
"RecursionAvailable: " + printBool(.RecursionAvailable) + ", " +
"RCode: " + .RCode.GoString() + "}"
}
type Message struct {
Header
Questions []Question
Answers []Resource
Authorities []Resource
Additionals []Resource
}
type section uint8
const (
sectionNotStarted section = iota
sectionHeader
sectionQuestions
sectionAnswers
sectionAuthorities
sectionAdditionals
sectionDone
headerBitQR = 1 << 15 // query/response (response=1)
headerBitAA = 1 << 10 // authoritative
headerBitTC = 1 << 9 // truncated
headerBitRD = 1 << 8 // recursion desired
headerBitRA = 1 << 7 // recursion available
)
var sectionNames = map[section]string{
sectionHeader: "header",
sectionQuestions: "Question",
sectionAnswers: "Answer",
sectionAuthorities: "Authority",
sectionAdditionals: "Additional",
}
type header struct {
id uint16
bits uint16
questions uint16
answers uint16
authorities uint16
additionals uint16
}
func ( *header) ( section) uint16 {
switch {
case sectionQuestions:
return .questions
case sectionAnswers:
return .answers
case sectionAuthorities:
return .authorities
case sectionAdditionals:
return .additionals
}
return 0
}
func ( *header) ( []byte) []byte {
= packUint16(, .id)
= packUint16(, .bits)
= packUint16(, .questions)
= packUint16(, .answers)
= packUint16(, .authorities)
return packUint16(, .additionals)
}
func ( *header) ( []byte, int) (int, error) {
:=
var error
if .id, , = unpackUint16(, ); != nil {
return , &nestedError{"id", }
}
if .bits, , = unpackUint16(, ); != nil {
return , &nestedError{"bits", }
}
if .questions, , = unpackUint16(, ); != nil {
return , &nestedError{"questions", }
}
if .answers, , = unpackUint16(, ); != nil {
return , &nestedError{"answers", }
}
if .authorities, , = unpackUint16(, ); != nil {
return , &nestedError{"authorities", }
}
if .additionals, , = unpackUint16(, ); != nil {
return , &nestedError{"additionals", }
}
return , nil
}
func ( *header) () Header {
return Header{
ID: .id,
Response: (.bits & headerBitQR) != 0,
OpCode: OpCode(.bits>>11) & 0xF,
Authoritative: (.bits & headerBitAA) != 0,
Truncated: (.bits & headerBitTC) != 0,
RecursionDesired: (.bits & headerBitRD) != 0,
RecursionAvailable: (.bits & headerBitRA) != 0,
RCode: RCode(.bits & 0xF),
}
}
realType() Type
GoString() string
}
func ( *Resource) ( []byte, map[string]int, int) ([]byte, error) {
if .Body == nil {
return , errNilResouceBody
}
:=
.Header.Type = .Body.realType()
, , := .Header.pack(, , )
if != nil {
return , &nestedError{"ResourceHeader", }
}
:= len()
, = .Body.pack(, , )
if != nil {
return , &nestedError{"content", }
}
if := .Header.fixLen(, , ); != nil {
return ,
}
return , nil
}
func ( *Parser) ( []byte) (Header, error) {
if .msg != nil {
* = Parser{}
}
.msg =
var error
if .off, = .header.unpack(, 0); != nil {
return Header{}, &nestedError{"unpacking header", }
}
.section = sectionQuestions
return .header.header(), nil
}
func ( *Parser) ( section) error {
if .section < {
return ErrNotStarted
}
if .section > {
return ErrSectionDone
}
.resHeaderValid = false
if .index == int(.header.count()) {
.index = 0
.section++
return ErrSectionDone
}
return nil
}
func ( *Parser) ( section) (Resource, error) {
var Resource
var error
.Header, = .resourceHeader()
if != nil {
return ,
}
.resHeaderValid = false
.Body, .off, = unpackResourceBody(.msg, .off, .Header)
if != nil {
return Resource{}, &nestedError{"unpacking " + sectionNames[], }
}
.index++
return , nil
}
func ( *Parser) ( section) (ResourceHeader, error) {
if .resHeaderValid {
return .resHeader, nil
}
if := .checkAdvance(); != nil {
return ResourceHeader{},
}
var ResourceHeader
, := .unpack(.msg, .off)
if != nil {
return ResourceHeader{},
}
.resHeaderValid = true
.resHeader =
.off =
return , nil
}
func ( *Parser) ( section) error {
if .resHeaderValid {
:= .off + int(.resHeader.Length)
if > len(.msg) {
return errResourceLen
}
.off =
.resHeaderValid = false
.index++
return nil
}
if := .checkAdvance(); != nil {
return
}
var error
.off, = skipResource(.msg, .off)
if != nil {
return &nestedError{"skipping: " + sectionNames[], }
}
.index++
return nil
}
func ( *Parser) () (Question, error) {
if := .checkAdvance(sectionQuestions); != nil {
return Question{},
}
var Name
, := .unpack(.msg, .off)
if != nil {
return Question{}, &nestedError{"unpacking Question.Name", }
}
, , := unpackType(.msg, )
if != nil {
return Question{}, &nestedError{"unpacking Question.Type", }
}
, , := unpackClass(.msg, )
if != nil {
return Question{}, &nestedError{"unpacking Question.Class", }
}
.off =
.index++
return Question{, , }, nil
}
func ( *Parser) () error {
if := .checkAdvance(sectionQuestions); != nil {
return
}
, := skipName(.msg, .off)
if != nil {
return &nestedError{"skipping Question Name", }
}
if , = skipType(.msg, ); != nil {
return &nestedError{"skipping Question Type", }
}
if , = skipClass(.msg, ); != nil {
return &nestedError{"skipping Question Class", }
}
.off =
.index++
return nil
}
func ( *Parser) () error {
for {
if := .SkipQuestion(); == ErrSectionDone {
return nil
} else if != nil {
return
}
}
}
func ( *Parser) () (ResourceHeader, error) {
return .resourceHeader(sectionAnswers)
}
func ( *Parser) () (Resource, error) {
return .resource(sectionAnswers)
}
func ( *Parser) () error {
return .skipResource(sectionAnswers)
}
func ( *Parser) () error {
for {
if := .SkipAnswer(); == ErrSectionDone {
return nil
} else if != nil {
return
}
}
}
func ( *Parser) () (ResourceHeader, error) {
return .resourceHeader(sectionAuthorities)
}
func ( *Parser) () (Resource, error) {
return .resource(sectionAuthorities)
}
func ( *Parser) () error {
return .skipResource(sectionAuthorities)
}
func ( *Parser) () error {
for {
if := .SkipAuthority(); == ErrSectionDone {
return nil
} else if != nil {
return
}
}
}
func ( *Parser) () (ResourceHeader, error) {
return .resourceHeader(sectionAdditionals)
}
func ( *Parser) () (Resource, error) {
return .resource(sectionAdditionals)
}
:= int(.header.additionals)
if > 10 {
= 10
}
:= make([]Resource, 0, )
for {
, := .Additional()
if == ErrSectionDone {
return , nil
}
if != nil {
return nil,
}
= append(, )
}
}
func ( *Parser) () error {
return .skipResource(sectionAdditionals)
}
func ( *Parser) () error {
for {
if := .SkipAdditional(); == ErrSectionDone {
return nil
} else if != nil {
return
}
}
}
func ( *Parser) () (CNAMEResource, error) {
if !.resHeaderValid || .resHeader.Type != TypeCNAME {
return CNAMEResource{}, ErrNotStarted
}
, := unpackCNAMEResource(.msg, .off)
if != nil {
return CNAMEResource{},
}
.off += int(.resHeader.Length)
.resHeaderValid = false
.index++
return , nil
}
func ( *Parser) () (MXResource, error) {
if !.resHeaderValid || .resHeader.Type != TypeMX {
return MXResource{}, ErrNotStarted
}
, := unpackMXResource(.msg, .off)
if != nil {
return MXResource{},
}
.off += int(.resHeader.Length)
.resHeaderValid = false
.index++
return , nil
}
func ( *Parser) () (NSResource, error) {
if !.resHeaderValid || .resHeader.Type != TypeNS {
return NSResource{}, ErrNotStarted
}
, := unpackNSResource(.msg, .off)
if != nil {
return NSResource{},
}
.off += int(.resHeader.Length)
.resHeaderValid = false
.index++
return , nil
}
func ( *Parser) () (PTRResource, error) {
if !.resHeaderValid || .resHeader.Type != TypePTR {
return PTRResource{}, ErrNotStarted
}
, := unpackPTRResource(.msg, .off)
if != nil {
return PTRResource{},
}
.off += int(.resHeader.Length)
.resHeaderValid = false
.index++
return , nil
}
func ( *Parser) () (SOAResource, error) {
if !.resHeaderValid || .resHeader.Type != TypeSOA {
return SOAResource{}, ErrNotStarted
}
, := unpackSOAResource(.msg, .off)
if != nil {
return SOAResource{},
}
.off += int(.resHeader.Length)
.resHeaderValid = false
.index++
return , nil
}
func ( *Parser) () (TXTResource, error) {
if !.resHeaderValid || .resHeader.Type != TypeTXT {
return TXTResource{}, ErrNotStarted
}
, := unpackTXTResource(.msg, .off, .resHeader.Length)
if != nil {
return TXTResource{},
}
.off += int(.resHeader.Length)
.resHeaderValid = false
.index++
return , nil
}
func ( *Parser) () (SRVResource, error) {
if !.resHeaderValid || .resHeader.Type != TypeSRV {
return SRVResource{}, ErrNotStarted
}
, := unpackSRVResource(.msg, .off)
if != nil {
return SRVResource{},
}
.off += int(.resHeader.Length)
.resHeaderValid = false
.index++
return , nil
}
func ( *Parser) () (AAAAResource, error) {
if !.resHeaderValid || .resHeader.Type != TypeAAAA {
return AAAAResource{}, ErrNotStarted
}
, := unpackAAAAResource(.msg, .off)
if != nil {
return AAAAResource{},
}
.off += int(.resHeader.Length)
.resHeaderValid = false
.index++
return , nil
}
func ( *Parser) () (OPTResource, error) {
if !.resHeaderValid || .resHeader.Type != TypeOPT {
return OPTResource{}, ErrNotStarted
}
, := unpackOPTResource(.msg, .off, .resHeader.Length)
if != nil {
return OPTResource{},
}
.off += int(.resHeader.Length)
.resHeaderValid = false
.index++
return , nil
}
func ( *Message) ( []byte) error {
var Parser
var error
if .Header, = .Start(); != nil {
return
}
if .Questions, = .AllQuestions(); != nil {
return
}
if .Answers, = .AllAnswers(); != nil {
return
}
if .Authorities, = .AllAuthorities(); != nil {
return
}
if .Additionals, = .AllAdditionals(); != nil {
return
}
return nil
}
func ( *Message) () ([]byte, error) {
return .AppendPack(make([]byte, 0, packStartingCap))
}
if len(.Questions) > int(^uint16(0)) {
return nil, errTooManyQuestions
}
if len(.Answers) > int(^uint16(0)) {
return nil, errTooManyAnswers
}
if len(.Authorities) > int(^uint16(0)) {
return nil, errTooManyAuthorities
}
if len(.Additionals) > int(^uint16(0)) {
return nil, errTooManyAdditionals
}
var header
.id, .bits = .Header.pack()
.questions = uint16(len(.Questions))
.answers = uint16(len(.Answers))
.authorities = uint16(len(.Authorities))
.additionals = uint16(len(.Additionals))
:= len()
:= .pack()
:= map[string]int{}
for := range .Questions {
var error
if , = .Questions[].pack(, , ); != nil {
return nil, &nestedError{"packing Question", }
}
}
for := range .Answers {
var error
if , = .Answers[].pack(, , ); != nil {
return nil, &nestedError{"packing Answer", }
}
}
for := range .Authorities {
var error
if , = .Authorities[].pack(, , ); != nil {
return nil, &nestedError{"packing Authority", }
}
}
for := range .Additionals {
var error
if , = .Additionals[].pack(, , ); != nil {
return nil, &nestedError{"packing Additional", }
}
}
return , nil
}
func ( *Message) () string {
:= "dnsmessage.Message{Header: " + .Header.GoString() + ", " +
"Questions: []dnsmessage.Question{"
if len(.Questions) > 0 {
+= .Questions[0].GoString()
for , := range .Questions[1:] {
+= ", " + .GoString()
}
}
+= "}, Answers: []dnsmessage.Resource{"
if len(.Answers) > 0 {
+= .Answers[0].GoString()
for , := range .Answers[1:] {
+= ", " + .GoString()
}
}
+= "}, Authorities: []dnsmessage.Resource{"
if len(.Authorities) > 0 {
+= .Authorities[0].GoString()
for , := range .Authorities[1:] {
+= ", " + .GoString()
}
}
+= "}, Additionals: []dnsmessage.Resource{"
if len(.Additionals) > 0 {
+= .Additionals[0].GoString()
for , := range .Additionals[1:] {
+= ", " + .GoString()
}
}
return + "}}"
}
compression map[string]int
}
func ( *Builder) () {
.compression = map[string]int{}
}
func ( *Builder) ( section) error {
if .section <= sectionNotStarted {
return ErrNotStarted
}
if .section > {
return ErrSectionDone
}
return nil
}
func ( *Builder) () error {
if := .startCheck(sectionQuestions); != nil {
return
}
.section = sectionQuestions
return nil
}
func ( *Builder) () error {
if := .startCheck(sectionAnswers); != nil {
return
}
.section = sectionAnswers
return nil
}
func ( *Builder) () error {
if := .startCheck(sectionAuthorities); != nil {
return
}
.section = sectionAuthorities
return nil
}
func ( *Builder) () error {
if := .startCheck(sectionAdditionals); != nil {
return
}
.section = sectionAdditionals
return nil
}
func ( *Builder) () error {
var *uint16
var error
switch .section {
case sectionQuestions:
= &.header.questions
= errTooManyQuestions
case sectionAnswers:
= &.header.answers
= errTooManyAnswers
case sectionAuthorities:
= &.header.authorities
= errTooManyAuthorities
case sectionAdditionals:
= &.header.additionals
= errTooManyAdditionals
}
if * == ^uint16(0) {
return
}
*++
return nil
}
func ( *Builder) ( Question) error {
if .section < sectionQuestions {
return ErrNotStarted
}
if .section > sectionQuestions {
return ErrSectionDone
}
, := .pack(.msg, .compression, .start)
if != nil {
return
}
if := .incrementSectionCount(); != nil {
return
}
.msg =
return nil
}
func ( *Builder) () error {
if .section < sectionAnswers {
return ErrNotStarted
}
if .section > sectionAdditionals {
return ErrSectionDone
}
return nil
}
func ( *Builder) ( ResourceHeader, CNAMEResource) error {
if := .checkResourceSection(); != nil {
return
}
.Type = .realType()
, , := .pack(.msg, .compression, .start)
if != nil {
return &nestedError{"ResourceHeader", }
}
:= len()
if , = .pack(, .compression, .start); != nil {
return &nestedError{"CNAMEResource body", }
}
if := .fixLen(, , ); != nil {
return
}
if := .incrementSectionCount(); != nil {
return
}
.msg =
return nil
}
func ( *Builder) ( ResourceHeader, MXResource) error {
if := .checkResourceSection(); != nil {
return
}
.Type = .realType()
, , := .pack(.msg, .compression, .start)
if != nil {
return &nestedError{"ResourceHeader", }
}
:= len()
if , = .pack(, .compression, .start); != nil {
return &nestedError{"MXResource body", }
}
if := .fixLen(, , ); != nil {
return
}
if := .incrementSectionCount(); != nil {
return
}
.msg =
return nil
}
func ( *Builder) ( ResourceHeader, NSResource) error {
if := .checkResourceSection(); != nil {
return
}
.Type = .realType()
, , := .pack(.msg, .compression, .start)
if != nil {
return &nestedError{"ResourceHeader", }
}
:= len()
if , = .pack(, .compression, .start); != nil {
return &nestedError{"NSResource body", }
}
if := .fixLen(, , ); != nil {
return
}
if := .incrementSectionCount(); != nil {
return
}
.msg =
return nil
}
func ( *Builder) ( ResourceHeader, PTRResource) error {
if := .checkResourceSection(); != nil {
return
}
.Type = .realType()
, , := .pack(.msg, .compression, .start)
if != nil {
return &nestedError{"ResourceHeader", }
}
:= len()
if , = .pack(, .compression, .start); != nil {
return &nestedError{"PTRResource body", }
}
if := .fixLen(, , ); != nil {
return
}
if := .incrementSectionCount(); != nil {
return
}
.msg =
return nil
}
func ( *Builder) ( ResourceHeader, SOAResource) error {
if := .checkResourceSection(); != nil {
return
}
.Type = .realType()
, , := .pack(.msg, .compression, .start)
if != nil {
return &nestedError{"ResourceHeader", }
}
:= len()
if , = .pack(, .compression, .start); != nil {
return &nestedError{"SOAResource body", }
}
if := .fixLen(, , ); != nil {
return
}
if := .incrementSectionCount(); != nil {
return
}
.msg =
return nil
}
func ( *Builder) ( ResourceHeader, TXTResource) error {
if := .checkResourceSection(); != nil {
return
}
.Type = .realType()
, , := .pack(.msg, .compression, .start)
if != nil {
return &nestedError{"ResourceHeader", }
}
:= len()
if , = .pack(, .compression, .start); != nil {
return &nestedError{"TXTResource body", }
}
if := .fixLen(, , ); != nil {
return
}
if := .incrementSectionCount(); != nil {
return
}
.msg =
return nil
}
func ( *Builder) ( ResourceHeader, SRVResource) error {
if := .checkResourceSection(); != nil {
return
}
.Type = .realType()
, , := .pack(.msg, .compression, .start)
if != nil {
return &nestedError{"ResourceHeader", }
}
:= len()
if , = .pack(, .compression, .start); != nil {
return &nestedError{"SRVResource body", }
}
if := .fixLen(, , ); != nil {
return
}
if := .incrementSectionCount(); != nil {
return
}
.msg =
return nil
}
func ( *Builder) ( ResourceHeader, AResource) error {
if := .checkResourceSection(); != nil {
return
}
.Type = .realType()
, , := .pack(.msg, .compression, .start)
if != nil {
return &nestedError{"ResourceHeader", }
}
:= len()
if , = .pack(, .compression, .start); != nil {
return &nestedError{"AResource body", }
}
if := .fixLen(, , ); != nil {
return
}
if := .incrementSectionCount(); != nil {
return
}
.msg =
return nil
}
func ( *Builder) ( ResourceHeader, AAAAResource) error {
if := .checkResourceSection(); != nil {
return
}
.Type = .realType()
, , := .pack(.msg, .compression, .start)
if != nil {
return &nestedError{"ResourceHeader", }
}
:= len()
if , = .pack(, .compression, .start); != nil {
return &nestedError{"AAAAResource body", }
}
if := .fixLen(, , ); != nil {
return
}
if := .incrementSectionCount(); != nil {
return
}
.msg =
return nil
}
func ( *Builder) ( ResourceHeader, OPTResource) error {
if := .checkResourceSection(); != nil {
return
}
.Type = .realType()
, , := .pack(.msg, .compression, .start)
if != nil {
return &nestedError{"ResourceHeader", }
}
:= len()
if , = .pack(, .compression, .start); != nil {
return &nestedError{"OPTResource body", }
}
if := .fixLen(, , ); != nil {
return
}
if := .incrementSectionCount(); != nil {
return
}
.msg =
return nil
}
func ( *Builder) () ([]byte, error) {
if .section < sectionHeader {
return nil, ErrNotStarted
}
func ( *ResourceHeader) () string {
return "dnsmessage.ResourceHeader{" +
"Name: " + .Name.GoString() + ", " +
"Type: " + .Type.GoString() + ", " +
"Class: " + .Class.GoString() + ", " +
"TTL: " + printUint32(.TTL) + ", " +
"Length: " + printUint16(.Length) + "}"
}
func ( *ResourceHeader) ( []byte, map[string]int, int) ( []byte, int, error) {
=
if , = .Name.pack(, , ); != nil {
return , 0, &nestedError{"Name", }
}
= packType(, .Type)
= packClass(, .Class)
= packUint32(, .TTL)
= len()
= packUint16(, .Length)
return , , nil
}
func ( *ResourceHeader) ( []byte, int) (int, error) {
:=
var error
if , = .Name.unpack(, ); != nil {
return , &nestedError{"Name", }
}
if .Type, , = unpackType(, ); != nil {
return , &nestedError{"Type", }
}
if .Class, , = unpackClass(, ); != nil {
return , &nestedError{"Class", }
}
if .TTL, , = unpackUint32(, ); != nil {
return , &nestedError{"TTL", }
}
if .Length, , = unpackUint16(, ); != nil {
return , &nestedError{"Length", }
}
return , nil
}
func ( *ResourceHeader) ( []byte, int, int) error {
:= len() -
if > int(^uint16(0)) {
return errResTooLong
}
packUint16([:], uint16())
.Length = uint16()
return nil
}
const (
edns0Version = 0
edns0DNSSECOK = 0x00008000
ednsVersionMask = 0x00ff0000
edns0DNSSECOKMask = 0x00ff8000
)
func ( *ResourceHeader) () bool {
return .TTL&edns0DNSSECOKMask == edns0DNSSECOK // RFC 6891 section 6.1.3
}
func ( *ResourceHeader) ( RCode) RCode {
if .TTL&ednsVersionMask == edns0Version { // RFC 6891 section 6.1.3
return RCode(.TTL>>24<<4) |
}
return
}
func ( []byte, int) (int, error) {
, := skipName(, )
if != nil {
return , &nestedError{"Name", }
}
if , = skipType(, ); != nil {
return , &nestedError{"Type", }
}
if , = skipClass(, ); != nil {
return , &nestedError{"Class", }
}
if , = skipUint32(, ); != nil {
return , &nestedError{"TTL", }
}
, , := unpackUint16(, )
if != nil {
return , &nestedError{"Length", }
}
if += int(); > len() {
return , errResourceLen
}
return , nil
}
func ( []byte, uint16) []byte {
return append(, byte(>>8), byte())
}
func ( []byte, int) (uint16, int, error) {
if +uint16Len > len() {
return 0, , errBaseLen
}
return uint16([])<<8 | uint16([+1]), + uint16Len, nil
}
func ( []byte, int) (int, error) {
if +uint16Len > len() {
return , errBaseLen
}
return + uint16Len, nil
}
func ( []byte, uint32) []byte {
return append(
,
byte(>>24),
byte(>>16),
byte(>>8),
byte(),
)
}
func ( []byte, int) (uint32, int, error) {
if +uint32Len > len() {
return 0, , errBaseLen
}
:= uint32([])<<24 | uint32([+1])<<16 | uint32([+2])<<8 | uint32([+3])
return , + uint32Len, nil
}
func ( []byte, int) (int, error) {
if +uint32Len > len() {
return , errBaseLen
}
return + uint32Len, nil
}
func ( []byte, string) ([]byte, error) {
:= len()
if > 255 {
return nil, errStringTooLong
}
= append(, byte())
= append(, ...)
return , nil
}
func ( []byte, int) (string, int, error) {
if >= len() {
return "", , errBaseLen
}
:= + 1
:= + int([])
if > len() {
return "", , errCalcLen
}
return string([:]), , nil
}
func ( *Name) () string {
return `dnsmessage.MustNewName("` + printString(.Data[:.Length]) + `")`
}
if .Length == 0 || .Data[.Length-1] != '.' {
return , errNonCanonicalName
}
if - >= 1<<6 {
return , errSegTooLong
}
if - == 0 {
return , errZeroSegLen
}
= append(, byte(-))
for := ; < ; ++ {
= append(, .Data[])
}
= + 1
continue
}
:=
:=
var int
:= .Data[:0]
:
for {
if >= len() {
return , errBaseLen
}
:= int([])
++
switch & 0xC0 {
case 0x00: // String segment
break
}
:= +
if > len() {
return , errCalcLen
}
= append(, [:]...)
= append(, '.')
=
case 0xC0: // Pointer
if ! {
return , errCompressedSRV
}
if >= len() {
return , errInvalidPtr
}
:= []
++
if == 0 {
=
if ++; > 10 {
return , errTooManyPtr
}
= (^0xC0)<<8 | int()
:=
:
for {
if >= len() {
return , errBaseLen
}
:= int([])
++
switch & 0xC0 {
case 0x00:
break
+=
if > len() {
return , errCalcLen
}
++
break
return , errReserved
}
}
return , nil
}
func ( *Question) () string {
return "dnsmessage.Question{" +
"Name: " + .Name.GoString() + ", " +
"Type: " + .Type.GoString() + ", " +
"Class: " + .Class.GoString() + "}"
}
func ( []byte, int, ResourceHeader) (ResourceBody, int, error) {
var (
ResourceBody
error
string
)
switch .Type {
case TypeA:
var AResource
, = unpackAResource(, )
= &
= "A"
case TypeNS:
var NSResource
, = unpackNSResource(, )
= &
= "NS"
case TypeCNAME:
var CNAMEResource
, = unpackCNAMEResource(, )
= &
= "CNAME"
case TypeSOA:
var SOAResource
, = unpackSOAResource(, )
= &
= "SOA"
case TypePTR:
var PTRResource
, = unpackPTRResource(, )
= &
= "PTR"
case TypeMX:
var MXResource
, = unpackMXResource(, )
= &
= "MX"
case TypeTXT:
var TXTResource
, = unpackTXTResource(, , .Length)
= &
= "TXT"
case TypeAAAA:
var AAAAResource
, = unpackAAAAResource(, )
= &
= "AAAA"
case TypeSRV:
var SRVResource
, = unpackSRVResource(, )
= &
= "SRV"
case TypeOPT:
var OPTResource
, = unpackOPTResource(, , .Length)
= &
= "OPT"
}
if != nil {
return nil, , &nestedError{ + " record", }
}
if == nil {
return nil, , errors.New("invalid resource type: " + .Type.String())
}
return , + int(.Length), nil
}
type CNAMEResource struct {
CNAME Name
}
func ( *CNAMEResource) () Type {
return TypeCNAME
}
func ( *CNAMEResource) () string {
return "dnsmessage.CNAMEResource{CNAME: " + .CNAME.GoString() + "}"
}
func ( []byte, int) (CNAMEResource, error) {
var Name
if , := .unpack(, ); != nil {
return CNAMEResource{},
}
return CNAMEResource{}, nil
}
type MXResource struct {
Pref uint16
MX Name
}
func ( *MXResource) () Type {
return TypeMX
}
func ( *MXResource) ( []byte, map[string]int, int) ([]byte, error) {
:=
= packUint16(, .Pref)
, := .MX.pack(, , )
if != nil {
return , &nestedError{"MXResource.MX", }
}
return , nil
}
func ( *MXResource) () string {
return "dnsmessage.MXResource{" +
"Pref: " + printUint16(.Pref) + ", " +
"MX: " + .MX.GoString() + "}"
}
func ( []byte, int) (MXResource, error) {
, , := unpackUint16(, )
if != nil {
return MXResource{}, &nestedError{"Pref", }
}
var Name
if , := .unpack(, ); != nil {
return MXResource{}, &nestedError{"MX", }
}
return MXResource{, }, nil
}
type NSResource struct {
NS Name
}
func ( *NSResource) () Type {
return TypeNS
}
func ( *NSResource) () string {
return "dnsmessage.NSResource{NS: " + .NS.GoString() + "}"
}
func ( []byte, int) (NSResource, error) {
var Name
if , := .unpack(, ); != nil {
return NSResource{},
}
return NSResource{}, nil
}
type PTRResource struct {
PTR Name
}
func ( *PTRResource) () Type {
return TypePTR
}
func ( *PTRResource) () string {
return "dnsmessage.PTRResource{PTR: " + .PTR.GoString() + "}"
}
func ( []byte, int) (PTRResource, error) {
var Name
if , := .unpack(, ); != nil {
return PTRResource{},
}
return PTRResource{}, nil
}
MinTTL uint32
}
func ( *SOAResource) () Type {
return TypeSOA
}
func ( *SOAResource) ( []byte, map[string]int, int) ([]byte, error) {
:=
, := .NS.pack(, , )
if != nil {
return , &nestedError{"SOAResource.NS", }
}
, = .MBox.pack(, , )
if != nil {
return , &nestedError{"SOAResource.MBox", }
}
= packUint32(, .Serial)
= packUint32(, .Refresh)
= packUint32(, .Retry)
= packUint32(, .Expire)
return packUint32(, .MinTTL), nil
}
func ( *SOAResource) () string {
return "dnsmessage.SOAResource{" +
"NS: " + .NS.GoString() + ", " +
"MBox: " + .MBox.GoString() + ", " +
"Serial: " + printUint32(.Serial) + ", " +
"Refresh: " + printUint32(.Refresh) + ", " +
"Retry: " + printUint32(.Retry) + ", " +
"Expire: " + printUint32(.Expire) + ", " +
"MinTTL: " + printUint32(.MinTTL) + "}"
}
func ( []byte, int) (SOAResource, error) {
var Name
, := .unpack(, )
if != nil {
return SOAResource{}, &nestedError{"NS", }
}
var Name
if , = .unpack(, ); != nil {
return SOAResource{}, &nestedError{"MBox", }
}
, , := unpackUint32(, )
if != nil {
return SOAResource{}, &nestedError{"Serial", }
}
, , := unpackUint32(, )
if != nil {
return SOAResource{}, &nestedError{"Refresh", }
}
, , := unpackUint32(, )
if != nil {
return SOAResource{}, &nestedError{"Retry", }
}
, , := unpackUint32(, )
if != nil {
return SOAResource{}, &nestedError{"Expire", }
}
, , := unpackUint32(, )
if != nil {
return SOAResource{}, &nestedError{"MinTTL", }
}
return SOAResource{, , , , , , }, nil
}
type TXTResource struct {
TXT []string
}
func ( *TXTResource) () Type {
return TypeTXT
}
func ( *TXTResource) () string {
:= "dnsmessage.TXTResource{TXT: []string{"
if len(.TXT) == 0 {
return + "}}"
}
+= `"` + printString([]byte(.TXT[0]))
for , := range .TXT[1:] {
+= `", "` + printString([]byte())
}
return + `"}}`
}
func ( []byte, int, uint16) (TXTResource, error) {
:= make([]string, 0, 1)
for := uint16(0); < ; {
var string
var error
if , , = unpackText(, ); != nil {
return TXTResource{}, &nestedError{"text", }
if - < uint16(len())+1 {
return TXTResource{}, errCalcLen
}
+= uint16(len()) + 1
= append(, )
}
return TXTResource{}, nil
}
func ( *SRVResource) ( []byte, map[string]int, int) ([]byte, error) {
:=
= packUint16(, .Priority)
= packUint16(, .Weight)
= packUint16(, .Port)
, := .Target.pack(, nil, )
if != nil {
return , &nestedError{"SRVResource.Target", }
}
return , nil
}
func ( *SRVResource) () string {
return "dnsmessage.SRVResource{" +
"Priority: " + printUint16(.Priority) + ", " +
"Weight: " + printUint16(.Weight) + ", " +
"Port: " + printUint16(.Port) + ", " +
"Target: " + .Target.GoString() + "}"
}
func ( []byte, int) (SRVResource, error) {
, , := unpackUint16(, )
if != nil {
return SRVResource{}, &nestedError{"Priority", }
}
, , := unpackUint16(, )
if != nil {
return SRVResource{}, &nestedError{"Weight", }
}
, , := unpackUint16(, )
if != nil {
return SRVResource{}, &nestedError{"Port", }
}
var Name
if , := .unpackCompressed(, , false /* allowCompression */); != nil {
return SRVResource{}, &nestedError{"Target", }
}
return SRVResource{, , , }, nil
}
type AAAAResource struct {
AAAA [16]byte
}
func ( *AAAAResource) () Type {
return TypeAAAA
}
func ( *AAAAResource) () string {
return "dnsmessage.AAAAResource{" +
"AAAA: [16]byte{" + printByteSlice(.AAAA[:]) + "}}"
}
func ( *AAAAResource) ( []byte, map[string]int, int) ([]byte, error) {
return packBytes(, .AAAA[:]), nil
}
func ( []byte, int) (AAAAResource, error) {
var [16]byte
if , := unpackBytes(, , [:]); != nil {
return AAAAResource{},
}
return AAAAResource{}, nil
}
type OPTResource struct {
Options []Option
}
func ( *Option) () string {
return "dnsmessage.Option{" +
"Code: " + printUint16(.Code) + ", " +
"Data: []byte{" + printByteSlice(.Data) + "}}"
}
func ( *OPTResource) () Type {
return TypeOPT
}
func ( *OPTResource) ( []byte, map[string]int, int) ([]byte, error) {
for , := range .Options {
= packUint16(, .Code)
:= uint16(len(.Data))
= packUint16(, )
= packBytes(, .Data)
}
return , nil
}
func ( *OPTResource) () string {
:= "dnsmessage.OPTResource{Options: []dnsmessage.Option{"
if len(.Options) == 0 {
return + "}}"
}
+= .Options[0].GoString()
for , := range .Options[1:] {
+= ", " + .GoString()
}
return + "}}"
}
func ( []byte, int, uint16) (OPTResource, error) {
var []Option
for := ; < +int(); {
var error
var Option
.Code, , = unpackUint16(, )
if != nil {
return OPTResource{}, &nestedError{"Code", }
}
var uint16
, , = unpackUint16(, )
if != nil {
return OPTResource{}, &nestedError{"Data", }
}
.Data = make([]byte, )
if copy(.Data, [:]) != int() {
return OPTResource{}, &nestedError{"Data", errCalcLen}
}
+= int()
= append(, )
}
return OPTResource{}, nil
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |