mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
Add hosts file as source for hostname resolver
This commit is contained in:
committed by
Cuong Manh Le
parent
e355fd70ab
commit
82e44b01af
@@ -178,6 +178,7 @@ type ServiceConfig struct {
|
|||||||
DiscoverARP *bool `mapstructure:"discover_arp" toml:"discover_dhcp,omitempty"`
|
DiscoverARP *bool `mapstructure:"discover_arp" toml:"discover_dhcp,omitempty"`
|
||||||
DiscoverDHCP *bool `mapstructure:"discover_dhcp" toml:"discover_dhcp,omitempty"`
|
DiscoverDHCP *bool `mapstructure:"discover_dhcp" toml:"discover_dhcp,omitempty"`
|
||||||
DiscoverPtr *bool `mapstructure:"discover_ptr" toml:"discover_ptr,omitempty"`
|
DiscoverPtr *bool `mapstructure:"discover_ptr" toml:"discover_ptr,omitempty"`
|
||||||
|
DiscoverHosts *bool `mapstructure:"discover_hosts" toml:"discover_hosts,omitempty"`
|
||||||
Daemon bool `mapstructure:"-" toml:"-"`
|
Daemon bool `mapstructure:"-" toml:"-"`
|
||||||
AllocateIP bool `mapstructure:"-" toml:"-"`
|
AllocateIP bool `mapstructure:"-" toml:"-"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -193,6 +193,13 @@ Perform LAN client discovery using PTR queries.
|
|||||||
- Required: no
|
- Required: no
|
||||||
- Default: true
|
- Default: true
|
||||||
|
|
||||||
|
### discover_hosts
|
||||||
|
Perform LAN client discovery using hosts file.
|
||||||
|
|
||||||
|
- Type: boolean
|
||||||
|
- Required: no
|
||||||
|
- Default: true
|
||||||
|
|
||||||
### dhcp_lease_file_path
|
### dhcp_lease_file_path
|
||||||
Relative or absolute path to a custom DHCP leases file location.
|
Relative or absolute path to a custom DHCP leases file location.
|
||||||
|
|
||||||
|
|||||||
1
go.mod
1
go.mod
@@ -23,6 +23,7 @@ require (
|
|||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/spf13/viper v1.16.0
|
github.com/spf13/viper v1.16.0
|
||||||
github.com/stretchr/testify v1.8.3
|
github.com/stretchr/testify v1.8.3
|
||||||
|
github.com/txn2/txeh v1.5.3
|
||||||
github.com/vishvananda/netlink v1.2.1-beta.2
|
github.com/vishvananda/netlink v1.2.1-beta.2
|
||||||
go4.org/mem v0.0.0-20220726221520-4f986261bf13
|
go4.org/mem v0.0.0-20220726221520-4f986261bf13
|
||||||
golang.org/x/net v0.10.0
|
golang.org/x/net v0.10.0
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -270,6 +270,8 @@ github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gt
|
|||||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
|
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
|
||||||
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||||
|
github.com/txn2/txeh v1.5.3 h1:ZMgc3r+5/AFtE/ayCoICpvxj7xl/CYsZjnIGhozV/Kc=
|
||||||
|
github.com/txn2/txeh v1.5.3/go.mod h1:qYzGG9kCzeVEI12geK4IlanHWY8X4uy/I3NcW7mk8g4=
|
||||||
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 h1:YcojQL98T/OO+rybuzn2+5KrD5dBwXIvYBvQ2cD3Avg=
|
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 h1:YcojQL98T/OO+rybuzn2+5KrD5dBwXIvYBvQ2cD3Avg=
|
||||||
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
|
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
|
||||||
github.com/vishvananda/netlink v1.2.1-beta.2 h1:Llsql0lnQEbHj0I1OuKyp8otXp0r3q0mPkuhwHfStVs=
|
github.com/vishvananda/netlink v1.2.1-beta.2 h1:Llsql0lnQEbHj0I1OuKyp8otXp0r3q0mPkuhwHfStVs=
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ type Table struct {
|
|||||||
arp *arpDiscover
|
arp *arpDiscover
|
||||||
ptr *ptrDiscover
|
ptr *ptrDiscover
|
||||||
mdns *mdns
|
mdns *mdns
|
||||||
|
hf *hostsFile
|
||||||
cfg *ctrld.Config
|
cfg *ctrld.Config
|
||||||
quitCh chan struct{}
|
quitCh chan struct{}
|
||||||
selfIP string
|
selfIP string
|
||||||
@@ -134,6 +135,17 @@ func (t *Table) init() {
|
|||||||
t.refreshers = append(t.refreshers, t.merlin)
|
t.refreshers = append(t.refreshers, t.merlin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if t.discoverHosts() {
|
||||||
|
t.hf = &hostsFile{}
|
||||||
|
ctrld.ProxyLogger.Load().Debug().Msg("start hosts file discovery")
|
||||||
|
if err := t.hf.init(); err != nil {
|
||||||
|
ctrld.ProxyLogger.Load().Error().Err(err).Msg("could not init hosts file discover")
|
||||||
|
} else {
|
||||||
|
t.hostnameResolvers = append(t.hostnameResolvers, t.hf)
|
||||||
|
t.refreshers = append(t.refreshers, t.hf)
|
||||||
|
}
|
||||||
|
go t.hf.watchChanges()
|
||||||
|
}
|
||||||
if t.discoverDHCP() {
|
if t.discoverDHCP() {
|
||||||
t.dhcp = &dhcp{selfIP: t.selfIP}
|
t.dhcp = &dhcp{selfIP: t.selfIP}
|
||||||
ctrld.ProxyLogger.Load().Debug().Msg("start dhcp discovery")
|
ctrld.ProxyLogger.Load().Debug().Msg("start dhcp discovery")
|
||||||
@@ -328,6 +340,13 @@ func (t *Table) discoverPTR() bool {
|
|||||||
return *t.cfg.Service.DiscoverPtr
|
return *t.cfg.Service.DiscoverPtr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Table) discoverHosts() bool {
|
||||||
|
if t.cfg.Service.DiscoverHosts == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return *t.cfg.Service.DiscoverHosts
|
||||||
|
}
|
||||||
|
|
||||||
// normalizeIP normalizes the ip parsed from dnsmasq/dhcpd lease file.
|
// normalizeIP normalizes the ip parsed from dnsmasq/dhcpd lease file.
|
||||||
func normalizeIP(in string) string {
|
func normalizeIP(in string) string {
|
||||||
// dnsmasq may put ip with interface index in lease file, strip it here.
|
// dnsmasq may put ip with interface index in lease file, strip it here.
|
||||||
|
|||||||
86
internal/clientinfo/hostsfile.go
Normal file
86
internal/clientinfo/hostsfile.go
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
package clientinfo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/fsnotify/fsnotify"
|
||||||
|
"github.com/txn2/txeh"
|
||||||
|
|
||||||
|
"github.com/Control-D-Inc/ctrld"
|
||||||
|
)
|
||||||
|
|
||||||
|
// hostsFile provides client discovery functionality using system hosts file.
|
||||||
|
type hostsFile struct {
|
||||||
|
h *txeh.Hosts
|
||||||
|
watcher *fsnotify.Watcher
|
||||||
|
}
|
||||||
|
|
||||||
|
// init performs initialization works, which is necessary before hostsFile can be fully operated.
|
||||||
|
func (hf *hostsFile) init() error {
|
||||||
|
h, err := txeh.NewHostsDefault()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
hf.h = h
|
||||||
|
watcher, err := fsnotify.NewWatcher()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
hf.watcher = watcher
|
||||||
|
if err := hf.watcher.Add(hf.h.ReadFilePath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// refresh reloads hosts file entries.
|
||||||
|
func (hf *hostsFile) refresh() error {
|
||||||
|
return hf.h.Reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
// watchChanges watches and updates hosts file data if any changes happens.
|
||||||
|
func (hf *hostsFile) watchChanges() {
|
||||||
|
if hf.watcher == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case event, ok := <-hf.watcher.Events:
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if event.Has(fsnotify.Write) || event.Has(fsnotify.Rename) || event.Has(fsnotify.Chmod) || event.Has(fsnotify.Remove) {
|
||||||
|
if err := hf.refresh(); err != nil && !os.IsNotExist(err) {
|
||||||
|
ctrld.ProxyLogger.Load().Err(err).Msg("hosts file changed but failed to update client info")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case err, ok := <-hf.watcher.Errors:
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctrld.ProxyLogger.Load().Err(err).Msg("could not watch client info file")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupHostnameByIP returns hostname for given IP from current hosts file entries.
|
||||||
|
func (hf *hostsFile) LookupHostnameByIP(ip string) string {
|
||||||
|
hf.h.Lock()
|
||||||
|
defer hf.h.Unlock()
|
||||||
|
|
||||||
|
if names := hf.h.ListHostsByIP(ip); len(names) > 0 {
|
||||||
|
return names[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupHostnameByMac returns hostname for given Mac from current hosts file entries.
|
||||||
|
func (hf *hostsFile) LookupHostnameByMac(mac string) string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns human-readable format of hostsFile.
|
||||||
|
func (hf *hostsFile) String() string {
|
||||||
|
return "hosts"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user