You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
1.7 KiB
90 lines
1.7 KiB
// Package salts contains MTProto server salt storage. |
|
package salts |
|
|
|
import ( |
|
"sort" |
|
"sync" |
|
"time" |
|
|
|
"github.com/gotd/td/internal/mt" |
|
) |
|
|
|
// Salts is a simple struct store server salts. |
|
type Salts struct { |
|
// server salts fetched by getSalts. |
|
salts []mt.FutureSalt |
|
saltsMux sync.Mutex |
|
} |
|
|
|
// Get returns next valid salt. |
|
func (s *Salts) Get(deadline time.Time) (int64, bool) { |
|
s.saltsMux.Lock() |
|
defer s.saltsMux.Unlock() |
|
|
|
check: |
|
if len(s.salts) < 1 { |
|
return 0, false |
|
} |
|
|
|
date := int(deadline.Unix()) |
|
if salt := s.salts[len(s.salts)-1]; salt.ValidUntil > date { |
|
return salt.Salt, true |
|
} |
|
|
|
// Filter (in place) from SliceTricks. |
|
n := 0 |
|
// Check that the salt will be valid until deadline. |
|
for _, salt := range s.salts { |
|
// Filter expired salts. |
|
if salt.ValidUntil > date { |
|
// Keep valid salt. |
|
s.salts[n] = salt |
|
n++ |
|
} |
|
} |
|
s.salts = s.salts[:n] |
|
goto check |
|
} |
|
|
|
type saltSlice []mt.FutureSalt |
|
|
|
func (s saltSlice) Len() int { |
|
return len(s) |
|
} |
|
|
|
func (s saltSlice) Less(i, j int) bool { |
|
return s[i].ValidUntil > s[j].ValidUntil |
|
} |
|
|
|
func (s saltSlice) Swap(i, j int) { |
|
s[i], s[j] = s[j], s[i] |
|
} |
|
|
|
// Store stores all given salts. |
|
func (s *Salts) Store(salts []mt.FutureSalt) { |
|
s.saltsMux.Lock() |
|
defer s.saltsMux.Unlock() |
|
|
|
s.salts = append(s.salts, salts...) |
|
// Filter duplicates. |
|
n := 0 |
|
dedup := make(map[int64]struct{}, len(s.salts)+1) |
|
for _, salt := range s.salts { |
|
if _, ok := dedup[salt.Salt]; !ok { |
|
dedup[salt.Salt] = struct{}{} |
|
s.salts[n] = salt |
|
n++ |
|
} |
|
} |
|
s.salts = s.salts[:n] |
|
|
|
// Sort slice by valid until. |
|
sort.Sort(saltSlice(s.salts)) |
|
} |
|
|
|
// Reset deletes all stored salts. |
|
func (s *Salts) Reset() { |
|
s.saltsMux.Lock() |
|
s.salts = s.salts[:0] |
|
s.saltsMux.Unlock() |
|
}
|
|
|