Pull request: aghnet: fix adding entry into multiple ipsets
Updates #3638. Squashed commit of the following: commit f9c52176806051c2e3d5e34a440a919ca022c319 Author: Ainar Garipov <A.Garipov@AdGuard.COM> Date: Wed Sep 22 14:31:46 2021 +0300 aghnet: fix docs commit 1167806d73ba14d0145a2d1e11cece5dbb7958aa Author: Ainar Garipov <A.Garipov@AdGuard.COM> Date: Wed Sep 22 14:26:28 2021 +0300 all: imp docs, names commit ba08f5c759fe4d83a4709f619fa65dffe3e9e164 Author: Ainar Garipov <A.Garipov@AdGuard.COM> Date: Wed Sep 22 14:14:05 2021 +0300 aghnet: fix adding entry into multiple ipsets
This commit is contained in:
parent
b1242ee93f
commit
e1e064db59
|
@ -116,6 +116,7 @@ In this release, the schema version has changed from 10 to 12.
|
|||
|
||||
### Fixed
|
||||
|
||||
- Adding an IP into only one of the matching ipsets on Linux ([#3638]).
|
||||
- Removal of temporary filter files ([#3567]).
|
||||
- Panic when an upstream server responds with an empty question section
|
||||
([#3551]).
|
||||
|
@ -201,6 +202,7 @@ In this release, the schema version has changed from 10 to 12.
|
|||
[#3568]: https://github.com/AdguardTeam/AdGuardHome/issues/3568
|
||||
[#3579]: https://github.com/AdguardTeam/AdGuardHome/issues/3579
|
||||
[#3607]: https://github.com/AdguardTeam/AdGuardHome/issues/3607
|
||||
[#3638]: https://github.com/AdguardTeam/AdGuardHome/issues/3638
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
"github.com/digineo/go-ipset/v2"
|
||||
"github.com/mdlayher/netlink"
|
||||
"github.com/ti-mo/netfilter"
|
||||
|
@ -67,6 +68,15 @@ type ipsetProps struct {
|
|||
// unit is a convenient alias for struct{}.
|
||||
type unit = struct{}
|
||||
|
||||
// ipsInIpset is the type of a set of IP-address-to-ipset mappings.
|
||||
type ipsInIpset map[ipInIpsetEntry]unit
|
||||
|
||||
// ipInIpsetEntry is the type for entries in an ipsInIpset set.
|
||||
type ipInIpsetEntry struct {
|
||||
ipsetName string
|
||||
ipArr [net.IPv6len]byte
|
||||
}
|
||||
|
||||
// ipsetMgr is the Linux Netfilter ipset manager.
|
||||
type ipsetMgr struct {
|
||||
nameToIpset map[string]ipsetProps
|
||||
|
@ -82,7 +92,7 @@ type ipsetMgr struct {
|
|||
// are either added to all corresponding ipsets or not. When that stops
|
||||
// being the case, for example if we add dynamic reconfiguration of
|
||||
// ipsets, this map will need to become a per-ipset-name one.
|
||||
addedIPs map[[16]byte]unit
|
||||
addedIPs ipsInIpset
|
||||
|
||||
ipv4Conn ipsetConn
|
||||
ipv6Conn ipsetConn
|
||||
|
@ -199,7 +209,7 @@ func newIpsetMgrWithDialer(ipsetConf []string, dial ipsetDialer) (mgr IpsetManag
|
|||
|
||||
dial: dial,
|
||||
|
||||
addedIPs: make(map[[16]byte]unit),
|
||||
addedIPs: make(ipsInIpset),
|
||||
}
|
||||
|
||||
err = m.dialNetfilter(&netlink.Config{})
|
||||
|
@ -265,16 +275,19 @@ func (m *ipsetMgr) addIPs(host string, set ipsetProps, ips []net.IP) (n int, err
|
|||
}
|
||||
|
||||
var entries []*ipset.Entry
|
||||
var newAddedIPs [][16]byte
|
||||
var newAddedEntries []ipInIpsetEntry
|
||||
for _, ip := range ips {
|
||||
var iparr [16]byte
|
||||
copy(iparr[:], ip.To16())
|
||||
if _, added := m.addedIPs[iparr]; added {
|
||||
e := ipInIpsetEntry{
|
||||
ipsetName: set.name,
|
||||
}
|
||||
copy(e.ipArr[:], ip.To16())
|
||||
|
||||
if _, added := m.addedIPs[e]; added {
|
||||
continue
|
||||
}
|
||||
|
||||
entries = append(entries, ipset.NewEntry(ipset.EntryIP(ip)))
|
||||
newAddedIPs = append(newAddedIPs, iparr)
|
||||
newAddedEntries = append(newAddedEntries, e)
|
||||
}
|
||||
|
||||
n = len(entries)
|
||||
|
@ -299,8 +312,8 @@ func (m *ipsetMgr) addIPs(host string, set ipsetProps, ips []net.IP) (n int, err
|
|||
|
||||
// Only add these to the cache once we're sure that all of them were
|
||||
// actually sent to the ipset.
|
||||
for _, iparr := range newAddedIPs {
|
||||
m.addedIPs[iparr] = unit{}
|
||||
for _, e := range newAddedEntries {
|
||||
m.addedIPs[e] = unit{}
|
||||
}
|
||||
|
||||
return n, nil
|
||||
|
@ -330,6 +343,8 @@ func (m *ipsetMgr) addToSets(
|
|||
return n, fmt.Errorf("unexpected family %s for ipset %q", set.family, set.name)
|
||||
}
|
||||
|
||||
log.Debug("ipset: added %d ips to set %s", nn, set.name)
|
||||
|
||||
n += nn
|
||||
}
|
||||
|
||||
|
@ -346,6 +361,8 @@ func (m *ipsetMgr) Add(host string, ip4s, ip6s []net.IP) (n int, err error) {
|
|||
return 0, nil
|
||||
}
|
||||
|
||||
log.Debug("ipset: found %d sets", len(sets))
|
||||
|
||||
return m.addToSets(host, ip4s, ip6s, sets)
|
||||
}
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ func (c *ipsetCtx) process(dctx *dnsContext) (rc resultCode) {
|
|||
return resultCodeSuccess
|
||||
}
|
||||
|
||||
log.Debug("ipset: added %d new ips", n)
|
||||
log.Debug("ipset: added %d new ipset entries", n)
|
||||
|
||||
return resultCodeSuccess
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ type fakeIpsetMgr struct {
|
|||
ip6s []net.IP
|
||||
}
|
||||
|
||||
// Add implements the aghnet.IpsetManager inteface for *fakeIpsetMgr.
|
||||
// Add implements the aghnet.IpsetManager interface for *fakeIpsetMgr.
|
||||
func (m *fakeIpsetMgr) Add(host string, ip4s, ip6s []net.IP) (n int, err error) {
|
||||
m.ip4s = append(m.ip4s, ip4s...)
|
||||
m.ip6s = append(m.ip6s, ip6s...)
|
||||
|
|
|
@ -69,7 +69,7 @@ type homeContext struct {
|
|||
|
||||
configFilename string // Config filename (can be overridden via the command line arguments)
|
||||
workDir string // Location of our directory, used to protect against CWD being somewhere else
|
||||
firstRun bool // if set to true, don't run any services except HTTP web inteface, and serve only first-run html
|
||||
firstRun bool // if set to true, don't run any services except HTTP web interface, and serve only first-run html
|
||||
pidFileName string // PID file name. Empty if no PID file was created.
|
||||
disableUpdate bool // If set, don't check for updates
|
||||
controlLock sync.Mutex
|
||||
|
|
Loading…
Reference in New Issue