Revert "Export EDNS0 interface (#1041)" (#1046)

This reverts commit a98e771ba5.

This is breaking people
This commit is contained in:
Miek Gieben 2019-12-06 21:23:18 +00:00 committed by GitHub
parent 78ecb5db60
commit 730ff1f016
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 129 additions and 184 deletions

278
edns.go
View File

@ -47,8 +47,7 @@ func (rr *OPT) String() string {
switch o.(type) { switch o.(type) {
case *EDNS0_NSID: case *EDNS0_NSID:
s += "\n; NSID: " + o.String() s += "\n; NSID: " + o.String()
h := make([]byte, o.Len()) h, e := o.pack()
_, e := o.Pack(h)
var r string var r string
if e == nil { if e == nil {
for _, c := range h { for _, c := range h {
@ -83,7 +82,8 @@ func (rr *OPT) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression) l := rr.Hdr.len(off, compression)
for _, o := range rr.Option { for _, o := range rr.Option {
l += 4 // Account for 2-byte option code and 2-byte option length. l += 4 // Account for 2-byte option code and 2-byte option length.
l += o.Len() lo, _ := o.pack()
l += len(lo)
} }
return l return l
} }
@ -152,19 +152,15 @@ func (rr *OPT) SetDo(do ...bool) {
type EDNS0 interface { type EDNS0 interface {
// Option returns the option code for the option. // Option returns the option code for the option.
Option() uint16 Option() uint16
// Len returns the length (number of bytes) of the option data when // pack returns the bytes of the option data.
// packed pack() ([]byte, error)
Len() int // unpack sets the data as found in the buffer. Is also sets
// Pack writes the option data into the buffer. The buffer should be at
// least Len() bytes long. Returns the number of bytes written.
Pack(b []byte) (int, error)
// Unpack sets the data as found in the buffer. Is also sets
// the length of the slice as the length of the option data. // the length of the slice as the length of the option data.
Unpack([]byte) (int, error) unpack([]byte) error
// String returns the string representation of the option. // String returns the string representation of the option.
String() string String() string
// copy returns a deep-copy of the option. // copy returns a deep-copy of the option.
Copy() EDNS0 copy() EDNS0
} }
// EDNS0_NSID option is used to retrieve a nameserver // EDNS0_NSID option is used to retrieve a nameserver
@ -184,20 +180,19 @@ type EDNS0_NSID struct {
Nsid string // This string needs to be hex encoded Nsid string // This string needs to be hex encoded
} }
func (e *EDNS0_NSID) Len() int { func (e *EDNS0_NSID) pack() ([]byte, error) {
return hex.DecodedLen(len(e.Nsid)) h, err := hex.DecodeString(e.Nsid)
} if err != nil {
return nil, err
func (e *EDNS0_NSID) Pack(b []byte) (int, error) { }
nsid := []byte(e.Nsid) return h, nil
return hex.Decode(nsid, b)
} }
// Option implements the EDNS0 interface. // Option implements the EDNS0 interface.
func (e *EDNS0_NSID) Option() uint16 { return EDNS0NSID } // Option returns the option code. func (e *EDNS0_NSID) Option() uint16 { return EDNS0NSID } // Option returns the option code.
func (e *EDNS0_NSID) Unpack(b []byte) (int, error) { e.Nsid = hex.EncodeToString(b); return len(b), nil } func (e *EDNS0_NSID) unpack(b []byte) error { e.Nsid = hex.EncodeToString(b); return nil }
func (e *EDNS0_NSID) String() string { return e.Nsid } func (e *EDNS0_NSID) String() string { return e.Nsid }
func (e *EDNS0_NSID) Copy() EDNS0 { return &EDNS0_NSID{e.Code, e.Nsid} } func (e *EDNS0_NSID) copy() EDNS0 { return &EDNS0_NSID{e.Code, e.Nsid} }
// EDNS0_SUBNET is the subnet option that is used to give the remote nameserver // 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 // an idea of where the client lives. See RFC 7871. It can then give back a different
@ -230,82 +225,77 @@ type EDNS0_SUBNET struct {
// Option implements the EDNS0 interface. // Option implements the EDNS0 interface.
func (e *EDNS0_SUBNET) Option() uint16 { return EDNS0SUBNET } func (e *EDNS0_SUBNET) Option() uint16 { return EDNS0SUBNET }
func (e *EDNS0_SUBNET) Len() int { func (e *EDNS0_SUBNET) pack() ([]byte, error) {
return 4 + int((e.SourceNetmask + 8 - 1) / 8) // division rounding up b := make([]byte, 4)
}
func (e *EDNS0_SUBNET) Pack(b []byte) (int, error) {
binary.BigEndian.PutUint16(b[0:], e.Family) binary.BigEndian.PutUint16(b[0:], e.Family)
b[2] = e.SourceNetmask b[2] = e.SourceNetmask
b[3] = e.SourceScope b[3] = e.SourceScope
var copied int = 0
switch e.Family { switch e.Family {
case 0: case 0:
// "dig" sets AddressFamily to 0 if SourceNetmask is also 0 // "dig" sets AddressFamily to 0 if SourceNetmask is also 0
// We might don't need to complain either // We might don't need to complain either
if e.SourceNetmask != 0 { if e.SourceNetmask != 0 {
return 0, errors.New("dns: bad address family") return nil, errors.New("dns: bad address family")
} }
case 1: case 1:
if e.SourceNetmask > net.IPv4len*8 { if e.SourceNetmask > net.IPv4len*8 {
return 0, errors.New("dns: bad netmask") return nil, errors.New("dns: bad netmask")
} }
if len(e.Address.To4()) != net.IPv4len { if len(e.Address.To4()) != net.IPv4len {
return 0, errors.New("dns: bad address") return nil, errors.New("dns: bad address")
} }
ip := e.Address.To4().Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv4len*8)) ip := e.Address.To4().Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv4len*8))
needLength := int((e.SourceNetmask + 8 - 1) / 8) // division rounding up needLength := (e.SourceNetmask + 8 - 1) / 8 // division rounding up
copied = copy(b[4:], ip[:needLength]) b = append(b, ip[:needLength]...)
case 2: case 2:
if e.SourceNetmask > net.IPv6len*8 { if e.SourceNetmask > net.IPv6len*8 {
return 0, errors.New("dns: bad netmask") return nil, errors.New("dns: bad netmask")
} }
if len(e.Address) != net.IPv6len { if len(e.Address) != net.IPv6len {
return 0, errors.New("dns: bad address") return nil, errors.New("dns: bad address")
} }
ip := e.Address.Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv6len*8)) ip := e.Address.Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv6len*8))
needLength := int((e.SourceNetmask + 8 - 1) / 8) // division rounding up needLength := (e.SourceNetmask + 8 - 1) / 8 // division rounding up
copied = copy(b[4:], ip[:needLength]) b = append(b, ip[:needLength]...)
default: default:
return 0, errors.New("dns: bad address family") return nil, errors.New("dns: bad address family")
} }
return 4 + copied, nil return b, nil
} }
func (e *EDNS0_SUBNET) Unpack(b []byte) (int, error) { func (e *EDNS0_SUBNET) unpack(b []byte) error {
if len(b) < 4 { if len(b) < 4 {
return 0, ErrBuf return ErrBuf
} }
e.Family = binary.BigEndian.Uint16(b) e.Family = binary.BigEndian.Uint16(b)
e.SourceNetmask = b[2] e.SourceNetmask = b[2]
e.SourceScope = b[3] e.SourceScope = b[3]
var l int = 0
switch e.Family { switch e.Family {
case 0: case 0:
// "dig" sets AddressFamily to 0 if SourceNetmask is also 0 // "dig" sets AddressFamily to 0 if SourceNetmask is also 0
// It's okay to accept such a packet // It's okay to accept such a packet
if e.SourceNetmask != 0 { if e.SourceNetmask != 0 {
return 0, errors.New("dns: bad address family") return errors.New("dns: bad address family")
} }
e.Address = net.IPv4(0, 0, 0, 0) e.Address = net.IPv4(0, 0, 0, 0)
case 1: case 1:
if e.SourceNetmask > net.IPv4len*8 || e.SourceScope > net.IPv4len*8 { if e.SourceNetmask > net.IPv4len*8 || e.SourceScope > net.IPv4len*8 {
return 0, errors.New("dns: bad netmask") return errors.New("dns: bad netmask")
} }
addr := make(net.IP, net.IPv4len) addr := make(net.IP, net.IPv4len)
l = copy(addr, b[4:]) copy(addr, b[4:])
e.Address = addr.To16() e.Address = addr.To16()
case 2: case 2:
if e.SourceNetmask > net.IPv6len*8 || e.SourceScope > net.IPv6len*8 { if e.SourceNetmask > net.IPv6len*8 || e.SourceScope > net.IPv6len*8 {
return 0, errors.New("dns: bad netmask") return errors.New("dns: bad netmask")
} }
addr := make(net.IP, net.IPv6len) addr := make(net.IP, net.IPv6len)
l = copy(addr, b[4:]) copy(addr, b[4:])
e.Address = addr e.Address = addr
default: default:
return 0, errors.New("dns: bad address family") return errors.New("dns: bad address family")
} }
return 4 + l, nil return nil
} }
func (e *EDNS0_SUBNET) String() (s string) { func (e *EDNS0_SUBNET) String() (s string) {
@ -320,7 +310,7 @@ func (e *EDNS0_SUBNET) String() (s string) {
return return
} }
func (e *EDNS0_SUBNET) Copy() EDNS0 { func (e *EDNS0_SUBNET) copy() EDNS0 {
return &EDNS0_SUBNET{ return &EDNS0_SUBNET{
e.Code, e.Code,
e.Family, e.Family,
@ -353,23 +343,19 @@ type EDNS0_COOKIE struct {
Cookie string // Hex-encoded cookie data Cookie string // Hex-encoded cookie data
} }
func (e *EDNS0_COOKIE) Len() int { func (e *EDNS0_COOKIE) pack() ([]byte, error) {
return hex.DecodedLen(len(e.Cookie)) h, err := hex.DecodeString(e.Cookie)
} if err != nil {
return nil, err
func (e *EDNS0_COOKIE) Pack(b []byte) (int, error) { }
cookie := []byte(e.Cookie) return h, nil
return hex.Decode(cookie, b)
} }
// Option implements the EDNS0 interface. // Option implements the EDNS0 interface.
func (e *EDNS0_COOKIE) Option() uint16 { return EDNS0COOKIE } func (e *EDNS0_COOKIE) Option() uint16 { return EDNS0COOKIE }
func (e *EDNS0_COOKIE) Unpack(b []byte) (int, error) { func (e *EDNS0_COOKIE) unpack(b []byte) error { e.Cookie = hex.EncodeToString(b); return nil }
e.Cookie = hex.EncodeToString(b) func (e *EDNS0_COOKIE) String() string { return e.Cookie }
return len(b), nil func (e *EDNS0_COOKIE) copy() EDNS0 { return &EDNS0_COOKIE{e.Code, e.Cookie} }
}
func (e *EDNS0_COOKIE) String() string { return e.Cookie }
func (e *EDNS0_COOKIE) Copy() EDNS0 { return &EDNS0_COOKIE{e.Code, e.Cookie} }
// The EDNS0_UL (Update Lease) (draft RFC) option is used to tell the server to set // 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 // an expiration on an update RR. This is helpful for clients that cannot clean
@ -392,39 +378,32 @@ type EDNS0_UL struct {
// Option implements the EDNS0 interface. // Option implements the EDNS0 interface.
func (e *EDNS0_UL) Option() uint16 { return EDNS0UL } func (e *EDNS0_UL) Option() uint16 { return EDNS0UL }
func (e *EDNS0_UL) String() string { return fmt.Sprintf("%d %d", e.Lease, e.KeyLease) } func (e *EDNS0_UL) String() string { return fmt.Sprintf("%d %d", e.Lease, e.KeyLease) }
func (e *EDNS0_UL) Copy() EDNS0 { return &EDNS0_UL{e.Code, e.Lease, e.KeyLease} } func (e *EDNS0_UL) copy() EDNS0 { return &EDNS0_UL{e.Code, e.Lease, e.KeyLease} }
func (e *EDNS0_UL) Len() int {
if e.KeyLease == 0 {
return 4
}
return 8
}
// Copied: http://golang.org/src/pkg/net/dnsmsg.go // Copied: http://golang.org/src/pkg/net/dnsmsg.go
func (e *EDNS0_UL) Pack(b []byte) (int, error) { func (e *EDNS0_UL) pack() ([]byte, error) {
l := 4 var b []byte
if e.KeyLease != 0 { if e.KeyLease == 0 {
b = make([]byte, 4)
} else {
b = make([]byte, 8)
binary.BigEndian.PutUint32(b[4:], e.KeyLease) binary.BigEndian.PutUint32(b[4:], e.KeyLease)
l += 4
} }
binary.BigEndian.PutUint32(b, e.Lease) binary.BigEndian.PutUint32(b, e.Lease)
return l, nil return b, nil
} }
func (e *EDNS0_UL) Unpack(b []byte) (int, error) { func (e *EDNS0_UL) unpack(b []byte) error {
l := len(b) switch len(b) {
switch l {
case 4: case 4:
e.KeyLease = 0 e.KeyLease = 0
case 8: case 8:
e.KeyLease = binary.BigEndian.Uint32(b[4:]) e.KeyLease = binary.BigEndian.Uint32(b[4:])
default: default:
return 0, ErrBuf return ErrBuf
} }
e.Lease = binary.BigEndian.Uint32(b) e.Lease = binary.BigEndian.Uint32(b)
return l, nil return nil
} }
// EDNS0_LLQ stands for Long Lived Queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 // EDNS0_LLQ stands for Long Lived Queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
@ -441,29 +420,26 @@ type EDNS0_LLQ struct {
// Option implements the EDNS0 interface. // Option implements the EDNS0 interface.
func (e *EDNS0_LLQ) Option() uint16 { return EDNS0LLQ } func (e *EDNS0_LLQ) Option() uint16 { return EDNS0LLQ }
func (e *EDNS0_LLQ) Len() int { func (e *EDNS0_LLQ) pack() ([]byte, error) {
return 18 b := make([]byte, 18)
}
func (e *EDNS0_LLQ) Pack(b []byte) (int, error) {
binary.BigEndian.PutUint16(b[0:], e.Version) binary.BigEndian.PutUint16(b[0:], e.Version)
binary.BigEndian.PutUint16(b[2:], e.Opcode) binary.BigEndian.PutUint16(b[2:], e.Opcode)
binary.BigEndian.PutUint16(b[4:], e.Error) binary.BigEndian.PutUint16(b[4:], e.Error)
binary.BigEndian.PutUint64(b[6:], e.Id) binary.BigEndian.PutUint64(b[6:], e.Id)
binary.BigEndian.PutUint32(b[14:], e.LeaseLife) binary.BigEndian.PutUint32(b[14:], e.LeaseLife)
return 18, nil return b, nil
} }
func (e *EDNS0_LLQ) Unpack(b []byte) (int, error) { func (e *EDNS0_LLQ) unpack(b []byte) error {
if len(b) < 18 { if len(b) < 18 {
return 0, ErrBuf return ErrBuf
} }
e.Version = binary.BigEndian.Uint16(b[0:]) e.Version = binary.BigEndian.Uint16(b[0:])
e.Opcode = binary.BigEndian.Uint16(b[2:]) e.Opcode = binary.BigEndian.Uint16(b[2:])
e.Error = binary.BigEndian.Uint16(b[4:]) e.Error = binary.BigEndian.Uint16(b[4:])
e.Id = binary.BigEndian.Uint64(b[6:]) e.Id = binary.BigEndian.Uint64(b[6:])
e.LeaseLife = binary.BigEndian.Uint32(b[14:]) e.LeaseLife = binary.BigEndian.Uint32(b[14:])
return 18, nil return nil
} }
func (e *EDNS0_LLQ) String() string { func (e *EDNS0_LLQ) String() string {
@ -472,7 +448,7 @@ func (e *EDNS0_LLQ) String() string {
" " + strconv.FormatUint(uint64(e.LeaseLife), 10) " " + strconv.FormatUint(uint64(e.LeaseLife), 10)
return s return s
} }
func (e *EDNS0_LLQ) Copy() EDNS0 { func (e *EDNS0_LLQ) copy() EDNS0 {
return &EDNS0_LLQ{e.Code, e.Version, e.Opcode, e.Error, e.Id, e.LeaseLife} return &EDNS0_LLQ{e.Code, e.Version, e.Opcode, e.Error, e.Id, e.LeaseLife}
} }
@ -483,13 +459,9 @@ type EDNS0_DAU struct {
} }
// Option implements the EDNS0 interface. // Option implements the EDNS0 interface.
func (e *EDNS0_DAU) Option() uint16 { return EDNS0DAU } func (e *EDNS0_DAU) Option() uint16 { return EDNS0DAU }
func (e *EDNS0_DAU) Len() int { return len(e.AlgCode) } func (e *EDNS0_DAU) pack() ([]byte, error) { return e.AlgCode, nil }
func (e *EDNS0_DAU) Pack(b []byte) (int, error) { return copy(b, e.AlgCode), nil } func (e *EDNS0_DAU) unpack(b []byte) error { e.AlgCode = b; return nil }
func (e *EDNS0_DAU) Unpack(b []byte) (int, error) {
e.AlgCode = make([]byte, len(b))
return copy(e.AlgCode, b), nil
}
func (e *EDNS0_DAU) String() string { func (e *EDNS0_DAU) String() string {
s := "" s := ""
@ -502,7 +474,7 @@ func (e *EDNS0_DAU) String() string {
} }
return s return s
} }
func (e *EDNS0_DAU) Copy() EDNS0 { return &EDNS0_DAU{e.Code, e.AlgCode} } func (e *EDNS0_DAU) copy() EDNS0 { return &EDNS0_DAU{e.Code, e.AlgCode} }
// EDNS0_DHU implements the EDNS0 "DS Hash Understood" option. See RFC 6975. // EDNS0_DHU implements the EDNS0 "DS Hash Understood" option. See RFC 6975.
type EDNS0_DHU struct { type EDNS0_DHU struct {
@ -511,13 +483,9 @@ type EDNS0_DHU struct {
} }
// Option implements the EDNS0 interface. // Option implements the EDNS0 interface.
func (e *EDNS0_DHU) Option() uint16 { return EDNS0DHU } func (e *EDNS0_DHU) Option() uint16 { return EDNS0DHU }
func (e *EDNS0_DHU) Len() int { return len(e.AlgCode) } func (e *EDNS0_DHU) pack() ([]byte, error) { return e.AlgCode, nil }
func (e *EDNS0_DHU) Pack(b []byte) (int, error) { return copy(b, e.AlgCode), nil } func (e *EDNS0_DHU) unpack(b []byte) error { e.AlgCode = b; return nil }
func (e *EDNS0_DHU) Unpack(b []byte) (int, error) {
e.AlgCode = make([]byte, len(b))
return copy(e.AlgCode, b), nil
}
func (e *EDNS0_DHU) String() string { func (e *EDNS0_DHU) String() string {
s := "" s := ""
@ -530,7 +498,7 @@ func (e *EDNS0_DHU) String() string {
} }
return s return s
} }
func (e *EDNS0_DHU) Copy() EDNS0 { return &EDNS0_DHU{e.Code, e.AlgCode} } func (e *EDNS0_DHU) copy() EDNS0 { return &EDNS0_DHU{e.Code, e.AlgCode} }
// EDNS0_N3U implements the EDNS0 "NSEC3 Hash Understood" option. See RFC 6975. // EDNS0_N3U implements the EDNS0 "NSEC3 Hash Understood" option. See RFC 6975.
type EDNS0_N3U struct { type EDNS0_N3U struct {
@ -539,13 +507,9 @@ type EDNS0_N3U struct {
} }
// Option implements the EDNS0 interface. // Option implements the EDNS0 interface.
func (e *EDNS0_N3U) Option() uint16 { return EDNS0N3U } func (e *EDNS0_N3U) Option() uint16 { return EDNS0N3U }
func (e *EDNS0_N3U) Len() int { return len(e.AlgCode) } func (e *EDNS0_N3U) pack() ([]byte, error) { return e.AlgCode, nil }
func (e *EDNS0_N3U) Pack(b []byte) (int, error) { return copy(b, e.AlgCode), nil } func (e *EDNS0_N3U) unpack(b []byte) error { e.AlgCode = b; return nil }
func (e *EDNS0_N3U) Unpack(b []byte) (int, error) {
e.AlgCode = make([]byte, len(b))
return copy(e.AlgCode, b), nil
}
func (e *EDNS0_N3U) String() string { func (e *EDNS0_N3U) String() string {
// Re-use the hash map // Re-use the hash map
@ -559,7 +523,7 @@ func (e *EDNS0_N3U) String() string {
} }
return s return s
} }
func (e *EDNS0_N3U) Copy() EDNS0 { return &EDNS0_N3U{e.Code, e.AlgCode} } func (e *EDNS0_N3U) copy() EDNS0 { return &EDNS0_N3U{e.Code, e.AlgCode} }
// EDNS0_EXPIRE implementes the EDNS0 option as described in RFC 7314. // EDNS0_EXPIRE implementes the EDNS0 option as described in RFC 7314.
type EDNS0_EXPIRE struct { type EDNS0_EXPIRE struct {
@ -570,26 +534,20 @@ type EDNS0_EXPIRE struct {
// Option implements the EDNS0 interface. // Option implements the EDNS0 interface.
func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE } func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE }
func (e *EDNS0_EXPIRE) String() string { return strconv.FormatUint(uint64(e.Expire), 10) } func (e *EDNS0_EXPIRE) String() string { return strconv.FormatUint(uint64(e.Expire), 10) }
func (e *EDNS0_EXPIRE) Copy() EDNS0 { return &EDNS0_EXPIRE{e.Code, e.Expire} } func (e *EDNS0_EXPIRE) copy() EDNS0 { return &EDNS0_EXPIRE{e.Code, e.Expire} }
func (e *EDNS0_EXPIRE) Len() int { func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
return 4 b := make([]byte, 4)
}
func (e *EDNS0_EXPIRE) Pack(b []byte) (int, error) {
if len(b) < 4 {
return 0, ErrBuf
}
binary.BigEndian.PutUint32(b, e.Expire) binary.BigEndian.PutUint32(b, e.Expire)
return 4, nil return b, nil
} }
func (e *EDNS0_EXPIRE) Unpack(b []byte) (int, error) { func (e *EDNS0_EXPIRE) unpack(b []byte) error {
if len(b) < 4 { if len(b) < 4 {
return 0, ErrBuf return ErrBuf
} }
e.Expire = binary.BigEndian.Uint32(b) e.Expire = binary.BigEndian.Uint32(b)
return 4, nil return nil
} }
// The EDNS0_LOCAL option is used for local/experimental purposes. The option // The EDNS0_LOCAL option is used for local/experimental purposes. The option
@ -615,31 +573,28 @@ func (e *EDNS0_LOCAL) Option() uint16 { return e.Code }
func (e *EDNS0_LOCAL) String() string { func (e *EDNS0_LOCAL) String() string {
return strconv.FormatInt(int64(e.Code), 10) + ":0x" + hex.EncodeToString(e.Data) return strconv.FormatInt(int64(e.Code), 10) + ":0x" + hex.EncodeToString(e.Data)
} }
func (e *EDNS0_LOCAL) Copy() EDNS0 { func (e *EDNS0_LOCAL) copy() EDNS0 {
b := make([]byte, len(e.Data)) b := make([]byte, len(e.Data))
copy(b, e.Data) copy(b, e.Data)
return &EDNS0_LOCAL{e.Code, b} return &EDNS0_LOCAL{e.Code, b}
} }
func (e *EDNS0_LOCAL) Len() int { func (e *EDNS0_LOCAL) pack() ([]byte, error) {
return len(e.Data) b := make([]byte, len(e.Data))
}
func (e *EDNS0_LOCAL) Pack(b []byte) (int, error) {
copied := copy(b, e.Data) copied := copy(b, e.Data)
if copied != len(e.Data) { if copied != len(e.Data) {
return 0, ErrBuf return nil, ErrBuf
} }
return copied, nil return b, nil
} }
func (e *EDNS0_LOCAL) Unpack(b []byte) (int, error) { func (e *EDNS0_LOCAL) unpack(b []byte) error {
e.Data = make([]byte, len(b)) e.Data = make([]byte, len(b))
copied := copy(e.Data, b) copied := copy(e.Data, b)
if copied != len(b) { if copied != len(b) {
return 0, ErrBuf return ErrBuf
} }
return copied, nil return nil
} }
// EDNS0_TCP_KEEPALIVE is an EDNS0 option that instructs the server to keep // EDNS0_TCP_KEEPALIVE is an EDNS0 option that instructs the server to keep
@ -653,40 +608,37 @@ type EDNS0_TCP_KEEPALIVE struct {
// Option implements the EDNS0 interface. // Option implements the EDNS0 interface.
func (e *EDNS0_TCP_KEEPALIVE) Option() uint16 { return EDNS0TCPKEEPALIVE } func (e *EDNS0_TCP_KEEPALIVE) Option() uint16 { return EDNS0TCPKEEPALIVE }
func (e *EDNS0_TCP_KEEPALIVE) Len() int { func (e *EDNS0_TCP_KEEPALIVE) pack() ([]byte, error) {
return int(4 + e.Length)
}
func (e *EDNS0_TCP_KEEPALIVE) Pack(b []byte) (int, error) {
if e.Timeout != 0 && e.Length != 2 { if e.Timeout != 0 && e.Length != 2 {
return 0, errors.New("dns: timeout specified but length is not 2") return nil, errors.New("dns: timeout specified but length is not 2")
} }
if e.Timeout == 0 && e.Length != 0 { if e.Timeout == 0 && e.Length != 0 {
return 0, errors.New("dns: timeout not specified but length is not 0") return nil, errors.New("dns: timeout not specified but length is not 0")
} }
b := make([]byte, 4+e.Length)
binary.BigEndian.PutUint16(b[0:], e.Code) binary.BigEndian.PutUint16(b[0:], e.Code)
binary.BigEndian.PutUint16(b[2:], e.Length) binary.BigEndian.PutUint16(b[2:], e.Length)
if e.Length == 2 { if e.Length == 2 {
binary.BigEndian.PutUint16(b[4:], e.Timeout) binary.BigEndian.PutUint16(b[4:], e.Timeout)
} }
return e.Len(), nil return b, nil
} }
func (e *EDNS0_TCP_KEEPALIVE) Unpack(b []byte) (int, error) { func (e *EDNS0_TCP_KEEPALIVE) unpack(b []byte) error {
if len(b) < 4 { if len(b) < 4 {
return 0, ErrBuf return ErrBuf
} }
e.Length = binary.BigEndian.Uint16(b[2:4]) e.Length = binary.BigEndian.Uint16(b[2:4])
if e.Length != 0 && e.Length != 2 { if e.Length != 0 && e.Length != 2 {
return 0, errors.New("dns: length mismatch, want 0/2 but got " + strconv.FormatUint(uint64(e.Length), 10)) return errors.New("dns: length mismatch, want 0/2 but got " + strconv.FormatUint(uint64(e.Length), 10))
} }
if e.Length == 2 { if e.Length == 2 {
if len(b) < 6 { if len(b) < 6 {
return 0, ErrBuf return ErrBuf
} }
e.Timeout = binary.BigEndian.Uint16(b[4:6]) e.Timeout = binary.BigEndian.Uint16(b[4:6])
} }
return e.Len(), nil return nil
} }
func (e *EDNS0_TCP_KEEPALIVE) String() (s string) { func (e *EDNS0_TCP_KEEPALIVE) String() (s string) {
@ -698,7 +650,7 @@ func (e *EDNS0_TCP_KEEPALIVE) String() (s string) {
} }
return return
} }
func (e *EDNS0_TCP_KEEPALIVE) Copy() EDNS0 { return &EDNS0_TCP_KEEPALIVE{e.Code, e.Length, e.Timeout} } func (e *EDNS0_TCP_KEEPALIVE) copy() EDNS0 { return &EDNS0_TCP_KEEPALIVE{e.Code, e.Length, e.Timeout} }
// EDNS0_PADDING option is used to add padding to a request/response. The default // 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 // value of padding SHOULD be 0x0 but other values MAY be used, for instance if
@ -708,15 +660,11 @@ type EDNS0_PADDING struct {
} }
// Option implements the EDNS0 interface. // Option implements the EDNS0 interface.
func (e *EDNS0_PADDING) Option() uint16 { return EDNS0PADDING } func (e *EDNS0_PADDING) Option() uint16 { return EDNS0PADDING }
func (e *EDNS0_PADDING) Len() int { return len(e.Padding) } func (e *EDNS0_PADDING) pack() ([]byte, error) { return e.Padding, nil }
func (e *EDNS0_PADDING) Pack(b []byte) (int, error) { return copy(b, e.Padding), nil } func (e *EDNS0_PADDING) unpack(b []byte) error { e.Padding = b; return nil }
func (e *EDNS0_PADDING) Unpack(b []byte) (int, error) { func (e *EDNS0_PADDING) String() string { return fmt.Sprintf("%0X", e.Padding) }
e.Padding = make([]byte, len(b)) func (e *EDNS0_PADDING) copy() EDNS0 {
return copy(e.Padding, b), nil
}
func (e *EDNS0_PADDING) String() string { return fmt.Sprintf("%0X", e.Padding) }
func (e *EDNS0_PADDING) Copy() EDNS0 {
b := make([]byte, len(e.Padding)) b := make([]byte, len(e.Padding))
copy(b, e.Padding) copy(b, e.Padding)
return &EDNS0_PADDING{b} return &EDNS0_PADDING{b}

View File

@ -94,14 +94,13 @@ func TestEDNS0_SUBNETUnpack(t *testing.T) {
s1.SourceNetmask = net.IPv4len * 8 s1.SourceNetmask = net.IPv4len * 8
} }
b := make([]byte, s1.Len()) b, err := s1.pack()
_, err := s1.Pack(b)
if err != nil { if err != nil {
t.Fatalf("failed to pack: %v", err) t.Fatalf("failed to pack: %v", err)
} }
var s2 EDNS0_SUBNET var s2 EDNS0_SUBNET
if _, err := s2.Unpack(b); err != nil { if err := s2.unpack(b); err != nil {
t.Fatalf("failed to unpack: %v", err) t.Fatalf("failed to unpack: %v", err)
} }
@ -121,13 +120,12 @@ func TestEDNS0_UL(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
expect := EDNS0_UL{EDNS0UL, c.l, c.kl} expect := EDNS0_UL{EDNS0UL, c.l, c.kl}
b := make([]byte, expect.Len()) b, err := expect.pack()
_, err := expect.Pack(b)
if err != nil { if err != nil {
t.Fatalf("failed to pack: %v", err) t.Fatalf("failed to pack: %v", err)
} }
actual := EDNS0_UL{EDNS0UL, ^uint32(0), ^uint32(0)} actual := EDNS0_UL{EDNS0UL, ^uint32(0), ^uint32(0)}
if _, err := actual.Unpack(b); err != nil { if err := actual.unpack(b); err != nil {
t.Fatalf("failed to unpack: %v", err) t.Fatalf("failed to unpack: %v", err)
} }
if expect != actual { if expect != actual {

View File

@ -426,63 +426,63 @@ Option:
switch code { switch code {
case EDNS0NSID: case EDNS0NSID:
e := new(EDNS0_NSID) e := new(EDNS0_NSID)
if _, err := e.Unpack(msg[off : off+int(optlen)]); err != nil { if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
return nil, len(msg), err return nil, len(msg), err
} }
edns = append(edns, e) edns = append(edns, e)
off += int(optlen) off += int(optlen)
case EDNS0SUBNET: case EDNS0SUBNET:
e := new(EDNS0_SUBNET) e := new(EDNS0_SUBNET)
if _, err := e.Unpack(msg[off : off+int(optlen)]); err != nil { if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
return nil, len(msg), err return nil, len(msg), err
} }
edns = append(edns, e) edns = append(edns, e)
off += int(optlen) off += int(optlen)
case EDNS0COOKIE: case EDNS0COOKIE:
e := new(EDNS0_COOKIE) e := new(EDNS0_COOKIE)
if _, err := e.Unpack(msg[off : off+int(optlen)]); err != nil { if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
return nil, len(msg), err return nil, len(msg), err
} }
edns = append(edns, e) edns = append(edns, e)
off += int(optlen) off += int(optlen)
case EDNS0UL: case EDNS0UL:
e := new(EDNS0_UL) e := new(EDNS0_UL)
if _, err := e.Unpack(msg[off : off+int(optlen)]); err != nil { if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
return nil, len(msg), err return nil, len(msg), err
} }
edns = append(edns, e) edns = append(edns, e)
off += int(optlen) off += int(optlen)
case EDNS0LLQ: case EDNS0LLQ:
e := new(EDNS0_LLQ) e := new(EDNS0_LLQ)
if _, err := e.Unpack(msg[off : off+int(optlen)]); err != nil { if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
return nil, len(msg), err return nil, len(msg), err
} }
edns = append(edns, e) edns = append(edns, e)
off += int(optlen) off += int(optlen)
case EDNS0DAU: case EDNS0DAU:
e := new(EDNS0_DAU) e := new(EDNS0_DAU)
if _, err := e.Unpack(msg[off : off+int(optlen)]); err != nil { if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
return nil, len(msg), err return nil, len(msg), err
} }
edns = append(edns, e) edns = append(edns, e)
off += int(optlen) off += int(optlen)
case EDNS0DHU: case EDNS0DHU:
e := new(EDNS0_DHU) e := new(EDNS0_DHU)
if _, err := e.Unpack(msg[off : off+int(optlen)]); err != nil { if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
return nil, len(msg), err return nil, len(msg), err
} }
edns = append(edns, e) edns = append(edns, e)
off += int(optlen) off += int(optlen)
case EDNS0N3U: case EDNS0N3U:
e := new(EDNS0_N3U) e := new(EDNS0_N3U)
if _, err := e.Unpack(msg[off : off+int(optlen)]); err != nil { if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
return nil, len(msg), err return nil, len(msg), err
} }
edns = append(edns, e) edns = append(edns, e)
off += int(optlen) off += int(optlen)
case EDNS0PADDING: case EDNS0PADDING:
e := new(EDNS0_PADDING) e := new(EDNS0_PADDING)
if _, err := e.Unpack(msg[off : off+int(optlen)]); err != nil { if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
return nil, len(msg), err return nil, len(msg), err
} }
edns = append(edns, e) edns = append(edns, e)
@ -490,7 +490,7 @@ Option:
default: default:
e := new(EDNS0_LOCAL) e := new(EDNS0_LOCAL)
e.Code = code e.Code = code
if _, err := e.Unpack(msg[off : off+int(optlen)]); err != nil { if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
return nil, len(msg), err return nil, len(msg), err
} }
edns = append(edns, e) edns = append(edns, e)
@ -506,8 +506,7 @@ Option:
func packDataOpt(options []EDNS0, msg []byte, off int) (int, error) { func packDataOpt(options []EDNS0, msg []byte, off int) (int, error) {
for _, el := range options { for _, el := range options {
b := make([]byte, el.Len()) b, err := el.pack()
_, err := el.Pack(b)
if err != nil || off+4 > len(msg) { if err != nil || off+4 > len(msg) {
return len(msg), &Error{err: "overflow packing opt"} return len(msg), &Error{err: "overflow packing opt"}
} }

View File

@ -805,7 +805,7 @@ func (rr *OPENPGPKEY) copy() RR {
func (rr *OPT) copy() RR { func (rr *OPT) copy() RR {
Option := make([]EDNS0, len(rr.Option)) Option := make([]EDNS0, len(rr.Option))
for i, e := range rr.Option { for i, e := range rr.Option {
Option[i] = e.Copy() Option[i] = e.copy()
} }
return &OPT{rr.Hdr, Option} return &OPT{rr.Hdr, Option}
} }