working on adding lease handouts

This commit is contained in:
2023-05-06 05:21:27 +00:00
parent c475287fb1
commit a53d392ed8
15 changed files with 477 additions and 76 deletions

View File

@@ -5,6 +5,8 @@ go_library(
srcs = [
"ifi.go",
"ifi_linux.go",
"lease_state.go",
"pools.go",
"server.go",
],
importpath = "git.wntrmute.dev/kyle/kdhcp/server",
@@ -12,6 +14,8 @@ go_library(
deps = [
"//config",
"//dhcp",
"//iptools",
"@dev_wntrmute_git_kyle_goutils//syslog",
"@in_gopkg_yaml_v2//:yaml_v2",
],
)

62
server/lease_state.go Normal file
View File

@@ -0,0 +1,62 @@
package server
import (
"fmt"
"os"
log "git.wntrmute.dev/kyle/goutils/syslog"
"git.wntrmute.dev/kyle/kdhcp/iptools"
"gopkg.in/yaml.v2"
)
type LeaseState struct {
Pools map[string]*iptools.Pool `yaml:"pools"`
Static map[string]*iptools.LeaseInfo `yaml:"static"`
}
func (srv *Server) SaveLeases() error {
leaseFile, err := os.Create(srv.Config.LeaseFile)
if err != nil {
return fmt.Errorf("server: while saving leases: %w", err)
}
defer leaseFile.Close()
encoder := yaml.NewEncoder(leaseFile)
state := &LeaseState{
Pools: srv.Pools,
Static: srv.Static,
}
if err = encoder.Encode(state); err != nil {
return fmt.Errorf("server: while saving leases: %w", err)
}
if err = encoder.Close(); err != nil {
return fmt.Errorf("server: while saving leases: %w", err)
}
return nil
}
func (srv *Server) LoadLeases() error {
leaseState := &LeaseState{}
leaseFile, err := os.Open(srv.Config.LeaseFile)
if err != nil {
if os.IsNotExist(err) {
log.Warningf("server: not loading leases from %s: lease file not found", srv.Config.LeaseFile)
return nil
}
return fmt.Errorf("server: while reading leases: %w", err)
}
defer leaseFile.Close()
decoder := yaml.NewDecoder(leaseFile)
if err = decoder.Decode(leaseState); err != nil {
return fmt.Errorf("server: while reading leases: %w", err)
}
srv.Pools = leaseState.Pools
srv.Static = leaseState.Static
return nil
}

37
server/pools.go Normal file
View File

@@ -0,0 +1,37 @@
package server
import (
"fmt"
"net/netip"
log "git.wntrmute.dev/kyle/goutils/syslog"
"git.wntrmute.dev/kyle/kdhcp/iptools"
)
// pools.go adds pool functionality to the server.
func (srv *Server) loadPoolsFromConfig() error {
for host, ip := range srv.Config.Statics {
addr, ok := netip.AddrFromSlice(ip.To4())
if !ok {
return fmt.Errorf("server: while instantiating pools, could not load IP %s", ip)
}
log.Debugf("server: added static host entry %s -> %s", host, addr)
srv.Static[host] = &iptools.LeaseInfo{
HostName: host,
Addr: addr,
}
}
for name, ipRange := range srv.Config.Pools {
pool, err := iptools.NewPool(name, ipRange)
if err != nil {
return fmt.Errorf("server: couldn't load pool %s: %w", name, err)
}
log.Debugf("server: added pool %s: %s -> %s", name, ipRange.Start, ipRange.End)
srv.Pools[name] = pool
}
return nil
}

View File

@@ -3,19 +3,25 @@ package server
import (
"errors"
"net"
"time"
log "git.wntrmute.dev/kyle/goutils/syslog"
"git.wntrmute.dev/kyle/kdhcp/config"
"git.wntrmute.dev/kyle/kdhcp/dhcp"
"git.wntrmute.dev/kyle/kdhcp/iptools"
)
const (
MaxPacketSize = 512
DefaultPool = "default"
MaxPacketSize = 512
MaxResponseWait = 5 * time.Minute
)
type Server struct {
Conn net.PacketConn
Config *config.Config
Pools map[string]*iptools.Pool
Static map[string]*iptools.LeaseInfo
}
func (s *Server) Close() error {
@@ -24,6 +30,8 @@ func (s *Server) Close() error {
func (s *Server) Bind() (err error) {
// In order to read DHCP packets, we'll need to listen on all addresses.
// That being said, we also want to limit our listening to the DHCP
// network device.
ip := net.IP([]byte{0, 0, 0, 0})
s.Conn, err = BindInterface(ip, s.Config.Port, s.Config.Interface)
return err
@@ -46,7 +54,7 @@ func (s *Server) ReadDHCPRequest() (*dhcp.BootRequest, error) {
return nil, err
}
log.Debugf("server: read %db packet from %s", len(pkt), addr)
log.Debugf("server: read packet from %s", addr)
return dhcp.ReadRequest(pkt)
}
@@ -77,10 +85,19 @@ func (s *Server) Listen() {
func New(cfg *config.Config) (*Server, error) {
srv := &Server{
Config: cfg,
Pools: map[string]*iptools.Pool{},
Static: map[string]*iptools.LeaseInfo{},
}
err := srv.Bind()
if err != nil {
if err := srv.loadPoolsFromConfig(); err != nil {
return nil, err
}
if err := srv.LoadLeases(); err != nil {
return nil, err
}
if err := srv.Bind(); err != nil {
return nil, err
}
@@ -88,3 +105,19 @@ func New(cfg *config.Config) (*Server, error) {
return srv, nil
}
func (srv *Server) SelectLease(req *dhcp.BootRequest, t time.Time) *iptools.LeaseInfo {
if li, ok := srv.Static[req.HostName]; ok {
return li
}
if pool, ok := srv.Pools[req.HostName]; ok {
return pool.Peek(t, MaxResponseWait)
}
if pool, ok := srv.Pools[DefaultPool]; ok {
return pool.Peek(t, MaxResponseWait)
}
return nil
}