dnsd/dhcp4d: listen on configured address (not hard-coded)
This commit is contained in:
parent
763aa18a74
commit
2ef8bf6ea0
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user