diff --git a/iptools/pool.go b/iptools/pool.go new file mode 100644 index 0000000..0c0db89 --- /dev/null +++ b/iptools/pool.go @@ -0,0 +1,69 @@ +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) { + +}