Skip to content

Commit

Permalink
Merge branch 'master' into 6570-querylog-size-memory
Browse files Browse the repository at this point in the history
  • Loading branch information
schzhn committed Dec 28, 2023
2 parents 5f7d205 + 94d437d commit 1cb404c
Show file tree
Hide file tree
Showing 15 changed files with 325 additions and 186 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ NOTE: Add new changes BELOW THIS COMMENT.

### Added

- Etc timezones to the timezone list ([#6568]).
- The schema version of the configuration file to the output of running
`AdGuardHome` (or `AdGuardHome.exe) with `-v --version` command-line options
([#6545]).
Expand All @@ -34,11 +35,13 @@ NOTE: Add new changes BELOW THIS COMMENT.
### Changed

- The field `"upstream_mode"` in `POST /control/dns_config` and
`GET /control/dns_info` HTTP APIs now accepts `load_balance` value. Check
`GET /control/dns_info` HTTP APIs now accepts `load_balance` value. Check
`openapi/CHANGELOG.md` for more details.

#### Configuration changes

- The new property `clients.persistent.*.uid`, which is unique identifier of the
persistent client.
- The properties `dns.'all_servers` and `dns.fastest_addr` were removed, their
values migrated to newly added field `dns.upstream_mode` that describes the
logic through which upstreams will be used.
Expand All @@ -59,6 +62,9 @@ NOTE: Add new changes BELOW THIS COMMENT.
### Fixed
- Zero value in `querylog.size_memory` disables logging ([#6570]).
- Non-anonymized IP addresses on the dashboard ([#6584]).
- Maximum cache TTL requirement when editing minimum cache TTL in the Web UI
([#6409]).
- Load balancing algorithm stuck on a single server ([#6480]).
- Statistics for 7 days displayed as 168 hours on the dashboard.
- Pre-filling the Edit static lease window with data ([#6534]).
Expand All @@ -68,11 +74,14 @@ NOTE: Add new changes BELOW THIS COMMENT.
work on iOS ([#6352]).

[#6352]: https://github.com/AdguardTeam/AdGuardHome/issues/6352
[#6409]: https://github.com/AdguardTeam/AdGuardHome/issues/6409
[#6480]: https://github.com/AdguardTeam/AdGuardHome/issues/6480
[#6534]: https://github.com/AdguardTeam/AdGuardHome/issues/6534
[#6541]: https://github.com/AdguardTeam/AdGuardHome/issues/6541
[#6545]: https://github.com/AdguardTeam/AdGuardHome/issues/6545
[#6568]: https://github.com/AdguardTeam/AdGuardHome/issues/6568
[#6570]: https://github.com/AdguardTeam/AdGuardHome/issues/6570
[#6584]: https://github.com/AdguardTeam/AdGuardHome/issues/6584

<!--
NOTE: Add new changes ABOVE THIS COMMENT.
Expand Down
26 changes: 15 additions & 11 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@nivo/line": "^0.64.0",
"axios": "^0.19.2",
"classnames": "^2.2.6",
"countries-and-timezones": "^3.6.0",
"date-fns": "^1.29.0",
"i18next": "^19.6.2",
"i18next-browser-languagedetector": "^4.2.0",
Expand All @@ -42,7 +43,6 @@
"redux-actions": "^2.6.5",
"redux-form": "^8.3.5",
"redux-thunk": "^2.3.0",
"timezones-list": "^3.0.2",
"url-polyfill": "^1.1.9"
},
"devDependencies": {
Expand Down
10 changes: 6 additions & 4 deletions client/src/components/Filters/Services/ScheduleForm/Timezone.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import timezones from 'timezones-list';
import ct from 'countries-and-timezones';
import { useTranslation } from 'react-i18next';
import PropTypes from 'prop-types';

Expand All @@ -15,6 +15,8 @@ export const Timezone = ({
setTimezone(event.target.value);
};

const timezones = ct.getAllTimezones();

return (
<div className="schedule__timezone">
<label className="form__label form__label--with-desc mb-2">
Expand All @@ -30,9 +32,9 @@ export const Timezone = ({
{t('schedule_timezone')}
</option>
{/* TODO: get timezones from backend method when the method is ready */}
{timezones.map((zone) => (
<option key={zone.name} value={zone.tzCode}>
{zone.label}
{Object.keys(timezones).map((zone) => (
<option key={zone} value={zone}>
{zone} (GMT{timezones[zone].utcOffsetStr})
</option>
))}
</select>
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/Settings/Dns/Cache/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const Form = ({
cache_ttl_max, cache_ttl_min,
} = useSelector((state) => state.form[FORM_NAME.CACHE].values, shallowEqual);

const minExceedsMax = cache_ttl_min > cache_ttl_max;
const minExceedsMax = cache_ttl_min > 0 && cache_ttl_max > 0 && cache_ttl_min > cache_ttl_max;

const handleClearCache = () => {
if (window.confirm(t('confirm_dns_cache_clear'))) {
Expand Down
52 changes: 47 additions & 5 deletions internal/dnsforward/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,11 +329,6 @@ func (s *Server) newProxyConfig() (conf *proxy.Config, err error) {
conf.EDNSAddr = net.IP(srvConf.EDNSClientSubnet.CustomIP.AsSlice())
}

if srvConf.CacheSize != 0 {
conf.CacheEnabled = true
conf.CacheSizeBytes = int(srvConf.CacheSize)
}

err = setProxyUpstreamMode(conf, srvConf.UpstreamMode, srvConf.FastestTimeout.Duration)
if err != nil {
return nil, fmt.Errorf("upstream mode: %w", err)
Expand Down Expand Up @@ -365,6 +360,37 @@ func (s *Server) newProxyConfig() (conf *proxy.Config, err error) {
return nil, errors.Error("no default upstream servers configured")
}

conf, err = prepareCacheConfig(conf,
srvConf.CacheSize,
srvConf.CacheMinTTL,
srvConf.CacheMaxTTL,
)
if err != nil {
// Don't wrap the error since it's informative enough as is.
return nil, err
}

return conf, nil
}

// prepareCacheConfig prepares the cache configuration and returns an error if
// there is one.
func prepareCacheConfig(
conf *proxy.Config,
size uint32,
minTTL uint32,
maxTTL uint32,
) (prepared *proxy.Config, err error) {
if size != 0 {
conf.CacheEnabled = true
conf.CacheSizeBytes = int(size)
}

err = validateCacheTTL(minTTL, maxTTL)
if err != nil {
return nil, fmt.Errorf("validating cache ttl: %w", err)
}

return conf, nil
}

Expand Down Expand Up @@ -743,3 +769,19 @@ func (s *Server) enableProtectionAfterPause() {

log.Info("dns: protection is restarted after pause")
}

// validateCacheTTL returns an error if the configuration of the cache TTL
// invalid.
//
// TODO(s.chzhen): Move to dnsproxy.
func validateCacheTTL(minTTL, maxTTL uint32) (err error) {
if minTTL == 0 && maxTTL == 0 {
return nil
}

if maxTTL > 0 && minTTL > maxTTL {
return errors.Error("cache_ttl_min must be less than or equal to cache_ttl_max")
}

return nil
}
7 changes: 2 additions & 5 deletions internal/dnsforward/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,15 +378,12 @@ func (req *jsonDNSConfig) checkCacheTTL() (err error) {
if req.CacheMinTTL != nil {
minTTL = *req.CacheMinTTL
}

if req.CacheMaxTTL != nil {
maxTTL = *req.CacheMaxTTL
}

if minTTL <= maxTTL {
return nil
}

return errors.Error("cache_ttl_min must be less or equal than cache_ttl_max")
return validateCacheTTL(minTTL, maxTTL)
}

// checkRatelimitSubnetMaskLen returns an error if the length of the subnet mask
Expand Down
2 changes: 1 addition & 1 deletion internal/dnsforward/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
`ParseAddr("a"): unable to parse IP`,
}, {
name: "cache_bad_ttl",
wantSet: `validating dns config: cache_ttl_min must be less or equal than cache_ttl_max`,
wantSet: `validating dns config: cache_ttl_min must be less than or equal to cache_ttl_max`,
}, {
name: "upstream_mode_bad",
wantSet: `validating dns config: upstream_mode: incorrect value "somethingelse"`,
Expand Down
4 changes: 2 additions & 2 deletions internal/dnsforward/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ func (s *Server) processQueryLogsAndStats(dctx *dnsContext) (rc resultCode) {

ip := pctx.Addr.Addr().AsSlice()
s.anonymizer.Load()(ip)
ipStr := net.IP(ip).String()

log.Debug("dnsforward: client ip for stats and querylog: %s", ip)
log.Debug("dnsforward: client ip for stats and querylog: %s", ipStr)

ipStr := pctx.Addr.Addr().String()
ids := []string{ipStr, dctx.clientID}
qt, cl := q.Qtype, q.Qclass

Expand Down
42 changes: 37 additions & 5 deletions internal/home/client.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,46 @@
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"
"github.com/google/uuid"
)

// Client contains information about persistent clients.
type Client struct {
// UID is the type for the unique IDs of persistent clients.
type UID uuid.UUID

// NewUID returns a new persistent client UID. Any error returned is an error
// from the cryptographic randomness reader.
func NewUID() (uid UID, err error) {
uuidv7, err := uuid.NewV7()

return UID(uuidv7), err
}

// type check
var _ encoding.TextMarshaler = UID{}

// MarshalText implements the [encoding.TextMarshaler] for UID.
func (uid UID) MarshalText() ([]byte, error) {
return uuid.UUID(uid).MarshalText()
}

// type check
var _ encoding.TextUnmarshaler = (*UID)(nil)

// UnmarshalText implements the [encoding.TextUnmarshaler] interface for UID.
func (uid *UID) UnmarshalText(data []byte) error {
return (*uuid.UUID)(uid).UnmarshalText(data)
}

// persistentClient contains information about persistent clients.
type persistentClient 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
Expand All @@ -31,6 +60,9 @@ type Client struct {
Tags []string
Upstreams []string

// UID is the unique identifier of the persistent client.
UID UID

UpstreamsCacheSize uint32
UpstreamsCacheEnabled bool

Expand All @@ -45,7 +77,7 @@ type Client struct {

// 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) {
func (c *persistentClient) ShallowClone() (sh *persistentClient) {
clone := *c

clone.BlockedServices = c.BlockedServices.Clone()
Expand All @@ -57,7 +89,7 @@ func (c *Client) ShallowClone() (sh *Client) {
}

// closeUpstreams closes the client-specific upstream config of c if any.
func (c *Client) closeUpstreams() (err error) {
func (c *persistentClient) closeUpstreams() (err error) {
if c.upstreamConfig != nil {
if err = c.upstreamConfig.Close(); err != nil {
return fmt.Errorf("closing upstreams of client %q: %w", c.Name, err)
Expand All @@ -68,7 +100,7 @@ func (c *Client) closeUpstreams() (err error) {
}

// setSafeSearch initializes and sets the safe search filter for this client.
func (c *Client) setSafeSearch(
func (c *persistentClient) setSafeSearch(
conf filtering.SafeSearchConfig,
cacheSize uint,
cacheTTL time.Duration,
Expand Down
Loading

0 comments on commit 1cb404c

Please sign in to comment.