github.com/sagernet/sing@v0.4.0-beta.19.0.20240518125136-f67a0988a636/common/replay/simple.go (about)

     1  package replay
     2  
     3  import (
     4  	"sync"
     5  	"time"
     6  )
     7  
     8  type SimpleFilter struct {
     9  	access    sync.Mutex
    10  	lastClean time.Time
    11  	timeout   time.Duration
    12  	pool      map[string]time.Time
    13  }
    14  
    15  func NewSimple(timeout time.Duration) Filter {
    16  	return &SimpleFilter{
    17  		lastClean: time.Now(),
    18  		pool:      make(map[string]time.Time),
    19  		timeout:   timeout,
    20  	}
    21  }
    22  
    23  func (f *SimpleFilter) Check(salt []byte) bool {
    24  	now := time.Now()
    25  	saltStr := string(salt)
    26  	f.access.Lock()
    27  	defer f.access.Unlock()
    28  
    29  	var exists bool
    30  	if now.Sub(f.lastClean) > f.timeout {
    31  		for oldSum, added := range f.pool {
    32  			if now.Sub(added) > f.timeout {
    33  				delete(f.pool, oldSum)
    34  			}
    35  		}
    36  		_, exists = f.pool[saltStr]
    37  		f.lastClean = now
    38  	} else {
    39  		if added, loaded := f.pool[saltStr]; loaded && now.Sub(added) <= f.timeout {
    40  			exists = true
    41  		}
    42  	}
    43  	if !exists {
    44  		f.pool[saltStr] = now
    45  	}
    46  	return !exists
    47  }