From fcd9225121ac450400850dd566edeed98535070f Mon Sep 17 00:00:00 2001 From: Ian Bashford Date: Sat, 9 Jan 2021 21:44:32 +0000 Subject: [PATCH] Threadsafe update (#1579) * threadsafe update for relays * locks around registeredRelays --- dnscrypt-proxy/proxy.go | 3 +++ dnscrypt-proxy/serversInfo.go | 30 ++++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/dnscrypt-proxy/proxy.go b/dnscrypt-proxy/proxy.go index 989b25f5..ec578808 100644 --- a/dnscrypt-proxy/proxy.go +++ b/dnscrypt-proxy/proxy.go @@ -352,6 +352,9 @@ func (proxy *Proxy) updateRegisteredServers() error { for _, registeredServer := range proxy.registeredServers { proxy.serversInfo.registerServer(registeredServer.name, registeredServer.stamp) } + for _, registeredRelay := range proxy.registeredRelays { + proxy.serversInfo.registerRelay(registeredRelay.name, registeredRelay.stamp) + } return nil } diff --git a/dnscrypt-proxy/serversInfo.go b/dnscrypt-proxy/serversInfo.go index ac4c4fe5..6f631fd8 100644 --- a/dnscrypt-proxy/serversInfo.go +++ b/dnscrypt-proxy/serversInfo.go @@ -116,12 +116,13 @@ type ServersInfo struct { sync.RWMutex inner []*ServerInfo registeredServers []RegisteredServer + registeredRelays []RegisteredServer lbStrategy LBStrategy lbEstimator bool } func NewServersInfo() ServersInfo { - return ServersInfo{lbStrategy: DefaultLBStrategy, lbEstimator: true, registeredServers: make([]RegisteredServer, 0)} + return ServersInfo{lbStrategy: DefaultLBStrategy, lbEstimator: true, registeredServers: make([]RegisteredServer, 0), registeredRelays: make([]RegisteredServer, 0)} } func (serversInfo *ServersInfo) registerServer(name string, stamp stamps.ServerStamp) { @@ -137,6 +138,19 @@ func (serversInfo *ServersInfo) registerServer(name string, stamp stamps.ServerS serversInfo.registeredServers = append(serversInfo.registeredServers, newRegisteredServer) } +func (serversInfo *ServersInfo) registerRelay(name string, stamp stamps.ServerStamp) { + newRegisteredServer := RegisteredServer{name: name, stamp: stamp} + serversInfo.Lock() + defer serversInfo.Unlock() + for i, oldRegisteredServer := range serversInfo.registeredRelays { + if oldRegisteredServer.name == name { + serversInfo.registeredRelays[i] = newRegisteredServer + return + } + } + serversInfo.registeredRelays = append(serversInfo.registeredRelays, newRegisteredServer) +} + func (serversInfo *ServersInfo) refreshServer(proxy *Proxy, name string, stamp stamps.ServerStamp) error { serversInfo.RLock() isNew := true @@ -286,7 +300,7 @@ func findFarthestRoute(proxy *Proxy, name string, relayStamps []stamps.ServerSta if serverAddr == nil { return nil } - if len(proxy.registeredRelays) == 0 { + if len(proxy.serversInfo.registeredRelays) == 0 { return nil } bestRelayIdxs := make([]int, 0) @@ -340,19 +354,21 @@ func route(proxy *Proxy, name string) (*Relay, error) { if relayStamp, err := stamps.NewServerStampFromString(relayName); err == nil { relayStamps = append(relayStamps, relayStamp) } else if relayName == "*" { - for _, registeredServer := range proxy.registeredRelays { + proxy.serversInfo.RLock() + for _, registeredServer := range proxy.serversInfo.registeredRelays { relayStamps = append(relayStamps, registeredServer.stamp) } + proxy.serversInfo.RUnlock() wildcard = true break } else { - for _, registeredServer := range proxy.registeredRelays { + proxy.serversInfo.RLock() + for _, registeredServer := range proxy.serversInfo.registeredRelays { if registeredServer.name == relayName { relayStamps = append(relayStamps, registeredServer.stamp) break } } - proxy.serversInfo.RLock() for _, registeredServer := range proxy.serversInfo.registeredServers { if registeredServer.name == relayName { relayStamps = append(relayStamps, registeredServer.stamp) @@ -375,12 +391,14 @@ func route(proxy *Proxy, name string) (*Relay, error) { return nil, fmt.Errorf("No valid relay for server [%v]", name) } relayName := relayCandidateStamp.ServerAddrStr - for _, registeredServer := range proxy.registeredRelays { + proxy.serversInfo.RLock() + for _, registeredServer := range proxy.serversInfo.registeredRelays { if registeredServer.stamp.ServerAddrStr == relayCandidateStamp.ServerAddrStr { relayName = registeredServer.name break } } + proxy.serversInfo.RUnlock() switch relayCandidateStamp.Proto { case stamps.StampProtoTypeDNSCrypt, stamps.StampProtoTypeDNSCryptRelay: relayUDPAddr, err := net.ResolveUDPAddr("udp", relayCandidateStamp.ServerAddrStr)