Pull request: 2145 optimistic cache

Updates #2145.

Squashed commit of the following:

commit 0c15347f4573252849817f27f290c0d45381454c
Merge: 98bd3b89 ebade2b6
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 14 20:44:58 2021 +0300

    Merge branch 'master' into 2145-optimistic-cache

commit 98bd3b895e0d881d5234f674b54f9fa7847dc8f0
Author: Ildar Kamalov <ik@adguard.com>
Date:   Wed Jul 14 13:12:56 2021 +0300

    client: handle optimistic cache

commit 0b469b72ffd43d736dbf139e7d47b23b9fa877c5
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Jul 1 19:01:01 2021 +0300

    openapi: fix log of changes

commit f1594e7f7567e0278b08025a8e4da901ef330602
Merge: a034eb98 e113b276
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Jul 1 18:53:01 2021 +0300

    Merge branch 'master' into 2145-optimistic-cache

commit a034eb98bafdca90befad7dfb6a9b0e4c939c879
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Jun 29 18:45:28 2021 +0300

    dnsforward: fix tests

commit c72227f83c849714721c3512beeb9d1b800a7225
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Jun 29 18:33:12 2021 +0300

    openapi: imp docs

commit 35fe0d2a8c98d007b8ac48653c18d10d52e72dce
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Mon Jun 28 14:19:46 2021 +0300

    dnsforward: add optimistic cache
This commit is contained in:
Ainar Garipov 2021-07-14 21:03:56 +03:00
parent ebade2b6ce
commit b9e85695db
11 changed files with 86 additions and 25 deletions

View File

