Skip to content

Commit d943aba

Browse files
committed
Fix possible race conditions
1 parent c9870a8 commit d943aba

3 files changed

Lines changed: 26 additions & 7 deletions

File tree

dnscrypt-proxy/common.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"os"
99
"strconv"
1010
"strings"
11+
"sync"
1112
"unicode"
1213
)
1314

@@ -40,6 +41,7 @@ var (
4041
var (
4142
FileDescriptors = make([]*os.File, 0)
4243
FileDescriptorNum = uintptr(0)
44+
FileDescriptorsMu sync.Mutex
4345
)
4446

4547
const (

dnscrypt-proxy/plugin_cache.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package main
33
import (
44
"crypto/sha512"
55
"encoding/binary"
6-
"fmt"
6+
"sync"
77
"time"
88

99
"github.com/jedisct1/go-sieve-cache/pkg/sievecache"
@@ -18,7 +18,9 @@ type CachedResponse struct {
1818
}
1919

2020
type CachedResponses struct {
21-
cache *sievecache.ShardedSieveCache[[32]byte, CachedResponse]
21+
cache *sievecache.ShardedSieveCache[[32]byte, CachedResponse]
22+
cacheMu sync.Mutex
23+
cacheOnce sync.Once
2224
}
2325

2426
var cachedResponses CachedResponses
@@ -142,14 +144,15 @@ func (plugin *PluginCacheResponse) Eval(pluginsState *PluginsState, msg *dns.Msg
142144
expiration: time.Now().Add(ttl),
143145
msg: *msg,
144146
}
145-
if cachedResponses.cache == nil {
147+
cachedResponses.cacheOnce.Do(func() {
146148
cache, err := sievecache.NewSharded[[32]byte, CachedResponse](pluginsState.cacheSize)
147-
if err != nil {
148-
return fmt.Errorf("failed to initialize the cache: %w", err)
149+
if err == nil {
150+
cachedResponses.cache = cache
149151
}
150-
cachedResponses.cache = cache
152+
})
153+
if cachedResponses.cache != nil {
154+
cachedResponses.cache.Insert(cacheKey, cachedResponse)
151155
}
152-
cachedResponses.cache.Insert(cacheKey, cachedResponse)
153156
updateTTL(msg, cachedResponse.expiration)
154157

155158
return nil

dnscrypt-proxy/proxy.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"os"
99
"runtime"
1010
"strings"
11+
"sync"
1112
"sync/atomic"
1213
"time"
1314

@@ -104,18 +105,25 @@ type Proxy struct {
104105
SourceDNSCrypt bool
105106
SourceDoH bool
106107
SourceODoH bool
108+
listenersMu sync.Mutex
107109
}
108110

109111
func (proxy *Proxy) registerUDPListener(conn *net.UDPConn) {
112+
proxy.listenersMu.Lock()
110113
proxy.udpListeners = append(proxy.udpListeners, conn)
114+
proxy.listenersMu.Unlock()
111115
}
112116

113117
func (proxy *Proxy) registerTCPListener(listener *net.TCPListener) {
118+
proxy.listenersMu.Lock()
114119
proxy.tcpListeners = append(proxy.tcpListeners, listener)
120+
proxy.listenersMu.Unlock()
115121
}
116122

117123
func (proxy *Proxy) registerLocalDoHListener(listener *net.TCPListener) {
124+
proxy.listenersMu.Lock()
118125
proxy.localDoHListeners = append(proxy.localDoHListeners, listener)
126+
proxy.listenersMu.Unlock()
119127
}
120128

121129
func (proxy *Proxy) addDNSListener(listenAddrStr string) {
@@ -168,23 +176,29 @@ func (proxy *Proxy) addDNSListener(listenAddrStr string) {
168176
}
169177
defer listenerUDP.Close()
170178
defer listenerTCP.Close()
179+
FileDescriptorsMu.Lock()
171180
FileDescriptors = append(FileDescriptors, fdUDP)
172181
FileDescriptors = append(FileDescriptors, fdTCP)
182+
FileDescriptorsMu.Unlock()
173183
return
174184
}
175185

176186
// child
187+
FileDescriptorsMu.Lock()
177188
listenerUDP, err := net.FilePacketConn(os.NewFile(InheritedDescriptorsBase+FileDescriptorNum, "listenerUDP"))
178189
if err != nil {
190+
FileDescriptorsMu.Unlock()
179191
dlog.Fatalf("Unable to switch to a different user: %v", err)
180192
}
181193
FileDescriptorNum++
182194

183195
listenerTCP, err := net.FileListener(os.NewFile(InheritedDescriptorsBase+FileDescriptorNum, "listenerTCP"))
184196
if err != nil {
197+
FileDescriptorsMu.Unlock()
185198
dlog.Fatalf("Unable to switch to a different user: %v", err)
186199
}
187200
FileDescriptorNum++
201+
FileDescriptorsMu.Unlock()
188202

189203
dlog.Noticef("Now listening to %v [UDP]", listenUDPAddr)
190204
proxy.registerUDPListener(listenerUDP.(*net.UDPConn))

0 commit comments

Comments
 (0)