From ce447e0e16bc9ad3aa14d18ddc4b700f4f372f20 Mon Sep 17 00:00:00 2001 From: Aestek Date: Mon, 4 Mar 2019 15:22:01 +0100 Subject: [PATCH] Fix race condition in DNS when using cache (#5398) * Fix race condition in DNS when using cache The healty node filtering was modifying the result from the cache, which caused a crash when multiple queries were made to the same service simultaneously. We now copy the node slice before filtering to ensure we do not modify the data stored in the cache. * Fix wording in dns cache config doc s/dns_max_age/cache_max_age/ --- agent/dns.go | 5 ++++- website/source/docs/agent/options.html.md | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/agent/dns.go b/agent/dns.go index 83b8b0999..d4464a45b 100644 --- a/agent/dns.go +++ b/agent/dns.go @@ -1100,7 +1100,10 @@ func (d *DNSServer) lookupServiceNodes(datacenter, service, tag string, connect } // Filter out any service nodes due to health checks - out.Nodes = out.Nodes.Filter(d.config.OnlyPassing) + // We copy the slice to avoid modifying the result if it comes from the cache + nodes := make(structs.CheckServiceNodes, len(out.Nodes)) + copy(nodes, out.Nodes) + out.Nodes = nodes.Filter(d.config.OnlyPassing) return out, nil } diff --git a/website/source/docs/agent/options.html.md b/website/source/docs/agent/options.html.md index 18022b62f..21a2fc807 100644 --- a/website/source/docs/agent/options.html.md +++ b/website/source/docs/agent/options.html.md @@ -1078,7 +1078,7 @@ default will automatically work with some tooling. * `use_cache` - When set to true, DNS resolution will use the agent cache described in [agent caching](/api/index.html#agent-caching). This setting affects all service and prepared queries DNS requests. Implies [`allow_stale`](#allow_stale) - * `dns_max_age` - When [use_cache](#dns_use_cache) is enabled, the agent + * `cache_max_age` - When [use_cache](#dns_use_cache) is enabled, the agent will attempt to re-fetch the result from the servers if the cached value is older than this duration. See: [agent caching](/api/index.html#agent-caching). * `domain` Equivalent to the