mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2024-11-28 18:08:51 +03:00
a7680a593a
Merge in DNS/adguard-home from fix-clients-races to master
Squashed commit of the following:
commit 2b29271b4c04b1c3046bd4cb3fb82f82fff0973b
Merge: 7f553feff cbc7985e7
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date: Thu May 25 17:43:07 2023 +0300
Merge branch 'master' into fix-clients-races
commit 7f553feff3aa46ae124a984776b60ed625148a1f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date: Thu May 25 16:25:43 2023 +0300
home: imp docs more
commit aaf74666cf069fc6cdd5a5e64915fef5675e0382
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date: Thu May 25 13:57:42 2023 +0300
home: imp docs
commit 50085085da3ae07b58bcc471906725339eec353e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date: Wed May 24 15:41:52 2023 +0300
home: imp code more
commit 9dc001640ec4bef62b2ccaed307a9daeeb3a8d3a
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date: Tue May 23 15:30:53 2023 +0300
home: imp code
commit fa906e78ec0777c8c585622873addd0f4791554e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date: Tue May 23 14:17:16 2023 +0300
home: fix clients races
140 lines
3.6 KiB
Go
140 lines
3.6 KiB
Go
package home
|
|
|
|
import (
|
|
"encoding"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
|
|
"github.com/AdguardTeam/AdGuardHome/internal/filtering/safesearch"
|
|
"github.com/AdguardTeam/dnsproxy/proxy"
|
|
"github.com/AdguardTeam/golibs/stringutil"
|
|
)
|
|
|
|
// 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
|
|
|
|
safeSearchConf filtering.SafeSearchConfig
|
|
SafeSearch filtering.SafeSearch
|
|
|
|
Name string
|
|
|
|
IDs []string
|
|
Tags []string
|
|
BlockedServices []string
|
|
Upstreams []string
|
|
|
|
UseOwnSettings bool
|
|
FilteringEnabled bool
|
|
SafeBrowsingEnabled bool
|
|
ParentalEnabled bool
|
|
UseOwnBlockedServices bool
|
|
IgnoreQueryLog bool
|
|
IgnoreStatistics bool
|
|
}
|
|
|
|
// ShallowClone returns a deep copy of the client, except upstreamConfig,
|
|
// safeSearchConf, SafeSearch fields, because it's difficult to copy them.
|
|
func (c *Client) ShallowClone() (sh *Client) {
|
|
clone := *c
|
|
|
|
clone.IDs = stringutil.CloneSlice(c.IDs)
|
|
clone.Tags = stringutil.CloneSlice(c.Tags)
|
|
clone.BlockedServices = stringutil.CloneSlice(c.BlockedServices)
|
|
clone.Upstreams = stringutil.CloneSlice(c.Upstreams)
|
|
|
|
return &clone
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// setSafeSearch initializes and sets the safe search filter for this client.
|
|
func (c *Client) setSafeSearch(
|
|
conf filtering.SafeSearchConfig,
|
|
cacheSize uint,
|
|
cacheTTL time.Duration,
|
|
) (err error) {
|
|
ss, err := safesearch.NewDefault(conf, fmt.Sprintf("client %q", c.Name), cacheSize, cacheTTL)
|
|
if err != nil {
|
|
// Don't wrap the error, because it's informative enough as is.
|
|
return err
|
|
}
|
|
|
|
c.SafeSearch = ss
|
|
|
|
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"`
|
|
}
|