From 91b975b0dcab02c8e54ea6aa1bf0cb0460bf80f1 Mon Sep 17 00:00:00 2001 From: Dimitri Herzog Date: Sun, 12 Sep 2021 21:17:32 +0200 Subject: [PATCH] Change configuration format for duration (#263) --- config/config.go | 51 ++++++-- config/config_test.go | 68 ++++++++++- docs/config.yml | 17 +-- docs/configuration.md | 182 +++++++++++++++++++++++++++-- docs/includes/abbreviations.md | 4 +- lists/list_cache.go | 6 +- mkdocs.yml | 1 + resolver/blocking_resolver.go | 8 +- resolver/blocking_resolver_test.go | 4 +- resolver/caching_resolver.go | 6 +- resolver/caching_resolver_test.go | 10 +- testdata/config.yml | 4 +- 12 files changed, 311 insertions(+), 50 deletions(-) diff --git a/config/config.go b/config/config.go index cad18a07..93149357 100644 --- a/config/config.go +++ b/config/config.go @@ -10,9 +10,9 @@ import ( "regexp" "strconv" "strings" + "time" "github.com/0xERR0R/blocky/log" - "gopkg.in/yaml.v2" ) @@ -33,6 +33,8 @@ type NetProtocol uint16 // ) type QueryLogType int16 +type Duration time.Duration + const ( validUpstream = `(?P(?:\[[^\]]+\])|[^\s/:]+):?(?P[^\s/:]*)?(?P/[^\s]*)?` ) @@ -127,6 +129,29 @@ func (c *CustomDNSMapping) UnmarshalYAML(unmarshal func(interface{}) error) erro return nil } +// UnmarshalYAML creates Duration from YAML. If no unit is used, uses minutes +func (c *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error { + var input string + if err := unmarshal(&input); err != nil { + return err + } + + if minutes, err := strconv.Atoi(input); err == nil { + // duration is defined as number without unit + // use minutes to ensure back compatibility + *c = Duration(time.Duration(minutes) * time.Minute) + return nil + } + + duration, err := time.ParseDuration(input) + if err == nil { + *c = Duration(duration) + return nil + } + + return err +} + // ParseUpstream creates new Upstream from passed string in format [net]:host[:port][/path] func ParseUpstream(upstream string) (result Upstream, err error) { if strings.TrimSpace(upstream) == "" { @@ -262,8 +287,8 @@ type BlockingConfig struct { WhiteLists map[string][]string `yaml:"whiteLists"` ClientGroupsBlock map[string][]string `yaml:"clientGroupsBlock"` BlockType string `yaml:"blockType"` - BlockTimeSec int `yaml:"blockTTL"` - RefreshPeriod int `yaml:"refreshPeriod"` + BlockTTL Duration `yaml:"blockTTL"` + RefreshPeriod Duration `yaml:"refreshPeriod"` } // ClientLookupConfig configuration for the client lookup @@ -275,13 +300,13 @@ type ClientLookupConfig struct { // CachingConfig configuration for domain caching type CachingConfig struct { - MinCachingTime int `yaml:"minTime"` - MaxCachingTime int `yaml:"maxTime"` - MaxItemsCount int `yaml:"maxItemsCount"` - Prefetching bool `yaml:"prefetching"` - PrefetchExpires int `yaml:"prefetchExpires"` - PrefetchThreshold int `yaml:"prefetchThreshold"` - PrefetchMaxItemsCount int `yaml:"prefetchMaxItemsCount"` + MinCachingTime Duration `yaml:"minTime"` + MaxCachingTime Duration `yaml:"maxTime"` + MaxItemsCount int `yaml:"maxItemsCount"` + Prefetching bool `yaml:"prefetching"` + PrefetchExpires Duration `yaml:"prefetchExpires"` + PrefetchThreshold int `yaml:"prefetchThreshold"` + PrefetchMaxItemsCount int `yaml:"prefetchMaxItemsCount"` } // QueryLogConfig configuration for the query logging @@ -316,7 +341,11 @@ func LoadConfig(path string, mandatory bool) { log.Log().Fatal("Can't read config file: ", err) } - err = yaml.UnmarshalStrict(data, &cfg) + unmarshalConfig(data, cfg) +} + +func unmarshalConfig(data []byte, cfg Config) { + err := yaml.UnmarshalStrict(data, &cfg) if err != nil { log.Log().Fatal("wrong file structure: ", err) } diff --git a/config/config_test.go b/config/config_test.go index 305a2014..69883c0e 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -4,6 +4,7 @@ import ( "io/ioutil" "net" "os" + "time" "github.com/0xERR0R/blocky/helpertest" @@ -41,9 +42,11 @@ var _ = Describe("Config", func() { Expect(config.Blocking.BlackLists).Should(HaveLen(2)) Expect(config.Blocking.WhiteLists).Should(HaveLen(1)) Expect(config.Blocking.ClientGroupsBlock).Should(HaveLen(2)) + Expect(config.Blocking.BlockTTL).Should(Equal(Duration(time.Minute))) + Expect(config.Blocking.RefreshPeriod).Should(Equal(Duration(2 * time.Hour))) - Expect(config.Caching.MaxCachingTime).Should(Equal(0)) - Expect(config.Caching.MinCachingTime).Should(Equal(0)) + Expect(config.Caching.MaxCachingTime).Should(Equal(Duration(0))) + Expect(config.Caching.MinCachingTime).Should(Equal(Duration(0))) Expect(GetConfig()).Should(Not(BeNil())) @@ -65,6 +68,66 @@ var _ = Describe("Config", func() { }) }) }) + When("duration is in wrong format", func() { + It("should log with fatal and exit", func() { + cfg := Config{} + data := + `blocking: + refreshPeriod: wrongduration` + helpertest.ShouldLogFatal(func() { + unmarshalConfig([]byte(data), cfg) + }) + }) + }) + When("CustomDNS hast wrong IP defined", func() { + It("should log with fatal and exit", func() { + cfg := Config{} + data := + `customDNS: + mapping: + someDomain: 192.168.178.WRONG` + helpertest.ShouldLogFatal(func() { + unmarshalConfig([]byte(data), cfg) + }) + }) + }) + When("Conditional mapping hast wrong defined upstreams", func() { + It("should log with fatal and exit", func() { + cfg := Config{} + data := + `conditional: + mapping: + multiple.resolvers: udp:192.168.178.1,wongprotocol:4.4.4.4:53` + helpertest.ShouldLogFatal(func() { + unmarshalConfig([]byte(data), cfg) + }) + }) + }) + When("Wrong upstreams are defined", func() { + It("should log with fatal and exit", func() { + cfg := Config{} + data := + `upstream: + default: + - udp:8.8.8.8 + - wrongprotocol:8.8.4.4 + - udp:1.1.1.1` + helpertest.ShouldLogFatal(func() { + unmarshalConfig([]byte(data), cfg) + }) + }) + }) + + When("config is not YAML", func() { + It("should log with fatal and exit", func() { + cfg := Config{} + data := + `///` + helpertest.ShouldLogFatal(func() { + unmarshalConfig([]byte(data), cfg) + }) + }) + }) When("deprecated querylog.dir parameter is used", func() { It("should be mapped to csv writer", func() { @@ -94,6 +157,7 @@ var _ = Describe("Config", func() { }) }) + When("config directory does not exist", func() { It("should log with fatal and exit if config is mandatory", func() { err := os.Chdir("../..") diff --git a/docs/config.yml b/docs/config.yml index 70e8493f..5c2f4347 100644 --- a/docs/config.yml +++ b/docs/config.yml @@ -70,18 +70,21 @@ blocking: # nxDomain: return NXDOMAIN as return code # comma separated list of destination IP adresses (for example: 192.100.100.15, 2001:0db8:85a3:08d3:1319:8a2e:0370:7344). Should contain ipv4 and ipv6 to cover all query types. Useful with running web server on this address to display the "blocked" page. blockType: zeroIp - # optional: automatically list refresh period in minutes. Default: 4h. + # optional: TTL for answers to blocked domains + # default: 6h + blockTTL: 1m + # optional: automatically list refresh period (in duration format). Default: 4h. # Negative value -> deactivate automatically refresh. # 0 value -> use default - refreshPeriod: 0 + refreshPeriod: 4h # optional: configuration for caching of DNS responses caching: - # amount in minutes, how long a response must be cached (min value). + # duration how long a response must be cached (min value). # If <=0, use response's TTL, if >0 use this value, if TTL is smaller # Default: 0 - minTime: 5 - # amount in minutes, how long a response must be cached (max value). + minTime: 5m + # duration how long a response must be cached (max value). # If <0, do not cache responses # If 0, use TTL # If > 0, use this value, if TTL is greater @@ -94,9 +97,9 @@ caching: # this improves the response time for often used queries, but significantly increases external traffic # default: false prefetching: true - # amount in minutes, prefetch track time window + # prefetch track time window (in duration format) # default: 120 - prefetchExpires: 120 + prefetchExpires: 2h # name queries threshold for prefetch # default: 5 prefetchThreshold: 5 diff --git a/docs/configuration.md b/docs/configuration.md index 273c538a..1e1b3603 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -3,6 +3,163 @@ This chapter describes all configuration options in `config.yaml`. You can download a reference file with all configuration properties as [JSON](config.yml). +??? example "reference configuration file" +```yaml upstream: +# these external DNS resolvers will be used. Blocky picks 2 random resolvers from the list for each query # format for +resolver: [net:]host:[port][/path]. net could be empty (default, shortcut for tcp+udp), tcp+udp, tcp, udp, tcp-tls or +https (DoH). If port is empty, default port will be used (53 for udp and tcp, 853 for tcp-tls, 443 for https (Doh)) +# this configuration is mandatory, please define at least one external DNS resolver default: +- 46.182.19.48 - 80.241.218.68 - tcp-tls:fdns1.dismail.de:853 - https://dns.digitale-gesellschaft.ch/dns-query +# optional: use client name (with wildcard support: * - sequence of any characters, [0-9] - range) +# or single ip address / client subnet as CIDR notation laptop*: +- 123.123.123.123 + + # optional: custom IP address(es) for domain name (with all sub-domains). Multiple addresses must be separated by a comma + # example: query "printer.lan" or "my.printer.lan" will return 192.168.178.3 + customDNS: + mapping: + printer.lan: 192.168.178.3,2001:0db8:85a3:08d3:1319:8a2e:0370:7344 + + # optional: definition, which DNS resolver(s) should be used for queries to the domain (with all sub-domains). Multiple resolvers must be separated by a comma + # Example: Query client.fritz.box will ask DNS server 192.168.178.1. This is necessary for local network, to resolve clients by host name + conditional: + # optional: replace domain in the query with other domain before resover lookup in the mapping + rewrite: + example.com: fritz.box + mapping: + fritz.box: udp:192.168.178.1 + lan.net: udp:192.168.178.1,udp:192.168.178.2 + + # optional: use black and white lists to block queries (for example ads, trackers, adult pages etc.) + blocking: + # definition of blacklist groups. Can be external link (http/https) or local file + blackLists: + ads: + - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt + - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts + - https://mirror1.malwaredomains.com/files/justdomains + - http://sysctl.org/cameleon/hosts + - https://zeustracker.abuse.ch/blocklist.php?download=domainblocklist + - https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt + - | + # inline definition with YAML literal block scalar style + # hosts format + someadsdomain.com + special: + - https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts + # definition of whitelist groups. Attention: if the same group has black and whitelists, whitelists will be used to disable particular blacklist entries. If a group has only whitelist entries -> this means only domains from this list are allowed, all other domains will be blocked + whiteLists: + ads: + - whitelist.txt + - | + # inline definition with YAML literal block scalar style + # hosts format + whitelistdomain.com + # definition: which groups should be applied for which client + clientGroupsBlock: + # default will be used, if no special definition for a client name exists + default: + - ads + - special + # use client name (with wildcard support: * - sequence of any characters, [0-9] - range) + # or single ip address / client subnet as CIDR notation + laptop*: + - ads + 192.168.178.1/24: + - special + # which response will be sent, if query is blocked: + # zeroIp: 0.0.0.0 will be returned (default) + # nxDomain: return NXDOMAIN as return code + # comma separated list of destination IP adresses (for example: 192.100.100.15, 2001:0db8:85a3:08d3:1319:8a2e:0370:7344). Should contain ipv4 and ipv6 to cover all query types. Useful with running web server on this address to display the "blocked" page. + blockType: zeroIp + # optional: TTL for answers to blocked domains + # default: 6h + blockTTL: 1m + # optional: automatically list refresh period (in duration format). Default: 4h. + # Negative value -> deactivate automatically refresh. + # 0 value -> use default + refreshPeriod: 4h + + # optional: configuration for caching of DNS responses + caching: + # duration how long a response must be cached (min value). + # If <=0, use response's TTL, if >0 use this value, if TTL is smaller + # Default: 0 + minTime: 5m + # duration how long a response must be cached (max value). + # If <0, do not cache responses + # If 0, use TTL + # If > 0, use this value, if TTL is greater + # Default: 0 + maxTime: -1 + # Max number of cache entries (responses) to be kept in cache (soft limit). Useful on systems with limited amount of RAM. + # Default (0): unlimited + maxItemsCount: 0 + # if true, will preload DNS results for often used queries (default: names queried more than 5 times in a 2 hour time window) + # this improves the response time for often used queries, but significantly increases external traffic + # default: false + prefetching: true + # prefetch track time window (in duration format) + # default: 120 + prefetchExpires: 2h + # name queries threshold for prefetch + # default: 5 + prefetchThreshold: 5 + # Max number of domains to be kept in cache for prefetching (soft limit). Useful on systems with limited amount of RAM. + # Default (0): unlimited + prefetchMaxItemsCount: 0 + + # optional: configuration of client name resolution + clientLookup: + # optional: this DNS resolver will be used to perform reverse DNS lookup (typically local router) + upstream: udp:192.168.178.1 + # optional: some routers return multiple names for client (host name and user defined name). Define which single name should be used. + # Example: take second name if present, if not take first name + singleNameOrder: + - 2 + - 1 + # optional: custom mapping of client name to IP addresses. Useful if reverse DNS does not work properly or just to have custom client names. + clients: + laptop: + - 192.168.178.29 + # optional: configuration for prometheus metrics endpoint + prometheus: + # enabled if true + enable: true + # url path, optional (default '/metrics') + path: /metrics + + # optional: write query information (question, answer, client, duration etc) to daily csv file + queryLog: + # optional one of: mysql, csv, csv-client. If empty, log to console + type: mysql + # directory (should be mounted as volume in docker) for csv, db connection string for mysql + target: db_user:db_password@tcp(db_host_or_ip:3306)/db_user?charset=utf8mb4&parseTime=True&loc=Local + # if > 0, deletes log files which are older than ... days + logRetentionDays: 7 + + # optional: DNS listener port and bind ip address, default 53 (UDP and TCP). Example: 53, :53, 127.0.0.1:53 + port: 53 + # optional: HTTPS listener port and bind ip address, default empty = no http listener. If > 0, will be used for prometheus metrics, pprof, REST API, DoH... Example: 443, :443, 127.0.0.1:443 + httpPort: 4000 + #httpsPort: 443 + # mandatory, if https port > 0: path to cert and key file for SSL encryption + #httpsCertFile: server.crt + #httpsKeyFile: server.key + # optional: use this DNS server to resolve blacklist urls and upstream DNS servers. Useful if no DNS resolver is configured and blocky needs to resolve a host name. Format net:IP:port, net must be udp or tcp + bootstrapDns: tcp:1.1.1.1 + # optional: Drop all AAAA query if set to true. Default: false + disableIPv6: false + # optional: Log level (one from debug, info, warn, error). Default: info + logLevel: info + # optional: Log format (text or json). Default: text + logFormat: text + # optional: log timestamps. Default: true + logTimestamp: true + # optional: obfuscate log output (replace all alphanumeric characters with *) for user sensitive data like request domains or responses to increase privacy. Default: false + logPrivacy: false + ``` + ## Basic configuration | Parameter | Mandatory | Default value | Description | @@ -270,28 +427,29 @@ default** block type. Server returns 0.0.0.0 (or :: for IPv6) as result for A an ### Block TTL -TTL for answers to blocked domains can be set to customize the time clients ask for those domains again. -This setting only makes sense when `blockType` is set to `nxDomain` or `zeroIP`, and will affect how much time it could take for a client to be able to see the real IP address for a domain after receiving the custom value. +TTL for answers to blocked domains can be set to customize the time (in **duration format**) clients ask for those +domains again. This setting only makes sense when `blockType` is set to `nxDomain` or `zeroIP`, and will affect how much +time it could take for a client to be able to see the real IP address for a domain after receiving the custom value. !!! example ```yaml blocking: blockType: 192.100.100.15, 2001:0db8:85a3:08d3:1319:8a2e:0370:7344 - blockTTL: 10 + blockTTL: 10s ``` ### List refresh period To keep the list cache up-to-date, blocky will periodically download and reload all external lists. Default period is ** -4 hours**. You can configure this by setting the `blocking.refreshPeriod` parameter to a value in **minutes**. Negative -value will deactivate automatically refresh. +4 hours**. You can configure this by setting the `blocking.refreshPeriod` parameter to a value in **duration format**. +Negative value will deactivate automatically refresh. !!! example ```yaml blocking: - refreshPeriod: 60 + refreshPeriod: 60m ``` Refresh every hour. @@ -311,11 +469,13 @@ With following parameters you can tune the caching behavior: | Parameter | Mandatory | Default value | Description | | ----------------------------- | --------- | -------------------| ------------------------------------------------- | -| caching.minTime | no | 0 (use TTL) | Amount in minutes, how long a response must be cached (min value). If <=0, use response's TTL, if >0 use this value, if TTL is smaller | -| caching.maxTime | no | 0 (use TTL) | Amount in minutes, how long a response must be cached (max value). If <0, do not cache responses. If 0, use TTL. If > 0, use this value, if TTL is greater | +| caching.minTime | no | 0 (use TTL) | How long (in **duration +format**) a response must be cached (min value). If <=0, use response's TTL, if >0 use this value, if TTL is smaller | +| caching.maxTime | no | 0 (use TTL) | How long (in **duration +format**) a response must be cached (max value). If <0, do not cache responses. If 0, use TTL. If > 0, use this value, if TTL is greater | | caching.maxItemsCount | no | 0 (unlimited) | Max number of cache entries (responses) to be kept in cache (soft limit). Default (0): unlimited. Useful on systems with limited amount of RAM. | | caching.prefetching | no | false | if true, blocky will preload DNS results for often used queries (default: names queried more than 5 times in a 2 hour time window). Results in cache will be loaded again on their expire (TTL). This improves the response time for often used queries, but significantly increases external traffic. It is recommended to increase "minTime" to reduce the number of prefetch queries to external resolvers. | -| caching.prefetchExpires | no | 120 | Amount in minutes, prefetch track time window +| caching.prefetchExpires | no | 2h | Prefetch track time window (in **duration format**) | caching.prefetchThreshold | no | 5 | Name queries threshold for prefetch | caching.prefetchMaxItemsCount | no | 0 (unlimited) | Max number of domains to be kept in cache for prefetching (soft limit). Default (0): unlimited. Useful on systems with limited amount of RAM. | @@ -323,8 +483,8 @@ With following parameters you can tune the caching behavior: ```yaml caching: - minTime: 5 - maxTime: 30 + minTime: 5m + maxTime: 30m prefetching: true ``` diff --git a/docs/includes/abbreviations.md b/docs/includes/abbreviations.md index 7b73438a..7f579af1 100644 --- a/docs/includes/abbreviations.md +++ b/docs/includes/abbreviations.md @@ -21,4 +21,6 @@ *[SSL]: Secure Sockets Layer *[CSV]: Comma-separated values *[SAMBA]: Server Message Block Protocol (Windows Network File System) -*[DHCP]: Dynamic Host Configuration Protocol \ No newline at end of file +*[DHCP]: Dynamic Host Configuration Protocol +*[duration format]: Example: "300ms", "1.5h" or "2h45m". Valid time units are "ns", "us", "ms", "s", "m", "h". Number +without unit treats as minutes. \ No newline at end of file diff --git a/lists/list_cache.go b/lists/list_cache.go index 28aac12f..40ee51fd 100644 --- a/lists/list_cache.go +++ b/lists/list_cache.go @@ -86,7 +86,7 @@ type ListCache struct { // Configuration returns current configuration and stats func (b *ListCache) Configuration() (result []string) { if b.refreshPeriod > 0 { - result = append(result, fmt.Sprintf("refresh period: %d minutes", b.refreshPeriod/time.Minute)) + result = append(result, fmt.Sprintf("refresh period: %s", b.refreshPeriod)) } else { result = append(result, "refresh: disabled") } @@ -114,10 +114,10 @@ func (b *ListCache) Configuration() (result []string) { } // NewListCache creates new list instance -func NewListCache(t ListCacheType, groupToLinks map[string][]string, refreshPeriod int) *ListCache { +func NewListCache(t ListCacheType, groupToLinks map[string][]string, refreshPeriod time.Duration) *ListCache { groupCaches := make(map[string]stringCache) - p := time.Duration(refreshPeriod) * time.Minute + p := refreshPeriod if refreshPeriod == 0 { p = defaultRefreshPeriod } diff --git a/mkdocs.yml b/mkdocs.yml index 94f07c09..3efa8337 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -23,6 +23,7 @@ markdown_extensions: - pymdownx.highlight - pymdownx.superfences - admonition + - pymdownx.details nav: - 'Welcome': 'index.md' diff --git a/resolver/blocking_resolver.go b/resolver/blocking_resolver.go index 30b8b01e..72b2bc77 100644 --- a/resolver/blocking_resolver.go +++ b/resolver/blocking_resolver.go @@ -82,8 +82,8 @@ type BlockingResolver struct { // NewBlockingResolver returns a new configured instance of the resolver func NewBlockingResolver(cfg config.BlockingConfig) ChainedResolver { blockHandler := createBlockHandler(cfg) - blacklistMatcher := lists.NewListCache(lists.ListCacheTypeBlacklist, cfg.BlackLists, cfg.RefreshPeriod) - whitelistMatcher := lists.NewListCache(lists.ListCacheTypeWhitelist, cfg.WhiteLists, cfg.RefreshPeriod) + blacklistMatcher := lists.NewListCache(lists.ListCacheTypeBlacklist, cfg.BlackLists, time.Duration(cfg.RefreshPeriod)) + whitelistMatcher := lists.NewListCache(lists.ListCacheTypeWhitelist, cfg.WhiteLists, time.Duration(cfg.RefreshPeriod)) whitelistOnlyGroups := determineWhitelistOnlyGroups(&cfg) res := &BlockingResolver{ @@ -454,11 +454,11 @@ func (b ipBlockHandler) handleBlock(question dns.Question, response *dns.Msg) { } func blockTTLFromConfig(cfg config.BlockingConfig) uint32 { - if cfg.BlockTimeSec <= 0 { + if cfg.BlockTTL <= 0 { return defaultBlockTTL } - return uint32(cfg.BlockTimeSec) + return uint32(time.Duration(cfg.BlockTTL).Seconds()) } func blockTypeFromConfig(cfg config.BlockingConfig) string { diff --git a/resolver/blocking_resolver_test.go b/resolver/blocking_resolver_test.go index e893124c..f455f8ad 100644 --- a/resolver/blocking_resolver_test.go +++ b/resolver/blocking_resolver_test.go @@ -246,7 +246,7 @@ badcnamedomain.com`) }) }) - When("BlockTimeSec is set", func() { + When("BlockTTL is set", func() { BeforeEach(func() { sutConfig = config.BlockingConfig{ BlackLists: map[string][]string{ @@ -255,7 +255,7 @@ badcnamedomain.com`) ClientGroupsBlock: map[string][]string{ "default": {"defaultGroup"}, }, - BlockTimeSec: 1234, + BlockTTL: config.Duration(time.Second * 1234), } }) diff --git a/resolver/caching_resolver.go b/resolver/caching_resolver.go index 4f48652a..1578210d 100644 --- a/resolver/caching_resolver.go +++ b/resolver/caching_resolver.go @@ -40,8 +40,8 @@ const ( // NewCachingResolver creates a new resolver instance func NewCachingResolver(cfg config.CachingConfig) ChainedResolver { c := &CachingResolver{ - minCacheTimeSec: 60 * cfg.MinCachingTime, - maxCacheTimeSec: 60 * cfg.MaxCachingTime, + minCacheTimeSec: int(time.Duration(cfg.MinCachingTime).Seconds()), + maxCacheTimeSec: int(time.Duration(cfg.MaxCachingTime).Seconds()), resultCache: createQueryResultCache(&cfg), } @@ -59,7 +59,7 @@ func createQueryResultCache(cfg *config.CachingConfig) *cache.Cache { func configurePrefetching(c *CachingResolver, cfg *config.CachingConfig) { c.prefetchExpires = prefetchingNameCacheExpiration if cfg.PrefetchExpires > 0 { - c.prefetchExpires = time.Duration(cfg.PrefetchExpires) * time.Minute + c.prefetchExpires = time.Duration(cfg.PrefetchExpires) } c.prefetchThreshold = prefetchingNameCountThreshold diff --git a/resolver/caching_resolver_test.go b/resolver/caching_resolver_test.go index eef39d4a..4de43c12 100644 --- a/resolver/caching_resolver_test.go +++ b/resolver/caching_resolver_test.go @@ -49,7 +49,7 @@ var _ = Describe("CachingResolver", func() { BeforeEach(func() { sutConfig = config.CachingConfig{ Prefetching: true, - PrefetchExpires: 120, + PrefetchExpires: config.Duration(time.Minute * 120), PrefetchThreshold: 5, } }) @@ -102,7 +102,7 @@ var _ = Describe("CachingResolver", func() { When("min caching time is defined", func() { BeforeEach(func() { sutConfig = config.CachingConfig{ - MinCachingTime: 5, + MinCachingTime: config.Duration(time.Minute * 5), } }) Context("response TTL is bigger than defined min caching time", func() { @@ -232,7 +232,7 @@ var _ = Describe("CachingResolver", func() { Context("max caching time is negative -> caching is disabled", func() { BeforeEach(func() { sutConfig = config.CachingConfig{ - MaxCachingTime: -1, + MaxCachingTime: config.Duration(time.Minute * -1), } }) @@ -265,7 +265,7 @@ var _ = Describe("CachingResolver", func() { Context("max caching time is positive", func() { BeforeEach(func() { sutConfig = config.CachingConfig{ - MaxCachingTime: 4, + MaxCachingTime: config.Duration(time.Minute * 4), } }) It("should cache response and use max caching time as TTL if response TTL is bigger", func() { @@ -369,7 +369,7 @@ var _ = Describe("CachingResolver", func() { When("resolver is disabled", func() { BeforeEach(func() { sutConfig = config.CachingConfig{ - MaxCachingTime: -1, + MaxCachingTime: config.Duration(time.Minute * -1), } }) It("should return 'disabled''", func() { diff --git a/testdata/config.yml b/testdata/config.yml index 3dae9906..511cbe22 100644 --- a/testdata/config.yml +++ b/testdata/config.yml @@ -31,7 +31,9 @@ blocking: - special Laptop-D.fritz.box: - ads - #blockMode: zeroIP + blockTTL: 1m + # without unit -> use minutes + refreshPeriod: 120 clientLookup: upstream: udp:192.168.178.1 singleNameOrder: