dnsd/dhcp4d: listen on configured address (not hard-coded)

This commit is contained in:
Michael Stapelberg 2018-06-04 08:02:28 +02:00
parent 763aa18a74
commit 2ef8bf6ea0
5 changed files with 78 additions and 10 deletions

View File

@ -22,7 +22,10 @@ func logic() error {
return err
}
errs := make(chan error)
handler := dhcp4d.NewHandler()
handler, err := dhcp4d.NewHandler("/perm")
if err != nil {
return err
}
handler.Leases = func(leases []*dhcp4d.Lease) {
b, err := json.Marshal(leases)
if err != nil {

View File

@ -12,12 +12,16 @@ import (
"router7/internal/dhcp4d"
"router7/internal/dns"
"router7/internal/netconfig"
)
func logic() error {
// TODO: serve on correct IP address
// TODO: set correct upstream DNS resolver(s)
srv := dns.NewServer("192.168.42.1:53", "lan")
ip, err := netconfig.LinkAddress("/perm", "lan0")
if err != nil {
return err
}
srv := dns.NewServer(ip.String()+":53", "lan")
readLeases := func() error {
b, err := ioutil.ReadFile("/perm/dhcp4d/leases.json")
if err != nil {
@ -31,7 +35,7 @@ func logic() error {
return nil
}
if err := readLeases(); err != nil {
log.Printf("readLeases: %v", err)
log.Printf("cannot resolve DHCP hostnames: %v", err)
}
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGUSR1)

View File

@ -7,6 +7,8 @@ import (
"net"
"time"
"router7/internal/netconfig"
"github.com/krolaw/dhcp4"
)
@ -31,14 +33,21 @@ type Handler struct {
}
// TODO: restore leases from permanent storage
func NewHandler() *Handler {
serverIP := net.IP{192, 168, 42, 1} // TODO: customizeable
func NewHandler(dir string) (*Handler, error) {
serverIP, err := netconfig.LinkAddress(dir, "lan0")
if err != nil {
return nil, err
}
serverIP = serverIP.To4()
start := make(net.IP, len(serverIP))
copy(start, serverIP)
start[len(start)-1] += 1
return &Handler{
leasesHW: make(map[string]*Lease),
leasesIP: make(map[int]*Lease),
serverIP: serverIP,
start: net.IP{192, 168, 42, 2},
leaseRange: 50,
start: start,
leaseRange: 200,
leasePeriod: 2 * time.Hour,
options: dhcp4.Options{
dhcp4.OptionSubnetMask: []byte{255, 255, 255, 0},
@ -47,7 +56,7 @@ func NewHandler() *Handler {
dhcp4.OptionDomainName: []byte("lan"),
dhcp4.OptionDomainSearch: []byte{0x03, 'l', 'a', 'n', 0x00},
},
}
}, nil
}
func (h *Handler) findLease() int {

View File

@ -2,19 +2,49 @@ package dhcp4d
import (
"bytes"
"io/ioutil"
"net"
"os"
"path/filepath"
"testing"
"github.com/krolaw/dhcp4"
)
const goldenInterfaces = `
{
"interfaces":[
{
"hardware_addr": "02:73:53:00:ca:fe",
"name": "uplink0"
},
{
"hardware_addr": "02:73:53:00:b0:0c",
"name": "lan0",
"addr": "192.168.42.1/24"
}
]
}
`
func TestLease(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "dhcp4dtest")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpdir)
if err := ioutil.WriteFile(filepath.Join(tmpdir, "interfaces.json"), []byte(goldenInterfaces), 0644); err != nil {
t.Fatal(err)
}
var (
addr = net.IP{192, 168, 42, 23}
hardwareAddr = net.HardwareAddr{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}
hostname = "xps"
)
handler := NewHandler()
handler, err := NewHandler(tmpdir)
if err != nil {
t.Fatal(err)
}
leasedCalled := false
handler.Leases = func(leases []*Lease) {
if got, want := len(leases), 1; got != want {

View File

@ -156,6 +156,28 @@ type InterfaceConfig struct {
Interfaces []InterfaceDetails `json:"interfaces"`
}
// LinkAddress returns the IP address configured for the interface ifname in
// interfaces.json.
func LinkAddress(dir, ifname string) (net.IP, error) {
fn := filepath.Join(dir, "interfaces.json")
b, err := ioutil.ReadFile(fn)
if err != nil {
return nil, err
}
var cfg InterfaceConfig
if err := json.Unmarshal(b, &cfg); err != nil {
return nil, err
}
for _, details := range cfg.Interfaces {
if details.Name != ifname {
continue
}
ip, _, err := net.ParseCIDR(details.Addr)
return ip, err
}
return nil, fmt.Errorf("%s does not configure interface %q", fn, ifname)
}
func applyInterfaces(dir, root string) error {
b, err := ioutil.ReadFile(filepath.Join(dir, "interfaces.json"))
if err != nil {