Documentation ¶
Overview ¶
Package client contains types and logic dealing with AdGuard Home's DNS clients.
TODO(a.garipov): Expand.
Index ¶
- Constants
- func ValidateClientID(id string) (err error)
- type AddressProcessor
- type AddressUpdater
- type DHCP
- type DefaultAddrProc
- type DefaultAddrProcConfig
- type EmptyAddrProc
- type EmptyDHCP
- type HostsContainer
- type Persistent
- func (c *Persistent) CloseUpstreams() (err error)
- func (c *Persistent) EqualIDs(prev *Persistent) (equal bool)
- func (c *Persistent) IDs() (ids []string)
- func (c *Persistent) IDsLen() (n int)
- func (c *Persistent) SetIDs(ids []string) (err error)
- func (c *Persistent) ShallowClone() (clone *Persistent)
- type Runtime
- type Source
- type Storage
- func (s *Storage) Add(p *Persistent) (err error)
- func (s *Storage) AllowedTags() (tags []string)
- func (s *Storage) ClientRuntime(ip netip.Addr) (rc *Runtime)
- func (s *Storage) Find(id string) (p *Persistent, ok bool)
- func (s *Storage) FindByMAC(mac net.HardwareAddr) (p *Persistent, ok bool)
- func (s *Storage) FindByName(name string) (p *Persistent, ok bool)
- func (s *Storage) FindLoose(ip netip.Addr, id string) (p *Persistent, ok bool)
- func (s *Storage) RangeByName(f func(c *Persistent) (cont bool))
- func (s *Storage) RangeRuntime(f func(rc *Runtime) (cont bool))
- func (s *Storage) ReloadARP()
- func (s *Storage) RemoveByName(name string) (ok bool)
- func (s *Storage) Shutdown(_ context.Context) (err error)
- func (s *Storage) Size() (n int)
- func (s *Storage) Start(_ context.Context) (err error)
- func (s *Storage) Update(name string, p *Persistent) (err error)
- func (s *Storage) UpdateAddress(ip netip.Addr, host string, info *whois.Info)
- func (s *Storage) UpdateDHCP()
- type StorageConfig
- type UID
Constants ¶
const ErrClosed errors.Error = "use of closed address processor"
ErrClosed is returned from [AddressProcessor.Close] if it's closed more than once.
Variables ¶
This section is empty.
Functions ¶
func ValidateClientID ¶
ValidateClientID returns an error if id is not a valid ClientID.
TODO(s.chzhen): It's an exact copy of the [dnsforward.ValidateClientID] to avoid the import cycle. Remove it.
Types ¶
type AddressProcessor ¶
AddressProcessor is the interface for types that can process clients.
type AddressUpdater ¶
type AddressUpdater interface { // UpdateAddress updates information about an IP address, setting host (if // not empty) and WHOIS information (if not nil). UpdateAddress(ip netip.Addr, host string, info *whois.Info) }
AddressUpdater is the interface for storages of DNS clients that can update information about them.
TODO(a.garipov): Consider using the actual client storage once it is moved into this package.
type DHCP ¶
type DHCP interface { // Leases returns all the DHCP leases. Leases() (leases []*dhcpsvc.Lease) // HostByIP returns the hostname of the DHCP client with the given IP // address. host will be empty if there is no such client, due to an // assumption that a DHCP client must always have a hostname. HostByIP(ip netip.Addr) (host string) // MACByIP returns the MAC address for the given IP address leased. It // returns nil if there is no such client, due to an assumption that a DHCP // client must always have a MAC address. MACByIP(ip netip.Addr) (mac net.HardwareAddr) }
DHCP is an interface for accessing DHCP lease data the Storage needs.
type DefaultAddrProc ¶
type DefaultAddrProc struct {
// contains filtered or unexported fields
}
DefaultAddrProc processes incoming client addresses with rDNS and WHOIS, if configured, and updates that information in a client storage.
func NewDefaultAddrProc ¶
func NewDefaultAddrProc(c *DefaultAddrProcConfig) (p *DefaultAddrProc)
NewDefaultAddrProc returns a new running client address processor. c must not be nil.
func (*DefaultAddrProc) Close ¶
func (p *DefaultAddrProc) Close() (err error)
Close implements the AddressProcessor interface for *DefaultAddrProc.
func (*DefaultAddrProc) Process ¶
func (p *DefaultAddrProc) Process(ip netip.Addr)
Process implements the AddressProcessor interface for *DefaultAddrProc.
type DefaultAddrProcConfig ¶
type DefaultAddrProcConfig struct { // BaseLogger is used to create loggers with custom prefixes for sources of // information about runtime clients. It must not be nil. BaseLogger *slog.Logger // DialContext is used to create TCP connections to WHOIS servers. // DialContext must not be nil if [DefaultAddrProcConfig.UseWHOIS] is true. DialContext aghnet.DialContextFunc // Exchanger is used to perform rDNS queries. Exchanger must not be nil if // [DefaultAddrProcConfig.UseRDNS] is true. Exchanger rdns.Exchanger // PrivateSubnets are used to determine if an incoming IP address is // private. It must not be nil. PrivateSubnets netutil.SubnetSet // AddressUpdater is used to update the information about a client's IP // address. It must not be nil. AddressUpdater AddressUpdater // InitialAddresses are the addresses that are queued for processing // immediately by [NewDefaultAddrProc]. InitialAddresses []netip.Addr // CatchPanics, if true, makes the address processor catch and log panics. // // TODO(a.garipov): Consider better ways to do this or apply this method to // other parts of the codebase. CatchPanics bool // UseRDNS, if true, enables resolving of client IP addresses using reverse // DNS. UseRDNS bool // UsePrivateRDNS, if true, enables resolving of private client IP addresses // using reverse DNS. See [DefaultAddrProcConfig.PrivateSubnets]. UsePrivateRDNS bool // UseWHOIS, if true, enables resolving of client IP addresses using WHOIS. UseWHOIS bool }
DefaultAddrProcConfig is the configuration structure for address processors.
type EmptyAddrProc ¶
type EmptyAddrProc struct{}
EmptyAddrProc is an AddressProcessor that does nothing.
func (EmptyAddrProc) Close ¶
func (EmptyAddrProc) Close() (_ error)
Close implements the AddressProcessor interface for EmptyAddrProc.
func (EmptyAddrProc) Process ¶
func (EmptyAddrProc) Process(_ netip.Addr)
Process implements the AddressProcessor interface for EmptyAddrProc.
type EmptyDHCP ¶
type EmptyDHCP struct{}
EmptyDHCP is the empty DHCP implementation that does nothing.
type HostsContainer ¶
type HostsContainer interface {
Upd() (updates <-chan *hostsfile.DefaultStorage)
}
HostsContainer is an interface for receiving updates to the system hosts file.
type Persistent ¶
type Persistent struct { // UpstreamConfig is the custom upstream configuration 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.CustomUpstreamConfig // SafeSearch handles search engine hosts rewrites. SafeSearch filtering.SafeSearch // BlockedServices is the configuration of blocked services of a client. It // must not be nil after initialization. BlockedServices *filtering.BlockedServices // Name of the persistent client. Must not be empty. Name string // Tags is a list of client tags that categorize the client. Tags []string // Upstreams is a list of custom upstream DNS servers for the client. Upstreams []string // IPs is a list of IP addresses that identify the client. The client must // have at least one ID (IP, subnet, MAC, or ClientID). IPs []netip.Addr // Subnets identifying the client. The client must have at least one ID // (IP, subnet, MAC, or ClientID). // // TODO(s.chzhen): Use netutil.Prefix. Subnets []netip.Prefix // MACs identifying the client. The client must have at least one ID (IP, // subnet, MAC, or ClientID). MACs []net.HardwareAddr // ClientIDs identifying the client. The client must have at least one ID // (IP, subnet, MAC, or ClientID). ClientIDs []string // UID is the unique identifier of the persistent client. UID UID // UpstreamsCacheSize is the cache size for custom upstreams. UpstreamsCacheSize uint32 // UpstreamsCacheEnabled specifies whether custom upstreams are used. UpstreamsCacheEnabled bool // UseOwnSettings specifies whether custom filtering settings are used. UseOwnSettings bool // FilteringEnabled specifies whether filtering is enabled. FilteringEnabled bool // SafeBrowsingEnabled specifies whether safe browsing is enabled. SafeBrowsingEnabled bool // ParentalEnabled specifies whether parental control is enabled. ParentalEnabled bool // UseOwnBlockedServices specifies whether custom services are blocked. UseOwnBlockedServices bool // IgnoreQueryLog specifies whether the client requests are logged. IgnoreQueryLog bool // IgnoreStatistics specifies whether the client requests are counted. IgnoreStatistics bool // SafeSearchConf is the safe search filtering configuration. // // TODO(d.kolyshev): Make SafeSearchConf a pointer. SafeSearchConf filtering.SafeSearchConfig }
Persistent contains information about persistent clients.
func (*Persistent) CloseUpstreams ¶
func (c *Persistent) CloseUpstreams() (err error)
CloseUpstreams closes the client-specific upstream config of c if any.
func (*Persistent) EqualIDs ¶
func (c *Persistent) EqualIDs(prev *Persistent) (equal bool)
EqualIDs returns true if the ids of the current and previous clients are the same.
func (*Persistent) IDs ¶
func (c *Persistent) IDs() (ids []string)
IDs returns a list of client IDs containing at least one element.
func (*Persistent) IDsLen ¶
func (c *Persistent) IDsLen() (n int)
IDsLen returns a length of client ids.
func (*Persistent) SetIDs ¶
func (c *Persistent) SetIDs(ids []string) (err error)
SetIDs parses a list of strings into typed fields and returns an error if there is one.
func (*Persistent) ShallowClone ¶
func (c *Persistent) ShallowClone() (clone *Persistent)
ShallowClone returns a deep copy of the client, except upstreamConfig, safeSearchConf, SafeSearch fields, because it's difficult to copy them.
type Runtime ¶
type Runtime struct {
// contains filtered or unexported fields
}
Runtime is a client information from different sources.
func NewRuntime ¶
NewRuntime constructs a new runtime client. ip must be valid IP address.
TODO(s.chzhen): Validate IP address.
type Source ¶
type Source uint8
Source represents the source from which the information about the client has been obtained.
const ( SourceWHOIS Source = iota + 1 SourceARP SourceRDNS SourceDHCP SourceHostsFile SourcePersistent )
Clients information sources. The order determines the priority.
func (Source) MarshalText ¶
MarshalText implements encoding.TextMarshaler for the Source.
type Storage ¶
type Storage struct {
// contains filtered or unexported fields
}
Storage contains information about persistent and runtime clients.
func NewStorage ¶
func NewStorage(conf *StorageConfig) (s *Storage, err error)
NewStorage returns initialized client storage. conf must not be nil.
func (*Storage) Add ¶
func (s *Storage) Add(p *Persistent) (err error)
Add stores persistent client information or returns an error.
func (*Storage) AllowedTags ¶
AllowedTags returns the list of available client tags. tags must not be modified.
func (*Storage) ClientRuntime ¶
ClientRuntime returns a copy of the saved runtime client by ip. If no such client exists, returns nil.
func (*Storage) Find ¶
func (s *Storage) Find(id string) (p *Persistent, ok bool)
Find finds persistent client by string representation of the client ID, IP address, or MAC. And returns its shallow copy.
TODO(s.chzhen): Accept ClientIDData structure instead, which will contain the parsed IP address, if any.
func (*Storage) FindByMAC ¶
func (s *Storage) FindByMAC(mac net.HardwareAddr) (p *Persistent, ok bool)
FindByMAC finds persistent client by MAC and returns its shallow copy. s.mu is expected to be locked.
func (*Storage) FindByName ¶
func (s *Storage) FindByName(name string) (p *Persistent, ok bool)
FindByName finds persistent client by name. And returns its shallow copy.
func (*Storage) FindLoose ¶
FindLoose is like Storage.Find but it also tries to find a persistent client by IP address without zone. It strips the IPv6 zone index from the stored IP addresses before comparing, because querylog entries don't have it. See TODO on [querylog.logEntry.IP].
Note that multiple clients can have the same IP address with different zones. Therefore, the result of this method is indeterminate.
func (*Storage) RangeByName ¶
func (s *Storage) RangeByName(f func(c *Persistent) (cont bool))
RangeByName calls f for each persistent client sorted by name, unless cont is false.
func (*Storage) RangeRuntime ¶
RangeRuntime calls f for each runtime client in an undefined order.
func (*Storage) ReloadARP ¶
func (s *Storage) ReloadARP()
ReloadARP reloads runtime clients from ARP, if configured.
func (*Storage) RemoveByName ¶
RemoveByName removes persistent client information. ok is false if no such client exists by that name.
func (*Storage) Shutdown ¶
Shutdown gracefully stops the client storage.
TODO(s.chzhen): Pass context.
func (*Storage) Start ¶
Start starts the goroutines for updating the runtime client information.
TODO(s.chzhen): Pass context.
func (*Storage) Update ¶
func (s *Storage) Update(name string, p *Persistent) (err error)
Update finds the stored persistent client by its name and updates its information from p.
func (*Storage) UpdateAddress ¶
UpdateAddress implements the AddressUpdater interface for *Storage
func (*Storage) UpdateDHCP ¶
func (s *Storage) UpdateDHCP()
UpdateDHCP updates SourceDHCP runtime client information.
type StorageConfig ¶
type StorageConfig struct { // DHCP is used to match IPs against MACs of persistent clients and update // [SourceDHCP] runtime client information. It must not be nil. DHCP DHCP // EtcHosts is used to update [SourceHostsFile] runtime client information. EtcHosts HostsContainer // ARPDB is used to update [SourceARP] runtime client information. ARPDB arpdb.Interface // InitialClients is a list of persistent clients parsed from the // configuration file. Each client must not be nil. InitialClients []*Persistent // ARPClientsUpdatePeriod defines how often [SourceARP] runtime client // information is updated. ARPClientsUpdatePeriod time.Duration // RuntimeSourceDHCP specifies whether to update [SourceDHCP] information // of runtime clients. RuntimeSourceDHCP bool }
StorageConfig is the client storage configuration structure.
type UID ¶
UID is the type for the unique IDs of persistent clients.
func MustNewUID ¶
func MustNewUID() (uid UID)
MustNewUID is a wrapper around NewUID that panics if there is an error.
func NewUID ¶
NewUID returns a new persistent client UID. Any error returned is an error from the cryptographic randomness reader.
func (UID) MarshalText ¶
MarshalText implements the encoding.TextMarshaler for UID.
func (*UID) UnmarshalText ¶
UnmarshalText implements the encoding.TextUnmarshaler interface for UID.