Skip to content

Commit

Permalink
proxy: edns cache bits
Browse files Browse the repository at this point in the history
  • Loading branch information
Mizzick committed May 15, 2023
1 parent e8b4b2c commit 33e1218
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 15 deletions.
21 changes: 12 additions & 9 deletions proxy/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,7 @@ func (c *cache) getWithSubnet(req *dns.Msg, n *net.IPNet) (ci *cacheItem, expire

var data []byte
for mask, bits := n.Mask.Size(); mask >= 0 && data == nil; mask-- {
ecsIP := n.IP.Mask(net.CIDRMask(mask, bits))
k = msgToKeyWithSubnet(req, ecsIP, mask)

k = msgToKeyWithSubnet(req, n.IP, mask, bits)
data = c.itemsWithSubnet.Get(k)
}

Expand Down Expand Up @@ -287,8 +285,8 @@ func (c *cache) setWithSubnet(m *dns.Msg, u upstream.Upstream, subnet *net.IPNet
return
}

pref, _ := subnet.Mask.Size()
key := msgToKeyWithSubnet(m, subnet.IP.Mask(subnet.Mask), pref)
pref, bits := subnet.Mask.Size()
key := msgToKeyWithSubnet(m, subnet.IP, pref, bits)
packed := item.pack()

c.itemsWithSubnetLock.Lock()
Expand Down Expand Up @@ -483,9 +481,8 @@ func msgToKey(m *dns.Msg) (b []byte) {
}

// msgToKeyWithSubnet constructs the cache key from DO bit, type, class, subnet
// mask, client's IP address and question's name of m. ecsIP is expected to be
// masked already.
func msgToKeyWithSubnet(m *dns.Msg, ecsIP net.IP, mask int) (key []byte) {
// mask, client's IP address and question's name of m.
func msgToKeyWithSubnet(m *dns.Msg, ecsIP net.IP, mask, bits int) (key []byte) {
q := m.Question[0]
keyLen := 1 + 2*packedMsgLenSz + 1 + len(q.Name)
ipLen := len(ecsIP)
Expand Down Expand Up @@ -518,7 +515,13 @@ func msgToKeyWithSubnet(m *dns.Msg, ecsIP net.IP, mask int) (key []byte) {
key[k] = uint8(mask)
k++
if masked {
k += copy(key[k:], ecsIP)
// Apply mask on the bits level to reduce allocations.
am := net.CIDRMask(mask, bits)
n := len(ecsIP)
for i := 0; i < n; i++ {
key[k] = ecsIP[i] & am[i]
k++
}
}
copy(key[k:], strings.ToLower(q.Name))

Expand Down
8 changes: 4 additions & 4 deletions proxy/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ func TestCache_getWithSubnet(t *testing.T) {
t.Run("different_ip", func(t *testing.T) {
ci, expired, key := c.getWithSubnet(req, &net.IPNet{IP: ip2234, Mask: mask24})
assert.False(t, expired)
assert.Equal(t, msgToKeyWithSubnet(req, ip2234, 0), key)
assert.Equal(t, msgToKeyWithSubnet(req, ip2234, 0, netutil.IPv4BitLen), key)
assert.Nil(t, ci)
})

Expand All @@ -627,7 +627,7 @@ func TestCache_getWithSubnet(t *testing.T) {
t.Run("with_subnet_1", func(t *testing.T) {
ci, expired, key := c.getWithSubnet(req, &net.IPNet{IP: ip1234, Mask: mask24})
assert.False(t, expired)
assert.Equal(t, msgToKeyWithSubnet(req, ip1234.Mask(mask16), 16), key)
assert.Equal(t, msgToKeyWithSubnet(req, ip1234, 16, netutil.IPv4BitLen), key)

require.NotNil(t, ci)
require.NotNil(t, ci.m)
Expand All @@ -640,7 +640,7 @@ func TestCache_getWithSubnet(t *testing.T) {
t.Run("with_subnet_2", func(t *testing.T) {
ci, expired, key := c.getWithSubnet(req, &net.IPNet{IP: ip2234, Mask: mask24})
assert.False(t, expired)
assert.Equal(t, msgToKeyWithSubnet(req, ip2234.Mask(mask16), 16), key)
assert.Equal(t, msgToKeyWithSubnet(req, ip2234, 16, netutil.IPv4BitLen), key)

require.NotNil(t, ci)
require.NotNil(t, ci.m)
Expand All @@ -653,7 +653,7 @@ func TestCache_getWithSubnet(t *testing.T) {
t.Run("with_subnet_3", func(t *testing.T) {
ci, expired, key := c.getWithSubnet(req, &net.IPNet{IP: ip3234, Mask: mask24})
assert.False(t, expired)
assert.Equal(t, msgToKeyWithSubnet(req, ip1234, 0), key)
assert.Equal(t, msgToKeyWithSubnet(req, ip1234, 0, netutil.IPv4BitLen), key)

require.NotNil(t, ci)
require.NotNil(t, ci.m)
Expand Down
4 changes: 2 additions & 2 deletions proxy/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1028,7 +1028,7 @@ func TestECSProxyCacheMinMaxTTL(t *testing.T) {
})
assert.False(t, expired)

assert.Equal(t, key, msgToKeyWithSubnet(d.Req, clientIP, 24))
assert.Equal(t, key, msgToKeyWithSubnet(d.Req, clientIP, 24, netutil.IPv4BitLen))
assert.True(t, ci.m.Answer[0].Header().Ttl == prx.CacheMinTTL)

// 2nd request
Expand All @@ -1055,7 +1055,7 @@ func TestECSProxyCacheMinMaxTTL(t *testing.T) {
Mask: net.CIDRMask(24, netutil.IPv4BitLen),
})
assert.False(t, expired)
assert.Equal(t, key, msgToKeyWithSubnet(d.Req, clientIP, 24))
assert.Equal(t, key, msgToKeyWithSubnet(d.Req, clientIP, 24, netutil.IPv4BitLen))
assert.True(t, ci.m.Answer[0].Header().Ttl == prx.CacheMaxTTL)
}

Expand Down

0 comments on commit 33e1218

Please sign in to comment.