dnsforward/ipset: synchronize access to ipset cache

Resolves read/write and write/write races on the cache maps present since feature
introduction.
This commit is contained in:
David Sheets 2020-10-12 10:56:08 +01:00 committed by ArtemBaskal
parent 1e63dbc4ba
commit a94149e404
1 changed files with 9 additions and 0 deletions

View File

@ -3,6 +3,7 @@ package dnsforward
import (
"net"
"strings"
"sync"
"github.com/AdguardTeam/AdGuardHome/util"
"github.com/AdguardTeam/golibs/log"
@ -13,6 +14,8 @@ type ipsetCtx struct {
ipsetList map[string][]string // domain -> []ipset_name
ipsetCache map[[4]byte]bool // cache for IP[] to prevent duplicate calls to ipset program
ipset6Cache map[[16]byte]bool // cache for IP[] to prevent duplicate calls to ipset program
ipv4Mutex *sync.RWMutex
ipv6Mutex *sync.RWMutex
}
// Convert configuration settings to an internal map
@ -21,6 +24,8 @@ func (c *ipsetCtx) init(ipsetConfig []string) {
c.ipsetList = make(map[string][]string)
c.ipsetCache = make(map[[4]byte]bool)
c.ipset6Cache = make(map[[16]byte]bool)
c.ipv4Mutex = &sync.RWMutex{}
c.ipv6Mutex = &sync.RWMutex{}
for _, it := range ipsetConfig {
it = strings.TrimSpace(it)
@ -67,6 +72,8 @@ func (c *ipsetCtx) getIP(rr dns.RR) net.IP {
case *dns.A:
var ip4 [4]byte
copy(ip4[:], a.A.To4())
c.ipv4Mutex.Lock()
defer c.ipv4Mutex.Unlock()
_, found := c.ipsetCache[ip4]
if found {
return nil // this IP was added before
@ -77,6 +84,8 @@ func (c *ipsetCtx) getIP(rr dns.RR) net.IP {
case *dns.AAAA:
var ip6 [16]byte
copy(ip6[:], a.AAAA)
c.ipv6Mutex.Lock()
defer c.ipv6Mutex.Unlock()
_, found := c.ipset6Cache[ip6]
if found {
return nil // this IP was added before