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
2835func computeCacheKey (pluginsState * PluginsState , msg * dns.Msg ) [32 ]byte {
2936 question := msg .Question [0 ]
@@ -57,7 +64,7 @@ func (plugin *PluginCache) Description() string {
5764}
5865
5966func (plugin * PluginCache ) Init (proxy * Proxy ) error {
60- return nil
67+ return initCachedResponses ( proxy . cacheSize )
6168}
6269
6370func (plugin * PluginCache ) Drop () error {
@@ -69,12 +76,11 @@ func (plugin *PluginCache) Reload() error {
6976}
7077
7178func (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
115121func (plugin * PluginCacheResponse ) Init (proxy * Proxy ) error {
116- return nil
122+ return initCachedResponses ( proxy . cacheSize )
117123}
118124
119125func (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}
0 commit comments