@ -10,11 +10,12 @@ and this project adheres to
## [Unreleased] ## [Unreleased]
<!-- <!--
## [v0.107.0] - 2021-06-28 (APPROX.) ## [v0.107.0] - 2021-08-03 (APPROX.)
--> -->
### Added ### Added
- Optimistic cache ([#2145]).
- New possible value of `6h` for `querylog_interval` setting ([#2504]). - New possible value of `6h` for `querylog_interval` setting ([#2504]).
- Blocking access using client IDs ([#2624], [#3162]). - Blocking access using client IDs ([#2624], [#3162]).
- `source` directives support in `/etc/network/interfaces` on Linux ([#3257]). - `source` directives support in `/etc/network/interfaces` on Linux ([#3257]).
@ -53,11 +54,6 @@ and this project adheres to
### Deprecated ### Deprecated
<!--
TODO(a.garipov): Remove the Go 1.16 deprecation message if Go 1.17 is not
released by then.
-->
- Go 1.16 support. v0.108.0 will require at least Go 1.17 to build. - Go 1.16 support. v0.108.0 will require at least Go 1.17 to build.
### Fixed ### Fixed
@ -83,6 +79,7 @@ released by then.
[#1381]: https://github.com/AdguardTeam/AdGuardHome/issues/1381 [#1381]: https://github.com/AdguardTeam/AdGuardHome/issues/1381
[#1691]: https://github.com/AdguardTeam/AdGuardHome/issues/1691 [#1691]: https://github.com/AdguardTeam/AdGuardHome/issues/1691
[#2141]: https://github.com/AdguardTeam/AdGuardHome/issues/2141 [#2141]: https://github.com/AdguardTeam/AdGuardHome/issues/2141
[#2145]: https://github.com/AdguardTeam/AdGuardHome/issues/2145
[#2280]: https://github.com/AdguardTeam/AdGuardHome/issues/2280 [#2280]: https://github.com/AdguardTeam/AdGuardHome/issues/2280
[#2439]: https://github.com/AdguardTeam/AdGuardHome/issues/2439 [#2439]: https://github.com/AdguardTeam/AdGuardHome/issues/2439
[#2441]: https://github.com/AdguardTeam/AdGuardHome/issues/2441 [#2441]: https://github.com/AdguardTeam/AdGuardHome/issues/2441

View File

@ -597,6 +597,8 @@
"cache_ttl_min_override_desc": "Extend short time-to-live values (seconds) received from the upstream server when caching DNS responses", "cache_ttl_min_override_desc": "Extend short time-to-live values (seconds) received from the upstream server when caching DNS responses",
"cache_ttl_max_override_desc": "Set a maximum time-to-live value (seconds) for entries in the DNS cache", "cache_ttl_max_override_desc": "Set a maximum time-to-live value (seconds) for entries in the DNS cache",
"ttl_cache_validation": "Minimum cache TTL value must be less than or equal to the maximum value", "ttl_cache_validation": "Minimum cache TTL value must be less than or equal to the maximum value",
"cache_optimistic": "Optimistic",
"cache_optimistic_desc": "Make AdGuard Home respond from the cache even when the entries are expired and also try to refresh them.",
"filter_category_general": "General", "filter_category_general": "General",
"filter_category_security": "Security", "filter_category_security": "Security",
"filter_category_regional": "Regional", "filter_category_regional": "Regional",

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { Field, reduxForm } from 'redux-form'; import { Field, reduxForm } from 'redux-form';
import { Trans, useTranslation } from 'react-i18next'; import { Trans, useTranslation } from 'react-i18next';
import { shallowEqual, useSelector } from 'react-redux'; import { shallowEqual, useSelector } from 'react-redux';
import { renderInputField, toNumber } from '../../../../helpers/form'; import { renderInputField, toNumber, CheckboxField } from '../../../../helpers/form';
import { CACHE_CONFIG_FIELDS, FORM_NAME, UINT32_RANGE } from '../../../../helpers/constants'; import { CACHE_CONFIG_FIELDS, FORM_NAME, UINT32_RANGE } from '../../../../helpers/constants';
import { replaceZeroWithEmptyString } from '../../../../helpers/helpers'; import { replaceZeroWithEmptyString } from '../../../../helpers/helpers';
@ -47,27 +47,48 @@ const Form = ({
}) => <div className="col-12" key={name}> }) => <div className="col-12" key={name}>
<div className="col-12 col-md-7 p-0"> <div className="col-12 col-md-7 p-0">
<div className="form__group form__group--settings"> <div className="form__group form__group--settings">
<label htmlFor={name} <label
className="form__label form__label--with-desc">{t(title)}</label> htmlFor={name}
className="form__label form__label--with-desc"
>
{t(title)}
</label>
<div className="form__desc form__desc--top">{t(description)}</div> <div className="form__desc form__desc--top">{t(description)}</div>
<Field <Field
name={name} name={name}
type="number" type="number"
component={renderInputField} component={renderInputField}
placeholder={t(placeholder)} placeholder={t(placeholder)}
disabled={processingSetConfig} disabled={processingSetConfig}
className="form-control" className="form-control"
validate={validate} validate={validate}
normalizeOnBlur={replaceZeroWithEmptyString} normalizeOnBlur={replaceZeroWithEmptyString}
normalize={toNumber} normalize={toNumber}
min={min} min={min}
max={max} max={max}
/> />
</div> </div>
</div> </div>
</div>)} </div>)}
{minExceedsMax {minExceedsMax && (
&& <span className="text-danger pl-3 pb-3">{t('ttl_cache_validation')}</span>} <span className="text-danger pl-3 pb-3">
{t('ttl_cache_validation')}
</span>
)}
</div>
<div className="row">
<div className="col-12 col-md-7">
<div className="form__group form__group--settings">
<Field
name="cache_optimistic"
type="checkbox"
component={CheckboxField}
placeholder={t('cache_optimistic')}
disabled={processingSetConfig}
subtitle={t('cache_optimistic_desc')}
/>
</div>
</div>
</div> </div>
<button <button
type="submit" type="submit"

View File

@ -10,7 +10,7 @@ const CacheConfig = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const dispatch = useDispatch(); const dispatch = useDispatch();
const { const {
cache_size, cache_ttl_max, cache_ttl_min, cache_size, cache_ttl_max, cache_ttl_min, cache_optimistic,
} = useSelector((state) => state.dnsConfig, shallowEqual); } = useSelector((state) => state.dnsConfig, shallowEqual);
const handleFormSubmit = (values) => { const handleFormSubmit = (values) => {
@ -31,6 +31,7 @@ const CacheConfig = () => {
cache_size: replaceZeroWithEmptyString(cache_size), cache_size: replaceZeroWithEmptyString(cache_size),
cache_ttl_max: replaceZeroWithEmptyString(cache_ttl_max), cache_ttl_max: replaceZeroWithEmptyString(cache_ttl_max),
cache_ttl_min: replaceZeroWithEmptyString(cache_ttl_min), cache_ttl_min: replaceZeroWithEmptyString(cache_ttl_min),
cache_optimistic,
}} }}
onSubmit={handleFormSubmit} onSubmit={handleFormSubmit}
/> />

View File

@ -101,6 +101,8 @@ type FilteringConfig struct {
CacheSize uint32 `yaml:"cache_size"` // DNS cache size (in bytes) CacheSize uint32 `yaml:"cache_size"` // DNS cache size (in bytes)
CacheMinTTL uint32 `yaml:"cache_ttl_min"` // override TTL value (minimum) received from upstream server CacheMinTTL uint32 `yaml:"cache_ttl_min"` // override TTL value (minimum) received from upstream server
CacheMaxTTL uint32 `yaml:"cache_ttl_max"` // override TTL value (maximum) received from upstream server CacheMaxTTL uint32 `yaml:"cache_ttl_max"` // override TTL value (maximum) received from upstream server
// CacheOptimistic defines if optimistic cache mechanism should be used.
CacheOptimistic bool `yaml:"cache_optimistic"`
// Other settings // Other settings
// -- // --
@ -210,6 +212,7 @@ func (s *Server) createProxyConfig() (proxy.Config, error) {
RefuseAny: s.conf.RefuseAny, RefuseAny: s.conf.RefuseAny,
CacheMinTTL: s.conf.CacheMinTTL, CacheMinTTL: s.conf.CacheMinTTL,
CacheMaxTTL: s.conf.CacheMaxTTL, CacheMaxTTL: s.conf.CacheMaxTTL,
CacheOptimistic: s.conf.CacheOptimistic,
UpstreamConfig: s.conf.UpstreamConfig, UpstreamConfig: s.conf.UpstreamConfig,
BeforeRequestHandler: s.beforeRequestHandler, BeforeRequestHandler: s.beforeRequestHandler,
RequestHandler: s.handleDNSRequest, RequestHandler: s.handleDNSRequest,

View File

@ -41,6 +41,7 @@ type dnsConfig struct {
CacheSize *uint32 `json:"cache_size"` CacheSize *uint32 `json:"cache_size"`
CacheMinTTL *uint32 `json:"cache_ttl_min"` CacheMinTTL *uint32 `json:"cache_ttl_min"`
CacheMaxTTL *uint32 `json:"cache_ttl_max"` CacheMaxTTL *uint32 `json:"cache_ttl_max"`
CacheOptimistic *bool `json:"cache_optimistic"`
ResolveClients *bool `json:"resolve_clients"` ResolveClients *bool `json:"resolve_clients"`
UsePrivateRDNS *bool `json:"use_private_ptr_resolvers"` UsePrivateRDNS *bool `json:"use_private_ptr_resolvers"`
LocalPTRUpstreams *[]string `json:"local_ptr_upstreams"` LocalPTRUpstreams *[]string `json:"local_ptr_upstreams"`
@ -64,6 +65,7 @@ func (s *Server) getDNSConfig() dnsConfig {
cacheSize := s.conf.CacheSize cacheSize := s.conf.CacheSize
cacheMinTTL := s.conf.CacheMinTTL cacheMinTTL := s.conf.CacheMinTTL
cacheMaxTTL := s.conf.CacheMaxTTL cacheMaxTTL := s.conf.CacheMaxTTL
cacheOptimistic := s.conf.CacheOptimistic
resolveClients := s.conf.ResolveClients resolveClients := s.conf.ResolveClients
usePrivateRDNS := s.conf.UsePrivateRDNS usePrivateRDNS := s.conf.UsePrivateRDNS
localPTRUpstreams := aghstrings.CloneSliceOrEmpty(s.conf.LocalPTRResolvers) localPTRUpstreams := aghstrings.CloneSliceOrEmpty(s.conf.LocalPTRResolvers)
@ -89,6 +91,7 @@ func (s *Server) getDNSConfig() dnsConfig {
CacheSize: &cacheSize, CacheSize: &cacheSize,
CacheMinTTL: &cacheMinTTL, CacheMinTTL: &cacheMinTTL,
CacheMaxTTL: &cacheMaxTTL, CacheMaxTTL: &cacheMaxTTL,
CacheOptimistic: &cacheOptimistic,
UpstreamMode: &upstreamMode, UpstreamMode: &upstreamMode,
ResolveClients: &resolveClients, ResolveClients: &resolveClients,
UsePrivateRDNS: &usePrivateRDNS, UsePrivateRDNS: &usePrivateRDNS,
@ -283,6 +286,11 @@ func (s *Server) setConfigRestartable(dc dnsConfig) (restart bool) {
restart = true restart = true
} }
if dc.CacheOptimistic != nil {
s.conf.CacheOptimistic = *dc.CacheOptimistic
restart = true
}
return restart return restart
} }

View File

@ -48,7 +48,7 @@ func loadTestData(t *testing.T, casesFileName string, cases interface{}) {
const jsonExt = ".json" const jsonExt = ".json"
func TestDNSForwardHTTTP_handleGetConfig(t *testing.T) { func TestDNSForwardHTTP_handleGetConfig(t *testing.T) {
filterConf := &filtering.Config{ filterConf := &filtering.Config{
SafeBrowsingEnabled: true, SafeBrowsingEnabled: true,
SafeBrowsingCacheSize: 1000, SafeBrowsingCacheSize: 1000,
@ -123,7 +123,7 @@ func TestDNSForwardHTTTP_handleGetConfig(t *testing.T) {
} }
} }
func TestDNSForwardHTTTP_handleSetConfig(t *testing.T) { func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
filterConf := &filtering.Config{ filterConf := &filtering.Config{
SafeBrowsingEnabled: true, SafeBrowsingEnabled: true,
SafeBrowsingCacheSize: 1000, SafeBrowsingCacheSize: 1000,

View File

@ -23,6 +23,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []
@ -51,6 +52,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []
@ -79,6 +81,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []

View File

@ -30,6 +30,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []
@ -62,6 +63,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []
@ -95,6 +97,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []
@ -128,6 +131,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []
@ -161,6 +165,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []
@ -194,6 +199,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []
@ -227,6 +233,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []
@ -260,6 +267,7 @@
"cache_size": 1024, "cache_size": 1024,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []
@ -293,6 +301,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []
@ -326,6 +335,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []
@ -361,6 +371,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []
@ -396,6 +407,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []
@ -430,6 +442,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []
@ -463,6 +476,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []
@ -498,6 +512,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [ "local_ptr_upstreams": [
@ -533,6 +548,7 @@
"cache_size": 0, "cache_size": 0,
"cache_ttl_min": 0, "cache_ttl_min": 0,
"cache_ttl_max": 0, "cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false, "resolve_clients": false,
"use_private_ptr_resolvers": false, "use_private_ptr_resolvers": false,
"local_ptr_upstreams": [] "local_ptr_upstreams": []

View File

@ -4,6 +4,14 @@
## v0.107: API changes ## v0.107: API changes
### The new field `"cache_optimistic"` in DNS configuration
* The new optional field `"cache_optimistic"` in `POST /control/dns_config`
method makes AdGuard Home use or not use the optimistic cache mechanism.
* The new field `"cache_optimistic"` in `GET /control/dns_info` method is true
if AdGuard Home uses the optimistic cache mechanism.
### New possible value of `"interval"` field in `QueryLogConfig` ### New possible value of `"interval"` field in `QueryLogConfig`
* The value of `"interval"` field in `POST /control/querylog_config` and `GET * The value of `"interval"` field in `POST /control/querylog_config` and `GET

View File

@ -1322,6 +1322,8 @@
'type': 'integer' 'type': 'integer'
'cache_ttl_max': 'cache_ttl_max':
'type': 'integer' 'type': 'integer'
'cache_optimistic':
'type': 'boolean'
'upstream_mode': 'upstream_mode':
'enum': 'enum':
- '' - ''