Pull request: 3890 fix anonymization
Merge in DNS/adguard-home from 3890-fix-stats to master
Updates #3890.
Squashed commit of the following:
commit a77a6204bc8a58f62a4fac70efdcae4267a64810
Merge: 834493a2 90e65b66
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Mon Dec 6 17:22:16 2021 +0300
Merge branch 'master' into 3890-fix-stats
commit 834493a22ae79199efcc44e0715e2ac6f6272963
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Mon Dec 6 17:09:30 2021 +0300
querylog: load once
commit b8000e7ba7a998fcd4553230ec5e5f9c90106e31
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Mon Dec 6 16:54:41 2021 +0300
querylog: fix docs
commit 7db99ccfa19b58100950c11d67b23bca7af3e5cb
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Mon Dec 6 16:51:31 2021 +0300
querylog: imp docs
commit 2a84650bd7ac5195730a7ab47b9562a83f721499
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Mon Dec 6 15:48:09 2021 +0300
querylog: imp anonyization
commit 0f63feb1ff5f006fc528c3b681ef3b9d2199581e
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Mon Dec 6 14:44:37 2021 +0300
all: imp code & docs
commit c4ccdcbb7248897edd178fd5cb77127e39ada73d
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Mon Dec 6 14:24:30 2021 +0300
all: log changes
commit 60bb777a5aff36bba129a078fa11ae566298178a
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Mon Dec 6 14:08:41 2021 +0300
all: use atomic value
commit c45886bd20eee2212b42686ff369830d8c08fe36
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Tue Nov 30 18:50:02 2021 +0300
all: anonymize separately
This commit is contained in:
@@ -16,10 +16,9 @@ type DiskConfig struct {
|
||||
|
||||
// Config - module configuration
|
||||
type Config struct {
|
||||
Filename string // database file name
|
||||
LimitDays uint32 // time limit (in days)
|
||||
UnitID unitIDCallback // user function to get the current unit ID. If nil, the current time hour is used.
|
||||
AnonymizeClientIP bool // anonymize clients' IP addresses
|
||||
Filename string // database file name
|
||||
LimitDays uint32 // time limit (in days)
|
||||
UnitID unitIDCallback // user function to get the current unit ID. If nil, the current time hour is used.
|
||||
|
||||
// Called when the configuration is changed by HTTP request
|
||||
ConfigModified func()
|
||||
|
||||
@@ -26,11 +26,13 @@ const (
|
||||
|
||||
// statsCtx - global context
|
||||
type statsCtx struct {
|
||||
// mu protects unit.
|
||||
mu *sync.Mutex
|
||||
// current is the actual statistics collection result.
|
||||
current *unit
|
||||
|
||||
db *bolt.DB
|
||||
conf *Config
|
||||
|
||||
unit *unit // the current unit
|
||||
unitLock sync.Mutex // protect 'unit'
|
||||
}
|
||||
|
||||
// data for 1 time unit
|
||||
@@ -66,7 +68,9 @@ type unitDB struct {
|
||||
}
|
||||
|
||||
func createObject(conf Config) (s *statsCtx, err error) {
|
||||
s = &statsCtx{}
|
||||
s = &statsCtx{
|
||||
mu: &sync.Mutex{},
|
||||
}
|
||||
if !checkInterval(conf.LimitDays) {
|
||||
conf.LimitDays = 1
|
||||
}
|
||||
@@ -112,7 +116,7 @@ func createObject(conf Config) (s *statsCtx, err error) {
|
||||
if udb != nil {
|
||||
deserialize(&u, udb)
|
||||
}
|
||||
s.unit = &u
|
||||
s.current = &u
|
||||
|
||||
log.Debug("stats: initialized")
|
||||
|
||||
@@ -178,11 +182,13 @@ func (s *statsCtx) dbOpen() bool {
|
||||
|
||||
// Atomically swap the currently active unit with a new value
|
||||
// Return old value
|
||||
func (s *statsCtx) swapUnit(new *unit) *unit {
|
||||
s.unitLock.Lock()
|
||||
u := s.unit
|
||||
s.unit = new
|
||||
s.unitLock.Unlock()
|
||||
func (s *statsCtx) swapUnit(new *unit) (u *unit) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
u = s.current
|
||||
s.current = new
|
||||
|
||||
return u
|
||||
}
|
||||
|
||||
@@ -250,6 +256,13 @@ func unitNameToID(name []byte) (id uint32, ok bool) {
|
||||
return uint32(binary.BigEndian.Uint64(name)), true
|
||||
}
|
||||
|
||||
func (s *statsCtx) ongoing() (u *unit) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
return s.current
|
||||
}
|
||||
|
||||
// Flush the current unit to DB and delete an old unit when a new hour is started
|
||||
// If a unit must be flushed:
|
||||
// . lock DB
|
||||
@@ -260,10 +273,7 @@ func unitNameToID(name []byte) (id uint32, ok bool) {
|
||||
// . unlock DB
|
||||
func (s *statsCtx) periodicFlush() {
|
||||
for {
|
||||
s.unitLock.Lock()
|
||||
ptr := s.unit
|
||||
s.unitLock.Unlock()
|
||||
|
||||
ptr := s.ongoing()
|
||||
if ptr == nil {
|
||||
break
|
||||
}
|
||||
@@ -491,22 +501,6 @@ func (s *statsCtx) clear() {
|
||||
log.Debug("stats: cleared")
|
||||
}
|
||||
|
||||
// Get Client IP address
|
||||
func (s *statsCtx) getClientIP(ip net.IP) (clientIP net.IP) {
|
||||
if s.conf.AnonymizeClientIP && ip != nil {
|
||||
const AnonymizeClientIP4Mask = 16
|
||||
const AnonymizeClientIP6Mask = 112
|
||||
|
||||
if ip.To4() != nil {
|
||||
return ip.Mask(net.CIDRMask(AnonymizeClientIP4Mask, 32))
|
||||
}
|
||||
|
||||
return ip.Mask(net.CIDRMask(AnonymizeClientIP6Mask, 128))
|
||||
}
|
||||
|
||||
return ip
|
||||
}
|
||||
|
||||
func (s *statsCtx) Update(e Entry) {
|
||||
if s.conf.limit == 0 {
|
||||
return
|
||||
@@ -521,14 +515,13 @@ func (s *statsCtx) Update(e Entry) {
|
||||
|
||||
clientID := e.Client
|
||||
if ip := net.ParseIP(clientID); ip != nil {
|
||||
ip = s.getClientIP(ip)
|
||||
clientID = ip.String()
|
||||
}
|
||||
|
||||
s.unitLock.Lock()
|
||||
defer s.unitLock.Unlock()
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
u := s.unit
|
||||
u := s.current
|
||||
|
||||
u.nResult[e.Result]++
|
||||
|
||||
@@ -549,10 +542,8 @@ func (s *statsCtx) loadUnits(limit uint32) ([]*unitDB, uint32) {
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
s.unitLock.Lock()
|
||||
curUnit := serialize(s.unit)
|
||||
curID := s.unit.id
|
||||
s.unitLock.Unlock()
|
||||
cur := s.ongoing()
|
||||
curID := cur.id
|
||||
|
||||
// Per-hour units.
|
||||
units := []*unitDB{}
|
||||
@@ -568,7 +559,7 @@ func (s *statsCtx) loadUnits(limit uint32) ([]*unitDB, uint32) {
|
||||
|
||||
_ = tx.Rollback()
|
||||
|
||||
units = append(units, curUnit)
|
||||
units = append(units, serialize(cur))
|
||||
|
||||
if len(units) != int(limit) {
|
||||
log.Fatalf("len(units) != limit: %d %d", len(units), limit)
|
||||
|
||||
Reference in New Issue
Block a user