Skip to content

Commit

Permalink
home: runtime clients sources control
Browse files Browse the repository at this point in the history
  • Loading branch information
EugeneOne1 committed Apr 22, 2022
1 parent 82af430 commit 3f71b99
Show file tree
Hide file tree
Showing 8 changed files with 276 additions and 65 deletions.
36 changes: 35 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ and this project adheres to

### Added

- The ability to control each source of runtime clients separately via
`clients.runtime_sources` configuration property ([#3020]).
- The ability to customize the set of networks that are considered private
through the new `dns.private_networks` property in the configuration file
([#3142]).
Expand Down Expand Up @@ -63,7 +65,7 @@ and this project adheres to

#### Configuration Changes

In this release, the schema version has changed from 12 to 13.
In this release, the schema version has changed from 12 to 14.

- Property `local_domain_name`, which in schema versions 12 and earlier used to
be a part of the `dns` object, is now a part of the `dhcp` object:
Expand All @@ -82,9 +84,40 @@ In this release, the schema version has changed from 12 to 13.
To rollback this change, move the property back into the `dns` object and
change the `schema_version` back to `12`.
- Object `clients`, which in schema versions 13 and earlier was an array of
actual persistent clients, is now consists of `persistent` and
`runtime_sources` properties:

```yaml
# BEFORE:
'clients':
- name: client-name
# …
# AFTER:
'clients':
'persistent':
- name: client-name
# …
'runtime_sources':
whois: true
arp: false
rdns: false
dhcp: false
hosts: false
```

The value for `clients.runtime_sources.rdns` field is taken from
`dns.resolve_clients` property. To rollback this change, remove the
`runtime_sources` property, move the contents of `persistent` into the
`clients` itself, the value of `clients.runtime_sources.rdns` into the
`dns.resolve_clietns`, and change the `schema_version` back to `13`.

### Deprecated

- The `--no-etc-hosts` option. It's functionality is now controlled by
`clients.runtime_sources.hosts` configuration property. v0.109.0 will remove
the flag completely.
- Go 1.17 support. v0.109.0 will require at least Go 1.18 to build.

### Fixed
Expand All @@ -93,6 +126,7 @@ In this release, the schema version has changed from 12 to 13.

[#1730]: https://github.com/AdguardTeam/AdGuardHome/issues/1730
[#2993]: https://github.com/AdguardTeam/AdGuardHome/issues/2993
[#3020]: https://github.com/AdguardTeam/AdGuardHome/issues/3020
[#3057]: https://github.com/AdguardTeam/AdGuardHome/issues/3057
[#3142]: https://github.com/AdguardTeam/AdGuardHome/issues/3142
[#3157]: https://github.com/AdguardTeam/AdGuardHome/issues/3157
Expand Down
24 changes: 17 additions & 7 deletions internal/home/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ const (
ClientSourceHostsFile
)

type clientSourcesConf struct {
WHOIS bool `yaml:"whois"`
ARP bool `yaml:"arp"`
RDNS bool `yaml:"rdns"`
DHCP bool `yaml:"dhcp"`
HostsFile bool `yaml:"hosts"`
}

// RuntimeClient information
type RuntimeClient struct {
WHOISInfo *RuntimeClientWHOISInfo
Expand Down Expand Up @@ -134,14 +142,14 @@ func (clients *clientsContainer) Init(
clients.dhcpServer.SetOnLeaseChanged(clients.onDHCPLeaseChanged)
}

go clients.handleHostsUpdates()
if clients.etcHosts != nil {
go clients.handleHostsUpdates()
}
}

func (clients *clientsContainer) handleHostsUpdates() {
if clients.etcHosts != nil {
for upd := range clients.etcHosts.Upd() {
clients.addFromHostsFile(upd)
}
for upd := range clients.etcHosts.Upd() {
clients.addFromHostsFile(upd)
}
}

Expand All @@ -152,7 +160,9 @@ func (clients *clientsContainer) Start() {
webHandlersRegistered = true
clients.registerWebHandlers()
}
go clients.periodicUpdate()
if clients.arpdb != nil {
go clients.periodicUpdate()
}
}
}

Expand Down Expand Up @@ -843,7 +853,7 @@ func (clients *clientsContainer) addFromSystemARP() {
// updateFromDHCP adds the clients that have a non-empty hostname from the DHCP
// server.
func (clients *clientsContainer) updateFromDHCP(add bool) {
if clients.dhcpServer == nil {
if clients.dhcpServer == nil || !config.Clients.Srcs.DHCP {
return
}

Expand Down
26 changes: 17 additions & 9 deletions internal/home/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ type osConfig struct {
RlimitNoFile uint64 `yaml:"rlimit_nofile"`
}

type clientsConfig struct {
Persistent []*clientObject `yaml:"persistent"`
Srcs *clientSourcesConf `yaml:"runtime_sources"`
}

// configuration is loaded from YAML
// field ordering is important -- yaml fields will mirror ordering from here
type configuration struct {
Expand Down Expand Up @@ -88,7 +93,7 @@ type configuration struct {
// Clients contains the YAML representations of the persistent clients.
// This field is only used for reading and writing persistent client data.
// Keep this field sorted to ensure consistent ordering.
Clients []*clientObject `yaml:"clients"`
Clients *clientsConfig `yaml:"clients"`

logSettings `yaml:",inline"`

Expand Down Expand Up @@ -123,9 +128,6 @@ type dnsConfig struct {
// UpstreamTimeout is the timeout for querying upstream servers.
UpstreamTimeout timeutil.Duration `yaml:"upstream_timeout"`

// ResolveClients enables and disables resolving clients with RDNS.
ResolveClients bool `yaml:"resolve_clients"`

// PrivateNets is the set of IP networks for which the private reverse DNS
// resolver should be used.
PrivateNets []string `yaml:"private_networks"`
Expand Down Expand Up @@ -198,7 +200,6 @@ var config = &configuration{
FilteringEnabled: true, // whether or not use filter lists
FiltersUpdateIntervalHours: 24,
UpstreamTimeout: timeutil.Duration{Duration: dnsforward.DefaultTimeout},
ResolveClients: true,
UsePrivateRDNS: true,
},
TLS: tlsConfigSettings{
Expand All @@ -209,6 +210,15 @@ var config = &configuration{
DHCP: &dhcpd.ServerConfig{
LocalDomainName: "lan",
},
Clients: &clientsConfig{
Srcs: &clientSourcesConf{
WHOIS: true,
ARP: true,
RDNS: true,
DHCP: true,
HostsFile: true,
},
},
logSettings: logSettings{
LogCompress: false,
LogLocalTime: false,
Expand Down Expand Up @@ -404,9 +414,7 @@ func (c *configuration) write() error {
s.WriteDiskConfig(&c)
dns := &config.DNS
dns.FilteringConfig = c
dns.LocalPTRResolvers,
dns.ResolveClients,
dns.UsePrivateRDNS = s.RDNSSettings()
dns.LocalPTRResolvers, config.Clients.Srcs.RDNS, dns.UsePrivateRDNS = s.RDNSSettings()
}

if Context.dhcpServer != nil {
Expand All @@ -415,7 +423,7 @@ func (c *configuration) write() error {
config.DHCP = c
}

config.Clients = Context.clients.forConfig()
config.Clients.Persistent = Context.clients.forConfig()

configFile := config.getConfigFilename()
log.Debug("Writing YAML file: %s", configFile)
Expand Down
17 changes: 11 additions & 6 deletions internal/home/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,10 @@ func initDNSServer() (err error) {
}

Context.rdns = NewRDNS(Context.dnsServer, &Context.clients, config.DNS.UsePrivateRDNS)
Context.whois = initWHOIS(&Context.clients)

if !config.Clients.Srcs.WHOIS {
Context.whois = initWHOIS(&Context.clients)
}

Context.filters.Init()
return nil
Expand All @@ -153,10 +156,11 @@ func onDNSRequest(pctx *proxy.DNSContext) {
return
}

if config.DNS.ResolveClients && !ip.IsLoopback() {
srcs := config.Clients.Srcs
if srcs.RDNS && !ip.IsLoopback() {
Context.rdns.Begin(ip)
}
if !netutil.IsSpecialPurpose(ip) {
if srcs.WHOIS && !netutil.IsSpecialPurpose(ip) {
Context.whois.Begin(ip)
}
}
Expand Down Expand Up @@ -239,7 +243,7 @@ func generateServerConfig() (newConf dnsforward.ServerConfig, err error) {
newConf.FilterHandler = applyAdditionalFiltering
newConf.GetCustomUpstreamByClient = Context.clients.findUpstreams

newConf.ResolveClients = dnsConf.ResolveClients
newConf.ResolveClients = config.Clients.Srcs.RDNS
newConf.UsePrivateRDNS = dnsConf.UsePrivateRDNS
newConf.LocalPTRResolvers = dnsConf.LocalPTRResolvers
newConf.UpstreamTimeout = dnsConf.UpstreamTimeout.Duration
Expand Down Expand Up @@ -387,10 +391,11 @@ func startDNSServer() error {
continue
}

if config.DNS.ResolveClients && !ip.IsLoopback() {
srcs := config.Clients.Srcs
if srcs.RDNS && !ip.IsLoopback() {
Context.rdns.Begin(ip)
}
if !netutil.IsSpecialPurpose(ip) {
if srcs.WHOIS && !netutil.IsSpecialPurpose(ip) {
Context.whois.Begin(ip)
}
}
Expand Down
15 changes: 9 additions & 6 deletions internal/home/home.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,11 @@ func setupContext(args options) {

os.Exit(0)
}

if !args.noEtcHosts && config.Clients.Srcs.HostsFile {
err = setupHostsContainer()
fatalOnError(err)
}
}

Context.mux = http.NewServeMux()
Expand Down Expand Up @@ -285,14 +290,12 @@ func setupConfig(args options) (err error) {
ConfName: config.getConfigFilename(),
})

if !args.noEtcHosts {
if err = setupHostsContainer(); err != nil {
return err
}
var arpdb aghnet.ARPDB
if config.Clients.Srcs.ARP {
arpdb = aghnet.NewARPDB()
}

arpdb := aghnet.NewARPDB()
Context.clients.Init(config.Clients, Context.dhcpServer, Context.etcHosts, arpdb)
Context.clients.Init(config.Clients.Persistent, Context.dhcpServer, Context.etcHosts, arpdb)

if args.bindPort != 0 {
uc := aghalg.UniqChecker{}
Expand Down
12 changes: 9 additions & 3 deletions internal/home/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,19 @@ var helpArg = arg{
}

var noEtcHostsArg = arg{
description: "Do not use the OS-provided hosts.",
description: "Deprecated. Do not use the OS-provided hosts.",
longName: "no-etc-hosts",
shortName: "",
updateWithValue: nil,
updateNoValue: func(o options) (options, error) { o.noEtcHosts = true; return o, nil },
effect: nil,
serialize: func(o options) []string { return boolSliceOrNil(o.noEtcHosts) },
effect: func(_ options, _ string) (f effect, err error) {
log.Info(
"warning: --no-etc-hosts flag is deprecated and will be removed in the future versions",
)

return nil, nil
},
serialize: func(o options) []string { return boolSliceOrNil(o.noEtcHosts) },
}

var localFrontendArg = arg{
Expand Down
69 changes: 67 additions & 2 deletions internal/home/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ import (
)

// currentSchemaVersion is the current schema version.
const currentSchemaVersion = 13
const currentSchemaVersion = 14

// These aliases are provided for convenience.
//
// TODO(e.burkov): Remove any after updating to go1.18.
type (
any = interface{}
yarr = []any
Expand Down Expand Up @@ -86,6 +88,7 @@ func upgradeConfigSchema(oldVersion int, diskConf yobj) (err error) {
upgradeSchema10to11,
upgradeSchema11to12,
upgradeSchema12to13,
upgradeSchema13to14,
}

n := 0
Expand Down Expand Up @@ -726,7 +729,7 @@ func upgradeSchema12to13(diskConf yobj) (err error) {
var dhcp yobj
dhcp, ok = dhcpVal.(yobj)
if !ok {
return fmt.Errorf("unexpected type of dhcp: %T", dnsVal)
return fmt.Errorf("unexpected type of dhcp: %T", dhcpVal)
}

const field = "local_domain_name"
Expand All @@ -737,6 +740,68 @@ func upgradeSchema12to13(diskConf yobj) (err error) {
return nil
}

// upgradeSchema13to14 performs the following changes:
//
// # BEFORE:
// 'clients':
// - name: client-name
// # …
//
// # AFTER:
// 'clients':
// 'persistent':
// - name: client-name
// # …
// 'runtime_sources':
// - whois: true
// - arp: true
// - rdns: true
// - dhcp: true
// - hosts: true
//
func upgradeSchema13to14(diskConf yobj) (err error) {
log.Printf("Upgrade yaml: 13 to 14")
diskConf["schema_version"] = 14

clientsVal, ok := diskConf["clients"]
if !ok {
clientsVal = yarr{}
}

var rdnsSrc bool
if dnsVal, dok := diskConf["dns"]; dok {
var dnsSettings yobj
dnsSettings, ok = dnsVal.(yobj)
if !ok {
return fmt.Errorf("unexpected type of dns: %T", dnsVal)
}

var rdnsSrcVal any
rdnsSrcVal, ok = dnsSettings["resolve_clients"]
if ok {
rdnsSrc, ok = rdnsSrcVal.(bool)
if !ok {
return fmt.Errorf("unexpected type of resolve_clients: %T", rdnsSrcVal)
}

delete(dnsSettings, "resolve_clients")
}
}

diskConf["clients"] = yobj{
"persistent": clientsVal,
"runtime_sources": &clientSourcesConf{
WHOIS: true,
ARP: true,
RDNS: rdnsSrc,
DHCP: true,
HostsFile: true,
},
}

return nil
}

// TODO(a.garipov): Replace with log.Output when we port it to our logging
// package.
func funcName() string {
Expand Down
Loading

0 comments on commit 3f71b99

Please sign in to comment.