diff --git a/internal/dhcpd/config.go b/internal/dhcpd/config.go index 8b255f76..c942039a 100644 --- a/internal/dhcpd/config.go +++ b/internal/dhcpd/config.go @@ -45,8 +45,10 @@ type DHCPServer interface { AddStaticLease(l *Lease) (err error) // RemoveStaticLease - remove a static lease RemoveStaticLease(l *Lease) (err error) - // FindMACbyIP - find a MAC address by IP address in the currently active DHCP leases - FindMACbyIP(ip net.IP) net.HardwareAddr + + // FindMACbyIP returns a MAC address by the IP address of its lease, if + // there is one. + FindMACbyIP(ip netip.Addr) (mac net.HardwareAddr) // WriteDiskConfig4 - copy disk configuration WriteDiskConfig4(c *V4ServerConf) diff --git a/internal/dhcpd/dhcpd.go b/internal/dhcpd/dhcpd.go index 3602b4db..ef7fe19f 100644 --- a/internal/dhcpd/dhcpd.go +++ b/internal/dhcpd/dhcpd.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "net" + "net/netip" "path/filepath" "time" @@ -42,7 +43,11 @@ type Lease struct { Hostname string `json:"hostname"` HWAddr net.HardwareAddr `json:"mac"` - IP net.IP `json:"ip"` + + // IP is the IP address leased to the client. + // + // TODO(a.garipov): Migrate leases.db and use netip.Addr. + IP net.IP `json:"ip"` } // Clone returns a deep copy of l. @@ -160,7 +165,7 @@ type Interface interface { Leases(flags GetLeasesFlags) (leases []*Lease) SetOnLeaseChanged(onLeaseChanged OnLeaseChangedT) - FindMACbyIP(ip net.IP) (mac net.HardwareAddr) + FindMACbyIP(ip netip.Addr) (mac net.HardwareAddr) WriteDiskConfig(c *ServerConfig) } @@ -174,7 +179,7 @@ type MockInterface struct { OnEnabled func() (ok bool) OnLeases func(flags GetLeasesFlags) (leases []*Lease) OnSetOnLeaseChanged func(f OnLeaseChangedT) - OnFindMACbyIP func(ip net.IP) (mac net.HardwareAddr) + OnFindMACbyIP func(ip netip.Addr) (mac net.HardwareAddr) OnWriteDiskConfig func(c *ServerConfig) } @@ -195,8 +200,10 @@ func (s *MockInterface) Leases(flags GetLeasesFlags) (ls []*Lease) { return s.On // SetOnLeaseChanged implements the Interface for *MockInterface. func (s *MockInterface) SetOnLeaseChanged(f OnLeaseChangedT) { s.OnSetOnLeaseChanged(f) } -// FindMACbyIP implements the Interface for *MockInterface. -func (s *MockInterface) FindMACbyIP(ip net.IP) (mac net.HardwareAddr) { return s.OnFindMACbyIP(ip) } +// FindMACbyIP implements the [Interface] for *MockInterface. +func (s *MockInterface) FindMACbyIP(ip netip.Addr) (mac net.HardwareAddr) { + return s.OnFindMACbyIP(ip) +} // WriteDiskConfig implements the Interface for *MockInterface. func (s *MockInterface) WriteDiskConfig(c *ServerConfig) { s.OnWriteDiskConfig(c) } @@ -375,11 +382,13 @@ func (s *server) Leases(flags GetLeasesFlags) (leases []*Lease) { return append(s.srv4.GetLeases(flags), s.srv6.GetLeases(flags)...) } -// FindMACbyIP - find a MAC address by IP address in the currently active DHCP leases -func (s *server) FindMACbyIP(ip net.IP) net.HardwareAddr { - if ip.To4() != nil { +// FindMACbyIP returns a MAC address by the IP address of its lease, if there is +// one. +func (s *server) FindMACbyIP(ip netip.Addr) (mac net.HardwareAddr) { + if ip.Is4() { return s.srv4.FindMACbyIP(ip) } + return s.srv6.FindMACbyIP(ip) } diff --git a/internal/dhcpd/v46_windows.go b/internal/dhcpd/v46_windows.go index 624ec767..dcdb3caf 100644 --- a/internal/dhcpd/v46_windows.go +++ b/internal/dhcpd/v46_windows.go @@ -4,23 +4,26 @@ package dhcpd // 'u-root/u-root' package, a dependency of 'insomniacslk/dhcp' package, doesn't build on Windows -import "net" +import ( + "net" + "net/netip" +) type winServer struct{} // type check var _ DHCPServer = winServer{} -func (winServer) ResetLeases(_ []*Lease) (err error) { return nil } -func (winServer) GetLeases(_ GetLeasesFlags) (leases []*Lease) { return nil } -func (winServer) getLeasesRef() []*Lease { return nil } -func (winServer) AddStaticLease(_ *Lease) (err error) { return nil } -func (winServer) RemoveStaticLease(_ *Lease) (err error) { return nil } -func (winServer) FindMACbyIP(_ net.IP) (mac net.HardwareAddr) { return nil } -func (winServer) WriteDiskConfig4(_ *V4ServerConf) {} -func (winServer) WriteDiskConfig6(_ *V6ServerConf) {} -func (winServer) Start() (err error) { return nil } -func (winServer) Stop() (err error) { return nil } +func (winServer) ResetLeases(_ []*Lease) (err error) { return nil } +func (winServer) GetLeases(_ GetLeasesFlags) (leases []*Lease) { return nil } +func (winServer) getLeasesRef() []*Lease { return nil } +func (winServer) AddStaticLease(_ *Lease) (err error) { return nil } +func (winServer) RemoveStaticLease(_ *Lease) (err error) { return nil } +func (winServer) FindMACbyIP(_ netip.Addr) (mac net.HardwareAddr) { return nil } +func (winServer) WriteDiskConfig4(_ *V4ServerConf) {} +func (winServer) WriteDiskConfig6(_ *V6ServerConf) {} +func (winServer) Start() (err error) { return nil } +func (winServer) Stop() (err error) { return nil } func v4Create(_ *V4ServerConf) (s DHCPServer, err error) { return winServer{}, nil } func v6Create(_ V6ServerConf) (s DHCPServer, err error) { return winServer{}, nil } diff --git a/internal/dhcpd/v4_unix.go b/internal/dhcpd/v4_unix.go index 64ebf25d..63ae46d9 100644 --- a/internal/dhcpd/v4_unix.go +++ b/internal/dhcpd/v4_unix.go @@ -200,20 +200,20 @@ func (s *v4Server) GetLeases(flags GetLeasesFlags) (leases []*Lease) { return leases } -// FindMACbyIP - find a MAC address by IP address in the currently active DHCP leases -func (s *v4Server) FindMACbyIP(ip net.IP) net.HardwareAddr { +// FindMACbyIP implements the [Interface] for *v4Server. +func (s *v4Server) FindMACbyIP(ip netip.Addr) (mac net.HardwareAddr) { now := time.Now() s.leasesLock.Lock() defer s.leasesLock.Unlock() - ip4 := ip.To4() - if ip4 == nil { + if !ip.Is4() { return nil } + netIP := ip.AsSlice() for _, l := range s.leases { - if l.IP.Equal(ip4) { + if l.IP.Equal(netIP) { if l.Expiry.After(now) || l.IsStatic() { return l.HWAddr } diff --git a/internal/dhcpd/v6_unix.go b/internal/dhcpd/v6_unix.go index 96512ddb..d69d47c2 100644 --- a/internal/dhcpd/v6_unix.go +++ b/internal/dhcpd/v6_unix.go @@ -6,6 +6,7 @@ import ( "bytes" "fmt" "net" + "net/netip" "sync" "time" @@ -107,21 +108,26 @@ func (s *v6Server) getLeasesRef() []*Lease { return s.leases } -// FindMACbyIP - find a MAC address by IP address in the currently active DHCP leases -func (s *v6Server) FindMACbyIP(ip net.IP) net.HardwareAddr { - now := time.Now().Unix() +// FindMACbyIP implements the [Interface] for *v6Server. +func (s *v6Server) FindMACbyIP(ip netip.Addr) (mac net.HardwareAddr) { + now := time.Now() s.leasesLock.Lock() defer s.leasesLock.Unlock() + if !ip.Is6() { + return nil + } + + netIP := ip.AsSlice() for _, l := range s.leases { - if l.IP.Equal(ip) { - unix := l.Expiry.Unix() - if unix > now || unix == leaseExpireStatic { + if l.IP.Equal(netIP) { + if l.Expiry.After(now) || l.IsStatic() { return l.HWAddr } } } + return nil } diff --git a/internal/dnsforward/dnsforward_test.go b/internal/dnsforward/dnsforward_test.go index 6d928422..6941c2d2 100644 --- a/internal/dnsforward/dnsforward_test.go +++ b/internal/dnsforward/dnsforward_test.go @@ -11,6 +11,7 @@ import ( "fmt" "math/big" "net" + "net/netip" "sync" "sync/atomic" "testing" @@ -1009,7 +1010,7 @@ var testDHCP = &dhcpd.MockInterface{ }} }, OnSetOnLeaseChanged: func(olct dhcpd.OnLeaseChangedT) {}, - OnFindMACbyIP: func(ip net.IP) (mac net.HardwareAddr) { panic("not implemented") }, + OnFindMACbyIP: func(ip netip.Addr) (mac net.HardwareAddr) { panic("not implemented") }, OnWriteDiskConfig: func(c *dhcpd.ServerConfig) { panic("not implemented") }, } diff --git a/internal/home/client.go b/internal/home/client.go new file mode 100644 index 00000000..d84b7c26 --- /dev/null +++ b/internal/home/client.go @@ -0,0 +1,102 @@ +package home + +import ( + "encoding" + "fmt" + + "github.com/AdguardTeam/dnsproxy/proxy" +) + +// Client contains information about persistent clients. +type Client struct { + // upstreamConfig is the custom upstream config for this client. If + // it's nil, it has not been initialized yet. If it's non-nil and + // empty, there are no valid upstreams. If it's non-nil and non-empty, + // these upstream must be used. + upstreamConfig *proxy.UpstreamConfig + + Name string + + IDs []string + Tags []string + BlockedServices []string + Upstreams []string + + UseOwnSettings bool + FilteringEnabled bool + SafeSearchEnabled bool + SafeBrowsingEnabled bool + ParentalEnabled bool + UseOwnBlockedServices bool +} + +// closeUpstreams closes the client-specific upstream config of c if any. +func (c *Client) closeUpstreams() (err error) { + if c.upstreamConfig != nil { + err = c.upstreamConfig.Close() + if err != nil { + return fmt.Errorf("closing upstreams of client %q: %w", c.Name, err) + } + } + + return nil +} + +// clientSource represents the source from which the information about the +// client has been obtained. +type clientSource uint + +// Clients information sources. The order determines the priority. +const ( + ClientSourceNone clientSource = iota + ClientSourceWHOIS + ClientSourceARP + ClientSourceRDNS + ClientSourceDHCP + ClientSourceHostsFile + ClientSourcePersistent +) + +// type check +var _ fmt.Stringer = clientSource(0) + +// String returns a human-readable name of cs. +func (cs clientSource) String() (s string) { + switch cs { + case ClientSourceWHOIS: + return "WHOIS" + case ClientSourceARP: + return "ARP" + case ClientSourceRDNS: + return "rDNS" + case ClientSourceDHCP: + return "DHCP" + case ClientSourceHostsFile: + return "etc/hosts" + default: + return "" + } +} + +// type check +var _ encoding.TextMarshaler = clientSource(0) + +// MarshalText implements encoding.TextMarshaler for the clientSource. +func (cs clientSource) MarshalText() (text []byte, err error) { + return []byte(cs.String()), nil +} + +// RuntimeClient is a client information about which has been obtained using the +// source described in the Source field. +type RuntimeClient struct { + WHOISInfo *RuntimeClientWHOISInfo + Host string + Source clientSource +} + +// RuntimeClientWHOISInfo is the filtered WHOIS data for a runtime client. +type RuntimeClientWHOISInfo struct { + City string `json:"city,omitempty"` + Country string `json:"country,omitempty"` + Orgname string `json:"orgname,omitempty"` +} diff --git a/internal/home/clients.go b/internal/home/clients.go index 2ae81377..d5e0d02d 100644 --- a/internal/home/clients.go +++ b/internal/home/clients.go @@ -2,7 +2,6 @@ package home import ( "bytes" - "encoding" "fmt" "net" "net/netip" @@ -25,122 +24,16 @@ import ( "golang.org/x/exp/slices" ) -const clientsUpdatePeriod = 10 * time.Minute - -var webHandlersRegistered = false - -// Client contains information about persistent clients. -type Client struct { - // upstreamConfig is the custom upstream config for this client. If - // it's nil, it has not been initialized yet. If it's non-nil and - // empty, there are no valid upstreams. If it's non-nil and non-empty, - // these upstream must be used. - upstreamConfig *proxy.UpstreamConfig - - Name string - - IDs []string - Tags []string - BlockedServices []string - Upstreams []string - - UseOwnSettings bool - FilteringEnabled bool - SafeSearchEnabled bool - SafeBrowsingEnabled bool - ParentalEnabled bool - UseOwnBlockedServices bool -} - -// closeUpstreams closes the client-specific upstream config of c if any. -func (c *Client) closeUpstreams() (err error) { - if c.upstreamConfig != nil { - err = c.upstreamConfig.Close() - if err != nil { - return fmt.Errorf("closing upstreams of client %q: %w", c.Name, err) - } - } - - return nil -} - -type clientSource uint - -// Clients information sources. The order determines the priority. -const ( - ClientSourceNone clientSource = iota - ClientSourceWHOIS - ClientSourceARP - ClientSourceRDNS - ClientSourceDHCP - ClientSourceHostsFile - ClientSourcePersistent -) - -// type check -var _ fmt.Stringer = clientSource(0) - -// String returns a human-readable name of cs. -func (cs clientSource) String() (s string) { - switch cs { - case ClientSourceWHOIS: - return "WHOIS" - case ClientSourceARP: - return "ARP" - case ClientSourceRDNS: - return "rDNS" - case ClientSourceDHCP: - return "DHCP" - case ClientSourceHostsFile: - return "etc/hosts" - default: - return "" - } -} - -// type check -var _ encoding.TextMarshaler = clientSource(0) - -// MarshalText implements encoding.TextMarshaler for the clientSource. -func (cs clientSource) MarshalText() (text []byte, err error) { - return []byte(cs.String()), nil -} - -// clientSourceConf is used to configure where the runtime clients will be -// obtained from. -type clientSourcesConf struct { - WHOIS bool `yaml:"whois"` - ARP bool `yaml:"arp"` - RDNS bool `yaml:"rdns"` - DHCP bool `yaml:"dhcp"` - HostsFile bool `yaml:"hosts"` -} - -// RuntimeClient information -type RuntimeClient struct { - WHOISInfo *RuntimeClientWHOISInfo - Host string - Source clientSource -} - -// RuntimeClientWHOISInfo is the filtered WHOIS data for a runtime client. -type RuntimeClientWHOISInfo struct { - City string `json:"city,omitempty"` - Country string `json:"country,omitempty"` - Orgname string `json:"orgname,omitempty"` -} - +// clientsContainer is the storage of all runtime and persistent clients. type clientsContainer struct { - // TODO(a.garipov): Perhaps use a number of separate indices for - // different types (string, netip.Addr, and so on). + // TODO(a.garipov): Perhaps use a number of separate indices for different + // types (string, netip.Addr, and so on). list map[string]*Client // name -> client idIndex map[string]*Client // ID -> client // ipToRC is the IP address to *RuntimeClient map. ipToRC map[netip.Addr]*RuntimeClient - lock sync.Mutex - allTags *stringutil.Set // dhcpServer is used for looking up clients IP addresses by MAC addresses @@ -156,7 +49,16 @@ type clientsContainer struct { // arpdb stores the neighbors retrieved from ARP. arpdb aghnet.ARPDB - testing bool // if TRUE, this object is used for internal tests + // lock protects all fields. + // + // TODO(a.garipov): Use a pointer and describe which fields are protected in + // more detail. + lock sync.Mutex + + // testing is a flag that disables some features for internal tests. + // + // TODO(a.garipov): Awful. Remove. + testing bool } // Init initializes clients container @@ -202,24 +104,34 @@ func (clients *clientsContainer) handleHostsUpdates() { } } -// Start - start the module +// webHandlersRegistered prevents a [clientsContainer] from regisering its web +// handlers more than once. +// +// TODO(a.garipov): Refactor HTTP handler registration logic. +var webHandlersRegistered = false + +// Start starts the clients container. func (clients *clientsContainer) Start() { - if !clients.testing { - if !webHandlersRegistered { - webHandlersRegistered = true - clients.registerWebHandlers() - } - go clients.periodicUpdate() + if clients.testing { + return } + + if !webHandlersRegistered { + webHandlersRegistered = true + clients.registerWebHandlers() + } + + go clients.periodicUpdate() } -// Reload reloads runtime clients. -func (clients *clientsContainer) Reload() { +// reloadARP reloads runtime clients from ARP, if configured. +func (clients *clientsContainer) reloadARP() { if clients.arpdb != nil { clients.addFromSystemARP() } } +// clientObject is the YAML representation of a persistent client. type clientObject struct { Name string `yaml:"name"` @@ -317,12 +229,15 @@ func (clients *clientsContainer) forConfig() (objs []*clientObject) { return objs } +// arpClientsUpdatePeriod defines how often ARP clients are updated. +const arpClientsUpdatePeriod = 10 * time.Minute + func (clients *clientsContainer) periodicUpdate() { defer log.OnPanic("clients container") for { - clients.Reload() - time.Sleep(clientsUpdatePeriod) + clients.reloadARP() + time.Sleep(arpClientsUpdatePeriod) } } @@ -485,7 +400,8 @@ func (clients *clientsContainer) findUpstreams( return conf, nil } -// findLocked searches for a client by its ID. For internal use only. +// findLocked searches for a client by its ID. clients.lock is expected to be +// locked. func (clients *clientsContainer) findLocked(id string) (c *Client, ok bool) { c, ok = clients.idIndex[id] if ok { @@ -499,13 +415,13 @@ func (clients *clientsContainer) findLocked(id string) (c *Client, ok bool) { for _, c = range clients.list { for _, id := range c.IDs { - var n netip.Prefix - n, err = netip.ParsePrefix(id) + var subnet netip.Prefix + subnet, err = netip.ParsePrefix(id) if err != nil { continue } - if n.Contains(ip) { + if subnet.Contains(ip) { return c, true } } @@ -515,20 +431,25 @@ func (clients *clientsContainer) findLocked(id string) (c *Client, ok bool) { return nil, false } - macFound := clients.dhcpServer.FindMACbyIP(ip.AsSlice()) - if macFound == nil { + return clients.findDHCP(ip) +} + +// findDHCP searches for a client by its MAC, if the DHCP server is active and +// there is such client. clients.lock is expected to be locked. +func (clients *clientsContainer) findDHCP(ip netip.Addr) (c *Client, ok bool) { + foundMAC := clients.dhcpServer.FindMACbyIP(ip) + if foundMAC == nil { return nil, false } for _, c = range clients.list { for _, id := range c.IDs { - var mac net.HardwareAddr - mac, err = net.ParseMAC(id) + mac, err := net.ParseMAC(id) if err != nil { continue } - if bytes.Equal(mac, macFound) { + if bytes.Equal(mac, foundMAC) { return c, true } } @@ -565,24 +486,13 @@ func (clients *clientsContainer) check(c *Client) (err error) { } for i, id := range c.IDs { - // Normalize structured data. - var ( - ip netip.Addr - n netip.Prefix - mac net.HardwareAddr - ) - - if ip, err = netip.ParseAddr(id); err == nil { - c.IDs[i] = ip.String() - } else if n, err = netip.ParsePrefix(id); err == nil { - c.IDs[i] = n.String() - } else if mac, err = net.ParseMAC(id); err == nil { - c.IDs[i] = mac.String() - } else if err = dnsforward.ValidateClientID(id); err == nil { - c.IDs[i] = strings.ToLower(id) - } else { - return fmt.Errorf("invalid clientid at index %d: %q", i, id) + var norm string + norm, err = normalizeClientIdentifier(id) + if err != nil { + return fmt.Errorf("client at index %d: %w", i, err) } + + c.IDs[i] = norm } for _, t := range c.Tags { @@ -601,6 +511,35 @@ func (clients *clientsContainer) check(c *Client) (err error) { return nil } +// normalizeClientIdentifier returns a normalized version of idStr. If idStr +// cannot be normalized, it returns an error. +func normalizeClientIdentifier(idStr string) (norm string, err error) { + if idStr == "" { + return "", errors.Error("clientid is empty") + } + + var ip netip.Addr + if ip, err = netip.ParseAddr(idStr); err == nil { + return ip.String(), nil + } + + var subnet netip.Prefix + if subnet, err = netip.ParsePrefix(idStr); err == nil { + return subnet.String(), nil + } + + var mac net.HardwareAddr + if mac, err = net.ParseMAC(idStr); err == nil { + return mac.String(), nil + } + + if err = dnsforward.ValidateClientID(idStr); err == nil { + return strings.ToLower(idStr), nil + } + + return "", fmt.Errorf("bad client identifier %q", idStr) +} + // Add adds a new client object. ok is false if such client already exists or // if an error occurred. func (clients *clientsContainer) Add(c *Client) (ok bool, err error) { @@ -666,21 +605,6 @@ func (clients *clientsContainer) Del(name string) (ok bool) { return true } -// equalStringSlices returns true if the slices are equal. -func equalStringSlices(a, b []string) (ok bool) { - if len(a) != len(b) { - return false - } - - for i := range a { - if a[i] != b[i] { - return false - } - } - - return true -} - // Update updates a client by its name. func (clients *clientsContainer) Update(name string, c *Client) (err error) { err = clients.check(c) @@ -704,22 +628,11 @@ func (clients *clientsContainer) Update(name string, c *Client) (err error) { } } - // Second, check the IP index. - if !equalStringSlices(prev.IDs, c.IDs) { - for _, id := range c.IDs { - c2, ok2 := clients.idIndex[id] - if ok2 && c2 != prev { - return fmt.Errorf("another client uses the same id (%q): %q", id, c2.Name) - } - } - - // Update ID index. - for _, id := range prev.IDs { - delete(clients.idIndex, id) - } - for _, id := range c.IDs { - clients.idIndex[id] = prev - } + // Second, update the ID index. + err = clients.updateIDIndex(prev, c.IDs) + if err != nil { + // Don't wrap the error, because it's informative enough as is. + return err } // Update name index. @@ -739,6 +652,32 @@ func (clients *clientsContainer) Update(name string, c *Client) (err error) { return nil } +// updateIDIndex updates the ID index data for cli using the information from +// newIDs. +func (clients *clientsContainer) updateIDIndex(cli *Client, newIDs []string) (err error) { + if slices.Equal(cli.IDs, newIDs) { + return nil + } + + for _, id := range newIDs { + existing, ok := clients.idIndex[id] + if ok && existing != cli { + return fmt.Errorf("id %q is used by client with name %q", id, existing.Name) + } + } + + // Update the IDs in the index. + for _, id := range cli.IDs { + delete(clients.idIndex, id) + } + + for _, id := range newIDs { + clients.idIndex[id] = cli + } + + return nil +} + // setWHOISInfo sets the WHOIS information for a client. func (clients *clientsContainer) setWHOISInfo(ip netip.Addr, wi *RuntimeClientWHOISInfo) { clients.lock.Lock() diff --git a/internal/home/config.go b/internal/home/config.go index c484f185..ee848051 100644 --- a/internal/home/config.go +++ b/internal/home/config.go @@ -75,11 +75,21 @@ type osConfig struct { type clientsConfig struct { // Sources defines the set of sources to fetch the runtime clients from. - Sources *clientSourcesConf `yaml:"runtime_sources"` + Sources *clientSourcesConfig `yaml:"runtime_sources"` // Persistent are the configured clients. Persistent []*clientObject `yaml:"persistent"` } +// clientSourceConfig is used to configure where the runtime clients will be +// obtained from. +type clientSourcesConfig struct { + WHOIS bool `yaml:"whois"` + ARP bool `yaml:"arp"` + RDNS bool `yaml:"rdns"` + DHCP bool `yaml:"dhcp"` + HostsFile bool `yaml:"hosts"` +} + // configuration is loaded from YAML // field ordering is important -- yaml fields will mirror ordering from here type configuration struct { @@ -336,7 +346,7 @@ var config = &configuration{ }, }, Clients: &clientsConfig{ - Sources: &clientSourcesConf{ + Sources: &clientSourcesConfig{ WHOIS: true, ARP: true, RDNS: true, diff --git a/internal/home/home.go b/internal/home/home.go index 2fb74b3c..9c0351eb 100644 --- a/internal/home/home.go +++ b/internal/home/home.go @@ -125,7 +125,7 @@ func Main(clientBuildFS fs.FS) { log.Info("Received signal %q", sig) switch sig { case syscall.SIGHUP: - Context.clients.Reload() + Context.clients.reloadARP() Context.tls.reload() default: cleanup(context.Background()) diff --git a/internal/home/upgrade.go b/internal/home/upgrade.go index 0f53bcdc..169633fe 100644 --- a/internal/home/upgrade.go +++ b/internal/home/upgrade.go @@ -792,7 +792,7 @@ func upgradeSchema13to14(diskConf yobj) (err error) { diskConf["clients"] = yobj{ "persistent": clientsVal, - "runtime_sources": &clientSourcesConf{ + "runtime_sources": &clientSourcesConfig{ WHOIS: true, ARP: true, RDNS: rdnsSrc, diff --git a/internal/home/upgrade_test.go b/internal/home/upgrade_test.go index 14a43f70..4e442fa0 100644 --- a/internal/home/upgrade_test.go +++ b/internal/home/upgrade_test.go @@ -579,7 +579,7 @@ func TestUpgradeSchema13to14(t *testing.T) { // The clients field will be added anyway. "clients": yobj{ "persistent": yarr{}, - "runtime_sources": &clientSourcesConf{ + "runtime_sources": &clientSourcesConfig{ WHOIS: true, ARP: true, RDNS: false, @@ -597,7 +597,7 @@ func TestUpgradeSchema13to14(t *testing.T) { "schema_version": newSchemaVer, "clients": yobj{ "persistent": []*clientObject{testClient}, - "runtime_sources": &clientSourcesConf{ + "runtime_sources": &clientSourcesConfig{ WHOIS: true, ARP: true, RDNS: false, @@ -618,7 +618,7 @@ func TestUpgradeSchema13to14(t *testing.T) { "schema_version": newSchemaVer, "clients": yobj{ "persistent": []*clientObject{testClient}, - "runtime_sources": &clientSourcesConf{ + "runtime_sources": &clientSourcesConfig{ WHOIS: true, ARP: true, RDNS: true,