mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2024-01-19 02:48:24 +00:00
Clean up old signature hash pools
This commit is contained in:
parent
cdd817edf9
commit
98dcec0ee2
|
@ -33,6 +33,7 @@ type IdentityAccessManagement struct {
|
|||
isAuthEnabled bool
|
||||
domain string
|
||||
hashes map[string]*sync.Pool
|
||||
hashCounters map[string]*int32
|
||||
hashMu sync.RWMutex
|
||||
}
|
||||
|
||||
|
@ -81,6 +82,7 @@ func NewIdentityAccessManagement(option *S3ApiServerOption) *IdentityAccessManag
|
|||
iam := &IdentityAccessManagement{
|
||||
domain: option.DomainName,
|
||||
hashes: make(map[string]*sync.Pool),
|
||||
hashCounters: make(map[string]*int32),
|
||||
}
|
||||
if option.Config != "" {
|
||||
if err := iam.loadS3ApiConfigurationFromFile(option.Config); err != nil {
|
||||
|
|
|
@ -32,6 +32,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
|
@ -463,36 +464,67 @@ func (iam *IdentityAccessManagement) doesPresignedSignatureMatch(hashedPayload s
|
|||
return identity, s3err.ErrNone
|
||||
}
|
||||
|
||||
// getSignature
|
||||
func (iam *IdentityAccessManagement) getSignature(secretKey string, t time.Time, region string, service string, stringToSign string) string {
|
||||
pool := iam.getSignatureHashPool(secretKey, t, region, service)
|
||||
h := pool.Get().(hash.Hash)
|
||||
defer pool.Put(h)
|
||||
|
||||
h.Reset()
|
||||
h.Write([]byte(stringToSign))
|
||||
sig := hex.EncodeToString(h.Sum(nil))
|
||||
|
||||
return sig
|
||||
}
|
||||
|
||||
func (iam *IdentityAccessManagement) getSignatureHashPool(secretKey string, t time.Time, region string, service string) *sync.Pool {
|
||||
// Build a caching key for the pool.
|
||||
date := t.Format(yyyymmdd)
|
||||
hashID := "AWS4" + secretKey + "/" + date + "/" + region + "/" + service + "/" + "aws4_request"
|
||||
|
||||
// Try to find an existing pool and return it.
|
||||
iam.hashMu.RLock()
|
||||
pool, ok := iam.hashes[hashID]
|
||||
iam.hashMu.RUnlock()
|
||||
|
||||
if !ok {
|
||||
iam.hashMu.Lock()
|
||||
if pool, ok = iam.hashes[hashID]; !ok {
|
||||
pool = &sync.Pool{
|
||||
defer iam.hashMu.Unlock()
|
||||
pool, ok = iam.hashes[hashID]
|
||||
}
|
||||
|
||||
if ok {
|
||||
atomic.StoreInt32(iam.hashCounters[hashID], 1)
|
||||
return pool
|
||||
}
|
||||
|
||||
// Create a pool that returns HMAC hashers for the requested parameters to avoid expensive re-initializing
|
||||
// of new instances on every request.
|
||||
iam.hashes[hashID] = &sync.Pool{
|
||||
New: func() any {
|
||||
signingKey := getSigningKey(secretKey, date, region, service)
|
||||
return hmac.New(sha256.New, signingKey)
|
||||
},
|
||||
}
|
||||
iam.hashes[hashID] = pool
|
||||
iam.hashCounters[hashID] = new(int32)
|
||||
|
||||
// Clean up unused pools automatically after one hour of inactivity
|
||||
ticker := time.NewTicker(time.Hour)
|
||||
go func() {
|
||||
for range ticker.C {
|
||||
old := atomic.SwapInt32(iam.hashCounters[hashID], 0)
|
||||
if old == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
ticker.Stop()
|
||||
iam.hashMu.Lock()
|
||||
delete(iam.hashes, hashID)
|
||||
delete(iam.hashCounters, hashID)
|
||||
iam.hashMu.Unlock()
|
||||
}
|
||||
}()
|
||||
|
||||
h := pool.Get().(hash.Hash)
|
||||
h.Reset()
|
||||
h.Write([]byte(stringToSign))
|
||||
sig := hex.EncodeToString(h.Sum(nil))
|
||||
pool.Put(h)
|
||||
|
||||
return sig
|
||||
return iam.hashes[hashID]
|
||||
}
|
||||
|
||||
func contains(list []string, elem string) bool {
|
||||
|
|
|
@ -128,6 +128,7 @@ func BenchmarkGetSignature(b *testing.B) {
|
|||
t := time.Now()
|
||||
iam := IdentityAccessManagement{
|
||||
hashes: make(map[string]*sync.Pool),
|
||||
hashCounters: make(map[string]*int32),
|
||||
}
|
||||
|
||||
b.ReportAllocs()
|
||||
|
|
Loading…
Reference in a new issue