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.
This commit is contained in:
Frank Denis 2019-10-20 12:26:12 +02:00
parent f9c244db10
commit 535bce308c
2 changed files with 62 additions and 43 deletions

View File

@ -180,6 +180,15 @@ func packTxtString(s string) ([]byte, error) {
} }
func dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress string, relayUDPAddr *net.UDPAddr, relayTCPAddr *net.TCPAddr) (*dns.Msg, time.Duration, error) { func dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress string, relayUDPAddr *net.UDPAddr, relayTCPAddr *net.TCPAddr) (*dns.Msg, time.Duration, error) {
response, ttl, err := _dnsExchange(proxy, proto, query, serverAddress, relayUDPAddr, relayTCPAddr)
if err != nil && relayUDPAddr != nil {
dlog.Warnf("Unable to get a certificate via relay [%v], retrying over a direct connection", relayUDPAddr.IP)
response, ttl, err = _dnsExchange(proxy, proto, query, serverAddress, nil, nil)
}
return response, ttl, err
}
func _dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress string, relayUDPAddr *net.UDPAddr, relayTCPAddr *net.TCPAddr) (*dns.Msg, time.Duration, error) {
var packet []byte var packet []byte
var rtt time.Duration var rtt time.Duration
if proto == "udp" { if proto == "udp" {

View File

@ -225,21 +225,15 @@ func fetchServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp, isNew
return ServerInfo{}, errors.New("Unsupported protocol") return ServerInfo{}, errors.New("Unsupported protocol")
} }
func fetchDNSCryptServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp, isNew bool) (ServerInfo, error) { func route(proxy *Proxy, name string) (*net.UDPAddr, *net.TCPAddr, error) {
if len(stamp.ServerPk) != ed25519.PublicKeySize {
serverPk, err := hex.DecodeString(strings.Replace(string(stamp.ServerPk), ":", "", -1))
if err != nil || len(serverPk) != ed25519.PublicKeySize {
dlog.Fatalf("Unsupported public key for [%s]: [%s]", name, stamp.ServerPk)
}
dlog.Warnf("Public key [%s] shouldn't be hex-encoded any more", string(stamp.ServerPk))
stamp.ServerPk = serverPk
}
var relayUDPAddr *net.UDPAddr
var relayTCPAddr *net.TCPAddr
var err error
routes := proxy.routes routes := proxy.routes
if routes != nil { if routes == nil {
if relayNames, ok := (*routes)[name]; ok { return nil, nil, nil
}
relayNames, ok := (*routes)[name]
if !ok {
return nil, nil, nil
}
var relayName string var relayName string
if len(relayNames) > 0 { if len(relayNames) > 0 {
candidate := rand.Intn(len(relayNames)) candidate := rand.Intn(len(relayNames))
@ -247,7 +241,7 @@ func fetchDNSCryptServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp
} }
var relayCandidateStamp *stamps.ServerStamp var relayCandidateStamp *stamps.ServerStamp
if len(relayName) == 0 { if len(relayName) == 0 {
dlog.Errorf("Route declared for [%v] but an empty relay list", name) return nil, nil, fmt.Errorf("Route declared for [%v] but an empty relay list", name)
} else if relayStamp, err := stamps.NewServerStampFromString(relayName); err == nil { } else if relayStamp, err := stamps.NewServerStampFromString(relayName); err == nil {
relayCandidateStamp = &relayStamp relayCandidateStamp = &relayStamp
} else if _, err := net.ResolveUDPAddr("udp", relayName); err == nil { } else if _, err := net.ResolveUDPAddr("udp", relayName); err == nil {
@ -262,22 +256,38 @@ func fetchDNSCryptServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp
} }
} }
} }
if relayCandidateStamp != nil && if relayCandidateStamp == nil {
(relayCandidateStamp.Proto == stamps.StampProtoTypeDNSCrypt || return nil, nil, fmt.Errorf("Undefined relay [%v] for server [%v]", relayName, name)
relayCandidateStamp.Proto == stamps.StampProtoTypeDNSCryptRelay) { }
relayUDPAddr, err = net.ResolveUDPAddr("udp", relayCandidateStamp.ServerAddrStr) if relayCandidateStamp.Proto == stamps.StampProtoTypeDNSCrypt ||
relayCandidateStamp.Proto == stamps.StampProtoTypeDNSCryptRelay {
relayUDPAddr, err := net.ResolveUDPAddr("udp", relayCandidateStamp.ServerAddrStr)
if err != nil { if err != nil {
return ServerInfo{}, err return nil, nil, err
} }
relayTCPAddr, err = net.ResolveTCPAddr("tcp", relayCandidateStamp.ServerAddrStr) relayTCPAddr, err := net.ResolveTCPAddr("tcp", relayCandidateStamp.ServerAddrStr)
if err != nil { if err != nil {
return nil, nil, err
}
return relayUDPAddr, relayTCPAddr, nil
}
return nil, nil, fmt.Errorf("Invalid relay [%v] for server [%v]", relayName, name)
}
func fetchDNSCryptServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp, isNew bool) (ServerInfo, error) {
if len(stamp.ServerPk) != ed25519.PublicKeySize {
serverPk, err := hex.DecodeString(strings.Replace(string(stamp.ServerPk), ":", "", -1))
if err != nil || len(serverPk) != ed25519.PublicKeySize {
dlog.Fatalf("Unsupported public key for [%s]: [%s]", name, stamp.ServerPk)
}
dlog.Warnf("Public key [%s] shouldn't be hex-encoded any more", string(stamp.ServerPk))
stamp.ServerPk = serverPk
}
relayUDPAddr, relayTCPAddr, err := route(proxy, name)
if err != nil {
dlog.Error(err)
return ServerInfo{}, err return ServerInfo{}, err
} }
} else {
dlog.Errorf("Invalid relay [%v] for server [%v]", relayName, name)
}
}
}
certInfo, rtt, err := FetchCurrentDNSCryptCert(proxy, &name, proxy.mainProto, stamp.ServerPk, stamp.ServerAddrStr, stamp.ProviderName, isNew, relayUDPAddr, relayTCPAddr) certInfo, rtt, err := FetchCurrentDNSCryptCert(proxy, &name, proxy.mainProto, stamp.ServerPk, stamp.ServerAddrStr, stamp.ProviderName, isNew, relayUDPAddr, relayTCPAddr)
if err != nil { if err != nil {
return ServerInfo{}, err return ServerInfo{}, err