diff --git a/internal/client/difft b/internal/client/difft new file mode 100644 index 00000000..e69de29b diff --git a/internal/client/storage.go b/internal/client/storage.go index 18d1bdda..473acf76 100644 --- a/internal/client/storage.go +++ b/internal/client/storage.go @@ -1,7 +1,6 @@ package client import ( - "cmp" "context" "fmt" "net" @@ -9,7 +8,6 @@ import ( "sync" "time" - "github.com/AdguardTeam/AdGuardHome/internal/aghnet" "github.com/AdguardTeam/AdGuardHome/internal/arpdb" "github.com/AdguardTeam/AdGuardHome/internal/dhcpsvc" "github.com/AdguardTeam/AdGuardHome/internal/whois" @@ -19,6 +17,33 @@ import ( "github.com/AdguardTeam/golibs/log" ) +// Tags is the list of available client tags. +var Tags = []string{ + "device_audio", + "device_camera", + "device_gameconsole", + "device_laptop", + "device_nas", // Network-attached Storage + "device_other", + "device_pc", + "device_phone", + "device_printer", + "device_securityalarm", + "device_tablet", + "device_tv", + + "os_android", + "os_ios", + "os_linux", + "os_macos", + "os_other", + "os_windows", + + "user_admin", + "user_child", + "user_regular", +} + // DHCP is an interface for accessing DHCP lease data the [Storage] needs. type DHCP interface { // Leases returns all the DHCP leases. @@ -35,20 +60,20 @@ type DHCP interface { MACByIP(ip netip.Addr) (mac net.HardwareAddr) } -// emptyDHCP is the empty [DHCP] implementation that does nothing. -type emptyDHCP struct{} +// EmptyDHCP is the empty [DHCP] implementation that does nothing. +type EmptyDHCP struct{} // type check -var _ DHCP = emptyDHCP{} +var _ DHCP = EmptyDHCP{} // Leases implements the [DHCP] interface for emptyDHCP. -func (emptyDHCP) Leases() (leases []*dhcpsvc.Lease) { return nil } +func (EmptyDHCP) Leases() (leases []*dhcpsvc.Lease) { return nil } // HostByIP implements the [DHCP] interface for emptyDHCP. -func (emptyDHCP) HostByIP(_ netip.Addr) (host string) { return "" } +func (EmptyDHCP) HostByIP(_ netip.Addr) (host string) { return "" } // MACByIP implements the [DHCP] interface for emptyDHCP. -func (emptyDHCP) MACByIP(_ netip.Addr) (mac net.HardwareAddr) { return nil } +func (EmptyDHCP) MACByIP(_ netip.Addr) (mac net.HardwareAddr) { return nil } // HostsContainer is an interface for receiving updates to the system hosts // file. @@ -56,9 +81,10 @@ type HostsContainer interface { Upd() (updates <-chan *hostsfile.DefaultStorage) } -// Config is the client storage configuration structure. -type Config struct { - // DHCP is used to update [SourceDHCP] runtime client information. +// StorageConfig is the client storage configuration structure. +type StorageConfig struct { + // DHCP is used to update [SourceDHCP] runtime client information. It must + // not be nil. DHCP DHCP // EtcHosts is used to update [SourceHostsFile] runtime client information. @@ -67,9 +93,6 @@ type Config struct { // ARPDB is used to update [SourceARP] runtime client information. ARPDB arpdb.Interface - // AllowedTags is a list of all allowed client tags. - AllowedTags []string - // InitialClients is a list of persistent clients parsed from the // configuration file. Each client must not be nil. InitialClients []*Persistent @@ -111,14 +134,13 @@ type Storage struct { } // NewStorage returns initialized client storage. conf must not be nil. -func NewStorage(conf *Config) (s *Storage, err error) { - allowedTags := container.NewMapSet(conf.AllowedTags...) +func NewStorage(conf *StorageConfig) (s *Storage, err error) { s = &Storage{ - allowedTags: allowedTags, + allowedTags: container.NewMapSet(Tags...), mu: &sync.Mutex{}, index: newIndex(), runtimeIndex: newRuntimeIndex(), - dhcp: cmp.Or(conf.DHCP, DHCP(emptyDHCP{})), + dhcp: conf.DHCP, etcHosts: conf.EtcHosts, arpDB: conf.ARPDB, arpClientsUpdatePeriod: conf.ARPClientsUpdatePeriod, @@ -132,16 +154,14 @@ func NewStorage(conf *Config) (s *Storage, err error) { } } - if hc, ok := s.etcHosts.(*aghnet.HostsContainer); ok && hc == nil { - s.etcHosts = nil - } - s.ReloadARP() return s, nil } // Start starts the goroutines for updating the runtime client information. +// +// TODO(s.chzhen): Pass context. func (s *Storage) Start(_ context.Context) (err error) { go s.periodicARPUpdate() go s.handleHostsUpdates() @@ -150,6 +170,8 @@ func (s *Storage) Start(_ context.Context) (err error) { } // Shutdown gracefully stops the client storage. +// +// TODO(s.chzhen): Pass context. func (s *Storage) Shutdown(_ context.Context) (err error) { close(s.done) diff --git a/internal/client/storage_test.go b/internal/client/storage_test.go index ad6b7f9b..c5f09c22 100644 --- a/internal/client/storage_test.go +++ b/internal/client/storage_test.go @@ -109,7 +109,8 @@ func TestStorage_Add_hostsfile(t *testing.T) { onUpd: func() (updates <-chan *hostsfile.DefaultStorage) { return hostCh }, } - storage, err := client.NewStorage(&client.Config{ + storage, err := client.NewStorage(&client.StorageConfig{ + DHCP: client.EmptyDHCP{}, EtcHosts: h, ARPClientsUpdatePeriod: testTimeout / 10, }) @@ -196,7 +197,8 @@ func TestStorage_Add_arp(t *testing.T) { }, } - storage, err := client.NewStorage(&client.Config{ + storage, err := client.NewStorage(&client.StorageConfig{ + DHCP: client.EmptyDHCP{}, ARPDB: a, ARPClientsUpdatePeriod: testTimeout / 10, }) @@ -270,7 +272,9 @@ func TestStorage_Add_whois(t *testing.T) { cliName3 = "client_three" ) - storage, err := client.NewStorage(&client.Config{}) + storage, err := client.NewStorage(&client.StorageConfig{ + DHCP: client.EmptyDHCP{}, + }) require.NoError(t, err) whois := &whois.Info{ @@ -359,7 +363,7 @@ func TestClientsDHCP(t *testing.T) { }, } - storage, err := client.NewStorage(&client.Config{ + storage, err := client.NewStorage(&client.StorageConfig{ DHCP: d, }) require.NoError(t, err) @@ -431,7 +435,7 @@ func TestClientsAddExisting(t *testing.T) { dhcpServer, err := dhcpd.Create(config) require.NoError(t, err) - storage, err := client.NewStorage(&client.Config{ + storage, err := client.NewStorage(&client.StorageConfig{ DHCP: dhcpServer, }) require.NoError(t, err) @@ -495,8 +499,8 @@ func TestClientsAddExisting(t *testing.T) { func newStorage(tb testing.TB, m []*client.Persistent) (s *client.Storage) { tb.Helper() - s, err := client.NewStorage(&client.Config{ - AllowedTags: nil, + s, err := client.NewStorage(&client.StorageConfig{ + DHCP: client.EmptyDHCP{}, }) require.NoError(tb, err) @@ -544,9 +548,7 @@ func TestStorage_Add(t *testing.T) { UID: existingClientUID, } - s, err := client.NewStorage(&client.Config{ - AllowedTags: []string{allowedTag}, - }) + s, err := client.NewStorage(&client.StorageConfig{}) require.NoError(t, err) err = s.Add(existingClient) @@ -637,9 +639,7 @@ func TestStorage_RemoveByName(t *testing.T) { UID: client.MustNewUID(), } - s, err := client.NewStorage(&client.Config{ - AllowedTags: nil, - }) + s, err := client.NewStorage(&client.StorageConfig{}) require.NoError(t, err) err = s.Add(existingClient) @@ -666,9 +666,7 @@ func TestStorage_RemoveByName(t *testing.T) { } t.Run("duplicate_remove", func(t *testing.T) { - s, err = client.NewStorage(&client.Config{ - AllowedTags: nil, - }) + s, err = client.NewStorage(&client.StorageConfig{}) require.NoError(t, err) err = s.Add(existingClient) diff --git a/internal/home/clients.go b/internal/home/clients.go index 60d7dafd..d7d4e628 100644 --- a/internal/home/clients.go +++ b/internal/home/clients.go @@ -95,15 +95,15 @@ func (clients *clientsContainer) Init( // TODO(e.burkov): The option should probably be returned, since hosts file // currently used not only for clients' information enrichment, but also in // the filtering module and upstream addresses resolution. + var EtcHosts client.HostsContainer = etcHosts if !config.Clients.Sources.HostsFile { - etcHosts = nil + EtcHosts = nil } - clients.storage, err = client.NewStorage(&client.Config{ - AllowedTags: clientTags, + clients.storage, err = client.NewStorage(&client.StorageConfig{ InitialClients: confClients, DHCP: dhcpServer, - EtcHosts: etcHosts, + EtcHosts: EtcHosts, ARPDB: arpDB, ARPClientsUpdatePeriod: arpClientsUpdatePeriod, }) diff --git a/internal/home/clients_internal_test.go b/internal/home/clients_internal_test.go index 927f9a32..c23f4b23 100644 --- a/internal/home/clients_internal_test.go +++ b/internal/home/clients_internal_test.go @@ -20,7 +20,7 @@ func newClientsContainer(t *testing.T) (c *clientsContainer) { testing: true, } - require.NoError(t, c.Init(nil, nil, nil, nil, &filtering.Config{})) + require.NoError(t, c.Init(nil, client.EmptyDHCP{}, nil, nil, &filtering.Config{})) return c } diff --git a/internal/home/clientshttp.go b/internal/home/clientshttp.go index b6f27448..a977acc0 100644 --- a/internal/home/clientshttp.go +++ b/internal/home/clientshttp.go @@ -119,7 +119,7 @@ func (clients *clientsContainer) handleGetClients(w http.ResponseWriter, r *http return true }) - data.Tags = clientTags + data.Tags = client.Tags aghhttp.WriteJSONResponseOK(w, r, data) } diff --git a/internal/home/clientstags.go b/internal/home/clientstags.go deleted file mode 100644 index b4fc518a..00000000 --- a/internal/home/clientstags.go +++ /dev/null @@ -1,27 +0,0 @@ -package home - -var clientTags = []string{ - "device_audio", - "device_camera", - "device_gameconsole", - "device_laptop", - "device_nas", // Network-attached Storage - "device_other", - "device_pc", - "device_phone", - "device_printer", - "device_securityalarm", - "device_tablet", - "device_tv", - - "os_android", - "os_ios", - "os_linux", - "os_macos", - "os_other", - "os_windows", - - "user_admin", - "user_child", - "user_regular", -} diff --git a/internal/home/dns_internal_test.go b/internal/home/dns_internal_test.go index ca112e59..d3712890 100644 --- a/internal/home/dns_internal_test.go +++ b/internal/home/dns_internal_test.go @@ -18,9 +18,7 @@ var testIPv4 = netip.AddrFrom4([4]byte{1, 2, 3, 4}) func newStorage(tb testing.TB, clients []*client.Persistent) (s *client.Storage) { tb.Helper() - s, err := client.NewStorage(&client.Config{ - AllowedTags: nil, - }) + s, err := client.NewStorage(&client.StorageConfig{}) require.NoError(tb, err) for _, p := range clients {