70 lines
1.5 KiB
Go
70 lines
1.5 KiB
Go
|
package iptools
|
||
|
|
||
|
import (
|
||
|
"net/netip"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type Pool struct {
|
||
|
Name string `yaml:"name"`
|
||
|
Range *Range `yaml:"range"`
|
||
|
Expiry time.Duration `yaml:"expiry"`
|
||
|
Available []LeaseInfo `yaml:"available"`
|
||
|
Active map[netip.Addr]LeaseInfo `yaml:"active"`
|
||
|
Limbo map[netip.Addr]LeaseInfo `yaml:"limbo"` // leases that are currently being offered
|
||
|
}
|
||
|
|
||
|
func NewPool(name string, exp time.Duration, r *Range) (*Pool, error) {
|
||
|
p := &Pool{
|
||
|
Name: name,
|
||
|
Expiry: exp,
|
||
|
Available: enumerateRange(name, r, true),
|
||
|
}
|
||
|
|
||
|
return p, nil
|
||
|
}
|
||
|
|
||
|
func (p *Pool) Sort() {
|
||
|
p.Available = SortLeases(p.Available)
|
||
|
}
|
||
|
|
||
|
func (p *Pool) IsAddressAvailable() bool {
|
||
|
return len(p.Available) > 0
|
||
|
}
|
||
|
|
||
|
func (p *Pool) Peek(t time.Time, waitFor time.Duration) netip.Addr {
|
||
|
lease := p.Available[0]
|
||
|
p.Available = p.Available[1:]
|
||
|
lease.ResetExpiry(t, waitFor)
|
||
|
|
||
|
p.Limbo[lease.Addr] = lease
|
||
|
|
||
|
return lease.Addr
|
||
|
}
|
||
|
|
||
|
// Update checks expirations on leases, moving any expired leases back
|
||
|
// to the available pool and removing any limbo leases that are expired.
|
||
|
func (p *Pool) Update(t time.Time) {
|
||
|
for k, v := range p.Active {
|
||
|
if v.IsExpired(t) {
|
||
|
delete(p.Active, k)
|
||
|
v = v.Reset()
|
||
|
p.Available = append(p.Available, v)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for k, v := range p.Limbo {
|
||
|
if v.IsExpired(t) {
|
||
|
delete(p.Limbo, k)
|
||
|
v = v.Reset()
|
||
|
p.Available = append(p.Available, v)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
p.Sort()
|
||
|
}
|
||
|
|
||
|
func (p *Pool) Renew(lease LeaseInfo, t time.Time) {
|
||
|
|
||
|
}
|