diff --git a/internal/dnsforward/dnsforward.go b/internal/dnsforward/dnsforward.go index adab01a3cbd..5a6045b5518 100644 --- a/internal/dnsforward/dnsforward.go +++ b/internal/dnsforward/dnsforward.go @@ -375,5 +375,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { // IsBlockedIP - return TRUE if this client should be blocked func (s *Server) IsBlockedIP(ip net.IP) (bool, string) { + if ip == nil { + return false, "" + } + return s.access.IsBlockedIP(ip) } diff --git a/internal/home/clients.go b/internal/home/clients.go index 3020ead5d1f..2396281ef58 100644 --- a/internal/home/clients.go +++ b/internal/home/clients.go @@ -274,31 +274,41 @@ func copyStrings(a []string) (b []string) { // the query log. err is always nil. func (clients *clientsContainer) findMultiple(ids []string) (c *querylog.Client, err error) { for _, id := range ids { + var name string + var foundIDs []string + var whois *querylog.ClientWhois + c, ok := clients.Find(id) if ok { - return &querylog.Client{ - Name: c.Name, - IDs: c.IDs, - }, nil - } + name = c.Name + foundIDs = c.IDs + } else { + var ac ClientHost + ac, ok = clients.FindAutoClient(id) + if !ok { + continue + } - ac, ok := clients.FindAutoClient(id) - if !ok { - continue - } + foundIDs = []string{ac.Host} - var whois *querylog.ClientWhois - if wi := ac.WhoisInfo; wi != nil { - whois = &querylog.ClientWhois{ - City: wi.City, - Country: wi.Country, - Orgname: wi.Orgname, + if wi := ac.WhoisInfo; wi != nil { + whois = &querylog.ClientWhois{ + City: wi.City, + Country: wi.Country, + Orgname: wi.Orgname, + } } } + ip := net.ParseIP(id) + disallowed, disallowedRule := clients.dnsServer.IsBlockedIP(ip) + return &querylog.Client{ - IDs: []string{ac.Host}, - Whois: whois, + Name: name, + DisallowedRule: disallowedRule, + Whois: whois, + IDs: foundIDs, + Disallowed: disallowed, }, nil } diff --git a/internal/home/clientshttp.go b/internal/home/clientshttp.go index 5c961a9f6c7..75a1d3c24cc 100644 --- a/internal/home/clientshttp.go +++ b/internal/home/clientshttp.go @@ -60,10 +60,17 @@ func (clients *clientsContainer) handleGetClients(w http.ResponseWriter, _ *http data.Clients = append(data.Clients, cj) } for ip, ch := range clients.ipHost { + whois := ch.WhoisInfo + if whois == nil { + // The frontent currently expects an empty object + // instead of null. + whois = &RuntimeClientWhoisInfo{} + } + cj := clientHostJSON{ IP: ip, Name: ch.Host, - WhoisInfo: ch.WhoisInfo, + WhoisInfo: whois, } cj.Source = "etc/hosts" diff --git a/internal/querylog/client.go b/internal/querylog/client.go index 10c2f5fa20e..101a8cd4570 100644 --- a/internal/querylog/client.go +++ b/internal/querylog/client.go @@ -3,9 +3,11 @@ package querylog // Client is the information required by the query log to match against clients // during searches. type Client struct { - Name string `json:"name"` - Whois *ClientWhois `json:"whois,omitempty"` - IDs []string `json:"ids"` + Name string `json:"name"` + DisallowedRule string `json:"disallowed_rule"` + Whois *ClientWhois `json:"whois,omitempty"` + IDs []string `json:"ids"` + Disallowed bool `json:"disallowed"` } // ClientWhois is the filtered WHOIS data for the client. diff --git a/openapi/openapi.yaml b/openapi/openapi.yaml index d5338aac9fd..7733cc9560b 100644 --- a/openapi/openapi.yaml +++ b/openapi/openapi.yaml @@ -1882,19 +1882,30 @@ 'description': > Client information for a query log item. 'properties': - 'ids': - 'description': > - IP, CIDR, MAC, or client ID. - 'items': - 'type': 'string' - 'type': 'array' 'name': 'description': > Persistent client's name or an empty string if this is a runtime client. 'type': 'string' + 'disallowed_rule': + 'type': 'string' + 'description': > + The rule due to which the client is disallowed. If disallowed is + set to true, and this string is empty, then the client IP is + disallowed by the "allowed IP list", that is it is not included in + the allowed list. 'whois': '$ref': '#/components/schemas/QueryLogItemClientWhois' + 'ids': + 'description': > + IP, CIDR, MAC, or client ID. + 'items': + 'type': 'string' + 'type': 'array' + 'disallowed': + 'type': 'boolean' + 'description': > + Whether the client's IP is blocked or not. 'required': - 'ids' - 'name'