diff --git a/internal/client/client.go b/internal/client/client.go index 56a0d99fc4c..32c815ee3eb 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -7,7 +7,6 @@ package client import ( "encoding" "fmt" - "strings" "github.com/AdguardTeam/AdGuardHome/internal/whois" ) @@ -18,8 +17,7 @@ type Source uint8 // Clients information sources. The order determines the priority. const ( - SourceNone Source = iota - SourceWHOIS + SourceWHOIS Source = iota SourceARP SourceRDNS SourceDHCP @@ -61,20 +59,24 @@ type Runtime struct { // whois is the filtered WHOIS information of a client. whois *whois.Info - // arp is the ARP information of a client. + // arp is the ARP information of a client. nil indicates that there is no + // information from the source. arp []string - // rdns is the RDNS information of a client. + // rdns is the RDNS information of a client. nil indicates that there is no + // information from the source. rdns []string - // dhcp is the DHCP information of a client. + // dhcp is the DHCP information of a client. nil indicates that there is no + // information from the source. dhcp []string - // hostsFile is the information from the hosts file. + // hostsFile is the information from the hosts file. nil indicates that + // there is no information from the source. hostsFile []string } -// Info returns a client information with highest priority. +// Info returns a client information from the highest-priority source. func (r *Runtime) Info() (cs Source, host string) { info := []string{} @@ -89,11 +91,16 @@ func (r *Runtime) Info() (cs Source, host string) { cs, info = SourceARP, r.arp } - return cs, strings.Join(info, " ") + // TODO(s.chzhen): Return the full information. + return cs, info[0] } -// SetInfo sets a client information. info must be non-nil. -func (r *Runtime) SetInfo(cs Source, info []string) { +// SetInfo sets a host as a client information from the cs. +// +// TODO(s.chzhen): Improve API. Use []string. +func (r *Runtime) SetInfo(cs Source, host string) { + info := []string{host} + switch cs { case SourceARP: r.arp = info diff --git a/internal/home/clients.go b/internal/home/clients.go index 15bd4f554c0..1ac87d2f511 100644 --- a/internal/home/clients.go +++ b/internal/home/clients.go @@ -50,7 +50,8 @@ type clientsContainer struct { list map[string]*Client // name -> client idIndex map[string]*Client // ID -> client - // ipToRC is a map where key is IP address and value is *client.Runtime. + // ipToRC is a map that contains the runtime clients according to their IP + // addresses. ipToRC map[netip.Addr]*client.Runtime allTags *stringutil.Set @@ -573,7 +574,7 @@ func (clients *clientsContainer) findRuntimeClient(ip netip.Addr) (rc *client.Ru rc = &client.Runtime{} } - rc.SetInfo(client.SourceDHCP, []string{host}) + rc.SetInfo(client.SourceDHCP, host) return rc, true } @@ -844,7 +845,7 @@ func (clients *clientsContainer) addHostLocked( clients.ipToRC[ip] = rc } - rc.SetInfo(src, []string{host}) + rc.SetInfo(src, host) log.Debug("clients: adding client info %s -> %q %q [%d]", ip, src, host, len(clients.ipToRC)) diff --git a/internal/home/clients_internal_test.go b/internal/home/clients_internal_test.go index 5e963ad41d6..93a84b0b321 100644 --- a/internal/home/clients_internal_test.go +++ b/internal/home/clients_internal_test.go @@ -60,9 +60,8 @@ func TestClients(t *testing.T) { cli1 = "1.1.1.1" cli2 = "2.2.2.2" - cliNoneIP = netip.MustParseAddr(cliNone) - cli1IP = netip.MustParseAddr(cli1) - cli2IP = netip.MustParseAddr(cli2) + cli1IP = netip.MustParseAddr(cli1) + cli2IP = netip.MustParseAddr(cli2) ) c := &Client{ @@ -100,7 +99,9 @@ func TestClients(t *testing.T) { assert.Equal(t, "client2", c.Name) - assert.Equal(t, clients.clientSource(cliNoneIP), client.SourceNone) + _, ok = clients.Find(cliNone) + assert.False(t, ok) + assert.Equal(t, clients.clientSource(cli1IP), client.SourcePersistent) assert.Equal(t, clients.clientSource(cli2IP), client.SourcePersistent) }) @@ -136,7 +137,6 @@ func TestClients(t *testing.T) { cliOld = "1.1.1.1" cliNew = "1.1.1.2" - cliOldIP = netip.MustParseAddr(cliOld) cliNewIP = netip.MustParseAddr(cliNew) ) @@ -149,7 +149,9 @@ func TestClients(t *testing.T) { }) require.NoError(t, err) - assert.Equal(t, clients.clientSource(cliOldIP), client.SourceNone) + _, ok = clients.Find(cliOld) + assert.False(t, ok) + assert.Equal(t, clients.clientSource(cliNewIP), client.SourcePersistent) prev, ok = clients.list["client1"] @@ -182,7 +184,8 @@ func TestClients(t *testing.T) { ok := clients.Del("client1-renamed") require.True(t, ok) - assert.Equal(t, clients.clientSource(netip.MustParseAddr("1.1.1.2")), client.SourceNone) + _, ok = clients.Find("1.1.1.2") + assert.False(t, ok) }) t.Run("del_fail", func(t *testing.T) { diff --git a/internal/home/clientshttp.go b/internal/home/clientshttp.go index ceb4d0b621d..d0ecab1f92b 100644 --- a/internal/home/clientshttp.go +++ b/internal/home/clientshttp.go @@ -100,9 +100,9 @@ type clientListJSON struct { Tags []string `json:"supported_tags"` } -// WHOISOrEmpty returns a WHOIS client information or a pointer to an empty +// whoisOrEmpty returns a WHOIS client information or a pointer to an empty // struct. Frontend expects a non-nil value. -func WHOISOrEmpty(r *client.Runtime) (info *whois.Info) { +func whoisOrEmpty(r *client.Runtime) (info *whois.Info) { info = r.WHOIS() if info != nil { return info @@ -126,7 +126,7 @@ func (clients *clientsContainer) handleGetClients(w http.ResponseWriter, r *http for ip, rc := range clients.ipToRC { src, host := rc.Info() cj := runtimeClientJSON{ - WHOIS: WHOISOrEmpty(rc), + WHOIS: whoisOrEmpty(rc), Name: host, Source: src, IP: ip, @@ -424,7 +424,7 @@ func (clients *clientsContainer) findRuntime(ip netip.Addr, idStr string) (cj *c cj = &clientJSON{ Name: host, IDs: []string{idStr}, - WHOIS: WHOISOrEmpty(rc), + WHOIS: whoisOrEmpty(rc), } disallowed, rule := clients.dnsServer.IsBlockedClient(ip, idStr)