improve ip shuffling (prevent ips in use from being dealt)

This commit is contained in:
Niko Storni 2019-07-12 23:54:48 +02:00
parent 8c2a8262e6
commit 43f745ae20

View file

@ -18,6 +18,7 @@ const unbanTimeout = 3 * time.Hour
var ipv6Pool []string var ipv6Pool []string
var ipv4Pool []string var ipv4Pool []string
var throttledIPs map[string]bool var throttledIPs map[string]bool
var ipInUse map[string]bool
var ipLastUsed map[string]time.Time var ipLastUsed map[string]time.Time
var ipMutex sync.Mutex var ipMutex sync.Mutex
var stopper = stop.New() var stopper = stop.New()
@ -27,6 +28,7 @@ func GetNextIP(ipv6 bool) (string, error) {
defer ipMutex.Unlock() defer ipMutex.Unlock()
if len(ipv4Pool) < 1 || len(ipv6Pool) < 1 { if len(ipv4Pool) < 1 || len(ipv6Pool) < 1 {
throttledIPs = make(map[string]bool) throttledIPs = make(map[string]bool)
ipInUse = make(map[string]bool)
ipLastUsed = make(map[string]time.Time) ipLastUsed = make(map[string]time.Time)
addrs, err := net.InterfaceAddrs() addrs, err := net.InterfaceAddrs()
if err != nil { if err != nil {
@ -37,8 +39,10 @@ func GetNextIP(ipv6 bool) (string, error) {
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.IP.To16() != nil && govalidator.IsIPv6(ipnet.IP.String()) { if ipnet.IP.To16() != nil && govalidator.IsIPv6(ipnet.IP.String()) {
ipv6Pool = append(ipv6Pool, ipnet.IP.String()) ipv6Pool = append(ipv6Pool, ipnet.IP.String())
ipLastUsed[ipnet.IP.String()] = time.Now().Add(-IPCooldownPeriod)
} else if ipnet.IP.To4() != nil && govalidator.IsIPv4(ipnet.IP.String()) { } else if ipnet.IP.To4() != nil && govalidator.IsIPv4(ipnet.IP.String()) {
ipv4Pool = append(ipv4Pool, ipnet.IP.String()) ipv4Pool = append(ipv4Pool, ipnet.IP.String())
ipLastUsed[ipnet.IP.String()] = time.Now().Add(-IPCooldownPeriod)
} }
} }
} }
@ -54,21 +58,32 @@ func GetNextIP(ipv6 bool) (string, error) {
} }
lastUse := ipLastUsed[nextIP] lastUse := ipLastUsed[nextIP]
if time.Since(lastUse) < IPCooldownPeriod { if time.Since(lastUse) < IPCooldownPeriod {
log.Debugf("The IP %s is too hot, waiting for %.1f seconds before continuing", nextIP, (IPCooldownPeriod - time.Since(lastUse)).Seconds())
time.Sleep(IPCooldownPeriod - time.Since(lastUse)) time.Sleep(IPCooldownPeriod - time.Since(lastUse))
} }
ipLastUsed[nextIP] = time.Now() ipInUse[nextIP] = true
return nextIP, nil return nextIP, nil
} }
func releaseIP(ip string) {
ipMutex.Lock()
defer ipMutex.Unlock()
ipLastUsed[ip] = time.Now()
ipInUse[ip] = false
}
func getLeastUsedIP(ipPool []string) string { func getLeastUsedIP(ipPool []string) string {
nextIP := "" nextIP := ""
veryLastUse := time.Now() veryLastUse := time.Now()
for _, ip := range ipPool { for _, ip := range ipPool {
isThrottled, _ := throttledIPs[ip] isThrottled := throttledIPs[ip]
if isThrottled { if isThrottled {
continue continue
} }
inUse := ipInUse[ip]
if inUse {
continue
}
lastUse := ipLastUsed[ip] lastUse := ipLastUsed[ip]
if lastUse.Before(veryLastUse) { if lastUse.Before(veryLastUse) {
nextIP = ip nextIP = ip
@ -81,7 +96,7 @@ func getLeastUsedIP(ipPool []string) string {
func SetIpThrottled(ip string, stopGrp *stop.Group) { func SetIpThrottled(ip string, stopGrp *stop.Group) {
ipMutex.Lock() ipMutex.Lock()
defer ipMutex.Unlock() defer ipMutex.Unlock()
isThrottled, _ := throttledIPs[ip] isThrottled := throttledIPs[ip]
if isThrottled { if isThrottled {
return return
} }