Pull request: querylog: fix panic

Merge in DNS/adguard-home from querylog-panic to master

Squashed commit of the following:

commit b7f2edd1d7dd91c0102b9cb4ea50c34d8d9ceb58
Merge: 1b355a2d fac574d3
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Sep 13 20:06:07 2021 +0300

    Merge branch 'master' into querylog-panic

commit 1b355a2df6bd96431a70111607470b873b742562
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Sep 13 19:41:58 2021 +0300

    querylog: fix panic
This commit is contained in:
Ainar Garipov 2021-09-13 20:16:06 +03:00
parent fac574d324
commit 9a1d3ec694
2 changed files with 48 additions and 50 deletions

View File

@ -149,19 +149,19 @@ func (clients *clientsContainer) Reload() {
} }
type clientObject struct { type clientObject struct {
Name string `yaml:"name"` Name string `yaml:"name"`
Tags []string `yaml:"tags"`
IDs []string `yaml:"ids"`
UseGlobalSettings bool `yaml:"use_global_settings"`
FilteringEnabled bool `yaml:"filtering_enabled"`
ParentalEnabled bool `yaml:"parental_enabled"`
SafeSearchEnabled bool `yaml:"safesearch_enabled"`
SafeBrowsingEnabled bool `yaml:"safebrowsing_enabled"`
UseGlobalBlockedServices bool `yaml:"use_global_blocked_services"` Tags []string `yaml:"tags"`
BlockedServices []string `yaml:"blocked_services"` IDs []string `yaml:"ids"`
BlockedServices []string `yaml:"blocked_services"`
Upstreams []string `yaml:"upstreams"`
Upstreams []string `yaml:"upstreams"` UseGlobalSettings bool `yaml:"use_global_settings"`
FilteringEnabled bool `yaml:"filtering_enabled"`
ParentalEnabled bool `yaml:"parental_enabled"`
SafeSearchEnabled bool `yaml:"safesearch_enabled"`
SafeBrowsingEnabled bool `yaml:"safebrowsing_enabled"`
UseGlobalBlockedServices bool `yaml:"use_global_blocked_services"`
} }
func (clients *clientsContainer) tagKnown(tag string) (ok bool) { func (clients *clientsContainer) tagKnown(tag string) (ok bool) {
@ -285,70 +285,68 @@ func toQueryLogWHOIS(wi *RuntimeClientWHOISInfo) (cw *querylog.ClientWHOIS) {
} }
} }
// findMultiple returns info about client. If no information about the client // findMultiple is a wrapper around Find to make it a valid client finder for
// is found, it sends the client by default only with the "Disallowed" field // the query log. c is never nil; if no information about the client is found,
// filled in. err is always nil. // it returns an artificial client record by only setting the blocking-related
// fields. err is always nil.
func (clients *clientsContainer) findMultiple(ids []string) (c *querylog.Client, err error) { func (clients *clientsContainer) findMultiple(ids []string) (c *querylog.Client, err error) {
var emptyClient *querylog.Client var artClient *querylog.Client
var art bool
for _, id := range ids { for _, id := range ids {
ip := net.ParseIP(id) c, art = clients.clientOrArtificial(net.ParseIP(id), id)
disallowed, disallowedRule := clients.dnsServer.IsBlockedClient(ip, id) if art {
artClient = c
client := clients.clientInfo(ip, id, disallowed, disallowedRule)
if client.Name == "" && client.DisallowedRule == "" {
emptyClient = client
continue continue
} }
return client, nil return c, nil
} }
return emptyClient, nil return artClient, nil
} }
// clientInfo is a wrapper around Find to make it a valid client finder for // clientOrArtificial returns information about one client. If art is true,
// the query log. // this is an artificial client record, meaning that we currently don't have any
func (clients *clientsContainer) clientInfo( // records about this client besides maybe whether or not it is blocked. c is
// never nil.
func (clients *clientsContainer) clientOrArtificial(
ip net.IP, ip net.IP,
id string, id string,
disallowed bool, ) (c *querylog.Client, art bool) {
rule string, defer func() {
) (c *querylog.Client) { c.Disallowed, c.DisallowedRule = clients.dnsServer.IsBlockedClient(ip, id)
whois := &querylog.ClientWHOIS{} if c.WHOIS == nil {
c.WHOIS = &querylog.ClientWHOIS{}
}
}()
client, ok := clients.Find(id) client, ok := clients.Find(id)
if ok { if ok {
return &querylog.Client{ return &querylog.Client{
Name: client.Name, Name: client.Name,
DisallowedRule: rule, }, false
WHOIS: whois,
Disallowed: disallowed,
}
} }
if ip == nil { if ip == nil {
return nil // Technically should never happen, but still.
return &querylog.Client{
Name: "",
}, true
} }
var rc *RuntimeClient var rc *RuntimeClient
rc, ok = clients.FindRuntimeClient(ip) rc, ok = clients.FindRuntimeClient(ip)
if ok { if ok {
return &querylog.Client{ return &querylog.Client{
Name: rc.Host, Name: rc.Host,
DisallowedRule: rule, WHOIS: toQueryLogWHOIS(rc.WHOISInfo),
WHOIS: toQueryLogWHOIS(rc.WHOISInfo), }, false
Disallowed: disallowed,
}
} }
return &querylog.Client{ return &querylog.Client{
Name: "", Name: "",
DisallowedRule: rule, }, true
WHOIS: &querylog.ClientWHOIS{},
Disallowed: disallowed,
}
} }
func (clients *clientsContainer) Find(id string) (c *Client, ok bool) { func (clients *clientsContainer) Find(id string) (c *Client, ok bool) {

View File

@ -1962,14 +1962,14 @@
The rule due to which the client is allowed or blocked. The rule due to which the client is allowed or blocked.
'name': 'name':
'description': > 'description': >
Persistent client's name or runtime client's hostname. Persistent client's name or runtime client's hostname. May be
empty.
'type': 'string' 'type': 'string'
'whois': 'whois':
'$ref': '#/components/schemas/QueryLogItemClientWhois' '$ref': '#/components/schemas/QueryLogItemClientWhois'
'required': 'required':
- 'disallowed' - 'disallowed'
- 'disallowed_rule' - 'disallowed_rule'
- 'ids'
- 'name' - 'name'
- 'whois' - 'whois'
'type': 'object' 'type': 'object'