package leases import ( "errors" "fmt" "time" "github.com/adrianokf/go-dhcp/pkg/types" "go.uber.org/zap" ) type LeaseState uint8 const ( Offered LeaseState = iota Requested ) type Lease struct { TransactionId types.TxId TTL time.Time State LeaseState ClientAddr types.HwAddr Address types.Ipv4Addr } type ILeaseManager interface { Request(xid types.TxId, clientAddr types.HwAddr) (*Lease, error) Release(l Lease) error Lookup(xid types.TxId) error } type LeaseManager struct { leases map[types.TxId]Lease count byte } func NewLeaseManager() *LeaseManager { m := &LeaseManager{ leases: make(map[types.TxId]Lease), } return m } func (m *LeaseManager) Request(xid types.TxId, clientAddr types.HwAddr) (*Lease, error) { zap.S().Debugf("LeaseManager.Request(%v, %v)", xid, clientAddr) if m.count > 254 { return nil, errors.New("lease address pool exhausted") } assigned := [4]byte{10, 0, 0, m.count + 2} lease := Lease{ TransactionId: xid, TTL: time.Now().Add(1 * time.Hour), State: Requested, ClientAddr: clientAddr, Address: assigned, } m.leases[xid] = lease m.count += 1 zap.S().Debug("lease=", lease) return &lease, nil } func (m LeaseManager) Release(l Lease) error { _, found := m.leases[l.TransactionId] if !found { return fmt.Errorf("invalid lease %v", l) } delete(m.leases, l.TransactionId) return nil } func (m LeaseManager) Lookup(xid types.TxId) (*Lease, error) { lease, found := m.leases[xid] if found { return &lease, nil } return nil, fmt.Errorf("no lease found for xid %v", xid) }