Skip to content

Commit 6fb0980

Browse files
committed
Initialize the DNS cache at plugin init time
No need for a lazily-created cache and sync.Once.
1 parent 8775802 commit 6fb0980

3 files changed

Lines changed: 29 additions & 37 deletions

File tree

dnscrypt-proxy/monitoring_ui.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -710,9 +710,9 @@ func (mc *MetricsCollector) collectCacheStats(cacheHitRatio float64, cacheHits,
710710
stats["neg_max_ttl"] = mc.proxy.cacheNegMaxTTL
711711
stats["neg_min_ttl"] = mc.proxy.cacheNegMinTTL
712712

713-
if cachedResponses.cache != nil {
714-
stats["entries"] = cachedResponses.cache.Len()
715-
stats["capacity"] = cachedResponses.cache.Capacity()
713+
if cachedResponses != nil {
714+
stats["entries"] = cachedResponses.Len()
715+
stats["capacity"] = cachedResponses.Capacity()
716716
}
717717

718718
return stats

dnscrypt-proxy/plugin_cache.go

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"crypto/sha512"
55
"encoding/binary"
66
"fmt"
7-
"sync"
87
"time"
98

109
"codeberg.org/miekg/dns"
@@ -18,12 +17,20 @@ type CachedResponse struct {
1817
msg *dns.Msg
1918
}
2019

21-
type CachedResponses struct {
22-
cache *sievecache.ShardedSieveCache[[32]byte, CachedResponse]
23-
cacheOnce sync.Once
24-
}
20+
// cachedResponses is created once, before any goroutine that reads it exists
21+
var cachedResponses *sievecache.ShardedSieveCache[[32]byte, CachedResponse]
2522

26-
var cachedResponses CachedResponses
23+
func initCachedResponses(cacheSize int) error {
24+
if cachedResponses != nil {
25+
return nil
26+
}
27+
cache, err := sievecache.NewSharded[[32]byte, CachedResponse](cacheSize)
28+
if err != nil {
29+
return fmt.Errorf("failed to initialize the cache: %w", err)
30+
}
31+
cachedResponses = cache
32+
return nil
33+
}
2734

2835
func computeCacheKey(pluginsState *PluginsState, msg *dns.Msg) [32]byte {
2936
question := msg.Question[0]
@@ -57,7 +64,7 @@ func (plugin *PluginCache) Description() string {
5764
}
5865

5966
func (plugin *PluginCache) Init(proxy *Proxy) error {
60-
return nil
67+
return initCachedResponses(proxy.cacheSize)
6168
}
6269

6370
func (plugin *PluginCache) Drop() error {
@@ -69,12 +76,11 @@ func (plugin *PluginCache) Reload() error {
6976
}
7077

7178
func (plugin *PluginCache) Eval(pluginsState *PluginsState, msg *dns.Msg) error {
72-
cacheKey := computeCacheKey(pluginsState, msg)
73-
74-
if cachedResponses.cache == nil {
79+
if cachedResponses == nil {
7580
return nil
7681
}
77-
cached, ok := cachedResponses.cache.Get(cacheKey)
82+
cacheKey := computeCacheKey(pluginsState, msg)
83+
cached, ok := cachedResponses.Get(cacheKey)
7884
if !ok {
7985
return nil
8086
}
@@ -113,7 +119,7 @@ func (plugin *PluginCacheResponse) Description() string {
113119
}
114120

115121
func (plugin *PluginCacheResponse) Init(proxy *Proxy) error {
116-
return nil
122+
return initCachedResponses(proxy.cacheSize)
117123
}
118124

119125
func (plugin *PluginCacheResponse) Drop() error {
@@ -131,6 +137,9 @@ func (plugin *PluginCacheResponse) Eval(pluginsState *PluginsState, msg *dns.Msg
131137
if msg.Truncated {
132138
return nil
133139
}
140+
if cachedResponses == nil {
141+
return nil
142+
}
134143
cacheKey := computeCacheKey(pluginsState, msg)
135144
ttl := getMinTTL(
136145
msg,
@@ -139,26 +148,11 @@ func (plugin *PluginCacheResponse) Eval(pluginsState *PluginsState, msg *dns.Msg
139148
pluginsState.cacheNegMinTTL,
140149
pluginsState.cacheNegMaxTTL,
141150
)
142-
cachedResponse := CachedResponse{
143-
expiration: time.Now().Add(ttl),
144-
msg: cloneMsg(msg),
145-
}
146-
var cacheInitError error
147-
cachedResponses.cacheOnce.Do(func() {
148-
cache, err := sievecache.NewSharded[[32]byte, CachedResponse](pluginsState.cacheSize)
149-
if err != nil {
150-
cacheInitError = err
151-
} else {
152-
cachedResponses.cache = cache
153-
}
154-
})
155-
if cacheInitError != nil {
156-
return fmt.Errorf("failed to initialize the cache: %w", cacheInitError)
157-
}
158-
if cachedResponses.cache != nil {
159-
cachedResponses.cache.Insert(cacheKey, cachedResponse)
160-
}
161-
updateTTL(msg, cachedResponse.expiration)
151+
expiration := time.Now().Add(ttl)
152+
cachedMsg := cloneMsg(msg)
153+
cachedMsg.Question = nil
154+
cachedResponses.Insert(cacheKey, CachedResponse{expiration: expiration, msg: cachedMsg})
155+
updateTTL(msg, expiration)
162156

163157
return nil
164158
}

dnscrypt-proxy/plugins.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ type PluginsState struct {
8282
timeout time.Duration
8383
returnCode PluginsReturnCode
8484
maxPayloadSize int
85-
cacheSize int
8685
originalMaxPayloadSize int
8786
maxUnencryptedUDPSafePayloadSize int
8887
rejectTTL uint32
@@ -255,7 +254,6 @@ func NewPluginsState(
255254
maxPayloadSize: MaxDNSUDPPacketSize - ResponseOverhead,
256255
clientProto: clientProto,
257256
clientAddr: clientAddr,
258-
cacheSize: proxy.cacheSize,
259257
cacheNegMinTTL: proxy.cacheNegMinTTL,
260258
cacheNegMaxTTL: proxy.cacheNegMaxTTL,
261259
cacheMinTTL: proxy.cacheMinTTL,

0 commit comments

Comments
 (0)