Skip to content

Commit dd21d52

Browse files
committed
Create completely new results for server refreshing
Exclude servers/relays that have been removed from the sources, had their privacy level lowered, or IPv6 has became unavailable. Don't need to shuffle `proxy.registeredServers`, update/10min; shuffle `ServersInfo.registeredServers` is enough.
1 parent d7ca4c9 commit dd21d52

File tree

3 files changed

+179
-80
lines changed

3 files changed

+179
-80
lines changed

dnscrypt-proxy/config.go

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ func (config *Config) loadSources(proxy *Proxy) error {
664664
if stamp.Proto == stamps.StampProtoTypeDNSCryptRelay || stamp.Proto == stamps.StampProtoTypeODoHRelay {
665665
dlog.Debugf("Adding [%s] to the set of available static relays", name)
666666
registeredServer := RegisteredServer{name: name, stamp: stamp, description: "static relay"}
667-
proxy.registeredRelays = append(proxy.registeredRelays, registeredServer)
667+
proxy.staticRelays = append(proxy.staticRelays, registeredServer)
668668
}
669669
}
670670
}
@@ -685,18 +685,14 @@ func (config *Config) loadSources(proxy *Proxy) error {
685685
if err != nil {
686686
return fmt.Errorf("Stamp error for the static [%s] definition: [%v]", serverName, err)
687687
}
688-
proxy.registeredServers = append(proxy.registeredServers, RegisteredServer{name: serverName, stamp: stamp})
688+
proxy.staticServers = append(proxy.staticServers, RegisteredServer{name: serverName, stamp: stamp})
689689
}
690690
if err := proxy.updateRegisteredServers(); err != nil {
691691
return err
692692
}
693-
rs1 := proxy.registeredServers
694-
rs2 := proxy.serversInfo.registeredServers
695-
rand.Shuffle(len(rs1), func(i, j int) {
696-
rs1[i], rs1[j] = rs1[j], rs1[i]
697-
})
698-
rand.Shuffle(len(rs2), func(i, j int) {
699-
rs2[i], rs2[j] = rs2[j], rs2[i]
693+
rs := proxy.serversInfo.registeredServers
694+
rand.Shuffle(len(rs), func(i, j int) {
695+
rs[i], rs[j] = rs[j], rs[i]
700696
})
701697
return nil
702698
}

dnscrypt-proxy/proxy.go

Lines changed: 124 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type Proxy struct {
2323
serversInfo ServersInfo
2424
questionSizeEstimator QuestionSizeEstimator
2525
registeredServers []RegisteredServer
26+
staticServers []RegisteredServer
2627
dns64Resolvers []string
2728
dns64Prefixes []string
2829
serversBlockingFragments []string
@@ -35,6 +36,7 @@ type Proxy struct {
3536
sources []*Source
3637
tcpListeners []*net.TCPListener
3738
registeredRelays []RegisteredServer
39+
staticRelays []RegisteredServer
3840
listenAddresses []string
3941
localDoHListenAddresses []string
4042
monitoringUI MonitoringUIConfig
@@ -336,6 +338,16 @@ func (proxy *Proxy) StartProxy() {
336338
}
337339

338340
func (proxy *Proxy) updateRegisteredServers() error {
341+
registeredServersBak := proxy.registeredServers
342+
registeredRelaysBak := proxy.registeredRelays
343+
proxy.registeredServers = make([]RegisteredServer, 0)
344+
proxy.registeredRelays = make([]RegisteredServer, 0)
345+
if len(proxy.staticServers) > 0 {
346+
proxy.registeredServers = append(proxy.registeredServers, proxy.staticServers...)
347+
}
348+
if len(proxy.staticRelays) > 0 {
349+
proxy.registeredRelays = append(proxy.registeredRelays, proxy.staticRelays...)
350+
}
339351
for _, source := range proxy.sources {
340352
registeredServers, err := source.Parse()
341353
if err != nil {
@@ -350,85 +362,122 @@ func (proxy *Proxy) updateRegisteredServers() error {
350362
len(registeredServers),
351363
)
352364
}
353-
for _, registeredServer := range registeredServers {
354-
if registeredServer.stamp.Proto != stamps.StampProtoTypeDNSCryptRelay &&
355-
registeredServer.stamp.Proto != stamps.StampProtoTypeODoHRelay {
356-
if len(proxy.ServerNames) > 0 {
357-
if !includesName(proxy.ServerNames, registeredServer.name) {
358-
continue
359-
}
360-
} else if registeredServer.stamp.Props&proxy.requiredProps != proxy.requiredProps {
365+
proxy.buildRegisteredServers(registeredServers, registeredServersBak, registeredRelaysBak)
366+
}
367+
if len(proxy.registeredServers) <= 0 {
368+
proxy.registeredServers = registeredServersBak
369+
}
370+
if len(proxy.registeredRelays) <= 0 {
371+
proxy.registeredRelays = registeredRelaysBak
372+
}
373+
dlog.Debugf("Total count of registered servers %v", len(proxy.registeredServers))
374+
dlog.Debugf("Total count of registered relays %v", len(proxy.registeredRelays))
375+
proxy.serversInfo.registerServers(proxy.registeredServers)
376+
proxy.serversInfo.registerRelays(proxy.registeredRelays)
377+
return nil
378+
}
379+
380+
func (proxy *Proxy) buildRegisteredServers(registeredServers, registeredServersBak, registeredRelaysBak []RegisteredServer) {
381+
for _, registeredServer := range registeredServers {
382+
if registeredServer.stamp.Proto != stamps.StampProtoTypeDNSCryptRelay &&
383+
registeredServer.stamp.Proto != stamps.StampProtoTypeODoHRelay {
384+
if len(proxy.ServerNames) > 0 {
385+
if !includesName(proxy.ServerNames, registeredServer.name) {
361386
continue
362387
}
388+
} else if registeredServer.stamp.Props&proxy.requiredProps != proxy.requiredProps {
389+
continue
390+
}
391+
}
392+
if includesName(proxy.DisabledServerNames, registeredServer.name) {
393+
continue
394+
}
395+
if proxy.SourceIPv4 || proxy.SourceIPv6 {
396+
isIPv4, isIPv6 := true, false
397+
if registeredServer.stamp.Proto == stamps.StampProtoTypeDoH {
398+
isIPv4, isIPv6 = true, true
363399
}
364-
if includesName(proxy.DisabledServerNames, registeredServer.name) {
400+
if strings.HasPrefix(registeredServer.stamp.ServerAddrStr, "[") {
401+
isIPv4, isIPv6 = false, true
402+
}
403+
if !(proxy.SourceIPv4 == isIPv4 || proxy.SourceIPv6 == isIPv6) {
365404
continue
366405
}
367-
if proxy.SourceIPv4 || proxy.SourceIPv6 {
368-
isIPv4, isIPv6 := true, false
369-
if registeredServer.stamp.Proto == stamps.StampProtoTypeDoH {
370-
isIPv4, isIPv6 = true, true
371-
}
372-
if strings.HasPrefix(registeredServer.stamp.ServerAddrStr, "[") {
373-
isIPv4, isIPv6 = false, true
374-
}
375-
if !(proxy.SourceIPv4 == isIPv4 || proxy.SourceIPv6 == isIPv6) {
376-
continue
406+
}
407+
if registeredServer.stamp.Proto == stamps.StampProtoTypeDNSCryptRelay ||
408+
registeredServer.stamp.Proto == stamps.StampProtoTypeODoHRelay {
409+
isNew := false
410+
foundServer, stampChanged := serverStampChanged(registeredRelaysBak, &registeredServer)
411+
var dupServer *RegisteredServer
412+
if foundServer == nil || stampChanged {
413+
// in case the same name exists in sources + static, rare
414+
foundServer2, stampChanged2 := serverStampChanged(proxy.registeredRelays, &registeredServer)
415+
isNew = foundServer == nil && foundServer2 == nil
416+
if foundServer2 != nil {
417+
foundServer = foundServer2
377418
}
419+
dupServer = foundServer2
420+
stampChanged = stampChanged || stampChanged2
378421
}
379-
if registeredServer.stamp.Proto == stamps.StampProtoTypeDNSCryptRelay ||
380-
registeredServer.stamp.Proto == stamps.StampProtoTypeODoHRelay {
381-
var found bool
382-
for i, currentRegisteredRelay := range proxy.registeredRelays {
383-
if currentRegisteredRelay.name == registeredServer.name {
384-
found = true
385-
if currentRegisteredRelay.stamp.String() != registeredServer.stamp.String() {
386-
dlog.Infof(
387-
"Updating stamp for [%s] was: %s now: %s",
388-
registeredServer.name,
389-
currentRegisteredRelay.stamp.String(),
390-
registeredServer.stamp.String(),
391-
)
392-
proxy.registeredRelays[i].stamp = registeredServer.stamp
393-
dlog.Debugf("Total count of registered relays %v", len(proxy.registeredRelays))
394-
}
395-
}
396-
}
397-
if !found {
398-
dlog.Debugf("Adding [%s] to the set of available relays", registeredServer.name)
399-
proxy.registeredRelays = append(proxy.registeredRelays, registeredServer)
400-
}
422+
if stampChanged {
423+
dlog.Infof(
424+
"Updating stamp for [%s] was: %s now: %s",
425+
registeredServer.name,
426+
foundServer.stamp.String(),
427+
registeredServer.stamp.String(),
428+
)
429+
}
430+
if dupServer != nil {
431+
dupServer.stamp = registeredServer.stamp
401432
} else {
402-
if !((proxy.SourceDNSCrypt && registeredServer.stamp.Proto == stamps.StampProtoTypeDNSCrypt) ||
403-
(proxy.SourceDoH && registeredServer.stamp.Proto == stamps.StampProtoTypeDoH) ||
404-
(proxy.SourceODoH && registeredServer.stamp.Proto == stamps.StampProtoTypeODoHTarget)) {
433+
proxy.registeredRelays = append(proxy.registeredRelays, registeredServer)
434+
if isNew {
435+
dlog.Debugf("Adding [%s] to the set of available relays", registeredServer.name)
436+
} else if !stampChanged {
405437
continue
406438
}
407-
var found bool
408-
for i, currentRegisteredServer := range proxy.registeredServers {
409-
if currentRegisteredServer.name == registeredServer.name {
410-
found = true
411-
if currentRegisteredServer.stamp.String() != registeredServer.stamp.String() {
412-
dlog.Infof("Updating stamp for [%s] was: %s now: %s", registeredServer.name, currentRegisteredServer.stamp.String(), registeredServer.stamp.String())
413-
proxy.registeredServers[i].stamp = registeredServer.stamp
414-
}
415-
}
439+
}
440+
dlog.Debugf("Count of registered relays %v", len(proxy.registeredRelays))
441+
} else {
442+
if !((proxy.SourceDNSCrypt && registeredServer.stamp.Proto == stamps.StampProtoTypeDNSCrypt) ||
443+
(proxy.SourceDoH && registeredServer.stamp.Proto == stamps.StampProtoTypeDoH) ||
444+
(proxy.SourceODoH && registeredServer.stamp.Proto == stamps.StampProtoTypeODoHTarget)) {
445+
continue
446+
}
447+
isNew := false
448+
foundServer, stampChanged := serverStampChanged(registeredServersBak, &registeredServer)
449+
var dupServer *RegisteredServer
450+
if foundServer == nil || stampChanged {
451+
// in case the same name exists in sources + static, rare
452+
foundServer2, stampChanged2 := serverStampChanged(proxy.registeredServers, &registeredServer)
453+
isNew = foundServer == nil && foundServer2 == nil
454+
if foundServer2 != nil {
455+
foundServer = foundServer2
416456
}
417-
if !found {
457+
dupServer = foundServer2
458+
stampChanged = stampChanged || stampChanged2
459+
}
460+
if stampChanged {
461+
dlog.Infof(
462+
"Updating stamp for [%s] was: %s now: %s",
463+
registeredServer.name,
464+
foundServer.stamp.String(),
465+
registeredServer.stamp.String(),
466+
)
467+
}
468+
if dupServer != nil {
469+
dupServer.stamp = registeredServer.stamp
470+
} else {
471+
proxy.registeredServers = append(proxy.registeredServers, registeredServer)
472+
if isNew {
418473
dlog.Debugf("Adding [%s] to the set of wanted resolvers", registeredServer.name)
419-
proxy.registeredServers = append(proxy.registeredServers, registeredServer)
420-
dlog.Debugf("Total count of registered servers %v", len(proxy.registeredServers))
474+
} else if !stampChanged {
475+
continue
421476
}
422477
}
478+
dlog.Debugf("Count of registered servers %v", len(proxy.registeredServers))
423479
}
424480
}
425-
for _, registeredServer := range proxy.registeredServers {
426-
proxy.serversInfo.registerServer(registeredServer.name, registeredServer.stamp)
427-
}
428-
for _, registeredRelay := range proxy.registeredRelays {
429-
proxy.serversInfo.registerRelay(registeredRelay.name, registeredRelay.stamp)
430-
}
431-
return nil
432481
}
433482

434483
func (proxy *Proxy) udpListener(clientPc *net.UDPConn) {
@@ -856,3 +905,15 @@ func NewProxy() *Proxy {
856905
serversInfo: NewServersInfo(),
857906
}
858907
}
908+
909+
func serverStampChanged(servers []RegisteredServer, server *RegisteredServer) (found *RegisteredServer, changed bool) {
910+
for _, s := range servers {
911+
if s.name == server.name {
912+
found = &s
913+
if s.stamp.String() != server.stamp.String() {
914+
changed = true
915+
}
916+
}
917+
}
918+
return found, changed
919+
}

dnscrypt-proxy/serversInfo.go

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,14 @@ func NewServersInfo() ServersInfo {
175175
}
176176
}
177177

178+
func (serversInfo *ServersInfo) registerServers(registeredServers []RegisteredServer) {
179+
rs := make([]RegisteredServer, len(registeredServers))
180+
copy(rs, registeredServers)
181+
serversInfo.Lock()
182+
serversInfo.registeredServers = rs
183+
serversInfo.Unlock()
184+
}
185+
178186
func (serversInfo *ServersInfo) registerServer(name string, stamp stamps.ServerStamp) {
179187
newRegisteredServer := RegisteredServer{name: name, stamp: stamp}
180188
serversInfo.Lock()
@@ -188,6 +196,14 @@ func (serversInfo *ServersInfo) registerServer(name string, stamp stamps.ServerS
188196
serversInfo.registeredServers = append(serversInfo.registeredServers, newRegisteredServer)
189197
}
190198

199+
func (serversInfo *ServersInfo) registerRelays(registeredRelays []RegisteredServer) {
200+
rr := make([]RegisteredServer, len(registeredRelays))
201+
copy(rr, registeredRelays)
202+
serversInfo.Lock()
203+
serversInfo.registeredRelays = rr
204+
serversInfo.Unlock()
205+
}
206+
191207
func (serversInfo *ServersInfo) registerRelay(name string, stamp stamps.ServerStamp) {
192208
newRegisteredServer := RegisteredServer{name: name, stamp: stamp}
193209
serversInfo.Lock()
@@ -201,7 +217,7 @@ func (serversInfo *ServersInfo) registerRelay(name string, stamp stamps.ServerSt
201217
serversInfo.registeredRelays = append(serversInfo.registeredRelays, newRegisteredServer)
202218
}
203219

204-
func (serversInfo *ServersInfo) refreshServer(proxy *Proxy, name string, stamp stamps.ServerStamp) error {
220+
func (serversInfo *ServersInfo) initServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp) (*ServerInfo, bool, error) {
205221
serversInfo.RLock()
206222
isNew := true
207223
for _, oldServer := range serversInfo.inner {
@@ -213,26 +229,33 @@ func (serversInfo *ServersInfo) refreshServer(proxy *Proxy, name string, stamp s
213229
serversInfo.RUnlock()
214230
newServer, err := fetchServerInfo(proxy, name, stamp, isNew)
215231
if err != nil {
216-
return err
232+
return nil, isNew, err
217233
}
218234
if name != newServer.Name {
219235
dlog.Fatalf("[%s] != [%s]", name, newServer.Name)
220236
}
221237
newServer.rtt = ewma.NewMovingAverage(RTTEwmaDecay)
222238
newServer.rtt.Set(float64(newServer.initialRtt))
223-
isNew = true
239+
return &newServer, isNew, err
240+
}
241+
242+
func (serversInfo *ServersInfo) refreshServer(proxy *Proxy, name string, stamp stamps.ServerStamp) error {
243+
newServer, isNew, err := serversInfo.initServerInfo(proxy, name, stamp)
244+
if err != nil {
245+
return err
246+
}
224247
serversInfo.Lock()
225248
for i, oldServer := range serversInfo.inner {
226249
if oldServer.Name == name {
227-
serversInfo.inner[i] = &newServer
250+
serversInfo.inner[i] = newServer
228251
isNew = false
229252
break
230253
}
231254
}
232255
serversInfo.Unlock()
233256
if isNew {
234257
serversInfo.Lock()
235-
serversInfo.inner = append(serversInfo.inner, &newServer)
258+
serversInfo.inner = append(serversInfo.inner, newServer)
236259
serversInfo.Unlock()
237260
proxy.serversInfo.registerServer(name, stamp)
238261
}
@@ -250,29 +273,48 @@ func (serversInfo *ServersInfo) refresh(proxy *Proxy) (int, error) {
250273
serversInfo.RUnlock()
251274
countChannel := make(chan struct{}, proxy.certRefreshConcurrency)
252275
errorChannel := make(chan error, serversCount)
276+
serverInfoChannel := make(chan *ServerInfo, serversCount)
277+
rebuildInner := len(serversInfo.inner) > 0
253278
for i := range registeredServers {
254279
countChannel <- struct{}{}
255280
go func(registeredServer *RegisteredServer) {
256-
err := serversInfo.refreshServer(proxy, registeredServer.name, registeredServer.stamp)
257-
if err == nil {
258-
proxy.xTransport.internalResolverReady = true
281+
var serverInfo *ServerInfo
282+
var err error
283+
if rebuildInner {
284+
serverInfo, _, err = serversInfo.initServerInfo(proxy, registeredServer.name, registeredServer.stamp)
285+
serverInfoChannel <- serverInfo
286+
} else {
287+
err = serversInfo.refreshServer(proxy, registeredServer.name, registeredServer.stamp)
288+
if err == nil {
289+
proxy.xTransport.internalResolverReady = true
290+
}
259291
}
260292
errorChannel <- err
261293
<-countChannel
262294
}(&registeredServers[i])
263295
}
264296
liveServers := 0
265297
var err error
298+
var innerRefresh []*ServerInfo
266299
for i := 0; i < serversCount; i++ {
267300
err = <-errorChannel
268301
if err == nil {
269302
liveServers++
270303
}
304+
if rebuildInner {
305+
serverInfo := <-serverInfoChannel
306+
if serverInfo != nil {
307+
innerRefresh = append(innerRefresh, serverInfo)
308+
}
309+
}
271310
}
272311
if liveServers > 0 {
273312
err = nil
274313
}
275314
serversInfo.Lock()
315+
if len(innerRefresh) > 0 {
316+
serversInfo.inner = innerRefresh
317+
}
276318
sort.SliceStable(serversInfo.inner, func(i, j int) bool {
277319
return serversInfo.inner[i].initialRtt < serversInfo.inner[j].initialRtt
278320
})

0 commit comments

Comments
 (0)