|  | @@ -3,6 +3,9 @@ package protocol
 | 
											
												
													
														|  |  import (
 |  |  import (
 | 
											
												
													
														|  |  	"sync"
 |  |  	"sync"
 | 
											
												
													
														|  |  	"time"
 |  |  	"time"
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	"github.com/v2ray/v2ray-core/common"
 | 
											
												
													
														|  | 
 |  | +	"github.com/v2ray/v2ray-core/common/signal"
 | 
											
												
													
														|  |  )
 |  |  )
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  const (
 |  |  const (
 | 
											
										
											
												
													
														|  | @@ -18,6 +21,8 @@ type idEntry struct {
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  type UserValidator interface {
 |  |  type UserValidator interface {
 | 
											
												
													
														|  | 
 |  | +	common.Releasable
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  	Add(user *User) error
 |  |  	Add(user *User) error
 | 
											
												
													
														|  |  	Get(timeHash []byte) (*User, Timestamp, bool)
 |  |  	Get(timeHash []byte) (*User, Timestamp, bool)
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
										
											
												
													
														|  | @@ -28,6 +33,7 @@ type TimedUserValidator struct {
 | 
											
												
													
														|  |  	ids        []*idEntry
 |  |  	ids        []*idEntry
 | 
											
												
													
														|  |  	access     sync.RWMutex
 |  |  	access     sync.RWMutex
 | 
											
												
													
														|  |  	hasher     IDHash
 |  |  	hasher     IDHash
 | 
											
												
													
														|  | 
 |  | +	cancel     *signal.CancelSignal
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  type indexTimePair struct {
 |  |  type indexTimePair struct {
 | 
											
										
											
												
													
														|  | @@ -42,11 +48,23 @@ func NewTimedUserValidator(hasher IDHash) UserValidator {
 | 
											
												
													
														|  |  		access:     sync.RWMutex{},
 |  |  		access:     sync.RWMutex{},
 | 
											
												
													
														|  |  		ids:        make([]*idEntry, 0, 512),
 |  |  		ids:        make([]*idEntry, 0, 512),
 | 
											
												
													
														|  |  		hasher:     hasher,
 |  |  		hasher:     hasher,
 | 
											
												
													
														|  | 
 |  | +		cancel:     signal.NewCloseSignal(),
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  | -	go tus.updateUserHash(time.Tick(updateIntervalSec * time.Second))
 |  | 
 | 
											
												
													
														|  | 
 |  | +	go tus.updateUserHash(time.Tick(updateIntervalSec*time.Second), tus.cancel)
 | 
											
												
													
														|  |  	return tus
 |  |  	return tus
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +func (this *TimedUserValidator) Release() {
 | 
											
												
													
														|  | 
 |  | +	this.cancel.Cancel()
 | 
											
												
													
														|  | 
 |  | +	this.cancel.WaitForDone()
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	this.validUsers = nil
 | 
											
												
													
														|  | 
 |  | +	this.userHash = nil
 | 
											
												
													
														|  | 
 |  | +	this.ids = nil
 | 
											
												
													
														|  | 
 |  | +	this.hasher = nil
 | 
											
												
													
														|  | 
 |  | +	this.cancel = nil
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  func (this *TimedUserValidator) generateNewHashes(nowSec Timestamp, idx int, entry *idEntry) {
 |  |  func (this *TimedUserValidator) generateNewHashes(nowSec Timestamp, idx int, entry *idEntry) {
 | 
											
												
													
														|  |  	var hashValue [16]byte
 |  |  	var hashValue [16]byte
 | 
											
												
													
														|  |  	var hashValueRemoval [16]byte
 |  |  	var hashValueRemoval [16]byte
 | 
											
										
											
												
													
														|  | @@ -70,13 +88,20 @@ func (this *TimedUserValidator) generateNewHashes(nowSec Timestamp, idx int, ent
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -func (this *TimedUserValidator) updateUserHash(tick <-chan time.Time) {
 |  | 
 | 
											
												
													
														|  | -	for now := range tick {
 |  | 
 | 
											
												
													
														|  | -		nowSec := Timestamp(now.Unix() + cacheDurationSec)
 |  | 
 | 
											
												
													
														|  | -		for _, entry := range this.ids {
 |  | 
 | 
											
												
													
														|  | -			this.generateNewHashes(nowSec, entry.userIdx, entry)
 |  | 
 | 
											
												
													
														|  | 
 |  | +func (this *TimedUserValidator) updateUserHash(tick <-chan time.Time, cancel *signal.CancelSignal) {
 | 
											
												
													
														|  | 
 |  | +L:
 | 
											
												
													
														|  | 
 |  | +	for {
 | 
											
												
													
														|  | 
 |  | +		select {
 | 
											
												
													
														|  | 
 |  | +		case now := <-tick:
 | 
											
												
													
														|  | 
 |  | +			nowSec := Timestamp(now.Unix() + cacheDurationSec)
 | 
											
												
													
														|  | 
 |  | +			for _, entry := range this.ids {
 | 
											
												
													
														|  | 
 |  | +				this.generateNewHashes(nowSec, entry.userIdx, entry)
 | 
											
												
													
														|  | 
 |  | +			}
 | 
											
												
													
														|  | 
 |  | +		case <-cancel.WaitForCancel():
 | 
											
												
													
														|  | 
 |  | +			break L
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  | 
 |  | +	cancel.Done()
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  func (this *TimedUserValidator) Add(user *User) error {
 |  |  func (this *TimedUserValidator) Add(user *User) error {
 |