Make request.Request smaller (#3351)

* Make request.Request smaller

This makes the request struct smaller and removes the pointer to the do
boolean (tri-bool) as size == 0 will indicate if we have cached it.

Family can be a int8 because it only carries 3 values, Size itself is
just a uint16 under the covers.

This is a more comprehensive fix than #3292

Closes #3292

Signed-off-by: Miek Gieben <miek@miek.nl>

* cache: fix test

this now needs a valid response writter

Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
Miek Gieben 2019-10-04 09:44:58 +01:00 committed by GitHub
parent f8551df272
commit 03ea2ae955
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 28 deletions

View file

@ -191,7 +191,7 @@ func TestCache(t *testing.T) {
m := tc.in.Msg() m := tc.in.Msg()
m = cacheMsg(m, tc) m = cacheMsg(m, tc)
state := request.Request{W: nil, Req: m} state := request.Request{W: &test.ResponseWriter{}, Req: m}
mt, _ := response.Typify(m, utc) mt, _ := response.Typify(m, utc)
valid, k := key(state.Name(), m, mt, state.Do()) valid, k := key(state.Name(), m, mt, state.Do())

View file

@ -63,7 +63,7 @@ func Version(req *dns.Msg) (*dns.Msg, error) {
} }
// Size returns a normalized size based on proto. // Size returns a normalized size based on proto.
func Size(proto string, size int) int { func Size(proto string, size uint16) uint16 {
if proto == "tcp" { if proto == "tcp" {
return dns.MaxMsgSize return dns.MaxMsgSize
} }

View file

@ -18,15 +18,16 @@ type Request struct {
// Optional lowercased zone of this query. // Optional lowercased zone of this query.
Zone string Zone string
// Cache size after first call to Size or Do. // Cache size after first call to Size or Do. If size is zero nothing has been cached yet.
size int // Both Size and Do set these values (and cache them).
do *bool // nil: nothing, otherwise *do value size uint16 // UDP buffer size, or 64K in case of TCP.
do bool // DNSSEC OK value
// Caches // Caches
family int8 // transport's family.
name string // lowercase qname. name string // lowercase qname.
ip string // client's ip. ip string // client's ip.
port string // client's port. port string // client's port.
family int // transport's family.
localPort string // server's port. localPort string // server's port.
localIP string // server's ip. localIP string // server's ip.
} }
@ -127,7 +128,7 @@ func Proto(w dns.ResponseWriter) string {
// Family returns the family of the transport, 1 for IPv4 and 2 for IPv6. // Family returns the family of the transport, 1 for IPv4 and 2 for IPv6.
func (r *Request) Family() int { func (r *Request) Family() int {
if r.family != 0 { if r.family != 0 {
return r.family return int(r.family)
} }
var a net.IP var a net.IP
@ -141,26 +142,20 @@ func (r *Request) Family() int {
if a.To4() != nil { if a.To4() != nil {
r.family = 1 r.family = 1
return r.family return 1
} }
r.family = 2 r.family = 2
return r.family return 2
} }
// Do returns if the request has the DO (DNSSEC OK) bit set. // Do returns if the request has the DO (DNSSEC OK) bit set.
func (r *Request) Do() bool { func (r *Request) Do() bool {
if r.do != nil { if r.size != 0 {
return *r.do return r.do
} }
r.do = new(bool) r.Size()
return r.do
if o := r.Req.IsEdns0(); o != nil {
*r.do = o.Do()
return *r.do
}
*r.do = false
return false
} }
// Len returns the length in bytes in the request. // Len returns the length in bytes in the request.
@ -170,21 +165,19 @@ func (r *Request) Len() int { return r.Req.Len() }
// Or when the request was over TCP, we return the maximum allowed size of 64K. // Or when the request was over TCP, we return the maximum allowed size of 64K.
func (r *Request) Size() int { func (r *Request) Size() int {
if r.size != 0 { if r.size != 0 {
return r.size return int(r.size)
} }
size := 0 size := uint16(0)
if o := r.Req.IsEdns0(); o != nil { if o := r.Req.IsEdns0(); o != nil {
if r.do == nil { r.do = o.Do()
r.do = new(bool) size = o.UDPSize()
}
*r.do = o.Do()
size = int(o.UDPSize())
} }
// normalize size
size = edns.Size(r.Proto(), size) size = edns.Size(r.Proto(), size)
r.size = size r.size = size
return size return int(size)
} }
// SizeAndDo adds an OPT record that the reflects the intent from request. // SizeAndDo adds an OPT record that the reflects the intent from request.

View file

@ -13,7 +13,7 @@ func TestRequestDo(t *testing.T) {
st := testRequest() st := testRequest()
st.Do() st.Do()
if st.do == nil { if !st.do {
t.Errorf("Expected st.do to be set") t.Errorf("Expected st.do to be set")
} }
} }