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
|
return err
|
||||||
}
|
}
|
||||||
errs := make(chan error)
|
errs := make(chan error)
|
||||||
handler := dhcp4d.NewHandler()
|
handler, err := dhcp4d.NewHandler("/perm")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
handler.Leases = func(leases []*dhcp4d.Lease) {
|
handler.Leases = func(leases []*dhcp4d.Lease) {
|
||||||
b, err := json.Marshal(leases)
|
b, err := json.Marshal(leases)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -12,12 +12,16 @@ import (
|
|||||||
|
|
||||||
"router7/internal/dhcp4d"
|
"router7/internal/dhcp4d"
|
||||||
"router7/internal/dns"
|
"router7/internal/dns"
|
||||||
|
"router7/internal/netconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
func logic() error {
|
func logic() error {
|
||||||
// TODO: serve on correct IP address
|
|
||||||
// TODO: set correct upstream DNS resolver(s)
|
// 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 {
|
readLeases := func() error {
|
||||||
b, err := ioutil.ReadFile("/perm/dhcp4d/leases.json")
|
b, err := ioutil.ReadFile("/perm/dhcp4d/leases.json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -31,7 +35,7 @@ func logic() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if err := readLeases(); err != 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)
|
ch := make(chan os.Signal, 1)
|
||||||
signal.Notify(ch, syscall.SIGUSR1)
|
signal.Notify(ch, syscall.SIGUSR1)
|
||||||
|
@ -7,6 +7,8 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"router7/internal/netconfig"
|
||||||
|
|
||||||
"github.com/krolaw/dhcp4"
|
"github.com/krolaw/dhcp4"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,14 +33,21 @@ type Handler struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: restore leases from permanent storage
|
// TODO: restore leases from permanent storage
|
||||||
func NewHandler() *Handler {
|
func NewHandler(dir string) (*Handler, error) {
|
||||||
serverIP := net.IP{192, 168, 42, 1} // TODO: customizeable
|
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{
|
return &Handler{
|
||||||
leasesHW: make(map[string]*Lease),
|
leasesHW: make(map[string]*Lease),
|
||||||
leasesIP: make(map[int]*Lease),
|
leasesIP: make(map[int]*Lease),
|
||||||
serverIP: serverIP,
|
serverIP: serverIP,
|
||||||
start: net.IP{192, 168, 42, 2},
|
start: start,
|
||||||
leaseRange: 50,
|
leaseRange: 200,
|
||||||
leasePeriod: 2 * time.Hour,
|
leasePeriod: 2 * time.Hour,
|
||||||
options: dhcp4.Options{
|
options: dhcp4.Options{
|
||||||
dhcp4.OptionSubnetMask: []byte{255, 255, 255, 0},
|
dhcp4.OptionSubnetMask: []byte{255, 255, 255, 0},
|
||||||
@ -47,7 +56,7 @@ func NewHandler() *Handler {
|
|||||||
dhcp4.OptionDomainName: []byte("lan"),
|
dhcp4.OptionDomainName: []byte("lan"),
|
||||||
dhcp4.OptionDomainSearch: []byte{0x03, 'l', 'a', 'n', 0x00},
|
dhcp4.OptionDomainSearch: []byte{0x03, 'l', 'a', 'n', 0x00},
|
||||||
},
|
},
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) findLease() int {
|
func (h *Handler) findLease() int {
|
||||||
|
@ -2,19 +2,49 @@ package dhcp4d
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/krolaw/dhcp4"
|
"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) {
|
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 (
|
var (
|
||||||
addr = net.IP{192, 168, 42, 23}
|
addr = net.IP{192, 168, 42, 23}
|
||||||
hardwareAddr = net.HardwareAddr{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}
|
hardwareAddr = net.HardwareAddr{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}
|
||||||
hostname = "xps"
|
hostname = "xps"
|
||||||
)
|
)
|
||||||
handler := NewHandler()
|
handler, err := NewHandler(tmpdir)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
leasedCalled := false
|
leasedCalled := false
|
||||||
handler.Leases = func(leases []*Lease) {
|
handler.Leases = func(leases []*Lease) {
|
||||||
if got, want := len(leases), 1; got != want {
|
if got, want := len(leases), 1; got != want {
|
||||||
|
@ -156,6 +156,28 @@ type InterfaceConfig struct {
|
|||||||
Interfaces []InterfaceDetails `json:"interfaces"`
|
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 {
|
func applyInterfaces(dir, root string) error {
|
||||||
b, err := ioutil.ReadFile(filepath.Join(dir, "interfaces.json"))
|
b, err := ioutil.ReadFile(filepath.Join(dir, "interfaces.json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user