Skip to content

Commit 535bce3

Browse files
committed
Retry over a direct connection if we can't get a cert via a relay
This is temporary and only to provide compatibility with servers not running the latest version of encrypted-dns-server.
1 parent f9c244d commit 535bce3

2 files changed

Lines changed: 62 additions & 43 deletions

File tree

dnscrypt-proxy/dnscrypt_certs.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,15 @@ func packTxtString(s string) ([]byte, error) {
180180
}
181181

182182
func dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress string, relayUDPAddr *net.UDPAddr, relayTCPAddr *net.TCPAddr) (*dns.Msg, time.Duration, error) {
183+
response, ttl, err := _dnsExchange(proxy, proto, query, serverAddress, relayUDPAddr, relayTCPAddr)
184+
if err != nil && relayUDPAddr != nil {
185+
dlog.Warnf("Unable to get a certificate via relay [%v], retrying over a direct connection", relayUDPAddr.IP)
186+
response, ttl, err = _dnsExchange(proxy, proto, query, serverAddress, nil, nil)
187+
}
188+
return response, ttl, err
189+
}
190+
191+
func _dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress string, relayUDPAddr *net.UDPAddr, relayTCPAddr *net.TCPAddr) (*dns.Msg, time.Duration, error) {
183192
var packet []byte
184193
var rtt time.Duration
185194
if proto == "udp" {

dnscrypt-proxy/serversInfo.go

Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,55 @@ func fetchServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp, isNew
225225
return ServerInfo{}, errors.New("Unsupported protocol")
226226
}
227227

228+
func route(proxy *Proxy, name string) (*net.UDPAddr, *net.TCPAddr, error) {
229+
routes := proxy.routes
230+
if routes == nil {
231+
return nil, nil, nil
232+
}
233+
relayNames, ok := (*routes)[name]
234+
if !ok {
235+
return nil, nil, nil
236+
}
237+
var relayName string
238+
if len(relayNames) > 0 {
239+
candidate := rand.Intn(len(relayNames))
240+
relayName = relayNames[candidate]
241+
}
242+
var relayCandidateStamp *stamps.ServerStamp
243+
if len(relayName) == 0 {
244+
return nil, nil, fmt.Errorf("Route declared for [%v] but an empty relay list", name)
245+
} else if relayStamp, err := stamps.NewServerStampFromString(relayName); err == nil {
246+
relayCandidateStamp = &relayStamp
247+
} else if _, err := net.ResolveUDPAddr("udp", relayName); err == nil {
248+
relayCandidateStamp = &stamps.ServerStamp{
249+
ServerAddrStr: relayName,
250+
Proto: stamps.StampProtoTypeDNSCryptRelay,
251+
}
252+
} else {
253+
for _, registeredServer := range proxy.registeredServers {
254+
if registeredServer.name == relayName {
255+
relayCandidateStamp = &registeredServer.stamp
256+
}
257+
}
258+
}
259+
if relayCandidateStamp == nil {
260+
return nil, nil, fmt.Errorf("Undefined relay [%v] for server [%v]", relayName, name)
261+
}
262+
if relayCandidateStamp.Proto == stamps.StampProtoTypeDNSCrypt ||
263+
relayCandidateStamp.Proto == stamps.StampProtoTypeDNSCryptRelay {
264+
relayUDPAddr, err := net.ResolveUDPAddr("udp", relayCandidateStamp.ServerAddrStr)
265+
if err != nil {
266+
return nil, nil, err
267+
}
268+
relayTCPAddr, err := net.ResolveTCPAddr("tcp", relayCandidateStamp.ServerAddrStr)
269+
if err != nil {
270+
return nil, nil, err
271+
}
272+
return relayUDPAddr, relayTCPAddr, nil
273+
}
274+
return nil, nil, fmt.Errorf("Invalid relay [%v] for server [%v]", relayName, name)
275+
}
276+
228277
func fetchDNSCryptServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp, isNew bool) (ServerInfo, error) {
229278
if len(stamp.ServerPk) != ed25519.PublicKeySize {
230279
serverPk, err := hex.DecodeString(strings.Replace(string(stamp.ServerPk), ":", "", -1))
@@ -234,49 +283,10 @@ func fetchDNSCryptServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp
234283
dlog.Warnf("Public key [%s] shouldn't be hex-encoded any more", string(stamp.ServerPk))
235284
stamp.ServerPk = serverPk
236285
}
237-
var relayUDPAddr *net.UDPAddr
238-
var relayTCPAddr *net.TCPAddr
239-
var err error
240-
routes := proxy.routes
241-
if routes != nil {
242-
if relayNames, ok := (*routes)[name]; ok {
243-
var relayName string
244-
if len(relayNames) > 0 {
245-
candidate := rand.Intn(len(relayNames))
246-
relayName = relayNames[candidate]
247-
}
248-
var relayCandidateStamp *stamps.ServerStamp
249-
if len(relayName) == 0 {
250-
dlog.Errorf("Route declared for [%v] but an empty relay list", name)
251-
} else if relayStamp, err := stamps.NewServerStampFromString(relayName); err == nil {
252-
relayCandidateStamp = &relayStamp
253-
} else if _, err := net.ResolveUDPAddr("udp", relayName); err == nil {
254-
relayCandidateStamp = &stamps.ServerStamp{
255-
ServerAddrStr: relayName,
256-
Proto: stamps.StampProtoTypeDNSCryptRelay,
257-
}
258-
} else {
259-
for _, registeredServer := range proxy.registeredServers {
260-
if registeredServer.name == relayName {
261-
relayCandidateStamp = &registeredServer.stamp
262-
}
263-
}
264-
}
265-
if relayCandidateStamp != nil &&
266-
(relayCandidateStamp.Proto == stamps.StampProtoTypeDNSCrypt ||
267-
relayCandidateStamp.Proto == stamps.StampProtoTypeDNSCryptRelay) {
268-
relayUDPAddr, err = net.ResolveUDPAddr("udp", relayCandidateStamp.ServerAddrStr)
269-
if err != nil {
270-
return ServerInfo{}, err
271-
}
272-
relayTCPAddr, err = net.ResolveTCPAddr("tcp", relayCandidateStamp.ServerAddrStr)
273-
if err != nil {
274-
return ServerInfo{}, err
275-
}
276-
} else {
277-
dlog.Errorf("Invalid relay [%v] for server [%v]", relayName, name)
278-
}
279-
}
286+
relayUDPAddr, relayTCPAddr, err := route(proxy, name)
287+
if err != nil {
288+
dlog.Error(err)
289+
return ServerInfo{}, err
280290
}
281291
certInfo, rtt, err := FetchCurrentDNSCryptCert(proxy, &name, proxy.mainProto, stamp.ServerPk, stamp.ServerAddrStr, stamp.ProviderName, isNew, relayUDPAddr, relayTCPAddr)
282292
if err != nil {

0 commit comments

Comments
 (0)