* Change EDNS_EXPIRE field to support zero length option data (Resolves #1292) As per [RFC7134](https://datatracker.ietf.org/doc/html/rfc7314#section-2) the Expire Option in queries should be zero-length. In the current implementation the field is uint32 which always instatiates 4bytes for that field when packing to wire format. For that reason we change the field to []uint8 so it can support 0-length and 4-byte length option data. * addressed comments * addressed comments * make change backwards compatible * add comment for Empty field
This commit is contained in:
parent
05140a3136
commit
d48e92a0e6
16
edns.go
16
edns.go
|
@ -584,14 +584,17 @@ func (e *EDNS0_N3U) copy() EDNS0 { return &EDNS0_N3U{e.Code, e.AlgCode} }
|
||||||
type EDNS0_EXPIRE struct {
|
type EDNS0_EXPIRE struct {
|
||||||
Code uint16 // Always EDNS0EXPIRE
|
Code uint16 // Always EDNS0EXPIRE
|
||||||
Expire uint32
|
Expire uint32
|
||||||
|
Empty bool // Empty is used to signal an empty Expire option in a backwards compatible way, it's not used on the wire.
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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) copy() EDNS0 { return &EDNS0_EXPIRE{e.Code, e.Expire, e.Empty} }
|
||||||
func (e *EDNS0_EXPIRE) copy() EDNS0 { return &EDNS0_EXPIRE{e.Code, e.Expire} }
|
|
||||||
|
|
||||||
func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
|
func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
|
||||||
|
if e.Empty {
|
||||||
|
return []byte{}, nil
|
||||||
|
}
|
||||||
b := make([]byte, 4)
|
b := make([]byte, 4)
|
||||||
binary.BigEndian.PutUint32(b, e.Expire)
|
binary.BigEndian.PutUint32(b, e.Expire)
|
||||||
return b, nil
|
return b, nil
|
||||||
|
@ -600,15 +603,24 @@ func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
|
||||||
func (e *EDNS0_EXPIRE) unpack(b []byte) error {
|
func (e *EDNS0_EXPIRE) unpack(b []byte) error {
|
||||||
if len(b) == 0 {
|
if len(b) == 0 {
|
||||||
// zero-length EXPIRE query, see RFC 7314 Section 2
|
// zero-length EXPIRE query, see RFC 7314 Section 2
|
||||||
|
e.Empty = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if len(b) < 4 {
|
if len(b) < 4 {
|
||||||
return ErrBuf
|
return ErrBuf
|
||||||
}
|
}
|
||||||
e.Expire = binary.BigEndian.Uint32(b)
|
e.Expire = binary.BigEndian.Uint32(b)
|
||||||
|
e.Empty = false
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *EDNS0_EXPIRE) String() (s string) {
|
||||||
|
if e.Empty {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strconv.FormatUint(uint64(e.Expire), 10)
|
||||||
|
}
|
||||||
|
|
||||||
// The EDNS0_LOCAL option is used for local/experimental purposes. The option
|
// The EDNS0_LOCAL option is used for local/experimental purposes. The option
|
||||||
// code is recommended to be within the range [EDNS0LOCALSTART, EDNS0LOCALEND]
|
// code is recommended to be within the range [EDNS0LOCALSTART, EDNS0LOCALEND]
|
||||||
// (RFC6891), although any unassigned code can actually be used. The content of
|
// (RFC6891), although any unassigned code can actually be used. The content of
|
||||||
|
|
Loading…
Reference in New Issue