// Copyright (c) 2019 Shivaram Lingamneni // released under the MIT license package connection_limits import ( "sync" "time" ) // TorLimiter is a combined limiter and throttler for use on connections // proxied from a Tor hidden service (so we don't have meaningful IPs, // a notion of CIDR width, etc.) type TorLimiter struct { sync.Mutex numConnections int maxConnections int throttle GenericThrottle } func (tl *TorLimiter) Configure(maxConnections int, duration time.Duration, maxConnectionsPerDuration int) { tl.Lock() defer tl.Unlock() tl.maxConnections = maxConnections tl.throttle.Duration = duration tl.throttle.Limit = maxConnectionsPerDuration } func (tl *TorLimiter) AddClient() error { tl.Lock() defer tl.Unlock() if tl.maxConnections != 0 && tl.maxConnections <= tl.numConnections { return ErrLimitExceeded } throttled, _ := tl.throttle.Touch() if throttled { return ErrThrottleExceeded } tl.numConnections += 1 return nil } func (tl *TorLimiter) RemoveClient() { tl.Lock() tl.numConnections -= 1 tl.Unlock() }