mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-11-04 17:27:23 -05:00
dc78733196
* rename AuthIDDecoderHolder private fields * ignore unused return value more clear * change PoolSwap to private fields * refactor Unlock to defer * use const capacity, reorder code layout * replace mismatch field name poolX with type Filter * change AntiReplayTime to private fileds, protect to modify * rename lastSwapTime to lastSwap * merge duplicate time.Now. Since the current unit is in seconds, there is no need to repeat the call * refine negate expression * rename antiReplayTime to interval * add docs * fix lint stutter issue, rename antireplay.AntiReplayWindow to antireplay.ReplayFilter * rename fileds m,n to poolA,poolB * rename antireplay.go to replayfilter.go * fix build issue Co-authored-by: Chinsyo <chinsyo@sina.cn>
59 lines
1.3 KiB
Go
59 lines
1.3 KiB
Go
package antireplay
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
|
|
cuckoo "github.com/seiflotfy/cuckoofilter"
|
|
)
|
|
|
|
const replayFilterCapacity = 100000
|
|
|
|
// ReplayFilter check for replay attacks.
|
|
type ReplayFilter struct {
|
|
lock sync.Mutex
|
|
poolA *cuckoo.Filter
|
|
poolB *cuckoo.Filter
|
|
poolSwap bool
|
|
lastSwap int64
|
|
interval int64
|
|
}
|
|
|
|
// NewReplayFilter create a new filter with specifying the expiration time interval in seconds.
|
|
func NewReplayFilter(interval int64) *ReplayFilter {
|
|
filter := &ReplayFilter{}
|
|
filter.interval = interval
|
|
return filter
|
|
}
|
|
|
|
// Interval in second for expiration time for duplicate records.
|
|
func (filter *ReplayFilter) Interval() int64 {
|
|
return filter.interval
|
|
}
|
|
|
|
// Check determine if there are duplicate records.
|
|
func (filter *ReplayFilter) Check(sum []byte) bool {
|
|
filter.lock.Lock()
|
|
defer filter.lock.Unlock()
|
|
|
|
now := time.Now().Unix()
|
|
if filter.lastSwap == 0 {
|
|
filter.lastSwap = now
|
|
filter.poolA = cuckoo.NewFilter(replayFilterCapacity)
|
|
filter.poolB = cuckoo.NewFilter(replayFilterCapacity)
|
|
}
|
|
|
|
elapsed := now - filter.lastSwap
|
|
if elapsed >= filter.Interval() {
|
|
if filter.poolSwap {
|
|
filter.poolA.Reset()
|
|
} else {
|
|
filter.poolB.Reset()
|
|
}
|
|
filter.poolSwap = !filter.poolSwap
|
|
filter.lastSwap = now
|
|
}
|
|
|
|
return filter.poolA.InsertUnique(sum) && filter.poolB.InsertUnique(sum)
|
|
}
|