dhcp reads done, moving on to offers
This commit is contained in:
parent
6ba2bf3911
commit
f66fbc0f6c
|
@ -9,7 +9,7 @@ go_library(
|
|||
"//config",
|
||||
"//server",
|
||||
"@com_github_peterbourgon_ff_v3//ffcli",
|
||||
"@dev_wntrmute_git_kyle_goutils//syslog",
|
||||
"@dev_wntrmute_git_kyle_goutils//log",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
log "git.wntrmute.dev/kyle/goutils/syslog"
|
||||
"git.wntrmute.dev/kyle/goutils/log"
|
||||
"git.wntrmute.dev/kyle/kdhcp/config"
|
||||
"git.wntrmute.dev/kyle/kdhcp/server"
|
||||
"github.com/peterbourgon/ff/v3/ffcli"
|
||||
|
|
|
@ -10,7 +10,7 @@ go_library(
|
|||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//iptools",
|
||||
"@dev_wntrmute_git_kyle_goutils//syslog",
|
||||
"@dev_wntrmute_git_kyle_goutils//log",
|
||||
"@in_gopkg_yaml_v2//:yaml_v2",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"io/ioutil"
|
||||
"net"
|
||||
|
||||
log "git.wntrmute.dev/kyle/goutils/syslog"
|
||||
log "git.wntrmute.dev/kyle/goutils/log"
|
||||
"git.wntrmute.dev/kyle/kdhcp/iptools"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"os/user"
|
||||
"path/filepath"
|
||||
|
||||
log "git.wntrmute.dev/kyle/goutils/syslog"
|
||||
log "git.wntrmute.dev/kyle/goutils/log"
|
||||
)
|
||||
|
||||
func FindConfigPath() string {
|
||||
|
|
49
deps.bzl
49
deps.bzl
|
@ -1,6 +1,13 @@
|
|||
load("@bazel_gazelle//:deps.bzl", "go_repository")
|
||||
|
||||
def go_dependencies():
|
||||
go_repository(
|
||||
name = "com_github_benbjohnson_clock",
|
||||
importpath = "github.com/benbjohnson/clock",
|
||||
sum = "h1:g+rSsSaAzhHJYcIQE78hJ3AhyjjtQvleKDjlhdBnIhc=",
|
||||
version = "v1.3.3",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_cloudflare_cfssl",
|
||||
importpath = "github.com/cloudflare/cfssl",
|
||||
|
@ -14,12 +21,32 @@ def go_dependencies():
|
|||
sum = "h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=",
|
||||
version = "v1.1.1",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_google_certificate_transparency_go",
|
||||
importpath = "github.com/google/certificate-transparency-go",
|
||||
sum = "h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE=",
|
||||
version = "v1.0.21",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_hashicorp_go_syslog",
|
||||
importpath = "github.com/hashicorp/go-syslog",
|
||||
sum = "h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE=",
|
||||
version = "v1.0.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_kr_fs",
|
||||
importpath = "github.com/kr/fs",
|
||||
sum = "h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=",
|
||||
version = "v0.1.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_kr_pretty",
|
||||
importpath = "github.com/kr/pretty",
|
||||
sum = "h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=",
|
||||
version = "v0.1.0",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_kr_text",
|
||||
importpath = "github.com/kr/text",
|
||||
|
@ -51,6 +78,13 @@ def go_dependencies():
|
|||
sum = "h1:/f3b24xrDhkhddlaobPe2JgBqfdt+gC/NYl0QY9IOuI=",
|
||||
version = "v1.12.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_pmezard_go_difflib",
|
||||
importpath = "github.com/pmezard/go-difflib",
|
||||
sum = "h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=",
|
||||
version = "v1.0.0",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_stretchr_testify",
|
||||
importpath = "github.com/stretchr/testify",
|
||||
|
@ -60,15 +94,15 @@ def go_dependencies():
|
|||
go_repository(
|
||||
name = "dev_wntrmute_git_kyle_goutils",
|
||||
importpath = "git.wntrmute.dev/kyle/goutils",
|
||||
sum = "h1:CRCBlmSXOTkShbqC6j9lgxh4lb+khzc2zpIJYGQJtnc=",
|
||||
version = "v1.6.6",
|
||||
sum = "h1:+lk6uUMcpJK49sEGEMCOns3WVd2ThH/htMWnsyXEGl8=",
|
||||
version = "v1.7.0",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "in_gopkg_check_v1",
|
||||
importpath = "gopkg.in/check.v1",
|
||||
sum = "h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=",
|
||||
version = "v0.0.0-20161208181325-20d25e280405",
|
||||
sum = "h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=",
|
||||
version = "v1.0.0-20180628173108-788fd7840127",
|
||||
)
|
||||
go_repository(
|
||||
name = "in_gopkg_yaml_v2",
|
||||
|
@ -76,6 +110,13 @@ def go_dependencies():
|
|||
sum = "h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=",
|
||||
version = "v2.4.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "in_gopkg_yaml_v3",
|
||||
importpath = "gopkg.in/yaml.v3",
|
||||
sum = "h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=",
|
||||
version = "v3.0.0-20200313102051-9f266ea9e77c",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "org_golang_x_crypto",
|
||||
importpath = "golang.org/x/crypto",
|
||||
|
|
|
@ -9,5 +9,5 @@ go_library(
|
|||
],
|
||||
importpath = "git.wntrmute.dev/kyle/kdhcp/dhcp",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["@dev_wntrmute_git_kyle_goutils//syslog"],
|
||||
deps = ["@dev_wntrmute_git_kyle_goutils//log"],
|
||||
)
|
||||
|
|
|
@ -33,6 +33,8 @@ const (
|
|||
OptionTagNBScope OptionTag = 47
|
||||
OptionTagMessageType OptionTag = 53
|
||||
OptionTagParameterRequestList OptionTag = 55
|
||||
OptionTagDHCPMaxMessageSize OptionTag = 57
|
||||
OptionTagClientID OptionTag = 61
|
||||
OptionTagDomainSearch OptionTag = 119
|
||||
OptionTagClasslessStaticRoute OptionTag = 121
|
||||
OptionTagEnd OptionTag = 255
|
||||
|
@ -53,6 +55,8 @@ var optionStrings = map[OptionTag]string{
|
|||
OptionTagNBScope: "NetBIOS scope",
|
||||
OptionTagMessageType: "message type",
|
||||
OptionTagParameterRequestList: "parameter request list",
|
||||
OptionTagDHCPMaxMessageSize: "DHCP max message size",
|
||||
OptionTagClientID: "client ID",
|
||||
OptionTagDomainSearch: "search domain",
|
||||
OptionTagClasslessStaticRoute: "classless static route",
|
||||
OptionTagEnd: "end",
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"net"
|
||||
"strings"
|
||||
|
||||
log "git.wntrmute.dev/kyle/goutils/syslog"
|
||||
log "git.wntrmute.dev/kyle/goutils/log"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -46,6 +46,7 @@ type BootRequest struct {
|
|||
|
||||
DHCPType DHCPMessageType // option 53
|
||||
HostName string // option 12
|
||||
ClientID string // option 61
|
||||
ParameterRequests []OptionTag
|
||||
endOptions bool
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
|
||||
log "git.wntrmute.dev/kyle/goutils/syslog"
|
||||
log "git.wntrmute.dev/kyle/goutils/log"
|
||||
)
|
||||
|
||||
var optionRegistry = map[OptionTag]Option{
|
||||
|
@ -14,6 +14,7 @@ var optionRegistry = map[OptionTag]Option{
|
|||
OptionTagHostName: OptionHostName,
|
||||
OptionTagMessageType: OptionMessageType,
|
||||
OptionTagParameterRequestList: OptionParameterRequestList,
|
||||
OptionTagClientID: OptionClientID,
|
||||
OptionTagEnd: OptionEnd,
|
||||
}
|
||||
|
||||
|
@ -22,6 +23,19 @@ func OptionPad(req *BootRequest, r io.Reader) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getOptionLength(r io.Reader) (int, error) {
|
||||
var length uint8
|
||||
read := newPacketReaderFunc(r)
|
||||
|
||||
if err := read(&length); err != nil {
|
||||
return -1, fmt.Errorf("dhcp: reading option length for DHCP Message Type")
|
||||
} else if length == 0 {
|
||||
return -1, errors.New("dhcp: read option length 0, but expected option length for DHCP Host Name is >= 1")
|
||||
}
|
||||
|
||||
return int(length), nil
|
||||
}
|
||||
|
||||
// OptionHostName reads a DHCP host name option.
|
||||
//
|
||||
// 3.14. Host Name Option
|
||||
|
@ -33,13 +47,9 @@ func OptionPad(req *BootRequest, r io.Reader) error {
|
|||
|
||||
// The code for this option is 12, and its minimum length is 1.
|
||||
func OptionHostName(req *BootRequest, r io.Reader) error {
|
||||
read := newPacketReaderFunc(r)
|
||||
|
||||
var length uint8
|
||||
if err := read(&length); err != nil {
|
||||
return fmt.Errorf("dhcp: reading option length for DHCP Message Type")
|
||||
} else if length == 0 {
|
||||
return errors.New("dhcp: read option length 0, but expected option length for DHCP Host Name is >= 1")
|
||||
length, err := getOptionLength(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hostName := make([]byte, int(length))
|
||||
|
@ -56,9 +66,8 @@ func OptionHostName(req *BootRequest, r io.Reader) error {
|
|||
func OptionMessageType(req *BootRequest, r io.Reader) error {
|
||||
read := newPacketReaderFunc(r)
|
||||
|
||||
var length uint8
|
||||
if err := read(&length); err != nil {
|
||||
return fmt.Errorf("dhcp: reading option length for DHCP Message Type")
|
||||
if length, err := getOptionLength(r); err != nil {
|
||||
return err
|
||||
} else if length != 1 {
|
||||
return fmt.Errorf("dhcp: read option length %d, but expected option length for DHCP Message Type is 1", length)
|
||||
}
|
||||
|
@ -71,11 +80,9 @@ func OptionMessageType(req *BootRequest, r io.Reader) error {
|
|||
}
|
||||
|
||||
func OptionParameterRequestList(req *BootRequest, r io.Reader) error {
|
||||
read := newPacketReaderFunc(r)
|
||||
|
||||
var length uint8
|
||||
if err := read(&length); err != nil {
|
||||
return fmt.Errorf("dhcp: reading option length for DHCP Message Type")
|
||||
length, err := getOptionLength(r)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if length == 0 {
|
||||
return fmt.Errorf("dhcp: read option length %d, but expected option length for DHCP Parameter Request is >= 1", length)
|
||||
}
|
||||
|
@ -96,6 +103,25 @@ func OptionParameterRequestList(req *BootRequest, r io.Reader) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func OptionClientID(req *BootRequest, r io.Reader) error {
|
||||
length, err := getOptionLength(r)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if length == 0 {
|
||||
return fmt.Errorf("dhcp: read option length %d, but expected option length for DHCP Parameter Request is >= 1", length)
|
||||
}
|
||||
|
||||
var clientID = make([]byte, int(length))
|
||||
if n, err := r.Read(clientID); err != nil {
|
||||
return fmt.Errorf("dhcp: while reading client ID: %w", err)
|
||||
} else if n != int(length) {
|
||||
return fmt.Errorf("dhcp: only read %d bytes of client ID, expected %d bytes", n, length)
|
||||
}
|
||||
|
||||
req.ClientID = string(clientID)
|
||||
return nil
|
||||
}
|
||||
|
||||
func OptionEnd(req *BootRequest, r io.Reader) error {
|
||||
req.endOptions = true
|
||||
return nil
|
||||
|
@ -108,7 +134,27 @@ func ReadOption(req *BootRequest, tag byte, r io.Reader) error {
|
|||
return f(req, r)
|
||||
}
|
||||
|
||||
return fmt.Errorf("dhcp: unknown/unhandled option %d", opt)
|
||||
return readUnknownOption(req, tag, r)
|
||||
}
|
||||
|
||||
func readUnknownOption(req *BootRequest, tag byte, r io.Reader) error {
|
||||
length, err := getOptionLength(r)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if length == 0 {
|
||||
log.Debugf("skipped option %d/%02x with length 0", tag, tag)
|
||||
return nil
|
||||
}
|
||||
|
||||
var data = make([]byte, length)
|
||||
if n, err := r.Read(data); err != nil {
|
||||
return fmt.Errorf("dhcp: while skipping unknown tag %d/%02x: %w", tag, tag, err)
|
||||
} else if n != int(length) {
|
||||
return fmt.Errorf("dhcp: only read %d bytes of unknown tag %d/%02x, expected %d bytes", n, tag, tag, length)
|
||||
}
|
||||
|
||||
log.Infof("skipped unknown tag %d/%02x with data %0x", tag, tag, data)
|
||||
return nil
|
||||
}
|
||||
|
||||
const magicCookieLength = 4
|
||||
|
|
10
go.mod
10
go.mod
|
@ -2,12 +2,16 @@ module git.wntrmute.dev/kyle/kdhcp
|
|||
|
||||
go 1.20
|
||||
|
||||
require github.com/hashicorp/go-syslog v1.0.0
|
||||
require github.com/hashicorp/go-syslog v1.0.0 // indirect
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/peterbourgon/ff/v3 v3.3.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
require git.wntrmute.dev/kyle/goutils v1.6.6 // indirect
|
||||
require github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
|
||||
require (
|
||||
git.wntrmute.dev/kyle/goutils v1.7.0
|
||||
github.com/benbjohnson/clock v1.3.3
|
||||
)
|
||||
|
|
10
go.sum
10
go.sum
|
@ -1,12 +1,16 @@
|
|||
git.wntrmute.dev/kyle/goutils v1.6.6 h1:CRCBlmSXOTkShbqC6j9lgxh4lb+khzc2zpIJYGQJtnc=
|
||||
git.wntrmute.dev/kyle/goutils v1.6.6/go.mod h1:p0m2YprqMXkqtxTPKCiRcmgYo/D/9DtAIRfNVFE3JBg=
|
||||
git.wntrmute.dev/kyle/goutils v1.7.0 h1:+lk6uUMcpJK49sEGEMCOns3WVd2ThH/htMWnsyXEGl8=
|
||||
git.wntrmute.dev/kyle/goutils v1.7.0/go.mod h1:hMcPr+XSYXjQ/IRTziNVYmUmb9BPATZc+cyehSjBs0w=
|
||||
github.com/benbjohnson/clock v1.3.3 h1:g+rSsSaAzhHJYcIQE78hJ3AhyjjtQvleKDjlhdBnIhc=
|
||||
github.com/benbjohnson/clock v1.3.3/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/peterbourgon/ff/v3 v3.3.0 h1:PaKe7GW8orVFh8Unb5jNHS+JZBwWUMa2se0HM6/BI24=
|
||||
github.com/peterbourgon/ff/v3 v3.3.0/go.mod h1:zjJVUhx+twciwfDl0zBcFzl4dW8axCRyXE/eKY9RztQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
|
|
|
@ -11,7 +11,10 @@ go_library(
|
|||
],
|
||||
importpath = "git.wntrmute.dev/kyle/kdhcp/iptools",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["@dev_wntrmute_git_kyle_goutils//assert"],
|
||||
deps = [
|
||||
"@dev_wntrmute_git_kyle_goutils//assert",
|
||||
"@dev_wntrmute_git_kyle_goutils//log",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
|
|
|
@ -15,6 +15,10 @@ type LeaseInfo struct {
|
|||
Expires time.Time `yaml:"expires"`
|
||||
}
|
||||
|
||||
func (li *LeaseInfo) String() string {
|
||||
return fmt.Sprintf("lease[hostname=%s addr=%s hw=%x expires=%s]", li.HostName, li.Addr, li.HardwareAddress, li.Expires)
|
||||
}
|
||||
|
||||
type sortableLease []*LeaseInfo
|
||||
|
||||
func (a sortableLease) Len() int { return len(a) }
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"time"
|
||||
|
||||
"git.wntrmute.dev/kyle/goutils/assert"
|
||||
"git.wntrmute.dev/kyle/goutils/log"
|
||||
)
|
||||
|
||||
const DefaultExpiry = 168 * time.Hour
|
||||
|
@ -23,7 +24,7 @@ type Pool struct {
|
|||
}
|
||||
|
||||
func (p *Pool) lock() {
|
||||
if p.lock == nil {
|
||||
if p.mtx == nil {
|
||||
p.mtx = &sync.Mutex{}
|
||||
}
|
||||
|
||||
|
@ -48,6 +49,7 @@ func NewPool(name string, r *Range) (*Pool, error) {
|
|||
Expiry: r.Expiry,
|
||||
NoHostName: r.NoHostName,
|
||||
Available: enumerateRange(name, r, true),
|
||||
Limbo: map[netip.Addr]*LeaseInfo{},
|
||||
}
|
||||
|
||||
return p, nil
|
||||
|
@ -114,39 +116,40 @@ func (p *Pool) Accept(addr netip.Addr, t time.Time) error {
|
|||
|
||||
// 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) {
|
||||
func (p *Pool) Update(t time.Time) bool {
|
||||
p.lock()
|
||||
defer p.unlock()
|
||||
|
||||
p.update(t)
|
||||
return p.update(t)
|
||||
}
|
||||
|
||||
func (p *Pool) update(t time.Time) {
|
||||
evictedHosts := []netip.Addr{}
|
||||
func (p *Pool) update(t time.Time) bool {
|
||||
var updated bool
|
||||
|
||||
for k, v := range p.Active {
|
||||
if v.IsExpired(t) {
|
||||
evictedHosts = append(evictedHosts, k)
|
||||
updated = true
|
||||
log.Infof("expiring active address %s for %x", v.Addr, v.HardwareAddress)
|
||||
delete(p.Active, k)
|
||||
v = v.Reset()
|
||||
p.Available = append(p.Available, v)
|
||||
}
|
||||
}
|
||||
|
||||
for _, ip := range evictedHosts {
|
||||
delete(p.Active, ip)
|
||||
}
|
||||
|
||||
for k, v := range p.Limbo {
|
||||
if v.IsExpired(t) {
|
||||
updated = true
|
||||
log.Infof("expiring limbo address %s for %x", v.Addr, v.HardwareAddress)
|
||||
delete(p.Limbo, k)
|
||||
v = v.Reset()
|
||||
p.Available = append(p.Available, v)
|
||||
}
|
||||
}
|
||||
|
||||
p.Sort()
|
||||
p.sort()
|
||||
return updated
|
||||
}
|
||||
|
||||
func (p *Pool) Renew(lease LeaseInfo, t time.Time) {
|
||||
|
||||
func (p *Pool) Renew(lease *LeaseInfo, t time.Time) {
|
||||
p.Active[lease.Addr].ResetExpiry(t, p.Expiry)
|
||||
}
|
||||
|
|
|
@ -15,7 +15,8 @@ go_library(
|
|||
"//config",
|
||||
"//dhcp",
|
||||
"//iptools",
|
||||
"@dev_wntrmute_git_kyle_goutils//syslog",
|
||||
"@com_github_benbjohnson_clock//:clock",
|
||||
"@dev_wntrmute_git_kyle_goutils//log",
|
||||
"@in_gopkg_yaml_v2//:yaml_v2",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
log "git.wntrmute.dev/kyle/goutils/syslog"
|
||||
log "git.wntrmute.dev/kyle/goutils/log"
|
||||
"git.wntrmute.dev/kyle/kdhcp/iptools"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
|
|
@ -3,8 +3,9 @@ package server
|
|||
import (
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"time"
|
||||
|
||||
log "git.wntrmute.dev/kyle/goutils/syslog"
|
||||
log "git.wntrmute.dev/kyle/goutils/log"
|
||||
"git.wntrmute.dev/kyle/kdhcp/iptools"
|
||||
)
|
||||
|
||||
|
@ -35,3 +36,14 @@ func (srv *Server) loadPoolsFromConfig() error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (srv *Server) updatePoolLoop() {
|
||||
for {
|
||||
time.Sleep(time.Minute)
|
||||
for _, p := range srv.Pools {
|
||||
if p.Update(srv.clock.Now()) {
|
||||
log.Debugln("pools updated")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,11 @@ import (
|
|||
"net"
|
||||
"time"
|
||||
|
||||
log "git.wntrmute.dev/kyle/goutils/syslog"
|
||||
log "git.wntrmute.dev/kyle/goutils/log"
|
||||
"git.wntrmute.dev/kyle/kdhcp/config"
|
||||
"git.wntrmute.dev/kyle/kdhcp/dhcp"
|
||||
"git.wntrmute.dev/kyle/kdhcp/iptools"
|
||||
"github.com/benbjohnson/clock"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -22,6 +23,8 @@ type Server struct {
|
|||
Config *config.Config
|
||||
Pools map[string]*iptools.Pool
|
||||
Static map[string]*iptools.LeaseInfo
|
||||
|
||||
clock clock.Clock
|
||||
}
|
||||
|
||||
func (s *Server) Close() error {
|
||||
|
@ -62,23 +65,34 @@ func (s *Server) WriteTo(b []byte, addr net.Addr) error {
|
|||
return errors.New("server: not implemented")
|
||||
}
|
||||
|
||||
func (s *Server) AcceptPacket() error {
|
||||
func (s *Server) AcceptPacket() (*dhcp.BootRequest, error) {
|
||||
request, err := s.ReadDHCPRequest()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debugf("BOOTP request received from %x", request.HardwareAddress)
|
||||
return nil
|
||||
return request, nil
|
||||
}
|
||||
|
||||
func (s *Server) Listen() {
|
||||
go s.updatePoolLoop()
|
||||
|
||||
for {
|
||||
if err := s.AcceptPacket(); err != nil {
|
||||
req, err := s.AcceptPacket()
|
||||
if err != nil {
|
||||
log.Errf("server: error reading packet: %s", err)
|
||||
continue
|
||||
}
|
||||
break
|
||||
|
||||
lease := s.SelectLease(req, s.clock.Now())
|
||||
if err != nil {
|
||||
log.Err("server: couldn't find available lease")
|
||||
continue
|
||||
}
|
||||
|
||||
log.Infof("available lease: %s", lease)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,6 +101,7 @@ func New(cfg *config.Config) (*Server, error) {
|
|||
Config: cfg,
|
||||
Pools: map[string]*iptools.Pool{},
|
||||
Static: map[string]*iptools.LeaseInfo{},
|
||||
clock: clock.New(),
|
||||
}
|
||||
|
||||
if err := srv.loadPoolsFromConfig(); err != nil {
|
||||
|
|
Loading…
Reference in New Issue